mirror of
https://github.com/CzBiX/qb-web.git
synced 2026-04-23 18:30:06 +08:00
9
src/assets/styles.scss
Normal file
9
src/assets/styles.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
@import '~vuetify/src/styles/styles.sass';
|
||||
|
||||
@mixin dialog-title {
|
||||
@include theme(v-card) using($material) {
|
||||
.v-card__title {
|
||||
background-color: map-get($material, 'app-bar');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,7 @@
|
||||
width="40em"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-link-plus</v-icon>
|
||||
<span>{{ $t('title.add_torrents') }}</span>
|
||||
</v-card-title>
|
||||
@@ -337,6 +335,10 @@ export default class AddForm extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.btn-add.with-footer {
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
:value="searchQuery"
|
||||
/>
|
||||
<v-spacer v-if="!phoneLayout" />
|
||||
<v-btn
|
||||
icon
|
||||
@click="toggleDarkMode"
|
||||
>
|
||||
<v-icon v-text="darkModeIcon" />
|
||||
</v-btn>
|
||||
<v-select
|
||||
v-show="!searchBarExpanded"
|
||||
class="locales"
|
||||
@@ -54,7 +60,7 @@ import Vue from 'vue';
|
||||
import { mapMutations } from 'vuex';
|
||||
|
||||
import i18n, { tr, translations, defaultLocale } from '@/locale';
|
||||
import { DialogType, DialogConfig, SnackBarConfig } from '@/store/types';
|
||||
import { DialogType, DialogConfig, SnackBarConfig, ConfigPayload } from '@/store/types';
|
||||
import Component from 'vue-class-component';
|
||||
import { Prop, Emit, Watch } from 'vue-property-decorator';
|
||||
|
||||
@@ -63,6 +69,7 @@ import { Prop, Emit, Watch } from 'vue-property-decorator';
|
||||
...mapMutations([
|
||||
'showDialog',
|
||||
'showSnackBar',
|
||||
'updateConfig',
|
||||
]),
|
||||
},
|
||||
})
|
||||
@@ -72,12 +79,17 @@ export default class MainToolbar extends Vue {
|
||||
|
||||
showDialog!: (_: DialogConfig) => void
|
||||
showSnackBar!: (_: SnackBarConfig) => void
|
||||
updateConfig!: (_: ConfigPayload) => void
|
||||
|
||||
locales = this.buildLocales()
|
||||
currentLocale = i18n.locale()
|
||||
oldLocale = this.currentLocale
|
||||
focusedSearch = false
|
||||
|
||||
get darkModeIcon() {
|
||||
return this.$vuetify.theme.dark ? 'mdi-brightness-4' : 'mdi-brightness-6';
|
||||
}
|
||||
|
||||
get searchQuery() {
|
||||
return this.$store.getters.config.filter.query;
|
||||
}
|
||||
@@ -115,7 +127,7 @@ export default class MainToolbar extends Vue {
|
||||
onSearch = throttle(async (v: string) => {
|
||||
// avoid hang input
|
||||
await this.$nextTick();
|
||||
this.$store.commit('updateConfig', {
|
||||
this.updateConfig({
|
||||
key: 'filter',
|
||||
value: {
|
||||
query: v,
|
||||
@@ -156,6 +168,16 @@ export default class MainToolbar extends Vue {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
toggleDarkMode() {
|
||||
const { theme } = this.$vuetify;
|
||||
theme.dark = !theme.dark;
|
||||
|
||||
this.updateConfig({
|
||||
key: 'darkMode',
|
||||
value: theme.dark,
|
||||
});
|
||||
}
|
||||
|
||||
@Watch('currentLocale')
|
||||
onCurrentLocaleChanged(v: keyof typeof translations) {
|
||||
this.switchLocale(v)
|
||||
|
||||
@@ -543,6 +543,8 @@ export default class Torrents extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
margin-left: 2px;
|
||||
@@ -559,7 +561,7 @@ export default class Torrents extends Vue {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
.v-data-table {
|
||||
@include theme(v-data-table) using ($material) {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -583,7 +585,7 @@ export default class Torrents extends Vue {
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #eee;
|
||||
background-color: map-deep-get($material, 'table', 'hover');
|
||||
}
|
||||
|
||||
td {
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
width="40em"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-delete</v-icon>
|
||||
<span>{{ $t('title.delete_torrents') }}</span>
|
||||
</v-card-title>
|
||||
@@ -121,6 +119,10 @@ export default class ConfirmDeleteDialog extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.torrents {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
width="40em"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-folder</v-icon>
|
||||
<span>{{ $t('title.set_category') }}</span>
|
||||
</v-card-title>
|
||||
@@ -122,6 +120,10 @@ export default class ConfirmSetCategoryDialog extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.torrents {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
width="40em"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-server</v-icon>
|
||||
<span>Edit tracker</span>
|
||||
</v-card-title>
|
||||
@@ -212,6 +210,10 @@ export default class EditTrackerDialog extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.torrents {
|
||||
overflow: auto;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
:fullscreen="phoneLayout"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">
|
||||
mdi-alert-circle
|
||||
</v-icon>
|
||||
@@ -148,6 +146,10 @@ export default class InfoDialog extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
::v-deep .v-dialog {
|
||||
max-width: 1100px;
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
:width="dialogWidth"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-delta</v-icon>
|
||||
<span>Logs</span>
|
||||
</v-card-title>
|
||||
@@ -63,7 +61,7 @@ import { Prop, Emit } from 'vue-property-decorator';
|
||||
},
|
||||
typeColor(type: number) {
|
||||
const map: any = {
|
||||
1: 'secondary--text',
|
||||
1: null,
|
||||
2: 'info--text',
|
||||
4: 'warn--text',
|
||||
8: 'error--text',
|
||||
@@ -114,6 +112,10 @@ export default class LogsDialog extends HasTask {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.logs {
|
||||
font-family: monospace;
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
persistent
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-rss-box</v-icon>
|
||||
<span>RSS</span>
|
||||
<v-spacer />
|
||||
@@ -425,6 +423,10 @@ export default class RssDialog extends HasTask {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.v-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
width="50%"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-4"
|
||||
>
|
||||
<v-card-title class="headline">
|
||||
<v-icon class="mr-2">mdi-filter</v-icon>
|
||||
<span v-text="$t('dialog.rss_rule.title')" />
|
||||
<v-spacer />
|
||||
@@ -347,6 +345,10 @@ export default class RssRulesDialog extends Vue {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/styles.scss';
|
||||
|
||||
@include dialog-title;
|
||||
|
||||
.v-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -28,7 +28,7 @@ function matchLocale() {
|
||||
export const defaultLocale = matchLocale()
|
||||
|
||||
function updateLocale() {
|
||||
let locale: keyof typeof translations | null = loadConfig()['locale'];
|
||||
let locale: keyof typeof translations | undefined | null = loadConfig()['locale'];
|
||||
|
||||
if (!locale) {
|
||||
locale = defaultLocale;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Vue from 'vue';
|
||||
import Vuetify from 'vuetify/lib';
|
||||
import i18n from '@/locale';
|
||||
import { loadConfig } from '@/store/config';
|
||||
|
||||
Vue.use(Vuetify);
|
||||
|
||||
@@ -9,6 +10,7 @@ locale = locale === 'zh-CN' ? 'zh-Hans' : locale.split('-', 1)[0];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { default: translation } = require('vuetify/src/locale/' + locale);
|
||||
const darkMode = !!loadConfig()['darkMode'];
|
||||
|
||||
export default new Vuetify({
|
||||
lang: {
|
||||
@@ -18,4 +20,7 @@ export default new Vuetify({
|
||||
icons: {
|
||||
iconfont: 'mdi',
|
||||
},
|
||||
theme: {
|
||||
dark: darkMode,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,13 +17,16 @@ const defaultConfig = {
|
||||
query: null,
|
||||
},
|
||||
locale: null,
|
||||
darkMode: null,
|
||||
};
|
||||
|
||||
export type Config = typeof defaultConfig
|
||||
|
||||
function saveConfig(obj: any) {
|
||||
localStorage.setItem(configKey, JSON.stringify(obj));
|
||||
}
|
||||
|
||||
export function loadConfig() {
|
||||
export function loadConfig(): Partial<Config> {
|
||||
const tmp = localStorage.getItem(configKey);
|
||||
if (!tmp) {
|
||||
return {};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { MainData } from '@/types';
|
||||
import { Config } from './config';
|
||||
|
||||
export interface RootState {
|
||||
rid: number;
|
||||
@@ -19,7 +20,7 @@ export interface ConfigState {
|
||||
}
|
||||
|
||||
export interface ConfigPayload {
|
||||
key: string;
|
||||
key: keyof Config;
|
||||
value: any;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user