forked from coracle/flotilla
Update pomade implementation
This commit is contained in:
@@ -1,51 +1,30 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {Client} from "@pomade/core"
|
||||
import type {SessionItem} from "@pomade/core"
|
||||
import {session, isPomadeSession} from "@welshman/app"
|
||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||
import {fly} from "@lib/transition"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Popover from "@lib/components/Popover.svelte"
|
||||
import TrashBin2 from "@assets/icons/trash-bin-2.svg?dataurl"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
import {onMount} from "svelte"
|
||||
import {loadOtherPomadeSessions} from "@app/core/commands"
|
||||
import type {PomadeSessionWithPeers} from "@app/core/commands"
|
||||
|
||||
type SessionWithPeers = SessionItem & {peers: string[]}
|
||||
|
||||
let sessions = $state<SessionWithPeers[]>([])
|
||||
let deletingSession = $state<string | null>(null)
|
||||
|
||||
const loadSessions = async () => {
|
||||
if (!isPomadeSession($session)) return
|
||||
|
||||
const client = new Client($session.clientOptions)
|
||||
const result = await client.listSessions()
|
||||
const pubkey = await client.getPubkey()
|
||||
|
||||
if (result.ok) {
|
||||
// Group sessions by client pubkey and collect peers
|
||||
const sessionMap = new Map<string, SessionWithPeers>()
|
||||
|
||||
for (const message of result.messages) {
|
||||
if (!message.res?.items) continue
|
||||
|
||||
for (const item of message.res.items) {
|
||||
const existing = sessionMap.get(item.client)
|
||||
|
||||
if (existing) {
|
||||
existing.peers.push(message.url)
|
||||
} else if (item.client !== pubkey) {
|
||||
sessionMap.set(item.client, {...item, peers: [message.url]})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sessions = Array.from(sessionMap.values())
|
||||
}
|
||||
const toggleMenu = (client: string) => {
|
||||
menuClient = menuClient === client ? "" : client
|
||||
}
|
||||
|
||||
const deleteSession = async (sessionItem: SessionWithPeers) => {
|
||||
if (!isPomadeSession($session)) return
|
||||
const closeMenu = () => {
|
||||
menuClient = ""
|
||||
}
|
||||
|
||||
deletingSession = sessionItem.client
|
||||
let menuClient = $state("")
|
||||
let sessions = $state<PomadeSessionWithPeers[]>([])
|
||||
|
||||
const deleteSession = async (sessionItem: PomadeSessionWithPeers) => {
|
||||
if (!isPomadeSession($session)) return
|
||||
|
||||
try {
|
||||
const client = new Client($session.clientOptions)
|
||||
@@ -70,8 +49,6 @@
|
||||
theme: "error",
|
||||
message: "Failed to delete session",
|
||||
})
|
||||
} finally {
|
||||
deletingSession = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +62,9 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
loadSessions()
|
||||
loadOtherPomadeSessions().then(_sessions => {
|
||||
sessions = _sessions
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -93,28 +72,46 @@
|
||||
<div class="flex flex-col gap-4 border-t border-solid border-base-100 pt-4">
|
||||
<strong>Other Sessions</strong>
|
||||
{#each sessions as sessionItem (sessionItem.client)}
|
||||
<div class="flex justify-between text-sm">
|
||||
<div class="flex flex-col gap-1">
|
||||
<span>{sessionItem.client.slice(0, 8)}</span>
|
||||
<div class="flex gap-1">
|
||||
<div class="badge badge-neutral">
|
||||
Created {formatDate(sessionItem.created_at)}
|
||||
</div>
|
||||
<div class="badge badge-neutral">
|
||||
Last active: {formatDate(sessionItem.last_activity)}
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex gap-3 items-center text-sm">
|
||||
<span>Session {sessionItem.client.slice(0, 8)}</span>
|
||||
<span class="opacity-75">
|
||||
{#if sessionItem.deactivated_at}
|
||||
Deactivated
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<Button
|
||||
class="btn btn-circle btn-ghost btn-sm"
|
||||
onclick={() => toggleMenu(sessionItem.client)}>
|
||||
<Icon icon={MenuDots} />
|
||||
</Button>
|
||||
{#if menuClient === sessionItem.client}
|
||||
<Popover hideOnClick onClose={closeMenu}>
|
||||
<ul
|
||||
transition:fly
|
||||
class="menu absolute right-0 z-popover mt-2 w-48 gap-1 rounded-box bg-base-100 p-2 shadow-md">
|
||||
<li>
|
||||
<Button onclick={() => deleteSession(sessionItem)}>
|
||||
<Icon icon={TrashBin2} />
|
||||
Delete Session
|
||||
</Button>
|
||||
</li>
|
||||
</ul>
|
||||
</Popover>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
<div class="badge badge-neutral">
|
||||
Created {formatDate(sessionItem.created_at)}
|
||||
</div>
|
||||
<div class="badge badge-neutral">
|
||||
Active {formatDate(sessionItem.last_activity)}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
class="btn btn-error btn-sm"
|
||||
disabled={deletingSession !== null}
|
||||
onclick={() => deleteSession(sessionItem)}>
|
||||
{#if deletingSession === sessionItem.client}
|
||||
<span class="loading loading-spinner"></span>
|
||||
{:else}
|
||||
<Icon icon={TrashBin2} />
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user