Skip to content

Commit 450f7bc

Browse files
authored
Merge branch 'master' into live_comments
2 parents efb12d6 + 06df4b7 commit 450f7bc

File tree

14 files changed

+565
-20
lines changed

14 files changed

+565
-20
lines changed

api/resolvers/item.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ import { verifyHmac } from './wallet'
2828
import { parse } from 'tldts'
2929
import { shuffleArray } from '@/lib/rand'
3030

31-
metadataRuleSets.title.rules.unshift(['h1 > yt-formatted-string.ytd-watch-metadata', el => el.getAttribute('title')])
32-
3331
function commentsOrderByClause (me, models, sort) {
3432
const sharedSortsArray = []
3533
sharedSortsArray.push('("Item"."pinId" IS NOT NULL) DESC')
3634
sharedSortsArray.push('("Item"."deletedAt" IS NULL) DESC')
35+
// outlawed items should be at the bottom
36+
sharedSortsArray.push(`NOT ("Item"."weightedVotes" - "Item"."weightedDownVotes" <= -${ITEM_FILTER_THRESHOLD} OR "Item".outlawed) DESC`)
3737
const sharedSorts = sharedSortsArray.join(', ')
3838

3939
if (sort === 'recent') {
@@ -595,7 +595,13 @@ export default {
595595
const response = await fetch(ensureProtocol(url), { redirect: 'follow' })
596596
const html = await response.text()
597597
const doc = domino.createWindow(html).document
598-
const metadata = getMetadata(doc, url, { title: metadataRuleSets.title, publicationDate: publicationDateRuleSet })
598+
const titleRuleSet = {
599+
rules: [
600+
['h1 > yt-formatted-string.ytd-watch-metadata', el => el.getAttribute('title')],
601+
...metadataRuleSets.title.rules
602+
]
603+
}
604+
const metadata = getMetadata(doc, url, { title: titleRuleSet, publicationDate: publicationDateRuleSet })
599605
const dateHint = ` (${metadata.publicationDate?.getFullYear()})`
600606
const moreThanOneYearAgo = metadata.publicationDate && metadata.publicationDate < datePivot(new Date(), { years: -1 })
601607

components/fireworks.js

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
import { useCallback, createContext, useContext, useState, useEffect } from 'react'
2+
import Particles from 'react-particles'
3+
import { loadFireworksPreset } from 'tsparticles-preset-fireworks'
4+
import styles from './fireworks.module.css'
5+
import {
6+
rgbToHsl,
7+
setRangeValue,
8+
stringToRgb
9+
} from 'tsparticles-engine'
10+
import useDarkMode from './dark-mode'
11+
12+
export const FireworksContext = createContext({
13+
strike: () => {}
14+
})
15+
16+
export const FireworksConsumer = FireworksContext.Consumer
17+
export function useFireworks () {
18+
const { strike } = useContext(FireworksContext)
19+
return strike
20+
}
21+
22+
export function FireworksProvider ({ children }) {
23+
const [cont, setCont] = useState()
24+
const [context, setContext] = useState({ strike: () => {} })
25+
const [darkMode] = useDarkMode()
26+
27+
useEffect(() => {
28+
setContext({
29+
strike: () => {
30+
const should = window.localStorage.getItem('lnAnimate') || 'yes'
31+
if (should !== 'yes') return false
32+
cont?.addEmitter(
33+
{
34+
direction: 'top',
35+
life: {
36+
count: 1,
37+
duration: 0.1,
38+
delay: 0.1
39+
},
40+
rate: {
41+
delay: 0,
42+
quantity: 1
43+
},
44+
size: {
45+
width: 10,
46+
height: 0
47+
},
48+
position: {
49+
y: 100,
50+
x: 50
51+
}
52+
})
53+
return true
54+
}
55+
})
56+
}, [cont])
57+
58+
const particlesLoaded = useCallback((container) => {
59+
setCont(container)
60+
}, [])
61+
62+
const particlesInit = useCallback(async engine => {
63+
// you can initiate the tsParticles instance (engine) here, adding custom shapes or presets
64+
// this loads the tsparticles package bundle, it's the easiest method for getting everything ready
65+
// starting from v2 you can add only the features you need reducing the bundle size
66+
await loadFireworksPreset(engine)
67+
}, [])
68+
69+
return (
70+
<FireworksContext.Provider value={context}>
71+
<Particles
72+
className={styles.fireworks}
73+
init={particlesInit}
74+
loaded={particlesLoaded}
75+
options={darkMode ? darkOptions : lightOptions}
76+
/>
77+
{children}
78+
</FireworksContext.Provider>
79+
)
80+
}
81+
82+
const fixRange = (value, min, max) => {
83+
const diffSMax = value.max > max ? value.max - max : 0
84+
let res = setRangeValue(value)
85+
86+
if (diffSMax) {
87+
res = setRangeValue(value.min - diffSMax, max)
88+
}
89+
90+
const diffSMin = value.min < min ? value.min : 0
91+
92+
if (diffSMin) {
93+
res = setRangeValue(0, value.max + diffSMin)
94+
}
95+
96+
return res
97+
}
98+
99+
const fireworksOptions = ['#ff595e', '#ffca3a', '#8ac926', '#1982c4', '#6a4c93']
100+
.map((color) => {
101+
const rgb = stringToRgb(color)
102+
103+
if (!rgb) {
104+
return undefined
105+
}
106+
107+
const hsl = rgbToHsl(rgb)
108+
const sRange = fixRange({ min: hsl.s - 30, max: hsl.s + 30 }, 0, 100)
109+
const lRange = fixRange({ min: hsl.l - 30, max: hsl.l + 30 }, 0, 100)
110+
111+
return {
112+
color: {
113+
value: {
114+
h: hsl.h,
115+
s: sRange,
116+
l: lRange
117+
}
118+
},
119+
stroke: {
120+
width: 0
121+
},
122+
number: {
123+
value: 0
124+
},
125+
opacity: {
126+
value: {
127+
min: 0.1,
128+
max: 1
129+
},
130+
animation: {
131+
enable: true,
132+
speed: 0.7,
133+
sync: false,
134+
startValue: 'max',
135+
destroy: 'min'
136+
}
137+
},
138+
shape: {
139+
type: 'circle'
140+
},
141+
size: {
142+
value: { min: 1, max: 2 },
143+
animation: {
144+
enable: true,
145+
speed: 5,
146+
count: 1,
147+
sync: false,
148+
startValue: 'min',
149+
destroy: 'none'
150+
}
151+
},
152+
life: {
153+
count: 1,
154+
duration: {
155+
value: {
156+
min: 1,
157+
max: 2
158+
}
159+
}
160+
},
161+
move: {
162+
decay: { min: 0.075, max: 0.1 },
163+
enable: true,
164+
gravity: {
165+
enable: true,
166+
inverse: false,
167+
acceleration: 5
168+
},
169+
speed: { min: 5, max: 15 },
170+
direction: 'none',
171+
outMode: {
172+
top: 'destroy',
173+
default: 'bounce'
174+
}
175+
}
176+
}
177+
})
178+
.filter((t) => t !== undefined)
179+
180+
const particlesOptions = (theme) => ({
181+
number: {
182+
value: 0
183+
},
184+
destroy: {
185+
mode: 'split',
186+
bounds: {
187+
top: { min: 5, max: 40 }
188+
},
189+
split: {
190+
sizeOffset: false,
191+
count: 1,
192+
factor: {
193+
value: 0.333333
194+
},
195+
rate: {
196+
value: { min: 75, max: 150 }
197+
},
198+
particles: fireworksOptions
199+
}
200+
},
201+
life: {
202+
count: 1
203+
},
204+
shape: {
205+
type: 'line'
206+
},
207+
size: {
208+
value: {
209+
min: 0.1,
210+
max: 50
211+
},
212+
animation: {
213+
enable: true,
214+
sync: true,
215+
speed: 90,
216+
startValue: 'max',
217+
destroy: 'min'
218+
}
219+
},
220+
rotate: {
221+
path: true
222+
},
223+
stroke: {
224+
color: {
225+
value: theme === 'dark' ? '#fff' : '#aaa'
226+
},
227+
width: 1
228+
},
229+
move: {
230+
enable: true,
231+
gravity: {
232+
acceleration: 15,
233+
enable: true,
234+
inverse: true,
235+
maxSpeed: 100
236+
},
237+
speed: {
238+
min: 10,
239+
max: 20
240+
},
241+
outModes: {
242+
default: 'split',
243+
top: 'none'
244+
},
245+
trail: {
246+
fillColor: theme === 'dark' ? '#000' : '#f5f5f7',
247+
enable: true,
248+
length: 10
249+
}
250+
}
251+
})
252+
253+
const darkOptions = {
254+
fullScreen: { enable: true, zIndex: -1 },
255+
detectRetina: true,
256+
background: {
257+
color: '#000',
258+
opacity: 0
259+
},
260+
fpsLimit: 120,
261+
emitters: [],
262+
particles: particlesOptions('dark')
263+
}
264+
265+
const lightOptions = {
266+
fullScreen: { enable: true, zIndex: -1 },
267+
detectRetina: true,
268+
background: {
269+
color: '#fff',
270+
opacity: 0
271+
},
272+
fpsLimit: 120,
273+
emitters: [],
274+
particles: particlesOptions('light')
275+
}

components/fireworks.module.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.fireworks {
2+
z-index: 0;
3+
position: fixed;
4+
top: 0;
5+
left: 0;
6+
width: 100vw;
7+
height: 100vh;
8+
}

components/item-act.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import { useMe } from './me'
66
import UpBolt from '@/svgs/bolt.svg'
77
import { amountSchema, boostSchema } from '@/lib/validate'
88
import { useToast } from './toast'
9-
import { useLightning } from './lightning'
109
import { nextTip, defaultTipIncludingRandom } from './upvote'
1110
import { ZAP_UNDO_DELAY_MS } from '@/lib/constants'
1211
import { usePaidMutation } from './use-paid-mutation'
1312
import { ACT_MUTATION } from '@/fragments/paidAction'
1413
import { meAnonSats } from '@/lib/apollo'
1514
import { BoostItemInput } from './adv-post-form'
1615
import { useSendWallets } from '@/wallets/index'
16+
import { useFireworks } from './fireworks'
1717

1818
const defaultTips = [100, 1000, 10_000, 100_000]
1919

@@ -96,7 +96,7 @@ export default function ItemAct ({ onClose, item, act = 'TIP', step, children, a
9696
}, [onClose, item.id])
9797

9898
const actor = useAct()
99-
const strike = useLightning()
99+
const strike = useFireworks()
100100

101101
const onSubmit = useCallback(async ({ amount }) => {
102102
if (abortSignal && zapUndoTrigger({ me, amount })) {
@@ -300,7 +300,7 @@ export function useAct ({ query = ACT_MUTATION, ...options } = {}) {
300300
export function useZap () {
301301
const wallets = useSendWallets()
302302
const act = useAct()
303-
const strike = useLightning()
303+
const strike = useFireworks()
304304
const toaster = useToast()
305305

306306
return useCallback(async ({ item, me, abortSignal }) => {

components/layout.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
height: 100%;
66
align-items: center;
77
margin: auto;
8+
z-index: 0;
89
}
910

1011
.content {

components/nav/common.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { useServiceWorker } from '../serviceworker'
1515
import { signOut } from 'next-auth/react'
1616
import Badges from '../badge'
1717
import { randInRange } from '../../lib/rand'
18-
import { useLightning } from '../lightning'
18+
import { useFireworks } from '../fireworks'
1919
import LightningIcon from '../../svgs/bolt.svg'
2020
import SearchIcon from '../../svgs/search-line.svg'
2121
import classNames from 'classnames'
@@ -400,13 +400,15 @@ export function LoginButtons ({ handleClose }) {
400400
}
401401

402402
export function AnonDropdown ({ path }) {
403-
const strike = useLightning()
403+
const strike = useFireworks()
404404

405405
useEffect(() => {
406406
if (!window.localStorage.getItem('striked')) {
407407
const to = setTimeout(() => {
408-
strike()
409-
window.localStorage.setItem('striked', 'yep')
408+
const striked = strike()
409+
if (striked) {
410+
window.localStorage.setItem('striked', 'yep')
411+
}
410412
}, randInRange(3000, 10000))
411413
return () => clearTimeout(to)
412414
}

0 commit comments

Comments
 (0)