Bugfixes, minor changes in settings interface.
Bugfixes, minor changes in settings interface, node modules updated
This commit is contained in:
60
src/App.vue
60
src/App.vue
@@ -3,9 +3,8 @@
|
||||
<v-img
|
||||
v-bind:src="backgroundImage"
|
||||
width="100vw"
|
||||
height="100vh"
|
||||
cover
|
||||
class="bg-image"
|
||||
class="bg-image h-screen"
|
||||
></v-img>
|
||||
<v-app-bar app>
|
||||
<v-app-bar-title class="headline text-uppercase" v-if="smAndUp">
|
||||
@@ -29,10 +28,29 @@
|
||||
@click="toggleTheme"
|
||||
></v-btn>
|
||||
-->
|
||||
<v-btn
|
||||
icon="mdi-cog-outline"
|
||||
@click="showSettings"
|
||||
></v-btn>
|
||||
<v-menu>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn
|
||||
icon="mdi-menu"
|
||||
v-bind="props"
|
||||
></v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item @click="showSettings">
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-cog-outline"></v-icon>
|
||||
</template>
|
||||
<v-list-item-title>{{ $t("settings") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-divider></v-divider>
|
||||
<v-list-item @click="showAbout">
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-information-outline"></v-icon>
|
||||
</template>
|
||||
<v-list-item-title>{{ $t("about") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-app-bar>
|
||||
|
||||
<v-progress-linear
|
||||
@@ -41,8 +59,11 @@
|
||||
v-if="showProgress"
|
||||
></v-progress-linear>
|
||||
|
||||
<v-main>
|
||||
<v-container fluid class="ma-0 pa-0">
|
||||
<v-main class="h-screen">
|
||||
<v-container
|
||||
fluid
|
||||
class="ma-0 pa-0 content-container"
|
||||
>
|
||||
<router-view v-slot="{ Component }"
|
||||
ref="view"
|
||||
@authorSelected="loadBooks"
|
||||
@@ -90,15 +111,13 @@
|
||||
<v-col
|
||||
cols="1"
|
||||
style="min-width: 0px; max-width: 100%"
|
||||
class="flex-grow-1 flex-shrink-0; background-color: red;"
|
||||
class="flex-grow-1 flex-shrink-0"
|
||||
v-if="smAndUp"
|
||||
>
|
||||
<v-card flat color="rgba(0, 0, 0, 0)">
|
||||
<v-list-item two-line>
|
||||
<v-list-item-header>
|
||||
<v-list-item-title>{{ $store.getters.book.author }}</v-list-item-title>
|
||||
<v-list-item-subtitle style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">{{ $store.getters.book.title }}<span v-if="$store.getters.chapters.length > 0 && currentChapter !== null && $store.getters.chapters[currentChapter].title !== ''"> - {{ $store.getters.chapters[currentChapter].title }}</span></v-list-item-subtitle>
|
||||
</v-list-item-header>
|
||||
<v-list-item-title>{{ $store.getters.book.author }}</v-list-item-title>
|
||||
<v-list-item-subtitle style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">{{ $store.getters.book.title }}<span v-if="$store.getters.chapters.length > 0 && currentChapter !== null && $store.getters.chapters[currentChapter].title !== ''"> - {{ $store.getters.chapters[currentChapter].title }}</span></v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -178,7 +197,8 @@
|
||||
</v-btn>
|
||||
</v-fab-transition>
|
||||
-->
|
||||
<message-box ref="MessageBox"/>
|
||||
<about-dialog ref="AboutDialog"/>
|
||||
<message-box ref="MessageBox"/>
|
||||
<settings-dialog ref="SettingsDialog"/>
|
||||
</v-app>
|
||||
</template>
|
||||
@@ -187,12 +207,15 @@
|
||||
//import { ref, onMounted } from "vue";
|
||||
import { ref } from "vue";
|
||||
import { useDisplay } from "vuetify";
|
||||
import AboutDialog from "./components/AboutDialog";
|
||||
import MessageBox from "./components/MessageBox";
|
||||
import SettingsDialog from "./components/SettingsDialog";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
|
||||
components: {
|
||||
AboutDialog,
|
||||
MessageBox,
|
||||
SettingsDialog,
|
||||
},
|
||||
@@ -240,6 +263,7 @@
|
||||
currentChapter: null,
|
||||
currentProgress: 0,
|
||||
currentTime: "00:00",
|
||||
duration: "00:00",
|
||||
playbackRate: 1,
|
||||
status: 0,
|
||||
volume: 5,
|
||||
@@ -689,6 +713,10 @@
|
||||
if (!silent) { this.alertMessage = this.$t("bookmarkSaved"); }
|
||||
},
|
||||
|
||||
showAbout () {
|
||||
this.$refs.AboutDialog.dialog = true;
|
||||
},
|
||||
|
||||
showMessage (title, text) {
|
||||
this.$refs.MessageBox.title = title;
|
||||
this.$refs.MessageBox.text = text;
|
||||
@@ -766,7 +794,9 @@
|
||||
background: rgba(15, 15, 15, .5)
|
||||
|
||||
.content-container
|
||||
height: calc(100vh - 160px)
|
||||
/* height: calc(100vh - 160px) */
|
||||
/* height: calc(100% - 160px) */
|
||||
max-height: 100%
|
||||
overflow-y: auto
|
||||
overflow-x: hidden
|
||||
|
||||
|
||||
61
src/components/AboutDialog.vue
Normal file
61
src/components/AboutDialog.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<v-layout row justify-center>
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
persistent
|
||||
scrollable
|
||||
max-width="600px"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title class="headline">{{ $t("about") }}</v-card-title>
|
||||
<v-card-text>
|
||||
<template v-if="locale == 'ru'">
|
||||
<p class="text-center">Аудиотека</p>
|
||||
<p class="text-center">© Александр Чебыкин, 2019-2022</p>
|
||||
<p class="text-center">Опубликовано под лицензией <a href="https://opensource.org/licenses/MIT" target="_blank">MIT license</a></p>
|
||||
<p class="text-center">Git: <a href="https://www.cainet.info/git/cai/AudioLib" target="_blank">https://home.cainet.info/git/cai/AudioLib</a></p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p class="text-center">Audiobooks library</p>
|
||||
<p class="text-center">© Alexander I Chebykin, 2019-2022</p>
|
||||
<p class="text-center">Published under <a href="https://opensource.org/licenses/MIT" target="_blank">MIT license</a></p>
|
||||
<p class="text-center">Git: <a href="https://www.cainet.info/git/cai/AudioLib" target="_blank">https://www.cainet.info/git/cai/AudioLib</a></p>
|
||||
</template>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn flat variant="outlined" color="info" @click="dialog = false">Ok</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AboutDialog",
|
||||
|
||||
data () {
|
||||
return {
|
||||
dialog: false,
|
||||
locale: "en",
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
dialog (val) {
|
||||
if (val) {
|
||||
let userLocale = navigator.language || navigator.userLanguage;
|
||||
|
||||
userLocale = userLocale.indexOf("-") > 0
|
||||
? userLocale.substring(0, userLocale.indexOf("-")).toLowerCase()
|
||||
: userLocale.toLowerCase();
|
||||
|
||||
this.locale = userLocale;
|
||||
}
|
||||
},
|
||||
|
||||
darkTheme (val) { this.$store.commit("setDarkTheme", val); },
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -3,7 +3,7 @@
|
||||
flat
|
||||
tile
|
||||
color="rgba(0, 0, 0, 0)"
|
||||
class="d-flex align-content-start flex-wrap content-container mx-0 pt-2 px-2"
|
||||
class="d-flex align-content-start flex-wrap mx-0 pt-2 px-2"
|
||||
>
|
||||
<v-row no-gutters>
|
||||
<v-col
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
flat
|
||||
tile
|
||||
color="rgba(0, 0, 0, 0)"
|
||||
class="d-flex align-content-start flex-wrap content-container mx-0 pa-2"
|
||||
class="d-flex align-content-start flex-wrap mx-0 pa-2"
|
||||
>
|
||||
<v-row
|
||||
no-gutters
|
||||
@@ -91,7 +91,6 @@
|
||||
lg="6"
|
||||
class="flex-grow-1 flex-shrink-0 pa-2"
|
||||
v-if="illustrated"
|
||||
style="background-color: yellow"
|
||||
>
|
||||
2
|
||||
</v-col>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<v-card
|
||||
flat
|
||||
color="rgba(0, 0, 0, 0)"
|
||||
class="content-container mx-0 pt-2 px-2"
|
||||
class="mx-0 pt-2 px-2"
|
||||
>
|
||||
<v-row
|
||||
no-gutters
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MessageDialog",
|
||||
|
||||
data () {
|
||||
return {
|
||||
dialog: false,
|
||||
|
||||
@@ -3,66 +3,41 @@
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
persistent
|
||||
scrollable
|
||||
max-width="600px"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title class="headline">{{ $t("settings") }}</v-card-title>
|
||||
<v-tabs
|
||||
v-model="activeTab"
|
||||
centered
|
||||
>
|
||||
<v-tab ripple value="settings">{{ $t("settings") }}</v-tab>
|
||||
<v-tab ripple value="about">{{ $t("about") }}</v-tab>
|
||||
</v-tabs>
|
||||
<v-card-text>
|
||||
<v-window v-model="activeTab">
|
||||
<v-window-item value="settings">
|
||||
<v-switch
|
||||
v-model="darkTheme"
|
||||
color="blue"
|
||||
:label="$t('darkTheme')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<v-switch
|
||||
v-model="autoBookmark"
|
||||
color="blue"
|
||||
:label="$t('autoBookmarks')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<v-switch
|
||||
v-model="autoLoadBooks"
|
||||
color="blue"
|
||||
:label="$t('autoLoadBooks')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<div class="mb-7 text-caption">{{ $t("playbackRate") }}</div>
|
||||
<v-slider
|
||||
v-model="playbackRate"
|
||||
color="blue"
|
||||
label="color"
|
||||
min="0.5"
|
||||
max="2"
|
||||
step="0.5"
|
||||
show-ticks="always"
|
||||
thumb-label="always"
|
||||
tick-size="4"
|
||||
></v-slider>
|
||||
</v-window-item>
|
||||
|
||||
<v-window-item value="about">
|
||||
<template v-if="locale == 'ru'">
|
||||
<p><center>Аудиотека</center></p>
|
||||
<p><center>© Александр Чебыкин, 2019-2022</center></p>
|
||||
<p><center>Опубликовано под лицензией <a href="https://opensource.org/licenses/MIT" target="_blank">MIT license</a></center></p>
|
||||
<p><center>Git: <a href="https://www.cainet.info/git/cai/AudioLib" target="_blank">https://home.cainet.info/git/cai/AudioLib</a></center></p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p><center>Audiobooks library</center></p>
|
||||
<p><center>© Alexander I Chebykin, 2019-2022</center></p>
|
||||
<p><center>Published under <a href="https://opensource.org/licenses/MIT" target="_blank">MIT license</a></center></p>
|
||||
<p><center>Git: <a href="https://www.cainet.info/git/cai/AudioLib" target="_blank">https://www.cainet.info/git/cai/AudioLib</a></center></p>
|
||||
</template>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
<v-switch
|
||||
v-model="darkTheme"
|
||||
color="blue"
|
||||
:label="$t('darkTheme')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<v-switch
|
||||
v-model="autoBookmark"
|
||||
color="blue"
|
||||
:label="$t('autoBookmarks')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<v-switch
|
||||
v-model="autoLoadBooks"
|
||||
color="blue"
|
||||
:label="$t('autoLoadBooks')"
|
||||
class="ml-3"
|
||||
></v-switch>
|
||||
<div class="mb-7 text-body-1">{{ $t("playbackRate") }}</div>
|
||||
<v-slider
|
||||
v-model="playbackRate"
|
||||
color="blue"
|
||||
min="0.5"
|
||||
max="2"
|
||||
step="0.5"
|
||||
show-ticks="always"
|
||||
thumb-label="always"
|
||||
tick-size="4"
|
||||
></v-slider>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
@@ -75,10 +50,11 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SettingsDialog",
|
||||
|
||||
data () {
|
||||
return {
|
||||
dialog: false,
|
||||
activeTab: 0,
|
||||
autoBookmark: false,
|
||||
autoLoadBooks: false,
|
||||
darkTheme: false,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import axios from "axios";
|
||||
import vueAxios from "vue-axios";
|
||||
import {createRouter, createWebHashHistory} from "vue-router";
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import routes from "./routes";
|
||||
import store from "./store";
|
||||
import vuetify from "./plugins/vuetify";
|
||||
@@ -15,6 +15,7 @@ const router = createRouter({
|
||||
history: createWebHashHistory(), //createWebHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
/**
|
||||
@@ -40,7 +41,8 @@ app.config.globalProperties.defaultBackground = "img/library1080.webp";
|
||||
fetch(process.env.BASE_URL + "data/config.json")
|
||||
.then((response) => response.json())
|
||||
.then((config) => {
|
||||
app.config.globalProperties.appConfig = config
|
||||
app.config.globalProperties.appConfig = config;
|
||||
|
||||
app
|
||||
.use(vueAxios, axios)
|
||||
.use(vuetify)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { register } from "register-service-worker"
|
||||
import { register } from "register-service-worker";
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
register(`${process.env.BASE_URL}service-worker.js`, {
|
||||
@@ -8,25 +8,31 @@ if (process.env.NODE_ENV === "production") {
|
||||
console.log(
|
||||
"App is being served from cache by a service worker.\n" +
|
||||
"For more details, visit https://goo.gl/AFskqB"
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
registered () {
|
||||
console.log("Service worker has been registered.")
|
||||
console.log("Service worker has been registered.");
|
||||
},
|
||||
|
||||
cached () {
|
||||
console.log("Content has been cached for offline use.")
|
||||
console.log("Content has been cached for offline use.");
|
||||
},
|
||||
|
||||
updatefound () {
|
||||
console.log("New content is downloading.")
|
||||
console.log("New content is downloading.");
|
||||
},
|
||||
|
||||
updated () {
|
||||
console.log("New content is available; please refresh.")
|
||||
console.log("New content is available; please refresh.");
|
||||
},
|
||||
|
||||
offline () {
|
||||
console.log("No internet connection found. App is running in offline mode.")
|
||||
console.log("No internet connection found. App is running in offline mode.");
|
||||
},
|
||||
|
||||
error (error) {
|
||||
console.error("Error during service worker registration:", error)
|
||||
console.error("Error during service worker registration:", error);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
//import { createApp } from "vue";
|
||||
import { createStore } from "vuex";
|
||||
|
||||
const store = createStore({
|
||||
|
||||
Reference in New Issue
Block a user