Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add PicSnap to serve OpenGraph image #5

Open
wants to merge 121 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
a4862e4
feat: add API endpoint to return a cached file
wa0x6e Apr 19, 2023
fff3ae7
feat: compress response
wa0x6e Apr 19, 2023
f1dedbd
feat: define precise error codes
wa0x6e Apr 19, 2023
e7174fa
chore: rename file to reflect its purpose
wa0x6e Apr 19, 2023
a757ee6
fix: fix missing new line in CSV file
wa0x6e Apr 19, 2023
ed221dc
fix: fix choices columns for votes with multiple choices
wa0x6e Apr 19, 2023
1a8150b
refactor: avoid passing `proposal` object
wa0x6e Apr 19, 2023
2c0fef4
fix: use different name for incomplete file
wa0x6e Apr 19, 2023
474b250
fix: prevent race condition on file generation
wa0x6e Apr 19, 2023
fd8a3c9
Merge branch 'main' into add-api
wa0x6e Apr 19, 2023
07fe282
feat: use AWS as cached file storage
wa0x6e Apr 20, 2023
399c8d4
feat: separate cache fetcher and generator in API endpoint
wa0x6e Apr 20, 2023
f7e8809
fix: do not return an error code on cache generation success
wa0x6e Apr 21, 2023
dbe874b
feat: add additional file storage engine
wa0x6e Apr 21, 2023
8d78400
chore: update README
wa0x6e Apr 21, 2023
a523f2a
fix: use inferred env variables for S3 client setup
wa0x6e Apr 21, 2023
57cb712
feat: custimize location of cached files
wa0x6e Apr 21, 2023
c7bd2cd
feat: protect generate endpoint behind authentication
wa0x6e Apr 21, 2023
cc31a4d
chore: add LICENCE file
wa0x6e Apr 22, 2023
d83e00a
feat: add webhook support for `generate` endpoint
wa0x6e Apr 22, 2023
8d0a8ed
feat: add basic queue system to handle cache file generation
wa0x6e Apr 22, 2023
e18cc3b
chore: update README
wa0x6e Apr 22, 2023
3eae769
chore: add tests
wa0x6e Apr 22, 2023
d0c7733
chore: fix github worflow
wa0x6e Apr 22, 2023
dee6171
fix: fix folder creation
wa0x6e Apr 22, 2023
9821586
chore: rename github workflow
wa0x6e Apr 22, 2023
fbdefa3
chore: update README
wa0x6e Apr 22, 2023
519a499
chorel; add test for weighted votes
wa0x6e Apr 22, 2023
9a36731
feat: add reason to votes report
wa0x6e Apr 22, 2023
9c91d29
chore: fix false positives in linter
wa0x6e Apr 24, 2023
3a391de
chore: dependencies upgrade
wa0x6e Apr 24, 2023
7b5404c
chore: fix CI job name
wa0x6e Apr 24, 2023
57e4400
chore: typecheck task should not also build
wa0x6e Apr 24, 2023
d2343d0
refactor: always throw Error objects instead of literal
wa0x6e Apr 25, 2023
cf48149
feat: add open graph image card for proposal
wa0x6e Apr 30, 2023
6e2a043
feat: add image card for space
wa0x6e Apr 30, 2023
3e32277
fix: show space followers number instead of members count
wa0x6e May 1, 2023
0f9e33d
fix: improve logo UI
wa0x6e May 1, 2023
c40d533
refactor: use `--fix` for default lint, for consistency with other repos
wa0x6e May 1, 2023
32aefba
refactor: allow customisation of logo color and dimension
wa0x6e May 1, 2023
d522592
feat: add new generic image card
wa0x6e May 1, 2023
45fc926
fix: handle errors for invalid file type
wa0x6e May 1, 2023
dc5718a
refactor: DRY
wa0x6e May 1, 2023
f00304f
feat: cache and serve cached ogImage when available
wa0x6e May 1, 2023
26d14fd
chore: fix test
wa0x6e May 1, 2023
1a5238c
fix: fix AWS storage to handle binary file type
wa0x6e May 1, 2023
c02c5e4
refactor: extract function for easier testing
wa0x6e May 1, 2023
fd8f84c
feat: add API endpoint to receive webhook to refresh OG image
wa0x6e May 1, 2023
efe9654
chore: update README with new og endpoint
wa0x6e May 1, 2023
ff92be4
fix(UI): improve UI
wa0x6e May 2, 2023
9f70118
refactor: refactor API endpoint
wa0x6e May 2, 2023
7576ba6
fix: remove members count in space image
wa0x6e May 2, 2023
abb7536
fix: fix missing emoji support
wa0x6e May 2, 2023
800dd1b
chore: update README
wa0x6e May 2, 2023
40430fb
fix: fix logo ratio
wa0x6e May 3, 2023
b9d9f9a
chore: set minimum required node version
wa0x6e May 3, 2023
07cef1f
Update readme
ChaituVR May 3, 2023
4e5acda
Minor updates
ChaituVR May 3, 2023
f9e18ce
fix: add default route
wa0x6e May 4, 2023
447cb91
fix: use await syntax
wa0x6e May 4, 2023
4d026bc
chore: remove unecessary rule
wa0x6e May 4, 2023
2b0fb49
refactor: set the storage engine via an env variable
wa0x6e May 4, 2023
6d76940
refactor: keep private method to bottom of files
wa0x6e May 4, 2023
5469f06
refactor: set the StorageEngine and its related setting to environmen…
wa0x6e May 4, 2023
71864d3
chore: lint task should fix by default
wa0x6e May 4, 2023
00650bb
Merge branch 'add-api' into add-open-graph-image
wa0x6e May 5, 2023
3d4e9eb
Merge branch 'main' into add-open-graph-image
wa0x6e May 5, 2023
3331b5d
chore: fix yarn.lock after merge conflict
wa0x6e May 5, 2023
100b7f7
refactor: refactor code to use main branch feature
wa0x6e May 5, 2023
1887b81
fix: fix invalid return code
wa0x6e May 5, 2023
1b175fd
Merge branch 'main' into add-open-graph-image
wa0x6e Jul 1, 2023
2d57fa7
chore: linting
wa0x6e Jul 1, 2023
17c9a2a
Merge branch 'main' into add-open-graph-image
wa0x6e Jul 17, 2023
1111b61
fix: all storage engine should return the same value type
wa0x6e Jul 17, 2023
6e13c95
refactor: uncouple cache logic from votesReport
wa0x6e Jul 18, 2023
691d715
fix: fix missing sentry capture calls
wa0x6e Jul 18, 2023
fc047e1
refactor: prefer class function over property
wa0x6e Jul 19, 2023
52fca59
refactor: rename ogImage to picSnap to make the module more generic
wa0x6e Jul 19, 2023
b479d06
chore: update README with PicSnap docs
wa0x6e Jul 19, 2023
4850934
chore: refactor to extract more logic into templates and components
wa0x6e Jul 19, 2023
6d0d8fe
chore: add tests for picSnap og-home
wa0x6e Jul 19, 2023
fb4192a
chore: cleanup after tests
wa0x6e Jul 19, 2023
8128ce0
chore: use path from storage engine
wa0x6e Jul 19, 2023
fa7f06f
chore: add tests for OpenGraph space image
wa0x6e Jul 19, 2023
b9a3fc1
chore: add tests to implement
wa0x6e Jul 19, 2023
e139109
chore: add missing test snapshot
wa0x6e Jul 19, 2023
193bc2d
chore: delete unused image snapshot
wa0x6e Jul 19, 2023
bbc2e1e
chore: add more tests
wa0x6e Jul 19, 2023
4fcf715
chore: add E2E tests for votesReport
wa0x6e Jul 19, 2023
2380a81
chore: fix deprecated rmdir usage
wa0x6e Jul 19, 2023
8a70985
fix: remove unused errors code
wa0x6e Jul 19, 2023
cc26966
chore: add more E2E tests
wa0x6e Jul 19, 2023
dc97148
fix: fix rename env var
wa0x6e Jul 19, 2023
70428ee
chore: fix missing sentry capture
wa0x6e Jul 19, 2023
2260b0e
chore: remove errors granularity
wa0x6e Jul 19, 2023
92e9dcf
chore: uncouple the cache engine from votesReport
wa0x6e Jul 19, 2023
5dc5324
chore: refactor webhook to handle more generic events
wa0x6e Jul 19, 2023
f8e5b44
Merge branch 'fix-missing-sentry' into base-pre-picsnap
wa0x6e Jul 20, 2023
ef6d98a
Merge branch 'remove-error-granularity' into base-pre-picsnap
wa0x6e Jul 20, 2023
fc370ed
Merge branch 'base-pre-picsnap' into add-open-graph-image
wa0x6e Jul 20, 2023
ac00d9c
fix: fix duplicate import
wa0x6e Jul 20, 2023
e1902de
chore: fix lint
wa0x6e Jul 20, 2023
38bb738
feat: add support for Buffer when setting/getting a cache
wa0x6e Jul 20, 2023
fc9d1a2
Merge branch 'uncouple-cache' into base-pre-picsnap
wa0x6e Jul 20, 2023
678dbc5
chore: fix tests
wa0x6e Jul 20, 2023
13cbf54
Merge branch 'uncouple-cache' into base-pre-picsnap
wa0x6e Jul 20, 2023
e1a73da
Merge branch 'base-pre-picsnap' into add-open-graph-image
wa0x6e Jul 20, 2023
a30f315
chore: lint
wa0x6e Jul 20, 2023
56f4d29
chore: add retry for flaky test
wa0x6e Jul 20, 2023
e9c003a
Merge branch 'main' into add-open-graph-image
wa0x6e Jul 21, 2023
271714c
Merge branch 'main' into add-open-graph-image
wa0x6e Jul 21, 2023
c70729c
Merge branch 'main' into add-open-graph-image
wa0x6e Jul 22, 2023
f13c040
chore: update README to remove unrelated changes
wa0x6e Aug 23, 2023
eac2788
Merge branch 'main' into add-open-graph-image
wa0x6e Aug 23, 2023
569dedc
Merge branch 'main' into add-open-graph-image
samuveth Aug 26, 2023
130b488
fix: fix wrong example link
wa0x6e Aug 26, 2023
6cff97a
Merge branch 'main' into add-open-graph-image
wa0x6e Aug 26, 2023
e4c35e5
Merge branch 'add-open-graph-image' of https://github.com/snapshot-la…
samuveth Aug 26, 2023
b367268
Fix closed color to match new color on snapshot
samuveth Aug 26, 2023
476e24d
Update e2e ogProposal image
samuveth Aug 26, 2023
f52bd64
chore: fix tests fixtures
wa0x6e Aug 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ AWS_BUCKET_NAME=
WEBHOOK_AUTH_TOKEN=
STORAGE_ENGINE=file
VOTE_REPORT_SUBDIR=votes
PICSNAP_SUBDIR=picsnap
NFT_CLAIMER_PRIVATE_KEY=
NFT_CLAIMER_NETWORK=
NFT_CLAIMER_DEPLOY_VERIFYING_CONTRACT=
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Sidekick is the service serving:
- All proposal's votes CSV report
- Moderation list
- NFT Claimer trusted backend server
- PicSnap, an image generator for pictures snapshot of proposals and spaces

---

Expand Down Expand Up @@ -272,6 +273,30 @@ If given proposal's space has enabled NFT claimer, and there are still mintable

> **NOTE**: The returned `proposalId` in the payload is a number representation

### PicSnap

PicSnap is an image generator for snapshot spaces/proposals info.

#### Configuration

Use the env variable `OG_IMAGES_SUBDIR` to specify the subdir where to store the cached files (relative to the storage engine root)

#### Usage

Send a `GET` request to `/api/picsnap/:type(og-space|og-proposal|og-home)/:id?.:ext(png|svg)?`

It will create the cached file if it does not exist yet, then serve it.

By default, all images are in png format. You can additionally explicitely set the format by appending the extension to the url to `.svg` to retrieve the raw svg file (slower as only png files are cached)

Available image types are:

| `TYPE` | Description | Example query | Size |
| ------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------- | -------- |
| `og-home` | Default image for OpenGraph | `localhost:3005/api/picsnap/og-home` | 1200x600 |
| `og-space` | OpenGraph image for space | `localhost:3005/api/picsnap/og-space/fabien.eth` | 1200x600 |
| `og-proposal` | OpenGraph image for proposal | `localhost:3005/api/picsnap/og-proposal/0x5280241b4ccc9b7c5088e657a714d28fa89bd5305a1ff0abf0736438c446ae98` | 1200x600 |

### Sentry tunnel

#### Problem
Expand Down
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default {
preset: 'ts-jest',
testEnvironment: 'jest-environment-node-single-context',
setupFiles: ['dotenv/config'],
//setupFilesAfterEnv: ['<rootDir>src/setupTests.ts'],
setupFilesAfterEnv: ['<rootDir>/test/setup.ts'],
moduleFileExtensions: ['js', 'ts'],
testPathIgnorePatterns: ['dist/'],
verbose: true
Expand Down
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lint:fix": "yarn lint --fix",
"typecheck": "tsc --noEmit",
"build": "tsc -p tsconfig.json && copyfiles data/*.json data/*.txt public/* dist/",
"dev": "nodemon src/index.ts -e js,ts",
"dev": "nodemon src/index.ts -e js,ts,tsx",
"start": "node dist/src/index.js",
"start:test": "dotenv -e test/.env.test yarn dev",
"test": "PORT=3003 start-server-and-test 'yarn start:test' 3003 'dotenv -e test/.env.test jest --runInBand'",
Expand All @@ -33,6 +33,7 @@
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@resvg/resvg-js": "^2.4.1",
"@snapshot-labs/snapshot-metrics": "^1.0.0",
"@snapshot-labs/snapshot-sentry": "^1.0.0",
"@snapshot-labs/snapshot.js": "0.4.97",
Expand All @@ -47,7 +48,10 @@
"morgan": "^1.10.0",
"multiformats": "^9",
"mysql": "^2.18.1",
"prom-client": "^14.2.0"
"react-jsx": "^1.0.0",
"satori": "^0.7.2",
"serve-favicon": "^2.5.0",
"sharp": "^0.32.1"
},
"devDependencies": {
"@snapshot-labs/eslint-config": "^0.1.0-beta.9",
Expand All @@ -57,9 +61,11 @@
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.3",
"@types/jest-image-snapshot": "^6.1.0",
"@types/morgan": "^1.9.4",
"@types/mysql": "^2.15.21",
"@types/node": "^20.4.8",
"@types/react": "^18.2.0",
"@types/serve-favicon": "^2.5.4",
"@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.60.1",
Expand All @@ -70,6 +76,7 @@
"eslint-plugin-prettier": "5",
"jest": "^29.6.2",
"jest-environment-node-single-context": "^29.1.0",
"jest-image-snapshot": "^6.1.0",
"nodemon": "^3.0.1",
"prettier": "^3.0.1",
"start-server-and-test": "^2.0.0",
Expand Down
24 changes: 24 additions & 0 deletions scripts/pic-snap-refresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'dotenv/config';
import picSnap, { ImageType } from '../src/lib/picSnap';
import { storageEngine } from '../src/helpers/utils';

async function main() {
if (process.argv.length < 3) {
console.error(`Usage: yarn ts-node scripts/pic-snap-refresh.ts [proposal|space] [ADDRESS]`);
return process.exit(1);
}
const [, , type, address] = process.argv;

const og = new picSnap(type as ImageType, address, storageEngine(process.env.OG_IMAGE_SUBDIR));
await og.createCache();
}

(async () => {
try {
await main();
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
})();
18 changes: 18 additions & 0 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { capture } from '@snapshot-labs/snapshot-sentry';
import { rpcError, rpcSuccess, storageEngine } from './helpers/utils';
import getModerationList from './lib/moderationList';
import VotesReport from './lib/votesReport';
import picSnap, { ImageType } from './lib/picSnap';
import mintPayload from './lib/nftClaimer/mint';
import deployPayload from './lib/nftClaimer/deploy';
import { queue, getProgress } from './lib/queue';
Expand Down Expand Up @@ -37,6 +38,23 @@ router.post('/votes/:id', async (req, res) => {
}
});

router.get('/picsnap/:type(og-space|og-proposal|og-home)/:id?.:ext(png|svg)?', async (req, res) => {
const { type, id = '', ext = 'png' } = req.params;

try {
const image = new picSnap(type as ImageType, id, storageEngine(process.env.PICSNAP_SUBDIR));

res.setHeader('Cache-Control', 'public, max-age=0, must-revalidate');
res.setHeader('Content-Type', `image/${ext === 'svg' ? 'svg+xml' : 'png'}`);
return res.end(
ext === 'svg' ? await image.getSvg() : (await image.getCache()) || (await image.createCache())
);
} catch (e: any) {
capture(e);
return rpcError(res, e, id || type);
}
});

router.get('/moderation', async (req, res) => {
const { list } = req.query;

Expand Down
Binary file added src/assets/fonts/Calibre-Medium-Custom.woff
Binary file not shown.
Binary file added src/assets/fonts/Calibre-Semibold-Custom.woff
Binary file not shown.
30 changes: 20 additions & 10 deletions src/helpers/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { gql, ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client
import { setContext } from '@apollo/client/link/context';
import fetch from 'cross-fetch';

export type State = 'pending' | 'active' | 'closed';

export type Proposal = {
id: string;
state: string;
title: string;
state: State;
choices: string[];
space: Space;
votes: number;
Expand All @@ -22,7 +25,10 @@ export type Vote = {

export type Space = {
id: string;
name: string;
about?: string;
network: string;
followersCount?: number;
};

const httpLink = createHttpLink({
Expand Down Expand Up @@ -62,6 +68,7 @@ const PROPOSAL_QUERY = gql`
query Proposal($id: String) {
proposal(id: $id) {
id
title
state
choices
votes
Expand All @@ -74,6 +81,18 @@ const PROPOSAL_QUERY = gql`
}
`;

const SPACE_QUERY = gql`
query Space($id: String) {
space(id: $id) {
id
name
about
network
followersCount
}
}
`;

const VOTES_QUERY = gql`
query Votes(
$id: String!
Expand All @@ -100,15 +119,6 @@ const VOTES_QUERY = gql`
}
`;

const SPACE_QUERY = gql`
query Space($id: String) {
space(id: $id) {
id
network
}
}
`;

export async function fetchProposal(id: string) {
const {
data: { proposal }
Expand Down
19 changes: 11 additions & 8 deletions src/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ export function rpcError(res: Response, e: Error | string, id: string | number)
const errorMessage = e instanceof Error ? e.message : e;
const errorCode = ERROR_CODES[errorMessage] ? ERROR_CODES[errorMessage] : -32603;

res.status(errorCode > 0 ? errorCode : 500).json({
jsonrpc: '2.0',
error: {
code: errorCode,
message: errorMessage
},
id
});
res
.setHeader('Content-Type', 'application/json')
.status(errorCode > 0 ? errorCode : 500)
.json({
jsonrpc: '2.0',
error: {
code: errorCode,
message: errorMessage
},
id
});
}

export async function sleep(time: number) {
Expand Down
39 changes: 39 additions & 0 deletions src/lib/picSnap/components/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
type LogoParams = {
logoColor: string;
textColor: string;
width: number;
height: number;
};

export default function (props: Partial<LogoParams>) {
const WIDTH = 590;
const HEIGHT = 126;
const { logoColor, textColor, width, height } = {
...{ logoColor: '#FFAC33', textColor: '#000' },
...props
};
return (
<svg
width={`${width || (height && WIDTH / (HEIGHT / height)) || WIDTH}px`}
height={`${height || (width && HEIGHT / (WIDTH / width)) || HEIGHT}px`}
viewBox="0 0 590 126"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<g id="logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" fill-rule="nonzero">
<path
d="M104.781694,54.7785 C104.270697,53.41 102.961707,52.5 101.498717,52.5 L59.2365129,52.5 L83.6138421,5.103 C84.3803368,3.612 83.9848395,1.7885 82.6653488,0.7525 C82.0283532,0.2485 81.2618586,0 80.498864,0 C79.6833697,0 78.8678754,0.287 78.21338,0.8505 L52.4990602,23.058 L1.21391953,67.3505 C0.107927276,68.306 -0.291069928,69.8495 0.219926491,71.218 C0.730922911,72.5865 2.03641376,73.5 3.49940351,73.5 L45.7616074,73.5 L21.3842782,120.897 C20.6177836,122.388 21.0132808,124.2115 22.3327715,125.2475 C22.9697671,125.7515 23.7362617,126 24.4992564,126 C25.3147506,126 26.1302449,125.713 26.7847403,125.1495 L52.4990602,102.942 L103.784201,58.6495 C104.893693,57.694 105.28919,56.1505 104.781694,54.7785 L104.781694,54.7785 Z"
id="Path"
fill={logoColor}
></path>
<path
d="M163.682969,89.9237288 C170.145678,89.9237288 175.401743,88.3231401 179.451163,85.1219625 C183.500582,81.8797443 185.525292,77.5294261 185.525292,72.071008 C185.484389,63.7397383 180.698711,58.4454832 171.168259,56.1882426 L171.168259,56.1882426 L159.38813,53.4179929 C155.543226,52.3919744 153.620775,50.6682635 153.620775,48.2468599 C153.620775,46.1537823 154.500194,44.5531936 156.259033,43.4450937 C158.017872,42.3369938 160.103936,41.7829438 162.517227,41.7829438 C168.039162,41.7829438 171.43413,43.8349807 172.70213,47.9390544 L172.70213,47.9390544 L185.034453,47.9390544 C184.011872,42.7679215 181.619034,38.7254089 177.855937,35.8115165 C174.09284,32.8976241 169.082195,31.440678 162.824001,31.440678 C156.565807,31.440678 151.452904,33.1028278 147.485291,36.4271276 C143.517678,39.7514273 141.533871,43.9375825 141.533871,48.9855932 C141.533871,57.0706185 146.135484,62.2007107 155.33871,64.3758698 L155.33871,64.3758698 L166.934775,67.1461195 C169.307162,67.7206899 170.984195,68.4594231 171.965872,69.3623194 C172.947549,70.2652156 173.438388,71.6195599 173.438388,73.4253524 C173.438388,75.2721855 172.57942,76.7701725 170.861485,77.9193131 C169.143549,79.0684538 166.832517,79.6430241 163.928388,79.6430241 C157.956517,79.6430241 154.254775,77.2831817 152.823162,72.5634969 L152.823162,72.5634969 L140,72.5634969 C140.818065,77.8987927 143.354065,82.1259887 147.608,85.2450847 C151.861936,88.3641808 157.220259,89.9237288 163.682969,89.9237288 Z M210.336032,88.1779661 L210.336032,51.6952798 C210.989244,49.0516068 212.397734,46.9163325 214.561501,45.2894569 C216.725268,43.6625813 219.378944,42.8491434 222.52253,42.8491434 C225.666116,42.8491434 228.115663,43.8456048 229.871172,45.8385274 C231.626681,47.8314501 232.504435,50.6174746 232.504435,54.1966011 L232.504435,54.1966011 L232.504435,88.1779661 L245.058366,88.1779661 L245.058366,52.0613268 C245.01754,45.7978555 243.282444,40.7952129 239.853078,37.0533989 C236.423711,33.311585 231.585855,31.440678 225.339509,31.440678 C219.093163,31.440678 214.092004,33.6166241 210.336032,37.9685165 L210.336032,37.9685165 L210.336032,32.7218425 L197.782101,32.7218425 L197.782101,88.1779661 L210.336032,88.1779661 Z M278.100767,89.0406995 C281.035204,89.1218834 283.806616,88.7159636 286.415004,87.82294 C289.023392,86.9299164 290.837037,85.9760049 291.855939,84.9612053 L291.855939,84.9612053 L291.855939,88.0664919 L303.715953,88.0664919 L303.715953,51.7772606 C303.715953,45.4449115 301.759662,40.4723938 297.84708,36.8597075 C293.934498,33.2470211 288.819612,31.440678 282.502422,31.440678 C276.225989,31.440678 271.049968,33.0034692 266.974362,36.1290518 C262.898756,39.2546344 260.453392,43.2326485 259.638271,48.0630943 L259.638271,48.0630943 L271.681687,48.0630943 C273.10815,44.0444882 276.287123,42.0351851 281.218606,42.0351851 C284.642116,42.0351851 287.270882,42.9688007 289.104905,44.8360318 C290.938927,46.7032629 291.855939,49.0981898 291.855939,52.0208125 L291.855939,52.0208125 L291.855939,56.5265224 C290.674013,55.6740908 288.819612,54.9028432 286.292736,54.2127795 C283.76586,53.5227158 281.320496,53.177684 278.956645,53.177684 C272.761723,53.2182759 267.606081,54.9028432 263.489719,58.2313856 C259.373356,61.5599281 257.315175,65.8829741 257.315175,71.2005237 C257.315175,76.5180732 259.291844,80.8208232 263.245182,84.1087737 C267.239277,87.3967242 272.191138,89.0406995 278.100767,89.0406995 Z M279.622568,79.4491525 C276.789883,79.4491525 274.2607,78.7642764 272.035019,77.3945241 C269.809339,76.0247718 268.696498,74.0708605 268.696498,71.5327901 C268.696498,68.9947197 269.829572,67.0609518 272.09572,65.7314863 C274.361868,64.4020209 276.911284,63.7372881 279.743969,63.7372881 C282.576654,63.7372881 285.085603,64.2610169 287.270817,65.3084746 C289.456031,66.3559322 290.85214,67.7055411 291.459144,69.3573012 L291.459144,69.3573012 L291.459144,73.8895698 C290.811673,75.501043 289.395331,76.8305085 287.210117,77.8779661 C284.984436,78.9254237 282.455253,79.4491525 279.622568,79.4491525 Z M331.149901,110 L331.149901,83.8135593 C332.496803,85.5347338 334.455933,86.9690459 337.027292,88.1164956 C339.59865,89.2639453 342.353677,89.8376701 345.292373,89.8376701 C353.128894,89.8376701 359.39403,87.0100263 364.08778,81.3547386 C368.78153,75.6994509 371.128405,68.7942628 371.128405,60.639174 C371.087589,52.4840853 368.740715,45.5788971 364.08778,39.9236095 C359.434845,34.2683218 353.16971,31.440678 345.292373,31.440678 C342.353677,31.440678 339.59865,32.034893 337.027292,33.223323 C334.455933,34.411753 332.496803,35.8460651 331.149901,37.5262593 L331.149901,37.5262593 L331.149901,32.7315588 L318.599222,32.7315588 L318.599222,110 L331.149901,110 Z M343.112444,78.5762712 C340.48607,78.5762712 338.068138,77.8841229 335.858649,76.4998265 C333.649159,75.11553 331.98162,73.3444448 330.856031,71.1865708 L330.856031,71.1865708 L330.856031,50.1778359 C331.98162,48.019962 333.649159,46.2488768 335.858649,44.8645803 C338.068138,43.4802838 340.48607,42.7881356 343.112444,42.7881356 C347.989996,42.7881356 351.84618,44.4574343 354.680997,47.7960317 C357.474125,51.1346291 358.870689,55.4300197 358.870689,60.6822034 C358.912378,65.9343871 357.515813,70.2297777 354.680997,73.5683751 C351.84618,76.9069725 347.989996,78.5762712 343.112444,78.5762712 Z M402.690751,89.9237288 C409.153461,89.9237288 414.409525,88.3231401 418.458945,85.1219625 C422.508364,81.8797443 424.533074,77.5294261 424.533074,72.071008 C424.492171,63.7397383 419.706493,58.4454832 410.176041,56.1882426 L410.176041,56.1882426 L398.395912,53.4179929 C394.551008,52.3919744 392.628557,50.6682635 392.628557,48.2468599 C392.628557,46.1537823 393.507976,44.5531936 395.266815,43.4450937 C397.025654,42.3369938 399.111718,41.7829438 401.525009,41.7829438 C407.046944,41.7829438 410.441912,43.8349807 411.709912,47.9390544 L411.709912,47.9390544 L424.042235,47.9390544 C423.019655,42.7679215 420.626816,38.7254089 416.863719,35.8115165 C413.100622,32.8976241 408.089977,31.440678 401.831783,31.440678 C395.573589,31.440678 390.460686,33.1028278 386.493073,36.4271276 C382.52546,39.7514273 380.541653,43.9375825 380.541653,48.9855932 C380.541653,57.0706185 385.143266,62.2007107 394.346492,64.3758698 L394.346492,64.3758698 L405.942557,67.1461195 C408.314944,67.7206899 409.991977,68.4594231 410.973654,69.3623194 C411.955332,70.2652156 412.44617,71.6195599 412.44617,73.4253524 C412.44617,75.2721855 411.587203,76.7701725 409.869267,77.9193131 C408.151331,79.0684538 405.840299,79.6430241 402.93617,79.6430241 C396.964299,79.6430241 393.262557,77.2831817 391.830944,72.5634969 L391.830944,72.5634969 L379.007782,72.5634969 C379.825847,77.8987927 382.361847,82.1259887 386.615782,85.2450847 C390.869718,88.3641808 396.228041,89.9237288 402.690751,89.9237288 Z M450.2193,89.0508475 L450.2193,52.1865298 C450.872513,49.5152025 452.281002,47.3575919 454.444769,45.7136981 C456.608536,44.0698044 459.262212,43.2478575 462.405798,43.2478575 C465.549384,43.2478575 467.998931,44.2547424 469.75444,46.2685123 C471.509949,48.2822821 472.387704,51.0974502 472.387704,54.7140165 L472.387704,54.7140165 L472.387704,89.0508475 L484.941634,89.0508475 L484.941634,52.5564059 C484.900808,46.2274149 483.165712,41.1724416 479.736346,37.3914859 C476.30698,33.6105303 471.469124,31.7200525 465.222778,31.7200525 C458.976432,31.7200525 453.975273,33.9187604 450.2193,38.3161762 L450.2193,38.3161762 L450.2193,7 L437.66537,7 L437.66537,89.0508475 L450.2193,89.0508475 Z M522.180675,89.9237288 C530.083331,89.9237288 536.50424,87.1945198 541.4434,81.7361017 C546.38256,76.2776836 548.85214,69.2597175 548.85214,60.6822034 C548.85214,52.1046893 546.38256,45.0867232 541.4434,39.6283051 C536.50424,34.169887 530.083331,31.440678 522.180675,31.440678 C514.236859,31.440678 507.795371,34.169887 502.856211,39.6283051 C497.917051,45.0867232 495.447471,52.1046893 495.447471,60.6822034 C495.447471,69.2597175 497.917051,76.2776836 502.856211,81.7361017 C507.836531,87.1945198 514.278019,89.9237288 522.180675,89.9237288 Z M522.618335,79.4491525 C518.185103,79.4491525 514.737033,77.7530185 512.274127,74.3607505 C509.81122,70.9684825 508.579767,66.554447 508.579767,61.1186441 C508.579767,55.6828411 509.81122,51.2688056 512.274127,47.8765376 C514.695985,44.4842696 518.144054,42.7881356 522.618335,42.7881356 C527.092616,42.7881356 530.540685,44.4842696 532.962543,47.8765376 C535.384402,51.2688056 536.595331,55.6828411 536.595331,61.1186441 C536.595331,66.554447 535.384402,70.9684825 532.962543,74.3607505 C530.540685,77.7530185 527.092616,79.4491525 522.618335,79.4491525 Z M579.732516,89.9237288 C584.295842,89.9237288 587.718337,89.2728505 590,87.971094 L590,87.971094 L590,76.5603841 C587.922057,78.0655401 585.538534,78.8181181 582.849431,78.8181181 C578.44908,78.8181181 576.248905,76.6620838 576.248905,72.3500152 L576.248905,72.3500152 L576.248905,43.609671 L588.77768,43.609671 L588.77768,33.2362984 L576.248905,33.2362984 L576.248905,18.3474576 L563.72013,18.3474576 L563.72013,33.2362984 L554.980545,33.2362984 L554.980545,43.609671 L563.72013,43.609671 L563.72013,73.6924516 C563.72013,78.9808377 565.248029,83.0081471 568.303828,85.7743798 C571.359627,88.5406125 575.169189,89.9237288 579.732516,89.9237288 Z"
id="snapshot"
fill={textColor}
></path>
</g>
</g>
</svg>
);
}
20 changes: 20 additions & 0 deletions src/lib/picSnap/components/membersIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default function () {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 24 24"
style={{ marginRight: '17px', marginTop: '-4px' }}
>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 20h5v-2a3 3 0 0 0-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 0 1 5.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 0 1 9.288 0M15 7a3 3 0 1 1-6 0a3 3 0 0 1 6 0Zm6 3a2 2 0 1 1-4 0a2 2 0 0 1 4 0ZM7 10a2 2 0 1 1-4 0a2 2 0 0 1 4 0Z"
/>
</svg>
);
}
Loading
Loading