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.
|
- Added "Aliases" page.
|
||||||
- Form for adding aliases.
|
- 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.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 { http } from "./common"
|
||||||
import { Aliases, User } from "./users"
|
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(
|
export async function changePassword(
|
||||||
authToken: string,
|
authToken: string,
|
||||||
newPassword: string,
|
newPassword: string,
|
||||||
|
|
|
@ -83,6 +83,7 @@ export function defaultProfile(): Profile {
|
||||||
export interface User extends Profile {
|
export interface User extends Profile {
|
||||||
source: Source;
|
source: Source;
|
||||||
role: Role,
|
role: Role,
|
||||||
|
client_config: { [clientName: string]: { [property: string]: any } },
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProfileWrapper extends Profile {}
|
export interface ProfileWrapper extends Profile {}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { ref } from "vue"
|
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 {
|
enum Theme {
|
||||||
Light = "light",
|
Light = "light",
|
||||||
|
@ -14,20 +16,39 @@ export function useTheme() {
|
||||||
function setTheme(theme: Theme) {
|
function setTheme(theme: Theme) {
|
||||||
document.documentElement.setAttribute("data-theme", theme)
|
document.documentElement.setAttribute("data-theme", theme)
|
||||||
currentTheme.value = 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() {
|
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)
|
setTheme(theme as Theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDarkMode() {
|
async function toggleDarkMode() {
|
||||||
|
let theme
|
||||||
if (currentTheme.value === Theme.Light) {
|
if (currentTheme.value === Theme.Light) {
|
||||||
setTheme(Theme.Dark)
|
theme = Theme.Dark
|
||||||
} else {
|
} else {
|
||||||
setTheme(Theme.Light)
|
theme = Theme.Light
|
||||||
}
|
}
|
||||||
|
setTheme(theme)
|
||||||
|
await persistTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export const ENV = process.env.NODE_ENV
|
export const ENV = process.env.NODE_ENV
|
||||||
|
|
||||||
export const BACKEND_URL = process.env.VUE_APP_BACKEND_URL
|
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
|
export const APP_VERSION = process.env.VUE_APP_VERSION
|
||||||
|
|
|
@ -11,6 +11,16 @@
|
||||||
Edit profile
|
Edit profile
|
||||||
</router-link>
|
</router-link>
|
||||||
</section>
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Appearance</h2>
|
||||||
|
<button
|
||||||
|
class="btn"
|
||||||
|
@click="onToggleDarkMode()"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
Toggle dark mode
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h2>Change password</h2>
|
<h2>Change password</h2>
|
||||||
<form @submit.prevent="onChangePassword()">
|
<form @submit.prevent="onChangePassword()">
|
||||||
|
@ -70,9 +80,6 @@
|
||||||
<router-link class="btn" :to="{ name: 'move-followers' }">
|
<router-link class="btn" :to="{ name: 'move-followers' }">
|
||||||
Move followers
|
Move followers
|
||||||
</router-link>
|
</router-link>
|
||||||
<button class="btn" @click="toggleDarkMode()">
|
|
||||||
Toggle dark mode
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</section>
|
</section>
|
||||||
|
@ -93,6 +100,13 @@ const { toggleDarkMode } = useTheme()
|
||||||
let newPassword = $ref("")
|
let newPassword = $ref("")
|
||||||
let newPasswordConfirmation = $ref("")
|
let newPasswordConfirmation = $ref("")
|
||||||
let passwordFormMessage = $ref<string | null>(null)
|
let passwordFormMessage = $ref<string | null>(null)
|
||||||
|
let isLoading = $ref(false)
|
||||||
|
|
||||||
|
async function onToggleDarkMode() {
|
||||||
|
isLoading = true
|
||||||
|
await toggleDarkMode()
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
|
||||||
function canChangePassword(): boolean {
|
function canChangePassword(): boolean {
|
||||||
return newPassword && newPassword === newPasswordConfirmation
|
return newPassword && newPassword === newPasswordConfirmation
|
||||||
|
|
Loading…
Reference in a new issue