From 1cd729c8209bc52cf25ddf2a86813dca01d3ed74 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Wed, 21 Feb 2024 22:09:08 -0800 Subject: [PATCH] applying app settings --- net/web/src/constants/Colors.js | 2 +- net/web/src/constants/Strings.js | 4 +- .../src/context/useSettingsContext.hook.js | 94 ++++++++++++++----- net/web/src/session/Session.styled.js | 2 + net/web/src/session/account/Account.jsx | 2 +- net/web/src/session/account/Account.styled.js | 2 +- .../src/session/account/profile/Profile.jsx | 21 ++--- .../session/account/profile/Profile.styled.js | 10 +- .../profile/accountAccess/AccountAccess.jsx | 70 +++++++++++--- .../accountAccess/AccountAccess.styled.js | 39 ++++++++ .../accountAccess/useAccountAccess.hook.js | 27 ++++++ net/web/src/session/identity/Identity.jsx | 4 +- net/web/src/session/welcome/Welcome.jsx | 4 +- .../src/session/welcome/useWelcome.hook.js | 6 +- 14 files changed, 227 insertions(+), 60 deletions(-) diff --git a/net/web/src/constants/Colors.js b/net/web/src/constants/Colors.js index b1caa718..d41b931b 100644 --- a/net/web/src/constants/Colors.js +++ b/net/web/src/constants/Colors.js @@ -61,7 +61,7 @@ export const LightTheme = { alertText: '#ff8888', itemBorder: '#eeeeee', inputBorder: '#888888', - sectionBorder: '#dddddd', + sectionBorder: '#bbbbbb', headerBorder: '#aaaaaa', }; diff --git a/net/web/src/constants/Strings.js b/net/web/src/constants/Strings.js index 949c3f1e..2cab3319 100644 --- a/net/web/src/constants/Strings.js +++ b/net/web/src/constants/Strings.js @@ -1,6 +1,6 @@ export const en = { code: 'en', - account: 'Account', + settings: 'Settings', contacts: 'Contacts', logout: 'Logout', confirmLogout: 'Are you sure you want to logout?', @@ -29,7 +29,7 @@ export const en = { export const fr = { code: 'fr', - account: 'Compte', + settings: 'Paramètres', contacts: 'Contacts', logout: 'Déconnexion', confirmLogout: 'Êtes-vous sûr de vouloir vous déconnecter?', diff --git a/net/web/src/context/useSettingsContext.hook.js b/net/web/src/context/useSettingsContext.hook.js index b6df4867..dcde739a 100644 --- a/net/web/src/context/useSettingsContext.hook.js +++ b/net/web/src/context/useSettingsContext.hook.js @@ -9,10 +9,14 @@ export function useSettingsContext() { width: null, height: null, theme: null, + setTheme: null, colors: {}, menuStyle: {}, - language: 'en', + languages: [{ value: null, label: 'Default' }, { value: 'en', label: 'English' }, { value: 'fr', label: 'Français' }], + language: null, strings: en, + dateFormat: 'mm/dd', + timeFormat: '12h', }); const SMALL_MEDIUM = 650; @@ -20,8 +24,6 @@ export function useSettingsContext() { const LARGE_XLARGE = 1600; const updateState = (value) => { -console.log("VALUE: ", value); - setState((s) => ({ ...s, ...value })); }; @@ -50,27 +52,52 @@ console.log("VALUE: ", value); const scheme = localStorage.getItem('color_scheme'); if (scheme === 'dark') { - updateState({ theme: scheme, colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); + updateState({ theme: scheme, scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); } else if (scheme === 'light') { - updateState({ theme: scheme, colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }) + updateState({ theme: scheme, scheme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }) } else { if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - updateState({ theme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); + updateState({ theme: null, scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); } else { - updateState({ theme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); + updateState({ theme: null, scheme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); } } + const timeFormat = localStorage.getItem('time_format'); + if (timeFormat == '24h') { + updateState({ timeFormat }); + } + else { + updateState({ timeFormat: '12h' }); + } + + const dateFormat = localStorage.getItem('date_format'); + if (dateFormat == 'dd/mm') { + updateState({ dateFormat }); + } + else { + updateState({ dateFormat: 'mm/dd' }); + } + const language = localStorage.getItem('language'); if (language && language.startsWith('fr')) { updateState({ language: 'fr', strings: fr }); } - else { + else if (language && language.startWith('en')) { updateState({ language: 'en', strings: en }); } + else { + const browser = navigator.language; + if (browser && browser.startsWith('fr')) { + updateState({ language: null, strings: fr }); + } + else { + updateState({ language: null, strings: en }); + } + } return () => { window.removeEventListener('resize', handleResize); @@ -80,31 +107,52 @@ console.log("VALUE: ", value); }, []); const actions = { - setDarkTheme: () => { - localStorage.setItem('color_scheme', 'dark'); - updateState({ theme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); - }, - setLightTheme : () => { - localStorage.setItem('color_scheme', 'light'); - updateState({ theme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); - }, - setDefaultTheme: () => { - localStorage.clearItem('color_scheme'); - if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - updateState({ theme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); + setTheme: (theme) => { + if (theme === 'dark') { + localStorage.setItem('color_scheme', 'dark'); + updateState({ theme: 'dark', scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); + } + else if (theme === 'light') { + localStorage.setItem('color_scheme', 'light'); + updateState({ theme: 'light', scheme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); } else { - updateState({ theme: 'light', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); + localStorage.removeItem('color_scheme'); + if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + updateState({ theme: null, scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } }); + } + else { + updateState({ theme: null, scheme: 'ligth', colors: LightTheme, menuStyle: { backgroundColor: LightTheme.modalArea, color: LightTheme.mainText } }); + } } }, setLanguage: (code: string) => { - localStorage.setItem('language', code); if (code && code.startsWith('fr')) { + localStorage.setItem('language', 'fr'); updateState({ language: 'fr', strings: fr }); } - else { + else if (code && code.startsWith('en')) { + localStorage.setItem('language', 'en'); updateState({ language: 'en', strings: en }); } + else { + localStorage.removeItem('language'); + const browser = navigator.language; + if (browser && browser.startsWith('fr')) { + updateState({ language: null, strings: fr }); + } + else { + updateState({ language: null, strings: en }); + } + } + }, + setDateFormat: (dateFormat) => { + localStorage.setItem('date_format', dateFormat); + updateState({ dateFormat }); + }, + setTimeFormat: (timeFormat) => { + localStorage.setItem('time_format', timeFormat); + updateState({ timeFormat }); }, } diff --git a/net/web/src/session/Session.styled.js b/net/web/src/session/Session.styled.js index 4f06a29f..05596846 100644 --- a/net/web/src/session/Session.styled.js +++ b/net/web/src/session/Session.styled.js @@ -191,6 +191,7 @@ export const SessionWrapper = styled.div` display: flex; flex-direction: column; position: relative; + background-color: ${props => props.theme.baseArea}; } } @@ -217,6 +218,7 @@ export const SessionWrapper = styled.div` .right { flex-grow: 1; position: relative; + background-color: ${props => props.theme.baseArea}; .drawer { padding: 0px; diff --git a/net/web/src/session/account/Account.jsx b/net/web/src/session/account/Account.jsx index 7e1ecc88..7e0bb12a 100644 --- a/net/web/src/session/account/Account.jsx +++ b/net/web/src/session/account/Account.jsx @@ -8,7 +8,7 @@ export function Account({ closeAccount, openProfile }) { return (
-
Account
+
Settings
diff --git a/net/web/src/session/account/Account.styled.js b/net/web/src/session/account/Account.styled.js index 905d558e..f0b36802 100644 --- a/net/web/src/session/account/Account.styled.js +++ b/net/web/src/session/account/Account.styled.js @@ -39,7 +39,7 @@ export const AccountWrapper = styled.div` display: flex; flex-direction: column; justify-content: center; - padding-top: 32px; + padding-top: 16px; align-items: center; flex-grow: 1; diff --git a/net/web/src/session/account/profile/Profile.jsx b/net/web/src/session/account/profile/Profile.jsx index 18cee336..b7541638 100644 --- a/net/web/src/session/account/profile/Profile.jsx +++ b/net/web/src/session/account/profile/Profile.jsx @@ -101,7 +101,7 @@ export function Profile({ closeProfile }) { { state.display !== 'xlarge' && (
{ state.handle }
-
Profile Settings
+
Profile
)}
@@ -144,17 +144,14 @@ export function Profile({ closeProfile }) {
{ state.display !== 'xlarge' && ( -
-
Account Settings
-
- - { state.display === 'small' && ( -
- -
Logout
-
- )} -
+
+ + { state.display === 'small' && ( +
+ +
Logout
+
+ )}
)} { modalContext } -
- saveSearchable(enable)} /> -
Visible in Registry   
+
+
Application
+
+
+
Time Format
+ + 12h + 24h + +
+
+
Date Format
+ + mm/dd + dd/mm + +
+
+
Theme
+ +
+
-
- -
Sealed Topics
-
-
- -
Change Login
+
+
Account
+
+
+ saveSearchable(enable)} /> +
Visible in Registry   
+
+
+ +
Sealed Topics
+
+
+ +
Change Login
+
+
diff --git a/net/web/src/session/account/profile/accountAccess/AccountAccess.styled.js b/net/web/src/session/account/profile/accountAccess/AccountAccess.styled.js index 90b693aa..a8f966f7 100644 --- a/net/web/src/session/account/profile/accountAccess/AccountAccess.styled.js +++ b/net/web/src/session/account/profile/accountAccess/AccountAccess.styled.js @@ -7,6 +7,45 @@ export const AccountAccessWrapper = styled.div` align-items: center; justify-content: center; padding-bottom: 8px; + width: 100%; + + .account { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + } + + .controls { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + padding: 8px; + width: fit-content; + + .option { + display: flex; + padding-top: 8px; + align-items: center; + + .label { + padding-right: 16px; + min-width: 110px; + } + } + } + + .section { + width: 100%; + color: ${props => props.theme.hintText}; + padding-top: 24px; + font-size: 12px; + display: flex; + widtH: 75%; + justify-content: center; + border-bottom: 1px solid ${props => props.theme.sectionBorder}; + } .switch { display: flex; diff --git a/net/web/src/session/account/profile/accountAccess/useAccountAccess.hook.js b/net/web/src/session/account/profile/accountAccess/useAccountAccess.hook.js index 4b4813aa..96d68f4b 100644 --- a/net/web/src/session/account/profile/accountAccess/useAccountAccess.hook.js +++ b/net/web/src/session/account/profile/accountAccess/useAccountAccess.hook.js @@ -1,6 +1,7 @@ import { useRef, useState, useEffect, useContext } from 'react'; import { AccountContext } from 'context/AccountContext'; import { ProfileContext } from 'context/ProfileContext'; +import { SettingsContext } from 'context/SettingsContext'; import { generateSeal, unlockSeal, updateSeal } from 'context/sealUtil'; import { getUsername } from 'api/getUsername'; export function useAccountAccess() { @@ -25,12 +26,19 @@ export function useAccountAccess() { sealDelete: null, sealUnlock: null, + timeFormat: '12h', + dateFormat: 'mm/dd', + theme: null, + language: null, + languages: [], + seal: null, sealKey: null, }); const profile = useContext(ProfileContext); const account = useContext(AccountContext); + const settings = useContext(SettingsContext); const debounce = useRef(null); const updateState = (value) => { @@ -47,6 +55,11 @@ export function useAccountAccess() { updateState({ searchable: status.searchable, seal, sealKey }); }, [account.state]); + useEffect(() => { + const { timeFormat, dateFormat, theme, language, languages } = settings.state; + updateState({ timeFormat, dateFormat, theme, language, languages }); + }, [settings.state]); + const sealUnlock = async () => { const unlocked = unlockSeal(state.seal, state.sealUnlock); await account.actions.unlockSeal(unlocked); @@ -85,6 +98,20 @@ export function useAccountAccess() { } const actions = { + setTimeFormat: (timeFormat) => { +console.log("TIME", timeFormat); + + settings.actions.setTimeFormat(timeFormat.target.value); + }, + setDateFormat: (dateFormat) => { + settings.actions.setDateFormat(dateFormat.target.value); + }, + setTheme: (theme) => { + settings.actions.setTheme(theme); + }, + setLanguage: (language) => { + settings.actions.setLanguage(language); + }, setEditSeal: () => { let sealMode; let sealEnabled = isEnabled(); diff --git a/net/web/src/session/identity/Identity.jsx b/net/web/src/session/identity/Identity.jsx index 16095378..5c8ce42a 100644 --- a/net/web/src/session/identity/Identity.jsx +++ b/net/web/src/session/identity/Identity.jsx @@ -32,10 +32,10 @@ export function Identity({ openAccount, openCards, cardUpdated }) { const menu = ( -
{ state.strings.account }
+
{ state.strings.contacts }
-
{ state.strings.contacts }
+
{ state.strings.settings }
{ state.strings.logout }
diff --git a/net/web/src/session/welcome/Welcome.jsx b/net/web/src/session/welcome/Welcome.jsx index 82286df8..98cbc804 100644 --- a/net/web/src/session/welcome/Welcome.jsx +++ b/net/web/src/session/welcome/Welcome.jsx @@ -16,10 +16,10 @@ export function Welcome() {
Databag
{ state.strings.communication }
- { state.theme === 'light' && ( + { state.scheme === 'light' && ( Session Background )} - { state.theme === 'dark' && ( + { state.scheme === 'dark' && ( Session Background )}
diff --git a/net/web/src/session/welcome/useWelcome.hook.js b/net/web/src/session/welcome/useWelcome.hook.js index 009e4d88..6a32a77d 100644 --- a/net/web/src/session/welcome/useWelcome.hook.js +++ b/net/web/src/session/welcome/useWelcome.hook.js @@ -4,7 +4,7 @@ import { SettingsContext } from 'context/SettingsContext'; export function useWelcome() { const [state, setState] = useState({ - theme: null, + scheme: null, strings: {}, }); @@ -15,8 +15,8 @@ export function useWelcome() { } useEffect(() => { - const { theme, strings } = settings.state; - updateState({ theme, strings }); + const { scheme, strings } = settings.state; + updateState({ scheme, strings }); }, [settings.state]); const actions = {};