forked from Uniswap/info
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathLocalStorage.js
More file actions
181 lines (150 loc) · 4.57 KB
/
LocalStorage.js
File metadata and controls
181 lines (150 loc) · 4.57 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import React, { createContext, useContext, useReducer, useMemo, useCallback, useEffect } from 'react'
const BSCSWAP = 'BSCSWAP'
const VERSION = 'VERSION'
const CURRENT_VERSION = 0
const LAST_SAVED = 'LAST_SAVED'
const DISMISSED_PATHS = 'DISMISSED_PATHS'
const SAVED_ACCOUNTS = 'SAVED_ACCOUNTS'
const SAVED_TOKENS = 'SAVED_TOKENS'
const SAVED_PAIRS = 'SAVED_PAIRS'
const DARK_MODE = 'DARK_MODE'
const UPDATABLE_KEYS = [DARK_MODE, DISMISSED_PATHS, SAVED_ACCOUNTS, SAVED_PAIRS, SAVED_TOKENS]
const UPDATE_KEY = 'UPDATE_KEY'
const LocalStorageContext = createContext()
function useLocalStorageContext() {
return useContext(LocalStorageContext)
}
function reducer(state, { type, payload }) {
switch (type) {
case UPDATE_KEY: {
const { key, value } = payload
if (!UPDATABLE_KEYS.some(k => k === key)) {
throw Error(`Unexpected key in LocalStorageContext reducer: '${key}'.`)
} else {
return {
...state,
[key]: value
}
}
}
default: {
throw Error(`Unexpected action type in LocalStorageContext reducer: '${type}'.`)
}
}
}
function init() {
const defaultLocalStorage = {
[VERSION]: CURRENT_VERSION,
[DARK_MODE]: true,
[DISMISSED_PATHS]: {},
[SAVED_ACCOUNTS]: [],
[SAVED_TOKENS]: {},
[SAVED_PAIRS]: {}
}
try {
const parsed = JSON.parse(window.localStorage.getItem(BSCSWAP))
if (parsed[VERSION] !== CURRENT_VERSION) {
// this is where we could run migration logic
return defaultLocalStorage
} else {
return { ...defaultLocalStorage, ...parsed }
}
} catch {
return defaultLocalStorage
}
}
export default function Provider({ children }) {
const [state, dispatch] = useReducer(reducer, undefined, init)
const updateKey = useCallback((key, value) => {
dispatch({ type: UPDATE_KEY, payload: { key, value } })
}, [])
return (
<LocalStorageContext.Provider value={useMemo(() => [state, { updateKey }], [state, updateKey])}>
{children}
</LocalStorageContext.Provider>
)
}
export function Updater() {
const [state] = useLocalStorageContext()
useEffect(() => {
window.localStorage.setItem(BSCSWAP, JSON.stringify({ ...state, [LAST_SAVED]: Math.floor(Date.now() / 1000) }))
})
return null
}
export function useDarkModeManager() {
const [state, { updateKey }] = useLocalStorageContext()
let isDarkMode = state[DARK_MODE]
const toggleDarkMode = useCallback(
value => {
updateKey(DARK_MODE, value === false || value === true ? value : !isDarkMode)
},
[updateKey, isDarkMode]
)
return [isDarkMode, toggleDarkMode]
}
export function usePathDismissed(path) {
const [state, { updateKey }] = useLocalStorageContext()
const pathDismissed = state?.[DISMISSED_PATHS]?.[path]
function dismiss() {
let newPaths = state?.[DISMISSED_PATHS]
newPaths[path] = true
updateKey(DISMISSED_PATHS, newPaths)
}
return [pathDismissed, dismiss]
}
export function useSavedAccounts() {
const [state, { updateKey }] = useLocalStorageContext()
const savedAccounts = state?.[SAVED_ACCOUNTS]
function addAccount(account) {
let newAccounts = state?.[SAVED_ACCOUNTS]
newAccounts.push(account)
updateKey(SAVED_ACCOUNTS, newAccounts)
}
function removeAccount(account) {
let newAccounts = state?.[SAVED_ACCOUNTS]
let index = newAccounts.indexOf(account)
if (index > -1) {
newAccounts.splice(index, 1)
}
updateKey(SAVED_ACCOUNTS, newAccounts)
}
return [savedAccounts, addAccount, removeAccount]
}
export function useSavedPairs() {
const [state, { updateKey }] = useLocalStorageContext()
const savedPairs = state?.[SAVED_PAIRS]
function addPair(address, token0Address, token1Address, token0Symbol, token1Symbol) {
let newList = state?.[SAVED_PAIRS]
newList[address] = {
address,
token0Address,
token1Address,
token0Symbol,
token1Symbol
}
updateKey(SAVED_PAIRS, newList)
}
function removePair(address) {
let newList = state?.[SAVED_PAIRS]
newList[address] = null
updateKey(SAVED_PAIRS, newList)
}
return [savedPairs, addPair, removePair]
}
export function useSavedTokens() {
const [state, { updateKey }] = useLocalStorageContext()
const savedTokens = state?.[SAVED_TOKENS]
function addToken(address, symbol) {
let newList = state?.[SAVED_TOKENS]
newList[address] = {
symbol
}
updateKey(SAVED_TOKENS, newList)
}
function removeToken(address) {
let newList = state?.[SAVED_TOKENS]
newList[address] = null
updateKey(SAVED_TOKENS, newList)
}
return [savedTokens, addToken, removeToken]
}