Skip to content

Commit

Permalink
✨ Add show context buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
NatoBoram committed Aug 6, 2023
1 parent e733f3f commit b643638
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 76 deletions.
5 changes: 1 addition & 4 deletions src/lib/comments/CommentNode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,7 @@

<!-- Load more -->
{#if Number($page.url.searchParams.get('parent_id')) !== commentView.comment.id && commentView.counts.child_count > countAllChildren(children)}
<a
class="max-w-fit rounded-md bg-base-container px-4 py-2 text-on-base-container"
href={commentLink($page.url).href}
>
<a class="base-container max-w-fit rounded-md px-4 py-2" href={commentLink($page.url).href}>
Load {commentView.counts.child_count} comments
</a>
{/if}
Expand Down
63 changes: 4 additions & 59 deletions src/lib/comments/Comments.svelte
Original file line number Diff line number Diff line change
@@ -1,72 +1,17 @@
<script lang="ts">
import type {
BlockPersonResponse,
CommentView,
CommunityModeratorView,
Language,
MyUserInfo,
PurgeItemResponse,
Site,
} from 'lemmy-js-client'
import type { CommunityModeratorView, Language, MyUserInfo, Site } from 'lemmy-js-client'
import { CommentNode as CommentNodeSvelte } from '$lib/comments'
import type { CommentNode } from './comment_node'
let className: string | undefined = undefined
export { className as class }
export let allLanguages: Language[]
export let commentViews: CommentView[]
export let jwt: string | undefined
export let moderators: CommunityModeratorView[]
export let myUser: MyUserInfo | undefined
export let site: Site
let tree: CommentNode[] = []
$: {
const nodes: CommentNode[] = commentViews.map(c => ({ comment: c, children: [] }))
const newTree = []
// flat_path = "0.123.456"
// node_path = "0.123"
// if (flat_path = "node_path.flat_id") node.push(flat)
for (const flat of nodes) {
const node = nodes.find(
node =>
`${node.comment.comment.path}.${flat.comment.comment.id}` === flat.comment.comment.path,
)
if (node) node.children.push(flat)
else newTree.push(flat)
}
tree = newTree
}
function onBlockPerson(event: CustomEvent<BlockPersonResponse>) {
if (!event.detail.blocked) return
commentViews = commentViews.filter(
comment => comment.creator.id !== event.detail.person_view.person.id,
)
}
export function getFirst() {
return tree[0]
}
export function getLast() {
return tree[tree.length - 1]
}
export function onPurge(
event: CustomEvent<{ commentView: CommentView; response: PurgeItemResponse }>,
) {
if (!event.detail.response.success) return
commentViews = commentViews.filter(
view => view.comment.id !== event.detail.commentView.comment.id,
)
}
export let tree: CommentNode[]
</script>

<div class="flex flex-col gap-4 {className}">
Expand All @@ -79,9 +24,9 @@
{site}
children={node.children}
commentView={node.comment}
on:block_person={onBlockPerson}
on:block_person
on:comment
on:purge={onPurge}
on:purge
personView={undefined}
/>
{/each}
Expand Down
22 changes: 22 additions & 0 deletions src/lib/comments/comment_tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { CommentView } from 'lemmy-js-client'
import type { CommentNode } from './comment_node'

export function buildCommentTree(commentViews: CommentView[]) {
const nodes: CommentNode[] = commentViews.map(c => ({ comment: c, children: [] }))
const tree = []

// flat_path = "0.123.456"
// node_path = "0.123"
// if (flat_path = "node_path.flat_id") node.push(flat)
for (const flat of nodes) {
const node = nodes.find(
node =>
`${node.comment.comment.path}.${flat.comment.comment.id}` === flat.comment.comment.path,
)

if (node) node.children.push(flat)
else tree.push(flat)
}

return tree
}
109 changes: 96 additions & 13 deletions src/routes/[site]/post/[post]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<script lang="ts">
import type { CommentResponse } from 'lemmy-js-client'
import type { CommentNode } from '$lib/comments/comment_node'
import { ArrowLongRight } from '@natoboram/heroicons.svelte/20/solid'
import type {
BlockPersonResponse,
CommentResponse,
CommentView,
PurgeItemResponse,
} from 'lemmy-js-client'
import { page } from '$app/stores'
import { buildCommentTree } from '$lib/comments/comment_tree'
import Comments from '$lib/comments/Comments.svelte'
import CommentSortSelector from '$lib/comments/CommentSortSelector.svelte'
import CommunitySidebar from '$lib/community/CommunitySidebar.svelte'
Expand All @@ -11,15 +18,15 @@
export let data: PageData
$: comments = data.comments
$: tree = buildCommentTree(data.comments)
function onComment(e: CustomEvent<CommentResponse>) {
data.comments.unshift(e.detail.comment_view)
comments = data.comments
data = data
}
function onNext() {
const first = getFirst()
const first = tree[0]
if (!first) return
document
Expand All @@ -28,16 +35,69 @@
}
function onPrevious() {
const last = getLast()
const last = tree[tree.length - 1]
if (!last) return
document
.querySelector(`[data-comment-id="${last.comment.comment.id}"]`)
?.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
let getFirst: () => CommentNode | undefined
let getLast: () => CommentNode | undefined
function onBlockPerson(event: CustomEvent<BlockPersonResponse>) {
if (!event.detail.blocked) return
data.comments = data.comments.filter(
comment => comment.creator.id !== event.detail.person_view.person.id,
)
data = data
}
export function onPurge(
event: CustomEvent<{ commentView: CommentView; response: PurgeItemResponse }>,
) {
if (!event.detail.response.success) return
data.comments = data.comments.filter(
view => view.comment.id !== event.detail.commentView.comment.id,
)
data = data
}
function hasContext(parentId: number | undefined) {
if (!parentId) return false
const first = tree[0]
if (!first) return false
return first.comment.comment.path !== `0.${first.comment.comment.id}`
}
function parentLink(url: URL) {
const first = tree[0]
if (!first) return
const paths = first.comment.comment.path.split('.')
if (paths.length < 3) return
// Remove 0 and itself
paths.shift()
paths.pop()
const id = paths.pop()
if (!id) return
const clone = new URL(url.href)
clone.searchParams.set('parent_id', id)
clone.searchParams.delete('page')
return clone.toString()
}
function postLink(url: URL) {
const clone = new URL(url.href)
clone.searchParams.delete('parent_id')
clone.searchParams.delete('page')
return clone.toString()
}
</script>

<svelte:head>
Expand Down Expand Up @@ -72,10 +132,33 @@
<CommentSortSelector sort={data.sort ?? 'Hot'} />
</nav>

<!-- View context button -->
{#if data.parent_id}
You are viewing a single comment thread.

<a
class="base-container flex max-w-fit flex-row items-center gap-2 rounded-md px-4 py-2"
href={postLink($page.url)}
>
View all comments
<ArrowLongRight />
</a>

{#if hasContext(data.parent_id)}
<a
class="base-container flex max-w-fit flex-row items-center gap-2 rounded-md px-4 py-2"
href={parentLink($page.url)}
>
Show context
<ArrowLongRight />
</a>
{/if}
{/if}

{#if data.comments.length || data.page}
<!-- Comments -->
<PaginationBar
length={comments.length}
length={data.comments.length}
limit={data.limit ?? 50}
on:next={onNext}
on:previous={onPrevious}
Expand All @@ -84,20 +167,20 @@
{/if}

<Comments
commentViews={comments}
{tree}
allLanguages={data.all_languages}
bind:getFirst
bind:getLast
jwt={data.jwt}
moderators={data.moderators}
myUser={data.my_user}
on:block_person={onBlockPerson}
on:comment={onComment}
on:purge={onPurge}
site={data.site_view.site}
/>

{#if data.comments.length || data.page}
<PaginationBar
length={comments.length}
length={data.comments.length}
limit={data.limit ?? 50}
on:next={onNext}
on:previous={onPrevious}
Expand Down

0 comments on commit b643638

Please sign in to comment.