Feature: Added pull to refresh and websocket indicator
This commit is contained in:
parent
7b5d31efca
commit
024ee26705
@ -28,6 +28,7 @@
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/bootstrap": "^5.2.10",
|
||||
"@types/node": "^20.10.6",
|
||||
"@types/pulltorefreshjs": "^0.1.7",
|
||||
"@types/sortablejs": "^1.15.7",
|
||||
"@types/spark-md5": "^3.0.4",
|
||||
"@vitejs/plugin-vue": "^5.0.2",
|
||||
@ -36,6 +37,7 @@
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"pulltorefreshjs": "^0.1.22",
|
||||
"sass": "^1.69.7",
|
||||
"terser": "^5.26.0",
|
||||
"typescript": "^5.3.3",
|
||||
|
||||
@ -4,7 +4,12 @@
|
||||
<div class="page-header">
|
||||
<div class="row">
|
||||
<div class="col-sm-11">
|
||||
<h1>{{ title }}</h1>
|
||||
<h1>{{ title }}
|
||||
<span v-if="showWebSocket" :class="{
|
||||
'onlineMarker': isWebsocketConnected,
|
||||
'offlineMarker': !isWebsocketConnected,
|
||||
}"></span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-sm-1" v-if="showReload">
|
||||
<button type="button" class="float-end btn btn-outline-primary"
|
||||
@ -28,6 +33,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BIconArrowClockwise } from 'bootstrap-icons-vue';
|
||||
import PullToRefresh from 'pulltorefreshjs';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -37,7 +43,81 @@ export default defineComponent({
|
||||
title: { type: String, required: true },
|
||||
isLoading: { type: Boolean, required: false, default: false },
|
||||
isWideScreen: { type: Boolean, required: false, default: false },
|
||||
isWebsocketConnected: { type: Boolean, required: false, default: false },
|
||||
showWebSocket: { type: Boolean, required: false, default: false },
|
||||
showReload: { type: Boolean, required: false, default: false },
|
||||
},
|
||||
mounted() {
|
||||
var self = this;
|
||||
console.log("init");
|
||||
PullToRefresh.init({
|
||||
mainElement: 'main', // above which element?
|
||||
instructionsPullToRefresh: this.$t('base.Pull'),
|
||||
instructionsReleaseToRefresh: this.$t('base.Release'),
|
||||
instructionsRefreshing: this.$t('base.Refreshing'),
|
||||
onRefresh: function() {
|
||||
self.$emit('reload');
|
||||
}
|
||||
});
|
||||
},
|
||||
unmounted() {
|
||||
console.log("destroy");
|
||||
PullToRefresh.destroyAll();
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.ptr--text {
|
||||
color: var(--bs-primary-text-emphasis) !important;
|
||||
}
|
||||
.ptr--icon {
|
||||
color: var(--bs-primary-text-emphasis) !important;
|
||||
}
|
||||
|
||||
.offlineMarker:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #ff0000;
|
||||
border-color: #ff0000;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.onlineMarker:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #00bb00;
|
||||
border-color: #00bb00;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.onlineMarker:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: -12px 0 0 -12px;
|
||||
border: 1px solid #00bb00;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #00bb00, inset 0 0 4px rgb(56, 111, 169);
|
||||
transform: scale(0);
|
||||
animation: online 2.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes online {
|
||||
0% {
|
||||
transform: scale(.1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(2.5);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -26,7 +26,10 @@
|
||||
"Loading": "Lade...",
|
||||
"Reload": "Aktualisieren",
|
||||
"Cancel": "Abbrechen",
|
||||
"Save": "Speichern"
|
||||
"Save": "Speichern",
|
||||
"Refreshing": "Aktualisieren",
|
||||
"Pull": "Zum Aktualisieren nach unten ziehen",
|
||||
"Release": "Loslassen zum Aktualisieren"
|
||||
},
|
||||
"localeswitcher": {
|
||||
"Dark": "Dunkel",
|
||||
|
||||
@ -26,7 +26,10 @@
|
||||
"Loading": "Loading...",
|
||||
"Reload": "Reload",
|
||||
"Cancel": "Cancel",
|
||||
"Save": "Save"
|
||||
"Save": "Save",
|
||||
"Refreshing": "Refreshing",
|
||||
"Pull": "Pull down to refresh",
|
||||
"Release": "Release to refresh"
|
||||
},
|
||||
"localeswitcher": {
|
||||
"Dark": "Dark",
|
||||
|
||||
@ -26,7 +26,10 @@
|
||||
"Loading": "Chargement...",
|
||||
"Reload": "Reload",
|
||||
"Cancel": "Annuler",
|
||||
"Save": "Sauvegarder"
|
||||
"Save": "Sauvegarder",
|
||||
"Refreshing": "Refreshing",
|
||||
"Pull": "Pull down to refresh",
|
||||
"Release": "Release to refresh"
|
||||
},
|
||||
"localeswitcher": {
|
||||
"Dark": "Sombre",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<BasePage :title="$t('home.LiveData')" :isLoading="dataLoading" :isWideScreen="true">
|
||||
<BasePage :title="$t('home.LiveData')" :isLoading="dataLoading" :isWideScreen="true" :showWebSocket="true" :isWebsocketConnected="isWebsocketConnected" @reload="reloadData">
|
||||
<HintView :hints="liveData.hints" />
|
||||
<InverterTotalInfo :totalData="liveData.total" /><br />
|
||||
<div class="row gy-3">
|
||||
@ -448,6 +448,8 @@ export default defineComponent({
|
||||
alertTypePower: "info",
|
||||
showAlertPower: false,
|
||||
successCommandPower: "",
|
||||
|
||||
isWebsocketConnected: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@ -475,17 +477,23 @@ export default defineComponent({
|
||||
this.closeSocket();
|
||||
},
|
||||
updated() {
|
||||
console.log("Updated");
|
||||
// Select first tab
|
||||
if (this.isFirstFetchAfterConnect) {
|
||||
this.isFirstFetchAfterConnect = false;
|
||||
console.log("isFirstFetchAfterConnect");
|
||||
|
||||
this.$nextTick(() => {
|
||||
console.log("nextTick");
|
||||
const firstTabEl = document.querySelector(
|
||||
"#v-pills-tab:first-child button"
|
||||
);
|
||||
if (firstTabEl != null) {
|
||||
this.isFirstFetchAfterConnect = false;
|
||||
console.log("Show");
|
||||
const firstTab = new bootstrap.Tab(firstTabEl);
|
||||
firstTab.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -508,15 +516,27 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
isLoggedIn,
|
||||
getInitialData() {
|
||||
getInitialData(triggerLoading : boolean = true) {
|
||||
if (triggerLoading) {
|
||||
this.dataLoading = true;
|
||||
}
|
||||
fetch("/api/livedata/status", { headers: authHeader() })
|
||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||
.then((data) => {
|
||||
this.liveData = data;
|
||||
if (triggerLoading) {
|
||||
this.dataLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
reloadData() {
|
||||
this.closeSocket();
|
||||
|
||||
setTimeout(() => {
|
||||
this.getInitialData(false);
|
||||
this.initSocket();
|
||||
}, 1000);
|
||||
},
|
||||
initSocket() {
|
||||
console.log("Starting connection to WebSocket Server");
|
||||
|
||||
@ -540,11 +560,19 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
|
||||
var self = this;
|
||||
|
||||
this.socket.onopen = function (event) {
|
||||
console.log(event);
|
||||
console.log("Successfully connected to the echo websocket server...");
|
||||
self.isWebsocketConnected = true;
|
||||
};
|
||||
|
||||
this.socket.onclose = function() {
|
||||
console.log("Connection to websocket closed...")
|
||||
self.isWebsocketConnected = false;
|
||||
}
|
||||
|
||||
// Listen to window events , When the window closes , Take the initiative to disconnect websocket Connect
|
||||
window.onbeforeunload = () => {
|
||||
this.closeSocket();
|
||||
|
||||
@ -442,6 +442,11 @@
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@types/pulltorefreshjs@^0.1.7":
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/pulltorefreshjs/-/pulltorefreshjs-0.1.7.tgz#1948638b0c7071282e47bd236d2ccb88bdf66753"
|
||||
integrity sha512-Y0g/yfuycIvpvUmP97n5NE2+HDAOwfREGVERjhMWw2Y0ODh5wvbflcQ5gXPZ+ihgoq+BQZjA1DL8apw2wAsJXA==
|
||||
|
||||
"@types/semver@^7.5.0":
|
||||
version "7.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367"
|
||||
@ -2142,6 +2147,11 @@ prelude-ls@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
|
||||
|
||||
pulltorefreshjs@^0.1.22:
|
||||
version "0.1.22"
|
||||
resolved "https://registry.yarnpkg.com/pulltorefreshjs/-/pulltorefreshjs-0.1.22.tgz#ddb5e3feee0b2a49fd46e1b18e84fffef2c47ac0"
|
||||
integrity sha512-haxNVEHnS4NCQA7NeG7TSV69z4uqy/N7nfPRuc4dPWe8H6ygUrMjdNeohE+6v0lVVX/ukSjbLYwPUGUYtFKfvQ==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user