mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-18 08:12:15 +00:00
UI setup for emojis and theme mode
This commit is contained in:
@@ -6,21 +6,21 @@
|
||||
<ToasterWrapper />
|
||||
<CookieDisclaimer />
|
||||
|
||||
<!--Show spinner before translations is loaded-->
|
||||
<Spinner v-if="! isLoaded"/>
|
||||
<!--Show spinner before translations is loaded-->
|
||||
<Spinner v-if="! isLoaded" />
|
||||
|
||||
<!--Show warning bar when user functionality is restricted-->
|
||||
<!--Show warning bar when user functionality is restricted-->
|
||||
<div v-if="isLimitedUser" class="bg-red-500 text-center py-1">
|
||||
<router-link :to="{name: 'Billing'}" class="text-white font-bold text-xs">
|
||||
{{ $t('Your functionality is restricted. Please review your billing settings.') }}
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!--App view-->
|
||||
<!--App view-->
|
||||
<router-view v-if="isLoaded" />
|
||||
|
||||
<!--Background under popups-->
|
||||
<Vignette/>
|
||||
<!--Background under popups-->
|
||||
<Vignette />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -34,93 +34,101 @@ import {mapGetters} from 'vuex'
|
||||
import {events} from './bus'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
CookieDisclaimer,
|
||||
ToasterWrapper,
|
||||
Vignette,
|
||||
Spinner,
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false
|
||||
}
|
||||
},
|
||||
name: 'app',
|
||||
components: {
|
||||
CookieDisclaimer,
|
||||
ToasterWrapper,
|
||||
Vignette,
|
||||
Spinner,
|
||||
Alert
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isLimitedUser',
|
||||
'isDarkMode',
|
||||
'config',
|
||||
'user',
|
||||
]),
|
||||
},
|
||||
watch: {
|
||||
isDarkMode() {
|
||||
this.toggleDarkMode()
|
||||
'config.defaultThemeMode': function () {
|
||||
this.handleDarkMode()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleDarkMode() {
|
||||
const webApp = document.getElementsByTagName("html")[0];
|
||||
|
||||
webApp.classList.toggle("dark");
|
||||
},
|
||||
methods: {
|
||||
spotlightListener(e) {
|
||||
if (e.key === 'k' && e.metaKey) {
|
||||
events.$emit('spotlight:show');
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
|
||||
// Set dark/light mode by user settings
|
||||
if (localStorage.hasOwnProperty('is_dark_mode')) {
|
||||
if (this.isDarkMode) this.toggleDarkMode()
|
||||
}
|
||||
|
||||
// Proceed dark/light mode by system settings
|
||||
if (! localStorage.hasOwnProperty('is_dark_mode')) {
|
||||
handleDarkMode() {
|
||||
const app = document.getElementsByTagName("html")[0];
|
||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
// Set up initial dark/light mode on app loading
|
||||
if (prefersDarkScheme.matches) this.toggleDarkMode()
|
||||
if (this.config.defaultThemeMode === 'dark') {
|
||||
|
||||
// Watch for dark/light mode changes on os system layer
|
||||
prefersDarkScheme.addEventListener('change', () => this.toggleDarkMode());
|
||||
app.classList.add("dark")
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
|
||||
} else if (this.config.defaultThemeMode === 'light') {
|
||||
|
||||
app.classList.remove("dark")
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
|
||||
} else if (this.config.defaultThemeMode === 'system' && prefersDarkScheme.matches) {
|
||||
|
||||
app.classList.add("dark")
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
|
||||
} else if (this.config.defaultThemeMode === 'system' && !prefersDarkScheme.matches) {
|
||||
|
||||
app.classList.remove("dark")
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
window.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', () => {
|
||||
this.handleDarkMode()
|
||||
});
|
||||
|
||||
// Get installation state
|
||||
let installation = this.$root.$data.config.installation
|
||||
// Get installation state
|
||||
let installation = this.$root.$data.config.installation
|
||||
|
||||
if (['setup-disclaimer', 'setup-database'].includes(installation))
|
||||
this.isLoaded = true
|
||||
if (['setup-disclaimer', 'setup-database'].includes(installation))
|
||||
this.isLoaded = true
|
||||
|
||||
// Redirect to database verify code
|
||||
if (installation === 'setup-database')
|
||||
this.$router.push({name: 'StatusCheck'})
|
||||
// Redirect to database verify code
|
||||
if (installation === 'setup-database')
|
||||
this.$router.push({name: 'StatusCheck'})
|
||||
|
||||
// Redirect to starting installation process
|
||||
if (installation === 'setup-disclaimer')
|
||||
this.$router.push({name: 'InstallationDisclaimer'})
|
||||
// Redirect to starting installation process
|
||||
if (installation === 'setup-disclaimer')
|
||||
this.$router.push({name: 'InstallationDisclaimer'})
|
||||
|
||||
if (installation === 'setup-done')
|
||||
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale)
|
||||
.then(() => {
|
||||
this.isLoaded = true
|
||||
if (installation === 'setup-done')
|
||||
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale)
|
||||
.then(() => {
|
||||
this.isLoaded = true
|
||||
|
||||
// Store config to vuex
|
||||
this.$store.commit('INIT', {
|
||||
config: this.$root.$data.config,
|
||||
rootDirectory: {
|
||||
name: this.$t('locations.home'),
|
||||
location: 'base',
|
||||
id: undefined
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
if (this.$isWindows()) {
|
||||
// Store config to vuex
|
||||
this.$store.commit('INIT', {
|
||||
config: this.$root.$data.config,
|
||||
rootDirectory: {
|
||||
name: this.$t('locations.home'),
|
||||
location: 'base',
|
||||
id: undefined
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
if (this.$isWindows()) {
|
||||
document.body.classList.add('windows')
|
||||
}
|
||||
|
||||
@@ -155,21 +163,21 @@ export default {
|
||||
|
||||
[v-cloak],
|
||||
[v-cloak] > * {
|
||||
display: none
|
||||
display: none
|
||||
}
|
||||
|
||||
* {
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: $text;
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.vue-feather {
|
||||
@@ -179,24 +187,24 @@ export default {
|
||||
}
|
||||
|
||||
#auth {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// Dark mode support
|
||||
.dark {
|
||||
|
||||
* {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
* {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
body, html {
|
||||
background: $dark_mode_background;
|
||||
color: $dark_mode_text_primary;
|
||||
body, html {
|
||||
background: $dark_mode_background;
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
img {
|
||||
opacity: .95;
|
||||
}
|
||||
}
|
||||
img {
|
||||
opacity: .95;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
|
||||
<!--Toggle Dark/Light mode-->
|
||||
<div @click="toggleDarkMode" :title="$t('dark_mode_toggle')" class="block mt-6">
|
||||
<div @click="$store.dispatch('toggleThemeMode')" :title="$t('dark_mode_toggle')" class="block mt-6">
|
||||
<div class="button-icon p-3 cursor-pointer inline-block dark:hover:bg-4x-dark-foreground hover:bg-light-300 rounded-xl">
|
||||
<sun-icon v-if="isDarkMode" size="20" />
|
||||
<moon-icon v-if="! isDarkMode" size="20" />
|
||||
@@ -91,7 +91,6 @@
|
||||
'user',
|
||||
]),
|
||||
navigation() {
|
||||
|
||||
if (this.user.data.attributes.role === 'admin') {
|
||||
return [
|
||||
{
|
||||
@@ -132,9 +131,6 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleDarkMode() {
|
||||
this.$store.dispatch('toggleDarkMode', !this.isDarkMode)
|
||||
},
|
||||
isSection(section) {
|
||||
return this.$route.matched[0].name === section
|
||||
}
|
||||
|
||||
@@ -245,7 +245,6 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isDarkMode',
|
||||
'config',
|
||||
'user',
|
||||
]),
|
||||
@@ -588,7 +587,7 @@ export default {
|
||||
}
|
||||
|
||||
if (arg.action.value === 'dark-mode') {
|
||||
this.$store.dispatch('toggleDarkMode', !this.isDarkMode)
|
||||
this.$store.dispatch('toggleThemeMode')
|
||||
}
|
||||
|
||||
if (arg.action.value === 'full-screen-mode') {
|
||||
|
||||
35
resources/js/store/modules/app.js
vendored
35
resources/js/store/modules/app.js
vendored
@@ -4,7 +4,7 @@ import Vue from "vue"
|
||||
|
||||
const defaultState = {
|
||||
isVisibleNavigationBars: localStorage.getItem('is_navigation_bars') !== 'false',
|
||||
darkMode: localStorage.getItem('is_dark_mode') === 'true' || false,
|
||||
isDarkMode: false,
|
||||
isVisibleSidebar: localStorage.getItem('file_info_visibility') === 'true' || false,
|
||||
itemViewType: localStorage.getItem('preview_type') || 'list',
|
||||
config: undefined,
|
||||
@@ -17,13 +17,20 @@ const defaultState = {
|
||||
},
|
||||
}
|
||||
const actions = {
|
||||
toggleDarkMode: ({commit}, visibility) => {
|
||||
toggleThemeMode: ({commit}, mode = undefined) => {
|
||||
const app = document.getElementsByTagName("html")[0];
|
||||
|
||||
// Store dark mode into localStorage
|
||||
localStorage.setItem('is_dark_mode', visibility)
|
||||
if (! mode) {
|
||||
mode = app.classList.contains('dark') ? 'light' : 'dark'
|
||||
}
|
||||
|
||||
// Change preview
|
||||
commit('TOGGLE_DARK_MODE', visibility)
|
||||
commit('REPLACE_CONFIG_VALUE', {
|
||||
key: 'defaultThemeMode',
|
||||
value: mode,
|
||||
})
|
||||
|
||||
// Update user settings
|
||||
Vue.prototype.$updateText('/user/settings', 'theme_mode', mode)
|
||||
},
|
||||
toggleNavigationBars: ({commit, state}) => {
|
||||
|
||||
@@ -43,10 +50,9 @@ const actions = {
|
||||
// Change preview
|
||||
commit('CHANGE_PREVIEW', previewType)
|
||||
},
|
||||
toggleEmojiType: ({commit, getters}) => {
|
||||
let newType = getters.config.defaultEmoji === 'twemoji'
|
||||
? 'applemoji'
|
||||
: 'twemoji'
|
||||
toggleEmojiType: ({commit, getters}, type = undefined) => {
|
||||
|
||||
let newType = type ? type : getters.config.defaultEmoji === 'twemoji' ? 'applemoji' : 'twemoji'
|
||||
|
||||
// Update config
|
||||
commit('REPLACE_CONFIG_VALUE', {
|
||||
@@ -111,9 +117,6 @@ const mutations = {
|
||||
CHANGE_PREVIEW(state, type) {
|
||||
state.itemViewType = type
|
||||
},
|
||||
TOGGLE_DARK_MODE(state, visibility) {
|
||||
state.darkMode = visibility
|
||||
},
|
||||
TOGGLE_NAVIGATION_BARS(state) {
|
||||
state.isVisibleNavigationBars = ! state.isVisibleNavigationBars
|
||||
},
|
||||
@@ -151,6 +154,10 @@ const mutations = {
|
||||
state.config.paypal_client_id = data.key
|
||||
state.config.isPayPal = true
|
||||
},
|
||||
UPDATE_DARK_MODE_STATUS(state, val) {
|
||||
console.log(val);
|
||||
state.isDarkMode = val
|
||||
},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
@@ -162,7 +169,7 @@ const getters = {
|
||||
config: state => state.config,
|
||||
emojis: state => state.emojis,
|
||||
index: state => state.index,
|
||||
isDarkMode: state => state.darkMode,
|
||||
isDarkMode: state => state.isDarkMode,
|
||||
sorting: (state) => {
|
||||
return {sorting: state.sorting, URI: '?sort=' + state.sorting.field + '&direction=' + state.sorting.sort}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div class="card shadow-card">
|
||||
<FormLabel>
|
||||
{{ $t('Appearance') }}
|
||||
</FormLabel>
|
||||
|
||||
<AppInputText :title="$t('Theme Mode')" :description="$t('Set your theme mode on dark, light or based on your system settings.')">
|
||||
<div class="flex items-center md:space-x-6 space-x-4">
|
||||
<div
|
||||
v-for="(theme, i) in themeSetup"
|
||||
:key="i"
|
||||
:title="theme.title"
|
||||
@click="$store.dispatch('toggleThemeMode', theme.type)"
|
||||
class="w-full rounded-xl shadow-lg overflow-hidden cursor-pointer border-3"
|
||||
:class="{'border-theme': config.defaultThemeMode === theme.type, 'border-transparent': config.defaultThemeMode !== theme.type}"
|
||||
>
|
||||
<img :src="theme.image" :alt="theme.type">
|
||||
</div>
|
||||
</div>
|
||||
</AppInputText>
|
||||
|
||||
<AppInputText :title="$t('Default Emojis')" :description="$t('Set your default emojis for your folder custom icons. You can set Twemoji or default Apple emojis.')" :is-last="true">
|
||||
<div class="flex items-center md:space-x-6 space-x-4">
|
||||
<div
|
||||
v-for="(emoji, i) in emojiSetup"
|
||||
:key="i"
|
||||
:title="emoji.title"
|
||||
@click="$store.dispatch('toggleEmojiType', emoji.type)"
|
||||
class="w-full rounded-xl shadow-lg overflow-hidden cursor-pointer border-3"
|
||||
:class="{'border-theme': currentEmojis === emoji.type, 'border-transparent': currentEmojis !== emoji.type}"
|
||||
>
|
||||
<img :src="isDarkMode ? emoji.image.dark : emoji.image.light" :alt="emoji.type">
|
||||
</div>
|
||||
</div>
|
||||
</AppInputText>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-card">
|
||||
<FormLabel>
|
||||
{{ $t('Account Settings') }}
|
||||
@@ -35,6 +72,7 @@
|
||||
:placeholder="$t('user_settings.timezone_plac')" />
|
||||
</AppInputText>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-card">
|
||||
<FormLabel>
|
||||
{{ $t('user_settings.title_billing') }}
|
||||
@@ -110,15 +148,54 @@
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isDarkMode',
|
||||
'countries',
|
||||
'timezones',
|
||||
'config',
|
||||
]),
|
||||
currentEmojis() {
|
||||
return this.config.defaultEmoji
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: this.$store.getters.user,
|
||||
isLoading: false,
|
||||
themeSetup: [
|
||||
{
|
||||
title: this.$t('Light mode'),
|
||||
type: 'light',
|
||||
image: '/assets/setup/light-mode.jpg',
|
||||
},
|
||||
{
|
||||
title: this.$t('Dark mode'),
|
||||
type: 'dark',
|
||||
image: '/assets/setup/dark-mode.jpg',
|
||||
},
|
||||
{
|
||||
title: this.$t('Based on system settings'),
|
||||
type: 'system',
|
||||
image: '/assets/setup/system-mode.jpg',
|
||||
},
|
||||
],
|
||||
emojiSetup: [
|
||||
{
|
||||
title: 'Twemoji',
|
||||
type: 'twemoji',
|
||||
image: {
|
||||
dark: '/assets/setup/twemoji-preview-dark.jpg',
|
||||
light: '/assets/setup/twemoji-preview.jpg',
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Applemoji',
|
||||
type: 'applemoji',
|
||||
image: {
|
||||
dark: '/assets/setup/applemoji-preview-dark.jpg',
|
||||
light: '/assets/setup/applemoji-preview.jpg',
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
Reference in New Issue
Block a user