Skip to content

Commit

Permalink
Subscribe change events
Browse files Browse the repository at this point in the history
  • Loading branch information
tachibanayu24 committed Feb 28, 2023
1 parent dfc66a2 commit 7ec8e73
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"Gapcursor",
"lowlight",
"orenotion",
"signin"
"signin",
"unsub"
]
}
35 changes: 20 additions & 15 deletions src/components/uis/Sidebar/PageItem/PageItem.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
import Link from 'next/link'
import { useState } from 'react'
import { useEffect, useState } from 'react'

import { usePage } from '@/hooks'
import { Unsubscribe } from 'firebase/auth'

import { IconButton } from '@/components/uis/Icon/IconButton/IconButton'

import { Menu } from '../../Menu'
import { Page } from '@/models/page'

type PageType = {
id: string
emoji?: string
title: string
}
import { Menu } from '../../Menu'

type Props = {
page: PageType
childPages?: PageType[]
page: Page
// childPages?: PageType[]
onDelete: (id: string) => void
unsubscribe: (id: string) => Unsubscribe
}

export const PageItem = ({ page }: Props) => {
const { deletePage } = usePage()

export const PageItem = ({ page, onDelete, unsubscribe }: Props) => {
const [isHover, setIsHover] = useState(false)
const [isOpenedMenu, setIsOpenedMenu] = useState(false)

const handleCopyLink = (pageId: string) => {
console.log('copy', pageId)
}

useEffect(() => {
const unsub = unsubscribe(page.id)
return () => unsub()
}, [page, unsubscribe])

if (!page) return <></>

// TODO: フルロードしてる
return (
<Link
Expand All @@ -38,7 +41,9 @@ export const PageItem = ({ page }: Props) => {
>
<div className="truncate">
<span className="mr-1">{page.emoji}</span>
<span>{page.title}</span>
<span className={page.title ? undefined : 'text-slate-400'}>
{page.title || 'Untitled'}
</span>
</div>

{(isHover || isOpenedMenu) && (
Expand All @@ -59,7 +64,7 @@ export const PageItem = ({ page }: Props) => {
type: 'default',
icon: 'trash',
title: '削除',
onClick: () => deletePage(page.id),
onClick: () => onDelete(page.id),
isDanger: true,
},
]}
Expand Down
19 changes: 15 additions & 4 deletions src/components/uis/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ export const Sidebar = () => {
const router = useRouter()

const { pages, refetchPages } = usePages()
const { addPage } = usePage()
const { addPage, deletePage, unsubscribePage } = usePage()
const { currentUser } = useCurrentUser()

const handleAddPage = async () => {
await addPage({ emoji: '🚀', title: '宇宙旅行', content: { hoge: 'hoge', fuga: 123 } })
await addPage({ emoji: '📝', title: '' })
refetchPages()
}

const handleDeletePage = async (pageId: string) => {
await deletePage(pageId)
refetchPages()
}

useEffect(() => {
Expand All @@ -41,8 +47,13 @@ export const Sidebar = () => {
</div>
{/* // TODO: */}
{pages ? (
pages.map((page: { id: string; emoji?: string | undefined; title: string }) => (
<PageItem key={page.id} page={page} />
pages.map((page) => (
<PageItem
key={page.id}
page={page}
onDelete={handleDeletePage}
unsubscribe={unsubscribePage}
/>
))
) : (
<SidebarSkeleton />
Expand Down
7 changes: 6 additions & 1 deletion src/hooks/usePage/usePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@ export const usePage = () => {
await pageRepo.delete(id).catch((e) => console.error(e))
}, [])

return { page, fetchPage, addPage, updatePage, deletePage }
const unsubscribePage = useCallback(
(id: string) => pageRepo.unsubscribe(id, (page) => setPage(page)),
[]
)

return { page, fetchPage, addPage, updatePage, deletePage, unsubscribePage }
}
3 changes: 2 additions & 1 deletion src/libs/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ export {
deleteDoc,
updateDoc,
FirestoreError,
onSnapshot,
} from 'firebase/firestore'

export type { DocumentData, FirestoreErrorCode } from 'firebase/firestore'
export type { DocumentData, FirestoreErrorCode, Unsubscribe } from 'firebase/firestore'

export { initializeApp } from 'firebase/app'
export { getAnalytics } from 'firebase/analytics'
Expand Down
10 changes: 10 additions & 0 deletions src/models/__common__/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ export class AuthError extends Error {
this.moduleError = error
}
}

export class NotFoundError extends Error {
private moduleError: Error | undefined

constructor(message: string, error?: Error) {
super()
this.message = message
this.moduleError = error
}
}
8 changes: 5 additions & 3 deletions src/models/page/page.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { JSONContent } from '@tiptap/core'

import { Entity } from '../__common__/entity'

export class Page extends Entity {
emoji?: string
emoji: string
title: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
content: any

content?: JSONContent

constructor(init: Page) {
super(init)
Expand Down
1 change: 1 addition & 0 deletions src/pages/[pageId]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type QueryType = {
pageId: string
}

// TODO: ここからsubscribeして、ページがないエラーをキャッチしたらrootに理レンダリングすればいい気がする
export default function PageDetail() {
const router = useRouter()
const { page, fetchPage, updatePage } = usePage()
Expand Down
13 changes: 10 additions & 3 deletions src/repository/db/page/page.repository.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { doc, getDoc, setDoc, deleteDoc, updateDoc } from '@/libs/firebase'
import { doc, getDoc, setDoc, deleteDoc, updateDoc, onSnapshot } from '@/libs/firebase'

import { db } from '@/config/firebase'

import { NotFoundError } from '@/models/__common__/error'
import { Page } from '@/models/page'

import { DBRepository } from '../__common__/dbRepository'
Expand All @@ -22,8 +23,7 @@ export class PageRepository extends DBRepository<Page> {
const document = await getDoc(ref)

if (!document.exists()) {
// TODO: エラーインスタンスのカスタム
throw new Error('ページが見つかりませんでした')
throw new NotFoundError('ページが見つかりませんでした')
} else {
return new Page(this.docToObject(document))
}
Expand All @@ -41,4 +41,11 @@ export class PageRepository extends DBRepository<Page> {
delete = async (id: Page['id']) => {
return await deleteDoc(doc(db, this.PATH, id))
}

unsubscribe = (id: Page['id'], onUpdate: (page: Page) => void) =>
onSnapshot(doc(db, this.PATH, id), (doc) => {
if (doc.exists()) {
onUpdate(new Page(this.docToObject(doc)))
}
})
}

0 comments on commit 7ec8e73

Please sign in to comment.