diff --git a/src/app/components/MenuSpace.svelte b/src/app/components/MenuSpace.svelte
index 16e3b3a..eb79053 100644
--- a/src/app/components/MenuSpace.svelte
+++ b/src/app/components/MenuSpace.svelte
@@ -35,6 +35,7 @@
import Alerts from "@app/components/Alerts.svelte"
import RoomCreate from "@app/components/RoomCreate.svelte"
import MenuSpaceRoomItem from "@app/components/MenuSpaceRoomItem.svelte"
+ import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
import {
ENABLE_ZAPS,
MESSAGE_FILTER,
@@ -123,7 +124,7 @@
class="flex w-full flex-col rounded-xl p-3 transition-all hover:bg-base-100"
onclick={openMenu}>
-
+
@@ -245,10 +246,13 @@
{/if}
-
-
diff --git a/src/app/components/MenuSpaceButton.svelte b/src/app/components/MenuSpaceButton.svelte
index 209acc7..e7d87dd 100644
--- a/src/app/components/MenuSpaceButton.svelte
+++ b/src/app/components/MenuSpaceButton.svelte
@@ -6,17 +6,22 @@
import {notifications} from "@app/util/notifications"
import {makeSpacePath} from "@app/util/routes"
import {pushDrawer} from "@app/util/modal"
+ import {deriveSocketStatus} from "@app/core/state"
const {url} = $props()
const path = makeSpacePath(url) + ":mobile"
+ const status = deriveSocketStatus(url)
+
const openMenu = () => pushDrawer(MenuSpace, {url})
- {#if $notifications.has(path)}
+ {#if $status.theme !== "success"}
+
+ {:else if $notifications.has(path)}
{/if}
diff --git a/src/app/components/SocketStatusIndicator.svelte b/src/app/components/SocketStatusIndicator.svelte
new file mode 100644
index 0000000..be57cce
--- /dev/null
+++ b/src/app/components/SocketStatusIndicator.svelte
@@ -0,0 +1,13 @@
+
+
+{$status.title}
diff --git a/src/app/components/SpaceRelayStatus.svelte b/src/app/components/SpaceRelayStatus.svelte
index 89096cb..5636308 100644
--- a/src/app/components/SpaceRelayStatus.svelte
+++ b/src/app/components/SpaceRelayStatus.svelte
@@ -2,8 +2,8 @@
import {deriveRelay} from "@welshman/app"
import Server from "@assets/icons/server.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
- import SocketStatusIndicator from "@lib/components/SocketStatusIndicator.svelte"
import ProfileLink from "@app/components/ProfileLink.svelte"
+ import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
interface Props {
url: string
diff --git a/src/app/core/state.ts b/src/app/core/state.ts
index ba8fe21..4672b4d 100644
--- a/src/app/core/state.ts
+++ b/src/app/core/state.ts
@@ -26,8 +26,23 @@ import {
last,
} from "@welshman/lib"
import type {Socket} from "@welshman/net"
-import {Pool, load, AuthStateEvent, AuthStatus, SocketEvent, netContext} from "@welshman/net"
-import {collection, custom, deriveEvents, deriveEventsMapped, withGetter} from "@welshman/store"
+import {
+ 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 {
getIdFilters,
@@ -771,6 +786,54 @@ export const deriveSocket = (url: string) =>
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) => {
const store = writable(false)
diff --git a/src/lib/components/SocketStatusIndicator.svelte b/src/lib/components/SocketStatusIndicator.svelte
deleted file mode 100644
index ae2b7be..0000000
--- a/src/lib/components/SocketStatusIndicator.svelte
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-{#if $socket.status === SocketStatus.Open}
- {#if $socket.auth.status === AuthStatus.None}
- Connected
- {:else if $socket.auth.status === AuthStatus.Requested}
- Authenticating
- {:else if $socket.auth.status === AuthStatus.PendingSignature}
- Authenticating
- {:else if $socket.auth.status === AuthStatus.DeniedSignature}
- Failed to Authenticate
- {:else if $socket.auth.status === AuthStatus.PendingResponse}
- Authenticating
- {:else if $socket.auth.status === AuthStatus.Forbidden || $relaysMostlyRestricted[url]}
- Access Denied
- {:else if $socket.auth.status === AuthStatus.Ok}
- Connected
- {/if}
-{:else if $socket.status === SocketStatus.Opening}
- Connecting
-{:else if $socket.status === SocketStatus.Closing}
- Not Connected
-{:else if $socket.status === SocketStatus.Closed}
- Not Connected
-{:else if $socket.status === SocketStatus.Error}
- Failed to Connect
-{/if}