july 4th festivities

This commit is contained in:
keyan 2023-07-03 14:46:54 -05:00
parent eac73e7169
commit b6628eb159
9 changed files with 21609 additions and 70 deletions

2
.npmrc
View File

@ -1 +1,3 @@
unsafe-perm=true unsafe-perm=true
legacy-peer-deps=true

View File

@ -8,4 +8,4 @@ WORKDIR /app
EXPOSE 3000 EXPOSE 3000
CMD npm install --loglevel verbose; npx prisma migrate dev; npm run dev CMD npm install --loglevel verbose --legacy-peer-deps; npx prisma migrate dev; npm run dev

268
components/fireworks.js Normal file
View File

@ -0,0 +1,268 @@
import { useCallback, createContext, useContext, useState, useEffect } from 'react'
import Particles from 'react-particles'
import { loadFireworksPreset } from 'tsparticles-preset-fireworks'
import styles from './fireworks.module.css'
import {
rgbToHsl,
setRangeValue,
stringToRgb
} from 'tsparticles-engine'
import useDarkMode from 'use-dark-mode'
export const FireworksContext = createContext({
strike: () => {}
})
export const FireworksConsumer = FireworksContext.Consumer
export function useFireworks () {
const { strike } = useContext(FireworksContext)
return strike
}
export function FireworksProvider ({ children }) {
const [cont, setCont] = useState()
const [context, setContext] = useState({ strike: () => {} })
const darkMode = useDarkMode(false)
useEffect(() => {
setContext({
strike: () => {
cont?.addEmitter(
{
direction: 'top',
life: {
count: 1,
duration: 0.1,
delay: 0.1
},
rate: {
delay: 0,
quantity: 1
},
size: {
width: 50,
height: 0
},
position: {
y: 100,
x: 50
}
})
}
})
}, [cont])
const particlesLoaded = useCallback((container) => {
setCont(container)
}, [])
const particlesInit = useCallback(async engine => {
// you can initiate the tsParticles instance (engine) here, adding custom shapes or presets
// this loads the tsparticles package bundle, it's the easiest method for getting everything ready
// starting from v2 you can add only the features you need reducing the bundle size
await loadFireworksPreset(engine)
}, [])
return (
<FireworksContext.Provider value={context}>
<Particles
className={styles.fireworks}
init={particlesInit}
loaded={particlesLoaded}
options={darkMode.value ? darkOptions : lightOptions}
/>
{children}
</FireworksContext.Provider>
)
}
const fixRange = (value, min, max) => {
const diffSMax = value.max > max ? value.max - max : 0
let res = setRangeValue(value)
if (diffSMax) {
res = setRangeValue(value.min - diffSMax, max)
}
const diffSMin = value.min < min ? value.min : 0
if (diffSMin) {
res = setRangeValue(0, value.max + diffSMin)
}
return res
}
const fireworksOptions = ['#ff595e', '#ffca3a', '#8ac926', '#1982c4', '#6a4c93']
.map((color) => {
const rgb = stringToRgb(color)
if (!rgb) {
return undefined
}
const hsl = rgbToHsl(rgb)
const sRange = fixRange({ min: hsl.s - 30, max: hsl.s + 30 }, 0, 100)
const lRange = fixRange({ min: hsl.l - 30, max: hsl.l + 30 }, 0, 100)
return {
color: {
value: {
h: hsl.h,
s: sRange,
l: lRange
}
},
stroke: {
width: 0
},
number: {
value: 0
},
opacity: {
value: {
min: 0.1,
max: 1
},
animation: {
enable: true,
speed: 0.7,
sync: false,
startValue: 'max',
destroy: 'min'
}
},
shape: {
type: 'circle'
},
size: {
value: { min: 1, max: 2 },
animation: {
enable: true,
speed: 5,
count: 1,
sync: false,
startValue: 'min',
destroy: 'none'
}
},
life: {
count: 1,
duration: {
value: {
min: 1,
max: 2
}
}
},
move: {
decay: { min: 0.075, max: 0.1 },
enable: true,
gravity: {
enable: true,
inverse: false,
acceleration: 5
},
speed: { min: 5, max: 15 },
direction: 'none',
outModes: 'destroy'
}
}
})
.filter((t) => t !== undefined)
const particlesOptions = (theme) => ({
number: {
value: 0
},
destroy: {
mode: 'split',
bounds: {
top: { min: 5, max: 50 }
},
split: {
sizeOffset: false,
count: 1,
factor: {
value: 0.333333
},
rate: {
value: { min: 75, max: 150 }
},
particles: fireworksOptions
}
},
life: {
count: 1
},
shape: {
type: 'line'
},
size: {
value: {
min: 0.1,
max: 50
},
animation: {
enable: true,
sync: true,
speed: 90,
startValue: 'max',
destroy: 'min'
}
},
rotate: {
path: true
},
stroke: {
color: {
value: theme === 'dark' ? '#fff' : '#aaa'
},
width: 1
},
move: {
enable: true,
gravity: {
acceleration: 15,
enable: true,
inverse: true,
maxSpeed: 100
},
direction: 'top-center',
speed: {
min: 10,
max: 20
},
outModes: {
default: 'destroy',
top: 'none'
},
trail: {
fillColor: theme === 'dark' ? '#000' : '#f5f5f7',
enable: true,
length: 10
}
}
})
const darkOptions = {
detectRetina: true,
background: {
color: '#000'
},
zIndex: -1,
fpsLimit: 120,
emitters: [],
particles: particlesOptions('dark')
}
const lightOptions = {
detectRetina: true,
background: {
color: '#fff'
},
zIndex: -1,
fpsLimit: 120,
emitters: [],
particles: particlesOptions('light')
}

View File

@ -0,0 +1,8 @@
.fireworks {
z-index: -1;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: vh;
}

View File

@ -8,7 +8,6 @@ import Price from './price'
import { useMe } from './me' import { useMe } from './me'
import Head from 'next/head' import Head from 'next/head'
import { signOut } from 'next-auth/client' import { signOut } from 'next-auth/client'
import { useLightning } from './lightning'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { randInRange } from '../lib/rand' import { randInRange } from '../lib/rand'
import { abbrNum } from '../lib/format' import { abbrNum } from '../lib/format'
@ -21,6 +20,7 @@ import SearchIcon from '../svgs/search-line.svg'
import BackArrow from '../svgs/arrow-left-line.svg' import BackArrow from '../svgs/arrow-left-line.svg'
import { useNotification } from './notifications' import { useNotification } from './notifications'
import { SUBS } from '../lib/constants' import { SUBS } from '../lib/constants'
import { useFireworks } from './fireworks'
function WalletSummary ({ me }) { function WalletSummary ({ me }) {
if (!me) return null if (!me) return null
@ -167,7 +167,7 @@ export default function Header ({ sub }) {
) )
} else { } else {
if (!fired) { if (!fired) {
const strike = useLightning() const strike = useFireworks()
useEffect(() => { useEffect(() => {
let isMounted = true let isMounted = true
if (!localStorage.getItem('striked')) { if (!localStorage.getItem('striked')) {

View File

@ -12,6 +12,7 @@ import LongPressable from 'react-longpressable'
import { Overlay, Popover } from 'react-bootstrap' import { Overlay, Popover } from 'react-bootstrap'
import { useShowModal } from './modal' import { useShowModal } from './modal'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { FireworksConsumer } from './fireworks'
const getColor = (meSats) => { const getColor = (meSats) => {
if (!meSats || meSats <= 10) { if (!meSats || meSats <= 10) {
@ -175,7 +176,7 @@ export default function UpVote ({ item, className }) {
const color = getColor(item?.meSats) const color = getColor(item?.meSats)
return ( return (
<LightningConsumer> <FireworksConsumer>
{({ strike }) => {({ strike }) =>
<div ref={ref} className='upvoteParent'> <div ref={ref} className='upvoteParent'>
<LongPressable <LongPressable
@ -263,6 +264,6 @@ export default function UpVote ({ item, className }) {
<TipPopover target={ref.current} show={tipShow} handleClose={() => setTipShow(false)} /> <TipPopover target={ref.current} show={tipShow} handleClose={() => setTipShow(false)} />
<UpvotePopover target={ref.current} show={voteShow} handleClose={() => setVoteShow(false)} /> <UpvotePopover target={ref.current} show={voteShow} handleClose={() => setVoteShow(false)} />
</div>} </div>}
</LightningConsumer> </FireworksConsumer>
) )
} }

21377
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,7 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-longpressable": "^1.1.1", "react-longpressable": "^1.1.1",
"react-markdown": "^8.0.3", "react-markdown": "^8.0.3",
"react-particles": "^2.10.1",
"react-string-replace": "^0.4.4", "react-string-replace": "^0.4.4",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",
"react-textarea-autosize": "^8.3.4", "react-textarea-autosize": "^8.3.4",
@ -75,6 +76,8 @@
"secp256k1": "^4.0.3", "secp256k1": "^4.0.3",
"swr": "^1.3.0", "swr": "^1.3.0",
"tldts": "^5.7.104", "tldts": "^5.7.104",
"tsparticles-engine": "^2.10.1",
"tsparticles-preset-fireworks": "^2.10.1",
"unist-util-visit": "^4.1.1", "unist-util-visit": "^4.1.1",
"url-unshort": "^6.1.0", "url-unshort": "^6.1.0",
"use-dark-mode": "^2.3.1", "use-dark-mode": "^2.3.1",
@ -83,7 +86,7 @@
"yup": "^0.32.11" "yup": "^0.32.11"
}, },
"engines": { "engines": {
"node": "14.17.0" "node": "16.16.0"
}, },
"standard": { "standard": {
"parser": "@babel/eslint-parser", "parser": "@babel/eslint-parser",

View File

@ -3,7 +3,6 @@ import { ApolloProvider, gql, useQuery } from '@apollo/client'
import { Provider } from 'next-auth/client' import { Provider } from 'next-auth/client'
import { MeProvider } from '../components/me' import { MeProvider } from '../components/me'
import PlausibleProvider from 'next-plausible' import PlausibleProvider from 'next-plausible'
import { LightningProvider } from '../components/lightning'
import getApolloClient from '../lib/apollo' import getApolloClient from '../lib/apollo'
import NextNProgress from 'nextjs-progressbar' import NextNProgress from 'nextjs-progressbar'
import { PriceProvider } from '../components/price' import { PriceProvider } from '../components/price'
@ -15,6 +14,7 @@ import Layout from '../components/layout'
import { ShowModalProvider } from '../components/modal' import { ShowModalProvider } from '../components/modal'
import ErrorBoundary from '../components/error-boundary' import ErrorBoundary from '../components/error-boundary'
import { NotificationProvider } from '../components/notifications' import { NotificationProvider } from '../components/notifications'
import { FireworksProvider } from '../components/fireworks'
function CSRWrapper ({ Component, apollo, ...props }) { function CSRWrapper ({ Component, apollo, ...props }) {
const { data, error } = useQuery(gql`${apollo.query}`, { variables: apollo.variables, fetchPolicy: 'cache-first' }) const { data, error } = useQuery(gql`${apollo.query}`, { variables: apollo.variables, fetchPolicy: 'cache-first' })
@ -91,13 +91,13 @@ function MyApp ({ Component, pageProps: { session, ...props } }) {
<MeProvider me={me}> <MeProvider me={me}>
<NotificationProvider> <NotificationProvider>
<PriceProvider price={price}> <PriceProvider price={price}>
<LightningProvider> <FireworksProvider>
<ShowModalProvider> <ShowModalProvider>
{data || !apollo?.query {data || !apollo?.query
? <Component {...props} /> ? <Component {...props} />
: <CSRWrapper Component={Component} {...props} />} : <CSRWrapper Component={Component} {...props} />}
</ShowModalProvider> </ShowModalProvider>
</LightningProvider> </FireworksProvider>
</PriceProvider> </PriceProvider>
</NotificationProvider> </NotificationProvider>
</MeProvider> </MeProvider>