Cache followed folds in localstorage

This commit is contained in:
Austin Chen 2022-03-29 10:10:40 -07:00
parent 6185e3b740
commit 50ccc68406
2 changed files with 49 additions and 5 deletions

View File

@ -5,8 +5,11 @@ import {
BookOpenIcon,
} from '@heroicons/react/outline'
import clsx from 'clsx'
import _ from 'lodash'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useFollowedFolds } from '../../hooks/use-fold'
import { useUser } from '../../hooks/use-user'
const navigation = [
{ name: 'Home', href: '/home', icon: HomeIcon },
@ -65,6 +68,10 @@ export default function Sidebar() {
const router = useRouter()
const currentPage = router.pathname
const user = useUser()
let folds = useFollowedFolds(user) || []
folds = _.sortBy(folds, 'followCount').reverse()
return (
<nav aria-label="Sidebar" className="sticky top-4 divide-y divide-gray-300">
<div className="space-y-1 pb-8">
@ -79,13 +86,13 @@ export default function Sidebar() {
/>
<div className="mt-3 space-y-2">
{communities.map((community) => (
{folds.map((fold) => (
<a
key={community.name}
href={community.href}
key={fold.name}
href={`/fold/${fold.slug}`}
className="group flex items-center rounded-md px-3 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 hover:text-gray-900"
>
<span className="truncate">&nbsp; {community.name}</span>
<span className="truncate">&nbsp; {fold.name}</span>
</a>
))}
</div>

View File

@ -1,7 +1,9 @@
import _ from 'lodash'
import { useEffect, useState } from 'react'
import { Fold } from '../../common/fold'
import { User } from '../../common/user'
import {
listAllFolds,
listenForFold,
listenForFolds,
listenForFoldsWithTags,
@ -49,7 +51,7 @@ export const useFollowingFold = (fold: Fold, user: User | null | undefined) => {
return following
}
// Note: We cache FollowedFolds in localstorage to speed up the initial load
// Note: We cache followedFoldIds in localstorage to speed up the initial load
export const useFollowedFoldIds = (user: User | null | undefined) => {
const [followedFoldIds, setFollowedFoldIds] = useState<string[] | undefined>(
undefined
@ -72,3 +74,38 @@ export const useFollowedFoldIds = (user: User | null | undefined) => {
return followedFoldIds
}
// We also cache followedFolds directly in JSON.
// TODO: Extract out localStorage caches to a utility
export const useFollowedFolds = (user: User | null | undefined) => {
const [followedFolds, setFollowedFolds] = useState<Fold[] | undefined>()
const ids = useFollowedFoldIds(user)
useEffect(() => {
if (user && ids) {
const key = `followed-full-folds-${user.id}`
const followedFoldJson = localStorage.getItem(key)
if (followedFoldJson) {
setFollowedFolds(JSON.parse(followedFoldJson))
// Exit early if ids and followedFoldIds have all the same elements.
if (
_.isEqual(
_.sortBy(ids),
_.sortBy(JSON.parse(followedFoldJson).map((f: Fold) => f.id))
)
) {
return
}
}
// Otherwise, fetch the full contents of all folds
listAllFolds().then((folds) => {
const followedFolds = folds.filter((fold) => ids.includes(fold.id))
setFollowedFolds(followedFolds)
localStorage.setItem(key, JSON.stringify(followedFolds))
})
}
}, [user, ids])
return followedFolds
}