diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index f0a680a5..eb878262 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -947,6 +947,8 @@ }, "account": { "accountDetails": { + "nicknameLabel": "Nickname", + "nicknamePlaceholder": "Enter your nickname", "deviceNameLabel": "Device name", "deviceNamePlaceholder": "Personal phone", "editProfile": "Edit", @@ -1144,6 +1146,7 @@ "backendVersion": "Backend version", "hostname": "Hostname", "insecure": "Insecure", + "nickname": "Nickname", "notLoggedIn": "You are not logged in", "secure": "Secure", "title": "App stats", diff --git a/src/backend/accounts/user.ts b/src/backend/accounts/user.ts index 5ab9e76c..dd7de943 100644 --- a/src/backend/accounts/user.ts +++ b/src/backend/accounts/user.ts @@ -8,9 +8,8 @@ import { ProgressMediaItem } from "@/stores/progress"; export interface UserResponse { id: string; namespace: string; - name: string; - roles: string[]; - createdAt: string; + nickname: string; + permissions: string[]; profile: { colorA: string; colorB: string; @@ -24,6 +23,7 @@ export interface UserEdit { colorB: string; icon: string; }; + nickname?: string; } export interface BookmarkResponse { diff --git a/src/hooks/auth/useAuthData.ts b/src/hooks/auth/useAuthData.ts index 68cc2ac8..c9efcca5 100644 --- a/src/hooks/auth/useAuthData.ts +++ b/src/hooks/auth/useAuthData.ts @@ -101,6 +101,7 @@ export function useAuthData() { sessionId: loginResponse.session.id, deviceName: session.device, profile: user.profile, + nickname: user.nickname, seed, }; setAccount(account); diff --git a/src/hooks/useSettingsState.ts b/src/hooks/useSettingsState.ts index 48fc0c61..a07f3def 100644 --- a/src/hooks/useSettingsState.ts +++ b/src/hooks/useSettingsState.ts @@ -42,6 +42,7 @@ export function useSettingsState( appLanguage: string, subtitleStyling: SubtitleStyling, deviceName: string, + nickname: string, proxyUrls: string[] | null, backendUrl: string | null, febboxKey: string | null, @@ -110,6 +111,8 @@ export function useSettingsState( resetDeviceName, deviceNameChanged, ] = useDerived(deviceName); + const [nicknameState, setNicknameState, resetNickname, nicknameChanged] = + useDerived(nickname); const [profileState, setProfileState, resetProfile, profileChanged] = useDerived(profile); const [ @@ -263,6 +266,7 @@ export function useSettingsState( resetFebboxKey(); resetRealDebridKey(); resetDeviceName(); + resetNickname(); resetProfile(); resetEnableThumbnails(); resetEnableAutoplay(); @@ -295,6 +299,7 @@ export function useSettingsState( appLanguageChanged || subStylingChanged || deviceNameChanged || + nicknameChanged || backendUrlChanged || proxyUrlsChanged || febboxKeyChanged || @@ -348,6 +353,11 @@ export function useSettingsState( set: setDeviceNameState, changed: deviceNameChanged, }, + nickname: { + state: nicknameState, + set: setNicknameState, + changed: nicknameChanged, + }, proxyUrls: { state: proxyUrlsState, set: setProxyUrls, diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index 2cda40cf..f01700cf 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -114,6 +114,8 @@ export function AccountSettings(props: { account: AccountWithToken; deviceName: string; setDeviceName: (s: string) => void; + nickname: string; + setNickname: (s: string) => void; colorA: string; setColorA: (s: string) => void; colorB: string; @@ -136,6 +138,8 @@ export function AccountSettings(props: { s.account); + const setAccount = useAuthStore((s) => s.setAccount); const updateProfile = useAuthStore((s) => s.setAccountProfile); const updateDeviceName = useAuthStore((s) => s.updateDeviceName); const decryptedName = useMemo(() => { @@ -513,6 +518,7 @@ export function SettingsPage() { appLanguage, subStyling, decryptedName, + account?.nickname || "", proxySet, backendUrlSetting, febboxKey, @@ -646,6 +652,14 @@ export function SettingsPage() { }); updateDeviceName(newDeviceName); } + if (state.nickname.changed) { + await editUser(backendUrl, account, { + nickname: state.nickname.state, + }); + // Update the account in the store + const updatedAccount = { ...account, nickname: state.nickname.state }; + setAccount(updatedAccount); + } if (state.profile.changed) { await editUser(backendUrl, account, { profile: state.profile.state, @@ -720,6 +734,7 @@ export function SettingsPage() { setProxySet, updateDeviceName, updateProfile, + setAccount, logout, setBackendUrl, setProxyTmdb, @@ -754,6 +769,8 @@ export function SettingsPage() { account={user.account} deviceName={state.deviceName.state} setDeviceName={state.deviceName.set} + nickname={state.nickname.state} + setNickname={state.nickname.set} colorA={state.profile.state.colorA} setColorA={(v) => { state.profile.set((s) => diff --git a/src/pages/parts/settings/AccountEditPart.tsx b/src/pages/parts/settings/AccountEditPart.tsx index 3b3bb16f..e989698e 100644 --- a/src/pages/parts/settings/AccountEditPart.tsx +++ b/src/pages/parts/settings/AccountEditPart.tsx @@ -13,6 +13,8 @@ import { ProfileEditModal } from "@/pages/parts/settings/ProfileEditModal"; export function AccountEditPart(props: { deviceName: string; setDeviceName: (s: string) => void; + nickname: string; + setNickname: (s: string) => void; colorA: string; setColorA: (s: string) => void; colorB: string; @@ -59,24 +61,38 @@ export function AccountEditPart(props: { />
-
- props.setDeviceName(value)} - /> -
- +
+
+ props.setNickname(value)} + className="w-full" + />
+
+ props.setDeviceName(value)} + className="w-full" + /> +
+
+
+
diff --git a/src/stores/auth/index.ts b/src/stores/auth/index.ts index 0a3c007a..7db2dd37 100644 --- a/src/stores/auth/index.ts +++ b/src/stores/auth/index.ts @@ -8,6 +8,7 @@ export interface Account { colorB: string; icon: string; }; + nickname: string; } export type AccountWithToken = Account & { @@ -25,7 +26,7 @@ interface AuthStore { removeAccount(): void; setAccount(acc: AccountWithToken): void; updateDeviceName(deviceName: string): void; - updateAccount(acc: Account): void; + updateAccount(acc: Partial): void; setAccountProfile(acc: Account["profile"]): void; setBackendUrl(url: null | string): void; setProxySet(urls: null | string[]): void;