about summary refs log tree commit diff
path: root/src/components/dialogs/nuxs/index.tsx
blob: 36db7764d331ca1a45927b7f1496907ea84a5aa9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import React from 'react'

import {Nux, useNuxs, useUpsertNuxMutation} from '#/state/queries/nuxs'
import {useSession} from '#/state/session'
import {isSnoozed, snooze} from '#/components/dialogs/nuxs/snoozing'
import {TenMillion} from '#/components/dialogs/nuxs/TenMillion'

type Context = {
  activeNux: Nux | undefined
  dismissActiveNux: () => void
}

const queuedNuxs = [Nux.TenMillionDialog]

const Context = React.createContext<Context>({
  activeNux: undefined,
  dismissActiveNux: () => {},
})

export function useNuxDialogContext() {
  return React.useContext(Context)
}

export function NuxDialogs() {
  const {hasSession} = useSession()
  return hasSession ? <Inner /> : null
}

function Inner() {
  const {nuxs} = useNuxs()
  const [snoozed, setSnoozed] = React.useState(() => {
    return isSnoozed()
  })
  const [activeNux, setActiveNux] = React.useState<Nux | undefined>()
  const {mutate: upsertNux} = useUpsertNuxMutation()

  const snoozeNuxDialog = React.useCallback(() => {
    snooze()
    setSnoozed(true)
  }, [setSnoozed])

  const dismissActiveNux = React.useCallback(() => {
    if (!activeNux) return
    setActiveNux(undefined)
    const nux = nuxs?.find(nux => nux.id === activeNux)
    upsertNux({
      id: activeNux,
      completed: true,
      data: nux?.data,
      expiresAt: nux?.expiresAt,
    })
  }, [activeNux, setActiveNux, upsertNux, nuxs])

  React.useEffect(() => {
    if (snoozed) return
    if (!nuxs) return

    for (const id of queuedNuxs) {
      const nux = nuxs.find(nux => nux.id === id)

      if (nux && nux.completed) continue

      setActiveNux(id)
      // snooze immediately upon enabling
      snoozeNuxDialog()

      break
    }
  }, [nuxs, snoozed, snoozeNuxDialog])

  const ctx = React.useMemo(() => {
    return {
      activeNux,
      dismissActiveNux,
    }
  }, [activeNux, dismissActiveNux])

  return (
    <Context.Provider value={ctx}>
      {activeNux === Nux.TenMillionDialog && <TenMillion />}
    </Context.Provider>
  )
}