Skip to content

Commit

Permalink
[chore] Sponsors in README (tldraw#301)
Browse files Browse the repository at this point in the history
* Add images, read me links

* Add API route for sponsor image

* Update cache max age
  • Loading branch information
steveruizok authored Nov 19, 2021
1 parent eb20f1c commit cd48b67
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 40 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ coverage
apps/www/public/worker-*
apps/www/public/sw.js
apps/www/public/sw.js.map
.env
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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:
Expand All @@ -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.
Expand Down
1 change: 0 additions & 1 deletion apps/www/.env

This file was deleted.

4 changes: 2 additions & 2 deletions apps/www/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
}, [])
Expand Down Expand Up @@ -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>
Expand Down
12 changes: 10 additions & 2 deletions apps/www/components/MultiplayerEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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>()
Expand Down Expand Up @@ -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>
Expand Down
26 changes: 1 addition & 25 deletions apps/www/pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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
}
96 changes: 96 additions & 0 deletions apps/www/pages/api/sponsors.ts
Original file line number Diff line number Diff line change
@@ -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)
}
2 changes: 1 addition & 1 deletion apps/www/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {

return {
props: {
isUser: false,
isUser: session?.user,
isSponsor: session?.user ? true : false,
},
}
Expand Down
2 changes: 1 addition & 1 deletion apps/www/pages/r/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
return {
props: {
id,
isUser: false,
isUser: session?.user,
isSponsor: session?.user ? true : false,
},
}
Expand Down
24 changes: 24 additions & 0 deletions apps/www/utils/isSponsoringMe.ts
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions assets/sentry.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
6 changes: 6 additions & 0 deletions assets/vercel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion examples/tldraw-example/.env

This file was deleted.

21 changes: 20 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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==
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit cd48b67

Please sign in to comment.