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

Fix open with for note kind #1 #497

Merged
merged 9 commits into from
Dec 18, 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
6 changes: 3 additions & 3 deletions src/app/shared/Feed.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import Card from "src/partials/Card.svelte"
import Spinner from "src/partials/Spinner.svelte"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Note from "src/app/shared/Note.svelte"
import FeedControls from "src/app/shared/FeedControls.svelte"
import {router} from "src/app/util"
import type {Feed} from "src/domain"
Expand All @@ -51,6 +50,7 @@
isEventMuted,
unwrapRepost,
} from "src/engine"
import FeedItem from "src/app/shared/FeedItem.svelte"

export let feed: Feed
export let anchor = null
Expand Down Expand Up @@ -241,10 +241,10 @@
</FeedControls>
{/if}

<FlexColumn xl bind:element>
<FlexColumn bind:element>
{#each events as note, i (note.id)}
<div in:fly={{y: 20}}>
<Note {filters} {reposts} {depth} {anchor} {note} />
<FeedItem {filters} {reposts} {depth} {anchor} {note} />
</div>
{#if i > 20 && parseInt(hash(note.id)) % 100 === 0 && $promptDismissed < ago(WEEK)}
<Card class="group flex items-center justify-between">
Expand Down
5 changes: 2 additions & 3 deletions src/app/shared/FeedCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import {slide} from "src/util/transition"
import {boolCtrl} from "src/partials/utils"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Card from "src/partials/Card.svelte"
import Chip from "src/partials/Chip.svelte"
import Anchor from "src/partials/Anchor.svelte"
import CopyValueSimple from "src/partials/CopyValueSimple.svelte"
Expand Down Expand Up @@ -49,7 +48,7 @@
)
</script>

<Card class="flex gap-3">
<div class="flex gap-3">
<div class="mt-[6px] hidden sm:block">
<i class="fa fa-rss fa-2xl" />
</div>
Expand Down Expand Up @@ -116,4 +115,4 @@
)}</pre>
{/if}
</FlexColumn>
</Card>
</div>
206 changes: 206 additions & 0 deletions src/app/shared/FeedItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<script lang="ts">
import {repository} from "@welshman/app"
import {ctx} from "@welshman/lib"
import {deriveEvents} from "@welshman/store"
import {getIdOrAddress, getReplyFilters, isChildOf, matchFilters, NOTE} from "@welshman/util"
import {quantify} from "hurdak"
import {onMount} from "svelte"
import NoteMeta from "src/app/shared/NoteMeta.svelte"
import Note from "src/app/shared/Note.svelte"
import {ensureUnwrapped, getSetting, isEventMuted, loadEvent, sortEventsDesc} from "src/engine"
import AltColor from "src/partials/AltColor.svelte"
import Popover from "src/partials/Popover.svelte"
import Spinner from "src/partials/Spinner.svelte"
import {fly, slide} from "src/util/transition"
import {openReplies} from "src/app/state"

export let note
export let relays = []
export let filters = null
export let reposts = new Map()
export let depth = 0
export let anchor = null
export let topLevel = false
export let isLastReply = false
export let showParent = true
export let showLoading = false
export let showMedia = getSetting("show_media")

let ready = false
let event = note
let showMutedReplies = false
let collapsed = depth === 0
let showHiddenReplies = anchor === getIdOrAddress(event)
let draftEventId: string

const showEntire = showHiddenReplies

const context = deriveEvents(repository, {filters: getReplyFilters([event])})

$: children = $context.filter(e => isChildOf(e, event))
$: replies = sortEventsDesc(children.filter(e => e.kind == NOTE))
$: replyIsActive = $openReplies[event.id]

let mutedReplies, hiddenReplies, visibleReplies

$: {
mutedReplies = []
hiddenReplies = []
visibleReplies = []

for (const e of replies) {
if ($isEventMuted(e)) {
mutedReplies.push(e)
} else if (collapsed) {
hiddenReplies.push(e)
} else if (
!showHiddenReplies &&
filters &&
!matchFilters(filters, e) &&
draftEventId !== e.id
) {
hiddenReplies.push(e)
} else {
visibleReplies.push(e)
}
}

if (depth === 0) {
mutedReplies.splice(0)
hiddenReplies.splice(0)
}

if (!showHiddenReplies && visibleReplies.length === 0) {
mutedReplies.splice(0)
hiddenReplies.splice(0)
}

if (showMutedReplies) {
visibleReplies = visibleReplies.concat(mutedReplies.splice(0))
}

if (!showHiddenReplies) {
hiddenReplies = hiddenReplies.concat(visibleReplies.slice(3))
visibleReplies = visibleReplies.slice(0, 3)
}
}

onMount(async () => {
if (!event.pubkey) {
event = await loadEvent(event.id, {
relays: ctx.app.router.FromRelays(relays).getUrls(),
})
}

event = await ensureUnwrapped(event)

if (event.pubkey) {
ready = true
}
})
</script>

{#if ready}
<div>
<NoteMeta {reposts} note={event} />
<div class="note relative">
{#if !showParent && !topLevel}
<AltColor let:isAlt>
<svg height="36" width="36" class="absolute -left-[18px] top-1">
<circle
cx="18"
cy="18"
r="14"
fill="transparent"
stroke-width="4"
stroke-dashoffset="54"
stroke-dasharray="100 100"
transform-origin="center"
class={isAlt ? "stroke-tinted-700" : "stroke-neutral-800"} />
</svg>
</AltColor>
{#if isLastReply}
<AltColor background class="absolute -left-4 h-[20px] w-1" let:isAlt />
{:else}
<AltColor background class="absolute -bottom-2 -left-4 top-0 w-1" let:isAlt />
{/if}
{/if}
<Note note={event} {showEntire} {showParent} {showMedia} />
{#if !replyIsActive && (visibleReplies.length > 0 || collapsed) && !showEntire && depth > 0}
<div class="relative">
<AltColor
background
class="absolute left-0 top-0 -mr-2 -mt-6 flex h-8 w-8 cursor-pointer items-center
justify-center rounded-full"
on:click={() => {
collapsed = !collapsed
}}>
<Popover triggerType="mouseenter">
<div slot="trigger">
<i
class="fa fa-arrow-up transition-all"
class:text-tinted-500={!collapsed}
class:text-tinted-100={collapsed}
class:rotate-180={collapsed} />
</div>
<div slot="tooltip">
{collapsed ? "Show replies" : "Hide replies"}
</div>
</Popover>
</AltColor>
</div>
{/if}

{#if visibleReplies.length > 0 || hiddenReplies.length > 0 || mutedReplies.length > 0}
<div
class="note-children relative ml-4 flex flex-col"
in:fly|local={{y: 20}}
out:slide|local>
{#if hiddenReplies.length > 0}
<button
class="mt-4 cursor-pointer rounded-md bg-gradient-to-l from-transparent via-tinted-700 to-tinted-700 py-2 text-neutral-100 outline-0 transition-colors hover:bg-tinted-700"
on:click={() => {
showHiddenReplies = true
}}>
<i class="fa fa-up-down pr-2 text-sm" />
Show {quantify(hiddenReplies.length, "other reply", "more replies")}
</button>
{#if visibleReplies.length > 0}
<AltColor background class="absolute -left-4 -top-10 h-28 w-1" />
{/if}
{:else if visibleReplies.length > 0}
<AltColor background class="absolute -left-4 -top-10 h-14 w-1" />
{/if}
{#if visibleReplies.length}
{#key showHiddenReplies}
<div in:fly={{y: 20}}>
{#each visibleReplies as r, i (r.id)}
<svelte:self
isLastReply={i === visibleReplies.length - 1}
showParent={false}
showHidden
note={r}
depth={depth - 1}
{filters}
{anchor} />
{/each}
</div>
{/key}
{/if}
{#if showHiddenReplies && mutedReplies.length > 0}
<button
class="mt-4 cursor-pointer rounded-md bg-gradient-to-l from-transparent via-tinted-700 to-tinted-700 py-2 text-neutral-100 outline-0 transition-colors hover:bg-tinted-700"
on:click={() => {
showMutedReplies = true
}}>
<i class="fa fa-up-down pr-2 text-sm" />
Show {quantify(mutedReplies.length, "hidden reply", "hidden replies")}
</button>
{/if}
</div>
{/if}
</div>
</div>
{:else if showLoading}
<Spinner />
{/if}
Loading
Loading