From ec7f882bebeb69fa3ac01fc6d70530e5c0514b28 Mon Sep 17 00:00:00 2001 From: Ash Keel Date: Sun, 16 May 2021 19:19:32 +0200 Subject: [PATCH] Update UI to use kilovolt v4 and new loyalty key --- frontend/package-lock.json | 6 +-- frontend/package.json | 2 +- frontend/src/lib/react-utils.ts | 4 +- frontend/src/store/api/reducer.ts | 58 +++++++++------------- frontend/src/ui/pages/loyalty/UserList.tsx | 23 +++++---- 5 files changed, 43 insertions(+), 50 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ea2ea19..60b866e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2274,9 +2274,9 @@ } }, "@strimertul/kilovolt-client": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-3.0.0.tgz", - "integrity": "sha512-jzm5gTJsxAJxkkDgpPsCttDwgN1wF3c1pPneE3drFIoI7+oRnXQsiWIsA6VZBYoVamitn4CcQHMK1eKAYGkxrQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@strimertul/kilovolt-client/-/kilovolt-client-4.1.0.tgz", + "integrity": "sha512-krobLL0IsXAm5gIw9uswnBDKX/mV5bpYp8bom4IJCrZLsd8QGUsMB3yd3ukS0Sxm7R5p0oXW91XbrqMixvgUHA==", "requires": { "@billjs/event-emitter": "^1.0.3" } diff --git a/frontend/package.json b/frontend/package.json index e30fd2e..9f32d80 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,7 @@ "@billjs/event-emitter": "^1.0.3", "@reach/router": "^1.3.4", "@reduxjs/toolkit": "^1.5.1", - "@strimertul/kilovolt-client": "^3.0.0", + "@strimertul/kilovolt-client": "^4.1.0", "@types/node": "^15.0.2", "@types/reach__router": "^1.3.7", "@types/react": "^17.0.5", diff --git a/frontend/src/lib/react-utils.ts b/frontend/src/lib/react-utils.ts index 2de6dee..90d185c 100644 --- a/frontend/src/lib/react-utils.ts +++ b/frontend/src/lib/react-utils.ts @@ -29,9 +29,9 @@ export function useModule({ const subscriber = (newValue) => { dispatch(asyncSetter(JSON.parse(newValue) as T)); }; - client.subscribe(key, subscriber); + client.subscribeKey(key, subscriber); return () => { - client.unsubscribe(key, subscriber); + client.unsubscribeKey(key, subscriber); }; }, []); return [data, setter]; diff --git a/frontend/src/store/api/reducer.ts b/frontend/src/store/api/reducer.ts index 98cbffa..88bb29a 100644 --- a/frontend/src/store/api/reducer.ts +++ b/frontend/src/store/api/reducer.ts @@ -17,7 +17,7 @@ const twitchConfigKey = 'twitch/config'; const twitchBotConfigKey = 'twitch/bot-config'; const stulbeConfigKey = 'stulbe/config'; const loyaltyConfigKey = 'loyalty/config'; -const loyaltyStorageKey = 'loyalty/users'; +const loyaltyPointsPrefix = 'loyalty/points/'; const loyaltyRewardsKey = 'loyalty/rewards'; const loyaltyGoalsKey = 'loyalty/goals'; const loyaltyRedeemQueueKey = 'loyalty/redeem-queue'; @@ -68,7 +68,11 @@ interface LoyaltyConfig { banlist: string[]; } -export type LoyaltyStorage = Record; +interface LoyaltyPointsEntry { + points: number; +} + +export type LoyaltyStorage = Record; export interface LoyaltyReward { enabled: boolean; @@ -199,6 +203,20 @@ export const createWSClient = createAsyncThunk( }, ); +export const getUserPoints = createAsyncThunk( + 'api/getUserPoints', + async (_: void, { getState }) => { + const { api } = getState() as { api: APIState }; + const keys = await api.client.getKeysByPrefix(loyaltyPointsPrefix); + console.log(keys); + const userpoints: LoyaltyStorage = {}; + Object.entries(keys).forEach(([k, v]) => { + userpoints[k.substr(loyaltyPointsPrefix.length)] = JSON.parse(v); + }); + return userpoints; + }, +); + export const modules = { moduleConfig: makeModule( moduleConfigKey, @@ -242,13 +260,6 @@ export const modules = { state.moduleConfigs.loyaltyConfig = payload; }, ), - loyaltyStorage: makeModule( - loyaltyStorageKey, - (state) => state.loyalty.users, - (state, { payload }) => { - state.loyalty.users = payload; - }, - ), loyaltyRewards: makeModule( loyaltyRewardsKey, (state) => state.loyalty.rewards, @@ -272,29 +283,6 @@ export const modules = { ), }; -export const setUserPoints = createAsyncThunk( - 'api/setUserPoints', - async ( - { - user, - points, - relative, - }: { user: string; points: number; relative: boolean }, - { getState, dispatch }, - ) => { - const { api } = getState() as { api: APIState }; - const newAmount = relative - ? (api.loyalty.users[user] ?? 0) + points - : points; - return dispatch( - modules.loyaltyStorage.setter({ - ...api.loyalty.users, - [user]: newAmount, - }), - ); - }, -); - export const createRedeem = createAsyncThunk( 'api/createRedeem', async (redeem: LoyaltyRedeem, { getState }) => { @@ -339,9 +327,6 @@ const apiReducer = createSlice({ loyaltyConfigChanged(state, { payload }: PayloadAction) { state.moduleConfigs.loyaltyConfig = payload; }, - loyaltyStorageChanged(state, { payload }: PayloadAction) { - state.loyalty.users = payload; - }, loyaltyRewardsChanged(state, { payload }: PayloadAction) { state.loyalty.rewards = payload; }, @@ -354,6 +339,9 @@ const apiReducer = createSlice({ state.client = payload; state.connected = true; }); + builder.addCase(getUserPoints.fulfilled, (state, { payload }) => { + state.loyalty.users = payload; + }); Object.values(modules).forEach((mod) => { builder.addCase(mod.getter.fulfilled, mod.stateSetter); builder.addCase(mod.asyncSetter, mod.stateSetter); diff --git a/frontend/src/ui/pages/loyalty/UserList.tsx b/frontend/src/ui/pages/loyalty/UserList.tsx index 75aca03..cf993ef 100644 --- a/frontend/src/ui/pages/loyalty/UserList.tsx +++ b/frontend/src/ui/pages/loyalty/UserList.tsx @@ -1,8 +1,9 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { RouteComponentProps } from '@reach/router'; -import { useModule } from '../../../lib/react-utils'; -import { modules } from '../../../store/api/reducer'; import PageList from '../../components/PageList'; +import { RootState } from '../../../store'; +import { getUserPoints } from '../../../store/api/reducer'; interface SortingOrder { key: 'user' | 'points'; @@ -12,13 +13,17 @@ export default function LoyaltyUserListPage( // eslint-disable-next-line @typescript-eslint/no-unused-vars props: RouteComponentProps, ): React.ReactElement { - const [users] = useModule(modules.loyaltyStorage); - + const users = useSelector((state: RootState) => state.api.loyalty.users); + const dispatch = useDispatch(); const [sorting, setSorting] = useState({ key: 'points', order: 'desc', }); + useEffect(() => { + dispatch(getUserPoints()); + }, []); + const [entriesPerPage, setEntriesPerPage] = useState(15); const [page, setPage] = useState(0); const [usernameFilter, setUsernameFilter] = useState(''); @@ -51,10 +56,10 @@ export default function LoyaltyUserListPage( case 'points': if (sorting.order === 'asc') { // eslint-disable-next-line @typescript-eslint/no-unused-vars - sortedEntries.sort(([_a, pointsA], [_b, pointsB]) => pointsA - pointsB); + sortedEntries.sort(([_a, a], [_b, b]) => a.points - b.points); } else { // eslint-disable-next-line @typescript-eslint/no-unused-vars - sortedEntries.sort(([_a, pointsA], [_b, pointsB]) => pointsB - pointsA); + sortedEntries.sort(([_a, a], [_b, b]) => b.points - a.points); } break; default: @@ -120,10 +125,10 @@ export default function LoyaltyUserListPage( - {paged.map(([user, points]) => ( + {paged.map(([user, p]) => ( {user} - {points} + {p.points} ))}