Skip to content

Commit

Permalink
feat: add value-indepent hook for setting online status message
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiVandivier committed Dec 11, 2023
1 parent 3253800 commit 734dff4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('useOnlineStatusMessage', () => {
wrapper,
})

expect(result.current.onlineStatusMessage).toBeUndefined()
expect(result.current.onlineStatusMessage).toBeNull()

act(() => {
result.current.setOnlineStatusMessage('8 offline events')
Expand Down
77 changes: 51 additions & 26 deletions services/offline/src/lib/online-status-message.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,64 @@
import React, { ReactElement, ReactNode, useContext, useState } from 'react'
import { OnlineStatusMessageContextAPI } from '../types'

const defaultApi: OnlineStatusMessageContextAPI = {
onlineStatusMessage: undefined,
setOnlineStatusMessage: () => undefined,
}

const OnlineStatusMessageContext =
React.createContext<OnlineStatusMessageContextAPI>(defaultApi)
type SetOnlineStatusMessage = (message: ReactNode) => void

export const useOnlineStatusMessage = (): OnlineStatusMessageContextAPI => {
const { onlineStatusMessage, setOnlineStatusMessage } =
useContext<OnlineStatusMessageContextAPI>(OnlineStatusMessageContext)

return {
onlineStatusMessage,
setOnlineStatusMessage,
}
}
// 'get' and 'set' contexts are separated so 'setter' consumers that don't
// actually need the value don't have to rerender when the value changes:
const OnlineStatusMessageValueContext = React.createContext<ReactNode>(null)
const SetOnlineStatusMessageContext =
React.createContext<SetOnlineStatusMessage>(() => undefined)

export const OnlineStatusMessageProvider = ({
children,
}: {
children: ReactNode
}): ReactElement => {
const [onlineStatusMessage, setOnlineStatusMessage] = useState<ReactNode>()
const [onlineStatusMessage, setOnlineStatusMessage] =
useState<ReactNode>(null) // note: not undefined

return (
<OnlineStatusMessageContext.Provider
value={{
onlineStatusMessage,
setOnlineStatusMessage,
}}
>
{children}
</OnlineStatusMessageContext.Provider>
<OnlineStatusMessageValueContext.Provider value={onlineStatusMessage}>
<SetOnlineStatusMessageContext.Provider
value={setOnlineStatusMessage}
>
{children}
</SetOnlineStatusMessageContext.Provider>
</OnlineStatusMessageValueContext.Provider>
)
}

export const useOnlineStatusMessageValue = () => {
const onlineStatusMessage = useContext(OnlineStatusMessageValueContext)

// note: value is initialized to `null` in provider, not undefined
if (onlineStatusMessage === undefined) {
throw new Error(
'useOnlineStatusMessageValue must be used within an OnlineStatusMessageProvider'
)
}

return onlineStatusMessage
}

export const useSetOnlineStatusMessage = () => {
const setOnlineStatusMessage = useContext(SetOnlineStatusMessageContext)

if (setOnlineStatusMessage === undefined) {
throw new Error(
'useSetOnlineStatusMessage must be used within an OnlineStatusMessageProvider'
)
}

return setOnlineStatusMessage
}

// combination of both getter and setter (also provides backward compatability)
export const useOnlineStatusMessage = () => {
const onlineStatusMessage = useOnlineStatusMessageValue()
const setOnlineStatusMessage = useSetOnlineStatusMessage()

return {
onlineStatusMessage,
setOnlineStatusMessage,
}
}
9 changes: 0 additions & 9 deletions services/offline/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { ReactNode } from 'react'

// Cacheable Section types

export type RecordingState = 'default' | 'pending' | 'error' | 'recording'
Expand Down Expand Up @@ -66,10 +64,3 @@ export interface OfflineInterface {
getCachedSections: () => Promise<IndexedDBCachedSection[]>
removeSection: (id: string) => Promise<boolean>
}

// Online status types

export type OnlineStatusMessageContextAPI = {
onlineStatusMessage?: ReactNode
setOnlineStatusMessage: (additionalInfo: ReactNode) => void
}

0 comments on commit 734dff4

Please sign in to comment.