|
@@ -1,10 +1,14 @@
|
|
<template>
|
|
<template>
|
|
<v-app dark>
|
|
<v-app dark>
|
|
<!-- height = 4rem, margin-y = 1rem -->
|
|
<!-- height = 4rem, margin-y = 1rem -->
|
|
- <v-app-bar app text class="topBar fly-in-from-top my-4 mx-auto">
|
|
|
|
|
|
+ <v-app-bar
|
|
|
|
+ app
|
|
|
|
+ class="topBar glass elevation-0 fly-in-from-top my-4 mx-auto"
|
|
|
|
+ >
|
|
|
|
+ <!-- Translator desktop -->
|
|
<v-tabs centered center-active color="primary" router show-arrows>
|
|
<v-tabs centered center-active color="primary" router show-arrows>
|
|
<v-tab v-for="link in links" :key="link.path" :to="link.path">
|
|
<v-tab v-for="link in links" :key="link.path" :to="link.path">
|
|
- {{ link.name }}
|
|
|
|
|
|
+ {{ $vuetify.lang.t(`$vuetify.${link.name}.name`) }}
|
|
</v-tab>
|
|
</v-tab>
|
|
</v-tabs>
|
|
</v-tabs>
|
|
</v-app-bar>
|
|
</v-app-bar>
|
|
@@ -12,7 +16,7 @@
|
|
<!-- abstract background -->
|
|
<!-- abstract background -->
|
|
<v-img
|
|
<v-img
|
|
src="/ui/abstract.svg"
|
|
src="/ui/abstract.svg"
|
|
- style="position: absolute; left: 0; right: 0; width: 100vw; height: 100vh"
|
|
|
|
|
|
+ style="position: fixed; left: 0; right: 0; width: 100vw; height: 100vh"
|
|
/>
|
|
/>
|
|
|
|
|
|
<v-main style="padding-top: 4rem !important">
|
|
<v-main style="padding-top: 4rem !important">
|
|
@@ -25,6 +29,34 @@
|
|
</center>
|
|
</center>
|
|
</v-main>
|
|
</v-main>
|
|
|
|
|
|
|
|
+ <!-- Translator mobile -->
|
|
|
|
+ <v-menu
|
|
|
|
+ top
|
|
|
|
+ left
|
|
|
|
+ offset-y
|
|
|
|
+ rounded="lg"
|
|
|
|
+ nudge-top="16"
|
|
|
|
+ class="d-flex flex-column"
|
|
|
|
+ transition="slide-y-reverse-transition"
|
|
|
|
+ >
|
|
|
|
+ <template v-slot:activator="{ on, attrs }">
|
|
|
|
+ <v-btn text fab class="glass" id="translator" v-bind="attrs" v-on="on">
|
|
|
|
+ <v-icon>mdi-translate</v-icon>
|
|
|
|
+ </v-btn>
|
|
|
|
+ </template>
|
|
|
|
+ <v-list class="py-0">
|
|
|
|
+ <v-list-item
|
|
|
|
+ v-for="(lang, index) in langs"
|
|
|
|
+ :key="index"
|
|
|
|
+ link
|
|
|
|
+ :class="$vuetify.lang.current === lang.locale ? 'primary--text' : ''"
|
|
|
|
+ @click="changeLocale(lang.locale)"
|
|
|
|
+ >
|
|
|
|
+ <v-list-item-title v-text="lang.name"></v-list-item-title>
|
|
|
|
+ </v-list-item>
|
|
|
|
+ </v-list>
|
|
|
|
+ </v-menu>
|
|
|
|
+
|
|
<!-- Debugger Notification -->
|
|
<!-- Debugger Notification -->
|
|
<v-snackbar
|
|
<v-snackbar
|
|
v-model="alert.show"
|
|
v-model="alert.show"
|
|
@@ -58,22 +90,39 @@
|
|
export default {
|
|
export default {
|
|
data: () => ({
|
|
data: () => ({
|
|
links: [
|
|
links: [
|
|
- { name: "Home", path: "/" },
|
|
|
|
- { name: "Install", path: "/install" },
|
|
|
|
- { name: "API", path: "/docs" },
|
|
|
|
- { name: "Help", path: "/help" },
|
|
|
|
- { name: "FAQ", path: "/faq" },
|
|
|
|
- { name: "Donate", path: "/donate" },
|
|
|
|
- { name: "Links", path: "/links" },
|
|
|
|
|
|
+ { name: "home", path: "/" },
|
|
|
|
+ { name: "install", path: "/install" },
|
|
|
|
+ { name: "api", path: "/docs" },
|
|
|
|
+ { name: "help", path: "/help" },
|
|
|
|
+ { name: "faq", path: "/faq" },
|
|
|
|
+ { name: "donate", path: "/donate" },
|
|
|
|
+ { name: "links", path: "/links" },
|
|
|
|
+ ],
|
|
|
|
+ langs: [
|
|
|
|
+ { name: "English", locale: "en" },
|
|
|
|
+ { name: "Español", locale: "es" },
|
|
|
|
+ { name: "Türkçe", locale: "tr" },
|
|
|
|
+ { name: "Русский", locale: "ru" },
|
|
|
|
+ // { name: "Français", locale: "fr" },
|
|
|
|
+ // { name: "Deutsch", locale: "de" },
|
|
|
|
+ // ...
|
|
],
|
|
],
|
|
alert: {
|
|
alert: {
|
|
show: false,
|
|
show: false,
|
|
html: "",
|
|
html: "",
|
|
},
|
|
},
|
|
}),
|
|
}),
|
|
|
|
+ created() {
|
|
|
|
+ // fetch locale preference or browser default
|
|
|
|
+ if (process.client && navigator.language) {
|
|
|
|
+ if (!("locale" in localStorage))
|
|
|
|
+ this.$vuetify.lang.current = navigator.language.slice(0, 2);
|
|
|
|
+ else this.$vuetify.lang.current = localStorage.locale;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
mounted() {
|
|
mounted() {
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
- // Chrome < 70 or FF < 60
|
|
|
|
|
|
+ // Chrome < 70 or FF < 60 unsupported warning popup
|
|
if (
|
|
if (
|
|
(this.$ua._parsed.name == "Chrome" &&
|
|
(this.$ua._parsed.name == "Chrome" &&
|
|
parseInt(this.$ua._parsed.version.split(".")[0]) < 70) ||
|
|
parseInt(this.$ua._parsed.version.split(".")[0]) < 70) ||
|
|
@@ -85,14 +134,17 @@ export default {
|
|
</b> is not supported. Consider upgrading to the latest version.`;
|
|
</b> is not supported. Consider upgrading to the latest version.`;
|
|
this.alert.show = true;
|
|
this.alert.show = true;
|
|
}
|
|
}
|
|
-
|
|
|
|
- // Win7
|
|
|
|
- if (window.navigator.userAgent.indexOf("Windows NT 6.1") > -1) {
|
|
|
|
- this.alert.html = `<b style="background: #222; border-radius: .5rem; padding: .25rem .5rem; margin: 0 .25rem;">Windows 7</b> is not supported. Consider upgrading Windows, or installing Linux.`;
|
|
|
|
- this.alert.show = true;
|
|
|
|
- }
|
|
|
|
}, 1000);
|
|
}, 1000);
|
|
},
|
|
},
|
|
|
|
+ methods: {
|
|
|
|
+ changeLocale(locale) {
|
|
|
|
+ // reset to browser default if selection matches browser default
|
|
|
|
+ if (locale == navigator.language.slice(0, 2)) localStorage.clear();
|
|
|
|
+ // else save preference
|
|
|
|
+ else localStorage.locale = locale;
|
|
|
|
+ this.$vuetify.lang.current = locale;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
};
|
|
};
|
|
</script>
|
|
</script>
|
|
|
|
|
|
@@ -147,18 +199,32 @@ body {
|
|
margin: 0.25em;
|
|
margin: 0.25em;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.title-text {
|
|
|
|
+ font-size: 3rem;
|
|
|
|
+}
|
|
.topBar {
|
|
.topBar {
|
|
padding: 0 3rem;
|
|
padding: 0 3rem;
|
|
width: fit-content !important;
|
|
width: fit-content !important;
|
|
- backdrop-filter: blur(16px) saturate(180%);
|
|
|
|
- -webkit-backdrop-filter: blur(16px) saturate(180%);
|
|
|
|
- background: rgba(42, 42, 42, 0.75) !important;
|
|
|
|
border-radius: 1rem !important;
|
|
border-radius: 1rem !important;
|
|
- /* border: 1px solid #222; */
|
|
|
|
- overflow: hidden;
|
|
|
|
|
|
+ /* overflow: hidden; */
|
|
}
|
|
}
|
|
-.title-text {
|
|
|
|
- font-size: 3rem;
|
|
|
|
|
|
+.glass {
|
|
|
|
+ backdrop-filter: blur(16px) saturate(200%);
|
|
|
|
+ -webkit-backdrop-filter: blur(16px) saturate(200%);
|
|
|
|
+ background: rgba(42, 42, 42, 0.75) !important;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* used in docs.vue */
|
|
|
|
+.flex-wrapper {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#translator {
|
|
|
|
+ border-radius: 1rem !important;
|
|
|
|
+ position: fixed;
|
|
|
|
+ bottom: 2rem;
|
|
|
|
+ right: 1rem;
|
|
}
|
|
}
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
@media (max-width: 768px) {
|
|
@@ -172,6 +238,38 @@ body {
|
|
) !important; /* (2rem = mx-4) 1rem on left, 1rem on right */
|
|
) !important; /* (2rem = mx-4) 1rem on left, 1rem on right */
|
|
padding: 0;
|
|
padding: 0;
|
|
}
|
|
}
|
|
|
|
+ .flex-wrapper {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ }
|
|
|
|
+ #translator {
|
|
|
|
+ bottom: 1rem;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* used in docs.vue, help.vue and faq.vue */
|
|
|
|
+.width-constraint {
|
|
|
|
+ max-width: auto;
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+}
|
|
|
|
+@media (min-width: 960px) {
|
|
|
|
+ /* tablet */
|
|
|
|
+ .width-constraint {
|
|
|
|
+ width: 75vw;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+@media (min-width: 1264px) {
|
|
|
|
+ /* desktop */
|
|
|
|
+ .width-constraint {
|
|
|
|
+ width: 60vw;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+@media (min-width: 1904) {
|
|
|
|
+ /* 4k/ultrawide */
|
|
|
|
+ .width-constraint {
|
|
|
|
+ width: 42vw;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* animations and all that */
|
|
/* animations and all that */
|
|
@@ -185,7 +283,6 @@ body {
|
|
.swoop-right-leave-active {
|
|
.swoop-right-leave-active {
|
|
transition-duration: 0.1s;
|
|
transition-duration: 0.1s;
|
|
transition-property: opacity, transform;
|
|
transition-property: opacity, transform;
|
|
- overflow: hidden;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
.swoop-left-enter,
|
|
.swoop-left-enter,
|