Store appearance settings on server
This commit is contained in:
parent
2d164cdd19
commit
2867d70eeb
6 changed files with 70 additions and 10 deletions
|
@ -10,6 +10,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
- Added "Aliases" page.
|
||||
- Form for adding aliases.
|
||||
- Store appearance settings on server.
|
||||
|
||||
### Changed
|
||||
|
||||
- Move dark mode toggle out of "Experiments" section.
|
||||
|
||||
## [1.19.0] - 2023-03-30
|
||||
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
import { BACKEND_URL } from "@/constants"
|
||||
import { APP_NAME, BACKEND_URL } from "@/constants"
|
||||
import { http } from "./common"
|
||||
import { Aliases, User } from "./users"
|
||||
|
||||
export async function updateClientConfig(
|
||||
authToken: string,
|
||||
clientConfig: { [property: string]: any },
|
||||
): Promise<User> {
|
||||
const url = `${BACKEND_URL}/api/v1/settings/client_config`
|
||||
const response = await http(url, {
|
||||
method: "POST",
|
||||
json: { [APP_NAME]: clientConfig },
|
||||
authToken,
|
||||
})
|
||||
const data = await response.json()
|
||||
if (response.status !== 200) {
|
||||
throw new Error(data.error_description)
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
export async function changePassword(
|
||||
authToken: string,
|
||||
newPassword: string,
|
||||
|
|
|
@ -83,6 +83,7 @@ export function defaultProfile(): Profile {
|
|||
export interface User extends Profile {
|
||||
source: Source;
|
||||
role: Role,
|
||||
client_config: { [clientName: string]: { [property: string]: any } },
|
||||
}
|
||||
|
||||
export interface ProfileWrapper extends Profile {}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { ref } from "vue"
|
||||
|
||||
const THEME_STORAGE_KEY = "theme"
|
||||
import { updateClientConfig } from "@/api/settings"
|
||||
import { APP_NAME } from "@/constants"
|
||||
import { useCurrentUser } from "@/store/user"
|
||||
|
||||
enum Theme {
|
||||
Light = "light",
|
||||
|
@ -14,20 +16,39 @@ export function useTheme() {
|
|||
function setTheme(theme: Theme) {
|
||||
document.documentElement.setAttribute("data-theme", theme)
|
||||
currentTheme.value = theme
|
||||
localStorage.setItem(THEME_STORAGE_KEY, theme)
|
||||
}
|
||||
|
||||
async function persistTheme(theme: Theme) {
|
||||
const {
|
||||
ensureAuthToken,
|
||||
ensureCurrentUser,
|
||||
setCurrentUser,
|
||||
} = useCurrentUser()
|
||||
const currentUser = ensureCurrentUser()
|
||||
let clientConfig = currentUser.client_config[APP_NAME] || {}
|
||||
clientConfig = { ...clientConfig, theme }
|
||||
const authToken = ensureAuthToken()
|
||||
const user = await updateClientConfig(authToken, clientConfig)
|
||||
setCurrentUser(user)
|
||||
}
|
||||
|
||||
function loadTheme() {
|
||||
const theme = localStorage.getItem(THEME_STORAGE_KEY) || Theme.Light
|
||||
const { ensureCurrentUser } = useCurrentUser()
|
||||
const currentUser = ensureCurrentUser()
|
||||
const clientConfig = currentUser.client_config[APP_NAME] || {}
|
||||
const theme = clientConfig.theme || Theme.Light
|
||||
setTheme(theme as Theme)
|
||||
}
|
||||
|
||||
function toggleDarkMode() {
|
||||
async function toggleDarkMode() {
|
||||
let theme
|
||||
if (currentTheme.value === Theme.Light) {
|
||||
setTheme(Theme.Dark)
|
||||
theme = Theme.Dark
|
||||
} else {
|
||||
setTheme(Theme.Light)
|
||||
theme = Theme.Light
|
||||
}
|
||||
setTheme(theme)
|
||||
await persistTheme(theme)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export const ENV = process.env.NODE_ENV
|
||||
|
||||
export const BACKEND_URL = process.env.VUE_APP_BACKEND_URL
|
||||
export const APP_NAME = "mitra-web"
|
||||
export const APP_VERSION = process.env.VUE_APP_VERSION
|
||||
|
|
|
@ -11,6 +11,16 @@
|
|||
Edit profile
|
||||
</router-link>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Appearance</h2>
|
||||
<button
|
||||
class="btn"
|
||||
@click="onToggleDarkMode()"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
Toggle dark mode
|
||||
</button>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Change password</h2>
|
||||
<form @submit.prevent="onChangePassword()">
|
||||
|
@ -70,9 +80,6 @@
|
|||
<router-link class="btn" :to="{ name: 'move-followers' }">
|
||||
Move followers
|
||||
</router-link>
|
||||
<button class="btn" @click="toggleDarkMode()">
|
||||
Toggle dark mode
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
</section>
|
||||
|
@ -93,6 +100,13 @@ const { toggleDarkMode } = useTheme()
|
|||
let newPassword = $ref("")
|
||||
let newPasswordConfirmation = $ref("")
|
||||
let passwordFormMessage = $ref<string | null>(null)
|
||||
let isLoading = $ref(false)
|
||||
|
||||
async function onToggleDarkMode() {
|
||||
isLoading = true
|
||||
await toggleDarkMode()
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
function canChangePassword(): boolean {
|
||||
return newPassword && newPassword === newPasswordConfirmation
|
||||
|
|
Loading…
Reference in a new issue