From f376a1e516856491cdc971a6d2cea5c8425730ef Mon Sep 17 00:00:00 2001
From: Daniil Isakov <12859907+oplexz@users.noreply.github.com>
Date: Sat, 13 Jan 2024 00:28:51 +0300
Subject: [PATCH] Icons and components; move functions to methods; dateTime and
timeago
---
webui/src/App.vue | 839 +++++-------------
webui/src/components/ClientAddress.vue | 60 ++
webui/src/components/ClientAvatar.vue | 22 +
webui/src/components/ClientName.vue | 64 ++
webui/src/components/ClientNewButton.vue | 30 +
webui/src/components/ClientTransfer.vue | 13 +
webui/src/components/LoadingSpinner.vue | 11 +
webui/src/components/UpdateNotification.vue | 28 +
.../components/icons/IconAvatarDefault.vue | 5 +
webui/src/components/icons/IconClose.vue | 5 +
webui/src/components/icons/IconDelete.vue | 9 +
webui/src/components/icons/IconDownArrow.vue | 9 +
webui/src/components/icons/IconDownload.vue | 10 +
webui/src/components/icons/IconEdit.vue | 16 +
webui/src/components/icons/IconLogout.vue | 10 +
webui/src/components/icons/IconNew.vue | 11 +
webui/src/components/icons/IconQRCode.vue | 10 +
webui/src/components/icons/IconSpinner.vue | 10 +
webui/src/components/icons/IconUpArrow.vue | 9 +
webui/src/components/icons/IconWarning.vue | 17 +
webui/src/composables/useDateTime.js | 13 +
webui/src/composables/useTimeAgo.js | 29 +
22 files changed, 632 insertions(+), 598 deletions(-)
create mode 100644 webui/src/components/ClientAddress.vue
create mode 100644 webui/src/components/ClientAvatar.vue
create mode 100644 webui/src/components/ClientName.vue
create mode 100644 webui/src/components/ClientNewButton.vue
create mode 100644 webui/src/components/ClientTransfer.vue
create mode 100644 webui/src/components/LoadingSpinner.vue
create mode 100644 webui/src/components/UpdateNotification.vue
create mode 100644 webui/src/components/icons/IconAvatarDefault.vue
create mode 100644 webui/src/components/icons/IconClose.vue
create mode 100644 webui/src/components/icons/IconDelete.vue
create mode 100644 webui/src/components/icons/IconDownArrow.vue
create mode 100644 webui/src/components/icons/IconDownload.vue
create mode 100644 webui/src/components/icons/IconEdit.vue
create mode 100644 webui/src/components/icons/IconLogout.vue
create mode 100644 webui/src/components/icons/IconNew.vue
create mode 100644 webui/src/components/icons/IconQRCode.vue
create mode 100644 webui/src/components/icons/IconSpinner.vue
create mode 100644 webui/src/components/icons/IconUpArrow.vue
create mode 100644 webui/src/components/icons/IconWarning.vue
create mode 100644 webui/src/composables/useDateTime.js
create mode 100644 webui/src/composables/useTimeAgo.js
diff --git a/webui/src/App.vue b/webui/src/App.vue
index 5b9480f6..27bd083d 100644
--- a/webui/src/App.vue
+++ b/webui/src/App.vue
@@ -2,6 +2,27 @@
import { ref, reactive } from 'vue';
import sha256 from 'crypto-js/sha256';
+import { useDateTime } from './composables/useDateTime';
+import { useTimeAgo } from './composables/useTimeAgo';
+
+import UpdateNotification from './components/UpdateNotification.vue';
+import ClientNewButton from './components/ClientNewButton.vue';
+import ClientName from './components/ClientName.vue';
+import ClientAvatar from './components/ClientAvatar.vue';
+import ClientAddress from './components/ClientAddress.vue';
+import IconUpArrow from './components/icons/IconUpArrow.vue';
+import IconDownArrow from './components/icons/IconDownArrow.vue';
+import IconLogout from './components/icons/IconLogout.vue';
+import IconQRCode from './components/icons/IconQRCode.vue';
+import IconDownload from './components/icons/IconDownload.vue';
+import IconDelete from './components/icons/IconDelete.vue';
+import IconNew from './components/icons/IconNew.vue';
+import LoadingSpinner from './components/LoadingSpinner.vue';
+import IconClose from './components/icons/IconClose.vue';
+import IconWarning from './components/icons/IconWarning.vue';
+import IconAvatarDefault from './components/icons/IconAvatarDefault.vue';
+import ClientTransfer from './components/ClientTransfer.vue'
+
class API {
async call({ method, path, body }) {
const res = await fetch(`./api${path}`, {
@@ -208,168 +229,8 @@ export default {
const api = new API();
- const dateTime = (value) => {
- return new Intl.DateTimeFormat(undefined, {
- year: 'numeric',
- month: 'short',
- day: 'numeric',
- hour: 'numeric',
- minute: 'numeric',
- }).format(value);
- };
-
- const refresh = async ({ updateCharts = false } = {}) => {
- if (!authenticated.value) return;
-
- const clientsData = await api.getClients();
- clients.value = clientsData.map((client) => {
- if (client.name.includes('@') && client.name.includes('.')) {
- client.avatar = `https://www.gravatar.com/avatar/${sha256(client.name)}?d=blank`;
- }
-
- if (!clientsPersist[client.id]) {
- clientsPersist[client.id] = {};
- clientsPersist[client.id].transferRxHistory = Array(50).fill(0);
- clientsPersist[client.id].transferRxPrevious = client.transferRx;
- clientsPersist[client.id].transferTxHistory = Array(50).fill(0);
- clientsPersist[client.id].transferTxPrevious = client.transferTx;
- }
-
- // Debug
- // client.transferRx = clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
- // client.transferTx = clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
-
- if (updateCharts) {
- clientsPersist[client.id].transferRxCurrent =
- client.transferRx - clientsPersist[client.id].transferRxPrevious;
- clientsPersist[client.id].transferRxPrevious = client.transferRx;
- clientsPersist[client.id].transferTxCurrent =
- client.transferTx - clientsPersist[client.id].transferTxPrevious;
- clientsPersist[client.id].transferTxPrevious = client.transferTx;
-
- clientsPersist[client.id].transferRxHistory.push(
- clientsPersist[client.id].transferRxCurrent
- );
- clientsPersist[client.id].transferRxHistory.shift();
-
- clientsPersist[client.id].transferTxHistory.push(
- clientsPersist[client.id].transferTxCurrent
- );
- clientsPersist[client.id].transferTxHistory.shift();
- }
-
- client.transferTxCurrent = clientsPersist[client.id].transferTxCurrent;
- client.transferRxCurrent = clientsPersist[client.id].transferRxCurrent;
-
- client.transferTxHistory = clientsPersist[client.id].transferTxHistory;
- client.transferRxHistory = clientsPersist[client.id].transferRxHistory;
- client.transferMax = Math.max(
- ...client.transferTxHistory,
- ...client.transferRxHistory
- );
-
- client.hoverTx = clientsPersist[client.id].hoverTx;
- client.hoverRx = clientsPersist[client.id].hoverRx;
-
- return client;
- });
- };
-
- const login = (e) => {
- e.preventDefault();
-
- if (!password.value) return;
- if (authenticating.value) return;
-
- authenticating.value = true;
- api
- .createSession({
- password: password.value,
- })
- .then(async () => {
- const session = await api.getSession();
- authenticated.value = session.authenticated;
- requiresPassword.value = session.requiresPassword;
- return refresh();
- })
- .catch((err) => {
- alert(err.message || err.toString());
- })
- .finally(() => {
- authenticating.value = false;
- password.value = null;
- });
- };
-
- const logout = (e) => {
- e.preventDefault();
-
- api
- .deleteSession()
- .then(() => {
- authenticated.value = false;
- clients.value = null;
- })
- .catch((err) => {
- alert(err.message || err.toString());
- });
- };
-
- const createClient = () => {
- const name = clientCreateName.value;
- if (!name) return;
-
- api
- .createClient({ name })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const deleteClient = (client) => {
- api
- .deleteClient({ clientId: client.id })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const enableClient = (client) => {
- api
- .enableClient({ clientId: client.id })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const disableClient = (client) => {
- api
- .disableClient({ clientId: client.id })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const updateClientName = (client, name) => {
- api
- .updateClientName({ clientId: client.id, name })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const updateClientAddress = (client, address) => {
- api
- .updateClientAddress({ clientId: client.id, address })
- .catch((err) => alert(err.message || err.toString()))
- .finally(() => refresh().catch(console.error));
- };
-
- const toggleTheme = () => {
- if (isDark.value) {
- localStorage.theme = 'light';
- document.documentElement.classList.remove('dark');
- } else {
- localStorage.theme = 'dark';
- document.documentElement.classList.add('dark');
- }
- isDark.value = !isDark.value;
- };
+ const { dateTime } = useDateTime();
+ const { timeago } = useTimeAgo();
return {
authenticated,
@@ -396,16 +257,7 @@ export default {
chartOptions,
dateTime,
- refresh,
- login,
- logout,
- createClient,
- deleteClient,
- enableClient,
- disableClient,
- updateClientName,
- updateClientAddress,
- toggleTheme,
+ timeago,
api,
};
@@ -469,6 +321,184 @@ export default {
})
.catch(console.error);
},
+ components: {
+ UpdateNotification,
+ ClientNewButton,
+ ClientName,
+ ClientAvatar,
+ ClientAddress,
+ IconUpArrow,
+ IconDownArrow,
+ IconLogout,
+ IconQRCode,
+ IconDownload,
+ IconDelete,
+ IconNew,
+ LoadingSpinner,
+ IconClose,
+ IconWarning,
+ IconAvatarDefault,
+ ClientTransfer,
+ },
+ methods: {
+ handleNewClient() {
+ this.clientCreate = true;
+ this.clientCreateName = '';
+ },
+
+ async refresh ({ updateCharts = false } = {}) {
+ if (!this.authenticated) return;
+
+ const clientsData = await this.api.getClients();
+ this.clients = clientsData.map((client) => {
+ if (client.name.includes('@') && client.name.includes('.')) {
+ client.avatar = `https://www.gravatar.com/avatar/${sha256(client.name)}?d=blank`;
+ }
+
+ if (!this.clientsPersist[client.id]) {
+ this.clientsPersist[client.id] = {};
+ this.clientsPersist[client.id].transferRxHistory = Array(50).fill(0);
+ this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
+ this.clientsPersist[client.id].transferTxHistory = Array(50).fill(0);
+ this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
+ }
+
+ // Debug
+ // client.transferRx = this.clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
+ // client.transferTx = this.clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
+
+ if (updateCharts) {
+ this.clientsPersist[client.id].transferRxCurrent =
+ client.transferRx - this.clientsPersist[client.id].transferRxPrevious;
+ this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
+ this.clientsPersist[client.id].transferTxCurrent =
+ client.transferTx - this.clientsPersist[client.id].transferTxPrevious;
+ this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
+
+ this.clientsPersist[client.id].transferRxHistory.push(
+ this.clientsPersist[client.id].transferRxCurrent
+ );
+ this.clientsPersist[client.id].transferRxHistory.shift();
+
+ this.clientsPersist[client.id].transferTxHistory.push(
+ this.clientsPersist[client.id].transferTxCurrent
+ );
+ this.clientsPersist[client.id].transferTxHistory.shift();
+ }
+
+ client.transferTxCurrent = this.clientsPersist[client.id].transferTxCurrent;
+ client.transferRxCurrent = this.clientsPersist[client.id].transferRxCurrent;
+
+ client.transferTxHistory = this.clientsPersist[client.id].transferTxHistory;
+ client.transferRxHistory = this.clientsPersist[client.id].transferRxHistory;
+ client.transferMax = Math.max(
+ ...client.transferTxHistory,
+ ...client.transferRxHistory
+ );
+
+ client.hoverTx = this.clientsPersist[client.id].hoverTx;
+ client.hoverRx = this.clientsPersist[client.id].hoverRx;
+
+ return client;
+ });
+ },
+
+ login (e) {
+ e.preventDefault();
+
+ if (!this.password) return;
+ if (this.authenticating) return;
+
+ this.authenticating = true;
+ this.api
+ .createSession({
+ password: this.password,
+ })
+ .then(async () => {
+ const session = await this.api.getSession();
+ this.authenticated = session.authenticated;
+ this.requiresPassword = session.requiresPassword;
+ return this.refresh();
+ })
+ .catch((err) => {
+ alert(err.message || err.toString());
+ })
+ .finally(() => {
+ this.authenticating = false;
+ this.password = null;
+ });
+ },
+
+ logout (e) {
+ e.preventDefault();
+
+ this.api
+ .deleteSession()
+ .then(() => {
+ this.authenticated = false;
+ this.clients = null;
+ })
+ .catch((err) => {
+ alert(err.message || err.toString());
+ });
+ },
+
+ createClient () {
+ const name = this.clientCreateName;
+ if (!name) return;
+
+ this.api
+ .createClient({ name })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ deleteClient (client) {
+ this.api
+ .deleteClient({ clientId: client.id })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ enableClient (client) {
+ this.api
+ .enableClient({ clientId: client.id })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ disableClient (client) {
+ this.api
+ .disableClient({ clientId: client.id })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ updateClientName (client, name) {
+ this.api
+ .updateClientName({ clientId: client.id, name })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ updateClientAddress (client, address) {
+ this.api
+ .updateClientAddress({ clientId: client.id, address })
+ .catch((err) => alert(err.message || err.toString()))
+ .finally(() => this.refresh().catch(console.error));
+ },
+
+ toggleTheme () {
+ if (this.isDark) {
+ localStorage.theme = 'light';
+ document.documentElement.classList.remove('dark');
+ } else {
+ localStorage.theme = 'dark';
+ document.documentElement.classList.add('dark');
+ }
+ this.isDark = !this.isDark;
+ },
+ },
};
@@ -482,20 +512,7 @@ export default {
@click="logout"
>
Logout
-
+
There is an update available!
-{{ latestRelease.changelog }}
-Clients
-Clients
+There is an update available!
+{{ latestRelease.changelog }}
+