on f34e8d0 help sign in
bridge/src/store/pointCache.js
187 lines 4.9 kB history raw
1import React, {
2 createContext,
3 forwardRef,
4 useCallback,
5 useContext,
6 useState,
7} from 'react';
8import Maybe from 'folktale/maybe';
9import * as azimuth from 'azimuth-js';
11import { useNetwork } from './network';
13export const PointCacheContext = createContext(null);
15// the default value of a point's invites
16const kEmptyInvites = {
17 availableInvites: Maybe.Nothing(),
18 sentInvites: Maybe.Nothing(),
19 acceptedInvites: Maybe.Nothing(),
20};
22// TODO(shrugs): this hook is too big -> refactor into individual hooks for
23// details, birthday, invites, etc
24function _usePointCache() {
25 const { contracts, web3 } = useNetwork();
26 const [pointCache, _setPointCache] = useState({});
27 const [birthdayCache, _setBirthdayCache] = useState({});
28 const [invitesCache, _setInvitesCache] = useState({});
30 const addToPointCache = useCallback(
31 entry => _setPointCache(cache => ({ ...cache, ...entry })),
32 [_setPointCache]
33 );
35 const addToBirthdayCache = useCallback(
36 entry => _setBirthdayCache(cache => ({ ...cache, ...entry })),
37 [_setBirthdayCache]
38 );
40 const addToInvitesCache = useCallback(
41 entry => _setInvitesCache(cache => ({ ...cache, ...entry })),
42 [_setInvitesCache]
43 );
45 // TODO: refactor pointCache access to use accessor like bithday
46 const getDetails = useCallback(
47 point => pointCache[point] || Maybe.Nothing(),
48 [pointCache]
49 );
50 const getBirthday = useCallback(
51 point => birthdayCache[point] || Maybe.Nothing(),
52 [birthdayCache]
53 );
54 const getInvites = useCallback(
55 point => invitesCache[point] || kEmptyInvites,
56 [invitesCache]
57 );
59 const syncDetails = useCallback(
60 async point => {
61 const _contracts = contracts.getOrElse(null);
62 if (!_contracts) {
63 return;
64 }
66 // fetch point details
67 const details = await azimuth.azimuth.getPoint(_contracts, point);
68 addToPointCache({
69 [point]: details,
70 });
71 },
72 [contracts, addToPointCache]
73 );
75 const syncBirthday = useCallback(
76 async point => {
77 const _contracts = contracts.getOrElse(null);
78 const _web3 = web3.getOrElse(null);
79 if (!_contracts || !web3) {
80 return;
81 }
83 // fetch birthday if not already known—will not change after being set
84 if (Maybe.Nothing.hasInstance(getBirthday(point))) {
85 const birthBlock = await azimuth.azimuth.getActivationBlock(
86 _contracts,
87 point
88 );
90 if (birthBlock > 0) {
91 const block = await _web3.eth.getBlock(birthBlock);
92 addToBirthdayCache({
93 [point]: Maybe.Just(new Date(block.timestamp * 1000)),
94 });
95 }
96 }
97 },
98 [contracts, web3, addToBirthdayCache, getBirthday]
99 );
101 const syncInvites = useCallback(
102 async point => {
103 const _contracts = contracts.getOrElse(null);
104 if (!_contracts) {
105 return;
106 }
108 const availableInvites = await azimuth.delegatedSending.getTotalUsableInvites(
109 _contracts,
110 point
111 );
113 const invitedPoints = await azimuth.delegatedSending.getInvited(
114 _contracts,
115 point
116 );
117 const invitedPointDetails = await Promise.all(
118 invitedPoints.map(async invitedPoint => {
119 console.log('invitedPoint', invitedPoint, typeof invitedPoint);
120 const active = await azimuth.azimuth.isActive(
121 _contracts,
122 invitedPoint
123 );
124 return {
125 point: Number(invitedPoint),
126 active,
127 };
128 })
129 );
130 const sentInvites = invitedPointDetails.length;
131 const acceptedInvites = invitedPointDetails.filter(i => i.active).length;
133 addToInvitesCache({
134 [point]: {
135 availableInvites: Maybe.Just(availableInvites),
136 sentInvites: Maybe.Just(sentInvites),
137 acceptedInvites: Maybe.Just(acceptedInvites),
138 },
139 });
140 },
141 [contracts, addToInvitesCache]
142 );
144 // sync all of the on-chain info required for a point that the user owns
145 const syncOwnedPoint = useCallback(
146 async point => {
147 await Promise.all([
148 syncDetails(point),
149 syncInvites(point),
150 syncBirthday(point),
151 ]);
152 },
153 [syncDetails, syncInvites, syncBirthday]
154 );
156 return {
157 pointCache,
158 getDetails,
159 getBirthday,
160 getInvites,
161 addToPointCache,
162 syncOwnedPoint,
163 };
166export function PointCacheProvider({ children }) {
167 const pointCache = _usePointCache();
169 return (
170 <PointCacheContext.Provider value={pointCache}>
171 {children}
172 </PointCacheContext.Provider>
173 );
176// Hook version
177export function usePointCache() {
178 return useContext(PointCacheContext);
181// HOC version
182export const withPointCache = Component =>
183 forwardRef((props, ref) => (
184 <PointCacheContext.Consumer>
185 {pointCache => <Component ref={ref} {...pointCache} {...props} />}
186 </PointCacheContext.Consumer>
187 ));