on fe527da help sign in
bridge/src/store/pointCache.js
134 lines 3.4 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};
22function _usePointCache() {
23 const { contracts, web3 } = useNetwork();
24 const [pointCache, _setPointCache] = useState({});
25 const [birthdayCache, _setBirthdayCache] = useState({});
26 const [invitesCache, _setInvitesCache] = useState({});
28 const addToPointCache = useCallback(
29 entry => _setPointCache(cache => ({ ...cache, ...entry })),
30 [_setPointCache]
31 );
33 const addToBirthdayCache = useCallback(
34 entry => _setBirthdayCache(cache => ({ ...cache, ...entry })),
35 [_setBirthdayCache]
36 );
38 const addToInvitesCache = useCallback(
39 entry => _setInvitesCache(cache => ({ ...cache, ...entry })),
40 [_setInvitesCache]
41 );
43 // TODO: refactor pointCache access to use accessor like bithday
44 const getBirthday = useCallback(
45 point => birthdayCache[point] || Maybe.Nothing(),
46 [birthdayCache]
47 );
48 const getInvites = useCallback(
49 point => invitesCache[point] || kEmptyInvites,
50 [invitesCache]
51 );
53 const fetchPoint = useCallback(
54 async point => {
55 const _contracts = contracts.getOrElse(null);
56 const _web3 = web3.getOrElse(null);
57 if (!_contracts || !_web3) {
58 return;
59 }
61 // fetch point details
62 const details = await azimuth.azimuth.getPoint(_contracts, point);
63 addToPointCache({ [point]: details });
65 // fetch invites
66 const count = await azimuth.delegatedSending.getTotalUsableInvites(
67 _contracts,
68 point
69 );
70 addToInvitesCache({
71 [point]: {
72 availableInvites: Maybe.Just(count),
73 // TODO: look up sent/accepted on-chain
74 sentInvites: Maybe.Just(6),
75 acceptedInvites: Maybe.Just(5),
76 },
77 });
79 // fetch birthday (if not already known — will not change after being set)
80 if (Maybe.Nothing.hasInstance(getBirthday(point))) {
81 const birthBlock = await azimuth.azimuth.getActivationBlock(
82 _contracts,
83 point
84 );
86 if (birthBlock > 0) {
87 const block = await _web3.eth.getBlock(birthBlock);
88 addToBirthdayCache({
89 [point]: Maybe.Just(new Date(block.timestamp * 1000)),
90 });
91 }
92 }
93 },
94 [
95 contracts,
96 web3,
97 addToPointCache,
98 addToBirthdayCache,
99 getBirthday,
100 addToInvitesCache,
101 ]
102 );
104 return {
105 pointCache,
106 getBirthday,
107 getInvites,
108 addToPointCache,
109 fetchPoint,
110 };
113export function PointCacheProvider({ children }) {
114 const pointCache = _usePointCache();
116 return (
117 <PointCacheContext.Provider value={pointCache}>
118 {children}
119 </PointCacheContext.Provider>
120 );
123// Hook version
124export function usePointCache() {
125 return useContext(PointCacheContext);
128// HOC version
129export const withPointCache = Component =>
130 forwardRef((props, ref) => (
131 <PointCacheContext.Consumer>
132 {pointCache => <Component ref={ref} {...pointCache} {...props} />}
133 </PointCacheContext.Consumer>
134 ));