refactor(components): update loading animations to use 'animate-spin-reverse' class for consistency

This commit is contained in:
2026-01-04 23:19:17 -06:00
parent 6a23727e55
commit 0492e7d7bf
11 changed files with 85 additions and 40 deletions

View File

@@ -85,7 +85,7 @@
<MaterialDesignIcon
icon-name="refresh"
class="size-6"
:class="{ 'animate-spin': isSyncingPropagationNode }"
:class="{ 'animate-spin-reverse': isSyncingPropagationNode }"
/>
<span class="hidden sm:inline-block my-auto mx-1 text-sm font-medium">{{
isSyncingPropagationNode

View File

@@ -178,7 +178,7 @@
<!-- Rendered Content -->
<div class="flex-1 overflow-y-auto p-4 nodeContainer overscroll-contain">
<div v-if="isLoading" class="flex items-center justify-center h-full text-zinc-500">
<MaterialDesignIcon icon-name="refresh" class="size-8 animate-spin" />
<MaterialDesignIcon icon-name="refresh" class="size-8 animate-spin-reverse" />
</div>
<div
v-else-if="!viewingArchive"

View File

@@ -31,7 +31,11 @@
title="Refresh"
@click="loadBlockedDestinations"
>
<MaterialDesignIcon icon-name="refresh" class="size-6" :class="{ 'animate-spin': isLoading }" />
<MaterialDesignIcon
icon-name="refresh"
class="size-6"
:class="{ 'animate-spin-reverse': isLoading }"
/>
</button>
</div>
</div>

View File

@@ -122,6 +122,7 @@
</optgroup>
<optgroup label="RNodes">
<option value="RNodeInterface">RNode Interface</option>
<option value="RNodeIPInterface">RNode IP Interface</option>
<option value="RNodeMultiInterface">RNode Multi Interface</option>
</optgroup>
<optgroup label="IP Networks">
@@ -263,20 +264,49 @@
<!-- RNode interface -->
<!-- interface port -->
<div v-if="newInterfaceType === 'RNodeInterface'" class="mb-2">
<FormLabel class="mb-1">Port</FormLabel>
<select
v-model="newInterfacePort"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-zinc-900 dark:border-zinc-600 dark:text-white dark:focus:ring-blue-600 dark:focus:border-blue-600"
>
<option v-for="comport of comports" :key="comport.device" :value="comport.device">
{{ comport.device }} (Product: {{ comport.product ?? "?" }}, Serial:
{{ comport.serial ?? "?" }})
</option>
</select>
<FormSubLabel>
<div class="text-blue-500 underline cursor-pointer" @click="loadComports">Reload Ports</div>
</FormSubLabel>
<div v-if="['RNodeInterface', 'RNodeIPInterface'].includes(newInterfaceType)" class="mb-2">
<div v-if="newInterfaceType === 'RNodeInterface'" class="flex items-center mb-2">
<Toggle id="rnode-use-ip" v-model="newInterfaceRNodeUseIP" />
<FormLabel for="rnode-use-ip" class="ml-2">Connect over IP</FormLabel>
</div>
<div v-if="newInterfaceRNodeUseIP || newInterfaceType === 'RNodeIPInterface'" class="space-y-2">
<div>
<FormLabel class="mb-1">Host</FormLabel>
<input
v-model="newInterfaceRNodeIPHost"
type="text"
placeholder="e.g: 10.0.0.1"
class="input-field"
/>
</div>
<div>
<FormLabel class="mb-1">Port</FormLabel>
<input
v-model="newInterfaceRNodeIPPort"
type="text"
placeholder="e.g: 7633"
class="input-field"
/>
</div>
</div>
<div v-else>
<FormLabel class="mb-1">Port</FormLabel>
<select
v-model="newInterfacePort"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-zinc-900 dark:border-zinc-600 dark:text-white dark:focus:ring-blue-600 dark:focus:border-blue-600"
>
<option v-for="comport of comports" :key="comport.device" :value="comport.device">
{{ comport.device }} (Product: {{ comport.product ?? "?" }}, Serial:
{{ comport.serial ?? "?" }})
</option>
</select>
<FormSubLabel>
<div class="text-blue-500 underline cursor-pointer" @click="loadComports">
Reload Ports
</div>
</FormSubLabel>
</div>
</div>
<!-- interface Frequency -->
@@ -694,7 +724,7 @@
</div>
<!-- RNodeInterface bitrate & link budget -->
<ExpandingSection v-if="newInterfaceType === 'RNodeInterface'">
<ExpandingSection v-if="['RNodeInterface', 'RNodeIPInterface'].includes(newInterfaceType)">
<template #title>Calculated RNode Bitrate & Link Budget</template>
<template #content>
<div class="p-2 space-y-3">
@@ -908,7 +938,7 @@
</ExpandingSection>
<!-- optional RNodeInterface settings -->
<ExpandingSection v-if="newInterfaceType === 'RNodeInterface'">
<ExpandingSection v-if="['RNodeInterface', 'RNodeIPInterface'].includes(newInterfaceType)">
<template #title>Optional RNodeInterface Settings</template>
<template #content>
<div class="p-2 space-y-3">
@@ -1127,6 +1157,9 @@ export default {
},
newInterfacePort: null,
newInterfaceRNodeUseIP: false,
newInterfaceRNodeIPHost: "localhost",
newInterfaceRNodeIPPort: "7633",
RNodeGHzValue: 0,
RNodeMHzValue: 0,
RNodekHzValue: 0,
@@ -1321,6 +1354,14 @@ export default {
// Port (For RNode, Serial, and KISS)
this.newInterfacePort = iface.port;
if (iface.type === "RNodeInterface" && iface.port && iface.port.startsWith("tcp://")) {
this.newInterfaceType = "RNodeIPInterface";
this.newInterfaceRNodeUseIP = true;
const address = iface.port.replace("tcp://", "");
const parts = address.split(":");
this.newInterfaceRNodeIPHost = parts[0];
this.newInterfaceRNodeIPPort = parts[1] || "7633";
}
// RNode Interface
this.newInterfaceFrequency = iface.frequency;
@@ -1425,7 +1466,10 @@ export default {
peers: this.I2PSettings.newInterfacePeers.join(","),
// rnode interface
port: this.newInterfacePort,
port:
this.newInterfaceRNodeUseIP || this.newInterfaceType === "RNodeIPInterface"
? `tcp://${this.newInterfaceRNodeIPHost}:${this.newInterfaceRNodeIPPort}`
: this.newInterfacePort,
frequency: this.calculateFrequencyInHz(),
bandwidth: this.newInterfaceBandwidth,
txpower: this.newInterfaceTxpower,

View File

@@ -194,7 +194,7 @@ export default {
case "AutoInterface":
return "home-automation";
case "RNodeInterface":
return "radio-tower";
return this.iface.port && this.iface.port.startsWith("tcp://") ? "lan-connect" : "radio-tower";
case "RNodeMultiInterface":
return "access-point-network";
case "TCPClientInterface":
@@ -226,6 +226,9 @@ export default {
if (this.iface.type === "SerialInterface") {
return `${this.iface.port} @ ${this.iface.speed || "9600"}bps`;
}
if (this.iface.type === "RNodeInterface" && this.iface.port && this.iface.port.startsWith("tcp://")) {
return `RNode over IP @ ${this.iface.port.replace("tcp://", "")}`;
}
if (this.iface.type === "AutoInterface") {
return "Auto-detect Ethernet and Wi-Fi peers";
}

View File

@@ -62,7 +62,7 @@
<MaterialDesignIcon
:icon-name="reloadingRns ? 'refresh' : 'restart'"
class="w-4 h-4"
:class="{ 'animate-spin': reloadingRns }"
:class="{ 'animate-spin-reverse': reloadingRns }"
/>
{{ reloadingRns ? $t("app.reloading_rns") : $t("app.reload_rns") }}
</button>

View File

@@ -920,9 +920,12 @@
>
<div
class="size-12 rounded-2xl bg-indigo-50 dark:bg-indigo-900/20 text-indigo-600 flex items-center justify-center group-hover:scale-110 transition-transform"
:class="{ 'animate-spin': isSyncingPropagationNode }"
>
<MaterialDesignIcon icon-name="sync" class="size-6" />
<MaterialDesignIcon
icon-name="sync"
class="size-6"
:class="{ 'animate-spin-reverse': isSyncingPropagationNode }"
/>
</div>
<span class="text-sm font-bold text-gray-900 dark:text-zinc-100">{{
isSyncingPropagationNode ? "Syncing..." : "Sync Node"

View File

@@ -1030,17 +1030,4 @@ export default {
background-image: radial-gradient(#18181b 1px, transparent 1px);
background-size: 32px 32px;
}
@keyframes spin-reverse {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
.animate-spin-reverse {
animation: spin-reverse 1s linear infinite;
}
</style>

View File

@@ -27,7 +27,7 @@
<MaterialDesignIcon
icon-name="refresh"
class="w-4 h-4"
:class="{ 'animate-spin': isLoading }"
:class="{ 'animate-spin-reverse': isLoading }"
/>
Refresh
</button>

View File

@@ -846,7 +846,7 @@
<MaterialDesignIcon
:icon-name="reloadingRns ? 'refresh' : 'restart'"
class="w-5 h-5"
:class="{ 'animate-spin': reloadingRns }"
:class="{ 'animate-spin-reverse': reloadingRns }"
/>
<span>{{ reloadingRns ? $t("app.reloading_rns") : $t("app.reload_rns") }}</span>
</button>

View File

@@ -20,7 +20,11 @@
title="Refresh"
@click="refreshAll"
>
<MaterialDesignIcon icon-name="refresh" class="size-6" :class="{ 'animate-spin': isLoading }" />
<MaterialDesignIcon
icon-name="refresh"
class="size-6"
:class="{ 'animate-spin-reverse': isLoading }"
/>
</button>
</div>
</div>