Skip to content

Commit

Permalink
Add: Storybookにテーマが適用されるように (VOICEVOX#2299)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hiroshiba Kazuyuki <[email protected]>
  • Loading branch information
3 people authored Oct 20, 2024
1 parent ce0a0ae commit b0d8c2e
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 82 deletions.
41 changes: 40 additions & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { markdownItPlugin } from "@/plugins/markdownItPlugin";

import "@quasar/extras/material-icons/material-icons.css";
import "quasar/dist/quasar.sass";
import "../src/styles/_index.scss";
import "@/styles/_index.scss";
import { UnreachableError } from "@/type/utility";
import { setThemeToCss, setFontToCss } from "@/domain/dom";
import { themes } from "@/domain/theme";

setup((app) => {
app.use(Quasar, {
Expand Down Expand Up @@ -61,6 +64,42 @@ const preview: Preview = {
defaultTheme: "light",
attributeName: "is-dark-theme",
}),

// テーマの設定をCSSへ反映する
() => {
let observer: MutationObserver | undefined = undefined;
return {
async mounted() {
setFontToCss("default");

const root = document.documentElement;
let lastIsDark: boolean | undefined = undefined;
observer = new MutationObserver(() => {
const isDark = root.getAttribute("is-dark-theme") === "true";
if (lastIsDark === isDark) return;
lastIsDark = isDark;

const theme = themes.find((theme) => theme.isDark === isDark);
if (!theme)
throw new UnreachableError("assert: theme !== undefined");

setThemeToCss(theme);
});

observer.observe(root, {
attributes: true,
attributeFilter: ["is-dark-theme"],
});
},
unmounted() {
if (observer) {
observer.disconnect();
}
},

template: `<story />`,
};
},
],
argTypesEnhancers: [addActionsWithEmits],
};
Expand Down
18 changes: 0 additions & 18 deletions public/themes/dark.json

This file was deleted.

18 changes: 0 additions & 18 deletions public/themes/default.json

This file was deleted.

11 changes: 0 additions & 11 deletions src/backend/browser/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
EngineSettings,
HotkeySettingType,
Sandbox,
ThemeConf,
} from "@/type/preload";
import { AssetTextFileNames } from "@/type/staticResources";

Expand Down Expand Up @@ -245,16 +244,6 @@ export const api: Sandbox = {
// TODO: Impl
return;
},
async getAvailableThemes() {
// NOTE: Electron版では起動時にテーマ情報が必要なので、
// この実装とは違って起動時に読み込んだキャッシュを返すだけになっている。
return Promise.all(
// FIXME: themeファイルのいい感じのパスの設定
["/themes/default.json", "/themes/dark.json"].map((url) =>
fetch(url).then((res) => res.json() as Promise<ThemeConf>),
),
);
},
vuexReady() {
// NOTE: 何もしなくて良さそう
return Promise.resolve();
Expand Down
20 changes: 1 addition & 19 deletions src/backend/electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { EngineAndVvppController } from "./engineAndVvppController";
import { failure, success } from "@/type/result";
import { AssetTextFileNames } from "@/type/staticResources";
import {
ThemeConf,
EngineInfo,
SystemError,
defaultHotkeySettings,
Expand All @@ -40,6 +39,7 @@ import {
EngineId,
TextAsset,
} from "@/type/preload";
import { themes } from "@/domain/theme";

type SingleInstanceLockData = {
filePath: string | undefined;
Expand Down Expand Up @@ -226,20 +226,6 @@ function checkMultiEngineEnabled(): boolean {
return enabled;
}

// テーマの読み込み
const themes = readThemeFiles();
function readThemeFiles() {
const themes: ThemeConf[] = [];
const dir = path.join(__static, "themes");
for (const file of fs.readdirSync(dir)) {
const theme = JSON.parse(
fs.readFileSync(path.join(dir, file)).toString(),
) as ThemeConf;
themes.push(theme);
}
return themes;
}

const appState = {
willQuit: false,
};
Expand Down Expand Up @@ -652,10 +638,6 @@ registerIpcMainHandle<IpcMainHandle>({
}
},

GET_AVAILABLE_THEMES: () => {
return themes;
},

OPEN_LOG_DIRECTORY: () => {
void shell.openPath(app.getPath("logs"));
},
Expand Down
4 changes: 0 additions & 4 deletions src/backend/electron/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,6 @@ const api: Sandbox = {
void ipcRendererInvokeProxy.SET_NATIVE_THEME(source);
},

getAvailableThemes: () => {
return ipcRendererInvokeProxy.GET_AVAILABLE_THEMES();
},

vuexReady: () => {
void ipcRendererInvokeProxy.ON_VUEX_READY();
},
Expand Down
41 changes: 41 additions & 0 deletions src/domain/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ThemeConf } from "@/type/preload";

const light = {
name: "Default",
displayName: "デフォルト",
order: 1,
isDark: false,
colors: {
primary: "#A5D4AD",
display: "#121212",
"display-on-primary": "#121212",
"display-hyperlink": "#0969DA",
background: "#FFFFFF",
surface: "#EEEEEE",
warning: "#C10015",
"text-splitter-hover": "#CCDDFF",
"active-point-focus": "#E0EAFF",
"active-point-hover": "#EEF3FF",
},
} as const satisfies ThemeConf;

const dark = {
name: "Dark",
displayName: "ダーク",
order: 2,
isDark: true,
colors: {
primary: "#86C591",
display: "#E1E1E1",
"display-on-primary": "#1F1F1F",
"display-hyperlink": "#58A6FF",
background: "#1F1F1F",
surface: "#2B2B2B",
warning: "#F27483",
"text-splitter-hover": "#394152",
"active-point-focus": "#292F38",
"active-point-hover": "#272A2F",
},
} as const satisfies ThemeConf;

export const themes = [light, dark];
3 changes: 2 additions & 1 deletion src/store/setting.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SettingStoreState, SettingStoreTypes } from "./type";
import { createDotNotationUILockAction as createUILockAction } from "./ui";
import { createDotNotationPartialStore as createPartialStore } from "./vuex";
import { themes } from "@/domain/theme";
import {
showAlertDialog,
showQuestionDialog,
Expand Down Expand Up @@ -83,7 +84,7 @@ export const settingStore = createPartialStore<SettingStoreTypes>({
});

mutations.SET_AVAILABLE_THEMES({
themes: await window.backend.getAvailableThemes(),
themes,
});
void actions.SET_CURRENT_THEME_SETTING({
currentTheme: await window.backend.getSetting("currentTheme"),
Expand Down
4 changes: 4 additions & 0 deletions src/store/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@ export const uiStore = createPartialStore<UiStoreTypes>({
},
},

/**
* 選択可能なテーマをセットする。
* NOTE: カスタムテーマが導入された場合を見越して残している。
*/
SET_AVAILABLE_THEMES: {
mutation(state, { themes }) {
state.availableThemes = themes;
Expand Down
10 changes: 7 additions & 3 deletions src/styles/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
// 優先度を強引に上げる
body:not(#dummy) {
user-select: none;
border-left: solid #{vars.$window-border-width} #{colors.$splitter};
border-right: solid #{vars.$window-border-width} #{colors.$splitter};
border-bottom: solid #{vars.$window-border-width} #{colors.$splitter};
color: colors.$display;
background: colors.$background;

// Storybookでは枠線を付けない
&:not(.sb-show-main) {
border-left: solid #{vars.$window-border-width} #{colors.$splitter};
border-right: solid #{vars.$window-border-width} #{colors.$splitter};
border-bottom: solid #{vars.$window-border-width} #{colors.$splitter};
}
}

body[data-editor-font="default"] {
Expand Down
6 changes: 0 additions & 6 deletions src/type/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
MessageBoxReturnValue,
NativeThemeType,
TextAsset,
ThemeConf,
ToolbarSettingType,
} from "@/type/preload";
import { AltPortInfos } from "@/store/type";
Expand Down Expand Up @@ -169,11 +168,6 @@ export type IpcIHData = {
return: ToolbarSettingType;
};

GET_AVAILABLE_THEMES: {
args: [];
return: ThemeConf[];
};

ON_VUEX_READY: {
args: [];
return: void;
Expand Down
1 change: 0 additions & 1 deletion src/type/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ export interface Sandbox {
getDefaultHotkeySettings(): Promise<HotkeySettingType[]>;
getDefaultToolbarSetting(): Promise<ToolbarSettingType>;
setNativeTheme(source: NativeThemeType): void;
getAvailableThemes(): Promise<ThemeConf[]>;
vuexReady(): void;
getSetting<Key extends keyof ConfigType>(key: Key): Promise<ConfigType[Key]>;
setSetting<Key extends keyof ConfigType>(
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b0d8c2e

Please sign in to comment.