798253f887
* Challenge bets * Store avatar url * Fix before and after probs * Check balance before creation * Calculate winning shares * pretty * Change winning value * Set shares to equal each other * Fix share challenge link * pretty * remove lib refs * Probability of bet is set to market * Remove peer pill * Cleanup * Button on contract page * don't show challenge if not binary or if resolved * challenge button (WIP) * fix accept challenge: don't change pool/probability * Opengraph preview [WIP] * elim lib * Edit og card props * Change challenge text * New card gen attempt * Get challenge on server * challenge button styling * Use env domain * Remove other window ref * Use challenge creator as avatar * Remove user name * Remove s from property, replace prob with outcome * challenge form * share text * Add in challenge parts to template and url * Challenge url params optional * Add challenge params to parse request * Parse please * Don't remove prob * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Challenge card styling * Add to readme about how to dev og-image * Add emojis * button: gradient background, 2xl size * beautify accept bet screen * update question button * Add separate challenge template * Accepted challenge sharing card, fix accept bet call * accept challenge button * challenge winner page * create challenge screen * Your outcome/cost=> acceptorOutcome/cost * New create challenge panel * Fix main merge * Add challenge slug to bet and filter by it * Center title * Add helper text * Add FAQ section * Lint * Columnize the user areas in preview link too * Absolutely position * Spacing * Orientation * Restyle challenges list, cache contract name * Make copying easy on mobile * Link spacing * Fix spacing * qr codes! * put your challenges first * eslint * Changes to contract buttons and create challenge modal * Change titles around for current bet * Add back in contract title after winning * Cleanup * Add challenge enabled flag * Spacing of switch button * Put sharing qr code in modal Co-authored-by: mantikoros <sgrugett@gmail.com>
204 lines
5.8 KiB
TypeScript
204 lines
5.8 KiB
TypeScript
import { sanitizeHtml } from './sanitizer'
|
|
import { ParsedRequest } from './types'
|
|
|
|
function getCss(theme: string, fontSize: string) {
|
|
let background = 'white'
|
|
let foreground = 'black'
|
|
let radial = 'lightgray'
|
|
|
|
if (theme === 'dark') {
|
|
background = 'black'
|
|
foreground = 'white'
|
|
radial = 'dimgray'
|
|
}
|
|
// To use Readex Pro: `font-family: 'Readex Pro', sans-serif;`
|
|
return `
|
|
@import url('https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Readex+Pro:wght@400;700&display=swap');
|
|
|
|
body {
|
|
background: ${background};
|
|
background-image: radial-gradient(circle at 25px 25px, ${radial} 2%, transparent 0%), radial-gradient(circle at 75px 75px, ${radial} 2%, transparent 0%);
|
|
background-size: 100px 100px;
|
|
height: 100vh;
|
|
font-family: "Readex Pro", sans-serif;
|
|
}
|
|
|
|
code {
|
|
color: #D400FF;
|
|
font-family: 'Vera';
|
|
white-space: pre-wrap;
|
|
letter-spacing: -5px;
|
|
}
|
|
|
|
code:before, code:after {
|
|
content: '\`';
|
|
}
|
|
|
|
.logo-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
align-content: center;
|
|
justify-content: center;
|
|
justify-items: center;
|
|
}
|
|
|
|
.logo {
|
|
margin: 0 75px;
|
|
}
|
|
|
|
.plus {
|
|
color: #BBB;
|
|
font-family: Times New Roman, Verdana;
|
|
font-size: 100px;
|
|
}
|
|
|
|
.spacer {
|
|
margin: 150px;
|
|
}
|
|
|
|
.emoji {
|
|
height: 1em;
|
|
width: 1em;
|
|
margin: 0 .05em 0 .1em;
|
|
vertical-align: -0.1em;
|
|
}
|
|
|
|
.heading {
|
|
font-family: 'Major Mono Display', monospace;
|
|
font-size: ${sanitizeHtml(fontSize)};
|
|
font-style: normal;
|
|
color: ${foreground};
|
|
line-height: 1.8;
|
|
}
|
|
|
|
.font-major-mono {
|
|
font-family: "Major Mono Display", monospace;
|
|
}
|
|
|
|
.text-primary {
|
|
color: #11b981;
|
|
}
|
|
`
|
|
}
|
|
|
|
export function getChallengeHtml(parsedReq: ParsedRequest) {
|
|
const {
|
|
theme,
|
|
fontSize,
|
|
question,
|
|
creatorName,
|
|
creatorAvatarUrl,
|
|
challengerAmount,
|
|
challengerOutcome,
|
|
creatorAmount,
|
|
creatorOutcome,
|
|
acceptedName,
|
|
acceptedAvatarUrl,
|
|
} = parsedReq
|
|
const MAX_QUESTION_CHARS = 78
|
|
const truncatedQuestion =
|
|
question.length > MAX_QUESTION_CHARS
|
|
? question.slice(0, MAX_QUESTION_CHARS) + '...'
|
|
: question
|
|
const hideAvatar = creatorAvatarUrl ? '' : 'hidden'
|
|
const hideAcceptedAvatar = acceptedAvatarUrl ? '' : 'hidden'
|
|
const accepted = acceptedName !== ''
|
|
return `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Generated Image</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
</head>
|
|
<style>
|
|
${getCss(theme, fontSize)}
|
|
</style>
|
|
<body>
|
|
<div class="px-24">
|
|
|
|
|
|
<div class="flex flex-col justify-between gap-16 pt-2">
|
|
<div class="flex flex-col text-indigo-700 mt-4 text-5xl leading-tight text-center">
|
|
${truncatedQuestion}
|
|
</div>
|
|
<div class="flex flex-row grid grid-cols-3">
|
|
<div class="flex flex-col justify-center items-center ${
|
|
creatorOutcome === 'YES' ? 'text-primary' : 'text-red-500'
|
|
}">
|
|
|
|
<!-- Creator user column-->
|
|
<div class="flex flex-col align-bottom gap-6 items-center justify-center">
|
|
<p class="text-gray-900 text-4xl">${creatorName}</p>
|
|
<img
|
|
class="h-36 w-36 rounded-full bg-white flex items-center justify-center ${hideAvatar}"
|
|
src="${creatorAvatarUrl}"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<div class="flex flex-row justify-center items-center gap-3 mt-6">
|
|
<div class="text-5xl">${'M$' + creatorAmount}</div>
|
|
<div class="text-4xl">${'on'}</div>
|
|
<div class="text-5xl ">${creatorOutcome}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- VS-->
|
|
<div class="flex flex-col text-gray-900 text-6xl mt-8 text-center">
|
|
VS
|
|
</div>
|
|
<div class="flex flex-col justify-center items-center ${
|
|
challengerOutcome === 'YES' ? 'text-primary' : 'text-red-500'
|
|
}">
|
|
|
|
<!-- Unaccepted user column-->
|
|
<div class="flex flex-col align-bottom gap-6 items-center justify-center
|
|
${accepted ? 'hidden' : ''}">
|
|
<p class="text-gray-900 text-4xl">You</p>
|
|
<img
|
|
class="h-36 w-36 rounded-full bg-white flex items-center justify-center "
|
|
src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<!-- Accepted user column-->
|
|
<div class="flex flex-col align-bottom gap-6 items-center justify-center">
|
|
<p class="text-gray-900 text-4xl">${acceptedName}</p>
|
|
<img
|
|
class="h-36 w-36 rounded-full bg-white flex items-center justify-center ${hideAcceptedAvatar}"
|
|
src="${acceptedAvatarUrl}"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<div class="flex flex-row justify-center items-center gap-3 mt-6">
|
|
<div class="text-5xl">${'M$' + challengerAmount}</div>
|
|
<div class="text-4xl">${'on'}</div>
|
|
<div class="text-5xl ">${challengerOutcome}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<!-- Manifold logo -->
|
|
<div class="flex flex-row justify-center absolute bottom-4 left-[24rem]">
|
|
<a class="flex flex-row gap-3" href="/">
|
|
<img
|
|
class="sm:h-12 sm:w-12"
|
|
src="https://manifold.markets/logo.png"
|
|
width="40"
|
|
height="40"
|
|
alt=''
|
|
/>
|
|
<div
|
|
class="hidden sm:flex font-major-mono lowercase mt-1 sm:text-3xl md:whitespace-nowrap"
|
|
>
|
|
Manifold Markets
|
|
</div></a>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
</html>`
|
|
}
|