Skip to content

Commit

Permalink
Added local storage hook and synced settings via it
Browse files Browse the repository at this point in the history
  • Loading branch information
TomPlum committed Oct 1, 2023
1 parent 1c79b22 commit 680dd05
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/hooks/useLocalStorage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './useLocalStorage.ts'
9 changes: 9 additions & 0 deletions src/hooks/useLocalStorage/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface LocalStorageProps<Value> {
key: string
value: Value
defaultValue: Value
}

export interface LocalStorage<Value> {
value: Value
}
24 changes: 24 additions & 0 deletions src/hooks/useLocalStorage/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LocalStorage, LocalStorageProps } from "hooks/useLocalStorage/types.ts"
import { useEffect, useMemo } from "react"

const useLocalStorage = <Value>({ key, value, defaultValue }: LocalStorageProps<Value>): LocalStorage<Value> => {
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value))
}, [key, value])

const localStorageValue: Value = useMemo(() => {
const storedValue = localStorage.getItem(key)

if (!storedValue) {
return defaultValue
}

return JSON.parse(storedValue) as Value
}, [defaultValue, key])

return {
value: localStorageValue
}
}

export default useLocalStorage
8 changes: 2 additions & 6 deletions src/modules/Settings/context/SettingsContext.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { createContext } from "react"
import { defaultAnkiSettings, NewsSource, SettingsContextBag } from "modules/Settings/context/types.ts"
import { FONTS } from "modules/Settings/components/FontSelector/types.ts"
import { defaultSettings, SettingsContextBag } from "modules/Settings/context/types.ts"

export const SettingsContext = createContext<SettingsContextBag>({
...defaultSettings,
open: false,
setOpen: () => {
console.debug('SettingsContext is not initialised. Tried to invoke setOpen().')
},
sources: [NewsSource.MAINICHI_RSS_FLASH_NEWS],
setSources: () => {
console.debug('SettingsContext is not initialised. Tried to invoke setSources().')
},
language: 'jp',
setLanguage: () => {
console.debug('SettingsContext not initialized. Tried to invoke setLanguage().')
},
font: FONTS[0],
setFont: () => {
console.debug('SettingsContext not initialized. Tried to invoke setFont().')
},
anki: defaultAnkiSettings,
setAnkiSettings: () => {
console.debug('SettingsContext not initialized. Tried to invoke setAnkiSettings().')
}
Expand Down
27 changes: 21 additions & 6 deletions src/modules/Settings/context/SettingsContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { PropsWithChildren, useMemo, useState } from "react"
import { defaultAnkiSettings, NewsSource, SettingsContextBag } from "modules/Settings/context/types.ts"
import {
defaultAnkiSettings,
defaultSettings,
NewsSource,
SettingsContextBag,
SettingsValues
} from "modules/Settings/context/types.ts"
import { SettingsContext } from "modules/Settings/context/SettingsContext.ts"
import { Language } from "modules/Settings/components/LanguageControls/types.ts"
import { Font, FONTS } from "modules/Settings/components/FontSelector/types.ts"
import useLocalStorage from "hooks/useLocalStorage"

const SettingsContextProvider = ({ children }: PropsWithChildren) => {
const [open, setOpen] = useState(false)
Expand All @@ -11,18 +18,26 @@ const SettingsContextProvider = ({ children }: PropsWithChildren) => {
const [language, setLanguage] = useState<Language>('jp')
const [sources, setSources] = useState<NewsSource[]>([NewsSource.MAINICHI_RSS_FLASH_NEWS])

const { value: settings } = useLocalStorage<SettingsValues>({
key: 'settings',
defaultValue: defaultSettings,
value: {
anki,
font,
language,
sources
}
})

const values: SettingsContextBag = useMemo(() => ({
...settings,
open,
setOpen,
sources,
setSources,
language,
setLanguage,
font,
setFont,
anki,
setAnkiSettings: setAnki
}), [open, sources, language, font, anki])
}), [open, settings])

return (
<SettingsContext.Provider value={values}>
Expand Down
22 changes: 16 additions & 6 deletions src/modules/Settings/context/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Language } from "modules/Settings/components/LanguageControls/types.ts"
import { Font } from "modules/Settings/components/FontSelector/types.ts"
import { Font, FONTS } from "modules/Settings/components/FontSelector/types.ts"

export interface AnkiSettings {
deckName: string
Expand All @@ -11,21 +11,31 @@ export const defaultAnkiSettings: AnkiSettings = {
tags: ['nyusu']
}

export interface SettingsContextBag {
export interface SettingsContextBag extends SettingsValues {
open: boolean
setOpen: (open: boolean) => void
sources: NewsSource[]
setSources: (sources: NewsSource[]) => void
language: Language
setLanguage: (language: Language) => void
font: Font
setFont: (font: Font) => void
anki: AnkiSettings
setAnkiSettings: (settings: AnkiSettings) => void
}

export interface SettingsValues {
sources: NewsSource[]
language: Language
font: Font
anki: AnkiSettings
}

export enum NewsSource {
MAINICHI_RSS_FLASH_NEWS = 'mainichi-rss-flash-news',
ASAHI_RSS_HEADLINES = 'asahi-rss-headlines',
NEWSCATCHER_API = 'newscatcher-api'
}

export const defaultSettings: SettingsValues = {
sources: [NewsSource.MAINICHI_RSS_FLASH_NEWS],
anki: defaultAnkiSettings,
font: FONTS[0],
language: 'jp'
}

0 comments on commit 680dd05

Please sign in to comment.