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, BookOpenIcon,
} from '@heroicons/react/outline' } from '@heroicons/react/outline'
import clsx from 'clsx' import clsx from 'clsx'
import _ from 'lodash'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useFollowedFolds } from '../../hooks/use-fold'
import { useUser } from '../../hooks/use-user'
const navigation = [ const navigation = [
{ name: 'Home', href: '/home', icon: HomeIcon }, { name: 'Home', href: '/home', icon: HomeIcon },
@ -65,6 +68,10 @@ export default function Sidebar() {
const router = useRouter() const router = useRouter()
const currentPage = router.pathname const currentPage = router.pathname
const user = useUser()
let folds = useFollowedFolds(user) || []
folds = _.sortBy(folds, 'followCount').reverse()
return ( return (
<nav aria-label="Sidebar" className="sticky top-4 divide-y divide-gray-300"> <nav aria-label="Sidebar" className="sticky top-4 divide-y divide-gray-300">
<div className="space-y-1 pb-8"> <div className="space-y-1 pb-8">
@ -79,13 +86,13 @@ export default function Sidebar() {
/> />
<div className="mt-3 space-y-2"> <div className="mt-3 space-y-2">
{communities.map((community) => ( {folds.map((fold) => (
<a <a
key={community.name} key={fold.name}
href={community.href} 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" 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> </a>
))} ))}
</div> </div>

View File

@ -1,7 +1,9 @@
import _ from 'lodash'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Fold } from '../../common/fold' import { Fold } from '../../common/fold'
import { User } from '../../common/user' import { User } from '../../common/user'
import { import {
listAllFolds,
listenForFold, listenForFold,
listenForFolds, listenForFolds,
listenForFoldsWithTags, listenForFoldsWithTags,
@ -49,7 +51,7 @@ export const useFollowingFold = (fold: Fold, user: User | null | undefined) => {
return following 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) => { export const useFollowedFoldIds = (user: User | null | undefined) => {
const [followedFoldIds, setFollowedFoldIds] = useState<string[] | undefined>( const [followedFoldIds, setFollowedFoldIds] = useState<string[] | undefined>(
undefined undefined
@ -72,3 +74,38 @@ export const useFollowedFoldIds = (user: User | null | undefined) => {
return followedFoldIds 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
}