瀏覽代碼

fix: dark mode handling

Nicolas Giard 6 年之前
父節點
當前提交
74aa09f39c

+ 2 - 2
client/components/admin.vue

@@ -22,7 +22,7 @@
             v-list-tile-avatar: v-icon insert_drive_file
             v-list-tile-title {{ $t('admin:pages.title') }}
             v-list-tile-action
-              v-chip(small, disabled, color='grey lighten-4')
+              v-chip(small, disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
                 .caption.grey--text 123
           v-list-tile(to='/theme')
             v-list-tile-avatar: v-icon palette
@@ -36,7 +36,7 @@
             v-list-tile-avatar: v-icon perm_identity
             v-list-tile-title {{ $t('admin:users.title') }}
             v-list-tile-action
-              v-chip(small, disabled, color='grey lighten-4')
+              v-chip(small, disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
                 .caption.grey--text 1
           v-divider.my-2
           v-subheader.pl-4 {{ $t('admin:nav.modules') }}

+ 4 - 2
client/components/admin/admin-contribute.vue

@@ -22,12 +22,12 @@
             v-subheader {{ $t('admin:contribute.fundOurWork') }}
             .body-1.pl-3 {{ $t('admin:contribute.openCollective') }}
             v-card-actions.ml-2
-              v-btn(outline, color='primary', href='https://opencollective.com/wikijs')
+              v-btn(outline, :color='darkMode ? `blue lighten-1` : `primary`', href='https://opencollective.com/wikijs')
                 v-icon(left) local_atm
                 span {{ $t('admin:contribute.makeADonation') }}
             .body-1.mt-3.pl-3 {{ $t('admin:contribute.tshirts') }}
             v-card-actions.ml-2
-              v-btn(outline, color='primary', href='https://wikijs.threadless.com')
+              v-btn(outline, :color='darkMode ? `blue lighten-1` : `primary`', href='https://wikijs.threadless.com')
                 v-icon(left) shopping_cart
                 span {{ $t('admin:contribute.shop') }}
             v-divider.mt-3
@@ -94,6 +94,7 @@
 
 <script>
 import _ from 'lodash'
+import { get } from 'vuex-pathify'
 
 import groupsQuery from 'gql/admin/contribute/contribute-query-contributors.gql'
 
@@ -109,6 +110,7 @@ export default {
     }
   },
   computed: {
+    darkMode: get('site/dark'),
     sponsors() {
       return _.filter(this.contributors, ['tier', 'sponsors'])
     },

+ 1 - 1
client/components/common/nav-header.vue

@@ -19,7 +19,7 @@
     v-menu(open-on-hover, offset-y, bottom, left, min-width='250')
       v-toolbar-side-icon.btn-animate-app(slot='activator')
         v-icon view_module
-      v-list(dense, :light='!$vuetify.dark').py-0
+      v-list(dense, :light='!$vuetify.dark', :dark='$vuetify.dark', :class='$vuetify.dark ? `grey darken-4` : ``').py-0
         v-list-tile(avatar, href='/')
           v-list-tile-avatar: v-icon(color='blue') home
           v-list-tile-content Home

+ 5 - 2
client/components/common/page-selector.vue

@@ -13,7 +13,7 @@
           v-show='searchLoading'
           )
       .d-flex(style='min-height:400px;')
-        v-flex(xs4).grey.lighten-3
+        v-flex(xs4).grey(:class='darkMode ? `darken-4` : `lighten-3`')
           v-toolbar(color='grey darken-3', dark, dense, flat)
             .body-2 Folders
             v-spacer
@@ -50,7 +50,7 @@
             v-list-tile
               v-list-tile-avatar: v-icon insert_drive_file
               v-list-tile-title File D
-      v-card-text.grey.lighten-1.pa-2
+      v-card-text.grey.pa-2(:class='darkMode ? `darken-3-d5` : `lighten-1`')
         v-text-field(
           solo
           hide-details
@@ -68,6 +68,8 @@
 </template>
 
 <script>
+import { get } from 'vuex-pathify'
+
 export default {
   props: {
     value: {
@@ -88,6 +90,7 @@ export default {
     }
   },
   computed: {
+    darkMode: get('site/dark'),
     isShown: {
       get() { return this.value },
       set(val) { this.$emit('input', val) }

+ 2 - 1
client/components/editor.vue

@@ -1,5 +1,5 @@
 <template lang="pug">
-  .editor
+  v-app.editor(:dark='darkMode')
     nav-header(dense)
       template(slot='actions')
         v-btn(
@@ -159,6 +159,7 @@ export default {
     }
   },
   computed: {
+    darkMode: get('site/dark'),
     mode: get('editor/mode'),
     notification: get('notification'),
     notificationState: sync('notification@isActive')

+ 4 - 0
client/components/editor/editor-markdown.vue

@@ -305,6 +305,10 @@ export default {
     height: calc(100vh - 112px);
     overflow: hidden;
 
+    @at-root .theme--dark & {
+      background-color: mc('grey', '900');
+    }
+
     @include until($tablet) {
       display: none;
     }

+ 3 - 2
client/components/editor/editor-modal-properties.vue

@@ -44,7 +44,7 @@
           v-model='description'
           )
       v-divider
-      v-card-text.grey.lighten-5
+      v-card-text.grey(:class='darkMode ? `darken-3-d3` : `lighten-5`')
         v-subheader.pl-0 Path &amp; Categorization
         v-container.pa-0(fluid, grid-list-lg)
           v-layout(row, wrap)
@@ -84,7 +84,7 @@
           persistent-hint
           )
       v-divider
-      v-card-text.pb-5.grey.lighten-4
+      v-card-text.pb-5.grey(:class='darkMode ? `darken-3-d5` : `lighten-4`')
         v-subheader.pl-0 Publishing State
         v-container.pa-0(fluid, grid-list-lg)
           v-layout(row, wrap)
@@ -206,6 +206,7 @@ export default {
     }
   },
   computed: {
+    darkMode: get('site/dark'),
     mode: get('editor/mode'),
     title: sync('page/title'),
     description: sync('page/description'),

+ 2 - 3
client/components/history.vue

@@ -108,12 +108,11 @@
 <script>
 import { Diff2Html } from 'diff2html'
 import { createPatch } from 'diff'
+import { get } from 'vuex-pathify'
 import _ from 'lodash'
 
 import historyTrailQuery from 'gql/history/history-trail-query.gql'
 
-/* global siteConfig */
-
 export default {
   props: {
     pageId: {
@@ -145,7 +144,7 @@ export default {
     }
   },
   computed: {
-    darkMode() { return siteConfig.darkMode },
+    darkMode: get('site/dark'),
     diffs() {
       return createPatch(`/${this.path}`, this.sourceText, this.targetText)
     },

+ 8 - 3
client/components/source.vue

@@ -9,7 +9,7 @@
         v-btn.ml-4(depressed, color='blue darken-1', @click='goLive') Return to Normal View
       v-card(tile)
         v-card-text
-          v-card.grey.lighten-4.radius-7(flat)
+          v-card.grey.radius-7(flat, :class='darkMode ? `darken-4` : `lighten-4`')
             v-card-text
               pre
                 code
@@ -19,7 +19,7 @@
 </template>
 
 <script>
-/* global siteConfig */
+import { get } from 'vuex-pathify'
 
 export default {
   props: {
@@ -40,7 +40,7 @@ export default {
     return {}
   },
   computed: {
-    darkMode() { return siteConfig.darkMode }
+    darkMode: get('site/dark')
   },
   created () {
     this.$store.commit('page/SET_ID', this.id)
@@ -67,6 +67,11 @@ export default {
     font-weight: 400;
     font-size: 1rem;
 
+    @at-root .theme--dark.source pre > code {
+      background-color: mc('grey', '900');
+      color: mc('grey', '400');
+    }
+
     &::before {
       display: none;
     }

+ 27 - 0
client/scss/base/base.scss

@@ -25,3 +25,30 @@ html {
     border-radius: #{$i}px;
   }
 }
+
+@for $i from 1 through 5 {
+  .grey.darken-2-d#{$i} {
+    background-color: darken(mc('grey', '700'), percentage($i/100)) !important;
+    border-color: darken(mc('grey', '700'), percentage($i/100)) !important;
+  }
+  .grey.darken-2-l#{$i} {
+    background-color: lighten(mc('grey', '700'), percentage($i/100)) !important;
+    border-color: lighten(mc('grey', '700'), percentage($i/100)) !important;
+  }
+  .grey.darken-3-d#{$i} {
+    background-color: darken(mc('grey', '800'), percentage($i/100)) !important;
+    border-color: darken(mc('grey', '800'), percentage($i/100)) !important;
+  }
+  .grey.darken-3-l#{$i} {
+    background-color: lighten(mc('grey', '800'), percentage($i/100)) !important;
+    border-color: lighten(mc('grey', '800'), percentage($i/100)) !important;
+  }
+  .grey.darken-4-d#{$i} {
+    background-color: darken(mc('grey', '900'), percentage($i/100)) !important;
+    border-color: darken(mc('grey', '900'), percentage($i/100)) !important;
+  }
+  .grey.darken-4-l#{$i} {
+    background-color: lighten(mc('grey', '900'), percentage($i/100)) !important;
+    border-color: lighten(mc('grey', '900'), percentage($i/100)) !important;
+  }
+}

+ 1 - 32
client/scss/base/material.scss

@@ -322,7 +322,7 @@ $material-colors: (
   )
 );
 
-@function material-color($color-name, $color-variant: '500') {
+@function mc($color-name, $color-variant: '500') {
   $color: map-get(map-get($material-colors, $color-name),$color-variant);
   @if $color {
 	@return $color;
@@ -331,34 +331,3 @@ $material-colors: (
 	@warn "=> ERROR: COLOR NOT FOUND! <= | Your $color-name, $color-variant combination did not match any of the values in the $material-colors map.";
   }
 }
-
-@function mc($color-name, $color-variant: '500') {
-	@return material-color($color-name, $color-variant);
-}
-
-/**
- * Material Elevation
- */
-@mixin md-elevation-0 {
-  box-shadow: none !important;
-}
-
-@mixin md-elevation-1 {
-  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2) !important;
-}
-
-@mixin md-elevation-2 {
-  box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3) !important;
-}
-
-@mixin md-elevation-3 {
-  box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.3) !important;
-}
-
-@mixin md-elevation-4 {
-  box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.3) !important;
-}
-
-@mixin md-elevation-5 {
-  box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.3) !important;
-}

+ 16 - 13
client/themes/default/components/page.vue

@@ -1,7 +1,8 @@
 <template lang="pug">
-  v-app(v-scroll='upBtnScroll')
+  v-app(v-scroll='upBtnScroll', :dark='darkMode')
     nav-header
-    v-navigation-drawer.primary(
+    v-navigation-drawer(
+      :class='darkMode ? `grey darken-3` : `primary`'
       dark
       app
       clipped
@@ -12,12 +13,12 @@
       v-model='navShown'
       )
       vue-scroll(:ops='scrollStyle')
-        nav-sidebar
+        nav-sidebar(:color='darkMode ? `grey darken-3` : `primary`')
           slot(name='sidebar')
 
     v-content
       template(v-if='path !== `home`')
-        v-toolbar(color='grey lighten-3', flat, dense)
+        v-toolbar(:color='darkMode ? `grey darken-4-d3` : `grey lighten-3`', flat, dense)
           v-btn.pl-0(v-if='$vuetify.breakpoint.xsOnly', flat, @click='toggleNavigation')
             v-icon(color='grey darken-2', left) menu
             span Navigation
@@ -36,19 +37,19 @@
         v-divider
       v-layout(row)
         v-flex(xs12, lg9, xl10)
-          v-toolbar(color='grey lighten-4', flat, :height='90')
+          v-toolbar(:color='darkMode ? `grey darken-4` : `grey lighten-4`', flat, :height='90')
             div
-              .headline.grey--text.text--darken-3 {{title}}
+              .headline.grey--text(:class='darkMode ? `text-lighten-2` : `text--darken-3`') {{title}}
               .caption.grey--text.text--darken-1 {{description}}
           v-divider
           .contents(ref='container')
             slot(name='contents')
 
         v-flex(lg3, xl2, fill-height, v-if='$vuetify.breakpoint.lgAndUp')
-          v-toolbar(color='grey lighten-4', flat, :height='90')
+          v-toolbar(:color='darkMode ? `grey darken-4` : `grey lighten-4`', flat, :height='90')
             div
               .caption.grey--text.text--lighten-1 Last edited by
-              .body-2.grey--text.text--darken-3 {{ authorName }}
+              .body-2.grey--text(:class='darkMode ? `` : `text--darken-3`') {{ authorName }}
               .caption.grey--text.text--darken-1 {{ updatedAt | moment('calendar') }}
             v-spacer
             v-tooltip(left)
@@ -57,8 +58,8 @@
               span Edit Page
           v-divider
           template(v-if='toc.length')
-            v-list.grey.lighten-3.pb-3(dense)
-              v-subheader.pl-4.primary--text Table of contents
+            v-list.grey.pb-3(dense, :class='darkMode ? `darken-3-d3` : `lighten-3`')
+              v-subheader.pl-4(:class='darkMode ? `blue--text text--lighten-1` : `primary--text`') Table of contents
               template(v-for='(tocItem, tocIdx) in toc')
                 v-list-tile(@click='$vuetify.goTo(tocItem.anchor, scrollOpts)')
                   v-icon(color='grey') arrow_right
@@ -70,7 +71,7 @@
                     v-list-tile-title.pl-3.caption {{tocSubItem.title}}
                   v-divider(inset, v-if='tocIdx < toc.length - 1')
             v-divider
-          v-list.grey.lighten-4(dense)
+          v-list.grey(dense, :class='darkMode ? `darken-3` : `lighten-4`')
             v-subheader.pl-4.yellow--text.text--darken-4 Rating
             .text-xs-center
               v-rating(
@@ -82,7 +83,7 @@
               )
               .pb-2.caption.grey--text 5 votes
           v-divider
-          v-list.grey.lighten-3(dense)
+          v-list.grey(dense, :class='darkMode ? `darken-3-d3` : `lighten-3`')
             v-subheader.pl-4.teal--text Tags
             v-list-tile
               v-list-tile-avatar: v-icon(color='teal') label
@@ -96,7 +97,7 @@
               v-list-tile-avatar: v-icon(color='teal') label
               v-list-tile-title Planets
           v-divider
-          v-toolbar(color='grey lighten-4', flat, dense)
+          v-toolbar(:color='darkMode ? `grey darken-3` : `grey lighten-4`', flat, dense)
             v-spacer
             v-tooltip(bottom)
               v-btn(icon, slot='activator'): v-icon(color='grey') bookmark
@@ -117,6 +118,7 @@
 <script>
 import { StatusIndicator } from 'vue-status-indicator'
 import Prism from '@/libs/prism/prism.js'
+import { get } from 'vuex-pathify'
 
 export default {
   components: {
@@ -205,6 +207,7 @@ export default {
     }
   },
   computed: {
+    darkMode: get('site/dark'),
     navShown: {
       get() { return this.navOpen || this.$vuetify.breakpoint.smAndUp },
       set(val) { this.navOpen = val }

+ 57 - 0
client/themes/default/scss/app.scss

@@ -4,6 +4,10 @@
   color: mc('grey', '800');
   padding-bottom: 50px;
 
+  @at-root .theme--dark & {
+    color: mc('grey', '300');
+  }
+
   // ---------------------------------
   // HEADERS
   // ---------------------------------
@@ -34,6 +38,10 @@
     margin-top: 2rem;
     position: relative;
 
+    @at-root .theme--dark & {
+      color: mc('blue', '500');
+    }
+
     &::after {
       content: '';
       position: absolute;
@@ -54,6 +62,10 @@
     color: mc('grey', '800');
     position: relative;
 
+    @at-root .theme--dark & {
+      color: mc('grey', '500');
+    }
+
     &::after {
       content: '';
       position: absolute;
@@ -62,6 +74,10 @@
       width: 100%;
       height: 1px;
       background: linear-gradient(to right, mc('grey', '700'), rgba(mc('grey', '700'), 0));
+
+      @at-root .theme--dark & {
+        background: linear-gradient(to right, mc('grey', '300'), rgba(mc('grey', '700'), 0));
+      }
     }
 
     & + h3 {
@@ -74,6 +90,10 @@
     color: mc('grey', '700');
     position: relative;
 
+    @at-root .theme--dark & {
+      color: mc('grey', '600');
+    }
+
     &::after {
       content: '';
       position: absolute;
@@ -100,6 +120,10 @@
     height: 1px;
     border: none;
     background-color: mc('grey', '400');
+
+    @at-root .theme--dark & {
+      background-color: mc('grey', '700');
+    }
   }
 
   blockquote {
@@ -118,6 +142,13 @@
         background-color: mc('blue', '50');
         color: mc('blue', '800');
       }
+
+      @at-root .theme--dark & {
+        background-color: mc('blue', '900');
+        background-image: radial-gradient(ellipse at top, mc('blue', '900'), darken(mc('blue', '900'), 5%));
+        border-color: mc('blue', '500');
+        box-shadow: 0 0 2px 0 mc('grey', '900');
+      }
     }
     &.is-warning {
       background-color: mc('orange', '50');
@@ -129,6 +160,13 @@
         background-color: mc('orange', '50');
         color: mc('orange', '800');
       }
+
+      @at-root .theme--dark & {
+        background-color: mc('orange', '900');
+        background-image: radial-gradient(ellipse at top, mc('orange', '900'), darken(mc('orange', '900'), 5%));
+        border-color: mc('orange', '500');
+        box-shadow: 0 0 2px 0 mc('grey', '900');
+      }
     }
     &.is-danger {
       background-color: mc('red', '50');
@@ -140,6 +178,13 @@
         background-color: mc('red', '50');
         color: mc('red', '800');
       }
+
+      @at-root .theme--dark & {
+        background-color: mc('red', '900');
+        background-image: radial-gradient(ellipse at top, mc('red', '900'), darken(mc('red', '900'), 5%));
+        border-color: mc('red', '500');
+        box-shadow: 0 0 2px 0 mc('grey', '900');
+      }
     }
     &.is-success {
       background-color: mc('green', '50');
@@ -151,6 +196,13 @@
         background-color: mc('green', '50');
         color: mc('green', '800');
       }
+
+      @at-root .theme--dark & {
+        background-color: mc('green', '900');
+        background-image: radial-gradient(ellipse at top, mc('green', '900'), darken(mc('green', '900'), 5%));
+        border-color: mc('green', '500');
+        box-shadow: 0 0 2px 0 mc('grey', '900');
+      }
     }
   }
 
@@ -235,6 +287,11 @@
         font-size: .8rem;
         line-height: 1rem;
         text-align: center;
+
+        @at-root .theme--dark & {
+          background-color: mc('grey', '900');
+          border-color: mc('grey', '700');
+        }
       }
 
       &[checked] + label::before  {

+ 3 - 3
server/models/pages.js

@@ -238,13 +238,13 @@ module.exports = class Page extends Model {
       creatorId: page.creatorId,
       creatorName: page.creatorName,
       description: page.description,
-      isPrivate: page.isPrivate === 1,
-      isPublished: page.isPublished === 1,
+      isPrivate: page.isPrivate === 1 || page.isPrivate === true,
+      isPublished: page.isPublished === 1 || page.isPublished === true,
       publishEndDate: page.publishEndDate,
       publishStartDate: page.publishStartDate,
       render: page.render,
       title: page.title,
-      toc: page.toc,
+      toc: _.isString(page.toc) ? page.toc : JSON.stringify(page.toc),
       updatedAt: page.updatedAt
     }))
   }

+ 12 - 13
server/views/editor.pug

@@ -2,16 +2,15 @@ extends master.pug
 
 block body
   #root
-    v-app
-      editor(
-        :page-id=page.id
-        locale=page.localeCode
-        path=page.path
-        title=page.title
-        description=page.description
-        tags=page.tags
-        :is-published=page.isPublished
-        init-mode=page.mode
-        init-editor=page.editorKey
-        init-content=page.content
-        )
+    editor(
+      :page-id=page.id
+      locale=page.localeCode
+      path=page.path
+      title=page.title
+      description=page.description
+      tags=page.tags
+      :is-published=page.isPublished
+      init-mode=page.mode
+      init-editor=page.editorKey
+      init-content=page.content
+      )

+ 1 - 1
server/views/page.pug

@@ -14,7 +14,7 @@ block body
       updated-at=page.updatedAt
       author-name=page.authorName
       :author-id=page.authorId
-      :is-published=page.isPublished
+      :is-published=page.isPublished.toString()
       :toc=page.toc
       )
       template(slot='sidebar')

+ 8 - 0
wiki.js

@@ -126,6 +126,8 @@ const init = {
     await global.WIKI.queue.quit()
     console.warn(chalk.yellow('--- Closing Server connections...'))
     global.WIKI.server.destroy(() => {
+      console.warn(chalk.yellow('--- Purging node modules cache...'))
+
       global.WIKI = {}
       Object.keys(require.cache).forEach(id => {
         if (/[/\\]server[/\\]/.test(id)) {
@@ -137,6 +139,12 @@ const init = {
           delete module.constructor._pathCache[cacheKey]
         }
       })
+
+      console.warn(chalk.yellow('--- Unregistering process listeners...'))
+
+      process.removeAllListeners('unhandledRejection')
+      process.removeAllListeners('uncaughtException')
+
       require('./server')
     })
   }