60f68b178d
* Fold type, fold page, query for fold contracts * Tsconfig: target esnext, nounused locals: false * Store tags in field on contract. Script to update contract tags * Show tags on fold page * Load all fold comments server-side to serve better feed * Fix the annoying firebase already initialized error! * Add links to /edit and /leaderboards for fold * Page with list of folds * UI for creating a fold * Create a fold * Edit fold page
85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
import {
|
|
doc,
|
|
collection,
|
|
onSnapshot,
|
|
setDoc,
|
|
query,
|
|
collectionGroup,
|
|
where,
|
|
orderBy,
|
|
} from 'firebase/firestore'
|
|
import { getValues, listenForValues } from './utils'
|
|
import { db } from './init'
|
|
import { User } from '../../../common/user'
|
|
import { Comment } from '../../../common/comment'
|
|
export type { Comment }
|
|
|
|
export async function createComment(
|
|
contractId: string,
|
|
betId: string,
|
|
text: string,
|
|
commenter: User
|
|
) {
|
|
const ref = doc(getCommentsCollection(contractId), betId)
|
|
return await setDoc(ref, {
|
|
contractId,
|
|
betId,
|
|
text,
|
|
createdTime: Date.now(),
|
|
userName: commenter.name,
|
|
userUsername: commenter.username,
|
|
userAvatarUrl: commenter.avatarUrl,
|
|
})
|
|
}
|
|
|
|
function getCommentsCollection(contractId: string) {
|
|
return collection(db, 'contracts', contractId, 'comments')
|
|
}
|
|
|
|
export async function listAllComments(contractId: string) {
|
|
const comments = await getValues<Comment>(getCommentsCollection(contractId))
|
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
|
return comments
|
|
}
|
|
|
|
export function listenForComments(
|
|
contractId: string,
|
|
setComments: (comments: Comment[]) => void
|
|
) {
|
|
return onSnapshot(getCommentsCollection(contractId), (snap) => {
|
|
const comments = snap.docs.map((doc) => doc.data() as Comment)
|
|
|
|
comments.sort((c1, c2) => c1.createdTime - c2.createdTime)
|
|
|
|
setComments(comments)
|
|
})
|
|
}
|
|
|
|
// Return a map of betId -> comment
|
|
export function mapCommentsByBetId(comments: Comment[]) {
|
|
const map: Record<string, Comment> = {}
|
|
for (const comment of comments) {
|
|
map[comment.betId] = comment
|
|
}
|
|
return map
|
|
}
|
|
|
|
const DAY_IN_MS = 24 * 60 * 60 * 1000
|
|
|
|
// Define "recent" as "<3 days ago" for now
|
|
const recentCommentsQuery = query(
|
|
collectionGroup(db, 'comments'),
|
|
where('createdTime', '>', Date.now() - 3 * DAY_IN_MS),
|
|
orderBy('createdTime', 'desc')
|
|
)
|
|
|
|
export async function getRecentComments() {
|
|
return getValues<Comment>(recentCommentsQuery)
|
|
}
|
|
|
|
export function listenForRecentComments(
|
|
setComments: (comments: Comment[]) => void
|
|
) {
|
|
return listenForValues<Comment>(recentCommentsQuery, setComments)
|
|
}
|