ng-app: feat: add connecting status to store and add pulsing logo

Laurin Weger 3 months ago
parent eb50e2c90f
commit e1dc6539b4
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 12
      ng-app/src/lib/FullLayout.svelte
  2. 12
      ng-app/src/lib/Home.svelte
  3. 63
      ng-app/src/lib/components/Logo.svelte
  4. 59
      ng-app/src/store.ts

@ -19,11 +19,7 @@
import { link, location } from "svelte-spa-router";
import MobileBottomBarItem from "./MobileBottomBarItem.svelte";
import MobileBottomBar from "./MobileBottomBar.svelte";
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
// @ts-ignore
import LogoGray from "../assets/nextgraph-gray.svg?component";
import { online } from "../store";
import Logo from "./components/Logo.svelte";
import { onMount, tick } from "svelte";
@ -96,11 +92,7 @@
<SidebarGroup ulClass="space-y-1 tall:space-y-2">
<SidebarItem label="NextGraph" href="#/user" class="mt-1">
<svelte:fragment slot="icon">
{#if $online}
<Logo class="w-7 h-7 tall:w-10 tall:h-10" />
{:else}
<LogoGray class="w-7 h-7 tall:w-10 tall:h-10" />
{/if}
<Logo className="w-7 h-7 tall:w-10 tall:h-10" />
</svelte:fragment>
</SidebarItem>
<SidebarItem

@ -10,7 +10,6 @@
-->
<script lang="ts">
import { online } from "../store";
import FullLayout from "./FullLayout.svelte";
import Test from "./Test.svelte";
import {
@ -19,10 +18,7 @@
ArrowRightOnRectangle,
Users,
} from "svelte-heros-v2";
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
// @ts-ignore
import LogoGray from "../assets/nextgraph-gray.svg?component";
import Logo from "./components/Logo.svelte";
let width: number;
let breakPoint: number = 662;
@ -43,11 +39,7 @@
class="mx-auto flex flex-wrap justify-between items-center w-full px-2 xxs:px-8 xs:px-10"
>
<a href="#/user" class="flex items-center" on:click>
{#if $online}
<Logo class="w-7 h-7 tall:w-10 tall:h-10" />
{:else}
<LogoGray class="w-7 h-7 tall:w-10 tall:h-10" />
{/if}
<Logo class="w-7 h-7 tall:w-10 tall:h-10" />
<span
class="ml-4 self-center text-lg font-normal text-gray-900 rounded-lg dark:text-white whitespace-nowrap"
>NextGraph</span

@ -0,0 +1,63 @@
<!--
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component Logo
The NextGraph Logo svg with color changing between blue and gray,
depending on connection status:
- connected: blue
- connecting: pulse between blue and gray
- disconnected: gray
Provide classes using the `className` prop.
-->
<script lang="ts">
import { connection_status } from "../../store";
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
export let className: string = "";
// Color is adjusted to connection status.
let connection_status_class = ""; // Default is blue.
if ($connection_status === "connecting") {
connection_status_class = "logo-pulse";
} else if ($connection_status === "disconnected") {
connection_status_class = "logo-gray";
}
</script>
<Logo class={`${className} ${connection_status_class}`} />
<style>
@keyframes pulse-logo-color {
0%,
100% {
stroke: rgb(73, 114, 165); /* Default color */
fill: rgb(73, 114, 165);
}
50% {
stroke: #888; /* Mid-transition color */
fill: #888;
}
}
.logo-pulse path {
animation: pulse-logo-color 2s infinite;
animation-timing-function: cubic-bezier(0.65, 0.01, 0.59, 0.83);
}
.logo-gray {
fill: #888;
stroke: #888;
}
</style>

@ -7,7 +7,7 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
import { writable, readable, readonly, derived, get } from "svelte/store";
import { writable, readable, readonly, derived, get, type Writable } from "svelte/store";
import ng from "./api";
let all_branches = {};
@ -19,31 +19,58 @@ export const active_wallet = writable(undefined);
export const wallets = writable({});
export const connections = writable({});
export const connections: Writable<Record<string, any>> = writable({});
export const active_session = writable(undefined);
let next_reconnect = null;
export const connection_status: Writable<"disconnected" | "connected" | "connecting"> = writable("disconnected");
export const online = derived(connections,($connections) => {
for (const cnx of Object.keys($connections)) {
if (!$connections[cnx].error) return true;
else if ($connections[cnx].error=="PeerAlreadyConnected") {
connections.update((c) => {
let next_reconnect: NodeJS.Timeout | null = null;
const updateConnectionStatus = ($connections: Record<string, any> ) => {
// Reset error state for PeerAlreadyConnected errors.
Object.entries($connections).forEach(([cnx, connection]) => {
if (connection.error === "PeerAlreadyConnected") {
connections.update(c => {
c[cnx].error = undefined;
return c;
});
return true; }
else if ($connections[cnx].error=="ConnectionError" && !$connections[cnx].connecting && next_reconnect==null) {
console.log("will try reconnect in 20 sec");
next_reconnect = setTimeout(async ()=> {
await reconnect();
},20000);
}
});
// Check if any connection is active.
const is_connected = Object.values($connections).some(connection => !connection.error);
// Check if any connection is connecting.
const is_connecting = Object.values($connections).some(connection => connection.connecting);
// Check, if reconnect is needed.
const should_reconnect = !is_connecting && (next_reconnect === null) && Object.values($connections).some(
connection => connection.error === "ConnectionError"
);
if (should_reconnect) {
console.log("will try reconnect in 20 sec");
next_reconnect = setTimeout(async () => {
await reconnect();
connection_status.set("connecting");
next_reconnect = null;
}, 20000);
}
return false;
if (is_connected) {
connection_status.set("connected");
} else if (!is_connected && is_connecting) {
connection_status.set("connecting");
} else {
connection_status.set("disconnected");
}
};
connections.subscribe(($connections) => {
updateConnectionStatus($connections);
});
export const online = derived(connection_status,($connectionStatus) => $connectionStatus == "connected");
export const cannot_load_offline = writable(false);
if (!get(online) && !import.meta.env.TAURI_PLATFORM) {
@ -123,8 +150,6 @@ export const reconnect = async function() {
get(active_session).user,
location.href
));
}catch (e) {
console.error(e)
}

Loading…
Cancel
Save