feat: refactor commonDisplay and related code
- more typescript - fix https://github.com/QURIresearch/metaforecast-frontend/issues/15 - simplify hasDisplayBeenCaptured code - various cleanups
This commit is contained in:
parent
9714e4cd0a
commit
23a4003f31
|
@ -1,100 +0,0 @@
|
||||||
/* Imports */
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { getFrontpage } from "../backend/frontpage";
|
|
||||||
import CommonDisplay from "../web/display/commonDisplay";
|
|
||||||
import { displayForecastsWrapperForCapture } from "../web/display/displayForecastsWrappers";
|
|
||||||
import { platformsWithLabels } from "../web/platforms.js";
|
|
||||||
import searchAccordingToQueryData from "../web/worker/searchAccordingToQueryData.js";
|
|
||||||
import Layout from "./layout.js";
|
|
||||||
|
|
||||||
/* get Props */
|
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
|
||||||
let urlQuery = context.query; // this is an object, not a string which I have to parse!!
|
|
||||||
|
|
||||||
let initialQueryParameters = {
|
|
||||||
query: "",
|
|
||||||
starsThreshold: 2,
|
|
||||||
numDisplay: 21, // 20
|
|
||||||
forecastsThreshold: 0,
|
|
||||||
forecastingPlatforms: platformsWithLabels, // weird key value format,
|
|
||||||
...urlQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
let frontPageForecasts = await getFrontpage();
|
|
||||||
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
|
||||||
...forecast,
|
|
||||||
item: {
|
|
||||||
...forecast.item,
|
|
||||||
timestamp: forecast.item.timestamp.toJSON(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
let initialResults;
|
|
||||||
switch (initialQueryParameters.query != "") {
|
|
||||||
case true:
|
|
||||||
initialResults = await searchAccordingToQueryData(initialQueryParameters);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
initialResults = frontPageForecasts;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let props = {
|
|
||||||
initialQueryParameters: initialQueryParameters,
|
|
||||||
initialResults: initialResults,
|
|
||||||
defaultResults: frontPageForecasts,
|
|
||||||
urlQuery: urlQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: props,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alternative: getStaticProps
|
|
||||||
export async function getStaticProps() {
|
|
||||||
// get frontPageForecasts somehow.
|
|
||||||
let lastUpdated = calculateLastUpdate(); // metaforecasts.find(forecast => forecast.platform == "Good Judgment Open").timestamp
|
|
||||||
let initialQueryParameters = {
|
|
||||||
query: "",
|
|
||||||
processedUrlYet: false,
|
|
||||||
starsThreshold: 2,
|
|
||||||
numDisplay: 21, // 20
|
|
||||||
forecastsThreshold: 0,
|
|
||||||
forecastingPlatforms: platforms,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
frontPageForecasts,
|
|
||||||
lastUpdated,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Body */
|
|
||||||
export default function Home({
|
|
||||||
initialResults,
|
|
||||||
defaultResults,
|
|
||||||
initialQueryParameters,
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<Layout key="index" page={"capture"}>
|
|
||||||
<CommonDisplay
|
|
||||||
initialResults={initialResults}
|
|
||||||
defaultResults={defaultResults}
|
|
||||||
initialQueryParameters={initialQueryParameters}
|
|
||||||
pageName={"capture"}
|
|
||||||
hasSearchbar={true}
|
|
||||||
hasCapture={true}
|
|
||||||
hasAdvancedOptions={false}
|
|
||||||
placeholder={"Get best title match..."}
|
|
||||||
setHasDisplayBeenCapturedOnChangeSearchInputs={() => false}
|
|
||||||
displaySeeMoreHint={false}
|
|
||||||
displayForecastsWrapper={displayForecastsWrapperForCapture}
|
|
||||||
/>
|
|
||||||
</Layout>
|
|
||||||
);
|
|
||||||
}
|
|
72
src/pages/capture.tsx
Normal file
72
src/pages/capture.tsx
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import { GetServerSideProps } from 'next';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { getFrontpage } from '../backend/frontpage';
|
||||||
|
import CommonDisplay, { QueryParameters } from '../web/display/commonDisplay';
|
||||||
|
import { displayForecastsWrapperForCapture } from '../web/display/displayForecastsWrappers';
|
||||||
|
import { platformsWithLabels } from '../web/platforms';
|
||||||
|
import searchAccordingToQueryData from '../web/worker/searchAccordingToQueryData';
|
||||||
|
import Layout from './layout';
|
||||||
|
|
||||||
|
/* get Props */
|
||||||
|
|
||||||
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
|
let urlQuery = context.query;
|
||||||
|
|
||||||
|
let initialQueryParameters: QueryParameters = {
|
||||||
|
query: "",
|
||||||
|
numDisplay: 21,
|
||||||
|
starsThreshold: 2,
|
||||||
|
forecastsThreshold: 0,
|
||||||
|
forecastingPlatforms: platformsWithLabels, // weird key value format,
|
||||||
|
...urlQuery,
|
||||||
|
};
|
||||||
|
|
||||||
|
let frontPageForecasts = await getFrontpage();
|
||||||
|
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
||||||
|
...forecast,
|
||||||
|
item: {
|
||||||
|
...forecast.item,
|
||||||
|
timestamp: forecast.item.timestamp.toJSON(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
let initialResults =
|
||||||
|
initialQueryParameters.query != ""
|
||||||
|
? await searchAccordingToQueryData(initialQueryParameters)
|
||||||
|
: frontPageForecasts;
|
||||||
|
|
||||||
|
let props = {
|
||||||
|
initialQueryParameters: initialQueryParameters,
|
||||||
|
initialResults: initialResults,
|
||||||
|
defaultResults: frontPageForecasts,
|
||||||
|
urlQuery: urlQuery,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: props,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Body */
|
||||||
|
export default function Home({
|
||||||
|
initialResults,
|
||||||
|
defaultResults,
|
||||||
|
initialQueryParameters,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Layout page={"capture"}>
|
||||||
|
<CommonDisplay
|
||||||
|
initialResults={initialResults}
|
||||||
|
defaultResults={defaultResults}
|
||||||
|
initialQueryParameters={initialQueryParameters}
|
||||||
|
hasSearchbar={true}
|
||||||
|
hasCapture={true}
|
||||||
|
hasAdvancedOptions={false}
|
||||||
|
placeholder={"Get best title match..."}
|
||||||
|
displaySeeMoreHint={false}
|
||||||
|
displayForecastsWrapper={displayForecastsWrapperForCapture}
|
||||||
|
/>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,18 +1,17 @@
|
||||||
/* Imports */
|
import { GetServerSideProps } from 'next';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { getFrontpage } from '../backend/frontpage';
|
import { getFrontpage } from '../backend/frontpage';
|
||||||
import CommonDisplay from '../web/display/commonDisplay';
|
import CommonDisplay from '../web/display/commonDisplay';
|
||||||
import { displayForecastsWrapperForSearch } from '../web/display/displayForecastsWrappers';
|
import { displayForecastsWrapperForSearch } from '../web/display/displayForecastsWrappers';
|
||||||
import { platformsWithLabels } from '../web/platforms.js';
|
import { platformsWithLabels } from '../web/platforms';
|
||||||
import searchAccordingToQueryData from '../web/worker/searchAccordingToQueryData.js';
|
import searchAccordingToQueryData from '../web/worker/searchAccordingToQueryData';
|
||||||
import Layout from './layout.js';
|
import Layout from './layout';
|
||||||
|
|
||||||
/* get Props */
|
/* get Props */
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
let urlQuery = context.query; // this is an object, not a string which I have to parse!!
|
let urlQuery = context.query;
|
||||||
|
|
||||||
let initialQueryParameters = {
|
let initialQueryParameters = {
|
||||||
query: "",
|
query: "",
|
||||||
|
@ -32,37 +31,22 @@ export async function getServerSideProps(context) {
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let initialResults;
|
let initialResults =
|
||||||
let props;
|
|
||||||
switch (
|
|
||||||
!!initialQueryParameters &&
|
!!initialQueryParameters &&
|
||||||
initialQueryParameters.query != "" &&
|
initialQueryParameters.query != "" &&
|
||||||
initialQueryParameters.query != undefined
|
initialQueryParameters.query != undefined
|
||||||
) {
|
? await searchAccordingToQueryData(initialQueryParameters)
|
||||||
case true:
|
: frontPageForecasts;
|
||||||
initialResults = await searchAccordingToQueryData(initialQueryParameters);
|
|
||||||
props = {
|
|
||||||
initialQueryParameters: initialQueryParameters,
|
|
||||||
initialResults: initialResults,
|
|
||||||
defaultResults: frontPageForecasts, // different from initialResults!
|
|
||||||
urlQuery: urlQuery,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
initialResults = frontPageForecasts;
|
|
||||||
props = {
|
|
||||||
initialQueryParameters: initialQueryParameters,
|
|
||||||
initialResults: initialResults,
|
|
||||||
defaultResults: frontPageForecasts, // different from initialResults!
|
|
||||||
urlQuery: urlQuery,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: {
|
||||||
|
initialQueryParameters: initialQueryParameters,
|
||||||
|
initialResults: initialResults,
|
||||||
|
defaultResults: frontPageForecasts, // different from initialResults!
|
||||||
|
urlQuery: urlQuery,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
export default function Home({
|
export default function Home({
|
||||||
|
@ -71,7 +55,7 @@ export default function Home({
|
||||||
initialQueryParameters,
|
initialQueryParameters,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Layout key="index" page={"search"}>
|
<Layout page={"search"}>
|
||||||
<CommonDisplay
|
<CommonDisplay
|
||||||
initialResults={initialResults}
|
initialResults={initialResults}
|
||||||
defaultResults={defaultResults}
|
defaultResults={defaultResults}
|
||||||
|
@ -80,7 +64,6 @@ export default function Home({
|
||||||
hasCapture={false}
|
hasCapture={false}
|
||||||
hasAdvancedOptions={true}
|
hasAdvancedOptions={true}
|
||||||
placeholder={"Find forecasts about..."}
|
placeholder={"Find forecasts about..."}
|
||||||
setHasDisplayBeenCapturedOnChangeSearchInputs={() => null}
|
|
||||||
displaySeeMoreHint={true}
|
displaySeeMoreHint={true}
|
||||||
displayForecastsWrapper={displayForecastsWrapperForSearch}
|
displayForecastsWrapper={displayForecastsWrapperForSearch}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { displayForecast } from '../web/display/displayForecasts.js';
|
import { displayForecast } from '../web/display/displayForecasts.js';
|
||||||
import { platformsWithLabels } from '../web/platforms.js';
|
import { platformsWithLabels } from '../web/platforms';
|
||||||
import searchAccordingToQueryData from '../web/worker/searchAccordingToQueryData';
|
import searchAccordingToQueryData from '../web/worker/searchAccordingToQueryData';
|
||||||
|
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import React, { useState } from "react";
|
import React from 'react';
|
||||||
|
|
||||||
export default function ButtonsForStars({ onChange, value }) {
|
interface Props {
|
||||||
const onChangeInner = (buttonPressed) => {
|
onChange: (x: number) => void;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ButtonsForStars: React.FC<Props> = ({ onChange, value }) => {
|
||||||
|
const onChangeInner = (buttonPressed: number) => {
|
||||||
onChange(buttonPressed);
|
onChange(buttonPressed);
|
||||||
};
|
};
|
||||||
let setStyle = (buttonNumber) =>
|
let setStyle = (buttonNumber: number) =>
|
||||||
`flex row-span-1 col-start-${buttonNumber + 1} col-end-${
|
`flex row-span-1 col-start-${buttonNumber + 1} col-end-${
|
||||||
buttonNumber + 2
|
buttonNumber + 2
|
||||||
} items-center justify-center text-center${
|
} items-center justify-center text-center${
|
||||||
|
@ -31,4 +36,6 @@ export default function ButtonsForStars({ onChange, value }) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default ButtonsForStars;
|
|
@ -1,29 +1,46 @@
|
||||||
/* Imports */
|
|
||||||
|
|
||||||
// React
|
|
||||||
import { useRouter } from 'next/router'; // https://nextjs.org/docs/api-reference/next/router
|
|
||||||
import React, { Fragment, useState } from 'react';
|
import React, { Fragment, useState } from 'react';
|
||||||
|
|
||||||
import { platformNames } from '../platforms.js';
|
import { platformNames, PlatformWithLabel } from '../platforms';
|
||||||
// Data
|
|
||||||
import searchAccordingToQueryData from '../worker/searchAccordingToQueryData';
|
import searchAccordingToQueryData from '../worker/searchAccordingToQueryData';
|
||||||
import ButtonsForStars from './buttonsForStars.js';
|
import ButtonsForStars from './buttonsForStars';
|
||||||
// Parts
|
import Form from './form';
|
||||||
import Form from './form.js';
|
import MultiSelectPlatform from './multiSelectPlatforms';
|
||||||
import MultiSelectPlatform from './multiSelectPlatforms.js';
|
import { SliderElement } from './slider';
|
||||||
import { SliderElement } from './slider.js';
|
|
||||||
|
|
||||||
/* Definitions */
|
export interface QueryParameters {
|
||||||
|
query: string;
|
||||||
|
numDisplay: number;
|
||||||
|
starsThreshold: number;
|
||||||
|
forecastsThreshold: number;
|
||||||
|
forecastingPlatforms: PlatformWithLabel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
initialResults: any;
|
||||||
|
defaultResults: any;
|
||||||
|
initialQueryParameters: QueryParameters;
|
||||||
|
hasSearchbar: boolean;
|
||||||
|
hasCapture: boolean;
|
||||||
|
hasAdvancedOptions: boolean;
|
||||||
|
placeholder: string;
|
||||||
|
displaySeeMoreHint: boolean;
|
||||||
|
displayForecastsWrapper: (opts: {
|
||||||
|
results: any;
|
||||||
|
numDisplay: number;
|
||||||
|
whichResultToDisplayAndCapture: number;
|
||||||
|
showIdToggle: boolean;
|
||||||
|
}) => React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
|
|
||||||
// URL slugs
|
// URL slugs
|
||||||
let transformObjectIntoUrlSlug = (obj) => {
|
let transformObjectIntoUrlSlug = (obj: QueryParameters) => {
|
||||||
let results = [];
|
let results = [];
|
||||||
for (let key in obj) {
|
for (let key in obj) {
|
||||||
if (typeof obj[key] == "number" || typeof obj[key] == "string") {
|
if (typeof obj[key] === "number" || typeof obj[key] === "string") {
|
||||||
results.push(`${key}=${obj[key]}`);
|
results.push(`${key}=${obj[key]}`);
|
||||||
} else if (key == "forecastingPlatforms") {
|
} else if (key === "forecastingPlatforms") {
|
||||||
let arr = obj[key].map((x) => x.value);
|
let arr = obj[key].map((x) => x.value);
|
||||||
let arrstring = arr.join("|");
|
let arrstring = arr.join("|");
|
||||||
results.push(`${key}=${arrstring}`);
|
results.push(`${key}=${arrstring}`);
|
||||||
|
@ -34,7 +51,7 @@ let transformObjectIntoUrlSlug = (obj) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
export default function CommonDisplay({
|
const CommonDisplay: React.FC<Props> = ({
|
||||||
initialResults,
|
initialResults,
|
||||||
defaultResults,
|
defaultResults,
|
||||||
initialQueryParameters,
|
initialQueryParameters,
|
||||||
|
@ -42,12 +59,10 @@ export default function CommonDisplay({
|
||||||
hasCapture,
|
hasCapture,
|
||||||
hasAdvancedOptions,
|
hasAdvancedOptions,
|
||||||
placeholder,
|
placeholder,
|
||||||
setHasDisplayBeenCapturedOnChangeSearchInputs,
|
|
||||||
displaySeeMoreHint,
|
displaySeeMoreHint,
|
||||||
displayForecastsWrapper,
|
displayForecastsWrapper,
|
||||||
}) {
|
}) => {
|
||||||
/* States */
|
/* States */
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const [queryParameters, setQueryParameters] = useState(
|
const [queryParameters, setQueryParameters] = useState(
|
||||||
initialQueryParameters
|
initialQueryParameters
|
||||||
|
@ -62,18 +77,18 @@ export default function CommonDisplay({
|
||||||
);
|
);
|
||||||
const [results, setResults] = useState(initialResults);
|
const [results, setResults] = useState(initialResults);
|
||||||
const [advancedOptions, showAdvancedOptions] = useState(false);
|
const [advancedOptions, showAdvancedOptions] = useState(false);
|
||||||
const [hasDisplayBeenCaptured, setHasDisplayBeenCaptured] = useState(false);
|
|
||||||
const [whichResultToDisplayAndCapture, setWhichResultToDisplayAndCapture] =
|
const [whichResultToDisplayAndCapture, setWhichResultToDisplayAndCapture] =
|
||||||
useState(0);
|
useState(0);
|
||||||
const [showIdToggle, setShowIdToggle] = useState(false);
|
const [showIdToggle, setShowIdToggle] = useState(false);
|
||||||
|
|
||||||
/* Functions which I want to have access to the Home namespace */
|
/* Functions which I want to have access to the Home namespace */
|
||||||
// I don't want to create an "defaultResults" object for each search.
|
// I don't want to create an "defaultResults" object for each search.
|
||||||
async function executeSearchOrAnswerWithDefaultResults(queryData) {
|
async function executeSearchOrAnswerWithDefaultResults(
|
||||||
console.log("executeSearchOrAnswerWithDefaultResults");
|
queryData: QueryParameters
|
||||||
|
) {
|
||||||
// the queryData object has the same contents as queryParameters.
|
// the queryData object has the same contents as queryParameters.
|
||||||
// but I wanted to spare myself having to think about namespace conflicts.
|
// but I wanted to spare myself having to think about namespace conflicts.
|
||||||
let filterManually = (queryData, results) => {
|
let filterManually = (queryData: QueryParameters, results) => {
|
||||||
if (
|
if (
|
||||||
queryData.forecastingPlatforms &&
|
queryData.forecastingPlatforms &&
|
||||||
queryData.forecastingPlatforms.length > 0
|
queryData.forecastingPlatforms.length > 0
|
||||||
|
@ -85,7 +100,7 @@ export default function CommonDisplay({
|
||||||
forecastingPlatforms.includes(result.item.platform)
|
forecastingPlatforms.includes(result.item.platform)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (queryData.starsThreshold == 4) {
|
if (queryData.starsThreshold === 4) {
|
||||||
results = results.filter(
|
results = results.filter(
|
||||||
(result) => result.item.qualityindicators.stars >= 4
|
(result) => result.item.qualityindicators.stars >= 4
|
||||||
);
|
);
|
||||||
|
@ -96,76 +111,44 @@ export default function CommonDisplay({
|
||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
let results;
|
const queryIsEmpty =
|
||||||
switch (
|
!queryData || queryData.query == "" || queryData.query == undefined;
|
||||||
!queryData ||
|
|
||||||
queryData.query == "" ||
|
let results = queryIsEmpty
|
||||||
queryData.query == undefined
|
? filterManually(queryData, defaultResults || initialResults)
|
||||||
) {
|
: await searchAccordingToQueryData(queryData);
|
||||||
case true:
|
|
||||||
console.log(1);
|
setResults(results);
|
||||||
results = filterManually(queryData, defaultResults || initialResults);
|
|
||||||
break;
|
|
||||||
case false:
|
|
||||||
console.log(2);
|
|
||||||
results = await searchAccordingToQueryData(queryData);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log(3);
|
|
||||||
console.log("This should not be happening");
|
|
||||||
results = [];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
console.log("executeSearchOrAnswerWithDefaultResults/queryData", queryData);
|
|
||||||
console.log("defaultResults", defaultResults);
|
|
||||||
console.log("initialResults", initialResults);
|
|
||||||
console.log(results);
|
|
||||||
setResults(results); // just double check
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// I don't want the function which dispaly 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.
|
// 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.
|
||||||
let getInfoToDisplayForecastsFunction = (
|
let getInfoToDisplayForecastsFunction = ({
|
||||||
displayForecastsFunction,
|
results,
|
||||||
{
|
whichResultToDisplayAndCapture,
|
||||||
results,
|
showIdToggle,
|
||||||
hasDisplayBeenCaptured,
|
}) => {
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
whichResultToDisplayAndCapture,
|
|
||||||
showIdToggle,
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
let numDisplayRounded =
|
let numDisplayRounded =
|
||||||
queryParameters.numDisplay % 3 != 0
|
queryParameters.numDisplay % 3 != 0
|
||||||
? queryParameters.numDisplay +
|
? queryParameters.numDisplay +
|
||||||
(3 - (Math.round(queryParameters.numDisplay) % 3))
|
(3 - (Math.round(queryParameters.numDisplay) % 3))
|
||||||
: queryParameters.numDisplay;
|
: queryParameters.numDisplay;
|
||||||
console.log("numDisplay", queryParameters.numDisplay);
|
return displayForecastsWrapper({
|
||||||
console.log("numDisplayRounded", numDisplayRounded);
|
|
||||||
return displayForecastsFunction({
|
|
||||||
results,
|
results,
|
||||||
numDisplay: numDisplayRounded,
|
numDisplay: numDisplayRounded,
|
||||||
hasDisplayBeenCaptured,
|
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
whichResultToDisplayAndCapture,
|
whichResultToDisplayAndCapture,
|
||||||
showIdToggle,
|
showIdToggle,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* State controllers */
|
/* State controllers */
|
||||||
let onChangeSearchInputs = (newQueryParameters) => {
|
let onChangeSearchInputs = (newQueryParameters: QueryParameters) => {
|
||||||
setQueryParameters(newQueryParameters); // ({ ...newQueryParameters, processedUrlYet: true });
|
setQueryParameters(newQueryParameters); // ({ ...newQueryParameters, processedUrlYet: true });
|
||||||
console.log("onChangeSearchInputs/newQueryParameters", newQueryParameters);
|
|
||||||
setResults([]);
|
setResults([]);
|
||||||
setHasDisplayBeenCaptured(setHasDisplayBeenCapturedOnChangeSearchInputs());
|
|
||||||
clearTimeout(searchSpeedSettings.timeoutId);
|
clearTimeout(searchSpeedSettings.timeoutId);
|
||||||
let newtimeoutId = setTimeout(async () => {
|
let newtimeoutId = setTimeout(async () => {
|
||||||
console.log(
|
|
||||||
"onChangeSearchInputs/timeout/newQueryParameters",
|
|
||||||
newQueryParameters
|
|
||||||
);
|
|
||||||
let urlSlug = transformObjectIntoUrlSlug(newQueryParameters);
|
let urlSlug = transformObjectIntoUrlSlug(newQueryParameters);
|
||||||
let urlWithoutDefaultParameters = urlSlug
|
let urlWithoutDefaultParameters = urlSlug
|
||||||
.replace("?query=&", "&")
|
.replace("?query=&", "?")
|
||||||
.replace("&starsThreshold=2", "")
|
.replace("&starsThreshold=2", "")
|
||||||
.replace("&numDisplay=21", "")
|
.replace("&numDisplay=21", "")
|
||||||
.replace("&forecastsThreshold=0", "")
|
.replace("&forecastsThreshold=0", "")
|
||||||
|
@ -180,7 +163,6 @@ export default function CommonDisplay({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// router.push(urlWithoutDefaultParameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
executeSearchOrAnswerWithDefaultResults(newQueryParameters);
|
executeSearchOrAnswerWithDefaultResults(newQueryParameters);
|
||||||
|
@ -191,9 +173,11 @@ export default function CommonDisplay({
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Change the stars threshold */
|
/* Change the stars threshold */
|
||||||
let onChangeStars = (value) => {
|
let onChangeStars = (value: number) => {
|
||||||
console.log("onChangeStars/buttons", value);
|
let newQueryParameters: QueryParameters = {
|
||||||
let newQueryParameters = { ...queryParameters, starsThreshold: value };
|
...queryParameters,
|
||||||
|
starsThreshold: value,
|
||||||
|
};
|
||||||
onChangeSearchInputs(newQueryParameters);
|
onChangeSearchInputs(newQueryParameters);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,8 +188,7 @@ export default function CommonDisplay({
|
||||||
: "Show " + Math.round(value) + " result";
|
: "Show " + Math.round(value) + " result";
|
||||||
};
|
};
|
||||||
let onChangeSliderForNumDisplay = (event) => {
|
let onChangeSliderForNumDisplay = (event) => {
|
||||||
console.log("onChangeSliderForNumDisplay", event[0]);
|
let newQueryParameters: QueryParameters = {
|
||||||
let newQueryParameters = {
|
|
||||||
...queryParameters,
|
...queryParameters,
|
||||||
numDisplay: Math.round(event[0]),
|
numDisplay: Math.round(event[0]),
|
||||||
};
|
};
|
||||||
|
@ -213,11 +196,10 @@ export default function CommonDisplay({
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Change the forecast threshold */
|
/* Change the forecast threshold */
|
||||||
let displayFunctionNumForecasts = (value) => {
|
let displayFunctionNumForecasts = (value: number) => {
|
||||||
return "# Forecasts > " + Math.round(value);
|
return "# Forecasts > " + Math.round(value);
|
||||||
};
|
};
|
||||||
let onChangeSliderForNumForecasts = (event) => {
|
let onChangeSliderForNumForecasts = (event) => {
|
||||||
console.log("onChangeSliderForNumForecasts", event[0]);
|
|
||||||
let newQueryParameters = {
|
let newQueryParameters = {
|
||||||
...queryParameters,
|
...queryParameters,
|
||||||
forecastsThreshold: Math.round(event[0]),
|
forecastsThreshold: Math.round(event[0]),
|
||||||
|
@ -226,15 +208,13 @@ export default function CommonDisplay({
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Change on the search bar */
|
/* Change on the search bar */
|
||||||
let onChangeSearchBar = (value) => {
|
let onChangeSearchBar = (value: string) => {
|
||||||
console.log("onChangeSearchBar/New query:", value);
|
|
||||||
let newQueryParameters = { ...queryParameters, query: value };
|
let newQueryParameters = { ...queryParameters, query: value };
|
||||||
onChangeSearchInputs(newQueryParameters);
|
onChangeSearchInputs(newQueryParameters);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*Change selected platforms */
|
/* Change selected platforms */
|
||||||
let onChangeSelectedPlatforms = (value) => {
|
let onChangeSelectedPlatforms = (value) => {
|
||||||
console.log("onChangeSelectedPlatforms/Change in platforms:", value);
|
|
||||||
let newQueryParameters = {
|
let newQueryParameters = {
|
||||||
...queryParameters,
|
...queryParameters,
|
||||||
forecastingPlatforms: value,
|
forecastingPlatforms: value,
|
||||||
|
@ -249,177 +229,145 @@ export default function CommonDisplay({
|
||||||
|
|
||||||
// Capture functionality
|
// Capture functionality
|
||||||
let onClickBack = () => {
|
let onClickBack = () => {
|
||||||
let decreaseUntil0 = (num) => (num - 1 > 0 ? num - 1 : 0);
|
let decreaseUntil0 = (num: number) => (num - 1 > 0 ? num - 1 : 0);
|
||||||
setWhichResultToDisplayAndCapture(
|
setWhichResultToDisplayAndCapture(
|
||||||
decreaseUntil0(whichResultToDisplayAndCapture)
|
decreaseUntil0(whichResultToDisplayAndCapture)
|
||||||
);
|
);
|
||||||
setHasDisplayBeenCaptured(false);
|
|
||||||
};
|
};
|
||||||
let onClickForward = (whichResultToDisplayAndCapture) => {
|
let onClickForward = (whichResultToDisplayAndCapture: number) => {
|
||||||
setWhichResultToDisplayAndCapture(whichResultToDisplayAndCapture + 1);
|
setWhichResultToDisplayAndCapture(whichResultToDisplayAndCapture + 1);
|
||||||
setHasDisplayBeenCaptured(false);
|
|
||||||
// setTimeout(()=> {onClickForward(whichResultToDisplayAndCapture+1)}, 5000)
|
// setTimeout(()=> {onClickForward(whichResultToDisplayAndCapture+1)}, 5000)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Final return */
|
/* Final return */
|
||||||
return (
|
return (
|
||||||
<Fragment key="index">
|
<Fragment>
|
||||||
<label
|
<label className="mb-4 mt-4 flex flex-row justify-center items-center">
|
||||||
className="mb-4 mt-4 flex flex-row justify-center items-center"
|
{hasSearchbar ? (
|
||||||
key={"common-1"}
|
<div className="w-10/12 mb-2">
|
||||||
>
|
<Form
|
||||||
<div
|
value={queryParameters.query}
|
||||||
className={`w-10/12 mb-2 ${hasSearchbar ? "" : "hidden"}`}
|
onChange={onChangeSearchBar}
|
||||||
key={"common-1-1"}
|
placeholder={placeholder}
|
||||||
>
|
/>
|
||||||
<Form
|
</div>
|
||||||
value={queryParameters.query}
|
) : null}
|
||||||
onChange={onChangeSearchBar}
|
|
||||||
placeholder={placeholder}
|
{hasAdvancedOptions ? (
|
||||||
/>
|
<div className="w-2/12 flex justify-center ml-4 md:ml-2 lg:ml-0">
|
||||||
</div>
|
<button
|
||||||
<div
|
className="text-gray-500 text-sm mb-2"
|
||||||
className={`w-2/12 flex justify-center ml-4 md:ml-2 lg:ml-0 ${
|
onClick={() => showAdvancedOptions(!advancedOptions)}
|
||||||
hasAdvancedOptions ? "" : "hidden"
|
>
|
||||||
}`}
|
Advanced options ▼
|
||||||
key={"common-1-2"}
|
</button>
|
||||||
>
|
</div>
|
||||||
<button
|
) : null}
|
||||||
className="text-gray-500 text-sm mb-2"
|
|
||||||
onClick={() => showAdvancedOptions(!advancedOptions)}
|
{hasCapture ? (
|
||||||
>
|
<div className="w-2/12 flex justify-center ml-4 md:ml-2 gap-1 lg:ml-0">
|
||||||
Advanced options ▼
|
<button
|
||||||
</button>
|
className="text-blue-500 cursor-pointer text-xl mb-3 pr-3 hover:text-blue-600"
|
||||||
</div>
|
onClick={() => onClickBack()}
|
||||||
<div
|
>
|
||||||
className={`w-2/12 flex justify-center ml-4 md:ml-2 gap-1 lg:ml-0 ${
|
◀
|
||||||
hasCapture ? "" : "hidden"
|
</button>
|
||||||
}`}
|
<button
|
||||||
key={"common-1-3"}
|
className="text-blue-500 cursor-pointer text-xl mb-3 pl-3 hover:text-blue-600"
|
||||||
>
|
onClick={() => onClickForward(whichResultToDisplayAndCapture)}
|
||||||
<button
|
>
|
||||||
className="text-blue-500 cursor-pointer text-xl mb-3 pr-3 hover:text-blue-600"
|
▶
|
||||||
onClick={() => onClickBack()}
|
</button>
|
||||||
key={"common-1-3-1"}
|
</div>
|
||||||
>
|
) : null}
|
||||||
◀
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="text-blue-500 cursor-pointer text-xl mb-3 pl-3 hover:text-blue-600"
|
|
||||||
onClick={() => onClickForward(whichResultToDisplayAndCapture)}
|
|
||||||
key={"common-1-3-2"}
|
|
||||||
>
|
|
||||||
▶
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div
|
{hasAdvancedOptions && advancedOptions ? (
|
||||||
className={`flex-1 flex-col mx-auto justify-center items-center w-full ${
|
<div className="flex-1 flex-col mx-auto justify-center items-center w-full">
|
||||||
hasAdvancedOptions && advancedOptions ? "" : "hidden"
|
<div className="grid sm:grid-rows-4 sm:grid-cols-1 md:grid-rows-2 lg:grid-rows-2 grid-cols-1 md:grid-cols-3 lg:grid-cols-3 items-center content-center bg-gray-50 rounded-md px-8 pt-4 pb-1 shadow mb-4">
|
||||||
}`}
|
<div className="flex row-start-1 row-end-1 col-start-1 col-end-4 md:row-span-1 md:col-start-1 md:col-end-1 md:row-start-1 md:row-end-1 lg:row-span-1 lg:col-start-1 lg:col-end-1 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4">
|
||||||
key={"common-2"}
|
<SliderElement
|
||||||
>
|
onChange={onChangeSliderForNumForecasts}
|
||||||
<div
|
value={queryParameters.forecastsThreshold}
|
||||||
className="grid sm:grid-rows-4 sm:grid-cols-1 md:grid-rows-2 lg:grid-rows-2 grid-cols-1 md:grid-cols-3 lg:grid-cols-3 items-center content-center bg-gray-50 rounded-md px-8 pt-4 pb-1 shadow mb-4"
|
displayFunction={displayFunctionNumForecasts}
|
||||||
key={"common-2-1"}
|
/>
|
||||||
>
|
</div>
|
||||||
<div
|
<div className="flex row-start-2 row-end-2 col-start-1 col-end-4 md:row-start-1 md:row-end-1 md:col-start-2 md:col-end-2 lg:row-start-1 lg:row-end-1 lg:col-start-2 items-center justify-center mb-4">
|
||||||
className="flex row-start-1 row-end-1 col-start-1 col-end-4 md:row-span-1 md:col-start-1 md:col-end-1 md:row-start-1 md:row-end-1 lg:row-span-1 lg:col-start-1 lg:col-end-1 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4"
|
<ButtonsForStars
|
||||||
key={"common-2-1-1"}
|
onChange={onChangeStars}
|
||||||
>
|
value={queryParameters.starsThreshold}
|
||||||
<SliderElement
|
/>
|
||||||
onChange={onChangeSliderForNumForecasts}
|
</div>
|
||||||
value={queryParameters.forecastsThreshold}
|
<div className="flex row-start-3 row-end-3 col-start-1 col-end-4 md:col-start-3 md:col-end-3 md:row-start-1 md:row-end-1 lg:col-start-3 lg:col-end-3 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4">
|
||||||
displayFunction={displayFunctionNumForecasts}
|
<SliderElement
|
||||||
key={"common-2-1-1-1"}
|
value={queryParameters.numDisplay}
|
||||||
/>
|
onChange={onChangeSliderForNumDisplay}
|
||||||
|
displayFunction={displayFunctionNumDisplaySlider}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex col-span-3 items-center justify-center">
|
||||||
|
<MultiSelectPlatform
|
||||||
|
value={queryParameters.forecastingPlatforms}
|
||||||
|
onChange={onChangeSelectedPlatforms}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="block col-start-1 col-end-4 md:col-start-2 md:col-end-3 md:row-start-4 md:row-end-4 lg:col-start-2 lg:col-end-3 lg:row-start-4 lg:row-end-4 bg-transparent hover:bg-blue-300 text-blue-400 hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded mt-5 p-10 text-center mb-2 mr-10 ml-10 items-center justify-center"
|
||||||
|
onClick={onChangeShowId}
|
||||||
|
>
|
||||||
|
Toggle show id
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
className="flex row-start-2 row-end-2 col-start-1 col-end-4 md:row-start-1 md:row-end-1 md:col-start-2 md:col-end-2 lg:row-start-1 lg:row-end-1 lg:col-start-2 md:col-end-2 items-center justify-center mb-4"
|
|
||||||
key={"common-2-1-2"}
|
|
||||||
>
|
|
||||||
<ButtonsForStars
|
|
||||||
onChange={onChangeStars}
|
|
||||||
value={queryParameters.starsThreshold}
|
|
||||||
key={"common-2-1-2-1"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="flex row-start-3 row-end-3 col-start-1 col-end-4 md:col-start-3 md:col-end-3 md:row-start-1 md:row-end-1 lg:col-start-3 lg:col-end-3 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4"
|
|
||||||
key={"common-2-1-3"}
|
|
||||||
>
|
|
||||||
<SliderElement
|
|
||||||
value={queryParameters.numDisplay}
|
|
||||||
onChange={onChangeSliderForNumDisplay}
|
|
||||||
displayFunction={displayFunctionNumDisplaySlider}
|
|
||||||
key={"common-2-1-3-1"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="flex col-span-3 items-center justify-center"
|
|
||||||
key={"common-2-1-4"}
|
|
||||||
>
|
|
||||||
<MultiSelectPlatform
|
|
||||||
value={queryParameters.forecastingPlatforms}
|
|
||||||
onChange={onChangeSelectedPlatforms}
|
|
||||||
key={"common-2-1-4-1"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
className="block col-start-1 col-end-4 md:col-start-2 md:col-end-3 md:row-start-4 md:row-end-4 lg:col-start-2 lg:col-end-3 lg:row-start-4 lg:row-end-4 bg-transparent hover:bg-blue-300 text-blue-400 hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded mt-5 p-10 text-center mb-2 mr-10 ml-10 items-center justify-center"
|
|
||||||
onClick={onChangeShowId}
|
|
||||||
>
|
|
||||||
Toggle show id
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : null}
|
||||||
|
|
||||||
<div key={"common-3"}>
|
<div>
|
||||||
{getInfoToDisplayForecastsFunction(displayForecastsWrapper, {
|
{getInfoToDisplayForecastsFunction({
|
||||||
results,
|
results,
|
||||||
hasDisplayBeenCaptured,
|
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
whichResultToDisplayAndCapture,
|
whichResultToDisplayAndCapture,
|
||||||
showIdToggle,
|
showIdToggle,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className={`${displaySeeMoreHint ? "" : "hidden"}`} key={"common-4"}>
|
|
||||||
<p
|
{displaySeeMoreHint ? (
|
||||||
className={`mt-4 mb-4 ${
|
<div>
|
||||||
!results ||
|
<p
|
||||||
(results.length != 0 && queryParameters.numDisplay < results.length)
|
className={`mt-4 mb-4 ${
|
||||||
? ""
|
!results ||
|
||||||
: "hidden"
|
(results.length != 0 &&
|
||||||
}`}
|
queryParameters.numDisplay < results.length)
|
||||||
key={"common-4-1"}
|
? ""
|
||||||
>
|
: "hidden"
|
||||||
{"Can't find what you were looking for?"}
|
|
||||||
<span
|
|
||||||
className={`cursor-pointer text-blue-800 ${
|
|
||||||
!results ? "hidden" : ""
|
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
|
||||||
setQueryParameters({
|
|
||||||
...queryParameters,
|
|
||||||
numDisplay: queryParameters.numDisplay * 2,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
key={"common-4-1-1"}
|
|
||||||
>
|
>
|
||||||
{" Show more, or"}
|
{"Can't find what you were looking for?"}
|
||||||
</span>{" "}
|
<span
|
||||||
<a
|
className={`cursor-pointer text-blue-800 ${
|
||||||
href="https://www.metaculus.com/questions/create/"
|
!results ? "hidden" : ""
|
||||||
className="cursor-pointer text-blue-800 no-underline"
|
}`}
|
||||||
target="_blank"
|
onClick={() => {
|
||||||
key={"common-4-1-2"}
|
setQueryParameters({
|
||||||
>
|
...queryParameters,
|
||||||
suggest a question on Metaculus
|
numDisplay: queryParameters.numDisplay * 2,
|
||||||
</a>
|
});
|
||||||
</p>
|
}}
|
||||||
</div>
|
>
|
||||||
|
{" Show more, or"}
|
||||||
|
</span>{" "}
|
||||||
|
<a
|
||||||
|
href="https://www.metaculus.com/questions/create/"
|
||||||
|
className="cursor-pointer text-blue-800 no-underline"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
suggest a question on Metaculus
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default CommonDisplay;
|
||||||
|
|
|
@ -15,22 +15,12 @@ export function displayForecastsWrapperForSearch({
|
||||||
|
|
||||||
export function displayForecastsWrapperForCapture({
|
export function displayForecastsWrapperForCapture({
|
||||||
results,
|
results,
|
||||||
hasDisplayBeenCaptured,
|
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
whichResultToDisplayAndCapture,
|
whichResultToDisplayAndCapture,
|
||||||
}) {
|
}) {
|
||||||
console.log({
|
|
||||||
results,
|
|
||||||
hasDisplayBeenCaptured,
|
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
whichResultToDisplayAndCapture,
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 w-full justify-center">
|
<div className="grid grid-cols-1 w-full justify-center">
|
||||||
{displayOneForecast({
|
{displayOneForecast({
|
||||||
result: results[whichResultToDisplayAndCapture],
|
result: results[whichResultToDisplayAndCapture],
|
||||||
hasDisplayBeenCaptured,
|
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import domtoimage from "dom-to-image"; // https://github.com/tsayen/dom-to-image
|
import domtoimage from 'dom-to-image'; // https://github.com/tsayen/dom-to-image
|
||||||
import { useRef, useState } from "react";
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
import { uploadToImgur } from "../worker/uploadToImgur";
|
|
||||||
import { displayForecast } from "./displayForecasts.js";
|
|
||||||
|
|
||||||
function displayOneForecastInner(result, containerRef, onLoadCallback) {
|
import { uploadToImgur } from '../worker/uploadToImgur';
|
||||||
|
import { displayForecast } from './displayForecasts.js';
|
||||||
|
|
||||||
|
function displayOneForecastInner(result, containerRef) {
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef}>
|
<div ref={containerRef}>
|
||||||
{result
|
{result
|
||||||
|
@ -21,7 +22,6 @@ function displayOneForecastInner(result, containerRef, onLoadCallback) {
|
||||||
|
|
||||||
let domToImageWrapper = (reactRef) => {
|
let domToImageWrapper = (reactRef) => {
|
||||||
let node = reactRef.current;
|
let node = reactRef.current;
|
||||||
console.log(node);
|
|
||||||
const scale = 3; // Increase for better quality
|
const scale = 3; // Increase for better quality
|
||||||
const style = {
|
const style = {
|
||||||
transform: "scale(" + scale + ")",
|
transform: "scale(" + scale + ")",
|
||||||
|
@ -36,7 +36,6 @@ let domToImageWrapper = (reactRef) => {
|
||||||
style,
|
style,
|
||||||
};
|
};
|
||||||
let image = domtoimage.toPng(node, param);
|
let image = domtoimage.toPng(node, param);
|
||||||
console.log(image);
|
|
||||||
return image;
|
return image;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,18 +102,17 @@ let generateIframeURL = (result) => {
|
||||||
let iframeURL = "";
|
let iframeURL = "";
|
||||||
if (result) {
|
if (result) {
|
||||||
// if check not strictly necessary today
|
// if check not strictly necessary today
|
||||||
iframeURL = result.item.url
|
let parts = result.item.url
|
||||||
.replace("questions", "questions/embed")
|
.replace("questions", "questions/embed")
|
||||||
.split("/");
|
.split("/");
|
||||||
iframeURL.pop();
|
parts.pop();
|
||||||
iframeURL.pop();
|
parts.pop();
|
||||||
iframeURL = iframeURL.join("/");
|
iframeURL = parts.join("/");
|
||||||
}
|
}
|
||||||
return iframeURL;
|
return iframeURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
let metaculusEmbed = (result) => {
|
let metaculusEmbed = (result) => {
|
||||||
//console.log(item.url)
|
|
||||||
let platform = "";
|
let platform = "";
|
||||||
let iframeURL = "";
|
let iframeURL = "";
|
||||||
if (result) {
|
if (result) {
|
||||||
|
@ -171,20 +169,24 @@ let generateMetaculusSource = (result, hasDisplayBeenCaptured) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function displayOneForecast({
|
interface Props {
|
||||||
result,
|
result: any;
|
||||||
hasDisplayBeenCaptured,
|
}
|
||||||
setHasDisplayBeenCaptured,
|
|
||||||
}) {
|
const DisplayOneForecast: React.FC<Props> = ({ result }) => {
|
||||||
|
const [hasDisplayBeenCaptured, setHasDisplayBeenCaptured] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHasDisplayBeenCaptured(false);
|
||||||
|
}, [result]);
|
||||||
|
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const [imgSrc, setImgSrc] = useState("");
|
const [imgSrc, setImgSrc] = useState("");
|
||||||
const [mainButtonStatus, setMainButtonStatus] = useState(
|
const [mainButtonStatus, setMainButtonStatus] = useState(
|
||||||
"Capture image and generate code"
|
"Capture image and generate code"
|
||||||
);
|
);
|
||||||
const [clickedAlreadyBool, setClickAlreadyBool] = useState(false);
|
|
||||||
|
|
||||||
let exportAsPictureAndCode = () => {
|
let exportAsPictureAndCode = () => {
|
||||||
console.log(containerRef.current);
|
|
||||||
let handleGettingImgurlImage = (imgurUrl) => {
|
let handleGettingImgurlImage = (imgurUrl) => {
|
||||||
setImgSrc(imgurUrl);
|
setImgSrc(imgurUrl);
|
||||||
setMainButtonStatus("Done!");
|
setMainButtonStatus("Done!");
|
||||||
|
@ -215,7 +217,7 @@ export default function displayOneForecast({
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={() => onCaptureButtonClick()}
|
onClick={() => onCaptureButtonClick()}
|
||||||
className="bg-blue-500 cursor-pointer px-5 py-4 bg-white rounded-md shadow text-white hover:bg-blue-600 active:bg-gray-700"
|
className="bg-blue-500 cursor-pointer px-5 py-4 rounded-md shadow text-white hover:bg-blue-600 active:bg-gray-700"
|
||||||
>
|
>
|
||||||
{mainButtonStatus}
|
{mainButtonStatus}
|
||||||
</button>
|
</button>
|
||||||
|
@ -232,10 +234,7 @@ export default function displayOneForecast({
|
||||||
{generateCaptureButton(result, onCaptureButtonClick)}
|
{generateCaptureButton(result, onCaptureButtonClick)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex col-span-1 items-center justify-center">
|
<div className="flex col-span-1 items-center justify-center">
|
||||||
<img
|
<img src={imgSrc} className={hasDisplayBeenCaptured ? "" : "hidden"} />
|
||||||
src={imgSrc}
|
|
||||||
className={hasDisplayBeenCaptured ? "" : "hidden"}
|
|
||||||
></img>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex col-span-1 items-center justify-center">
|
<div className="flex col-span-1 items-center justify-center">
|
||||||
<div>{generateSource(result, imgSrc, hasDisplayBeenCaptured)}</div>
|
<div>{generateSource(result, imgSrc, hasDisplayBeenCaptured)}</div>
|
||||||
|
@ -249,7 +248,9 @@ export default function displayOneForecast({
|
||||||
<br></br>
|
<br></br>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default DisplayOneForecast;
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/39501289/in-reactjs-how-to-copy-text-to-clipboard
|
// https://stackoverflow.com/questions/39501289/in-reactjs-how-to-copy-text-to-clipboard
|
||||||
// Note: https://stackoverflow.com/questions/66016033/can-no-longer-upload-images-to-imgur-from-localhost
|
// Note: https://stackoverflow.com/questions/66016033/can-no-longer-upload-images-to-imgur-from-localhost
|
|
@ -1,7 +1,7 @@
|
||||||
import chroma from "chroma-js";
|
import chroma from "chroma-js";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
import { platformsWithLabels } from "../platforms.js";
|
import { platformsWithLabels } from "../platforms";
|
||||||
|
|
||||||
const colourStyles = {
|
const colourStyles = {
|
||||||
control: (styles) => ({ ...styles, backgroundColor: "white" }),
|
control: (styles) => ({ ...styles, backgroundColor: "white" }),
|
||||||
|
|
|
@ -42,11 +42,19 @@ export const platformNames = [
|
||||||
"X-risk estimates",
|
"X-risk estimates",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const platformsWithLabels = platformNames.map((name, i) => ({
|
export interface PlatformWithLabel {
|
||||||
value: name,
|
value: string;
|
||||||
label: name,
|
label: string;
|
||||||
color: distinctColors[i],
|
color: string;
|
||||||
}));
|
}
|
||||||
|
|
||||||
|
export const platformsWithLabels: PlatformWithLabel[] = platformNames.map(
|
||||||
|
(name, i) => ({
|
||||||
|
value: name,
|
||||||
|
label: name,
|
||||||
|
color: distinctColors[i],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
export const platforms = platformsWithLabels;
|
export const platforms = platformsWithLabels;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user