Skip to content

Commit

Permalink
web/settings: add custom css editor
Browse files Browse the repository at this point in the history
  • Loading branch information
tulir committed Nov 17, 2024
1 parent 63a1aa6 commit 2487c8c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 3 deletions.
54 changes: 53 additions & 1 deletion web/src/ui/settings/SettingsView.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ div.settings-view {
display: flex;
flex-direction: column;

> h2 {
h2, h3 {
margin: 0;
}

Expand All @@ -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);
}
}
}
}
}
}
54 changes: 52 additions & 2 deletions web/src/ui/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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)=> {
Expand Down Expand Up @@ -186,6 +235,7 @@ const SettingsView = ({ room }: SettingsViewProps) => {
/>)}
</tbody>
</table>
<CustomCSSInput setPref={setPref} room={room} />
<JSONView data={room.preferences} />
</>
}
Expand Down

0 comments on commit 2487c8c

Please sign in to comment.