enhance(frontend): ウィジェットの設定項目の多言語対応 (#17032)
* enhance(frontend): ウィジェットの設定項目の多言語対応
* Update Changelog
* refactor: move options locale key to root for optimizing artifacts for locale inlining
* fix
* fix
* ✌️
---------
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
parent
4285303c81
commit
97d485bdd2
|
|
@ -6,6 +6,7 @@
|
||||||
### Client
|
### Client
|
||||||
- Enhance: ドライブのファイル一覧で自動でもっと見るを利用可能に
|
- Enhance: ドライブのファイル一覧で自動でもっと見るを利用可能に
|
||||||
- Enhance: ウィジェットの表示設定をプレビューを見ながら行えるように
|
- Enhance: ウィジェットの表示設定をプレビューを見ながら行えるように
|
||||||
|
- Enhance: ウィジェットの設定項目のラベルの多言語対応
|
||||||
- Fix: ドライブクリーナーでファイルを削除しても画面に反映されない問題を修正 #16061
|
- Fix: ドライブクリーナーでファイルを削除しても画面に反映されない問題を修正 #16061
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
|
||||||
|
|
@ -2603,6 +2603,43 @@ _widgets:
|
||||||
birthdayFollowings: "今日誕生日のユーザー"
|
birthdayFollowings: "今日誕生日のユーザー"
|
||||||
chat: "ダイレクトメッセージ"
|
chat: "ダイレクトメッセージ"
|
||||||
|
|
||||||
|
_widgetOptions:
|
||||||
|
showHeader: "ヘッダーを表示"
|
||||||
|
transparent: "背景を透明にする"
|
||||||
|
height: "高さ"
|
||||||
|
_button:
|
||||||
|
colored: "色付き"
|
||||||
|
_clock:
|
||||||
|
size: "サイズ"
|
||||||
|
thickness: "針の太さ"
|
||||||
|
thicknessThin: "細い"
|
||||||
|
thicknessMedium: "普通"
|
||||||
|
thicknessThick: "太い"
|
||||||
|
graduations: "文字盤の目盛り"
|
||||||
|
graduationDots: "ドット"
|
||||||
|
graduationArabic: "アラビア数字"
|
||||||
|
fadeGraduations: "目盛りをフェード"
|
||||||
|
sAnimation: "秒針のアニメーション"
|
||||||
|
sAnimationElastic: "リアル"
|
||||||
|
sAnimationEaseOut: "滑らか"
|
||||||
|
twentyFour: "24時間表示"
|
||||||
|
labelTime: "時刻"
|
||||||
|
labelTz: "タイムゾーン"
|
||||||
|
labelTimeAndTz: "時刻とタイムゾーン"
|
||||||
|
timezone: "タイムゾーン"
|
||||||
|
showMs: "ミリ秒を表示"
|
||||||
|
showLabel: "ラベルを表示"
|
||||||
|
_jobQueue:
|
||||||
|
sound: "音を鳴らす"
|
||||||
|
_rss:
|
||||||
|
url: "RSSフィードのURL"
|
||||||
|
refreshIntervalSec: "更新間隔(秒)"
|
||||||
|
maxEntries: "最大表示件数"
|
||||||
|
_rssTicker:
|
||||||
|
shuffle: "表示順をシャッフル"
|
||||||
|
duration: "ティッカーのスクロール速度(秒)"
|
||||||
|
reverse: "逆方向にスクロール"
|
||||||
|
|
||||||
_cw:
|
_cw:
|
||||||
hide: "隠す"
|
hide: "隠す"
|
||||||
show: "もっと見る"
|
show: "もっと見る"
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,12 @@ const name = 'activity';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
|
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
|
||||||
import { useWidgetPropsManager } from './widget.js';
|
import { useWidgetPropsManager } from './widget.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import type { WidgetComponentProps, WidgetComponentEmits, WidgetComponentExpose } from './widget.js';
|
import type { WidgetComponentProps, WidgetComponentEmits, WidgetComponentExpose } from './widget.js';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
|
|
||||||
|
|
@ -20,6 +21,7 @@ const name = 'ai';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,12 @@ const name = 'aiscript';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
script: {
|
script: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts.script,
|
||||||
multiline: true,
|
multiline: true,
|
||||||
default: '(1 + 1)',
|
default: '(1 + 1)',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import type { AsUiComponent, AsUiRoot } from '@/aiscript/ui.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js';
|
import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js';
|
||||||
import { $i } from '@/i.js';
|
import { $i } from '@/i.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import MkAsUi from '@/components/MkAsUi.vue';
|
import MkAsUi from '@/components/MkAsUi.vue';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
import { registerAsUiLib } from '@/aiscript/ui.js';
|
import { registerAsUiLib } from '@/aiscript/ui.js';
|
||||||
|
|
@ -33,11 +34,13 @@ const name = 'aiscriptApp';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
script: {
|
script: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts.script,
|
||||||
multiline: true,
|
multiline: true,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,12 @@ import { misskeyApi } from '@/utility/misskey-api.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import { $i } from '@/i.js';
|
import { $i } from '@/i.js';
|
||||||
|
|
||||||
const name = i18n.ts._widgets.birthdayFollowings;
|
const name = 'birthdayFollowings';
|
||||||
|
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,24 @@ import * as os from '@/os.js';
|
||||||
import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js';
|
import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js';
|
||||||
import { $i } from '@/i.js';
|
import { $i } from '@/i.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
const name = 'button';
|
const name = 'button';
|
||||||
|
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
label: {
|
label: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts.label,
|
||||||
default: 'BUTTON',
|
default: 'BUTTON',
|
||||||
},
|
},
|
||||||
colored: {
|
colored: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._button.colored,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
script: {
|
script: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts.script,
|
||||||
multiline: true,
|
multiline: true,
|
||||||
default: 'Mk:dialog("hello" "world")',
|
default: 'Mk:dialog("hello" "world")',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ const name = 'calendar';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ const name = 'chat';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { useWidgetPropsManager } from './widget.js';
|
import { useWidgetPropsManager } from './widget.js';
|
||||||
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
import MkClickerGame from '@/components/MkClickerGame.vue';
|
import MkClickerGame from '@/components/MkClickerGame.vue';
|
||||||
|
|
||||||
|
|
@ -23,6 +24,7 @@ const name = 'clicker';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,12 @@ const name = 'clock';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
label: i18n.ts._widgetOptions._clock.size,
|
||||||
default: 'medium',
|
default: 'medium',
|
||||||
options: [{
|
options: [{
|
||||||
value: 'small' as const,
|
value: 'small' as const,
|
||||||
|
|
@ -62,79 +64,89 @@ const widgetPropsDef = {
|
||||||
},
|
},
|
||||||
thickness: {
|
thickness: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
label: i18n.ts._widgetOptions._clock.thickness,
|
||||||
default: 0.2,
|
default: 0.2,
|
||||||
options: [{
|
options: [{
|
||||||
value: 0.1 as const,
|
value: 0.1 as const,
|
||||||
label: 'thin',
|
label: i18n.ts._widgetOptions._clock.thicknessThin,
|
||||||
}, {
|
}, {
|
||||||
value: 0.2 as const,
|
value: 0.2 as const,
|
||||||
label: 'medium',
|
label: i18n.ts._widgetOptions._clock.thicknessMedium,
|
||||||
}, {
|
}, {
|
||||||
value: 0.3 as const,
|
value: 0.3 as const,
|
||||||
label: 'thick',
|
label: i18n.ts._widgetOptions._clock.thicknessThick,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
graduations: {
|
graduations: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
label: i18n.ts._widgetOptions._clock.graduations,
|
||||||
default: 'numbers',
|
default: 'numbers',
|
||||||
options: [{
|
options: [{
|
||||||
value: 'none' as const,
|
value: 'none' as const,
|
||||||
label: 'None',
|
label: i18n.ts.none,
|
||||||
}, {
|
}, {
|
||||||
value: 'dots' as const,
|
value: 'dots' as const,
|
||||||
label: 'Dots',
|
label: i18n.ts._widgetOptions._clock.graduationDots,
|
||||||
}, {
|
}, {
|
||||||
value: 'numbers' as const,
|
value: 'numbers' as const,
|
||||||
label: 'Numbers',
|
label: i18n.ts._widgetOptions._clock.graduationArabic,
|
||||||
}],
|
}, /*, {
|
||||||
|
value: 'roman' as const,
|
||||||
|
label: i18n.ts._widgetOptions._clock.graduationRoman,
|
||||||
|
}*/],
|
||||||
},
|
},
|
||||||
fadeGraduations: {
|
fadeGraduations: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.fadeGraduations,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
sAnimation: {
|
sAnimation: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
label: i18n.ts._widgetOptions._clock.sAnimation,
|
||||||
default: 'elastic',
|
default: 'elastic',
|
||||||
options: [{
|
options: [{
|
||||||
value: 'none' as const,
|
value: 'none' as const,
|
||||||
label: 'None',
|
label: i18n.ts.none,
|
||||||
}, {
|
}, {
|
||||||
value: 'elastic' as const,
|
value: 'elastic' as const,
|
||||||
label: 'Elastic',
|
label: i18n.ts._widgetOptions._clock.sAnimationElastic,
|
||||||
}, {
|
}, {
|
||||||
value: 'easeOut' as const,
|
value: 'easeOut' as const,
|
||||||
label: 'Ease out',
|
label: i18n.ts._widgetOptions._clock.sAnimationEaseOut,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
twentyFour: {
|
twentyFour: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.twentyFour,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
|
label: i18n.ts.label,
|
||||||
default: 'none',
|
default: 'none',
|
||||||
options: [{
|
options: [{
|
||||||
value: 'none' as const,
|
value: 'none' as const,
|
||||||
label: 'None',
|
label: i18n.ts.none,
|
||||||
}, {
|
}, {
|
||||||
value: 'time' as const,
|
value: 'time' as const,
|
||||||
label: 'Time',
|
label: i18n.ts._widgetOptions._clock.labelTime,
|
||||||
}, {
|
}, {
|
||||||
value: 'tz' as const,
|
value: 'tz' as const,
|
||||||
label: 'TZ',
|
label: i18n.ts._widgetOptions._clock.labelTz,
|
||||||
}, {
|
}, {
|
||||||
value: 'timeAndTz' as const,
|
value: 'timeAndTz' as const,
|
||||||
label: 'Time + TZ',
|
label: i18n.ts._widgetOptions._clock.labelTimeAndTz,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
timezone: {
|
timezone: {
|
||||||
type: 'enum',
|
type: 'enum',
|
||||||
|
label: i18n.ts._widgetOptions._clock.timezone,
|
||||||
default: null,
|
default: null,
|
||||||
enum: [...timezones.map((tz) => ({
|
enum: [...timezones.map((tz) => ({
|
||||||
label: tz.name,
|
label: tz.name,
|
||||||
value: tz.name.toLowerCase(),
|
value: tz.name.toLowerCase(),
|
||||||
})), {
|
})), {
|
||||||
label: '(auto)',
|
label: i18n.ts.auto,
|
||||||
value: null,
|
value: null,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import { useWidgetPropsManager } from './widget.js';
|
||||||
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
import { timezones } from '@/utility/timezones.js';
|
import { timezones } from '@/utility/timezones.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import MkDigitalClock from '@/components/MkDigitalClock.vue';
|
import MkDigitalClock from '@/components/MkDigitalClock.vue';
|
||||||
|
|
||||||
const name = 'digitalClock';
|
const name = 'digitalClock';
|
||||||
|
|
@ -26,29 +27,34 @@ const name = 'digitalClock';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts.fontSize,
|
||||||
default: 1.5,
|
default: 1.5,
|
||||||
step: 0.1,
|
step: 0.1,
|
||||||
},
|
},
|
||||||
showMs: {
|
showMs: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.showMs,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showLabel: {
|
showLabel: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.showLabel,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
timezone: {
|
timezone: {
|
||||||
type: 'enum',
|
type: 'enum',
|
||||||
|
label: i18n.ts._widgetOptions._clock.timezone,
|
||||||
default: null,
|
default: null,
|
||||||
enum: [...timezones.map((tz) => ({
|
enum: [...timezones.map((tz) => ({
|
||||||
label: tz.name,
|
label: tz.name,
|
||||||
value: tz.name.toLowerCase(),
|
value: tz.name.toLowerCase(),
|
||||||
})), {
|
})), {
|
||||||
label: '(auto)',
|
label: i18n.ts.auto,
|
||||||
value: null,
|
value: null,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ const name = 'federation';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,14 @@ import MkTagCloud from '@/components/MkTagCloud.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||||
import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js';
|
import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
const name = 'instanceCloud';
|
const name = 'instanceCloud';
|
||||||
|
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -61,16 +61,19 @@ import * as sound from '@/utility/sound.js';
|
||||||
import { deepClone } from '@/utility/clone.js';
|
import { deepClone } from '@/utility/clone.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { genId } from '@/utility/id.js';
|
import { genId } from '@/utility/id.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
const name = 'jobQueue';
|
const name = 'jobQueue';
|
||||||
|
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
sound: {
|
sound: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._jobQueue.sound,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,12 @@ const name = 'memo';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
height: {
|
height: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts.height,
|
||||||
default: 100,
|
default: 100,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ const name = 'notifications';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
height: {
|
height: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts.height,
|
||||||
default: 300,
|
default: 300,
|
||||||
},
|
},
|
||||||
excludeTypes: {
|
excludeTypes: {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ const name = 'onlineUsers';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,12 @@ const name = 'photos';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import * as Misskey from 'misskey-js';
|
||||||
import { url as base } from '@@/js/config.js';
|
import { url as base } from '@@/js/config.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
import { useWidgetPropsManager } from './widget.js';
|
import { useWidgetPropsManager } from './widget.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
|
|
@ -34,19 +35,23 @@ const name = 'rss';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts._widgetOptions._rss.url,
|
||||||
default: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews',
|
default: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews',
|
||||||
manualSave: true,
|
manualSave: true,
|
||||||
},
|
},
|
||||||
refreshIntervalSec: {
|
refreshIntervalSec: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts._widgetOptions._rss.refreshIntervalSec,
|
||||||
default: 60,
|
default: 60,
|
||||||
},
|
},
|
||||||
maxEntries: {
|
maxEntries: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts._widgetOptions._rss.maxEntries,
|
||||||
default: 15,
|
default: 15,
|
||||||
},
|
},
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import MkMarqueeText from '@/components/MkMarqueeText.vue';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
import { shuffle } from '@/utility/shuffle.js';
|
import { shuffle } from '@/utility/shuffle.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import { url as base } from '@@/js/config.js';
|
import { url as base } from '@@/js/config.js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
|
|
||||||
|
|
@ -43,23 +44,28 @@ const name = 'rssTicker';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
url: {
|
url: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
label: i18n.ts._widgetOptions._rss.url,
|
||||||
default: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews',
|
default: 'http://feeds.afpbb.com/rss/afpbb/afpbbnews',
|
||||||
manualSave: true,
|
manualSave: true,
|
||||||
},
|
},
|
||||||
shuffle: {
|
shuffle: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._rssTicker.shuffle,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
refreshIntervalSec: {
|
refreshIntervalSec: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts._widgetOptions._rss.refreshIntervalSec,
|
||||||
default: 60,
|
default: 60,
|
||||||
},
|
},
|
||||||
maxEntries: {
|
maxEntries: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts._widgetOptions._rss.maxEntries,
|
||||||
default: 15,
|
default: 15,
|
||||||
},
|
},
|
||||||
duration: {
|
duration: {
|
||||||
type: 'range',
|
type: 'range',
|
||||||
|
label: i18n.ts._widgetOptions._rssTicker.duration,
|
||||||
default: 70,
|
default: 70,
|
||||||
step: 1,
|
step: 1,
|
||||||
min: 5,
|
min: 5,
|
||||||
|
|
@ -67,14 +73,17 @@ const widgetPropsDef = {
|
||||||
},
|
},
|
||||||
reverse: {
|
reverse: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._rssTicker.reverse,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ const name = 'slideshow';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
height: {
|
height: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts._widgetOptions.height,
|
||||||
default: 300,
|
default: 300,
|
||||||
},
|
},
|
||||||
folderId: {
|
folderId: {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ const name = 'hashtags';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onUnmounted, ref, watch } from 'vue';
|
import { onUnmounted, ref, watch } from 'vue';
|
||||||
import { useWidgetPropsManager } from './widget.js';
|
import { useWidgetPropsManager } from './widget.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
|
|
||||||
|
|
@ -26,19 +27,23 @@ const name = 'unixClock';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
label: i18n.ts.fontSize,
|
||||||
default: 1.5,
|
default: 1.5,
|
||||||
step: 0.1,
|
step: 0.1,
|
||||||
},
|
},
|
||||||
showMs: {
|
showMs: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.showMs,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
showLabel: {
|
showLabel: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions._clock.showLabel,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
} satisfies FormWithDefault;
|
} satisfies FormWithDefault;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ const name = 'userList';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
listId: {
|
listId: {
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,12 @@ const name = 'serverMetric';
|
||||||
const widgetPropsDef = {
|
const widgetPropsDef = {
|
||||||
showHeader: {
|
showHeader: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.showHeader,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
transparent: {
|
transparent: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
|
label: i18n.ts._widgetOptions.transparent,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import type { Reactive } from 'vue';
|
||||||
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { deepClone } from '@/utility/clone.js';
|
import { deepClone } from '@/utility/clone.js';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
export type Widget<P extends Record<string, unknown>> = {
|
export type Widget<P extends Record<string, unknown>> = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -75,7 +76,7 @@ export const useWidgetPropsManager = <F extends FormWithDefault>(
|
||||||
canceled: true;
|
canceled: true;
|
||||||
}>((resolve) => {
|
}>((resolve) => {
|
||||||
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWidgetSettingsDialog.vue')), {
|
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWidgetSettingsDialog.vue')), {
|
||||||
widgetName: name,
|
widgetName: i18n.ts._widgets[name] ?? name,
|
||||||
form: form,
|
form: form,
|
||||||
currentSettings: widgetProps,
|
currentSettings: widgetProps,
|
||||||
}, {
|
}, {
|
||||||
|
|
|
||||||
|
|
@ -9893,6 +9893,138 @@ export interface Locale extends ILocale {
|
||||||
*/
|
*/
|
||||||
"chat": string;
|
"chat": string;
|
||||||
};
|
};
|
||||||
|
"_widgetOptions": {
|
||||||
|
/**
|
||||||
|
* ヘッダーを表示
|
||||||
|
*/
|
||||||
|
"showHeader": string;
|
||||||
|
/**
|
||||||
|
* 背景を透明にする
|
||||||
|
*/
|
||||||
|
"transparent": string;
|
||||||
|
/**
|
||||||
|
* 高さ
|
||||||
|
*/
|
||||||
|
"height": string;
|
||||||
|
"_button": {
|
||||||
|
/**
|
||||||
|
* 色付き
|
||||||
|
*/
|
||||||
|
"colored": string;
|
||||||
|
};
|
||||||
|
"_clock": {
|
||||||
|
/**
|
||||||
|
* サイズ
|
||||||
|
*/
|
||||||
|
"size": string;
|
||||||
|
/**
|
||||||
|
* 針の太さ
|
||||||
|
*/
|
||||||
|
"thickness": string;
|
||||||
|
/**
|
||||||
|
* 細い
|
||||||
|
*/
|
||||||
|
"thicknessThin": string;
|
||||||
|
/**
|
||||||
|
* 普通
|
||||||
|
*/
|
||||||
|
"thicknessMedium": string;
|
||||||
|
/**
|
||||||
|
* 太い
|
||||||
|
*/
|
||||||
|
"thicknessThick": string;
|
||||||
|
/**
|
||||||
|
* 文字盤の目盛り
|
||||||
|
*/
|
||||||
|
"graduations": string;
|
||||||
|
/**
|
||||||
|
* ドット
|
||||||
|
*/
|
||||||
|
"graduationDots": string;
|
||||||
|
/**
|
||||||
|
* アラビア数字
|
||||||
|
*/
|
||||||
|
"graduationArabic": string;
|
||||||
|
/**
|
||||||
|
* 目盛りをフェード
|
||||||
|
*/
|
||||||
|
"fadeGraduations": string;
|
||||||
|
/**
|
||||||
|
* 秒針のアニメーション
|
||||||
|
*/
|
||||||
|
"sAnimation": string;
|
||||||
|
/**
|
||||||
|
* リアル
|
||||||
|
*/
|
||||||
|
"sAnimationElastic": string;
|
||||||
|
/**
|
||||||
|
* 滑らか
|
||||||
|
*/
|
||||||
|
"sAnimationEaseOut": string;
|
||||||
|
/**
|
||||||
|
* 24時間表示
|
||||||
|
*/
|
||||||
|
"twentyFour": string;
|
||||||
|
/**
|
||||||
|
* 時刻
|
||||||
|
*/
|
||||||
|
"labelTime": string;
|
||||||
|
/**
|
||||||
|
* タイムゾーン
|
||||||
|
*/
|
||||||
|
"labelTz": string;
|
||||||
|
/**
|
||||||
|
* 時刻とタイムゾーン
|
||||||
|
*/
|
||||||
|
"labelTimeAndTz": string;
|
||||||
|
/**
|
||||||
|
* タイムゾーン
|
||||||
|
*/
|
||||||
|
"timezone": string;
|
||||||
|
/**
|
||||||
|
* ミリ秒を表示
|
||||||
|
*/
|
||||||
|
"showMs": string;
|
||||||
|
/**
|
||||||
|
* ラベルを表示
|
||||||
|
*/
|
||||||
|
"showLabel": string;
|
||||||
|
};
|
||||||
|
"_jobQueue": {
|
||||||
|
/**
|
||||||
|
* 音を鳴らす
|
||||||
|
*/
|
||||||
|
"sound": string;
|
||||||
|
};
|
||||||
|
"_rss": {
|
||||||
|
/**
|
||||||
|
* RSSフィードのURL
|
||||||
|
*/
|
||||||
|
"url": string;
|
||||||
|
/**
|
||||||
|
* 更新間隔(秒)
|
||||||
|
*/
|
||||||
|
"refreshIntervalSec": string;
|
||||||
|
/**
|
||||||
|
* 最大表示件数
|
||||||
|
*/
|
||||||
|
"maxEntries": string;
|
||||||
|
};
|
||||||
|
"_rssTicker": {
|
||||||
|
/**
|
||||||
|
* 表示順をシャッフル
|
||||||
|
*/
|
||||||
|
"shuffle": string;
|
||||||
|
/**
|
||||||
|
* ティッカーのスクロール速度(秒)
|
||||||
|
*/
|
||||||
|
"duration": string;
|
||||||
|
/**
|
||||||
|
* 逆方向にスクロール
|
||||||
|
*/
|
||||||
|
"reverse": string;
|
||||||
|
};
|
||||||
|
};
|
||||||
"_cw": {
|
"_cw": {
|
||||||
/**
|
/**
|
||||||
* 隠す
|
* 隠す
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue