// gomuks - A Matrix client written in Go. // Copyright (C) 2024 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import { use, useCallback, useState } from "react" import { RoomStateStore, usePreferences } from "@/api/statestore" import { Preference, PreferenceContext, PreferenceValueType, Preferences, preferences } from "@/api/types/preferences" import useEvent from "@/util/useEvent.ts" import ClientContext from "../ClientContext.ts" import JSONView from "../util/JSONView.tsx" import Toggle from "../util/Toggle.tsx" import CloseIcon from "@/icons/close.svg?react" import "./SettingsView.css" interface PreferenceCellProps { context: PreferenceContext name: keyof Preferences pref: Preference setPref: SetPrefFunc value: T | undefined inheritedValue: T } const useRemover = ( context: PreferenceContext, setPref: SetPrefFunc, name: keyof Preferences, value: PreferenceValueType | undefined, ) => { const onClear = useCallback(() => { setPref(context, name, undefined) }, [setPref, context, name]) if (value === undefined) { return null } return } const BooleanPreferenceCell = ({ context, name, setPref, value, inheritedValue }: PreferenceCellProps) => { const onChange = useCallback((evt: React.ChangeEvent) => { setPref(context, name, evt.target.checked) }, [setPref, context, name]) return
{useRemover(context, setPref, name, value)}
} const SelectPreferenceCell = ({ context, name, pref, setPref, value, inheritedValue }: PreferenceCellProps) => { const onChange = useCallback((evt: React.ChangeEvent) => { setPref(context, name, evt.target.value) }, [setPref, context, name]) const remover = useRemover(context, setPref, name, value) if (!pref.allowedValues) { return null } return
{remover}
} type SetPrefFunc = (context: PreferenceContext, key: keyof Preferences, value: PreferenceValueType | undefined) => void interface PreferenceRowProps { name: keyof Preferences pref: Preference setPref: SetPrefFunc globalServer?: PreferenceValueType globalLocal?: PreferenceValueType roomServer?: PreferenceValueType roomLocal?: PreferenceValueType } const PreferenceRow = ({ name, pref, setPref, globalServer, globalLocal, roomServer, roomLocal, }: PreferenceRowProps) => { const prefType = typeof pref.defaultValue if (prefType !== "boolean" && !pref.allowedValues) { return null } const makeContentCell = ( context: PreferenceContext, val: PreferenceValueType | undefined, inheritedVal: PreferenceValueType, ) => { if (prefType === "boolean") { return } value={val as boolean | undefined} inheritedValue={inheritedVal as boolean} /> } else if (typeof prefType === "string" && pref.allowedValues) { return } value={val as string | undefined} inheritedValue={inheritedVal as string} /> } else { return null } } let inherit: PreferenceValueType return {pref.displayName} {makeContentCell(PreferenceContext.Account, globalServer, inherit = pref.defaultValue)} {makeContentCell(PreferenceContext.Device, globalLocal, inherit = globalServer ?? inherit)} {makeContentCell(PreferenceContext.RoomAccount, roomServer, inherit = globalLocal ?? inherit)} {makeContentCell(PreferenceContext.RoomDevice, roomLocal, inherit = roomServer ?? inherit)} } interface SettingsViewProps { room: RoomStateStore } const CustomCSSInput = ({ setPref, room }: { setPref: SetPrefFunc, room: RoomStateStore }) => { const client = use(ClientContext)! const [context, setContext] = useState(PreferenceContext.Account) const getContextText = useCallback((context: PreferenceContext) => { if (context === PreferenceContext.Account) { return client.store.serverPreferenceCache.custom_css } else if (context === PreferenceContext.Device) { return client.store.localPreferenceCache.custom_css } else if (context === PreferenceContext.RoomAccount) { return room.serverPreferenceCache.custom_css } else if (context === PreferenceContext.RoomDevice) { return room.localPreferenceCache.custom_css } }, [client, room]) const origText = getContextText(context) const [text, setText] = useState(origText ?? "") const onChangeContext = useCallback((evt: React.ChangeEvent) => { const newContext = evt.target.value as PreferenceContext setContext(newContext) setText(getContextText(newContext) ?? "") }, [getContextText]) const onChangeText = useCallback((evt: React.ChangeEvent) => { setText(evt.target.value) }, []) const onSave = useEvent(() => { setPref(context, "custom_css", text) }) const onDelete = useEvent(() => { setPref(context, "custom_css", undefined) setText("") }) return

Custom CSS