From 54b2843e69645ed29431a6b346edc1401d2b6102 Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Fri, 2 Feb 2024 17:08:19 +0000 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E3=82=AB=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=A0CSS=E3=81=AE=E3=83=90=E3=83=83=E3=82=AF=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E6=A9=9F=E8=83=BD=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backup-and-syncing-custom-css/backup.vue | 257 ++++++++++++++++++ .../backup-and-syncing-custom-css/main.vue | 27 ++ packages/frontend/src/pages/tms/flags.vue | 4 + 3 files changed, 288 insertions(+) create mode 100644 packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue create mode 100644 packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue new file mode 100644 index 000000000000..1e5eb68860d5 --- /dev/null +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -0,0 +1,257 @@ + + + + + + + diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue new file mode 100644 index 000000000000..b8c66eac2039 --- /dev/null +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/frontend/src/pages/tms/flags.vue b/packages/frontend/src/pages/tms/flags.vue index 38015c91e7c0..a45b88615e31 100644 --- a/packages/frontend/src/pages/tms/flags.vue +++ b/packages/frontend/src/pages/tms/flags.vue @@ -15,6 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.tsx._tms._flags.warning({ name: instance.name ?? host }) }} {{ i18n.ts._tms.reportIssuesToGithub }} {{ i18n.ts.learnMore }} +
{{ i18n.ts._tms.taiymeSettings }}
@@ -43,6 +44,9 @@ import TmsSoftwareVersions from '@/components/TmsSoftwareVersions.vue'; const XMain = defineAsyncComponent(() => import('@/pages/tms/flags.main.vue')); const xMain = shallowRef | null>(null); +const XBackupAndSyncingCustomCss = defineAsyncComponent(() => import('@/pages/tms/backup-and-syncing-custom-css/main.vue')); +const backupAndSyncingCustomCss = shallowRef | null>(null); + definePageMetadata(() => ({ title: i18n.ts._tms._flags.title, icon: 'ti ti-flask', From 7307edc468748fd78fc200b05d7b0f5dced6bad4 Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Sun, 4 Feb 2024 10:58:05 +0000 Subject: [PATCH 02/11] fix: fix css style --- .../src/pages/tms/backup-and-syncing-custom-css/backup.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue index 1e5eb68860d5..7ea98e9e9c85 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -246,11 +246,11 @@ defineExpose({ cursor: pointer; border: var(--panelBorder); - >.name { + > .name { font-weight: 700; } - >.time { + > .time { font-size: 0.85em; opacity: 0.7; } From cef62651682b72ae66d53604a084c036f946ad10 Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Mon, 5 Feb 2024 17:53:54 +0000 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=E3=82=AB=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=A0CSS=E3=81=AE=E5=90=8C=E6=9C=9F=E6=A9=9F=E8=83=BD?= =?UTF-8?q?=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 113 ++++++++++++++ locales/ja-JP.yml | 29 ++++ packages/backend/src/server/web/boot.js | 1 + packages/frontend/src/_dev_boot_.ts | 1 + packages/frontend/src/boot/common.ts | 36 ++++- .../src/pages/settings/custom-css.vue | 35 ++++- .../backup-and-syncing-custom-css/backup.vue | 146 +++++++++++++++--- .../backup-and-syncing-custom-css/main.vue | 39 +++-- .../backup-and-syncing-custom-css/sync.vue | 80 ++++++++++ .../frontend/src/pages/tms/flags.main.vue | 8 +- packages/frontend/src/pages/tms/flags.vue | 8 +- packages/frontend/src/pages/tms/settings.vue | 6 +- .../src/pages/tms/waitTmsStoreLoaded.ts | 4 + packages/frontend/src/tms/flask-store.ts | 8 + 14 files changed, 461 insertions(+), 53 deletions(-) create mode 100644 packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue create mode 100644 packages/frontend/src/pages/tms/waitTmsStoreLoaded.ts diff --git a/locales/index.d.ts b/locales/index.d.ts index 4bcee2962b3b..06be08f14618 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9704,6 +9704,119 @@ export interface Locale extends ILocale { * {x}を開く */ readonly "openX": ParameterizedString<"x">; + readonly "_backupAndSyncingCustomCss": { + /** + * カスタムCSSのバックアップと同期 + */ + readonly "title": string; + readonly "_backup": { + /** + * カスタムCSSのバックアップ + */ + readonly "title": string; + /** + * 現在のカスタムCSSをバックアップとしてサーバーに保存することが可能です。 + */ + readonly "description": string; + /** + * バックアップがありません。「新規作成」で現在適用されているカスタムCSSのバックアップを作成できます。 + */ + readonly "notfound": string; + /** + * 作成日時: {datetime} + */ + readonly "createdAt": ParameterizedString<"datetime">; + /** + * バックアップの読み込みに失敗しました。 + */ + readonly "cannnotLoad": string; + /** + * バックアップファイルはjson形式である必要があります。 + */ + readonly "invalidFile": string; + /** + * バックアップIDが不正です。 + */ + readonly "invalidId": string; + /** + * バックアップ名が不正です。 + */ + readonly "invalidName": string; + /** + * バックアップのカスタムCSSが不正です。 + */ + readonly "invalidCustomCss": string; + /** + * カスタムCSSが設定されていません + */ + readonly "noCustomCss": string; + /** + * カスタムCSSを設定されていない状態ではバックアップを作成できません。 + */ + readonly "noCustomCssDescription": string; + /** + * バックアップ名を入力 + */ + readonly "inputBackupName": string; + /** + * カスタムCSSのバックアップを適用 + */ + readonly "applyBackup": string; + /** + * カスタムCSSのバックアップ「{name}」を適用しますか? + */ + readonly "applyBackupDescription": ParameterizedString<"name">; + /** + * カスタムCSSを設定されていない状態では上書き保存できません。 + * カスタムCSSのバックアップを削除する場合はメニューから「削除」を選択してください。 + */ + readonly "cannotOverrideEmpty": string; + /** + * カスタムCSSのバックアップを上書き保存 + */ + readonly "overrideBackup": string; + /** + * カスタムCSSのバックアップ「{name}」を上書き保存しますか? + * この操作は取り消せません。 + */ + readonly "overrideBackupDescription": ParameterizedString<"name">; + /** + * カスタムCSSのバックアップを削除 + */ + readonly "deleteBackup": string; + /** + * カスタムCSSのバックアップ「{name}」を削除しますか? + * この操作は取り消せません。 + */ + readonly "deleteBackupDescription": ParameterizedString<"name">; + /** + * 上書き保存 + */ + readonly "override": string; + }; + readonly "_syncing": { + /** + * カスタムCSSの同期 + */ + readonly "title": string; + /** + * カスタムCSSの同期を有効化すると、カスタムCSSの変更がリアルタイムに同期されます。 + */ + readonly "description": string; + /** + * カスタムCSSの同期を有効化 + */ + readonly "enable": string; + /** + * 同期するカスタムCSSを選択 + */ + readonly "select": string; + /** + * 任意のカスタムCSSのバックアップを他のデバイスとの間で同期することができます。 + */ + readonly "selectDescription": string; + }; + }; }; }; } diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index dcfadc7323d4..8b7866891125 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2588,3 +2588,32 @@ _tms: warning: "これらの設定を有効にすると、ページの表示や挙動に深刻な影響を及ぼし、{name}が正常に利用できなくなる可能性があります。" forceFetchX: "{x}を強制取得" openX: "{x}を開く" + _backupAndSyncingCustomCss: + title: "カスタムCSSのバックアップと同期" + _backup: + title: "カスタムCSSのバックアップ" + description: "現在のカスタムCSSをバックアップとしてサーバーに保存することが可能です。" + notfound: "バックアップがありません。「新規作成」で現在適用されているカスタムCSSのバックアップを作成できます。" + createdAt: "作成日時: {datetime}" + cannnotLoad: "バックアップの読み込みに失敗しました。" + invalidFile: "バックアップファイルはjson形式である必要があります。" + invalidId: "バックアップIDが不正です。" + invalidName: "バックアップ名が不正です。" + invalidCustomCss: "バックアップのカスタムCSSが不正です。" + noCustomCss: "カスタムCSSが設定されていません" + noCustomCssDescription: "カスタムCSSを設定されていない状態ではバックアップを作成できません。" + inputBackupName: "バックアップ名を入力" + applyBackup: "カスタムCSSのバックアップを適用" + applyBackupDescription: "カスタムCSSのバックアップ「{name}」を適用しますか?" + cannotOverrideEmpty: "カスタムCSSを設定されていない状態では上書き保存できません。\nカスタムCSSのバックアップを削除する場合はメニューから「削除」を選択してください。" + overrideBackup: "カスタムCSSのバックアップを上書き保存" + overrideBackupDescription: "カスタムCSSのバックアップ「{name}」を上書き保存しますか?\nこの操作は取り消せません。" + deleteBackup: "カスタムCSSのバックアップを削除" + deleteBackupDescription: "カスタムCSSのバックアップ「{name}」を削除しますか?\nこの操作は取り消せません。" + override: "上書き保存" + _syncing: + title: "カスタムCSSの同期" + description: "カスタムCSSの同期を有効化すると、カスタムCSSの変更がリアルタイムに同期されます。" + enable: "カスタムCSSの同期を有効化" + select: "同期するカスタムCSSを選択" + selectDescription: "任意のカスタムCSSのバックアップを他のデバイスとの間で同期することができます。" diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index c6b52a7a6bd7..69eb93a97b99 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -146,6 +146,7 @@ if (customCss && customCss.length > 0) { const style = document.createElement('style'); style.innerHTML = customCss; + style.id = 'customCss'; document.head.appendChild(style); } diff --git a/packages/frontend/src/_dev_boot_.ts b/packages/frontend/src/_dev_boot_.ts index d01a957048ec..9164b1db1eaf 100644 --- a/packages/frontend/src/_dev_boot_.ts +++ b/packages/frontend/src/_dev_boot_.ts @@ -86,6 +86,7 @@ async function main() { if (customCss && customCss.length > 0) { const style = document.createElement('style'); style.innerHTML = customCss; + style.id = 'customCss'; document.head.appendChild(style); } } diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index b7c1f7800cf0..4918c0da84f4 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -5,6 +5,7 @@ import { computed, watch, version as vueVersion, App } from 'vue'; import { compareVersions } from 'compare-versions'; +import type { CustomCSSBackup } from '@/pages/tms/backup-and-syncing-custom-css/backup.vue'; import widgets from '@/widgets/index.js'; import directives from '@/directives/index.js'; import components from '@/components/index.js'; @@ -25,6 +26,8 @@ import { fetchCustomEmojis } from '@/custom-emojis.js'; import { setupRouter } from '@/global/router/definition.js'; import { tmsFlaskStore } from '@/tms/flask-store.js'; import { tmsStore } from '@/tms/store.js'; +import { useStream } from '@/stream.js'; +import { misskeyApi } from '@/scripts/misskey-api.js'; export async function common(createVue: () => App) { console.info(`Misskey v${version}`); @@ -123,10 +126,10 @@ export async function common(createVue: () => App) { html.setAttribute('lang', lang); //#endregion - await defaultStore.ready; - await deckStore.ready; - await tmsStore.ready; - await tmsFlaskStore.ready; + await defaultStore.loaded; + await deckStore.loaded; + await tmsStore.loaded; + await tmsFlaskStore.loaded; const fetchInstanceMetaPromise = fetchInstance(); @@ -210,6 +213,31 @@ export async function common(createVue: () => App) { } }, { immediate: true }); + // tms custom css syncing + const enabledCustomCssSyncing = tmsFlaskStore.state.enabledCustomCssSyncing; + if (enabledCustomCssSyncing) { + const syncingCustomCssId = tmsFlaskStore.state.syncingCustomCssId; + const connection = useStream().useChannel('main'); + const scope = ['tms', 'customCssBackups'] as const satisfies string[]; + + connection.on('registryUpdated', ({ scope: recievedScope, key, value }) => { + if (!recievedScope || scope.length !== recievedScope.length || scope.some((v, i) => v !== recievedScope[i])) { + return; + } + if (key !== syncingCustomCssId) { + return; + } + + const customCss = (value as CustomCSSBackup).customCss; + miLocalStorage.setItem('customCss', customCss); + + const styleDom = document.querySelector('style#customCss'); + if (styleDom) { + styleDom.innerHTML = customCss; + } + }); + } + // Keep screen on const onVisibilityChange = () => document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { diff --git a/packages/frontend/src/pages/settings/custom-css.vue b/packages/frontend/src/pages/settings/custom-css.vue index 5c12ab81e750..987f46baa19d 100644 --- a/packages/frontend/src/pages/settings/custom-css.vue +++ b/packages/frontend/src/pages/settings/custom-css.vue @@ -15,6 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue index ce92d99a6d06..39e8c99c7d95 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -301,7 +301,10 @@ const menu = (ev: MouseEvent, backupId: string) => { icon: 'ti ti-forms', action: () => renameBackup(backupId), }, { - text: '上書き保存', + text: i18n.ts._tms._flags._backupAndSyncingCustomCss._backup.preview, + icon: 'ti ti-eye-code', + action: () => preview(backupId), + }, { text: i18n.ts._tms._flags._backupAndSyncingCustomCss._backup.override, icon: 'ti ti-device-floppy', action: () => overrideBackup(backupId), diff --git a/packages/frontend/src/tms/popup.ts b/packages/frontend/src/tms/popup.ts new file mode 100644 index 000000000000..2cdfe5d09e66 --- /dev/null +++ b/packages/frontend/src/tms/popup.ts @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { BUNDLED_LANGUAGES, type Lang as ShikiLangs } from 'shiki'; +import { popup } from '@/os.js'; +import TmsCodePreviewDialog from '@/components/TmsCodePreviewDialog.vue'; +import { getHighlighter } from '@/scripts/code-highlighter.js'; + +type CodePreviewProps = { + lang?: ShikiLangs | 'aiscript'; + code: string; +}; +export const codePreview = async (props: CodePreviewProps): Promise => { + return new Promise(async (resolve) => { + const highlighter = await getHighlighter(); + let codeLang: CodePreviewProps['lang'] = undefined; + if (props.lang && !highlighter.getLoadedLanguages().includes(props.lang as ShikiLangs)) { + const bundles = BUNDLED_LANGUAGES.filter((lang) => lang.id === props.lang || lang.aliases?.includes(props.lang as ShikiLangs)); + if (bundles.length > 0) { + await highlighter.loadLanguage(props.lang as ShikiLangs); + codeLang = props.lang; + } + } else { + codeLang = props.lang; + } + const html = highlighter.codeToHtml(props.code, { + lang: codeLang, + }); + + popup(TmsCodePreviewDialog, { html }, { + done: () => { + resolve(); + }, + }, 'closed'); + }); +}; From 999d380769db48f5a65a18a3c91c19846b0dd79f Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Mon, 5 Feb 2024 19:58:23 +0000 Subject: [PATCH 05/11] =?UTF-8?q?change:=20MkCode=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E3=81=86=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/TmsCodePreviewDialog.vue | 45 +++++++++---------- .../backup-and-syncing-custom-css/backup.vue | 1 + packages/frontend/src/tms/popup.ts | 21 ++------- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/packages/frontend/src/components/TmsCodePreviewDialog.vue b/packages/frontend/src/components/TmsCodePreviewDialog.vue index 09b5c32e16bc..7dec5fd4ce32 100644 --- a/packages/frontend/src/components/TmsCodePreviewDialog.vue +++ b/packages/frontend/src/components/TmsCodePreviewDialog.vue @@ -4,16 +4,24 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue index 39e8c99c7d95..145c1ca21bf7 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -281,6 +281,7 @@ const preview = async (backupId: string) => { } await codePreview({ + name: backup.name, lang: 'css', code: backup.customCss, }); diff --git a/packages/frontend/src/tms/popup.ts b/packages/frontend/src/tms/popup.ts index 2cdfe5d09e66..f38c1cc73cb0 100644 --- a/packages/frontend/src/tms/popup.ts +++ b/packages/frontend/src/tms/popup.ts @@ -3,33 +3,18 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { BUNDLED_LANGUAGES, type Lang as ShikiLangs } from 'shiki'; +import { type BundledLanguage as ShikiLangs } from 'shiki'; import { popup } from '@/os.js'; import TmsCodePreviewDialog from '@/components/TmsCodePreviewDialog.vue'; -import { getHighlighter } from '@/scripts/code-highlighter.js'; type CodePreviewProps = { + name: string; lang?: ShikiLangs | 'aiscript'; code: string; }; export const codePreview = async (props: CodePreviewProps): Promise => { return new Promise(async (resolve) => { - const highlighter = await getHighlighter(); - let codeLang: CodePreviewProps['lang'] = undefined; - if (props.lang && !highlighter.getLoadedLanguages().includes(props.lang as ShikiLangs)) { - const bundles = BUNDLED_LANGUAGES.filter((lang) => lang.id === props.lang || lang.aliases?.includes(props.lang as ShikiLangs)); - if (bundles.length > 0) { - await highlighter.loadLanguage(props.lang as ShikiLangs); - codeLang = props.lang; - } - } else { - codeLang = props.lang; - } - const html = highlighter.codeToHtml(props.code, { - lang: codeLang, - }); - - popup(TmsCodePreviewDialog, { html }, { + popup(TmsCodePreviewDialog, props, { done: () => { resolve(); }, From 8b7ed9bcccdb8309436821b8d699bc97b594e87e Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Thu, 8 Feb 2024 04:35:52 +0000 Subject: [PATCH 06/11] =?UTF-8?q?chore:=20tweak=20changed=E3=83=95?= =?UTF-8?q?=E3=83=A9=E3=82=B0=E3=81=8C=E6=AD=A3=E3=81=97=E3=81=8F=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=95=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=20=E3=83=90=E3=83=83=E3=82=AF=E3=82=A2=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=81=AE=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BF=E6=99=82=E3=81=AB?= =?UTF-8?q?ID=E3=81=8C=E3=81=AA=E3=81=84=E5=A0=B4=E5=90=88=E3=81=A8?= =?UTF-8?q?=E6=97=A2=E5=AD=98=E3=81=AE=E3=82=82=E3=81=AE=E3=81=A8=E8=A1=9D?= =?UTF-8?q?=E7=AA=81=E3=81=97=E3=81=9F=E9=9A=9B=E3=81=AB=E6=96=B0=E8=A6=8F?= =?UTF-8?q?=E7=94=9F=E6=88=90=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=20=E3=83=90=E3=83=83=E3=82=AF=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=81=AE=E6=9B=B4=E6=96=B0=E6=97=A5=E6=99=82?= =?UTF-8?q?=E3=82=92=E8=A8=98=E9=8C=B2=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 4 ---- locales/ja-JP.yml | 1 - .../tms/backup-and-syncing-custom-css/backup.vue | 14 +++++++++----- .../tms/backup-and-syncing-custom-css/sync.vue | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index 8d4496f3b757..c8a87fedbe4e 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9742,10 +9742,6 @@ export interface Locale extends ILocale { * バックアップファイルはjson形式である必要があります。 */ readonly "invalidFile": string; - /** - * バックアップIDが不正です。 - */ - readonly "invalidId": string; /** * バックアップ名が不正です。 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 67e5c0344212..7277ad6a9cfa 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2599,7 +2599,6 @@ _tms: createdAt: "作成日時: {datetime}" cannnotLoad: "バックアップの読み込みに失敗しました。" invalidFile: "バックアップファイルはjson形式である必要があります。" - invalidId: "バックアップIDが不正です。" invalidName: "バックアップ名が不正です。" invalidCustomCss: "バックアップのカスタムCSSが不正です。" noCustomCss: "カスタムCSSが設定されていません" diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue index 145c1ca21bf7..9b9c5d2e8dca 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -43,6 +43,7 @@ export type CustomCSSBackup = { id: string; name: string; createAt: string; + updatedAt: string; customCss: string; }; export type CustomCSSBackups = CustomCSSBackup[]; @@ -74,6 +75,7 @@ const saveNew = async () => { id: v4(), name, createAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), customCss: miLocalStorage.getItem('customCss') ?? '', }; @@ -141,11 +143,8 @@ const upload = async () => { const validate = (json: { [key: string]: unknown }): { valid: true, value: CustomCSSBackup } | { valid: false, error: string } => { const uuidv4Matcher = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/; - if ('id' in json && (typeof json.id !== 'string' || !uuidv4Matcher.test(json.id))) { - return { - valid: false, - error: i18n.ts._tms._flags._backupAndSyncingCustomCss._backup.invalidId, - }; + if ('id' in json && (typeof json.id !== 'string' || !uuidv4Matcher.test(json.id) || customCssBackups.value.some((b) => b.id === json.id))) { + json.id = v4(); } if ('name' in json && typeof json.name !== 'string') { return { @@ -156,6 +155,9 @@ const validate = (json: { [key: string]: unknown }): { valid: true, value: Custo if ('createAt' in json && typeof json.createAt !== 'string') { json.createAt = new Date().toISOString(); } + if ('updatedAt' in json && typeof json.updatedAt !== 'string') { + json.updatedAt = new Date().toISOString(); + } if ('customCss' in json && (typeof json.customCss !== 'string' || json.customCss.length === 0)) { return { valid: false, @@ -203,6 +205,7 @@ const renameBackup = async (backupId: string) => { return; } + backup.updatedAt = new Date().toISOString(); backup.name = name; await apiWithDialog('i/registry/set', { @@ -238,6 +241,7 @@ const overrideBackup = async (backupId: string) => { return; } + backup.updatedAt = new Date().toISOString(); backup.customCss = customCss; await apiWithDialog('i/registry/set', { diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue index a4edff925c67..f24a5f85c381 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue @@ -65,7 +65,7 @@ watch([ selected, ], () => { edited.value = true; - changed.value = true; + changed.value = tmsFlaskStore.state.enabledCustomCssSyncing !== enabled.value || tmsFlaskStore.state.syncingCustomCssId !== selected.value; }, { deep: true }); defineProps<{ From 4613772fb91d1bb2e4ffbc2c927389e0137a8104 Mon Sep 17 00:00:00 2001 From: CaffeinePower Date: Thu, 8 Feb 2024 05:25:40 +0000 Subject: [PATCH 07/11] =?UTF-8?q?MkFolder=E3=82=92=E3=82=84=E3=82=81?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 4 --- locales/ja-JP.yml | 1 - .../backup-and-syncing-custom-css/backup.vue | 1 - .../backup-and-syncing-custom-css/main.vue | 33 +++++++++---------- .../frontend/src/pages/tms/flags.main.vue | 4 +-- 5 files changed, 16 insertions(+), 27 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index c8a87fedbe4e..c34881bd4e5f 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9713,10 +9713,6 @@ export interface Locale extends ILocale { */ readonly "openX": ParameterizedString<"x">; readonly "_backupAndSyncingCustomCss": { - /** - * カスタムCSSのバックアップと同期 - */ - readonly "title": string; readonly "_backup": { /** * カスタムCSSのバックアップ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7277ad6a9cfa..ddc5077854e4 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2591,7 +2591,6 @@ _tms: forceFetchX: "{x}を強制取得" openX: "{x}を開く" _backupAndSyncingCustomCss: - title: "カスタムCSSのバックアップと同期" _backup: title: "カスタムCSSのバックアップ" description: "現在のカスタムCSSをバックアップとしてサーバーに保存することが可能です。" diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue index 9b9c5d2e8dca..9b62350f5e7f 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/backup.vue @@ -352,7 +352,6 @@ defineExpose({ .profile { padding: 20px; cursor: pointer; - border: var(--panelBorder); > .name { font-weight: 700; diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue index e0bd21f381a6..173f08bc6044 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue @@ -4,25 +4,22 @@ SPDX-License-Identifier: AGPL-3.0-only --> +} + diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue index 173f08bc6044..4cab1cedd4ae 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/main.vue @@ -26,7 +26,6 @@ SPDX-License-Identifier: AGPL-3.0-only import { defineAsyncComponent, shallowRef } from 'vue'; import { i18n } from '@/i18n.js'; import FormSection from '@/components/form/section.vue'; -import MkFolder from '@/components/MkFolder.vue'; import MkButton from '@/components/MkButton.vue'; const XBackup = defineAsyncComponent(() => import('@/pages/tms/backup-and-syncing-custom-css/backup.vue')); diff --git a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue index f24a5f85c381..0463884084c7 100644 --- a/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue +++ b/packages/frontend/src/pages/tms/backup-and-syncing-custom-css/sync.vue @@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only