diff --git a/docs/coding-style.md b/docs/coding-style.md index 5ad0991..60003f1 100644 --- a/docs/coding-style.md +++ b/docs/coding-style.md @@ -13,7 +13,7 @@ # React - create one file per one component (tiny helper components in the same file are fine) -- name file identically to the component it describes (e.g. `const DisplayForecasts: React.FC = ...` in `DisplayForecasts.ts`) +- name file identically to the component it describes (e.g. `const DisplayQuestions: React.FC = ...` in `DisplayQuestions.ts`) - use named export instead of default export for all React components - it's better for refactoring - and it plays well with `React.FC` typing diff --git a/src/backend/database/pg-wrapper.ts b/src/backend/database/pg-wrapper.ts index aba9324..3a57067 100644 --- a/src/backend/database/pg-wrapper.ts +++ b/src/backend/database/pg-wrapper.ts @@ -1,13 +1,13 @@ import { Pool, PoolClient } from "pg"; -import { Forecast } from "../platforms"; +import { Question } from "../platforms"; import { hash } from "../utils/hash"; import { measureTime } from "../utils/measureTime"; import { roughSizeOfObject } from "../utils/roughSize"; -const forecastTableNames = ["questions", "history"]; +const questionTableNames = ["questions", "history"]; -const allTableNames = [...forecastTableNames, "dashboards", "frontpage"]; +const allTableNames = [...questionTableNames, "dashboards", "frontpage"]; /* Postgres database connection code */ const databaseURL = process.env.DIGITALOCEAN_POSTGRES; @@ -51,11 +51,11 @@ export async function pgBulkInsert({ tableName, client, }: { - data: Forecast[]; + data: Question[]; tableName: string; client: PoolClient; }) { - if (!forecastTableNames.includes(tableName)) { + if (!questionTableNames.includes(tableName)) { throw Error( `Table ${tableName} not in whitelist; stopping to avoid tricky sql injections` ); @@ -171,11 +171,11 @@ export async function pgUpsert({ tableName, replacePlatform, }: { - contents: Forecast[]; + contents: Question[]; tableName: string; replacePlatform?: string; }) { - if (!forecastTableNames.includes(tableName)) { + if (!questionTableNames.includes(tableName)) { throw Error( `Table ${tableName} not in whitelist; stopping to avoid tricky sql injections` ); diff --git a/src/backend/frontpage.ts b/src/backend/frontpage.ts index a010d00..36e37b4 100644 --- a/src/backend/frontpage.ts +++ b/src/backend/frontpage.ts @@ -1,7 +1,7 @@ import { pgRead, pool } from "./database/pg-wrapper"; -import { Forecast } from "./platforms"; +import { Question } from "./platforms"; -export async function getFrontpage(): Promise { +export async function getFrontpage(): Promise { const res = await pool.query( "SELECT frontpage_sliced FROM frontpage ORDER BY id DESC LIMIT 1" ); @@ -9,7 +9,7 @@ export async function getFrontpage(): Promise { return res.rows[0].frontpage_sliced; } -export async function getFrontpageFull(): Promise { +export async function getFrontpageFull(): Promise { const res = await pool.query( "SELECT frontpage_full FROM frontpage ORDER BY id DESC LIMIT 1" ); diff --git a/src/backend/platforms/betfair.ts b/src/backend/platforms/betfair.ts index db7c410..bbfd061 100644 --- a/src/backend/platforms/betfair.ts +++ b/src/backend/platforms/betfair.ts @@ -3,7 +3,7 @@ import axios from "axios"; import https from "https"; import { calculateStars } from "../utils/stars"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; const platformName = "betfair"; @@ -80,7 +80,7 @@ async function whipIntoShape(data) { async function processPredictions(data) { let predictions = await whipIntoShape(data); // console.log(JSON.stringify(predictions, null, 4)) - let results: Forecast[] = predictions.map((prediction) => { + let results: Question[] = predictions.map((prediction) => { /* if(Math.floor(Math.random() * 10) % 20 ==0){ console.log(JSON.stringify(prediction, null, 4)) } */ diff --git a/src/backend/platforms/fantasyscotus.ts b/src/backend/platforms/fantasyscotus.ts index 9b0470e..6feb947 100644 --- a/src/backend/platforms/fantasyscotus.ts +++ b/src/backend/platforms/fantasyscotus.ts @@ -2,7 +2,7 @@ import axios from "axios"; import { calculateStars } from "../utils/stars"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; const platformName = "fantasyscotus"; @@ -67,7 +67,7 @@ async function processData(data) { let historicalPercentageCorrect = data.stats.pcnt_correct; let historicalProbabilityCorrect = Number(historicalPercentageCorrect.replace("%", "")) / 100; - let results: Forecast[] = []; + let results: Question[] = []; for (let event of events) { if (event.accuracy == "") { let id = `${platformName}-${event.id}`; @@ -75,7 +75,7 @@ async function processData(data) { let predictionData = await getPredictionsData(event.docket_url); let pAffirm = predictionData.proportionAffirm; //let trackRecord = event.prediction.includes("Affirm") ? historicalProbabilityCorrect : 1-historicalProbabilityCorrect - let eventObject: Forecast = { + let eventObject: Question = { id: id, title: `In ${event.short_name}, the SCOTUS will affirm the lower court's decision`, url: `https://fantasyscotus.net/user-predictions${event.docket_url}`, diff --git a/src/backend/platforms/index.ts b/src/backend/platforms/index.ts index e247ec4..8906c97 100644 --- a/src/backend/platforms/index.ts +++ b/src/backend/platforms/index.ts @@ -16,7 +16,7 @@ import { smarkets } from "./smarkets"; import { wildeford } from "./wildeford"; import { xrisk } from "./xrisk"; -export interface Forecast { +export interface Question { id: string; // "fantasyscotus-580" @@ -63,8 +63,8 @@ export interface Forecast { extra?: any; } -// fetcher should return null if platform failed to fetch forecasts for some reason -export type PlatformFetcher = () => Promise; +// fetcher should return null if platform failed to fetch questions for some reason +export type PlatformFetcher = () => Promise; export interface Platform { name: string; // short name for ids and `platform` db column, e.g. "xrisk" @@ -76,7 +76,7 @@ export interface Platform { // draft for the future callback-based streaming/chunking API: // interface FetchOptions { // since?: string; // some kind of cursor, Date object or opaque string? -// save: (forecasts: Forecast[]) => Promise; +// save: (questions: Question[]) => Promise; // } // export type PlatformFetcher = (options: FetchOptions) => Promise; diff --git a/src/backend/platforms/infer.ts b/src/backend/platforms/infer.ts index 0235070..23a78d6 100644 --- a/src/backend/platforms/infer.ts +++ b/src/backend/platforms/infer.ts @@ -1,12 +1,11 @@ /* Imports */ import axios from "axios"; -import { Tabletojson } from "tabletojson"; import { applyIfSecretExists } from "../utils/getSecrets"; import { measureTime } from "../utils/measureTime"; import { calculateStars } from "../utils/stars"; import toMarkdown from "../utils/toMarkdown"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; /* Definitions */ const platformName = "infer"; @@ -78,12 +77,12 @@ async function fetchStats(questionUrl, cookie) { let comments_count = firstEmbeddedJson.question.comments_count; let numforecasters = firstEmbeddedJson.question.predictors_count; let numforecasts = firstEmbeddedJson.question.prediction_sets_count; - let forecastType = firstEmbeddedJson.question.type; + let questionType = firstEmbeddedJson.question.type; if ( - forecastType.includes("Binary") || - forecastType.includes("NonExclusiveOpinionPoolQuestion") || - forecastType.includes("Forecast::Question") || - !forecastType.includes("Forecast::MultiTimePeriodQuestion") + questionType.includes("Binary") || + questionType.includes("NonExclusiveOpinionPoolQuestion") || + questionType.includes("Forecast::Question") || + !questionType.includes("Forecast::MultiTimePeriodQuestion") ) { options = firstEmbeddedJson.question.answers.map((answer) => ({ name: answer.name, @@ -148,7 +147,7 @@ function sleep(ms) { async function infer_inner(cookie: string) { let i = 1; let response = await fetchPage(i, cookie); - let results: Forecast[] = []; + let results: Question[] = []; await measureTime(async () => { // console.log("Downloading... This might take a couple of minutes. Results will be shown.") @@ -179,7 +178,7 @@ async function infer_inner(cookie: string) { let questionNumRegex = new RegExp("questions/([0-9]+)"); let questionNum = url.match(questionNumRegex)[1]; //.split("questions/")[1].split("-")[0]; let id = `${platformName}-${questionNum}`; - let question: Forecast = { + let question: Question = { id: id, title: title, description: moreinfo.description, diff --git a/src/backend/platforms/manifold.ts b/src/backend/platforms/manifold.ts index 7de7756..8304c61 100644 --- a/src/backend/platforms/manifold.ts +++ b/src/backend/platforms/manifold.ts @@ -2,7 +2,7 @@ import axios from "axios"; import { calculateStars } from "../utils/stars"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; /* Definitions */ const platformName = "manifold"; @@ -23,7 +23,7 @@ async function fetchData() { return response; } -function showStatistics(results: Forecast[]) { +function showStatistics(results: Question[]) { console.log(`Num unresolved markets: ${results.length}`); let sum = (arr) => arr.reduce((tally, a) => tally + a, 0); let num2StarsOrMore = results.filter( @@ -44,7 +44,7 @@ function showStatistics(results: Forecast[]) { } async function processPredictions(predictions) { - let results: Forecast[] = await predictions.map((prediction) => { + let results: Question[] = await predictions.map((prediction) => { let id = `${platformName}-${prediction.id}`; // oops, doesn't match platform name let probability = prediction.probability; let options = [ @@ -59,7 +59,7 @@ async function processPredictions(predictions) { type: "PROBABILITY", }, ]; - const result: Forecast = { + const result: Question = { id: id, title: prediction.question, url: prediction.url, diff --git a/src/backend/platforms/polymarket.ts b/src/backend/platforms/polymarket.ts index c5e24ab..72c53f1 100644 --- a/src/backend/platforms/polymarket.ts +++ b/src/backend/platforms/polymarket.ts @@ -2,7 +2,7 @@ import axios from "axios"; import { calculateStars } from "../utils/stars"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; /* Definitions */ const platformName = "polymarket"; @@ -68,7 +68,7 @@ export const polymarket: Platform = { label: "PolyMarket", color: "#00314e", async fetcher() { - let results: Forecast[] = []; + let results: Question[] = []; let webpageEndpointData = await fetchAllContractInfo(); for (let marketInfo of webpageEndpointData) { let address = marketInfo.marketMakerAddress; @@ -102,7 +102,7 @@ export const polymarket: Platform = { }); } - let result: Forecast = { + let result: Question = { id: id, title: marketInfo.question, url: "https://polymarket.com/market/" + marketInfo.slug, diff --git a/src/backend/platforms/rootclaim.ts b/src/backend/platforms/rootclaim.ts index 8701133..d195cd7 100644 --- a/src/backend/platforms/rootclaim.ts +++ b/src/backend/platforms/rootclaim.ts @@ -3,7 +3,7 @@ import { JSDOM } from "jsdom"; import { calculateStars } from "../utils/stars"; import toMarkdown from "../utils/toMarkdown"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; const platformName = "rootclaim"; const jsonEndpoint = @@ -50,7 +50,7 @@ export const rootclaim: Platform = { color: "#0d1624", async fetcher() { const claims = await fetchAllRootclaims(); - const results: Forecast[] = []; + const results: Question[] = []; for (const claim of claims) { const id = `${platformName}-${claim.slug.toLowerCase()}`; @@ -71,7 +71,7 @@ export const rootclaim: Platform = { const description = await fetchDescription(url, claim.isclaim); - let obj: Forecast = { + let obj: Question = { id, title: toMarkdown(claim.question).replace("\n", ""), url, diff --git a/src/backend/platforms/smarkets.ts b/src/backend/platforms/smarkets.ts index 260df9a..845caea 100644 --- a/src/backend/platforms/smarkets.ts +++ b/src/backend/platforms/smarkets.ts @@ -1,7 +1,7 @@ import axios from "axios"; import { calculateStars } from "../utils/stars"; -import { Forecast, Platform } from "./"; +import { Platform, Question } from "./"; /* Definitions */ const platformName = "smarkets"; @@ -159,7 +159,7 @@ export const smarkets: Platform = { name = name+ (contractName=="Yes"?'':` (${contracts["contracts"][0].name})`) } */ - let result: Forecast = { + let result: Question = { id: id, title: name, url: "https://smarkets.com/event/" + market.event_id + market.slug, diff --git a/src/backend/utils/evaluations/pullForecastsToCSVForRating.ts b/src/backend/utils/evaluations/pullForecastsToCSVForRating.ts index d6ac803..1c044cf 100644 --- a/src/backend/utils/evaluations/pullForecastsToCSVForRating.ts +++ b/src/backend/utils/evaluations/pullForecastsToCSVForRating.ts @@ -8,14 +8,14 @@ import { pgRead } from "../../database/pg-wrapper"; /* Utilities */ /* Support functions */ -let getQualityIndicators = (forecast) => - Object.entries(forecast.qualityindicators) +const getQualityIndicators = (question) => + Object.entries(question.qualityindicators) .map((entry) => `${entry[0]}: ${entry[1]}`) .join("; "); /* Body */ -let main = async () => { +const main = async () => { let highQualityPlatforms = [ "CSET-foretell", "Foretold", @@ -24,21 +24,21 @@ let main = async () => { "PredictIt", "Rootclaim", ]; - let json = await pgRead({ tableName: "questions" }); + const json = await pgRead({ tableName: "questions" }); console.log(json.length); //let uniquePlatforms = [...new Set(json.map(forecast => forecast.platform))] //console.log(uniquePlatforms) - let forecastsFromGoodPlatforms = json.filter((forecast) => - highQualityPlatforms.includes(forecast.platform) + const questionsFromGoodPlatforms = json.filter((question) => + highQualityPlatforms.includes(question.platform) ); - let tsv = + const tsv = "index\ttitle\turl\tqualityindicators\n" + - forecastsFromGoodPlatforms - .map((forecast, index) => { - let row = `${index}\t${forecast.title}\t${ - forecast.url - }\t${getQualityIndicators(forecast)}`; + questionsFromGoodPlatforms + .map((question, index) => { + let row = `${index}\t${question.title}\t${ + question.url + }\t${getQualityIndicators(question)}`; console.log(row); return row; }) diff --git a/src/backend/utils/evaluations/pullMetaculusForecastsToCSVForRating.ts b/src/backend/utils/evaluations/pullMetaculusForecastsToCSVForRating.ts index ddd8c42..0076f67 100644 --- a/src/backend/utils/evaluations/pullMetaculusForecastsToCSVForRating.ts +++ b/src/backend/utils/evaluations/pullMetaculusForecastsToCSVForRating.ts @@ -8,8 +8,8 @@ import { pgRead } from "../../database/pg-wrapper"; /* Utilities */ /* Support functions */ -let getQualityIndicators = (forecast) => - Object.entries(forecast.qualityindicators) +let getQualityIndicators = (question) => + Object.entries(question.qualityindicators) .map((entry) => `${entry[0]}: ${entry[1]}`) .join("; "); @@ -28,22 +28,22 @@ let main = async () => { let highQualityPlatforms = ["Metaculus"]; // ['CSET-foretell', 'Foretold', 'Good Judgment Open', 'Metaculus', 'PredictIt', 'Rootclaim'] let json = await pgRead({ tableName: "questions" }); console.log(json.length); - //let uniquePlatforms = [...new Set(json.map(forecast => forecast.platform))] + //let uniquePlatforms = [...new Set(json.map(question => question.platform))] //console.log(uniquePlatforms) - let forecastsFromGoodPlatforms = json.filter((forecast) => - highQualityPlatforms.includes(forecast.platform) + let questionsFromGoodPlatforms = json.filter((question) => + highQualityPlatforms.includes(question.platform) ); - let forecastsFromGoodPlatformsShuffled = shuffleArray( - forecastsFromGoodPlatforms + let questionsFromGoodPlatformsShuffled = shuffleArray( + questionsFromGoodPlatforms ); let tsv = "index\ttitle\turl\tqualityindicators\n" + - forecastsFromGoodPlatforms - .map((forecast, index) => { - let row = `${index}\t${forecast.title}\t${ - forecast.url - }\t${getQualityIndicators(forecast)}`; + questionsFromGoodPlatforms + .map((question, index) => { + let row = `${index}\t${question.title}\t${ + question.url + }\t${getQualityIndicators(question)}`; console.log(row); return row; }) diff --git a/src/pages/capture.tsx b/src/pages/capture.tsx index 16712bd..63ec63c 100644 --- a/src/pages/capture.tsx +++ b/src/pages/capture.tsx @@ -1,7 +1,7 @@ import { NextPage } from "next"; import React from "react"; -import { displayForecastsWrapperForCapture } from "../web/display/displayForecastsWrappers"; +import { displayQuestionsWrapperForCapture } from "../web/display/displayQuestionsWrappers"; import { Layout } from "../web/display/Layout"; import { Props } from "../web/search/anySearchPage"; import CommonDisplay from "../web/search/CommonDisplay"; @@ -18,7 +18,7 @@ const CapturePage: NextPage = (props) => { hasAdvancedOptions={false} placeholder={"Get best title match..."} displaySeeMoreHint={false} - displayForecastsWrapper={displayForecastsWrapperForCapture} + displayQuestionsWrapper={displayQuestionsWrapperForCapture} /> ); diff --git a/src/pages/dashboards/embed/[id].tsx b/src/pages/dashboards/embed/[id].tsx index 04a3c76..e43ea61 100644 --- a/src/pages/dashboards/embed/[id].tsx +++ b/src/pages/dashboards/embed/[id].tsx @@ -2,13 +2,13 @@ import { GetServerSideProps, NextPage } from "next"; import Error from "next/error"; import { DashboardItem } from "../../../backend/dashboards"; -import { DisplayForecasts } from "../../../web/display/DisplayForecasts"; -import { FrontendForecast } from "../../../web/platforms"; -import { getDashboardForecastsByDashboardId } from "../../../web/worker/getDashboardForecasts"; +import { DisplayQuestions } from "../../../web/display/DisplayQuestions"; +import { FrontendQuestion } from "../../../web/platforms"; import { reqToBasePath } from "../../../web/utils"; +import { getDashboardQuestionsByDashboardId } from "../../../web/worker/getDashboardQuestions"; interface Props { - dashboardForecasts: FrontendForecast[]; + dashboardQuestions: FrontendQuestion[]; dashboardItem: DashboardItem; numCols?: number; } @@ -19,8 +19,8 @@ export const getServerSideProps: GetServerSideProps = async ( const dashboardId = context.query.id as string; const numCols = Number(context.query.numCols); - const { dashboardItem, dashboardForecasts } = - await getDashboardForecastsByDashboardId({ + const { dashboardItem, dashboardQuestions } = + await getDashboardQuestionsByDashboardId({ dashboardId, basePath: reqToBasePath(context.req), // required on server side to find the API endpoint }); @@ -31,7 +31,7 @@ export const getServerSideProps: GetServerSideProps = async ( return { props: { - dashboardForecasts, + dashboardQuestions, dashboardItem, numCols: !numCols ? null : numCols < 5 ? numCols : 4, }, @@ -39,7 +39,7 @@ export const getServerSideProps: GetServerSideProps = async ( }; const EmbedDashboardPage: NextPage = ({ - dashboardForecasts, + dashboardQuestions, dashboardItem, numCols, }) => { @@ -57,9 +57,9 @@ const EmbedDashboardPage: NextPage = ({ numCols || 3 } gap-4 mb-6`} > - diff --git a/src/pages/dashboards/view/[id].tsx b/src/pages/dashboards/view/[id].tsx index 84184e0..57a64dd 100644 --- a/src/pages/dashboards/view/[id].tsx +++ b/src/pages/dashboards/view/[id].tsx @@ -3,16 +3,16 @@ import Error from "next/error"; import Link from "next/link"; import { DashboardItem } from "../../../backend/dashboards"; -import { DisplayForecasts } from "../../../web/display/DisplayForecasts"; +import { DisplayQuestions } from "../../../web/display/DisplayQuestions"; import { InfoBox } from "../../../web/display/InfoBox"; import { Layout } from "../../../web/display/Layout"; import { LineHeader } from "../../../web/display/LineHeader"; -import { FrontendForecast } from "../../../web/platforms"; +import { FrontendQuestion } from "../../../web/platforms"; import { reqToBasePath } from "../../../web/utils"; -import { getDashboardForecastsByDashboardId } from "../../../web/worker/getDashboardForecasts"; +import { getDashboardQuestionsByDashboardId } from "../../../web/worker/getDashboardQuestions"; interface Props { - dashboardForecasts: FrontendForecast[]; + dashboardQuestions: FrontendQuestion[]; dashboardItem: DashboardItem; } @@ -21,8 +21,8 @@ export const getServerSideProps: GetServerSideProps = async ( ) => { const dashboardId = context.query.id as string; - const { dashboardForecasts, dashboardItem } = - await getDashboardForecastsByDashboardId({ + const { dashboardQuestions, dashboardItem } = + await getDashboardQuestionsByDashboardId({ dashboardId, basePath: reqToBasePath(context.req), // required on server side to find the API endpoint }); @@ -33,7 +33,7 @@ export const getServerSideProps: GetServerSideProps = async ( return { props: { - dashboardForecasts, + dashboardQuestions, dashboardItem, }, }; @@ -78,7 +78,7 @@ const DashboardMetadata: React.FC<{ dashboardItem: DashboardItem }> = ({ /* Body */ const ViewDashboardPage: NextPage = ({ - dashboardForecasts, + dashboardQuestions, dashboardItem, }) => { return ( @@ -91,9 +91,9 @@ const ViewDashboardPage: NextPage = ({ )}
-
diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 786e7a9..45b4637 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,7 +1,7 @@ import { NextPage } from "next"; import React from "react"; -import { displayForecastsWrapperForSearch } from "../web/display/displayForecastsWrappers"; +import { displayQuestionsWrapperForSearch } from "../web/display/displayQuestionsWrappers"; import { Layout } from "../web/display/Layout"; import { Props } from "../web/search/anySearchPage"; import CommonDisplay from "../web/search/CommonDisplay"; @@ -18,7 +18,7 @@ const IndexPage: NextPage = (props) => { hasAdvancedOptions={true} placeholder={"Find forecasts about..."} displaySeeMoreHint={true} - displayForecastsWrapper={displayForecastsWrapperForSearch} + displayQuestionsWrapper={displayQuestionsWrapperForSearch} /> ); diff --git a/src/pages/secretEmbed.tsx b/src/pages/secretEmbed.tsx index fa99277..d97b885 100644 --- a/src/pages/secretEmbed.tsx +++ b/src/pages/secretEmbed.tsx @@ -4,12 +4,12 @@ import { GetServerSideProps, NextPage } from "next"; import React from "react"; import { platforms } from "../backend/platforms"; -import { DisplayForecast } from "../web/display/DisplayForecast"; -import { FrontendForecast } from "../web/platforms"; +import { DisplayQuestion } from "../web/display/DisplayQuestion"; +import { FrontendQuestion } from "../web/platforms"; import searchAccordingToQueryData from "../web/worker/searchAccordingToQueryData"; interface Props { - results: FrontendForecast[]; + results: FrontendQuestion[]; } export const getServerSideProps: GetServerSideProps = async ( @@ -25,7 +25,7 @@ export const getServerSideProps: GetServerSideProps = async ( ...urlQuery, }; - let results: FrontendForecast[] = []; + let results: FrontendQuestion[] = []; if (initialQueryParameters.query != "") { results = await searchAccordingToQueryData(initialQueryParameters, 1); } @@ -46,8 +46,8 @@ const SecretEmbedPage: NextPage = ({ results }) => {
{result ? ( - diff --git a/src/web/display/DisplayForecasts.tsx b/src/web/display/DisplayForecasts.tsx deleted file mode 100644 index f10d677..0000000 --- a/src/web/display/DisplayForecasts.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from "react"; - -import { FrontendForecast } from "../platforms"; -import { DisplayForecast } from "./DisplayForecast"; - -interface Props { - results: FrontendForecast[]; - numDisplay: number; - showIdToggle: boolean; -} - -export const DisplayForecasts: React.FC = ({ - results, - numDisplay, - showIdToggle, -}) => { - if (!results) { - return <>; - } - return ( - <> - {results.slice(0, numDisplay).map((result) => ( - /*let displayWithMetaculusCapture = - fuseSearchResult.item.platform == "Metaculus" - ? metaculusEmbed(fuseSearchResult.item) - : displayForecast({ ...fuseSearchResult.item }); - */ - - ))} - - ); -}; diff --git a/src/web/display/DisplayOneForecastForCapture.tsx b/src/web/display/DisplayOneQuestionForCapture.tsx similarity index 95% rename from src/web/display/DisplayOneForecastForCapture.tsx rename to src/web/display/DisplayOneQuestionForCapture.tsx index 0797d55..8505ba5 100644 --- a/src/web/display/DisplayOneForecastForCapture.tsx +++ b/src/web/display/DisplayOneQuestionForCapture.tsx @@ -2,16 +2,16 @@ import domtoimage from "dom-to-image"; // https://github.com/tsayen/dom-to-image import { useEffect, useRef, useState } from "react"; import { CopyToClipboard } from "react-copy-to-clipboard"; -import { FrontendForecast } from "../platforms"; +import { FrontendQuestion } from "../platforms"; import { uploadToImgur } from "../worker/uploadToImgur"; -import { DisplayForecast } from "./DisplayForecast"; +import { DisplayQuestion } from "./DisplayQuestion"; -function displayOneForecastInner(result: FrontendForecast, containerRef) { +function displayOneQuestionInner(result: FrontendQuestion, containerRef) { return (
{result ? ( - @@ -168,10 +168,10 @@ let generateMetaculusSource = (result, hasDisplayBeenCaptured) => { }; interface Props { - result: FrontendForecast; + result: FrontendQuestion; } -export const DisplayOneForecastForCapture: React.FC = ({ result }) => { +export const DisplayOneQuestionForCapture: React.FC = ({ result }) => { const [hasDisplayBeenCaptured, setHasDisplayBeenCaptured] = useState(false); useEffect(() => { @@ -226,7 +226,7 @@ export const DisplayOneForecastForCapture: React.FC = ({ result }) => { return (
- {displayOneForecastInner(result, containerRef)} + {displayOneQuestionInner(result, containerRef)}
{generateCaptureButton(result, onCaptureButtonClick)} diff --git a/src/web/display/DisplayForecast/ForecastFooter.tsx b/src/web/display/DisplayQuestion/QuestionFooter.tsx similarity index 99% rename from src/web/display/DisplayForecast/ForecastFooter.tsx rename to src/web/display/DisplayQuestion/QuestionFooter.tsx index aa1707f..1933106 100644 --- a/src/web/display/DisplayForecast/ForecastFooter.tsx +++ b/src/web/display/DisplayQuestion/QuestionFooter.tsx @@ -243,7 +243,7 @@ interface Props { expandFooterToFullWidth: boolean; } -export const ForecastFooter: React.FC = ({ +export const QuestionFooter: React.FC = ({ stars, platform, platformLabel, diff --git a/src/web/display/DisplayForecast/index.tsx b/src/web/display/DisplayQuestion/index.tsx similarity index 97% rename from src/web/display/DisplayForecast/index.tsx rename to src/web/display/DisplayQuestion/index.tsx index 2eff8be..1854a9e 100644 --- a/src/web/display/DisplayForecast/index.tsx +++ b/src/web/display/DisplayQuestion/index.tsx @@ -1,9 +1,9 @@ import { FaRegClipboard } from "react-icons/fa"; import ReactMarkdown from "react-markdown"; -import { FrontendForecast } from "../../platforms"; +import { FrontendQuestion } from "../../platforms"; import { Card } from "../Card"; -import { ForecastFooter } from "./ForecastFooter"; +import { QuestionFooter } from "./QuestionFooter"; const truncateText = (length: number, text: string): string => { if (!text) { @@ -268,14 +268,14 @@ const LastUpdated: React.FC<{ timestamp: string }> = ({ timestamp }) => ( // Main component interface Props { - forecast: FrontendForecast; + question: FrontendQuestion; showTimeStamp: boolean; expandFooterToFullWidth: boolean; showIdToggle?: boolean; } -export const DisplayForecast: React.FC = ({ - forecast: { +export const DisplayQuestion: React.FC = ({ + question: { id, title, url, @@ -372,7 +372,7 @@ export const DisplayForecast: React.FC = ({
- = ({ + results, + numDisplay, + showIdToggle, +}) => { + if (!results) { + return <>; + } + return ( + <> + {results.slice(0, numDisplay).map((result) => ( + + ))} + + ); +}; diff --git a/src/web/display/displayForecastsWrappers.tsx b/src/web/display/displayQuestionsWrappers.tsx similarity index 61% rename from src/web/display/displayForecastsWrappers.tsx rename to src/web/display/displayQuestionsWrappers.tsx index 6244be3..7c4683d 100644 --- a/src/web/display/displayForecastsWrappers.tsx +++ b/src/web/display/displayQuestionsWrappers.tsx @@ -1,14 +1,14 @@ -import { DisplayForecasts } from "./DisplayForecasts"; -import { DisplayOneForecastForCapture } from "./DisplayOneForecastForCapture"; +import { DisplayOneQuestionForCapture } from "./DisplayOneQuestionForCapture"; +import { DisplayQuestions } from "./DisplayQuestions"; -export function displayForecastsWrapperForSearch({ +export function displayQuestionsWrapperForSearch({ results, numDisplay, showIdToggle, }) { return (
- -
diff --git a/src/web/platforms.ts b/src/web/platforms.ts index ad14113..aa35a59 100644 --- a/src/web/platforms.ts +++ b/src/web/platforms.ts @@ -1,20 +1,20 @@ -import { Forecast, PlatformConfig } from "../backend/platforms"; +import { PlatformConfig, Question } from "../backend/platforms"; -export type FrontendForecast = Forecast & { +export type FrontendQuestion = Question & { platformLabel: string; visualization?: any; }; // ok on client side -export const addLabelsToForecasts = ( - forecasts: Forecast[], +export const addLabelsToQuestions = ( + questions: Question[], platformsConfig: PlatformConfig[] -): FrontendForecast[] => { +): FrontendQuestion[] => { const platformNameToLabel = Object.fromEntries( platformsConfig.map((platform) => [platform.name, platform.label]) ); - return forecasts.map((result) => ({ + return questions.map((result) => ({ ...result, platformLabel: platformNameToLabel[result.platform] || result.platform, })); diff --git a/src/web/search/CommonDisplay.tsx b/src/web/search/CommonDisplay.tsx index 98c7c1a..8c70378 100644 --- a/src/web/search/CommonDisplay.tsx +++ b/src/web/search/CommonDisplay.tsx @@ -6,7 +6,7 @@ import { MultiSelectPlatform } from "../display/MultiSelectPlatform"; import { QueryForm } from "../display/QueryForm"; import { SliderElement } from "../display/SliderElement"; import { useNoInitialEffect } from "../hooks"; -import { FrontendForecast } from "../platforms"; +import { FrontendQuestion } from "../platforms"; import searchAccordingToQueryData from "../worker/searchAccordingToQueryData"; import { Props as AnySearchPageProps, QueryParameters } from "./anySearchPage"; @@ -16,8 +16,8 @@ interface Props extends AnySearchPageProps { hasAdvancedOptions: boolean; placeholder: string; displaySeeMoreHint: boolean; - displayForecastsWrapper: (opts: { - results: FrontendForecast[]; + displayQuestionsWrapper: (opts: { + results: FrontendQuestion[]; numDisplay: number; whichResultToDisplayAndCapture: number; showIdToggle: boolean; @@ -38,7 +38,7 @@ const CommonDisplay: React.FC = ({ hasAdvancedOptions, placeholder, displaySeeMoreHint, - displayForecastsWrapper, + displayQuestionsWrapper, }) => { const router = useRouter(); /* States */ @@ -68,7 +68,7 @@ const CommonDisplay: React.FC = ({ const filterManually = ( queryData: QueryParameters, - results: FrontendForecast[] + results: FrontendQuestion[] ) => { if ( queryData.forecastingPlatforms && @@ -99,13 +99,13 @@ const CommonDisplay: React.FC = ({ setResults(results); } - // I don't want the function which display forecasts (displayForecasts) to change with a change in queryParameters. But I want it to have access to the queryParameters, and in particular access to queryParameters.numDisplay. Hence why this function lives inside Home. - const getInfoToDisplayForecastsFunction = () => { + // I don't want the component which display questions (DisplayQuestions) to change with a change in queryParameters. But I want it to have access to the queryParameters, and in particular access to queryParameters.numDisplay. Hence why this function lives inside Home. + const getInfoToDisplayQuestionsFunction = () => { const numDisplayRounded = numDisplay % 3 != 0 ? numDisplay + (3 - (Math.round(numDisplay) % 3)) : numDisplay; - return displayForecastsWrapper({ + return displayQuestionsWrapper({ results, numDisplay: numDisplayRounded, whichResultToDisplayAndCapture, @@ -307,7 +307,7 @@ const CommonDisplay: React.FC = ({
) : null} -
{getInfoToDisplayForecastsFunction()}
+
{getInfoToDisplayQuestionsFunction()}
{displaySeeMoreHint && (!results || (results.length != 0 && numDisplay < results.length)) ? ( diff --git a/src/web/search/anySearchPage.tsx b/src/web/search/anySearchPage.tsx index 2fb84c1..aa3110a 100644 --- a/src/web/search/anySearchPage.tsx +++ b/src/web/search/anySearchPage.tsx @@ -2,7 +2,7 @@ import { GetServerSideProps } from "next"; import { getFrontpage } from "../../backend/frontpage"; import { getPlatformsConfig, PlatformConfig, platforms } from "../../backend/platforms"; -import { addLabelsToForecasts, FrontendForecast } from "../platforms"; +import { addLabelsToQuestions, FrontendQuestion } from "../platforms"; import searchAccordingToQueryData from "../worker/searchAccordingToQueryData"; /* Common code for / and /capture */ @@ -15,8 +15,8 @@ export interface QueryParameters { } export interface Props { - defaultResults: FrontendForecast[]; - initialResults: FrontendForecast[]; + defaultResults: FrontendQuestion[]; + initialResults: FrontendQuestion[]; initialQueryParameters: QueryParameters; defaultQueryParameters: QueryParameters; initialNumDisplay: number; @@ -61,7 +61,7 @@ export const getServerSideProps: GetServerSideProps = async ( const defaultNumDisplay = 21; const initialNumDisplay = Number(urlQuery.numDisplay) || defaultNumDisplay; - const defaultResults = addLabelsToForecasts( + const defaultResults = addLabelsToQuestions( await getFrontpage(), platformsConfig ); diff --git a/src/web/worker/getDashboardForecasts.ts b/src/web/worker/getDashboardQuestions.ts similarity index 73% rename from src/web/worker/getDashboardForecasts.ts rename to src/web/worker/getDashboardQuestions.ts index 95dba39..73a7985 100644 --- a/src/web/worker/getDashboardForecasts.ts +++ b/src/web/worker/getDashboardQuestions.ts @@ -1,25 +1,25 @@ import axios from "axios"; import { DashboardItem } from "../../backend/dashboards"; -import { Forecast, getPlatformsConfig } from "../../backend/platforms"; -import { addLabelsToForecasts, FrontendForecast } from "../platforms"; +import { getPlatformsConfig, Question } from "../../backend/platforms"; +import { addLabelsToQuestions, FrontendQuestion } from "../platforms"; -export async function getDashboardForecastsByDashboardId({ +export async function getDashboardQuestionsByDashboardId({ dashboardId, basePath, }: { dashboardId: string; basePath?: string; }): Promise<{ - dashboardForecasts: FrontendForecast[]; + dashboardQuestions: FrontendQuestion[]; dashboardItem: DashboardItem; }> { - console.log("getDashboardForecastsByDashboardId: "); + console.log("getDashboardQuestionsByDashboardId: "); if (typeof window === undefined && !basePath) { throw new Error("`basePath` option is required on server side"); } - let dashboardForecasts: Forecast[] = []; + let dashboardQuestions: Question[] = []; let dashboardItem: DashboardItem | null = null; try { let { data } = await axios({ @@ -31,18 +31,18 @@ export async function getDashboardForecastsByDashboardId({ }); console.log(data); - dashboardForecasts = data.dashboardContents; + dashboardQuestions = data.dashboardContents; dashboardItem = data.dashboardItem as DashboardItem; } catch (error) { console.log(error); } finally { - const labeledDashboardForecasts = addLabelsToForecasts( - dashboardForecasts, + const labeledDashboardQuestions = addLabelsToQuestions( + dashboardQuestions, getPlatformsConfig({ withGuesstimate: false }) ); return { - dashboardForecasts: labeledDashboardForecasts, + dashboardQuestions: labeledDashboardQuestions, dashboardItem, }; } diff --git a/src/web/worker/searchAccordingToQueryData.ts b/src/web/worker/searchAccordingToQueryData.ts index 856159f..2f41182 100644 --- a/src/web/worker/searchAccordingToQueryData.ts +++ b/src/web/worker/searchAccordingToQueryData.ts @@ -1,4 +1,4 @@ -import { FrontendForecast } from "../platforms"; +import { FrontendQuestion } from "../platforms"; import { QueryParameters } from "../search/anySearchPage"; import searchGuesstimate from "./searchGuesstimate"; import searchWithAlgolia from "./searchWithAlgolia"; @@ -6,8 +6,8 @@ import searchWithAlgolia from "./searchWithAlgolia"; export default async function searchAccordingToQueryData( queryData: QueryParameters, limit: number -): Promise { - let results: FrontendForecast[] = []; +): Promise { + let results: FrontendQuestion[] = []; try { // defs diff --git a/src/web/worker/searchGuesstimate.ts b/src/web/worker/searchGuesstimate.ts index 6b45607..d36c4d1 100644 --- a/src/web/worker/searchGuesstimate.ts +++ b/src/web/worker/searchGuesstimate.ts @@ -1,7 +1,7 @@ /* Imports */ import axios from "axios"; -import { FrontendForecast } from "../platforms"; +import { FrontendQuestion } from "../platforms"; /* Definitions */ let urlEndPoint = @@ -11,7 +11,7 @@ let urlEndPoint = export default async function searchGuesstimate( query -): Promise { +): Promise { let response = await axios({ url: urlEndPoint, // credentials: "omit", @@ -31,7 +31,7 @@ export default async function searchGuesstimate( }); const models: any[] = response.data.hits; - const mappedModels: FrontendForecast[] = models.map((model, index) => { + const mappedModels: FrontendQuestion[] = models.map((model, index) => { let description = model.description ? model.description.replace(/\n/g, " ").replace(/ /g, " ") : ""; @@ -57,7 +57,7 @@ export default async function searchGuesstimate( // filter for duplicates. Surprisingly common. let uniqueTitles = []; - let uniqueModels: FrontendForecast[] = []; + let uniqueModels: FrontendQuestion[] = []; for (let model of mappedModels) { if (!uniqueTitles.includes(model.title) && !model.title.includes("copy")) { uniqueModels.push(model); diff --git a/src/web/worker/searchWithAlgolia.ts b/src/web/worker/searchWithAlgolia.ts index 6a6fde8..48654c2 100644 --- a/src/web/worker/searchWithAlgolia.ts +++ b/src/web/worker/searchWithAlgolia.ts @@ -1,6 +1,6 @@ import algoliasearch from "algoliasearch"; -import { FrontendForecast } from "../platforms"; +import { FrontendQuestion } from "../platforms"; const client = algoliasearch( process.env.NEXT_PUBLIC_ALGOLIA_APP_ID, @@ -82,8 +82,8 @@ export default async function searchWithAlgolia({ starsThreshold, filterByPlatforms, forecastsThreshold, -}): Promise { - let response = await index.search(queryString, { +}): Promise { + let response = await index.search(queryString, { hitsPerPage, filters: buildFilter({ starsThreshold, @@ -93,7 +93,7 @@ export default async function searchWithAlgolia({ //facetFilters: buildFacetFilter({filterByPlatforms}), getRankingInfo: true, }); - let results: FrontendForecast[] = response.hits; + let results: FrontendQuestion[] = response.hits; let recursionError = ["metaforecast", "metaforecasts", "metaforecasting"]; if (