diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/preferencesContext.tsx | 62 | ||||
-rw-r--r-- | components/ui.tsx | 36 |
2 files changed, 79 insertions, 19 deletions
diff --git a/components/preferencesContext.tsx b/components/preferencesContext.tsx new file mode 100644 index 0000000..f7bc409 --- /dev/null +++ b/components/preferencesContext.tsx @@ -0,0 +1,62 @@ +import { useState, useEffect, createContext, ReactNode } from 'react'; +import axios from 'axios'; + +import { userPreferences } from '../api/api'; + +function applyPreferences(preferences: userPreferences) { + if(typeof preferences === "undefined") return; + if(typeof preferences.darkMode !== "undefined") + document.getElementsByTagName("html")[0].classList[preferences.darkMode ? "add" : "remove"]("dark"); +} + +var PreferencesContext = createContext<{ preferences?: userPreferences; updatePreference?: (newPreference: userPreferences) => void }>({}); + +export function PreferencesContextWrapper(props: { children?: ReactNode }) { + var [gotData, setGotData] = useState(false); + var [preferences, setPreferences] = useState<userPreferences>(); + + useEffect(() => {(async() => { + if (gotData) return; + if (typeof window === "undefined") return; + if (!document.cookie.includes("token")) return; + + var local_prefs = window.localStorage.getItem("preferences"); + if (local_prefs) { + var local_prefs_json = JSON.parse(local_prefs) as userPreferences; + setPreferences(local_prefs_json); + applyPreferences(local_prefs_json); + } + + var preferencesReq = await axios.request<{ preferences: userPreferences; }>({ + method: "get", + url: `/api/user/preferences`, + headers: {"content-type": "application/json"} + }); + + window.localStorage.setItem("preferences", JSON.stringify(preferencesReq.data.preferences)); + setPreferences(preferencesReq.data.preferences); + + setGotData(true); + })()}); + + useEffect(() => applyPreferences(preferences), [preferences]); + + function updatePreference(newPreference: userPreferences) { + var prefs: userPreferences = Object.assign(preferences, newPreference); + setPreferences(prefs); + applyPreferences(prefs); + axios.request({ + method: "post", + url: `/api/user/updatePreferences`, + headers: {"content-type": "application/json"}, + data: { "newPreferences": prefs } + }); + } + + return <PreferencesContext.Provider value={{ preferences, updatePreference }}> + {props.children} + </PreferencesContext.Provider> +} + +export default PreferencesContext; + diff --git a/components/ui.tsx b/components/ui.tsx index e2d7f41..f17ae5d 100644 --- a/components/ui.tsx +++ b/components/ui.tsx @@ -1,4 +1,4 @@ -import { Component, CSSProperties, ReactNode } from "react"; +import { Component, CSSProperties, ReactNode, useState } from "react"; import SearchIcon from '@material-ui/icons/Search'; import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; @@ -160,31 +160,29 @@ export function SearchBar(props: { label?: string }) { </div> } -export class CheckBox extends Component<{ +export function CheckBox(props: { state?: boolean; style?: CSSProperties; id?: string; onclick?: (state: boolean) => void; -}> { - state = { on: this.props.state || false } - public toggle = () => { - this.setState({ on: !this.state.on }); - this.props.onclick && this.props.onclick(!this.state.on); +}) { + var [on, setOn] = useState(props.state || false); + var toggle = () => { + setOn(!on); + props.onclick && props.onclick(!on); } - render() { - return <div onClick={this.toggle} id={this.props.id} className={this.state.on ? "on" : "off"} style={{ - ...this.props.style, - display: "inline-block", - cursor: "pointer" - }}> - { - this.state.on ? - <CheckBoxIcon/> : - <CheckBoxOutlineBlankIcon/> - } - </div>; + return <div onClick={toggle} id={props.id} className={on ? "on" : "off"} style={{ + ...props.style, + display: "inline-block", + cursor: "pointer" + }}> + { + on ? + <CheckBoxIcon/> : + <CheckBoxOutlineBlankIcon/> } + </div> } export class ColorPicker extends Component<{ |