Compare commits
14 Commits
543ea966af
...
5fc9930265
Author | SHA1 | Date | |
---|---|---|---|
5fc9930265 | |||
685414e8fb | |||
fe4bba5169 | |||
e9796c545d | |||
fc84300712 | |||
73329df47b | |||
dc1e75d99d | |||
0a7d2d160a | |||
67e4b825db | |||
dfe1de5279 | |||
38a2fe8215 | |||
8ccb88558f | |||
31bfb357b3 | |||
611d553193 |
11
package.json
11
package.json
|
@ -28,12 +28,12 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react-dom": "^0.7.2",
|
"@floating-ui/react-dom": "^0.7.2",
|
||||||
"@graphql-yoga/node": "^2.13.13",
|
"@graphql-yoga/plugin-response-cache": "^1.1.0",
|
||||||
"@pothos/core": "^3.22.8",
|
"@pothos/core": "^3.22.8",
|
||||||
"@pothos/plugin-prisma": "^3.35.6",
|
"@pothos/plugin-prisma": "^3.35.6",
|
||||||
"@pothos/plugin-relay": "^3.28.6",
|
"@pothos/plugin-relay": "^3.28.6",
|
||||||
"@prisma/client": "^3.15.2",
|
"@prisma/client": "^3.15.2",
|
||||||
"@quri/squiggle-lang": "^0.2.12",
|
"@quri/squiggle-lang": "^0.5.1",
|
||||||
"@tailwindcss/forms": "^0.4.1",
|
"@tailwindcss/forms": "^0.4.1",
|
||||||
"@tailwindcss/typography": "^0.5.7",
|
"@tailwindcss/typography": "^0.5.7",
|
||||||
"@types/chroma-js": "^2.1.4",
|
"@types/chroma-js": "^2.1.4",
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
"ajv": "^8.11.0",
|
"ajv": "^8.11.0",
|
||||||
"algoliasearch": "^4.14.2",
|
"algoliasearch": "^4.14.2",
|
||||||
"autoprefixer": "10.4.5",
|
"autoprefixer": "10.4.5",
|
||||||
"axios": "^0.25.0",
|
"axios": "^1.2.0",
|
||||||
"chroma-js": "^2.4.2",
|
"chroma-js": "^2.4.2",
|
||||||
"critters": "^0.0.16",
|
"critters": "^0.0.16",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
|
@ -60,7 +60,8 @@
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"google-spreadsheet": "^3.3.0",
|
"google-spreadsheet": "^3.3.0",
|
||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"graphql-request": "^4.3.0",
|
"graphql-request": "^5.0.0",
|
||||||
|
"graphql-yoga": "^3.0.0-next.10",
|
||||||
"html-to-image": "^1.10.8",
|
"html-to-image": "^1.10.8",
|
||||||
"https": "^1.0.0",
|
"https": "^1.0.0",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
|
@ -117,6 +118,6 @@
|
||||||
"@types/pg": "^8.6.5",
|
"@types/pg": "^8.6.5",
|
||||||
"eslint": "^8.25.0",
|
"eslint": "^8.25.0",
|
||||||
"eslint-config-next": "^12.3.1",
|
"eslint-config-next": "^12.3.1",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,8 @@ function processPredictions(predictions: any[]): FetchedQuestion[] {
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
createdTime: prediction.createdTime,
|
createdTime: prediction.createdTime,
|
||||||
volume7Days: prediction.volume7Days,
|
// volume7Days: prediction.volume7Days, // deprecated.
|
||||||
volume24Hours: prediction.volume24Hours,
|
volume24Hours: prediction.volume24Hours,
|
||||||
pool: prediction.pool, // normally liquidity, but I don't actually want to show it.
|
pool: prediction.pool, // normally liquidity, but I don't actually want to show it.
|
||||||
},
|
},
|
||||||
extra: {
|
extra: {
|
||||||
|
@ -122,9 +122,9 @@ export const manifold: Platform = {
|
||||||
},
|
},
|
||||||
calculateStars(data) {
|
calculateStars(data) {
|
||||||
let nuno = () =>
|
let nuno = () =>
|
||||||
(data.qualityindicators.volume7Days || 0) > 250 ||
|
(data.qualityindicators.volume24Hours || 0) > 100 ||
|
||||||
((data.qualityindicators.pool || 0) > 500 &&
|
((data.qualityindicators.pool || 0) > 500 &&
|
||||||
(data.qualityindicators.volume7Days || 0) > 100)
|
(data.qualityindicators.volume24Hours || 0) > 50)
|
||||||
? 2
|
? 2
|
||||||
: 1;
|
: 1;
|
||||||
let eli = () => null;
|
let eli = () => null;
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
import {NextApiRequest, NextApiResponse} from "next";
|
||||||
|
|
||||||
// apollo-server-micro is problematic since v3, see https://github.com/apollographql/apollo-server/issues/5547, so we use graphql-yoga instead
|
// apollo-server-micro is problematic since v3, see https://github.com/apollographql/apollo-server/issues/5547, so we use graphql-yoga instead
|
||||||
import { createServer } from "@graphql-yoga/node";
|
import {createYoga} from "graphql-yoga";
|
||||||
|
import {useResponseCache} from '@graphql-yoga/plugin-response-cache'
|
||||||
|
|
||||||
import { schema } from "../../graphql/schema";
|
import {schema} from "../../graphql/schema";
|
||||||
|
|
||||||
const server = createServer<{
|
const server = createYoga < {
|
||||||
req: NextApiRequest;
|
req: NextApiRequest;
|
||||||
res: NextApiResponse;
|
res: NextApiResponse;
|
||||||
}>({ schema });
|
} > ({
|
||||||
|
schema,
|
||||||
|
graphqlEndpoint: '/api/graphql',
|
||||||
|
plugins: [useResponseCache(
|
||||||
|
{ // global cache
|
||||||
|
session: () => null,
|
||||||
|
ttl: 2 * 60 * 60 * 1000,
|
||||||
|
// ^ 2h * 60 mins per hour, 60 seconds per min 1000 miliseconds per second
|
||||||
|
}
|
||||||
|
)]
|
||||||
|
});
|
||||||
|
|
||||||
export default server;
|
export default server;
|
||||||
|
|
|
@ -11,13 +11,13 @@ export const BoxedLink: React.FC<Props> = ({
|
||||||
children,
|
children,
|
||||||
}) => (
|
}) => (
|
||||||
<a
|
<a
|
||||||
className={`px-2 py-1 border-2 border-gray-400 rounded-lg text-black no-underline text-normal hover:bg-gray-100 inline-flex flex-nowrap space-x-1 items-center ${
|
className={`px-2 py-1 border-2 border-gray-400 rounded-lg text-black no-underline hover:bg-gray-100 inline-flex flex-nowrap space-x-1 items-center text-xs md:text-lg ${
|
||||||
size === "small" ? "text-sm" : ""
|
size === "small" ? "text-sm" : ""
|
||||||
}`}
|
}`}
|
||||||
href={url}
|
href={url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<span>{children}</span>
|
<span>{children}</span>
|
||||||
<FaExternalLinkAlt className="text-gray-400 inline" />
|
<FaExternalLinkAlt className="text-gray-400 inline " />
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,9 +13,11 @@ import {
|
||||||
VictoryVoronoiContainer,
|
VictoryVoronoiContainer,
|
||||||
} from "victory";
|
} from "victory";
|
||||||
|
|
||||||
import { chartColors, ChartData, ChartSeries, height, width } from "./utils";
|
import { chartColors, ChartData, ChartSeries, goldenRatio } from "./utils";
|
||||||
|
|
||||||
let dateFormat = "MMM do y"; // "yyyy-MM-dd"
|
const height = 200
|
||||||
|
const width = 200 * goldenRatio
|
||||||
|
let dateFormat = "dd/MM/yy"; // "yyyy-MM-dd" // "MMM do yy"
|
||||||
|
|
||||||
// can't be replaced with React component, VictoryChart requires VictoryGroup elements to be immediate children
|
// can't be replaced with React component, VictoryChart requires VictoryGroup elements to be immediate children
|
||||||
const getVictoryGroup = ({
|
const getVictoryGroup = ({
|
||||||
|
@ -37,7 +39,7 @@ const getVictoryGroup = ({
|
||||||
data: {
|
data: {
|
||||||
// strokeOpacity: highlight ? 1 : 0.5,
|
// strokeOpacity: highlight ? 1 : 0.5,
|
||||||
strokeOpacity: highlight && !isBinary ? 0.8 : 0.6,
|
strokeOpacity: highlight && !isBinary ? 0.8 : 0.6,
|
||||||
strokeWidth: highlight && !isBinary ? 4 : 3,
|
strokeWidth: highlight && !isBinary ? 2.5 : 1.5,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -71,9 +73,9 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
const domainMax =
|
const domainMax =
|
||||||
maxProbability < 0.5 ? Math.round(10 * (maxProbability + 0.05)) / 10 : 1;
|
maxProbability < 0.5 ? Math.round(10 * (maxProbability + 0.05)) / 10 : 1;
|
||||||
const padding = {
|
const padding = {
|
||||||
top: 20,
|
top: 12,
|
||||||
bottom: 75,
|
bottom: 33,
|
||||||
left: 70,
|
left: 30,
|
||||||
right: 17,
|
right: 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,12 +101,12 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
<VictoryLabel
|
<VictoryLabel
|
||||||
style={[
|
style={[
|
||||||
{
|
{
|
||||||
fontSize: 16,
|
fontSize: 10,
|
||||||
fill: "black",
|
fill: "black",
|
||||||
strokeWidth: 0.05,
|
strokeWidth: 0.05,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fontSize: 16,
|
fontSize: 10,
|
||||||
fill: "#777",
|
fill: "#777",
|
||||||
strokeWidth: 0.05,
|
strokeWidth: 0.05,
|
||||||
},
|
},
|
||||||
|
@ -118,7 +120,7 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
)}`
|
)}`
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
fontSize: 17, // needs to be set here and not just in labelComponent for text size calculations
|
fontSize: 10, // needs to be set here and not just in labelComponent for text size calculations
|
||||||
fontFamily:
|
fontFamily:
|
||||||
'"Gill Sans", "Gill Sans MT", "Seravek", "Trebuchet MS", sans-serif',
|
'"Gill Sans", "Gill Sans MT", "Seravek", "Trebuchet MS", sans-serif',
|
||||||
// default font family from Victory, need to be specified explicitly for some reason, otherwise text size gets miscalculated
|
// default font family from Victory, need to be specified explicitly for some reason, otherwise text size gets miscalculated
|
||||||
|
@ -128,10 +130,10 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
fill: "white",
|
fill: "white",
|
||||||
}}
|
}}
|
||||||
cornerRadius={4}
|
cornerRadius={4}
|
||||||
flyoutPadding={{ top: 4, bottom: 4, left: 16, right: 16 }}
|
flyoutPadding={{ top: 4, bottom: 4, left: 10, right: 10 }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
radius={50}
|
radius={20}
|
||||||
voronoiBlacklist={
|
voronoiBlacklist={
|
||||||
[...Array(seriesList.length).keys()].map((i) => `line-${i}`)
|
[...Array(seriesList.length).keys()].map((i) => `line-${i}`)
|
||||||
// see: https://github.com/FormidableLabs/victory/issues/545
|
// see: https://github.com/FormidableLabs/victory/issues/545
|
||||||
|
@ -159,10 +161,10 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
}}
|
}}
|
||||||
tickLabelComponent={
|
tickLabelComponent={
|
||||||
<VictoryLabel
|
<VictoryLabel
|
||||||
dx={-40}
|
dx={-10}
|
||||||
dy={0}
|
dy={0}
|
||||||
angle={-30}
|
angle={-30}
|
||||||
style={{ fontSize: 15, fill: "#777" }}
|
style={{ fontSize: 9, fill: "#777" }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
scale={{ x: "time" }}
|
scale={{ x: "time" }}
|
||||||
|
@ -174,7 +176,7 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
grid: { stroke: "#D3D3D3", strokeWidth: 0.5 },
|
grid: { stroke: "#D3D3D3", strokeWidth: 0.5 },
|
||||||
}}
|
}}
|
||||||
tickLabelComponent={
|
tickLabelComponent={
|
||||||
<VictoryLabel dy={0} style={{ fontSize: 18, fill: "#777" }} />
|
<VictoryLabel dy={0} dx={5} style={{ fontSize: 9, fill: "#777" }} />
|
||||||
}
|
}
|
||||||
// tickFormat specifies how ticks should be displayed
|
// tickFormat specifies how ticks should be displayed
|
||||||
tickFormat={(x) => `${x * 100}%`}
|
tickFormat={(x) => `${x * 100}%`}
|
||||||
|
@ -205,6 +207,7 @@ export const InnerChart: React.FC<Props> = ({
|
||||||
})
|
})
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
</VictoryChart>
|
</VictoryChart>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,7 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
const data = useMemo(() => buildChartData(question), [question]);
|
const data = useMemo(() => buildChartData(question), [question]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center flex-col space-y-4 sm:flex-row sm:space-y-0">
|
<div className="flex items-center space-y-4 sm:flex-row sm:space-y-0 ">
|
||||||
<InnerChart data={data} highlight={highlight} />
|
<InnerChart data={data} highlight={highlight} />
|
||||||
<Legend
|
<Legend
|
||||||
items={data.seriesNames.map((name, i) => ({
|
items={data.seriesNames.map((name, i) => ({
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const chartColors = [
|
||||||
"#F59E0B", // amber-500
|
"#F59E0B", // amber-500
|
||||||
];
|
];
|
||||||
|
|
||||||
const goldenRatio = (1 + Math.sqrt(5)) / 2;
|
export const goldenRatio = (1 + Math.sqrt(5)) / 2;
|
||||||
// used both for chart and for ssr placeholder
|
// used both for chart and for ssr placeholder
|
||||||
export const width = 750;
|
export const width = 750;
|
||||||
export const height = width / goldenRatio;
|
export const height = width / goldenRatio;
|
||||||
|
|
|
@ -17,8 +17,8 @@ const truncateText = (length: number, text: string): string => {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
const breakpoints = " .!?";
|
const breakpoints = " .!?";
|
||||||
let lastLetter: string | undefined = undefined;
|
let lastLetter
|
||||||
let lastIndex: number | undefined = undefined;
|
let lastIndex
|
||||||
for (let index = length; index > 0; index--) {
|
for (let index = length; index > 0; index--) {
|
||||||
const letter = text[index];
|
const letter = text[index];
|
||||||
if (breakpoints.includes(letter)) {
|
if (breakpoints.includes(letter)) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ const OptionRow: React.FC<OptionProps> = ({ option, mode, textMode }) => {
|
||||||
<div
|
<div
|
||||||
className={`flex-none rounded-md text-center ${
|
className={`flex-none rounded-md text-center ${
|
||||||
mode === "primary"
|
mode === "primary"
|
||||||
? "text-normal text-white px-2 py-0.5 font-bold"
|
? "text-sm md:text-lg text-normal text-white px-2 py-0.5 font-bold"
|
||||||
: "text-sm w-14 py-0.5"
|
: "text-sm w-14 py-0.5"
|
||||||
} ${
|
} ${
|
||||||
mode === "primary"
|
mode === "primary"
|
||||||
|
@ -113,7 +113,7 @@ const OptionRow: React.FC<OptionProps> = ({ option, mode, textMode }) => {
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`leading-snug ${
|
className={`leading-snug ${
|
||||||
mode === "primary" ? "text-normal" : "text-sm"
|
mode === "primary" ? "text-sm md:text-lg text-normal" : "text-sm"
|
||||||
} ${
|
} ${
|
||||||
mode === "primary" ? textColor(option.probability) : "text-gray-700"
|
mode === "primary" ? textColor(option.probability) : "text-gray-700"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
@ -10,7 +10,7 @@ export const QuestionTitle: React.FC<Props> = ({
|
||||||
question,
|
question,
|
||||||
linkToMetaforecast,
|
linkToMetaforecast,
|
||||||
}) => (
|
}) => (
|
||||||
<h1 className="sm:text-3xl text-xl">
|
<h1 className="sm:text-3xl text-lg">
|
||||||
<a
|
<a
|
||||||
className="text-black no-underline hover:text-gray-700"
|
className="text-black no-underline hover:text-gray-700"
|
||||||
href={
|
href={
|
||||||
|
|
|
@ -54,5 +54,5 @@ function getStarsColor(numstars: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Stars: React.FC<{ num: number }> = ({ num }) => {
|
export const Stars: React.FC<{ num: number }> = ({ num }) => {
|
||||||
return <div className={getStarsColor(num)}>{getstars(num)}</div>;
|
return <div className={getStarsColor(num) + " text-xs md:text-lg"}>{getstars(num)}</div>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,24 +30,25 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
|
||||||
props: {
|
props: {
|
||||||
urqlState: ssrCache.extractData(),
|
urqlState: ssrCache.extractData(),
|
||||||
id,
|
id,
|
||||||
|
question
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const EmbedQuestionPage: NextPage<Props> = ({ id }) => {
|
const EmbedQuestionPage: NextPage<Props> = ({ id }) => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white min-h-screen">
|
<div className="block bg-white min-h-screen">
|
||||||
<Query document={QuestionPageDocument} variables={{ id }}>
|
<Query document={QuestionPageDocument} variables={{ id }}>
|
||||||
{({ data: { result: question } }) =>
|
{({ data: { result: question } }) =>
|
||||||
question ? (
|
question ? (
|
||||||
<div className="p-4">
|
<div className="flex flex-col p-2 w-full h-12/12">
|
||||||
<QuestionTitle question={question} linkToMetaforecast={true} />
|
{/*<QuestionTitle question={question} linkToMetaforecast={true} /> */}
|
||||||
|
|
||||||
<div className="mb-5 mt-5">
|
<div className="mb-1 mt-1">
|
||||||
<QuestionInfoRow question={question} />
|
<QuestionInfoRow question={question} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-10">
|
<div className="mb-0">
|
||||||
<QuestionChartOrVisualization question={question} />
|
<QuestionChartOrVisualization question={question} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -72,7 +72,7 @@ const Section: React.FC<{ title: string; id?: string }> = ({
|
||||||
const EmbedSection: React.FC<{ question: QuestionWithHistoryFragment }> = ({
|
const EmbedSection: React.FC<{ question: QuestionWithHistoryFragment }> = ({
|
||||||
question,
|
question,
|
||||||
}) => {
|
}) => {
|
||||||
const url = getBasePath() + `/questions/embed/${question.id}`;
|
const url = `https://${getBasePath()}/questions/embed/${question.id}`;
|
||||||
return (
|
return (
|
||||||
<Section title="Embed" id="embed">
|
<Section title="Embed" id="embed">
|
||||||
<CopyParagraph
|
<CopyParagraph
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { QuestionFragment } from "./fragments.generated";
|
||||||
|
|
||||||
export const getBasePath = () => {
|
export const getBasePath = () => {
|
||||||
if (process.env.NEXT_PUBLIC_VERCEL_URL) {
|
if (process.env.NEXT_PUBLIC_VERCEL_URL) {
|
||||||
return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`;
|
return `https://metaforecast.org`;//`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be used for local development if you prefer non-default port
|
// can be used for local development if you prefer non-default port
|
||||||
|
|
Loading…
Reference in New Issue
Block a user