Skip to content

Commit

Permalink
move all vote buttons into PostActionBar
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannesNakayama committed Oct 16, 2024
1 parent da53f1b commit 451d849
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 128 deletions.
131 changes: 99 additions & 32 deletions app/components/building-blocks/post-action-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import TextareaAutosize from 'react-textarea-autosize'
import { Icon } from '#app/components/ui/icon.tsx'
import { MAX_CHARS_PER_POST } from '#app/constants.ts'
import { postIsPoll } from '#app/modules/posts/post-service.ts'
import { VoteDirection, type Post } from '#app/modules/posts/post-types.ts'
import {
type Poll,
PollType,
VoteDirection,
type Post,
} from '#app/modules/posts/post-types.ts'
import {
type CommentTreeState,
type ReplyTree,
Expand Down Expand Up @@ -87,10 +92,6 @@ export function PostActionBar({
})
}

const isTargetPost = post.id == treeContext.targetPostId

const isTopLevelPost = post.parentId === null

const submitVote = async function (direction: VoteDirection) {
const payLoad = {
postId: post.id,
Expand Down Expand Up @@ -162,35 +163,17 @@ export function PostActionBar({
<Icon name="chevron-down" className="ml-[-0.2em]" />
</button>
))}
{loggedIn && (!isTargetPost || !isTopLevelPost || !isPoll) && (
{loggedIn && !isDeleted && (
<>
<button
title={'Upvote'}
onClick={async () => await submitVote(VoteDirection.Up)}
>
<Icon
name={
postState.voteState.vote == VoteDirection.Up
? 'thick-arrow-up-solid'
: 'thick-arrow-up'
}
/>
</button>
<span className="mx-[-0.6em]">Vote</span>
<button
title={'Downvote'}
onClick={async () => await submitVote(VoteDirection.Down)}
className="mr-[0.3em]"
>
<Icon
name={
postState.voteState.vote == VoteDirection.Down
? 'thick-arrow-down-solid'
: 'thick-arrow-down'
}
className="mt-[-0.2em]"
{isPoll ? (
<PollVoteButtons
poll={post}
postState={postState}
submitVote={submitVote}
/>
</button>
) : (
<VoteButtons postState={postState} submitVote={submitVote} />
)}
</>
)}
{false && (
Expand Down Expand Up @@ -262,6 +245,90 @@ export function PostActionBar({
)
}

function VoteButtons({
postState,
submitVote,
}: {
postState: PostState
submitVote: (direction: VoteDirection) => Promise<void>
}) {
return (
<>
<button
title={'Upvote'}
onClick={async () => await submitVote(VoteDirection.Up)}
>
<Icon
name={
postState.voteState.vote == VoteDirection.Up
? 'thick-arrow-up-solid'
: 'thick-arrow-up'
}
/>
</button>
<span className="mx-[-0.6em]">Vote</span>
<button
title={'Downvote'}
onClick={async () => await submitVote(VoteDirection.Down)}
className="mr-[0.3em]"
>
<Icon
name={
postState.voteState.vote == VoteDirection.Down
? 'thick-arrow-down-solid'
: 'thick-arrow-down'
}
className="mt-[-0.2em]"
/>
</button>
</>
)
}

function PollVoteButtons({
poll,
postState,
submitVote,
}: {
poll: Poll
postState: PostState
submitVote: (direction: VoteDirection) => Promise<void>
}) {
// TODO: handle else case properly
const upvoteLabel = poll.pollType == PollType.FactCheck ? 'True' : 'Agree'

// TODO: handle else case properly
const downvoteLabel =
poll.pollType == PollType.FactCheck ? 'False' : 'Disagree'

return (
<div className="flex space-x-1 rounded px-2 opacity-100 ">
<button
title={upvoteLabel}
onClick={async () => await submitVote(VoteDirection.Up)}
className={
postState.voteState.vote == VoteDirection.Up
? 'font-bold text-purple-700 dark:text-purple-500'
: ''
}
>
{upvoteLabel + ' <'}
</button>
<button
title={downvoteLabel}
onClick={async () => await submitVote(VoteDirection.Down)}
className={
postState.voteState.vote == VoteDirection.Down
? 'font-bold text-purple-700 dark:text-purple-500'
: ''
}
>
{'> ' + downvoteLabel}
</button>
</div>
)
}

function AdminFeatureBar({
isDeleted,
handleDeletePost,
Expand Down
107 changes: 11 additions & 96 deletions app/components/building-blocks/post-details.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import { Link, useNavigate } from '@remix-run/react'
import { useNavigate } from '@remix-run/react'
import type Immutable from 'immutable'
import { useRef } from 'react'
import PollResult from '#app/components/building-blocks/poll-result.tsx'
import { PostActionBar } from '#app/components/building-blocks/post-action-bar.tsx'
import { PostContent } from '#app/components/building-blocks/post-content.tsx'
import { PostInfoBar } from '#app/components/building-blocks/post-info-bar.tsx'
import { postIsPoll } from '#app/modules/posts/post-service.ts'
import {
type Poll,
PollType,
VoteDirection,
} from '#app/modules/posts/post-types.ts'
import {
type CommentTreeState,
type ReplyTree,
type PostState,
} from '#app/modules/posts/ranking/ranking-types.ts'
import { VoteDirection } from '#app/modules/posts/post-types.ts'
import { type ReplyTree } from '#app/modules/posts/ranking/ranking-types.ts'
import { type TreeContext } from '#app/routes/post.$postId.tsx'
import { invariant } from '#app/utils/misc.tsx'
import { useOptionalUser } from '#app/utils/user.ts'

export function PostDetails({
replyTree,
Expand Down Expand Up @@ -77,21 +68,16 @@ export function PostDetails({
This post was deleted.
</div>
)}
{isTargetPost && isTopLevelPost && isPoll && (
<PollVoteButtons
poll={post}
postState={postState}
<div className="mt-auto">
<PostActionBar
key={`${post.id}-actionbar`}
replyTree={replyTree}
pathFromTargetPost={pathFromTargetPost}
postDetailsRef={postDetailsRef}
treeContext={treeContext}
postState={postState}
/>
)}
<PostActionBar
key={`${post.id}-actionbar`}
replyTree={replyTree}
pathFromTargetPost={pathFromTargetPost}
postDetailsRef={postDetailsRef}
treeContext={treeContext}
postState={postState}
/>
</div>
</div>

{isTargetPost && isTopLevelPost && isPoll && (
Expand All @@ -105,74 +91,3 @@ export function PostDetails({
</div>
)
}

function PollVoteButtons({
poll,
postState,
treeContext,
}: {
poll: Poll
postState: PostState
treeContext: TreeContext
}) {
const user = useOptionalUser()
const loggedIn: boolean = user !== null

const submitVote = async function (direction: VoteDirection) {
const payLoad = {
postId: poll.id,
focussedPostId: treeContext.targetPostId,
direction: direction,
currentVoteState: postState.voteState.vote,
}
const response = await fetch('/vote', {
method: 'POST',
body: JSON.stringify(payLoad),
headers: {
'Content-Type': 'application/json',
},
})
const newCommentTreeState = (await response.json()) as CommentTreeState
treeContext.setCommentTreeState(newCommentTreeState)
}

// TODO: handle else case properly
const upvoteLabel = poll.pollType == PollType.FactCheck ? 'True' : 'Agree'

// todo: handle else case properly
const downvoteLabel =
poll.pollType == PollType.FactCheck ? 'False' : 'Disagree'

return loggedIn ? (
<div className="my-2 space-x-4">
<button
title={'Upvote'}
onClick={async () => await submitVote(VoteDirection.Up)}
className={
'rounded-full px-4 py-2 text-primary-foreground ' +
(postState.voteState.vote == VoteDirection.Up
? 'bg-primary text-primary-foreground'
: 'text-secondary-foreground outline outline-2 outline-secondary-foreground')
}
>
{upvoteLabel}
</button>
<button
title={'Downvote'}
onClick={async () => await submitVote(VoteDirection.Down)}
className={
'rounded-full px-4 py-2 text-primary-foreground ' +
(postState.voteState.vote == VoteDirection.Down
? 'bg-primary text-primary-foreground'
: 'text-secondary-foreground outline outline-2 outline-secondary-foreground')
}
>
{downvoteLabel}
</button>
</div>
) : (
<div className="mt-2 text-sm opacity-50">
<Link to="/login">Log in to comment and vote.</Link>
</div>
)
}

0 comments on commit 451d849

Please sign in to comment.