From 0a64f638c64ff41075ec95d0305a196c7366a55a Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 27 Sep 2018 01:32:04 +0900
Subject: [PATCH] wip

---
 src/client/app/app.vue                        |  8 ++++++-
 src/client/app/common/scripts/theme.ts        | 21 +++++++++++++++++--
 .../app/common/views/components/menu.vue      | 18 +++++-----------
 .../views/components/reaction-picker.vue      | 20 ++++++------------
 .../views/components/visibility-chooser.vue   |  2 +-
 .../app/desktop/views/components/home.vue     |  2 +-
 .../desktop/views/components/ui.header.vue    |  2 +-
 src/client/theme/dark.json                    | 10 +++++++--
 src/client/theme/halloween.json               | 17 +++++++++++++++
 src/client/theme/light.json                   |  6 ++++++
 10 files changed, 71 insertions(+), 35 deletions(-)
 create mode 100644 src/client/theme/halloween.json

diff --git a/src/client/app/app.vue b/src/client/app/app.vue
index bb8377c237..9b6af27ece 100644
--- a/src/client/app/app.vue
+++ b/src/client/app/app.vue
@@ -7,13 +7,15 @@ import Vue from 'vue';
 import { url, lang } from './config';
 import applyTheme from './common/scripts/theme';
 const darkTheme = require('../theme/dark');
+const halloweenTheme = require('../theme/halloween');
 
 export default Vue.extend({
 	computed: {
 		keymap(): any {
 			return {
 				'h|slash': this.help,
-				'd': this.dark
+				'd': this.dark,
+				'x': this.test
 			};
 		}
 	},
@@ -25,6 +27,10 @@ export default Vue.extend({
 
 		dark() {
 			applyTheme(darkTheme);
+		},
+
+		test() {
+			applyTheme(halloweenTheme);
 		}
 	}
 });
diff --git a/src/client/app/common/scripts/theme.ts b/src/client/app/common/scripts/theme.ts
index 2cad547c01..a08028ff9a 100644
--- a/src/client/app/common/scripts/theme.ts
+++ b/src/client/app/common/scripts/theme.ts
@@ -1,6 +1,23 @@
 import * as tinycolor from 'tinycolor2';
+const lightTheme = require('../../../theme/light');
+const darkTheme = require('../../../theme/dark');
+
+type Theme = {
+	meta: {
+		id: string;
+		name: string;
+		inherit: string;
+	};
+} & {
+	[key: string]: string;
+};
+
+export default function(theme: Theme) {
+	if (theme.meta.inherit) {
+		const inherit = [lightTheme, darkTheme].find(x => x.meta.id == theme.meta.inherit);
+		theme = Object.assign({}, inherit, theme);
+	}
 
-export default function(theme: { [key: string]: string }) {
 	const props = compile(theme);
 
 	Object.entries(props).forEach(([k, v]) => {
@@ -11,7 +28,7 @@ export default function(theme: { [key: string]: string }) {
 	localStorage.setItem('theme', JSON.stringify(props));
 }
 
-function compile(theme: { [key: string]: string }): { [key: string]: string } {
+function compile(theme: Theme): { [key: string]: string } {
 	function getColor(code: string): tinycolor.Instance {
 		// ref
 		if (code[0] == '@') {
diff --git a/src/client/app/common/views/components/menu.vue b/src/client/app/common/views/components/menu.vue
index 3b9f07d1ee..be2c03f54c 100644
--- a/src/client/app/common/views/components/menu.vue
+++ b/src/client/app/common/views/components/menu.vue
@@ -117,10 +117,8 @@ export default Vue.extend({
 </script>
 
 <style lang="stylus" scoped>
-
-
-root(isDark)
-	$bg-color = isDark ? #2c303c : #fff
+.onchrpzrvnoruiaenfcqvccjfuupzzwv
+	$bg-color = var(--popupBg)
 	$border-color = rgba(27, 31, 35, 0.15)
 
 	position initial
@@ -132,7 +130,7 @@ root(isDark)
 		z-index 10000
 		width 100%
 		height 100%
-		background rgba(#000, isDark ? 0.5 : 0.1)
+		background var(--modalBackdrop)
 		opacity 0
 
 	> .popover
@@ -179,7 +177,7 @@ root(isDark)
 			display block
 			padding 8px 16px
 			width 100%
-			color isDark ? #d6dce2 : #111
+			color var(--popupFg)
 
 			&:hover
 				color var(--primaryForeground)
@@ -193,12 +191,6 @@ root(isDark)
 		> div
 			margin 8px 0
 			height 1px
-			background isDark ? #1c2023 : #eee
-
-.onchrpzrvnoruiaenfcqvccjfuupzzwv[data-darkmode]
-	root(true)
-
-.onchrpzrvnoruiaenfcqvccjfuupzzwv:not([data-darkmode])
-	root(false)
+			background var(--faceDivider)
 
 </style>
diff --git a/src/client/app/common/views/components/reaction-picker.vue b/src/client/app/common/views/components/reaction-picker.vue
index a86850ac7c..13e8cf1f07 100644
--- a/src/client/app/common/views/components/reaction-picker.vue
+++ b/src/client/app/common/views/components/reaction-picker.vue
@@ -210,11 +210,9 @@ export default Vue.extend({
 </script>
 
 <style lang="stylus" scoped>
-
-
 $border-color = rgba(27, 31, 35, 0.15)
 
-root(isDark)
+.mk-reaction-picker
 	position initial
 
 	> .backdrop
@@ -224,11 +222,11 @@ root(isDark)
 		z-index 10000
 		width 100%
 		height 100%
-		background isDark ? rgba(#000, 0.4) : rgba(#000, 0.1)
+		background var(--modalBackdrop)
 		opacity 0
 
 	> .popover
-		$bgcolor = isDark ? #2c303c : #fff
+		$bgcolor = var(--popupBg)
 		position absolute
 		z-index 10001
 		background $bgcolor
@@ -281,8 +279,8 @@ root(isDark)
 			margin 0
 			padding 8px 10px
 			font-size 14px
-			color isDark ? #d6dce2 : #586069
-			border-bottom solid 1px isDark ? #1c2023 : #e1e4e8
+			color var(--popupFg)
+			border-bottom solid 1px var(--faceDivider)
 
 		> div
 			padding 4px
@@ -312,16 +310,10 @@ root(isDark)
 				border-radius 2px
 
 				&:hover
-					background isDark ? #252731 : #eee
+					background var(--reactionPickerButtonHoverBg)
 
 				&:active
 					background var(--primary)
 					box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
 
-.mk-reaction-picker[data-darkmode]
-	root(true)
-
-.mk-reaction-picker:not([data-darkmode])
-	root(false)
-
 </style>
diff --git a/src/client/app/common/views/components/visibility-chooser.vue b/src/client/app/common/views/components/visibility-chooser.vue
index d0a892fd56..5faf09fa11 100644
--- a/src/client/app/common/views/components/visibility-chooser.vue
+++ b/src/client/app/common/views/components/visibility-chooser.vue
@@ -145,7 +145,7 @@ root(isDark)
 		opacity 0
 
 	> .popover
-		$bgcolor = isDark ? #2c303c : #fff
+		$bgcolor = var(--popupBg)
 		position absolute
 		z-index 10001
 		width 240px
diff --git a/src/client/app/desktop/views/components/home.vue b/src/client/app/desktop/views/components/home.vue
index 3d77da52d9..a07af02ea6 100644
--- a/src/client/app/desktop/views/components/home.vue
+++ b/src/client/app/desktop/views/components/home.vue
@@ -280,7 +280,7 @@ root(isDark)
 		width 100%
 		height 48px
 		color isDark ? #fff : #000
-		background isDark ? #313543 : #f7f7f7
+		background var(--desktopHeaderBg)
 		box-shadow 0 1px 1px rgba(#000, 0.075)
 
 		> a
diff --git a/src/client/app/desktop/views/components/ui.header.vue b/src/client/app/desktop/views/components/ui.header.vue
index bec0ee37ad..264da8bef8 100644
--- a/src/client/app/desktop/views/components/ui.header.vue
+++ b/src/client/app/desktop/views/components/ui.header.vue
@@ -151,7 +151,7 @@ root(isDark)
 			z-index 1000
 			width 100%
 			height 48px
-			background isDark ? #313543 : #f7f7f7
+			background var(--desktopHeaderBg)
 
 		> .main
 			z-index 1001
diff --git a/src/client/theme/dark.json b/src/client/theme/dark.json
index cf9306558b..18b674fef4 100644
--- a/src/client/theme/dark.json
+++ b/src/client/theme/dark.json
@@ -1,16 +1,22 @@
 {
 	"meta": {
+		"id": "9978f7f9-5616-44fd-a704-cc5985efdd63",
 		"name": "Dark"
 	},
 	"primary": "#fb4e4e",
 	"primaryForeground": "#fff",
-	"bg": "#191B22",
-	"scrollbarTrack": "#282C37",
+	"bg": "#191b22",
+	"scrollbarTrack": "#282c37",
 	"scrollbarHandle": "#454954",
 	"scrollbarHandleHover": "#535660",
 	"face": "#282c37",
 	"faceHeader": "#313543",
 	"faceDivider": "rgba(0, 0, 0, 0.3)",
+	"popupBg": "#2c303c",
+	"popupFg": "#d6dce2",
+	"reactionPickerButtonHoverBg": "rgba(0, 0, 0, 0.18)",
+	"modalBackdrop": "rgba(0, 0, 0, 0.5)",
+	"desktopHeaderBg": "#313543",
 	"mobileSignedInAsBg": "#273c34",
 	"mobileSignedInAsFg": "#49ab63",
 	"mobileSignoutBg": "#652222",
diff --git a/src/client/theme/halloween.json b/src/client/theme/halloween.json
new file mode 100644
index 0000000000..d38bd849ed
--- /dev/null
+++ b/src/client/theme/halloween.json
@@ -0,0 +1,17 @@
+{
+	"meta": {
+		"id": "42e4f09b-67d5-498c-af7d-29faa54745b0",
+		"name": "Halloween",
+		"inherit": "9978f7f9-5616-44fd-a704-cc5985efdd63"
+	},
+	"primary": "#fb8d4e",
+	"primaryForeground": "#fff",
+	"bg": "#1b1a35",
+	"face": "#282c37",
+	"faceHeader": "#313543",
+	"faceDivider": "rgba(0, 0, 0, 0.3)",
+	"popupBg": "#2c303c",
+	"popupFg": "#d6dce2",
+	"reactionPickerButtonHoverBg": "rgba(0, 0, 0, 0.18)",
+	"desktopHeaderBg": "#0c0b19"
+}
diff --git a/src/client/theme/light.json b/src/client/theme/light.json
index 64ebd8e293..b012629faf 100644
--- a/src/client/theme/light.json
+++ b/src/client/theme/light.json
@@ -1,5 +1,6 @@
 {
 	"meta": {
+		"id": "406cfea3-a4e7-486c-9057-30ede1353c3f",
 		"name": "Light"
 	},
 	"primary": "#fb4e4e",
@@ -11,6 +12,11 @@
 	"face": "#fff",
 	"faceHeader": "#fff",
 	"faceDivider": "rgba(0, 0, 0, 0.082)",
+	"popupBg": "#fff",
+	"popupFg": "#586069",
+	"reactionPickerButtonHoverBg": "#eee",
+	"modalBackdrop": "rgba(0, 0, 0, 0.1)",
+	"desktopHeaderBg": "#f7f7f7",
 	"mobileSignedInAsBg": "#fcfff5",
 	"mobileSignedInAsFg": "#2c662d",
 	"mobileSignoutBg": "#fff6f5",