mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
web/settings: add custom css editor
This commit is contained in:
parent
63a1aa6cb7
commit
2487c8c88f
2 changed files with 105 additions and 3 deletions
|
@ -3,7 +3,7 @@ div.settings-view {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> h2 {
|
||||
h2, h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -14,4 +14,56 @@ div.settings-view {
|
|||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
> div.custom-css-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: .5rem;
|
||||
margin-right: 1rem;
|
||||
|
||||
> div.header {
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
> textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
border: 1px solid var(--border-color);
|
||||
outline: none;
|
||||
height: 10rem;
|
||||
min-height: 3rem;
|
||||
font-family: var(--monospace-font-stack);
|
||||
}
|
||||
|
||||
> div.buttons {
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
gap: .5rem;
|
||||
|
||||
> button {
|
||||
padding: .5rem 1rem;
|
||||
|
||||
&.save {
|
||||
background-color: var(--primary-color);
|
||||
color: var(--inverted-text-color);
|
||||
font-weight: bold;
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--primary-color-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&.delete {
|
||||
font-weight: bold;
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--error-color);
|
||||
color: var(--inverted-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import { use, useCallback } from "react"
|
||||
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"
|
||||
|
@ -85,12 +86,15 @@ interface PreferenceRowProps {
|
|||
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,
|
||||
) => {
|
||||
const prefType = typeof pref.defaultValue
|
||||
if (prefType === "boolean") {
|
||||
return <BooleanPreferenceCell
|
||||
name={name}
|
||||
|
@ -127,6 +131,51 @@ interface SettingsViewProps {
|
|||
room: RoomStateStore
|
||||
}
|
||||
|
||||
const CustomCSSInput = ({ setPref, room }: { setPref: SetPrefFunc, room: RoomStateStore }) => {
|
||||
const client = use(ClientContext)!
|
||||
const [context, setContext] = useState(PreferenceContext.Account)
|
||||
const [text, setText] = useState("")
|
||||
const onChangeContext = useCallback((evt: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const newContext = evt.target.value as PreferenceContext
|
||||
setContext(newContext)
|
||||
if (newContext === PreferenceContext.Account) {
|
||||
setText(client.store.serverPreferenceCache.custom_css ?? "")
|
||||
} else if (newContext === PreferenceContext.Device) {
|
||||
setText(client.store.localPreferenceCache.custom_css ?? "")
|
||||
} else if (newContext === PreferenceContext.RoomAccount) {
|
||||
setText(room.serverPreferenceCache.custom_css ?? "")
|
||||
} else if (newContext === PreferenceContext.RoomDevice) {
|
||||
setText(room.localPreferenceCache.custom_css ?? "")
|
||||
}
|
||||
}, [client, room])
|
||||
const onChangeText = useCallback((evt: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setText(evt.target.value)
|
||||
}, [])
|
||||
const onSave = useEvent(() => {
|
||||
setPref(context, "custom_css", text)
|
||||
})
|
||||
const onDelete = useEvent(() => {
|
||||
setPref(context, "custom_css", undefined)
|
||||
setText("")
|
||||
})
|
||||
return <div className="custom-css-input">
|
||||
<div className="header">
|
||||
<h3>Custom CSS</h3>
|
||||
<select value={context} onChange={onChangeContext}>
|
||||
<option value={PreferenceContext.Account}>Account</option>
|
||||
<option value={PreferenceContext.Device}>Device</option>
|
||||
<option value={PreferenceContext.RoomAccount}>Room (account)</option>
|
||||
<option value={PreferenceContext.RoomDevice}>Room (device)</option>
|
||||
</select>
|
||||
</div>
|
||||
<textarea value={text} onChange={onChangeText}/>
|
||||
<div className="buttons">
|
||||
<button className="delete" onClick={onDelete}>Delete</button>
|
||||
<button className="save" onClick={onSave}>Save</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
const SettingsView = ({ room }: SettingsViewProps) => {
|
||||
const client = use(ClientContext)!
|
||||
const setPref = useCallback((context: PreferenceContext, key: keyof Preferences, value: PreferenceValueType | undefined)=> {
|
||||
|
@ -186,6 +235,7 @@ const SettingsView = ({ room }: SettingsViewProps) => {
|
|||
/>)}
|
||||
</tbody>
|
||||
</table>
|
||||
<CustomCSSInput setPref={setPref} room={room} />
|
||||
<JSONView data={room.preferences} />
|
||||
</>
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue