manifold/og-image/api/_lib/challenge-template.ts
Ian Philips 798253f887
Challenge Bets (#679)
* 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>
2022-08-04 15:27:02 -06:00

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:&#x2F;&#x2F;manifold.markets&#x2F;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>`
}