Skip to content

Commit 5b8b347

Browse files
Merge pull request #135 from positivecrash/master
Fixes and new features for the UI
2 parents 8b787a6 + 12e6f32 commit 5b8b347

File tree

19 files changed

+742
-351
lines changed

19 files changed

+742
-351
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"buffer": "^6.0.3",
2525
"chroma-js": "^2.4.2",
2626
"events": "^3.3.0",
27-
"highcharts": "^10.2.1",
27+
"highcharts": "^11.4.3",
28+
"highcharts-vue": "^2.0.1",
2829
"js-file-download": "^0.4.12",
2930
"js-queue": "^2.0.2",
3031
"leaflet": "^1.9.2",
@@ -41,7 +42,6 @@
4142
"vite-plugin-mkcert": "^1.17.5",
4243
"vite-plugin-pwa": "^0.19.7",
4344
"vue": "^3.2.38",
44-
"vue-highcharts": "^0.2.0",
4545
"vue-i18n": "9",
4646
"vue-matomo": "^4.1.0",
4747
"vue-router": "^4.1.5",

src/assets/styles/base.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,15 @@ label {
162162
.popovercontrol .svg-inline--fa path {
163163
fill: var(--app-textcolor);
164164
}
165+
166+
@supports not selector(:popover-open) {
167+
.popover {
168+
background-color: #fff;
169+
inset: unset;
170+
border: 0;
171+
padding: var(--gap);
172+
}
173+
}
165174
/* - POPOVER API */
166175

167176
/* + SCROLLABLE CONTENT */

src/components/Bookmarks.vue

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<template v-if="!bookmarks || bookmarks.length < 1">{{$t("bookmarks.listempty")}}</template>
33
<template v-else>
44
<section v-for="bookmark in bookmarks" :key="bookmark.id" class="flexline">
5-
<a :href="bookmark.link" @click.prevent="showsensor">
5+
<a :href="bookmark.link" @click.prevent="showsensor(bookmark.link)">
66
<b v-if="bookmark.customName" class="name">{{bookmark.customName}}</b>
77
<b v-if="bookmark.address" :class="bookmark.customName ? 'addresssm' : 'adresslg'">{{bookmark.address}}</b>
88
</a>
@@ -13,44 +13,41 @@
1313

1414
<script>
1515
import { useStore } from "@/store";
16-
import {IDBgettable, IDBworkflow} from "../idb";
16+
import { IDBworkflow } from "../idb";
1717
1818
export default {
1919
data() {
2020
return {
21-
bookmarks: [],
2221
store: useStore(),
2322
}
2423
},
2524
26-
methods: {
25+
computed: {
26+
bookmarks: function() {
27+
return this.store.idbBookmarks;
28+
}
29+
},
2730
28-
async getbookmarks() {
29-
this.bookmarks = await IDBgettable(this.store.idbBookmarkDbname, this.store.idbBookmarkVDbver, this.store.idbBookmarkVDbtable);
30-
},
31+
methods: {
3132
3233
deletebookmark(id) {
3334
IDBworkflow(this.store.idbBookmarkDbname, this.store.idbBookmarkVDbver, this.store.idbBookmarkVDbtable, 'readwrite', store => {
3435
store.delete(id);
35-
this.getbookmarks();
36+
37+
const bc = new BroadcastChannel(this.store.idbWatcherBroadcast);
38+
bc.postMessage(true);
39+
bc.close();
3640
})
3741
},
3842
39-
showsensor() {
40-
this.$router.go();
41-
},
43+
showsensor(link) {
44+
/*
45+
I'm really sorry for that, but current routing system is very complicated and it seems
46+
very hard to impelement proper router mechanism here, so I just reload - positivecrash */
47+
window.location.href = link;
48+
location.reload();
49+
}
4250
},
43-
44-
mounted() {
45-
this.getbookmarks()
46-
47-
const bc = new BroadcastChannel(this.store.idbWatcherBroadcast)
48-
bc.onmessage = e => {
49-
if(e.data) {
50-
this.getbookmarks();
51-
}
52-
};
53-
}
5451
}
5552
</script>
5653

@@ -83,4 +80,5 @@ export default {
8380
button:hover {
8481
color: var(--color-red);
8582
}
83+
8684
</style>

src/components/Map.vue

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div :class="{ inactive: store.isColored }" class="mapcontainer" id="map"></div>
2+
<div :class="{ inactive: store.mapinactive }" class="mapcontainer" id="map"></div>
33
<Footer
44
:currentProvider="provider"
55
:canHistory="historyready"
@@ -20,11 +20,11 @@
2020

2121
<script>
2222
import { useStore } from "@/store";
23-
import Footer from "../components/footer/Footer.vue";
2423
import { drawuser, init, removeMap, setTheme, setview } from "../utils/map/instance";
2524
import { init as initMarkers } from "../utils/map/marker";
2625
import { init as initWind } from "../utils/map/wind";
2726
import { getTypeProvider } from "../utils/utils";
27+
import Footer from "../components/footer/Footer.vue";
2828
2929
export default {
3030
emits: ["city", "clickMarker", "close"],
@@ -126,6 +126,11 @@ export default {
126126
/* Если не удалось получить позицию юзера, то проверяем локальное хранилище */
127127
this.getlocalmappos();
128128
resolve();
129+
},
130+
{
131+
enableHighAccuracy: true,
132+
timeout: 200000,
133+
maximumAge: 0
129134
}
130135
);
131136
} else {
@@ -187,16 +192,20 @@ export default {
187192
});
188193
189194
map.on("moveend", (e) => {
190-
this.relocatemap(
191-
e.target.getCenter().lat.toFixed(4),
192-
e.target.getCenter().lng.toFixed(4),
193-
e.target.getZoom()
194-
);
195-
this.store.setmapposition(
196-
e.target.getCenter().lat.toFixed(4),
197-
e.target.getCenter().lng.toFixed(4),
198-
e.target.getZoom()
199-
);
195+
/* setTimeout for mobiles (whne swiping up app, it causes unpleasant map moving before closing app) */
196+
setTimeout( () => {
197+
this.relocatemap(
198+
e.target.getCenter().lat.toFixed(4),
199+
e.target.getCenter().lng.toFixed(4),
200+
e.target.getZoom()
201+
);
202+
this.store.setmapposition(
203+
e.target.getCenter().lat.toFixed(4),
204+
e.target.getCenter().lng.toFixed(4),
205+
e.target.getZoom()
206+
);
207+
}, 50)
208+
200209
});
201210
202211
initMarkers(map, this.measuretype, (data) => {
@@ -208,6 +217,9 @@ export default {
208217
}
209218
});
210219
/* - Operate with a map */
220+
221+
/* get bookmarks and listenning for broadcast from DB */
222+
await this.store.idbBookmarkGet();
211223
},
212224
};
213225
</script>

src/components/footer/Footer.vue

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
<div class="mapcontrols">
33
<div style="display:none">{{bufer}}</div>
44
<div class="flexline">
5-
<div id="bookmarks" class="popover-bottom-left" popover>
5+
6+
<div id="bookmarks" class="popover-bottom-left popover" popover>
67
<h3>{{$t("bookmarks.listtitle")}}</h3>
78
<Bookmarks />
89
</div>
9-
<button class="popovercontrol" popovertarget="bookmarks"><font-awesome-icon icon="fa-solid fa-bookmark" /></button>
10-
10+
<button class="popovercontrol" :class="bookmarks && bookmarks.length > 0 ? 'active' : null" popovertarget="bookmarks"><font-awesome-icon icon="fa-solid fa-bookmark" /></button>
11+
1112
<input
1213
type="date"
1314
v-model="start"
@@ -19,7 +20,7 @@
1920
</div>
2021

2122
<div class="flexline">
22-
<div id="mapsettings" class="popover-bottom-right" popover>
23+
<div id="mapsettings" class="popover-bottom-right popover" popover>
2324
<section>
2425
<input id="realtime" v-model="realtime" type="checkbox" :checked="realtime" />
2526
<label for="realtime">{{$t('provider.realtime')}}</label>
@@ -62,6 +63,7 @@ export default {
6263
6364
data() {
6465
return {
66+
store: useStore(),
6567
isActive: false,
6668
isActiveMenu: false,
6769
isMeasuresPopupOpen: false,
@@ -71,7 +73,6 @@ export default {
7173
messages: config.SHOW_MESSAGES,
7274
start: moment().format("YYYY-MM-DD"),
7375
maxDate: moment().format("YYYY-MM-DD"),
74-
store: useStore(),
7576
};
7677
},
7778
computed: {
@@ -85,6 +86,9 @@ export default {
8586
moment(this.start + " 23:59:59", "YYYY-MM-DD HH:mm:ss").format("X")
8687
);
8788
},
89+
bookmarks: function() {
90+
return this.store.idbBookmarks;
91+
}
8892
},
8993
watch: {
9094
async realtime(v) {
@@ -121,35 +125,6 @@ export default {
121125
},
122126
123127
methods: {
124-
toggleOpen(state) {
125-
if (!this[state]) {
126-
this[state] = true;
127-
this.store.colorMap();
128-
} else {
129-
this[state] = false;
130-
this.store.removeColorMap();
131-
}
132-
},
133-
134-
toggleIsActive() {
135-
this.toggleOpen("isActive");
136-
},
137-
138-
toggleMobileMenu() {
139-
this.toggleOpen("isActiveMenu");
140-
},
141-
142-
toggleMeasurePopup(e) {
143-
if (
144-
e.target.classList.contains("footer__close-popup") &&
145-
this.$refs.details.open
146-
) {
147-
this.$refs.details.open = false;
148-
} else {
149-
this.toggleOpen("isMeasuresPopupOpen");
150-
}
151-
},
152-
153128
getHistory() {
154129
if (this.realtime) {
155130
return;
@@ -159,7 +134,7 @@ export default {
159134
end: this.endTimestamp,
160135
});
161136
},
162-
}
137+
},
163138
};
164139
</script>
165140

@@ -193,4 +168,14 @@ export default {
193168
.popover-bottom-left {
194169
left: var(--app-controlsgap);
195170
}
171+
</style>
172+
173+
<style>
174+
.popovercontrol.active {
175+
border-color: var(--color-green);
176+
}
177+
178+
.popovercontrol.active path {
179+
fill: var(--color-green) !important;
180+
}
196181
</style>

src/components/header/Header.vue

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<header class="flexline space-between">
33
<div class="flexline align-start">
44
<router-link to="/" class="appicon"><img alt="App logo" src="../../../public/app-icon-512.png" /></router-link>
5-
<b class="text-changabletheme" v-if="countPoints > 0">{{$t('loadedsesnsors')}}: {{countPoints}}</b>
5+
<b class="sensorscount" v-if="countPoints > 0"><IconSensor/> {{countPoints}}</b>
66
</div>
77

88
<div class="flexline">
@@ -11,7 +11,8 @@
1111
<option value="ru">Русский</option>
1212
</select>
1313

14-
<div id="about" class="popover-top-right" popover>
14+
15+
<div id="about" class="popover popover-top-right" popover>
1516
<template v-if="locale === 'ru'">
1617
<h3>Web3 открытая сеть датчиков</h3>
1718
<p>Добро пожаловать в открытую сеть датчиков, которая построена на open-source принципах и поддерживается энтузиастами (см.
@@ -46,19 +47,23 @@
4647
</section>
4748
</div>
4849
<button class="popovercontrol" popovertarget="about"><font-awesome-icon icon="fa-solid fa-bars" /></button>
50+
4951

5052
</div>
5153
</header>
5254
</template>
5355

5456
<script>
5557
import { useStore } from "@/store";
58+
import IconSensor from "../icons/Sensor.vue";
5659
5760
export default {
61+
components: { IconSensor },
62+
5863
data() {
5964
return {
6065
locale: localStorage.getItem("locale") || this.$i18n.locale || 'en',
61-
store: useStore()
66+
store: useStore(),
6267
}
6368
},
6469
watch: {
@@ -102,12 +107,18 @@ export default {
102107
}
103108
104109
.popover-top-right {
105-
top: calc(var(--gap) * 2 + var(--app-inputheight));
110+
top: calc(var(--gap) * 3 + var(--app-inputheight));
106111
right: var(--gap);
107112
width: 500px;
108113
max-width: calc(100vw - var(--gap) * 2);
109114
}
110115
116+
@supports not selector(:popover-open) {
117+
.popover-top-right {
118+
right: var(--gap) !important;
119+
}
120+
}
121+
111122
#about p {
112123
font-size: .9em;
113124
}
@@ -123,4 +134,19 @@ export default {
123134
.navlinks a:not(:last-child) {
124135
margin-bottom: calc(var(--gap) * .5);
125136
}
137+
138+
.sensorscount {
139+
color: #fff;
140+
background: var(--color-orange);
141+
padding: 4px 10px;
142+
display: block;
143+
border-radius: 5px;
144+
display: flex;
145+
gap: 10px;
146+
align-items: center;
147+
}
148+
149+
.sensorscount svg {
150+
width: 22px;
151+
}
126152
</style>

0 commit comments

Comments
 (0)