diff --git a/src/components/App.tsx b/src/components/App.tsx
index 5a362864..f8f9a6c5 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -12,6 +12,7 @@ import { InboxProvider } from '../context/inbox'
import { LocalizeProvider } from '../context/localize'
import { MediaQueryProvider } from '../context/mediaQuery'
import { NotificationsProvider } from '../context/notifications'
+import { SeenProvider } from '../context/seen'
import { SessionProvider } from '../context/session'
import { SnackbarProvider } from '../context/snackbar'
import { TopicsProvider } from '../context/topics'
@@ -115,21 +116,23 @@ export const App = (props: Props) => {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx
index 213589ef..6fdbee40 100644
--- a/src/components/Feed/Sidebar/Sidebar.tsx
+++ b/src/components/Feed/Sidebar/Sidebar.tsx
@@ -4,18 +4,17 @@ import { For, Show, createSignal } from 'solid-js'
import { useFollowing } from '../../../context/following'
import { useLocalize } from '../../../context/localize'
+import { useSeen } from '../../../context/seen'
import { Author } from '../../../graphql/schema/core.gen'
import { router, useRouter } from '../../../stores/router'
import { useArticlesStore } from '../../../stores/zine/articles'
-import { useSeenStore } from '../../../stores/zine/seen'
import { Userpic } from '../../Author/Userpic'
import { Icon } from '../../_shared/Icon'
-
import styles from './Sidebar.module.scss'
export const Sidebar = () => {
const { t } = useLocalize()
- const { seen } = useSeenStore()
+ const { seen } = useSeen()
const { subscriptions } = useFollowing()
const { page } = useRouter()
const { articlesByTopic } = useArticlesStore()
diff --git a/src/context/seen.tsx b/src/context/seen.tsx
new file mode 100644
index 00000000..f26ef3e2
--- /dev/null
+++ b/src/context/seen.tsx
@@ -0,0 +1,67 @@
+import { openDB } from 'idb'
+import { Accessor, JSX, createContext, createSignal, onMount, useContext } from 'solid-js'
+
+type SeenContextType = {
+ seen: Accessor<{ [slug: string]: number }>
+ addSeen: (slug: string) => void
+}
+
+const SeenContext = createContext()
+export function useSeen() {
+ return useContext(SeenContext)
+}
+
+const DB_NAME = 'discourseAppDB'
+const DB_VERSION = 1
+const STORE_NAME = 'seen'
+const setupIndexedDB = async () => {
+ return await openDB(DB_NAME, DB_VERSION, {
+ upgrade(db) {
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
+ db.createObjectStore(STORE_NAME, { keyPath: 'slug' })
+ }
+ },
+ })
+}
+
+const getSeenFromIndexedDB = async (db) => {
+ const tx = db.transaction(STORE_NAME, 'readonly')
+ const store = tx.objectStore(STORE_NAME)
+ const seen = await store.getAll()
+ return seen.reduce((acc, { slug, date }) => {
+ acc[slug] = date
+ return acc
+ }, {})
+}
+
+const saveSeenToIndexedDB = async (db, seen) => {
+ const tx = db.transaction(STORE_NAME, 'readwrite')
+ const store = tx.objectStore(STORE_NAME)
+ for (const [slug, date] of Object.entries(seen)) {
+ await store.put({ slug, date })
+ }
+ await tx.done
+}
+
+export const SeenProvider = (props: { children: JSX.Element }) => {
+ const [seen, setSeen] = createSignal<{ [slug: string]: number }>({})
+ const [db, setDb] = createSignal()
+ const addSeen = async (slug: string) => {
+ setSeen((prev) => {
+ const newSeen = { ...prev, [slug]: Date.now() }
+ saveSeenToIndexedDB(db(), newSeen)
+ return newSeen
+ })
+ }
+
+ onMount(async () => {
+ const ndb = await setupIndexedDB()
+ setDb(ndb)
+ const seenFromDB = await getSeenFromIndexedDB(ndb)
+ setSeen(seenFromDB)
+ })
+
+ const value: SeenContextType = { seen, addSeen }
+
+ return {props.children}
+}
diff --git a/src/stores/zine/seen.ts b/src/stores/zine/seen.ts
deleted file mode 100644
index bf01d92d..00000000
--- a/src/stores/zine/seen.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { createStorageSignal } from '@solid-primitives/storage'
-
-// TODO: use indexedDB here
-export const [seen, setSeen] = createStorageSignal<{ [slug: string]: Date }>('seen', {})
-export const addSeen = (slug) => setSeen({ ...seen(), [slug]: Date.now() })
-
-export const useSeenStore = (initialData: { [slug: string]: Date } = {}) => {
- setSeen({ ...seen(), ...initialData })
-
- return {
- seen,
- setSeen,
- addSeen,
- }
-}