diff --git a/src/client/app/app.vue b/src/client/app/app.vue
index bb8377c23..9b6af27ec 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 2cad547c0..a08028ff9 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 3b9f07d1e..be2c03f54 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({
diff --git a/src/client/app/common/views/components/reaction-picker.vue b/src/client/app/common/views/components/reaction-picker.vue
index a86850ac7..13e8cf1f0 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({
diff --git a/src/client/app/common/views/components/visibility-chooser.vue b/src/client/app/common/views/components/visibility-chooser.vue
index d0a892fd5..5faf09fa1 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 3d77da52d..a07af02ea 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 bec0ee37a..264da8bef 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 cf9306558..18b674fef 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 000000000..d38bd849e
--- /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 64ebd8e29..b012629fa 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",