mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
preparing access page
This commit is contained in:
parent
bb83b87cb3
commit
8471e997c1
77
app/client/web/src/constants/Colors.ts
Normal file
77
app/client/web/src/constants/Colors.ts
Normal file
@ -0,0 +1,77 @@
|
||||
export const LightTheme = {
|
||||
remoteArea: '#080808',
|
||||
localArea: '#888888',
|
||||
splashArea: '#8fbea7',
|
||||
baseArea: '#8fbea7',
|
||||
frameArea: '#e4e4e4',
|
||||
iconArea: '#ffffff',
|
||||
headerArea: '#f0f0f0',
|
||||
footerArea: '#f0f0f0',
|
||||
modalArea: '#eeeeee',
|
||||
itemArea: '#f4f4f4',
|
||||
inputArea: '#ffffff',
|
||||
hoverArea: '#cccccc',
|
||||
noticeArea: '#8fbea7',
|
||||
selectedArea: '#e8e8e8',
|
||||
enabledArea: '#448866',
|
||||
disabledArea: '#cccccc',
|
||||
mainText: '#444444',
|
||||
descriptionText: '#585858',
|
||||
hintText: '#777777',
|
||||
activeText: '#ffffff',
|
||||
idleText: '#aaaaaa',
|
||||
placeholderText: '#777777',
|
||||
linkText: '#448866',
|
||||
labelText: '#888888',
|
||||
alertText: '#ff8888',
|
||||
itemBorder: '#eeeeee',
|
||||
inputBorder: '#888888',
|
||||
sectionBorder: '#bbbbbb',
|
||||
headerBorder: '#aaaaaa',
|
||||
drawerBorder: '#cccccc',
|
||||
unsaved: '#ffff00',
|
||||
connected: '#44cc44',
|
||||
connecting: '#dd88ff',
|
||||
requested: '#4488ff',
|
||||
pending: '#22aaaa',
|
||||
confirmed: '#aaaaaa',
|
||||
}
|
||||
|
||||
export const DarkTheme = {
|
||||
remoteArea: '#080808',
|
||||
localArea: '#888888',
|
||||
splashArea: '#4c4c4c',
|
||||
baseArea: '#080808',
|
||||
frameArea: '#0a0a0a',
|
||||
iconArea: '#ffffff',
|
||||
headerArea: '#111111',
|
||||
footerArea: '#111111',
|
||||
modalArea: '#444444',
|
||||
itemArea: '#222222',
|
||||
inputArea: '#000000',
|
||||
hoverArea: '#555555',
|
||||
noticeArea: '#8fbea7',
|
||||
selectedArea: '#333333',
|
||||
enabledArea: '#448866',
|
||||
disabledArea: '#888888',
|
||||
mainText: '#ffffff',
|
||||
descriptionText: '#999999',
|
||||
hintText: '#aaaaaa',
|
||||
activeText: '#ffffff',
|
||||
idleText: '#aaaaaa',
|
||||
placeholderText: '#686868',
|
||||
linkText: '#66aa88',
|
||||
labelText: '#dddddd',
|
||||
alertText: '#ff8888',
|
||||
itemBorder: '#555555',
|
||||
inputBorder: '#aaaaaa',
|
||||
sectionBorder: '#777777',
|
||||
headerBorder: '#aaaaaa',
|
||||
drawerBorder: '#444444',
|
||||
unsaved: '#ffff00',
|
||||
connected: '#44cc44',
|
||||
connecting: '#dd88ff',
|
||||
requested: '#4488ff',
|
||||
pending: '#22aaaa',
|
||||
confirmed: '#aaaaaa',
|
||||
}
|
1254
app/client/web/src/constants/Strings.ts
Normal file
1254
app/client/web/src/constants/Strings.ts
Normal file
File diff suppressed because it is too large
Load Diff
13
app/client/web/src/context/SettingsContext.tsx
Normal file
13
app/client/web/src/context/SettingsContext.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { ReactNode, createContext } from 'react'
|
||||
import { useSettingsContext } from './useSettingsContext.hook'
|
||||
|
||||
export const SettingsContext = createContext({})
|
||||
|
||||
export function SettingsContextProvider ({ children }: { children: ReactNode }) {
|
||||
const { state, actions } = useSettingsContext()
|
||||
return (
|
||||
<SettingsContext.Provider value={{ state, actions }}>
|
||||
{children}
|
||||
</SettingsContext.Provider>
|
||||
)
|
||||
}
|
229
app/client/web/src/context/useSettingsContext.hook.ts
Normal file
229
app/client/web/src/context/useSettingsContext.hook.ts
Normal file
@ -0,0 +1,229 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { LightTheme, DarkTheme } from '../constants/Colors'
|
||||
import { en, fr, sp, pt, de, ru } from '../constants/Strings'
|
||||
|
||||
export function useSettingsContext () {
|
||||
const [state, setState] = useState({
|
||||
display: null,
|
||||
width: null,
|
||||
height: null,
|
||||
themes: [{ value: 'dark', label: 'Dark' }, { value: 'light', label: 'Light' }],
|
||||
theme: null,
|
||||
scheme: null,
|
||||
colors: {},
|
||||
menuStyle: {},
|
||||
languages: [{ value: 'en', label: 'English' }, { value: 'fr', label: 'Français' }, { value: 'sp', label: 'Español' }, { value: 'pt', label: 'Português' }, { value: 'de', label: 'Deutsch' }, { value: 'ru', label: 'Русский' }],
|
||||
language: null,
|
||||
strings: en,
|
||||
dateFormat: 'mm/dd',
|
||||
timeFormat: '12h',
|
||||
audioId: null,
|
||||
audioInputs: [],
|
||||
videoId: null,
|
||||
videoInputs: [],
|
||||
})
|
||||
|
||||
const SMALL_MEDIUM = 650
|
||||
const MEDIUM_LARGE = 1000
|
||||
const LARGE_XLARGE = 1600
|
||||
|
||||
const updateState = (value: any) => {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
if (window.innerWidth < SMALL_MEDIUM) {
|
||||
updateState({ display: 'small', width: window.innerWidth, height: window.innerHeight })
|
||||
} else if (window.innerWidth < MEDIUM_LARGE) {
|
||||
updateState({ display: 'medium', width: window.innerWidth, height: window.innerHeight })
|
||||
} else if (window.innerWidth < LARGE_XLARGE) {
|
||||
updateState({ display: 'large', width: window.innerWidth, height: window.innerHeight })
|
||||
} else {
|
||||
updateState({ display: 'xlarge', width: window.innerWidth, height: window.innerHeight })
|
||||
}
|
||||
}
|
||||
|
||||
const getDevices = async (type: string) => {
|
||||
if (!navigator || !navigator.mediaDevices) {
|
||||
return []
|
||||
}
|
||||
|
||||
const filtered = new Map()
|
||||
const devices = await navigator.mediaDevices.enumerateDevices()
|
||||
|
||||
devices.filter(item => item.kind === type + 'input').forEach(item => {
|
||||
if (item) {
|
||||
const label = item.label ? item.label : state.strings.integrated
|
||||
const entry = filtered.get(item.groupId)
|
||||
if (entry) {
|
||||
if (item.label && label.length < entry.label.length) {
|
||||
filtered.set(item.groupId, { value: item.deviceId, label })
|
||||
}
|
||||
} else {
|
||||
filtered.set(item.groupId, { value: item.deviceId, label })
|
||||
}
|
||||
}
|
||||
})
|
||||
return Array.from(filtered.values())
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getDevices('audio').then(audio => {
|
||||
updateState({ audioInputs: audio })
|
||||
})
|
||||
getDevices('video').then(video => {
|
||||
updateState({ videoInputs: video })
|
||||
})
|
||||
// eslint-disable-next-line
|
||||
}, [state.strings]);
|
||||
|
||||
useEffect(() => {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
setTimeout(handleResize, 100 * i) // cludge for my mobile browser
|
||||
}
|
||||
handleResize()
|
||||
window.addEventListener('resize', handleResize)
|
||||
window.addEventListener('orientationchange', handleResize)
|
||||
|
||||
const scheme = localStorage.getItem('color_scheme')
|
||||
if (scheme === 'dark') {
|
||||
updateState({ theme: scheme, scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } })
|
||||
} else if (scheme === 'light') {
|
||||
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: null, scheme: 'dark', colors: DarkTheme, menuStyle: { backgroundColor: DarkTheme.modalArea, color: DarkTheme.mainText } })
|
||||
} else {
|
||||
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, themes: [{ value: 'dark', label: fr.dark }, { value: 'light', label: fr.light }] })
|
||||
} else if (language && language.startsWith('sp')) {
|
||||
updateState({ language: 'sp', strings: sp, themes: [{ value: 'dark', label: sp.dark }, { value: 'light', label: sp.light }] })
|
||||
} else if (language && language.startsWith('en')) {
|
||||
updateState({ language: 'en', strings: en, themes: [{ value: 'dark', label: en.dark }, { value: 'light', label: en.light }] })
|
||||
} else if (language && language.startsWith('pt')) {
|
||||
updateState({ language: 'pt', strings: pt, themes: [{ value: 'dark', label: pt.dark }, { value: 'light', label: pt.light }] })
|
||||
} else if (language && language.startsWith('de')) {
|
||||
updateState({ language: 'de', strings: de, themes: [{ value: 'dark', label: de.dark }, { value: 'light', label: de.light }] })
|
||||
} else if (language && language.startsWith('ru')) {
|
||||
updateState({ language: 'ru', strings: ru, themes: [{ value: 'dark', label: ru.dark }, { value: 'light', label: ru.light }] })
|
||||
} else {
|
||||
const browser = navigator.language
|
||||
if (browser && browser.startsWith('fr')) {
|
||||
updateState({ language: null, strings: fr, themes: [{ value: 'dark', label: fr.dark }, { value: 'light', label: fr.light }] })
|
||||
} else if (browser && browser.startsWith('sp')) {
|
||||
updateState({ language: null, strings: sp, themes: [{ value: 'dark', label: sp.dark }, { value: 'light', label: sp.light }] })
|
||||
} else if (browser && browser.startsWith('pt')) {
|
||||
updateState({ language: null, strings: pt, themes: [{ value: 'dark', label: pt.dark }, { value: 'light', label: pt.light }] })
|
||||
} else if (browser && browser.startsWith('de')) {
|
||||
updateState({ language: null, strings: de, themes: [{ value: 'dark', label: de.dark }, { value: 'light', label: de.light }] })
|
||||
} else if (browser && browser.startsWith('ru')) {
|
||||
updateState({ language: null, strings: ru, themes: [{ value: 'dark', label: ru.dark }, { value: 'light', label: ru.light }] })
|
||||
} else {
|
||||
updateState({ language: null, strings: en, themes: [{ value: 'dark', label: en.dark }, { value: 'light', label: en.light }] })
|
||||
}
|
||||
}
|
||||
|
||||
const audioId = localStorage.getItem('audio_input')
|
||||
const videoId = localStorage.getItem('video_input')
|
||||
updateState({ audioId, videoId })
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
window.removeEventListener('orientationchange', handleResize)
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const actions = {
|
||||
setTheme: (theme: string) => {
|
||||
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 {
|
||||
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) => {
|
||||
if (code && code.startsWith('fr')) {
|
||||
localStorage.setItem('language', 'fr')
|
||||
updateState({ language: 'fr', strings: fr, themes: [{ value: 'dark', label: fr.dark }, { value: 'light', label: fr.light }] })
|
||||
} else if (code && code.startsWith('sp')) {
|
||||
localStorage.setItem('language', 'sp')
|
||||
updateState({ language: 'sp', strings: sp, themes: [{ value: 'dark', label: sp.dark }, { value: 'light', label: sp.light }] })
|
||||
} else if (code && code.startsWith('en')) {
|
||||
localStorage.setItem('language', 'en')
|
||||
updateState({ language: 'en', strings: en, themes: [{ value: 'dark', label: en.dark }, { value: 'light', label: en.light }] })
|
||||
} else if (code && code.startsWith('pt')) {
|
||||
localStorage.setItem('language', 'pt')
|
||||
updateState({ language: 'pt', strings: pt, themes: [{ value: 'dark', label: pt.dark }, { value: 'light', label: pt.light }] })
|
||||
} else if (code && code.startsWith('de')) {
|
||||
localStorage.setItem('language', 'de')
|
||||
updateState({ language: 'de', strings: de, themes: [{ value: 'dark', label: de.dark }, { value: 'light', label: de.light }] })
|
||||
} else if (code && code.startsWith('ru')) {
|
||||
localStorage.setItem('language', 'ru')
|
||||
updateState({ language: 'ru', strings: ru, themes: [{ value: 'dark', label: ru.dark }, { value: 'light', label: ru.light }] })
|
||||
} else {
|
||||
localStorage.removeItem('language')
|
||||
const browser = navigator.language
|
||||
if (browser && browser.startsWith('fr')) {
|
||||
updateState({ language: null, strings: fr, themes: [{ value: 'dark', label: fr.dark }, { value: 'light', label: fr.light }] })
|
||||
} else if (browser && browser.startsWith('sp')) {
|
||||
updateState({ language: null, strings: sp, themes: [{ value: 'dark', label: sp.dark }, { value: 'light', label: sp.light }] })
|
||||
} else if (browser && browser.startsWith('pt')) {
|
||||
updateState({ language: null, strings: pt, themes: [{ value: 'dark', label: pt.dark }, { value: 'light', label: pt.light }] })
|
||||
} else if (browser && browser.startsWith('de')) {
|
||||
updateState({ language: null, strings: de, themes: [{ value: 'dark', label: de.dark }, { value: 'light', label: de.light }] })
|
||||
} else if (browser && browser.startsWith('ru')) {
|
||||
updateState({ language: null, strings: ru, themes: [{ value: 'dark', label: ru.dark }, { value: 'light', label: ru.light }] })
|
||||
} else {
|
||||
updateState({ language: null, strings: en, themes: [{ value: 'dark', label: en.dark }, { value: 'light', label: en.light }] })
|
||||
}
|
||||
}
|
||||
},
|
||||
setDateFormat: (dateFormat: string) => {
|
||||
localStorage.setItem('date_format', dateFormat)
|
||||
updateState({ dateFormat })
|
||||
},
|
||||
setTimeFormat: (timeFormat: string) => {
|
||||
localStorage.setItem('time_format', timeFormat)
|
||||
updateState({ timeFormat })
|
||||
},
|
||||
setAudioInput: (audioId: string) => {
|
||||
localStorage.setItem('audio_input', audioId)
|
||||
updateState({ audioId })
|
||||
},
|
||||
setVideoInput: (videoId: string) => {
|
||||
localStorage.setItem('video_input', videoId)
|
||||
updateState({ videoId })
|
||||
},
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
}
|
@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client'
|
||||
import { App } from '@/App'
|
||||
import './index.css'
|
||||
import { AppContextProvider } from './context/AppContext'
|
||||
import { SettingsContextProvider } from './context/SettingsContext'
|
||||
|
||||
const rootElement = document.querySelector('[data-js="root"]')
|
||||
|
||||
@ -12,9 +13,11 @@ if (!rootElement) {
|
||||
|
||||
const root = createRoot(rootElement)
|
||||
root.render(
|
||||
<AppContextProvider>
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
</AppContextProvider>,
|
||||
<SettingsContextProvider>
|
||||
<AppContextProvider>
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
</AppContextProvider>
|
||||
</SettingsContextProvider>,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user