mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Add space status indicator #245
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
import Alerts from "@app/components/Alerts.svelte"
|
import Alerts from "@app/components/Alerts.svelte"
|
||||||
import RoomCreate from "@app/components/RoomCreate.svelte"
|
import RoomCreate from "@app/components/RoomCreate.svelte"
|
||||||
import MenuSpaceRoomItem from "@app/components/MenuSpaceRoomItem.svelte"
|
import MenuSpaceRoomItem from "@app/components/MenuSpaceRoomItem.svelte"
|
||||||
|
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
||||||
import {
|
import {
|
||||||
ENABLE_ZAPS,
|
ENABLE_ZAPS,
|
||||||
MESSAGE_FILTER,
|
MESSAGE_FILTER,
|
||||||
@@ -123,7 +124,7 @@
|
|||||||
class="flex w-full flex-col rounded-xl p-3 transition-all hover:bg-base-100"
|
class="flex w-full flex-col rounded-xl p-3 transition-all hover:bg-base-100"
|
||||||
onclick={openMenu}>
|
onclick={openMenu}>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<strong class="ellipsize flex items-center gap-3">
|
<strong class="ellipsize flex items-center gap-1">
|
||||||
<RelayName {url} />
|
<RelayName {url} />
|
||||||
</strong>
|
</strong>
|
||||||
<Icon icon={AltArrowDown} />
|
<Icon icon={AltArrowDown} />
|
||||||
@@ -245,10 +246,13 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</SecondaryNavSection>
|
</SecondaryNavSection>
|
||||||
<div class="p-4">
|
<div class="flex flex-col gap-2 p-4">
|
||||||
<button class="btn btn-neutral btn-sm w-full" onclick={manageAlerts}>
|
<Button class="btn btn-neutral btn-sm" onclick={showDetail}>
|
||||||
|
<SocketStatusIndicator {url} />
|
||||||
|
</Button>
|
||||||
|
<Button class="btn btn-neutral btn-sm" onclick={manageAlerts}>
|
||||||
<Icon icon={Bell} />
|
<Icon icon={Bell} />
|
||||||
Manage Alerts
|
Manage Alerts
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,17 +6,22 @@
|
|||||||
import {notifications} from "@app/util/notifications"
|
import {notifications} from "@app/util/notifications"
|
||||||
import {makeSpacePath} from "@app/util/routes"
|
import {makeSpacePath} from "@app/util/routes"
|
||||||
import {pushDrawer} from "@app/util/modal"
|
import {pushDrawer} from "@app/util/modal"
|
||||||
|
import {deriveSocketStatus} from "@app/core/state"
|
||||||
|
|
||||||
const {url} = $props()
|
const {url} = $props()
|
||||||
|
|
||||||
const path = makeSpacePath(url) + ":mobile"
|
const path = makeSpacePath(url) + ":mobile"
|
||||||
|
|
||||||
|
const status = deriveSocketStatus(url)
|
||||||
|
|
||||||
const openMenu = () => pushDrawer(MenuSpace, {url})
|
const openMenu = () => pushDrawer(MenuSpace, {url})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button onclick={openMenu} class="btn btn-neutral btn-sm relative md:hidden">
|
<Button onclick={openMenu} class="btn btn-neutral btn-sm relative md:hidden">
|
||||||
<Icon icon={MenuDots} />
|
<Icon icon={MenuDots} />
|
||||||
{#if $notifications.has(path)}
|
{#if $status.theme !== "success"}
|
||||||
|
<div class="absolute right-0 top-0 -mr-1 -mt-1 h-2 w-2 rounded-full bg-{$status.theme}"></div>
|
||||||
|
{:else if $notifications.has(path)}
|
||||||
<div class="absolute right-0 top-0 -mr-1 -mt-1 h-2 w-2 rounded-full bg-primary"></div>
|
<div class="absolute right-0 top-0 -mr-1 -mt-1 h-2 w-2 rounded-full bg-primary"></div>
|
||||||
{/if}
|
{/if}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
13
src/app/components/SocketStatusIndicator.svelte
Normal file
13
src/app/components/SocketStatusIndicator.svelte
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import StatusIndicator from "@lib/components/StatusIndicator.svelte"
|
||||||
|
import {deriveSocketStatus} from "@app/core/state"
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const {url}: Props = $props()
|
||||||
|
const status = deriveSocketStatus(url)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<StatusIndicator class="bg-{$status.theme}">{$status.title}</StatusIndicator>
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
import {deriveRelay} from "@welshman/app"
|
import {deriveRelay} from "@welshman/app"
|
||||||
import Server from "@assets/icons/server.svg?dataurl"
|
import Server from "@assets/icons/server.svg?dataurl"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import SocketStatusIndicator from "@lib/components/SocketStatusIndicator.svelte"
|
|
||||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||||
|
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
url: string
|
url: string
|
||||||
|
|||||||
@@ -26,8 +26,23 @@ import {
|
|||||||
last,
|
last,
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
import type {Socket} from "@welshman/net"
|
import type {Socket} from "@welshman/net"
|
||||||
import {Pool, load, AuthStateEvent, AuthStatus, SocketEvent, netContext} from "@welshman/net"
|
import {
|
||||||
import {collection, custom, deriveEvents, deriveEventsMapped, withGetter} from "@welshman/store"
|
Pool,
|
||||||
|
load,
|
||||||
|
SocketStatus,
|
||||||
|
AuthStateEvent,
|
||||||
|
AuthStatus,
|
||||||
|
SocketEvent,
|
||||||
|
netContext,
|
||||||
|
} from "@welshman/net"
|
||||||
|
import {
|
||||||
|
collection,
|
||||||
|
custom,
|
||||||
|
throttled,
|
||||||
|
deriveEvents,
|
||||||
|
deriveEventsMapped,
|
||||||
|
withGetter,
|
||||||
|
} from "@welshman/store"
|
||||||
import {isKindFeed, findFeed} from "@welshman/feeds"
|
import {isKindFeed, findFeed} from "@welshman/feeds"
|
||||||
import {
|
import {
|
||||||
getIdFilters,
|
getIdFilters,
|
||||||
@@ -771,6 +786,54 @@ export const deriveSocket = (url: string) =>
|
|||||||
return () => subs.forEach(call)
|
return () => subs.forEach(call)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const deriveSocketStatus = (url: string) =>
|
||||||
|
throttled(
|
||||||
|
800,
|
||||||
|
derived([deriveSocket(url), relaysMostlyRestricted], ([$socket, $relaysMostlyRestricted]) => {
|
||||||
|
if ($socket.status === SocketStatus.Opening) {
|
||||||
|
return {theme: "warning", title: "Connecting"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.status === SocketStatus.Closing) {
|
||||||
|
return {theme: "gray-500", title: "Not Connected"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.status === SocketStatus.Closed) {
|
||||||
|
return {theme: "gray-500", title: "Not Connected"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.status === SocketStatus.Error) {
|
||||||
|
return {theme: "error", title: "Failed to Connect"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.auth.status === AuthStatus.Requested) {
|
||||||
|
return {theme: "warning", title: "Authenticating"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.auth.status === AuthStatus.PendingSignature) {
|
||||||
|
return {theme: "warning", title: "Authenticating"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.auth.status === AuthStatus.DeniedSignature) {
|
||||||
|
return {theme: "error", title: "Failed to Authenticate"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.auth.status === AuthStatus.PendingResponse) {
|
||||||
|
return {theme: "warning", title: "Authenticating"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($socket.auth.status === AuthStatus.Forbidden) {
|
||||||
|
return {theme: "error", title: "Access Denied"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($relaysMostlyRestricted[url]) {
|
||||||
|
return {theme: "error", title: "Access Denied"}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {theme: "success", title: "Connected"}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
export const deriveTimeout = (timeout: number) => {
|
export const deriveTimeout = (timeout: number) => {
|
||||||
const store = writable<boolean>(false)
|
const store = writable<boolean>(false)
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import {throttled} from "@welshman/store"
|
|
||||||
import {AuthStatus, SocketStatus} from "@welshman/net"
|
|
||||||
import StatusIndicator from "@lib/components/StatusIndicator.svelte"
|
|
||||||
import {deriveSocket, relaysMostlyRestricted} from "@app/core/state"
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const {url}: Props = $props()
|
|
||||||
const socket = throttled(800, deriveSocket(url))
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if $socket.status === SocketStatus.Open}
|
|
||||||
{#if $socket.auth.status === AuthStatus.None}
|
|
||||||
<StatusIndicator class="bg-green-500">Connected</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.Requested}
|
|
||||||
<StatusIndicator class="bg-yellow-500">Authenticating</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.PendingSignature}
|
|
||||||
<StatusIndicator class="bg-yellow-500">Authenticating</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.DeniedSignature}
|
|
||||||
<StatusIndicator class="bg-red-500">Failed to Authenticate</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.PendingResponse}
|
|
||||||
<StatusIndicator class="bg-yellow-500">Authenticating</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.Forbidden || $relaysMostlyRestricted[url]}
|
|
||||||
<StatusIndicator class="bg-red-500">Access Denied</StatusIndicator>
|
|
||||||
{:else if $socket.auth.status === AuthStatus.Ok}
|
|
||||||
<StatusIndicator class="bg-green-500">Connected</StatusIndicator>
|
|
||||||
{/if}
|
|
||||||
{:else if $socket.status === SocketStatus.Opening}
|
|
||||||
<StatusIndicator class="bg-yellow-500">Connecting</StatusIndicator>
|
|
||||||
{:else if $socket.status === SocketStatus.Closing}
|
|
||||||
<StatusIndicator class="bg-gray-500">Not Connected</StatusIndicator>
|
|
||||||
{:else if $socket.status === SocketStatus.Closed}
|
|
||||||
<StatusIndicator class="bg-gray-500">Not Connected</StatusIndicator>
|
|
||||||
{:else if $socket.status === SocketStatus.Error}
|
|
||||||
<StatusIndicator class="bg-red-500">Failed to Connect</StatusIndicator>
|
|
||||||
{/if}
|
|
||||||
Reference in New Issue
Block a user