import React, { createContext, useContext, ReactElement, ReactNode, useState, useEffect } from 'react' import { LoggerInstance, LogLevel } from '@oceanprotocol/lib' import { isBrowser } from '@utils/index' import { useSiteMetadata } from '@hooks/useSiteMetadata' interface UserPreferencesValue { debug: boolean setDebug: (value: boolean) => void currency: string setCurrency: (value: string) => void chainIds: number[] privacyPolicySlug: string showPPC: boolean setChainIds: (chainIds: number[]) => void bookmarks: string[] addBookmark: (did: string) => void removeBookmark: (did: string) => void setPrivacyPolicySlug: (slug: string) => void setShowPPC: (value: boolean) => void infiniteApproval: boolean setInfiniteApproval: (value: boolean) => void locale: string } const UserPreferencesContext = createContext(null) const localStorageKey = 'ocean-user-preferences' function getLocalStorage(): UserPreferencesValue { const storageParsed = isBrowser && JSON.parse(window.localStorage.getItem(localStorageKey)) return storageParsed } function setLocalStorage(values: Partial) { return ( isBrowser && window.localStorage.setItem(localStorageKey, JSON.stringify(values)) ) } function UserPreferencesProvider({ children }: { children: ReactNode }): ReactElement { const { appConfig } = useSiteMetadata() const localStorage = getLocalStorage() // Set default values from localStorage const [debug, setDebug] = useState(localStorage?.debug || false) const [currency, setCurrency] = useState( localStorage?.currency || 'EUR' ) const [locale, setLocale] = useState() const [bookmarks, setBookmarks] = useState(localStorage?.bookmarks || []) const [chainIds, setChainIds] = useState( localStorage?.chainIds || appConfig.chainIds ) const { defaultPrivacyPolicySlug } = useSiteMetadata().appConfig const [privacyPolicySlug, setPrivacyPolicySlug] = useState( localStorage?.privacyPolicySlug || defaultPrivacyPolicySlug ) const [showPPC, setShowPPC] = useState( localStorage?.showPPC !== false ) const [infiniteApproval, setInfiniteApproval] = useState( localStorage?.infiniteApproval || false ) // Write values to localStorage on change useEffect(() => { setLocalStorage({ chainIds, debug, currency, bookmarks, privacyPolicySlug, showPPC, infiniteApproval }) }, [ chainIds, debug, currency, bookmarks, privacyPolicySlug, showPPC, infiniteApproval ]) // Set ocean.js log levels, default: Error useEffect(() => { debug === true ? LoggerInstance.setLevel(LogLevel.Verbose) : LoggerInstance.setLevel(LogLevel.Error) }, [debug]) // Get locale always from user's browser useEffect(() => { if (!window) return setLocale(window.navigator.language) }, []) function addBookmark(didToAdd: string): void { const newPinned = [...bookmarks, didToAdd] setBookmarks(newPinned) } function removeBookmark(didToAdd: string): void { const newPinned = bookmarks.filter((did: string) => did !== didToAdd) setBookmarks(newPinned) } // Bookmarks old data structure migration useEffect(() => { if (bookmarks.length !== undefined) return const newPinned: string[] = [] for (const network in bookmarks) { ;(bookmarks[network] as unknown as string[]).forEach((did: string) => { did !== null && newPinned.push(did) }) } setBookmarks(newPinned) }, [bookmarks]) return ( {children} ) } // Helper hook to access the provider values const useUserPreferences = (): UserPreferencesValue => useContext(UserPreferencesContext) export { UserPreferencesProvider, useUserPreferences }