Skip to content

Commit

Permalink
Merge pull request #135 from weaponsforge/fix/viky-134
Browse files Browse the repository at this point in the history
changelogs:
  • Loading branch information
weaponsforge authored May 1, 2023
2 parents 293f5a9 + f952426 commit de99c2d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 96 deletions.
12 changes: 8 additions & 4 deletions client/src/common/layout/page/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Box from '@mui/material/Box'
import Header from '@/common/layout/header'
import Section from '@/common/layout/section'
import { useSyncLocalStorage } from '@/lib/hooks/useSync'
import { setSyncLocalStorage, useSyncLocalStorage } from '@/lib/hooks/useSync'
import { Sidebar } from '../sidebar'
import { updateSyncV, useSyncV } from 'use-sync-v'
import { Divider, useMediaQuery } from '@mui/material'
Expand All @@ -20,8 +20,7 @@ const Background = () => {
top: 0,
width: '100%',
height: '100%',
animation: `animate 90s linear infinite, ${
activeTheme === 'dark' ? 'darkColorSwitcher' : 'lightColorSwitcher'
animation: `animate 90s linear infinite, ${activeTheme === 'dark' ? 'darkColorSwitcher' : 'lightColorSwitcher'
} 42s linear infinite`,
},
'&:after': {
Expand Down Expand Up @@ -79,6 +78,11 @@ function Page({ children }) {
updateSyncV('show.sidebar', true)
}
}, [isMobile])
useEffect(() => {
if (typeof animate === 'undefined') {
setSyncLocalStorage('animate', true)
}
},[animate])
return (
<>
{animate && <Background />}
Expand All @@ -98,7 +102,7 @@ function Page({ children }) {
sx={{
flex: 1,
display: 'flex',
overflowY:'scroll'
overflowY: 'scroll'
}}
>
{showSidebar && auth.authStatus === 'signedIn' && <Sidebar />}
Expand Down
100 changes: 10 additions & 90 deletions client/src/lib/hooks/useSync.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useCallback, useSyncExternalStore } from 'react'

const useSyncLocalStorageSubscribers = {}
const useSyncStoreSubscribers = {}
const store = {}

export const useSyncLocalStorage = (saveDirectory = 'global') => {
const subscribe = useCallback(
Expand Down Expand Up @@ -34,7 +32,11 @@ export const useSyncLocalStorage = (saveDirectory = 'global') => {

const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)

return state ? JSON.parse(state) : undefined
try {
return JSON.parse(state)
} catch (e) {
return state
}
}

export const setSyncLocalStorage = (saveDirectory = 'global', updatedValue) => {
Expand All @@ -43,94 +45,12 @@ export const setSyncLocalStorage = (saveDirectory = 'global', updatedValue) => {
subscriber()
}
}
localStorage[saveDirectory] = JSON.stringify(updatedValue)
emitChange()
}

// this is an attempt to solve the bug, and detach getter from setter, so calling setter won't neccesarily subscribe the component to the store
/**
* Returns the state of the given save directory in the store, by subscribing to the save directory
* and using an external state manager to manage state updates.
*
* @param {string} saveDirectory - The save directory to be subscribed to.
* @returns {*} The state of the given save directory in the store.
*/
export const useSyncStore = (saveDirectory = 'global') => {
/**
* Subscribes to the given save directory and returns a function to unsubscribe from the
* save directory.
*
* @param {Function} callback - The callback function to be called when the save directory changes.
* @returns {Function} A function to unsubscribe from the save directory.
*/
const subscribe = useCallback(
(callback) => {
if (!useSyncStoreSubscribers[saveDirectory]) {
useSyncStoreSubscribers[saveDirectory] = []
}

// Adds the callback function to the list of subscribers for the save directory
useSyncStoreSubscribers[saveDirectory] = [
...useSyncStoreSubscribers[saveDirectory],
callback,
]

// Returns a function to remove the callback function from the list of subscribers
return () => {
useSyncStoreSubscribers[saveDirectory] = useSyncStoreSubscribers[
saveDirectory
].filter((el) => el !== callback)
}
},
[saveDirectory]
)

/**
* Returns a snapshot of the state of the given save directory in the store.
*
* @returns {*} A snapshot of the state of the given save directory in the store.
*/
const getSnapshot = () => {
return JSON.stringify(store[saveDirectory])
}

/**
* Returns a snapshot of the state of the given save directory in the server.
*
* @returns {*} A snapshot of the state of the given save directory in the server.
*/
const getServerSnapshot = () => {
return JSON.stringify(store[saveDirectory])
}


// Uses an external state manager to manage state updates and returns the state of the given save directory
const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)

// Returns the parsed state of the given save directory
return state ? JSON.parse(state) : undefined
}

/**
* Sets the updated value to the given save directory in the store, and notifies all subscribers
* subscribed to the save directory.
*
* @param {string} saveDirectory - The save directory in which to set the updated value.
* @param {*} updatedValue - The updated value to be set in the save directory.
*/
export const setSyncStore = (saveDirectory = 'global', updatedValue) => {
/**
* Emits change event to all subscribers subscribed to the save directory.
*/
const emitChange = () => {
for (let subscriber of useSyncStoreSubscribers[saveDirectory]) {
subscriber()
}
try {
const data = JSON.stringify(updatedValue)
localStorage[saveDirectory] = data
} catch(e) {
localStorage[saveDirectory] = updatedValue
}

// Sets the updated value to the given save directory in the store
store[saveDirectory] = updatedValue

// Notifies all subscribers subscribed to the save directory
emitChange()
}
9 changes: 7 additions & 2 deletions client/src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import '@/styles/globals.css'
// MUI
import createEmotionCache from '@/lib/mui/createEmotionCache'
import { lightTheme, darkTheme } from '@/lib/mui/theme'
import { useSyncLocalStorage } from '@/lib/hooks/useSync'
import { setSyncLocalStorage, useSyncLocalStorage } from '@/lib/hooks/useSync'
import { init } from '@/lib/store'
import useInitAuth from '@/hooks/useInitAuth'
import { useEffect } from 'react'

init()
// Source: https://github.com/mui/material-ui/tree/master/examples/material-next
Expand All @@ -22,7 +23,11 @@ export default function MyApp(props) {
const activeTheme = useSyncLocalStorage('activeTheme')
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props
useInitAuth()

useEffect(()=>{
if (typeof activeTheme === 'undefined') {
setSyncLocalStorage('activeTheme', 'light')
}
}, [activeTheme])
return (
<CacheProvider value={emotionCache}>
<Head>
Expand Down

0 comments on commit de99c2d

Please sign in to comment.