From f2fea7f3cd5a131f994ad9bc1d2b4833865dd165 Mon Sep 17 00:00:00 2001 From: syuilo <syuilotan@yahoo.co.jp> Date: Fri, 20 Apr 2018 03:41:24 +0900 Subject: [PATCH] [wip] darkmode --- src/client/app/boot.js | 8 +++++ src/client/app/desktop/script.ts | 25 ++++++++++++++ src/client/app/desktop/style.styl | 3 ++ .../desktop/views/components/notes.note.vue | 34 +++++++++++-------- .../app/desktop/views/components/notes.vue | 16 ++++++--- .../app/desktop/views/components/settings.vue | 16 ++++++--- .../app/desktop/views/components/timeline.vue | 16 ++++++--- .../desktop/views/components/ui.header.vue | 4 +-- .../views/components/widget-container.vue | 23 +++++++++---- .../app/desktop/views/components/window.vue | 22 +++++++----- src/client/app/init.css | 7 ++++ 11 files changed, 130 insertions(+), 44 deletions(-) diff --git a/src/client/app/boot.js b/src/client/app/boot.js index a0709842b9..ac90fda05f 100644 --- a/src/client/app/boot.js +++ b/src/client/app/boot.js @@ -62,6 +62,14 @@ app = isMobile ? 'mobile' : 'desktop'; } + // Dark/Light + const me = JSON.parse(localStorage.getItem('me') || null); + if (me && me.clientSettings) { + if ((app == 'desktop' && me.clientSettings.dark) || (app == 'mobile' && me.clientSettings.darkMobile)) { + document.documentElement.setAttribute('data-darkmode', 'true'); + } + } + // Script version const ver = localStorage.getItem('v') || VERSION; diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts index b3152e708b..ba7a64ff22 100644 --- a/src/client/app/desktop/script.ts +++ b/src/client/app/desktop/script.ts @@ -2,6 +2,7 @@ * Desktop Client */ +import Vue from 'vue'; import VueRouter from 'vue-router'; // Style @@ -43,6 +44,30 @@ init(async (launch) => { require('./views/components'); require('./views/widgets'); + // Dark/Light + Vue.mixin({ + mounted() { + const set = () => { + if (!this.$el || !this.os || !this.os.i) return; + if (this.os.i.clientSettings.dark) { + document.documentElement.setAttribute('data-darkmode', 'true'); + this.$el.setAttribute('data-darkmode', 'true'); + } else { + document.documentElement.removeAttribute('data-darkmode'); + this.$el.removeAttribute('data-darkmode'); + } + }; + + set(); + + this.$watch('os.i.clientSettings', i => { + set(); + }, { + deep: true + }); + } + }); + // Init router const router = new VueRouter({ mode: 'history', diff --git a/src/client/app/desktop/style.styl b/src/client/app/desktop/style.styl index 49f71fbde7..6c83cad2b1 100644 --- a/src/client/app/desktop/style.styl +++ b/src/client/app/desktop/style.styl @@ -44,6 +44,9 @@ html height 100% background #f7f7f7 + &[data-darkmode] + background #191B22 + body display flex flex-direction column diff --git a/src/client/app/desktop/views/components/notes.note.vue b/src/client/app/desktop/views/components/notes.note.vue index 873d724b25..6a12071537 100644 --- a/src/client/app/desktop/views/components/notes.note.vue +++ b/src/client/app/desktop/views/components/notes.note.vue @@ -291,11 +291,11 @@ export default Vue.extend({ <style lang="stylus" scoped> @import '~const.styl' -.note +root(isDark) margin 0 padding 0 - background #fff - border-bottom solid 1px #eaeaea + background isDark ? #282C37 : #fff + border-bottom solid 1px isDark ? #1c2023 : #eaeaea &:first-child border-top-left-radius 6px @@ -374,7 +374,7 @@ export default Vue.extend({ &:hover > .main > footer > button - color #888 + color isDark ? #707b97 : #888 > .avatar-anchor display block @@ -407,7 +407,7 @@ export default Vue.extend({ margin 0 .5em 0 0 padding 0 overflow hidden - color #627079 + color isDark ? #fff : #627079 font-size 1em font-weight bold text-decoration none @@ -426,7 +426,7 @@ export default Vue.extend({ > .username margin 0 .5em 0 0 - color #ccc + color isDark ? #606984 : #ccc > .info margin-left auto @@ -443,7 +443,7 @@ export default Vue.extend({ border-right solid 1px #eaeaea > .created-at - color #c0c0c0 + color isDark ? #606984 : #c0c0c0 > .body @@ -454,7 +454,7 @@ export default Vue.extend({ padding 0 overflow-wrap break-word font-size 1.1em - color #717171 + color isDark ? #fff : #717171 >>> .title display block @@ -462,7 +462,7 @@ export default Vue.extend({ padding 4px font-size 90% text-align center - background #eef1f3 + background isDark ? #2f3944 : #eef1f3 border-radius 4px >>> .code @@ -471,12 +471,12 @@ export default Vue.extend({ >>> .quote margin 8px padding 6px 12px - color #aaa - border-left solid 3px #eee + color isDark ? #6f808e : #aaa + border-left solid 3px isDark ? #637182 : #eee > .reply margin-right 8px - color #717171 + color isDark ? #99abbf : #717171 > .rp margin-left 4px @@ -547,13 +547,13 @@ export default Vue.extend({ padding 0 8px line-height 32px font-size 1em - color #ddd + color isDark ? #606984 : #ddd background transparent border none cursor pointer &:hover - color #666 + color isDark ? #9198af : #666 > .count display inline @@ -572,6 +572,12 @@ export default Vue.extend({ padding-top 4px background rgba(0, 0, 0, 0.0125) +.note[data-darkmode] + root(true) + +.note:not([data-darkmode]) + root(false) + </style> <style lang="stylus" module> diff --git a/src/client/app/desktop/views/components/notes.vue b/src/client/app/desktop/views/components/notes.vue index b5f6957a16..14834f0962 100644 --- a/src/client/app/desktop/views/components/notes.vue +++ b/src/client/app/desktop/views/components/notes.vue @@ -50,17 +50,16 @@ export default Vue.extend({ </script> <style lang="stylus" scoped> -.mk-notes - +root(isDark) > .date display block margin 0 line-height 32px font-size 14px text-align center - color #aaa - background #fdfdfd - border-bottom solid 1px #eaeaea + color isDark ? #666b79 : #aaa + background isDark ? #242731 : #fdfdfd + border-bottom solid 1px isDark ? #1c2023 : #eaeaea span margin 0 16px @@ -86,4 +85,11 @@ export default Vue.extend({ &:active background #eee + +.mk-notes[data-darkmode] + root(true) + +.mk-notes:not([data-darkmode]) + root(false) + </style> diff --git a/src/client/app/desktop/views/components/settings.vue b/src/client/app/desktop/views/components/settings.vue index f9d9bab187..ffa82b9e02 100644 --- a/src/client/app/desktop/views/components/settings.vue +++ b/src/client/app/desktop/views/components/settings.vue @@ -37,14 +37,17 @@ <section class="web" v-show="page == 'web'"> <h1>デザインと表示</h1> <div class="div"> - <button class="ui button" @click="customizeHome">ホームをカスタマイズ</button> + <button class="ui button" @click="customizeHome" style="margin-bottom: 16px">ホームをカスタマイズ</button> + </div> + <div class="div"> + <mk-switch v-model="os.i.clientSettings.dark" @change="onChangeDark" text="ダークモード"/> + <mk-switch v-model="os.i.clientSettings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/> </div> <mk-switch v-model="os.i.clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/> <mk-switch v-model="os.i.clientSettings.showReplyTarget" @change="onChangeShowReplyTarget" text="リプライ先を表示する"/> <mk-switch v-model="os.i.clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開"> <span>位置情報が添付された投稿のマップを自動的に展開します。</span> </mk-switch> - <mk-switch v-model="os.i.clientSettings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/> </section> <section class="web" v-show="page == 'web'"> @@ -298,6 +301,12 @@ export default Vue.extend({ autoWatch: v }); }, + onChangeDark(v) { + (this as any).api('i/update_client_setting', { + name: 'dark', + value: v + }); + }, onChangeShowPostFormOnTopOfTl(v) { (this as any).api('i/update_client_setting', { name: 'showPostFormOnTopOfTl', @@ -431,7 +440,6 @@ export default Vue.extend({ > .web > .div border-bottom solid 1px #eee - padding 0 0 16px 0 - margin 0 0 16px 0 + margin 16px 0 </style> diff --git a/src/client/app/desktop/views/components/timeline.vue b/src/client/app/desktop/views/components/timeline.vue index c99fabcc60..12f928d15d 100644 --- a/src/client/app/desktop/views/components/timeline.vue +++ b/src/client/app/desktop/views/components/timeline.vue @@ -66,14 +66,16 @@ export default Vue.extend({ <style lang="stylus" scoped> @import '~const.styl' -.mk-timeline - background #fff +root(isDark) + background isDark ? #282C37 : #fff border solid 1px rgba(0, 0, 0, 0.075) border-radius 6px > header padding 0 8px z-index 10 + background isDark ? #313543 : #fff + border-radius 6px 6px 0 0 box-shadow 0 1px rgba(0, 0, 0, 0.08) > span @@ -99,10 +101,16 @@ export default Vue.extend({ background $theme-color &:not([data-is-active]) - color #6f7477 + color isDark ? #9aa2a7 : #6f7477 cursor pointer &:hover - color #525a5f + color isDark ? #d9dcde : #525a5f + +.mk-timeline[data-darkmode] + root(true) + +.mk-timeline:not([data-darkmode]) + root(false) </style> diff --git a/src/client/app/desktop/views/components/ui.header.vue b/src/client/app/desktop/views/components/ui.header.vue index 2b63030cd2..96c26367f5 100644 --- a/src/client/app/desktop/views/components/ui.header.vue +++ b/src/client/app/desktop/views/components/ui.header.vue @@ -169,10 +169,10 @@ root(isDark) > .mk-ui-header-search display none -.header[data-is-darkmode] +.header[data-darkmode] root(true) -.header +.header:not([data-darkmode]) root(false) </style> diff --git a/src/client/app/desktop/views/components/widget-container.vue b/src/client/app/desktop/views/components/widget-container.vue index 188a67313e..c3fac1399d 100644 --- a/src/client/app/desktop/views/components/widget-container.vue +++ b/src/client/app/desktop/views/components/widget-container.vue @@ -34,8 +34,8 @@ export default Vue.extend({ </script> <style lang="stylus" scoped> -.mk-widget-container - background #fff +root(isDark) + background isDark ? #282C37 : #fff border solid 1px rgba(0, 0, 0, 0.075) border-radius 6px overflow hidden @@ -45,6 +45,8 @@ export default Vue.extend({ border none !important > header + background isDark ? #313543 : #fff + > .title z-index 1 margin 0 @@ -52,7 +54,7 @@ export default Vue.extend({ line-height 42px font-size 0.9em font-weight bold - color #888 + color isDark ? #e3e5e8 : #888 box-shadow 0 1px rgba(0, 0, 0, 0.07) > [data-fa] @@ -70,16 +72,23 @@ export default Vue.extend({ width 42px font-size 0.9em line-height 42px - color #ccc + color isDark ? #9baec8 : #ccc &:hover - color #aaa + color isDark ? #b2c1d5 : #aaa &:active - color #999 + color isDark ? #b2c1d5 : #999 &.withGradient > .title - background linear-gradient(to bottom, #fff, #ececec) + background isDark ? linear-gradient(to bottom, #313543, #1d2027) : linear-gradient(to bottom, #fff, #ececec) box-shadow 0 1px rgba(#000, 0.11) + +.mk-widget-container[data-darkmode] + root(true) + +.mk-widget-container:not([data-darkmode]) + root(false) + </style> diff --git a/src/client/app/desktop/views/components/window.vue b/src/client/app/desktop/views/components/window.vue index e2cab21799..3de1413ac4 100644 --- a/src/client/app/desktop/views/components/window.vue +++ b/src/client/app/desktop/views/components/window.vue @@ -465,7 +465,7 @@ export default Vue.extend({ <style lang="stylus" scoped> @import '~const.styl' -.mk-window +root(isDark) display block > .bg @@ -559,7 +559,7 @@ export default Vue.extend({ > .body height 100% overflow hidden - background #fff + background isDark ? #282C37 : #fff border-radius 6px box-shadow 0 2px 6px 0 rgba(0, 0, 0, 0.2) @@ -571,12 +571,12 @@ export default Vue.extend({ overflow hidden white-space nowrap cursor move - background #fff + background isDark ? #313543 : #fff border-radius 6px 6px 0 0 box-shadow 0 1px 0 rgba(#000, 0.1) &.withGradient - background linear-gradient(to bottom, #fff, #ececec) + background isDark ? linear-gradient(to bottom, #313543, #1d2027) : linear-gradient(to bottom, #fff, #ececec) box-shadow 0 1px 0 rgba(#000, 0.15) &, * @@ -593,7 +593,7 @@ export default Vue.extend({ font-size 1em line-height $header-height font-weight normal - color #666 + color isDark ? #e3e5e8 : #666 > div:last-child position absolute @@ -608,16 +608,16 @@ export default Vue.extend({ padding 0 cursor pointer font-size 1em - color rgba(#000, 0.4) + color isDark ? #9baec8 : rgba(#000, 0.4) border none outline none background transparent &:hover - color rgba(#000, 0.6) + color isDark ? #b2c1d5 : rgba(#000, 0.6) &:active - color darken(#000, 30%) + color isDark ? #b2c1d5 : darken(#000, 30%) > [data-fa] padding 0 @@ -632,4 +632,10 @@ export default Vue.extend({ > .main > .body > .content height calc(100% - 40px) +.mk-window[data-darkmode] + root(true) + +.mk-window:not([data-darkmode]) + root(false) + </style> diff --git a/src/client/app/init.css b/src/client/app/init.css index 2587f63943..fa59195f71 100644 --- a/src/client/app/init.css +++ b/src/client/app/init.css @@ -56,6 +56,13 @@ body > noscript { animation-delay: 0.32s; } +html[data-darkmode] #ini { + background: #191b22; +} + html[data-darkmode] #ini > p { + color: #fff; + } + @keyframes ini { 0%, 80%, 100% { opacity: 1;