Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove tags #84

Merged
merged 17 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions app/components/ui/deleted-post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,18 @@ export function DeletedPost({ post }: { post: ScoredPost }) {
<div
style={{ cursor: 'pointer' }}
className={'italic text-gray-400'}
onClick={() =>
`/tags/${post.tag}/posts/${post.id}` &&
navigate(`/tags/${post.tag}/posts/${post.id}`)
}
onClick={() => `/post/${post.id}` && navigate(`/post/${post.id}`)}
>
This post was deleted.
</div>

<div className="mt-2 flex w-full text-sm">
<Link to={`/tags/${post.tag}/posts/${post.id}`} className="ml-2">
<Link to={`/post/${post.id}`} className="ml-2">
<CommentIcon needsVote={false} nReplies={post.nReplies} />
</Link>
{isAdminUser && (
<Form id="restore-post-form" method="POST" action="/restorePost">
<input type="hidden" name="postId" value={post.id} />
<input type="hidden" name="tag" value={post.tag} />
<input type="hidden" name="userId" value={user?.id} />
<button className="ml-2 rounded bg-green-600 px-1 text-white">
restore
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function Feed({
(followsParent ? (
<div className="link-to-parent threadline" />
) : (
<ParentPost parentPost={post.parent} tag={post.tag} />
<ParentPost parentPost={post.parent} />
))}
<PostDetails
post={post}
Expand Down
9 changes: 1 addition & 8 deletions app/components/ui/post-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ import { useFetcher } from '@remix-run/react'
import { useState, type FormEvent } from 'react'
import { Textarea } from '#app/components/ui/textarea.tsx'

export function PostForm({
tag,
className,
}: {
tag: string
className?: string
}) {
export function PostForm({ className }: { className?: string }) {
const [textAreaValue, setTextAreaValue] = useState<string>('')

const replyFetcher = useFetcher<{ newPostId: number }>()
Expand All @@ -25,7 +19,6 @@ export function PostForm({
onSubmit={handleSubmit}
>
<div className={`flex flex-col items-end ${className || ''}`}>
<input type="hidden" name="tag" value={`${tag}`} />
<Textarea
placeholder="What's on your mind?"
name="content"
Expand Down
31 changes: 7 additions & 24 deletions app/components/ui/post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export function PostDetails({
>
<VoteButtons
postId={post.id}
tag={post.tag}
noteId={note !== null ? note.id : null}
vote={visibleVoteState}
pCurrent={post.p}
Expand All @@ -125,23 +124,20 @@ export function PostDetails({
content={post.content}
maxLines={teaser ? postTeaserMaxLines : undefined}
deactivateLinks={false}
linkTo={`/tags/${post.tag}/posts/${post.id}`}
linkTo={`/post/${post.id}`}
/>
) : (
<div
style={{ cursor: 'pointer' }}
className={'italic text-gray-400'}
onClick={() =>
`/tags/${post.tag}/posts/${post.id}` &&
navigate(`/tags/${post.tag}/posts/${post.id}`)
}
onClick={() => `/post/${post.id}` && navigate(`/post/${post.id}`)}
>
This post was deleted.
</div>
)}

<div className="mt-2 flex w-full text-sm">
<Link to={`/tags/${post.tag}/posts/${post.id}`} className="ml-2">
<Link to={`/post/${post.id}`} className="ml-2">
<CommentIcon needsVote={needsVote} nReplies={post.nReplies} />
</Link>
{post.deletedAt == null && (
Expand All @@ -160,7 +156,6 @@ export function PostDetails({
{post.deletedAt == null && isAdminUser && (
<Form id="delete-post-form" method="POST" action="/deletePost">
<input type="hidden" name="postId" value={post.id} />
<input type="hidden" name="tag" value={post.tag} />
<input type="hidden" name="userId" value={user?.id} />
<button className="ml-2 rounded bg-red-400 px-1 text-white">
delete
Expand All @@ -183,24 +178,18 @@ export function PostDetails({
action="/reply"
onSubmit={handleReplySubmit}
>
<ReplyForm post={post} tag={post.tag} className="mt-2" />
<ReplyForm post={post} className="mt-2" />
</Form>
)}
</div>
</div>
)
}

export function ParentPost({
parentPost,
tag,
}: {
parentPost: Post
tag: string
}) {
export function ParentPost({ parentPost }: { parentPost: Post }) {
return (
<div className="threadline">
<Link key={parentPost.id} to={`/tags/${tag}/posts/${parentPost.id}`}>
<Link key={parentPost.id} to={`/post/${parentPost.id}`}>
<div
key={parentPost.id}
className="postparent mb-1 ml-3 rounded-lg bg-post p-3 text-sm text-postparent-foreground"
Expand All @@ -222,17 +211,14 @@ export function ParentPost({

function ReplyForm({
post,
tag,
className,
}: {
post: ScoredPost
tag: string
className: string
}) {
return (
<div className={'flex flex-col items-end ' + className}>
<input type="hidden" name="parentId" value={post.id} />
<input type="hidden" name="tag" value={tag} />

<Textarea
name="content"
Expand All @@ -254,13 +240,11 @@ function ReplyForm({
}

export function VoteButtons({
tag,
postId,
noteId,
vote,
pCurrent,
}: {
tag: string
postId: number
noteId: number | null
vote: VoteState
Expand All @@ -274,7 +258,6 @@ export function VoteButtons({
return (
<>
<input type="hidden" name="postId" value={postId} />
<input type="hidden" name="tag" value={tag} />
<input type="hidden" name="state" value={Direction[vote.vote]} />

{noteId === null ? (
Expand All @@ -287,7 +270,7 @@ export function VoteButtons({
<button name="direction" value="Up" className={upClass}>
</button>
<Link to={`/tags/${tag}/stats/${postId}`} className="hyperlink">
<Link to={`/stats/${postId}`} className="hyperlink">
<div className="text-xs">{pCurrentString}</div>
</Link>
<button name="direction" value="Down" className={downClass}>
Expand Down
8 changes: 1 addition & 7 deletions app/conversations.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { type Transaction, sql } from 'kysely'
import { type DB } from './db/kysely-types.ts'
import { getScoredPost, type ScoredPost } from './ranking.ts'
import { getOrInsertTagId } from './tag.ts'
import { relativeEntropy } from './utils/entropy.ts'
import { invariant } from './utils/misc.tsx'

Expand All @@ -13,21 +12,16 @@ export type ThreadPost = ScoredPost & {
export async function getCriticalThread(
trx: Transaction<DB>,
postId: number,
tag: string,
): Promise<ThreadPost[]> {
const tagId = await getOrInsertTagId(trx, tag)

const postWithCriticalThreadId = await trx
.withRecursive('CriticalThread', db =>
db
.selectFrom('Score')
.where('postId', '=', postId)
.where('tagId', '=', tagId)
.select(['postId', 'topNoteId', 'criticalThreadId'])
.unionAll(db =>
db
.selectFrom('Score as S')
.where('tagId', '=', tagId)
.innerJoin('CriticalThread as CT', 'S.postId', 'CT.topNoteId')
.select(['S.postId', 'S.topNoteId', 'S.criticalThreadId']),
),
Expand All @@ -48,7 +42,7 @@ export async function getCriticalThread(
})

const scoredPosts = await Promise.all(
postWithCriticalThreadId.map(post => getScoredPost(trx, tag, post.postId)),
postWithCriticalThreadId.map(post => getScoredPost(trx, post.postId)),
)

const effects = await trx
Expand Down
10 changes: 0 additions & 10 deletions app/db/kysely-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export type Timestamp = ColumnType<Date, Date | string, Date | string>

export type Vote = {
userId: string
tagId: number
postId: number
vote: number
latestVoteEventId: number
Expand All @@ -26,7 +25,6 @@ export type Post = {
deletedAt: number | null
}
export type PostStats = {
tagId: number
postId: number
replies: number
}
Expand All @@ -37,10 +35,6 @@ export type Session = {
updatedAt: number
userId: string
}
export type Tag = {
id: Generated<number>
tag: string
}
export type User = {
id: string
email: string
Expand Down Expand Up @@ -99,7 +93,6 @@ export type VoteEvent = {
export type Score = {
voteEventId: number
voteEventTime: number
tagId: number | null
parentId: number | null
postId: number
topNoteId: number | null
Expand All @@ -114,7 +107,6 @@ export type Score = {
export type Effect = {
voteEventId: number
voteEventTime: number
tagId: number
postId: number
noteId: number | null
topSubthreadId: number | null
Expand All @@ -130,7 +122,6 @@ export type Effect = {
export type FullScore = {
voteEventId: number
voteEventTime: number
tagId: number
postId: number
noteId: number | null
topSubthreadId: number | null
Expand All @@ -155,7 +146,6 @@ export type DB = {
Post: Post
PostStats: PostStats
Session: Session
Tag: Tag
User: User
Verification: Verification
VoteEvent: VoteEvent
Expand Down
1 change: 0 additions & 1 deletion app/db/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type * as schema from '#app/db/kysely-types.ts'

export type User = Selectable<schema.User>
export type Post = Selectable<schema.Post>
export type Tag = Selectable<schema.Tag>
export type Password = Selectable<schema.Password>
export type PostStats = Selectable<schema.PostStats>
export type Verification = Selectable<schema.Verification>
Expand Down
25 changes: 5 additions & 20 deletions app/post.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import assert from 'assert'
import { type Transaction } from 'kysely'
import { type VoteEvent, type Post } from '#app/db/types.ts'
import { type Post } from '#app/db/types.ts'
import { invariant } from '#app/utils/misc.tsx'
import { Direction, vote } from '#app/vote.ts'
import { type DB } from './db/kysely-types.ts'

export async function createPost(
trx: Transaction<DB>,
tag: string,
parentId: number | null, // TODO: use parentId?: number
content: string,
authorId: string,
Expand All @@ -20,31 +19,19 @@ export async function createPost(

invariant(persistedPost, `Reply to ${parentId} not submitted successfully`)

const voteEvent: VoteEvent = await vote(
trx,
tag,
authorId,
persistedPost.id,
null,
Direction.Up,
)
await vote(trx, authorId, persistedPost.id, null, Direction.Up)

if (parentId !== null) {
await incrementReplyCount(trx, voteEvent.tagId, parentId)
await incrementReplyCount(trx, parentId)
}

return persistedPost.id
}

export async function initPostStats(
trx: Transaction<DB>,
tagId: number,
postId: number,
) {
export async function initPostStats(trx: Transaction<DB>, postId: number) {
await trx
.insertInto('PostStats')
.values({
tagId: tagId,
postId: postId,
replies: 0,
})
Expand All @@ -55,16 +42,14 @@ export async function initPostStats(

export async function incrementReplyCount(
trx: Transaction<DB>,
tagId: number,
postId: number,
) {
await initPostStats(trx, tagId, postId)
await initPostStats(trx, postId)
await trx
.updateTable('PostStats')
.set(eb => ({
replies: eb('replies', '+', 1),
}))
.where('tagId', '=', tagId)
.where('postId', '=', postId)
.execute()
}
Expand Down
Loading
Loading