keanu-weblite/src/App.vue

260 lines
7.2 KiB
Vue

<template>
<v-app>
<v-main class="main">
<router-view />
<!-- Loading indicator -->
<v-container
fluid
fill-height
v-if="showLoadingScreen"
class="loading-container"
>
<v-row align="center" justify="center">
<v-col class="text-center">
<v-progress-circular
indeterminate
class="loading-convene"
></v-progress-circular>
<div>{{ $t("menu.loading", { appName: appName }) }}</div>
</v-col>
</v-row>
</v-container>
<v-skeleton-loader
type="list-item-avatar-two-line, divider, list-item-three-line, card-heading"
v-if="showLoadingScreen"
></v-skeleton-loader>
</v-main>
</v-app>
</template>
<script>
import stickers from "./plugins/stickers";
import { registerServiceWorker, notificationCount, windowNotificationPermission } from "./plugins/notificationAndServiceWorker.js"
import logoMixin from "./components/logoMixin";
import { mapState } from 'vuex'
export default {
name: "App",
mixins: [logoMixin],
data() {
return {
loading: true,
browserLanguage: null,
availableJsonTranslation: null
}
},
beforeMount() {
this.setDefaultLanguage();
},
mounted() {
registerServiceWorker(this.$t('notification.periodicSync_new_msg_reminder'));
/**
if (
window.location.protocol == "http" &&
!window.location.hostname.endsWith(".onion")
) {
// Redirect to HTTPS
// window.location.href = window.location.href.replace("http:", "https:");
return;
}
**/
if (this.currentUser) {
this.$matrix
.login(this.currentUser)
.then(() => {
console.log("Matrix client ready");
})
.catch((error) => {
console.log("Error creating client", error);
if (error.data && ((error.data.errcode ==='M_FORBIDDEN' && this.currentUser.is_guest) || error.data.errcode ==='M_USER_DEACTIVATED')) {
// Guest account and password don't work. We are in a strange state, probably because
// of server cleanup of accounts or similar. Wipe account and restart...
this.$store.commit("setUser", null);
this.$store.commit("setCurrentRoomId", null);
this.$navigation.push({ path: "/login" }, -1);
}
})
.finally(() => {
this.loading = false;
});
} else {
this.loading = false;
}
this.$config.promise.then(this.onConfigLoaded);
},
methods: {
windowNotificationPermission,
onConfigLoaded(config) {
if (config.shortCodeStickers) {
stickers.loadStickersFromConfig(config);
}
},
setDefaultLanguage() {
let LocalesArr= Object.keys(this.$i18n.messages);
// No language set, default to browser language?
this.browserLanguage = (navigator.language ||navigator.userLanguage ||"").toLowerCase();
// Try with language name only.
let lang = this.browserLanguage.split("-")[0];
// Assigns available language for ex 'zh_Hans' when browser header language is 'zh' or 'zh-HK'
this.availableJsonTranslation= LocalesArr[LocalesArr.findIndex(locale => locale.includes(lang))];
if (!this.$store.state.language) {
// Set default language if not set already
if (this.$i18n.messages[this.browserLanguage]) {
this.$store.commit("setLanguage", this.browserLanguage);
} else if (this.browserLanguage.includes("-")) {
if (this.$i18n.messages[lang]) {
this.$store.commit("setLanguage", lang);
} else {
this.$store.commit("setLanguage", this.availableJsonTranslation);
}
} else {
this.$store.commit("setLanguage", this.availableJsonTranslation);
}
}
// Set language
this.$i18n.locale = this.$store.state.language || "en";
},
showNotification() {
if(document.visibilityState === "hidden") {
const title = this.$t('notification.title');
const self = this;
navigator.serviceWorker.ready.then(function(registration) {
registration.showNotification(title, {
icon: self.logotype,
data: { url: window.location.href }
});
});
}
},
},
computed: {
showLoadingScreen() {
return this.loading || !(this.$config.loaded);
},
notificationCount,
currentUser() {
return this.$store.state.auth.user;
},
appName() {
var translated = undefined;
if (this.$config.appNames) {
translated = this.$config.appNames[this.$i18n.locale];
}
return translated || this.$config.appName;
},
title() {
var title = this.appName;
if (this.notificationCount > 0) {
title += " [" + this.notificationCount + "]";
}
if (this.$route.meta.title) {
title += " - " + this.$route.meta.title;
}
if (this.$route.meta.includeRoom) {
if (this.$matrix.currentRoom) {
title +=
" - " +
(this.$matrix.currentRoom.name || this.$matrix.currentRoom.roomId);
} else if (this.$matrix.currentRoomId) {
title += " - " + this.$matrix.currentRoomId;
}
}
return title;
},
favicon() {
var favicon = this.$config.logo ? this.$config.logo : 'favicon.ico';
if (this.$route.meta.includeFavicon) {
if (this.$matrix.currentRoom) {
favicon = this.$matrix.currentRoom.avatar || favicon;
}
}
return favicon;
},
...mapState([
'globalNotification'
])
},
watch: {
notificationCount: {
handler(nCount) {
// windowNotificationPermission
// return value: 'granted', 'default', 'denied'
if (this.globalNotification && nCount > 0 && this.windowNotificationPermission() === "granted") {
this.showNotification()
}
}
},
"$i18n.locale": {
handler(val) {
// Locale changed, check file if RTL
var isRTL = this.$i18n.messages[val].language_is_rtl || false;
if (isRTL) {
this.$vuetify.rtl = true;
document.documentElement.setAttribute("dir", "rtl");
} else {
this.$vuetify.rtl = false;
document.documentElement.setAttribute("dir", "ltr");
}
},
immediate: true,
},
title: {
handler(title) {
document.title = title;
},
immediate: true,
},
favicon: {
handler(favicon) {
document.getElementById("favicon").setAttribute('href', favicon);
},
immediate: true,
}
}
};
</script>
<style lang="scss">
@import '~vuetify/src/styles/settings/_variables.scss';
@import '@/assets/css/variables';
.copyright {
font-size: 10px;
}
#app {
background-color: var(--v-app-background);
}
.main {
@media #{map-get($display-breakpoints, 'lg-and-up')} {
margin: 0 auto;
width: $main-desktop-width;
}
}
.v-skeleton-loader--is-loading {
z-index: 100;
}
.loading {
&-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 20;
background-color: rgba(255, 255, 255, 1);
}
&-convene {
color: $very-very-purple;
}
}
</style>