2023-10-19 19:31:05 +00:00
|
|
|
"use client";
|
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
|
2023-10-22 01:47:03 +00:00
|
|
|
import { SortType, SortTypes } from "@/types/SortTypes";
|
2023-10-21 21:16:46 +00:00
|
|
|
import { getPlayerInfo } from "@/utils/scoresaber/api";
|
2023-10-22 04:14:37 +00:00
|
|
|
import moment from "moment";
|
2023-10-19 19:31:05 +00:00
|
|
|
import { create } from "zustand";
|
2023-10-21 21:25:41 +00:00
|
|
|
import { createJSONStorage, persist } from "zustand/middleware";
|
2023-10-19 19:31:05 +00:00
|
|
|
|
2023-10-21 21:16:46 +00:00
|
|
|
interface SettingsStore {
|
|
|
|
userId: string | undefined;
|
|
|
|
profilePicture: string | undefined;
|
2023-10-22 01:47:03 +00:00
|
|
|
lastUsedSortType: SortType;
|
2023-10-22 04:14:37 +00:00
|
|
|
friends: ScoresaberPlayer[];
|
|
|
|
profilesLastUpdated: number;
|
2023-10-21 21:16:46 +00:00
|
|
|
|
|
|
|
setUserId: (userId: string) => void;
|
|
|
|
setProfilePicture: (profilePicture: string) => void;
|
2023-10-22 01:47:03 +00:00
|
|
|
setLastUsedSortType: (sortType: SortType) => void;
|
2023-10-22 04:14:37 +00:00
|
|
|
addFriend: (friendId: string) => Promise<boolean>;
|
|
|
|
removeFriend: (friendId: string) => void;
|
|
|
|
isFriend: (friendId: string) => boolean;
|
|
|
|
clearFriends: () => void;
|
|
|
|
setProfilesLastUpdated: (profilesLastUpdated: number) => void;
|
|
|
|
refreshProfiles: () => void;
|
2023-10-21 21:16:46 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
const UPDATE_INTERVAL = 1000 * 60 * 10; // 10 minutes
|
|
|
|
|
2023-10-21 21:16:46 +00:00
|
|
|
export const useSettingsStore = create<SettingsStore>()(
|
2023-10-19 19:31:05 +00:00
|
|
|
persist(
|
2023-10-21 21:16:46 +00:00
|
|
|
(set) => ({
|
|
|
|
userId: undefined,
|
|
|
|
profilePicture: undefined,
|
2023-10-22 01:47:03 +00:00
|
|
|
lastUsedSortType: SortTypes.top,
|
2023-10-22 04:14:37 +00:00
|
|
|
friends: [],
|
|
|
|
profilesLastUpdated: 0,
|
2023-10-19 19:31:05 +00:00
|
|
|
|
2023-10-21 21:16:46 +00:00
|
|
|
setUserId: (userId: string) => {
|
|
|
|
set({ userId });
|
|
|
|
},
|
2023-10-22 01:17:21 +00:00
|
|
|
|
2023-10-21 21:16:46 +00:00
|
|
|
setProfilePicture: (profilePicture: string) => set({ profilePicture }),
|
2023-10-22 01:17:21 +00:00
|
|
|
|
2023-10-22 01:47:03 +00:00
|
|
|
setLastUsedSortType: (sortType: SortType) =>
|
|
|
|
set({ lastUsedSortType: sortType }),
|
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
async addFriend(friendId: string) {
|
|
|
|
const friends = useSettingsStore.getState().friends;
|
|
|
|
if (friends.some((friend) => friend.id == friendId)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const friend = await getPlayerInfo(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: [] }),
|
2023-10-21 21:25:41 +00:00
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
isFriend: (friendId: string) => {
|
|
|
|
const friends: ScoresaberPlayer[] = useSettingsStore.getState().friends;
|
|
|
|
return friends.some((friend) => friend.id == friendId);
|
|
|
|
},
|
|
|
|
|
|
|
|
setProfilesLastUpdated: (profilesLastUpdated: number) =>
|
|
|
|
set({ profilesLastUpdated }),
|
|
|
|
|
|
|
|
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 userId = useSettingsStore.getState().userId;
|
|
|
|
const profiles =
|
|
|
|
useSettingsStore.getState().friends.map((f) => f.id) ?? [];
|
|
|
|
if (userId) {
|
|
|
|
profiles.push(userId);
|
|
|
|
}
|
2023-10-21 21:25:41 +00:00
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
for (const profileId of profiles) {
|
|
|
|
const profile = await getPlayerInfo(profileId);
|
|
|
|
if (profile == undefined || profile == null) return;
|
|
|
|
|
|
|
|
if (this.isFriend(profileId)) {
|
|
|
|
const friends = useSettingsStore.getState().friends;
|
|
|
|
const friendIndex = friends.findIndex(
|
|
|
|
(friend) => friend.id == profileId,
|
|
|
|
);
|
|
|
|
friends[friendIndex] = profile;
|
|
|
|
set({ friends });
|
|
|
|
} else {
|
|
|
|
this.setProfilePicture(profile.profilePicture);
|
|
|
|
set({ userId: profile.id });
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("Updated profile:", profile.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
useSettingsStore.setState({ profilesLastUpdated: Date.now() });
|
2023-10-21 21:25:41 +00:00
|
|
|
},
|
2023-10-19 19:31:05 +00:00
|
|
|
}),
|
|
|
|
{
|
2023-10-21 21:16:46 +00:00
|
|
|
name: "settings",
|
2023-10-21 21:25:41 +00:00
|
|
|
storage: createJSONStorage(() => localStorage),
|
2023-10-19 19:31:05 +00:00
|
|
|
},
|
|
|
|
),
|
|
|
|
);
|
2023-10-21 21:16:46 +00:00
|
|
|
|
2023-10-22 04:14:37 +00:00
|
|
|
useSettingsStore.getState().refreshProfiles();
|
|
|
|
setInterval(
|
|
|
|
() => useSettingsStore.getState().refreshProfiles(),
|
|
|
|
UPDATE_INTERVAL,
|
|
|
|
);
|