diff --git a/app/imports/api/users/Users.js b/app/imports/api/users/Users.js index 47f1f25d..dc9779e9 100644 --- a/app/imports/api/users/Users.js +++ b/app/imports/api/users/Users.js @@ -143,12 +143,12 @@ Meteor.users.generateApiKey = new ValidatedMethod({ Meteor.users.setDarkMode = new ValidatedMethod({ name: 'users.setDarkMode', validate: new SimpleSchema({ - darkMode: { type: Boolean }, + darkMode: { type: Boolean, optional: true }, }).validator(), mixins: [RateLimiterMixin], rateLimit: { numRequests: 5, - timeInterval: 5000, + timeInterval: 2000, }, run({ darkMode }) { if (!this.userId) return; diff --git a/app/imports/client/ui/layouts/AppLayout.vue b/app/imports/client/ui/layouts/AppLayout.vue index 4312d456..c1e70af7 100644 --- a/app/imports/client/ui/layouts/AppLayout.vue +++ b/app/imports/client/ui/layouts/AppLayout.vue @@ -66,7 +66,6 @@ import Sidebar from '/imports/client/ui/layouts/Sidebar.vue'; import DialogStack from '/imports/client/ui/dialogStack/DialogStack.vue'; import { mapMutations } from 'vuex'; import SnackbarQueue from '/imports/client/ui/components/snackbars/SnackbarQueue.vue'; -import { getUserTier } from '/imports/api/users/patreon/tiers.js'; import ConnectionBanner from '/imports/client/ui/layouts/ConnectionBanner.vue'; export default { @@ -95,9 +94,8 @@ export default { meteor: { darkMode() { let user = Meteor.user(); - if (!user) return; - let tier = getUserTier(user); - return tier.paidBenefits && user.darkMode; + if (!user) return null; + return user.darkMode; }, }, watch: { @@ -106,6 +104,9 @@ export default { handler(newDarkModeValue) { if (typeof newDarkModeValue === 'boolean') { this.$vuetify.theme.dark = newDarkModeValue; + } else { + const deviceDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + this.$vuetify.theme.dark = !!deviceDarkMode; } }, }, @@ -113,6 +114,12 @@ export default { this.$store.commit('setPageTitle', to.meta && to.meta.title || 'DiceCloud'); } }, + mounted() { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + if (typeof this.darkMode === 'boolean') return; + this.$vuetify.theme.dark = !!e.matches; + }); + }, methods: { ...mapMutations([ 'toggleDrawer', diff --git a/app/imports/client/ui/pages/Account.vue b/app/imports/client/ui/pages/Account.vue index 5f196ce8..807428cd 100644 --- a/app/imports/client/ui/pages/Account.vue +++ b/app/imports/client/ui/pages/Account.vue @@ -20,15 +20,18 @@ - + Preferences - @@ -260,7 +263,7 @@ return user && user.emails; }, darkMode(){ - return this.user && this.tier.paidBenefits && this.user.darkMode; + return this.user && this.user.darkMode; }, invites(){ let usernames = {}; @@ -342,8 +345,16 @@ Meteor.logout(); router.push('/'); }, - setDarkMode(value, ack){ - Meteor.users.setDarkMode.call({darkMode: !!value}, ack); + setDarkMode(value, ack) { + let darkMode; + if (value === 'true') { + darkMode = true; + } else if (value === 'false') { + darkMode = false; + } else if (value === 'unset') { + darkMode = null; + } + Meteor.users.setDarkMode.call({darkMode}, ack); }, swapAbilityScoresAndModifiers(value, ack){ Meteor.users.setPreference.call({