lokalne fonty; poprawki offline i cachingu pwa

This commit is contained in:
2023-12-21 19:27:27 +01:00
parent 0c6b55146f
commit 2027b85450
23 changed files with 168 additions and 82 deletions
+34 -34
View File
@@ -37,7 +37,6 @@ import { defineComponent, watch } from 'vue';
import Clock from './components/App/Clock.vue';
import packageInfo from '.././package.json';
import { regions } from './data/options.json';
import { useMainStore } from './store/mainStore';
import StatusIndicator from './components/App/StatusIndicator.vue';
@@ -46,6 +45,7 @@ import AppHeader from './components/App/AppHeader.vue';
import axios from 'axios';
import StorageManager from './managers/storageManager';
import { useApiStore } from './store/apiStore';
import { Status } from './typings/common';
export default defineComponent({
components: {
@@ -66,26 +66,10 @@ export default defineComponent({
}),
created() {
this.loadLang();
this.apiStore.setupAPI();
this.store.isOffline = !window.navigator.onLine;
window.addEventListener('offline', () => {
this.store.isOffline = true;
this.apiStore.activeData = undefined;
this.apiStore.setDataStatuses();
});
window.addEventListener('online', () => {
this.store.isOffline = false;
});
this.init();
},
async mounted() {
this.setReleaseURL();
watch(
() => this.store.blockScroll,
(value) => {
@@ -95,23 +79,39 @@ export default defineComponent({
);
},
watch: {
'$route.query.region': {
immediate: true,
handler(regionQuery: string) {
if (regionQuery) {
this.store.region.id =
regions.find(
(reg) =>
reg.id == regionQuery.toLocaleLowerCase() ||
reg.value.toLocaleLowerCase() == regionQuery.toLocaleLowerCase()
)?.id || 'eu';
}
}
}
},
methods: {
init() {
this.loadLang();
this.setReleaseURL();
this.setupOfflineHandling();
this.apiStore.setupAPI();
},
setupOfflineHandling() {
this.store.isOffline = !window.navigator.onLine;
if (this.store.isOffline) this.handleOfflineMode();
window.addEventListener('offline', this.handleOfflineMode);
window.addEventListener('online', this.handleOnlineMode);
},
handleOfflineMode() {
this.store.isOffline = true;
this.apiStore.stopActiveDataScheduler();
this.apiStore.activeData = undefined;
this.apiStore.dataStatuses.connection = Status.Data.Offline;
},
handleOnlineMode() {
this.store.isOffline = false;
this.apiStore.setupAPI();
},
changeLang(lang: string) {
this.$i18n.locale = lang;
this.currentLang = lang;
+4 -4
View File
@@ -240,9 +240,9 @@ export default defineComponent({
const trainsDataStatus = statuses.trains;
const dispatcherDataStatus = statuses.dispatchers;
if (this.store.isOffline) {
this.setSignalStatus(Status.Data.Initialized);
this.indicator.status = Status.Data.Initialized;
if (connectionStatus == Status.Data.Offline) {
this.setSignalStatus(Status.Data.Offline);
this.indicator.status = Status.Data.Offline;
this.indicator.message = 'data-status.S1-offline';
return;
}
@@ -293,7 +293,7 @@ export default defineComponent({
this.orangeLight = false;
this.redBottomLight = false;
if (status == Status.Data.Initialized) {
if (status == Status.Data.Initialized || status == Status.Data.Offline) {
this.redTopLight = true;
}
+15
View File
@@ -59,6 +59,21 @@ export default defineComponent({
'store.region.id': {
handler(regionId) {
this.selectedItemIndex = this.regionList.findIndex((reg) => reg.id == regionId);
console.log('region id', regionId);
}
},
'$route.query.region': {
immediate: true,
handler(regionQuery: string) {
if (regionQuery) {
this.store.region.id =
regionsJSON.find(
(reg) =>
reg.id == regionQuery.toLocaleLowerCase() ||
reg.value.toLocaleLowerCase() == regionQuery.toLocaleLowerCase()
)?.id || 'eu';
}
}
}
},
+3 -7
View File
@@ -279,7 +279,7 @@
</table>
</div>
<Loading v-if="!isDataLoaded && stations.length == 0" />
<Loading v-if="apiStore.dataStatuses.sceneries == Status.Loading" />
<div class="no-stations" v-else-if="stations.length == 0">
{{ $t('sceneries.no-stations') }}
@@ -288,7 +288,7 @@
</template>
<script lang="ts">
import { defineComponent, computed, PropType } from 'vue';
import { defineComponent, PropType } from 'vue';
import dateMixin from '../../mixins/dateMixin';
import stationInfoMixin from '../../mixins/stationInfoMixin';
import styleMixin from '../../mixins/styleMixin';
@@ -330,12 +330,8 @@ export default defineComponent({
const apiStore = useApiStore();
const stationFiltersStore = useStationFiltersStore();
const isDataLoaded = computed(() => {
return apiStore.dataStatuses.sceneries != Status.Data.Loading;
});
return {
isDataLoaded,
Status: Status.Data,
stationFiltersStore,
mainStore,
apiStore
+5 -6
View File
@@ -5,13 +5,12 @@
{{ $t('app.offline') }}
</div>
<Loading v-else-if="trains.length == 0 && apiStore.dataStatuses.trains == 0" key="loading" />
<Loading
v-else-if="trains.length == 0 && apiStore.dataStatuses.connection == 0"
key="loading"
/>
<div
class="table-info"
key="no-trains"
v-else-if="trains.length == 0 && apiStore.dataStatuses.trains != 0"
>
<div class="table-info" key="no-trains" v-else-if="trains.length == 0">
{{ $t('trains.no-trains') }}
</div>
+10 -3
View File
@@ -18,7 +18,8 @@ const routes: Array<RouteRecordRaw> = [
props: (route) => ({
train: route.query.train,
driver: route.query.driver,
trainId: route.query.trainId
trainId: route.query.trainId,
region: route.query.region
})
},
{
@@ -37,12 +38,18 @@ const routes: Array<RouteRecordRaw> = [
{
path: '/journal/timetables',
name: 'JournalTimetables',
component: JournalTimetablesVue
component: JournalTimetablesVue,
props: (route) => ({
region: route.query.region
})
},
{
path: '/journal/dispatchers',
name: 'JournalDispatchers',
component: JournalDispatchersVue
component: JournalDispatchersVue,
props: (route) => ({
region: route.query.region
})
},
{
path: '/:catchAll(.*)',
+39 -19
View File
@@ -18,7 +18,9 @@ export const useApiStore = defineStore('apiStore', {
activeData: undefined as API.ActiveData.Response | undefined,
rollingStockData: undefined as API.RollingStock.Response | undefined,
donatorsData: [] as API.Donators.Response,
sceneryData: [] as StationJSONData[]
sceneryData: [] as StationJSONData[],
activeDataTimeout: undefined as number | undefined
}),
actions: {
@@ -28,22 +30,32 @@ export const useApiStore = defineStore('apiStore', {
this.fetchDonatorsData();
this.fetchStationsGeneralInfo();
this.scheduleFetchActiveData();
if (this.activeDataTimeout === undefined) this.startActiveDataScheduler();
},
async setDataStatuses() {
if (!this.activeData?.activeSceneries) {
this.dataStatuses.sceneries = Status.Data.Error;
this.dataStatuses.trains = Status.Data.Error;
this.dataStatuses.dispatchers = Status.Data.Error;
// async setDataStatuses() {
// if (!window.navigator.onLine) {
// this.dataStatuses.connection = Status.Data.Offline;
// this.dataStatuses.sceneries = Status.Data.Offline;
// this.dataStatuses.trains = Status.Data.Offline;
// this.dataStatuses.dispatchers = Status.Data.Offline;
// this.dataStatuses.timetables = Status.Data.Offline;
// }
return;
}
// if (!this.activeData?.activeSceneries) {
// this.dataStatuses.connection = Status.Data.Loaded;
// this.dataStatuses.sceneries = Status.Data.Error;
// this.dataStatuses.trains = Status.Data.Error;
// this.dataStatuses.dispatchers = Status.Data.Error;
this.dataStatuses.sceneries = Status.Data.Loaded;
this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
this.dataStatuses.dispatchers = Status.Data.Loaded;
},
// return;
// }
// this.dataStatuses.connection = Status.Data.Loaded;
// this.dataStatuses.sceneries = Status.Data.Loaded;
// this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
// this.dataStatuses.dispatchers = Status.Data.Loaded;
// },
async fetchDonatorsData() {
try {
@@ -67,12 +79,16 @@ export const useApiStore = defineStore('apiStore', {
}
},
async scheduleFetchActiveData() {
async startActiveDataScheduler() {
if (!window.navigator.onLine) {
this.dataStatuses.connection = Status.Data.Offline;
return;
}
if (import.meta.env.VITE_API_MODE === 'mock') {
const mockActiveData = await import('../data/mockActiveData.json');
this.dataStatuses.connection = Status.Data.Loaded;
this.activeData = mockActiveData;
this.setDataStatuses();
console.warn('Stacjownik działa w trybie mockowania danych z WS');
@@ -84,21 +100,24 @@ export const useApiStore = defineStore('apiStore', {
this.activeData = data;
this.dataStatuses.connection = Status.Data.Loaded;
this.setDataStatuses();
} catch (error) {
this.dataStatuses.connection = Status.Data.Error;
console.error('Wystąpił błąd podczas pobierania danych online z API!');
} finally {
setTimeout(
this.activeDataTimeout = window.setTimeout(
() => {
this.scheduleFetchActiveData();
this.startActiveDataScheduler();
},
~~(1000 * (Math.random() * (25 - 20) + 25))
);
}
},
async stopActiveDataScheduler() {
window.clearTimeout(this.activeDataTimeout);
this.activeDataTimeout = undefined;
},
async fetchStationsGeneralInfo() {
const sceneryData: StationJSONData[] = (await http.get<StationJSONData[]>('api/getSceneries'))
.data;
@@ -108,6 +127,7 @@ export const useApiStore = defineStore('apiStore', {
return;
}
this.dataStatuses.sceneries = Status.Data.Loaded;
this.sceneryData = sceneryData;
}
}
+2 -1
View File
@@ -5,6 +5,7 @@
overflow-y: auto;
height: 90vh;
min-height: 550px;
margin-top: 0.5em;
padding-right: 0.2em;
}
@@ -24,7 +25,7 @@
text-align: end;
padding: 0.25em;
margin: 0.5em 0;
margin-top: 0.5em;
}
.journal_warning {
+49
View File
@@ -0,0 +1,49 @@
@font-face {
font-family: 'Quicksand';
src:
url('/fonts/Quicksand-Bold.woff2') format('woff2'),
url('/fonts/Quicksand-Bold.woff') format('woff');
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Quicksand';
src:
url('/fonts/Quicksand-SemiBold.woff2') format('woff2'),
url('/fonts/Quicksand-SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Quicksand';
src:
url('/fonts/Quicksand-Medium.woff2') format('woff2'),
url('/fonts/Quicksand-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Quicksand';
src:
url('/fonts/Quicksand-Regular.woff2') format('woff2'),
url('/fonts/Quicksand-Regular.woff') format('woff');
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Quicksand';
src:
url('/fonts/Quicksand-Light.woff2') format('woff2'),
url('/fonts/Quicksand-Light.woff') format('woff');
font-weight: 300;
font-style: normal;
font-display: swap;
}
+2
View File
@@ -1,3 +1,5 @@
@import 'fonts.scss';
:root {
--clr-primary: #ffc014;
--clr-secondary: #2f2f2f;
+1 -1
View File
@@ -11,7 +11,7 @@ export namespace Status {
}
export enum Data {
Offline = 2,
Offline = -2,
Initialized = -1,
Loading = 0,
Error = 1,