scoresaber-reloaded-v2/src/store/settingsStore.ts
Liam 1001e68e1a
All checks were successful
deploy / deploy (push) Successful in 58s
remove debug and cleanup
2023-10-23 06:16:51 +01:00

127 lines
3.9 KiB
TypeScript

"use client";
import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { SortType, SortTypes } from "@/types/SortTypes";
import { ScoreSaberAPI } from "@/utils/scoresaber/api";
import moment from "moment";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
interface SettingsStore {
player: ScoresaberPlayer | undefined;
friends: ScoresaberPlayer[];
lastUsedSortType: SortType;
profilesLastUpdated: number;
setProfile: (playerData: ScoresaberPlayer) => void;
addFriend: (friendId: string) => Promise<boolean>;
removeFriend: (friendId: string) => void;
isFriend: (friendId: string) => boolean;
clearFriends: () => void;
setLastUsedSortType: (sortType: SortType) => void;
setProfilesLastUpdated: (profilesLastUpdated: number) => void;
refreshProfiles: () => void;
}
const UPDATE_INTERVAL = 1000 * 60 * 10; // 10 minutes
export const useSettingsStore = create<SettingsStore>()(
persist(
(set) => ({
player: undefined,
lastUsedSortType: SortTypes.top,
friends: [],
profilesLastUpdated: 0,
async setProfile(playerData: ScoresaberPlayer) {
set({
player: playerData,
});
},
async addFriend(friendId: string) {
const friends = useSettingsStore.getState().friends;
if (friends.some((friend) => friend.id == friendId)) {
return false;
}
const friend = await ScoreSaberAPI.fetchPlayerData(friendId);
if (friend == undefined || friend == null) return false;
set({ friends: [...friends, friend] });
return true;
},
removeFriend: (friendId: string) => {
const friends = useSettingsStore.getState().friends;
set({ friends: friends.filter((friend) => friend.id != friendId) });
return friendId;
},
clearFriends: () => set({ friends: [] }),
isFriend: (friendId: string) => {
const friends: ScoresaberPlayer[] = useSettingsStore.getState().friends;
return friends.some((friend) => friend.id == friendId);
},
setProfilesLastUpdated: (profilesLastUpdated: number) => {
set({ profilesLastUpdated });
},
setLastUsedSortType: (sortType: SortType) => {
set({ lastUsedSortType: sortType });
},
async refreshProfiles() {
const timeUntilRefreshMs =
UPDATE_INTERVAL -
(Date.now() - useSettingsStore.getState().profilesLastUpdated);
if (timeUntilRefreshMs > 0) {
console.log(
"Waiting",
moment.duration(timeUntilRefreshMs).humanize(),
"to refresh profiles",
);
setTimeout(() => this.refreshProfiles(), timeUntilRefreshMs);
return;
}
const player = useSettingsStore.getState().player;
if (player != undefined) {
const newPlayer = await ScoreSaberAPI.fetchPlayerData(player.id);
if (newPlayer != undefined && newPlayer != null) {
console.log("Updated player data for", newPlayer.name);
set({ player: newPlayer });
}
}
const friends = useSettingsStore.getState().friends;
const newFriends = await Promise.all(
friends.map(async (friend) => {
const newFriend = await ScoreSaberAPI.fetchPlayerData(friend.id);
if (newFriend == undefined || newFriend == null) return friend;
console.log("Updated friend data for", newFriend.name);
return newFriend;
}),
);
set({ friends: newFriends });
useSettingsStore.setState({ profilesLastUpdated: Date.now() });
},
}),
{
name: "settings",
storage: createJSONStorage(() => localStorage),
},
),
);
// Refresh profiles every 10 minutes
useSettingsStore.getState().refreshProfiles();
setInterval(
() => useSettingsStore.getState().refreshProfiles(),
UPDATE_INTERVAL,
);