[chore] Sponsors in README (#301)

* Add images, read me links

* Add API route for sponsor image

* Update cache max age
This commit is contained in:
Steve Ruiz 2021-11-19 12:59:08 +00:00 committed by GitHub
parent eb20f1c816
commit cd48b67a74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 177 additions and 40 deletions

1
.gitignore vendored
View file

@ -14,3 +14,4 @@ coverage
apps/www/public/worker-*
apps/www/public/sw.js
apps/www/public/sw.js.map
.env

View file

@ -1,5 +1,5 @@
<div style="text-align: center; transform: scale(.5);">
<img src="card-repo.png"/>
<img src="./assets/tldraw.png"/>
</div>
Welcome to the [tldraw](https://tldraw.com) monorepo. Here you'll find the source code for [@tldraw/tldraw](https://www.npmjs.com/package/@tldraw/tldraw), [@tldraw/core](https://www.npmjs.com/package/@tldraw/core), and the tldraw.com website.
@ -8,6 +8,14 @@ Welcome to the [tldraw](https://tldraw.com) monorepo. Here you'll find the sourc
💕 Love this project? Consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
Thanks to our corporate sponsors:
<a href="https://sentry.io"><img src="./assets/sentry.svg"></img></a>
<a href="https://vercel.com/?utm_source=team-slug&utm_campaign=oss"><img src="./assets/vercel.svg"></img></a>
...and to our [individual sponsors](https://github.com/sponsors/steveruizok#sponsors)!
## Contents
This repository is a monorepo containing two packages:
@ -27,18 +35,18 @@ This repository is a monorepo containing two packages:
- [**examples/core-example-advanced**](https://github.com/tldraw/tldraw/tree/main/examples/core-example-advanced) is a second example for `@tldraw/core`.
- [**examples/tldraw-example**](https://github.com/tldraw/tldraw/tree/main/examples/tldraw-example) is an example for `@tldraw/tldraw`.
## Discussion
Want to connect? Visit the [Discord channel](https://discord.gg/SBBEVCA4PG).
## Contribution
See the [contributing guide](/CONTRIBUTING.md).
Interested in contributing? See the [contributing guide](/CONTRIBUTING.md).
## Support
Need help? Please [open an issue](https://github.com/tldraw/tldraw/issues/new) for support.
## Discussion
Want to connect with other devs? Visit the [Discord channel](https://discord.gg/SBBEVCA4PG).
## License
This project is licensed under MIT.

View file

@ -1 +0,0 @@
NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY=pk_live_1LJGGaqBSNLjLT-4Jalkl-U9

View file

@ -11,7 +11,7 @@ interface EditorProps {
isSponsor?: boolean
}
export default function Editor({ id = 'home', isSponsor = false }: EditorProps) {
export default function Editor({ id = 'home', isUser = false, isSponsor = false }: EditorProps) {
const handleMount = React.useCallback((app: TldrawApp) => {
window.app = app
}, [])
@ -39,7 +39,7 @@ export default function Editor({ id = 'home', isSponsor = false }: EditorProps)
onPersist={handlePersist}
showSponsorLink={!isSponsor}
onSignIn={isSponsor ? undefined : onSignIn}
onSignOut={onSignOut}
onSignOut={isUser ? onSignOut : undefined}
{...fileSystemEvents}
/>
</div>

View file

@ -38,7 +38,15 @@ export default function MultiplayerEditor({
// Inner Editor
function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: boolean }) {
function Editor({
roomId,
isUser,
isSponsor,
}: {
roomId: string
isUser: boolean
isSponsor: boolean
}) {
const [docId] = React.useState(() => Utils.uniqueId())
const [app, setApp] = React.useState<TldrawApp>()
@ -175,7 +183,7 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
showPages={false}
showSponsorLink={isSponsor}
onSignIn={isSponsor ? undefined : onSignIn}
onSignOut={onSignOut}
onSignOut={isUser ? onSignOut : undefined}
{...fileSystemEvents}
/>
</div>

View file

@ -1,3 +1,4 @@
import { isSponsoringMe } from '-utils/isSponsoringMe'
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
@ -30,28 +31,3 @@ export default function Auth(
},
})
}
const whitelist = ['steveruizok']
async function isSponsoringMe(login: string) {
if (whitelist.includes(login)) return true
const res = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
},
body: JSON.stringify({
query: `
query {
user(login: "steveruizok") {
isSponsoredBy(accountLogin: "${login}")
}
}
`,
}),
}).then((res) => res.json())
return res?.data?.user?.isSponsoredBy
}

View file

@ -0,0 +1,96 @@
import { NextApiRequest, NextApiResponse } from 'next'
const AV_SIZE = 32
const PADDING = 4
const COLS = 16
type SponsorResult = { url: string; login: string }
type QueryResult = {
node: { sponsorEntity: { avatarUrl: string; login: string } }
}
function getXY(i: number) {
return [(i % COLS) * (AV_SIZE + PADDING), Math.floor(i / COLS) * (AV_SIZE + PADDING)]
}
export default async function GetSponsors(req: NextApiRequest, res: NextApiResponse) {
const sponsorInfo = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
},
body: JSON.stringify({
query: `{
viewer {
sponsors(first: 0) {
totalCount
}
sponsorshipsAsMaintainer(first: 100, orderBy: {
field:CREATED_AT,
direction:DESC
}) {
edges {
node {
sponsorEntity {
...on User {
avatarUrl
login
}
}
}
}
}
}
}`,
}),
}).then((res) => res.json())
const totalCount: number = sponsorInfo.data.viewer.sponsors.totalCount
const results = (
sponsorInfo.data.viewer.sponsorshipsAsMaintainer.edges as QueryResult[]
).map<SponsorResult>((edge) => ({
url: edge.node.sponsorEntity.avatarUrl?.replaceAll('&', '&amp;') ?? '',
login: edge.node.sponsorEntity.login,
}))
if (results.length % COLS <= 2) {
results.pop()
results.pop()
results.pop()
}
// Avatars
const avatars = results
.map(({ url, login }, i) => {
const [x, y] = getXY(i)
return `<image alt="${login}" href="${url}" x="${x}" y="${y}" width="${AV_SIZE}" height="${AV_SIZE}"/>`
})
.join('')
// More text
const [x, y] = getXY(results.length)
const width = (AV_SIZE + PADDING) * 3
const more = `
<g transform="translate(${x},${y})"><text text-lenth="${width}" font-family="Arial" font-size="12px" font-weight="bold" text-anchor="middle" text-align="center" x="${
width / 2
}" y="${AV_SIZE / 2 + 3}">...and ${totalCount - 100} more!</text></g>`
const svgImage = `
<svg xmlns="http://www.w3.org/2000/svg"><a href="https://github.com/sponsors/steveruizok"><g>${avatars}${more}</g></a></svg>`
// const html = `
// <div style="display: grid; width: fit-content; grid-template-columns: repeat(25, auto); gap: 4px;">
// ${images.join(`
// `)}
// </div>`
res
.status(200)
.setHeader('Cache-Control', 'max-age=604800')
.setHeader('Content-Type', 'image/svg+xml')
.send(svgImage)
}

View file

@ -26,7 +26,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
return {
props: {
isUser: false,
isUser: session?.user,
isSponsor: session?.user ? true : false,
},
}

View file

@ -22,7 +22,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
return {
props: {
id,
isUser: false,
isUser: session?.user,
isSponsor: session?.user ? true : false,
},
}

View file

@ -0,0 +1,24 @@
const whitelist = ['steveruizok']
export async function isSponsoringMe(login: string) {
if (whitelist.includes(login)) return true
const res = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
},
body: JSON.stringify({
query: `
query {
user(login: "steveruizok") {
isSponsoredBy(accountLogin: "${login}")
}
}
`,
}),
}).then((res) => res.json())
return res?.data?.user?.isSponsoredBy
}

1
assets/sentry.svg Normal file
View file

@ -0,0 +1 @@
<svg class="__sntry__ css-15xgryy e10nushx5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" width="212" height="47" style=""><defs><style type="text/css">@media (prefers-color-scheme: dark) {path.__sntry__ { fill: #362d59 !important; }}</style></defs><path d="M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z" fill="#ffffff" class="__sntry__"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

6
assets/vercel.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -1 +0,0 @@
LIVEBLOCKS_PUBLIC_API_KEY=pk_live_1LJGGaqBSNLjLT-4Jalkl-U9

View file

@ -9341,7 +9341,7 @@ jose@^1.27.2:
dependencies:
"@panva/asn1.js" "^1.0.0"
jpeg-js@^0.4.2:
jpeg-js@^0.4.1, jpeg-js@^0.4.2:
version "0.4.3"
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==
@ -11183,6 +11183,11 @@ only@~0.0.2:
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
opentype.js@^0.4.3:
version "0.4.11"
resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.4.11.tgz#281a2390639cc15931c955d8d63c14a7c7772b41"
integrity sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E=
optionator@^0.8.1:
version "0.8.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
@ -11711,6 +11716,11 @@ plist@^3.0.1:
base64-js "^1.5.1"
xmlbuilder "^9.0.7"
pngjs@^3.3.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
pngjs@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
@ -11975,6 +11985,15 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
pureimage@^0.3.6:
version "0.3.6"
resolved "https://registry.yarnpkg.com/pureimage/-/pureimage-0.3.6.tgz#3ab6070e2779193a8767fc9b657d41c6894b070f"
integrity sha512-Wtk+QdlB1X7wnfaXads+5i6tI95dNMyR7Hq9Q0qmEOXiG38JvPRcAISSzuSVGXPlgi54VFzl26ic8UpT6GLs6g==
dependencies:
jpeg-js "^0.4.1"
opentype.js "^0.4.3"
pngjs "^3.3.1"
q@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"