Compare commits

..

14 Commits

Author SHA1 Message Date
5fc9930265 upgrade: safe dependencies 2022-11-29 09:10:30 +00:00
685414e8fb feat: upgrade dependencies part 1. 2022-11-29 09:00:31 +00:00
fe4bba5169 tweak: change manifold quality indicators. 2022-11-26 13:27:00 +00:00
e9796c545d tweak: make indicators responsive to mobile 2022-11-17 21:58:15 +00:00
fc84300712 tweak: change getBasePath implementation
Unnecessary to expose the vercel url.
2022-11-17 20:16:24 +00:00
73329df47b feat: Fix embeds so that they are a bit more compressible.
Also remove the title, which is variable width & thus
very annoying to account for.
2022-11-17 20:12:31 +00:00
dc1e75d99d tweak: change embed page a bit more 2022-11-17 19:22:46 +00:00
0a7d2d160a tweak: Make embedded chart more compressible
Per pointers here:
<https://github.com/ForumMagnum/ForumMagnum/pull/6096#issuecomment-1317821272>
2022-11-17 18:19:24 +00:00
67e4b825db fix: bug 2022-11-09 22:15:29 +00:00
dfe1de5279 feat: tweak metaforecast path in question embed.
No idea why this works differently in that particular page.
2022-11-09 22:12:21 +00:00
38a2fe8215 feat: add caching!! 2022-11-09 21:54:08 +00:00
8ccb88558f fix: yoga import bug 2022-11-09 21:37:32 +00:00
31bfb357b3 fix: continue yoga-graphql update 2022-11-09 21:36:19 +00:00
611d553193 feat: Start migration to yoga v3
Per <https://www.the-guild.dev/graphql/yoga-server/v3/migration/migration-from-yoga-v2>.

This is necessay in order to use the caching functionality
2022-11-09 21:30:39 +00:00
15 changed files with 938 additions and 828 deletions

View File

@ -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"
} }
} }

View File

@ -92,7 +92,7 @@ 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.
}, },
@ -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;

View File

@ -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;

View File

@ -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>
); );

View File

@ -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", "Ser­avek", "Trebuchet MS", sans-serif', '"Gill Sans", "Gill Sans MT", "Ser­avek", "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>
); );
}; };

View File

@ -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) => ({

View File

@ -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;

View File

@ -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)) {

View File

@ -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"
}`} }`}

View File

@ -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={

View File

@ -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>;
}; };

View File

@ -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>

View File

@ -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

View File

@ -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

1660
yarn.lock

File diff suppressed because it is too large Load Diff