From a599c398146049be6daa5c6d80f6ef0d7730e666 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sun, 27 Apr 2025 04:35:29 +0900 Subject: [PATCH] [Update] Remove unnecessary plugins files that is for plugin development. --- src-ui/plugins/dev_plugin_subtitles/index.jsx | 25 --- .../dev_plugin_subtitles/locales/en.yml | 2 - .../dev_plugin_subtitles/locales/initI18n.js | 11 -- .../dev_plugin_subtitles/locales/ja.yml | 2 - .../locales/usePluginTranslation.jsx | 7 - .../dev_plugin_subtitles/plugin_configs.js | 7 - .../dev_plugin_subtitles/plugin_info.json | 20 -- .../dev_plugin_subtitles/store/store.js | 37 ---- .../SubtitleSystemContainer.jsx | 47 ----- .../SubtitleSystemContainer.module.scss | 124 ------------ .../_controllers/SubtitlesController.jsx | 42 ---- .../_logics/useSubtitles.jsx | 182 ------------------ .../_subtitles_utils.js | 112 ----------- .../CountdownContainer.jsx | 72 ------- .../CountdownContainer.module.scss | 47 ----- .../InputFileContainer.jsx | 62 ------ .../InputFileContainer.module.scss | 42 ---- .../ModeSelectorContainer.jsx | 74 ------- .../ModeSelectorContainer.module.scss | 50 ----- .../PlayControlContainer.jsx | 33 ---- .../PlayControlContainer.module.scss | 31 --- .../SubtitlesListContainer.jsx | 45 ----- .../SubtitlesListContainer.module.scss | 0 src-ui/plugins/plugins_index.js | 2 +- 24 files changed, 1 insertion(+), 1075 deletions(-) delete mode 100644 src-ui/plugins/dev_plugin_subtitles/index.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/locales/en.yml delete mode 100644 src-ui/plugins/dev_plugin_subtitles/locales/initI18n.js delete mode 100644 src-ui/plugins/dev_plugin_subtitles/locales/ja.yml delete mode 100644 src-ui/plugins/dev_plugin_subtitles/locales/usePluginTranslation.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/plugin_configs.js delete mode 100644 src-ui/plugins/dev_plugin_subtitles/plugin_info.json delete mode 100644 src-ui/plugins/dev_plugin_subtitles/store/store.js delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.module.scss delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_controllers/SubtitlesController.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_logics/useSubtitles.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_subtitles_utils.js delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.module.scss delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.module.scss delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.module.scss delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.module.scss delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.jsx delete mode 100644 src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.module.scss diff --git a/src-ui/plugins/dev_plugin_subtitles/index.jsx b/src-ui/plugins/dev_plugin_subtitles/index.jsx deleted file mode 100644 index fc496275..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/index.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import { initStore, StoreContext } from "@plugin_store"; -import { initI18n } from "@initI18n"; -import { SubtitleSystemContainer } from "./subtitle_system_container/SubtitleSystemContainer"; -import { SubtitlesController } from "./subtitle_system_container/_controllers/SubtitlesController.jsx"; - -export const init = (plugin_context) => { - const { createAtomWithHook, i18n, logics } = plugin_context; - - initStore(createAtomWithHook); - initI18n(i18n); - - const EntryComponents = () => { - return ( - - - - - - ); - }; - - plugin_context.registerComponent(EntryComponents); -}; - -export default init; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/locales/en.yml b/src-ui/plugins/dev_plugin_subtitles/locales/en.yml deleted file mode 100644 index 6a5ae6e1..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/locales/en.yml +++ /dev/null @@ -1,2 +0,0 @@ -main_page: - title: "VRCT Subtitles" \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/locales/initI18n.js b/src-ui/plugins/dev_plugin_subtitles/locales/initI18n.js deleted file mode 100644 index 6e71957e..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/locales/initI18n.js +++ /dev/null @@ -1,11 +0,0 @@ -import en from "./en.yml"; -import ja from "./ja.yml"; -import plugin_info from "../plugin_info.json"; - -export const initI18n = (i18n) => { - const ns = plugin_info.plugin_id; - - // addResourceBundle will merge into i18n’s store - i18n.addResourceBundle("en", ns, en, /* deep = */ true, /* overwrite = */ true); - i18n.addResourceBundle("ja", ns, ja, /* deep = */ true, /* overwrite = */ true); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/locales/ja.yml b/src-ui/plugins/dev_plugin_subtitles/locales/ja.yml deleted file mode 100644 index 3862be1e..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/locales/ja.yml +++ /dev/null @@ -1,2 +0,0 @@ -main_page: - title: "字幕プレイヤー" \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/locales/usePluginTranslation.jsx b/src-ui/plugins/dev_plugin_subtitles/locales/usePluginTranslation.jsx deleted file mode 100644 index 2e9e8d79..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/locales/usePluginTranslation.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import { useTranslation } from "react-i18next"; -import plugin_info from "../plugin_info.json"; - -export const usePluginTranslation = () => { - const ns = plugin_info.plugin_id; - return useTranslation(ns); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/plugin_configs.js b/src-ui/plugins/dev_plugin_subtitles/plugin_configs.js deleted file mode 100644 index 36f116d1..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/plugin_configs.js +++ /dev/null @@ -1,7 +0,0 @@ -export const configs = { - alias: { - "@plugin_store": "store/store.js", - "@initI18n": "locales/initI18n.js", - "@usePluginTranslation": "locales/usePluginTranslation.jsx", - } -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/plugin_info.json b/src-ui/plugins/dev_plugin_subtitles/plugin_info.json deleted file mode 100644 index ec673298..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/plugin_info.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "title": "VRCT Subtitles", - "desc": "No description", - "plugin_id": "vrct_plugin_subtitles", - "asset_name": "vrct_plugin_subtitles.zip", - "location": "main_section", - "plugin_version": "0.0.5", - "min_supported_vrct_version": "3.0.5", - "max_supported_vrct_version": "3.0.5", - "locales": { - "en": { - "title": "VRCT Subtitles", - "desc": "No description" - }, - "ja": { - "title": "VRCT 字幕表示機能", - "desc": "VRCTのオーバーレイ機能を使い、目の前に字幕としてテキストを表示する機能です。ワールドギミックの開始タイミングに合わせて字幕を設定し、同時に表示しているだけではあります。" - } - } -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/store/store.js b/src-ui/plugins/dev_plugin_subtitles/store/store.js deleted file mode 100644 index 6f338573..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/store/store.js +++ /dev/null @@ -1,37 +0,0 @@ -const store_hooks = {}; - -export const initStore = (createAtomWithHook) => { - Object.assign(store_hooks, { - useStore_IsSubtitlePlaying: createAtomWithHook(false, "IsSubtitlePlaying", { is_state_ok: true }).useHook, - useStore_SubtitlePlaybackMode: createAtomWithHook("relative", "SubtitlePlaybackMode", { is_state_ok: true }).useHook, - useStore_SubtitleAbsoluteTargetTime: createAtomWithHook({ - hour: "23", - minute: "00", - }, "SubtitleAbsoluteTargetTime", { is_state_ok: true }).useHook, - useStore_IsCuesScheduled: createAtomWithHook(false, "IsCuesScheduled", { is_state_ok: true }).useHook, - useStore_CountdownAdjustment: createAtomWithHook(0, "CountdownAdjustment", { is_state_ok: true }).useHook, - useStore_EffectiveCountdown: createAtomWithHook(null, "EffectiveCountdown", { is_state_ok: true }).useHook, - useStore_SubtitleCues: createAtomWithHook([], "SubtitleCues", { is_state_ok: true }).useHook, - - useStore_SubtitleTimers: createAtomWithHook([], "SubtitleTimers", { is_state_ok: true }).useHook, - useStore_SubtitleCountdownTimerId: createAtomWithHook([], "SubtitleCountdownTimerId", { is_state_ok: true }).useHook, - useStore_SubtitleFileName: createAtomWithHook("ファイルが選択されていません", "SubtitleFileName", { is_state_ok: true }).useHook, - }); -}; - -export const useStore = (hook_name) => { - if (!store_hooks[hook_name]) { - throw new Error(`Hook ${hook_name} is not initialized.`); - } - return store_hooks[hook_name](); -}; - - -// StoreContext.js -import React, { createContext, useContext } from "react"; - -export const StoreContext = createContext(null); - -export const useStoreContext = () => { - return useContext(StoreContext); -}; diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.jsx deleted file mode 100644 index 64349850..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import styles from "./SubtitleSystemContainer.module.scss"; -import { InputFileContainer } from "./input_file_container/InputFileContainer"; -import { ModeSelectorContainer } from "./mode_selector_container/ModeSelectorContainer"; -import { PlayControlContainer } from "./play_control_container/PlayControlContainer"; -import { CountdownContainer } from "./countdown_container/CountdownContainer"; -import { SubtitlesListContainer } from "./subtitles_list_container/SubtitlesListContainer"; -import { usePluginTranslation } from "@usePluginTranslation"; - -export const SubtitleSystemContainer = () => { - const { t } = usePluginTranslation(); - // const [srtContent, setSrtContent] = useState(""); - // const [cues, setCues] = useState([]); - // const [isPlaying, setIsPlaying] = useState(false); - - // 再生モード ("relative": ボタン押下から、"absolute": 指定時刻から) - // const [playbackMode, setPlaybackMode] = useState("relative"); - // 絶対モード用の再生開始時刻(ドロップダウンで選択、HH:MM) - // const [targetHour, setTargetHour] = useState("23"); - // const [targetMinute, setTargetMinute] = useState("00"); - - // カウントダウン状態 - // // initialCountdown: 再生開始ボタン押下時に算出される元の残り秒数 - // const [initialCountdown, setInitialCountdown] = useState(null); - // countdownAdjustment: ユーザーが上下ボタンで調整する値(秒単位) - // const [countdownAdjustment, setCountdownAdjustment] = useState(0); - // effectiveCountdown: (initialCountdown + countdownAdjustment) から経過秒数を差し引いた表示用の値 - // const [effectiveCountdown, setEffectiveCountdown] = useState(null); - // cuesScheduled: 字幕タイマーが一度スケジュールされたか - // const [cuesScheduled, setCuesScheduled] = useState(false); - - // // タイマー(setTimeout/setInterval)のID管理用 - // const timersRef = useRef([]); - // // カウントダウンタイマー専用の ref - // const countdownIntervalRef = useRef(null); - - return ( -
-

{t("main_page.title")}

- - - -
- - -
- ); -}; diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.module.scss deleted file mode 100644 index ef618213..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/SubtitleSystemContainer.module.scss +++ /dev/null @@ -1,124 +0,0 @@ -.container { - padding: 2rem 4rem; - background: var(--dark_900_color); - border-radius: 1rem; - flex-shrink: 0; - height: 100%; - overflow: auto; - display: flex; - flex-direction: column; - gap: 2rem; -} - -.title { - font-size: 1.8rem; - text-align: center; - flex-shrink: 0; -} - -.border { - width: 100%; - height: 0.2rem; - background-color: var(--dark_800_color); - flex-shrink: 0; - -} - - // label { - // display: block; - // font-size: 1.6rem; - // margin-bottom: 0.5rem; - // } - - // input, - // select { - // font-size: 1.6rem; - // padding: 0.5rem; - // border-radius: 0.5rem; - // border: 0.1rem solid #ccc; - // background: #333; - // color: #fff; - // } - - - // ボタンの基本スタイル - // button { - // // font-size: 1.8rem; - // // padding: 1rem 2rem; - // // border: none; - // // border-radius: 0.5rem; - // // cursor: pointer; - // // // transition: background 0.3s; - // // margin-right: 1rem; - - // &:focus { - // outline: none; - // box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); - // } - // } - - // 再生開始用ボタン(通常時) - .primary { - background: #007bff; - color: #fff; - &:hover { - background: #0056b3; - } - } - - // 再生停止用ボタン - .secondary { - background: #dc3545; - color: #fff; - &:hover { - background: #a71d2a; - } - } - - - - // 「再生中」状態(クリック不可)用のスタイル - .is_playing { - background: #6c757d; - cursor: not-allowed; - pointer-events: none; - } - - - // 字幕一覧のテーブル - table { - width: 100%; - border-collapse: collapse; - margin-top: 2rem; - - th, - td { - padding: 1rem; - border: 0.1rem solid #444; - text-align: left; - font-size: 1.4rem; - } - - th { - background: #555; - } - - tbody { - tr { - cursor: pointer; - transition: background 0.2s; - - &:nth-child(even) { - background: #2a2a2a; - } - - &:hover { - background: #444; - } - } - } -} - -.subtitle_lists { - font-size: 1.4rem; -} diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_controllers/SubtitlesController.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_controllers/SubtitlesController.jsx deleted file mode 100644 index d58be5aa..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_controllers/SubtitlesController.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useStoreContext } from "../../store/store.js"; - -import { useSubtitles } from "../_logics/useSubtitles"; -import { secToDayTime } from "../_subtitles_utils" -import { useEffect } from "react"; -export const SubtitlesController = () => { - const { useSendTextToOverlay } = useStoreContext(); - const { sendTextToOverlay } = useSendTextToOverlay(); - - const { - currentIsSubtitlePlaying, - currentIsCuesScheduled, - updateIsCuesScheduled, - currentCountdownAdjustment, - currentEffectiveCountdown, - scheduleCues, - } = useSubtitles(); - - // currentEffectiveCountdown.data が 0 になったとき、字幕開始 - useEffect(() => { - if ( - currentIsSubtitlePlaying.data && - currentEffectiveCountdown.data !== null && - currentEffectiveCountdown.data <= 0 && - !currentIsCuesScheduled.data - ) { - sendTextToOverlay("スタート!"); - console.log("スタート!"); - // 調整後のタイミングで字幕スケジュールを開始 - scheduleCues(0); - updateIsCuesScheduled(true); - } - - if (currentEffectiveCountdown.data > 0) { - console.log(secToDayTime(currentEffectiveCountdown.data)); - sendTextToOverlay(secToDayTime(currentEffectiveCountdown.data)); - } - - }, [currentEffectiveCountdown.data, currentIsSubtitlePlaying.data, currentIsCuesScheduled.data, currentCountdownAdjustment.data]); - - return null; -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_logics/useSubtitles.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_logics/useSubtitles.jsx deleted file mode 100644 index 80585abf..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_logics/useSubtitles.jsx +++ /dev/null @@ -1,182 +0,0 @@ -import { useStore, useStoreContext } from "../../store/store.js"; - -export const useSubtitles = () => { - const { useSendTextToOverlay } = useStoreContext(); - const { sendTextToOverlay } = useSendTextToOverlay(); - - const { currentSubtitleFileName, updateSubtitleFileName } = useStore("useStore_SubtitleFileName"); - const { currentIsSubtitlePlaying, updateIsSubtitlePlaying } = useStore("useStore_IsSubtitlePlaying"); - const { currentSubtitlePlaybackMode, updateSubtitlePlaybackMode } = useStore("useStore_SubtitlePlaybackMode"); - const { currentSubtitleAbsoluteTargetTime, updateSubtitleAbsoluteTargetTime } = useStore("useStore_SubtitleAbsoluteTargetTime"); - const { currentIsCuesScheduled, updateIsCuesScheduled } = useStore("useStore_IsCuesScheduled"); - - const { currentCountdownAdjustment, updateCountdownAdjustment } = useStore("useStore_CountdownAdjustment"); - const { currentEffectiveCountdown, updateEffectiveCountdown } = useStore("useStore_EffectiveCountdown"); - const { currentSubtitleCues, updateSubtitleCues } = useStore("useStore_SubtitleCues"); - - // タイマー(setTimeout/setInterval)のID管理用 - const { currentSubtitleTimers, updateSubtitleTimers, addSubtitleTimers } = useStore("useStore_SubtitleTimers"); - // const timersRef = useRef([]); - // カウントダウンタイマー専用の ref - const { currentSubtitleCountdownTimerId, updateSubtitleCountdownTimerId, AddSubtitleCountdownTimerId } = useStore("useStore_SubtitleCountdownTimerId"); - - // cues のスケジュールを行う(字幕開始時のオフセットは調整後のタイミングに合わせる) - const scheduleCues = (offset) => { - // 字幕開始時の処理 - const startFunction = (cue) => { - let send_text = ""; - if (cue.actor !== "") { - send_text = `[${cue.actor}] ${cue.text}`; - } else { - send_text = `${cue.text}`; - } - console.log(`字幕開始 (index: ${cue.index}) send_text:${send_text}`); - sendTextToOverlay(send_text); - }; - - // 字幕終了時の処理 - const endFunction = (cue) => { - console.log(`字幕終了 (index: ${cue.index}): ${cue.text}`); - // 必要に応じた終了処理(例:テキストクリア)を実装可能 - // sendTextToOverlay(""); - }; - - currentSubtitleCues.data.forEach((cue) => { - const startDelay = cue.startTime * 1000 + offset; - const endDelay = cue.endTime * 1000 + offset; - if (startDelay >= 0) { - const timerId = setTimeout(() => startFunction(cue), startDelay); - addSubtitleTimers(timerId); - } - if (endDelay >= 0) { - const timerId = setTimeout(() => endFunction(cue), endDelay); - addSubtitleTimers(timerId); - } - }); - }; - - - // カウントダウンタイマーの開始/再登録(指定した値から1秒ごとに減らす) - const startCountdownInterval = (startValue) => { - // 既存のタイマーがあればクリア - if (currentSubtitleCountdownTimerId.data) { - clearInterval(currentSubtitleCountdownTimerId.data); - } - // 新たな開始値を設定 - updateEffectiveCountdown(startValue); - const countdown_timer_id = setInterval(() => { - updateEffectiveCountdown((prev) => { - if (prev.data <= 1) { - clearInterval(currentSubtitleCountdownTimerId.data); - return 0; - } - return prev.data - 1; - }); - }, 1000); - updateSubtitleCountdownTimerId(countdown_timer_id); - addSubtitleTimers(currentSubtitleCountdownTimerId.data); - }; - - - // 字幕一覧の表示(relative モードの場合、クリックでジャンプ) - // テーブル内の字幕行をクリック(relative モードのみ)でジャンプ - const handleJump = (jumpCue) => { - if (currentSubtitlePlaybackMode.data !== "relative") return; - handleSubtitlesStop(); - const offset = -jumpCue.startTime * 1000; - scheduleCues(offset); - updateIsSubtitlePlaying(true); - }; - - - - // 「再生開始」ボタン押下時の処理 - const handleSubtitlesStart = () => { - handleSubtitlesStop(); - updateIsSubtitlePlaying(true); - updateIsCuesScheduled(false); - const target_time = currentSubtitleAbsoluteTargetTime.data; - - let computedCountdown = 0; - if (currentSubtitlePlaybackMode.data === "absolute") { - const now = new Date(); - const hour = parseInt(target_time.hour, 10); - const minute = parseInt(target_time.minute, 10); - let targetDate = new Date( - now.getFullYear(), - now.getMonth(), - now.getDate(), - hour, - minute, - 0, - 0 - ); - if (targetDate.getTime() < now.getTime()) { - targetDate.setDate(targetDate.getDate() + 1); - } - computedCountdown = Math.ceil((targetDate.getTime() - now.getTime()) / 1000); - } else { - computedCountdown = 10; // relative モードの場合は固定値 - } - // setInitialCountdown(computedCountdown); - // 調整値を反映した開始値 - const startValue = computedCountdown + currentCountdownAdjustment.data; - startCountdownInterval(startValue); - sendTextToOverlay(startValue.toString()); - }; - - - // すべてのタイマーを停止し、各状態を初期化する - const handleSubtitlesStop = () => { - currentSubtitleTimers.data.forEach((timerId) => { - clearTimeout(timerId); - clearInterval(timerId); - }); - - updateSubtitleTimers([]); - if (currentSubtitleCountdownTimerId.data) { - clearInterval(currentSubtitleCountdownTimerId.data); - updateSubtitleCountdownTimerId(null); - } - console.log("再生を停止しました。"); - updateIsSubtitlePlaying(false); - // setInitialCountdown(null); - updateEffectiveCountdown(null); - updateCountdownAdjustment(0); - updateIsCuesScheduled(false); - }; - - - return { - currentSubtitleFileName, - updateSubtitleFileName, - - currentIsSubtitlePlaying, - updateIsSubtitlePlaying, - - currentSubtitlePlaybackMode, - updateSubtitlePlaybackMode, - - currentSubtitleAbsoluteTargetTime, - updateSubtitleAbsoluteTargetTime, - - currentIsCuesScheduled, - updateIsCuesScheduled, - - currentCountdownAdjustment, - updateCountdownAdjustment, - - currentEffectiveCountdown, - updateEffectiveCountdown, - - currentSubtitleCues, - updateSubtitleCues, - - handleSubtitlesStart, - handleSubtitlesStop, - startCountdownInterval, - scheduleCues, - handleJump, - } - -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_subtitles_utils.js b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_subtitles_utils.js deleted file mode 100644 index 8bed1f7b..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/_subtitles_utils.js +++ /dev/null @@ -1,112 +0,0 @@ - -/** - * SRT形式の文字列を解析する関数 - * 改行コードを正規化し、空行で分割して解析する - * (actor は存在しないため、空文字列をセット) - */ -export const parseSRT = (data) => { - const cues = []; - const normalizedData = data.replace(/\r\n/g, "\n").trim(); - const blocks = normalizedData.split(/\n\s*\n/); - blocks.forEach((block) => { - const lines = block.split("\n").filter((line) => line.trim() !== ""); - if (lines.length >= 3) { - const index = parseInt(lines[0], 10); - const timeMatch = lines[1].match(/([\d:,]+)\s+-->\s+([\d:,]+)/); - if (!timeMatch) return; - const start = parseTime(timeMatch[1]); - const end = parseTime(timeMatch[2]); - const text = lines.slice(2).join("\n"); - cues.push({ index, startTime: start, endTime: end, actor: "", text }); - } - }); - return cues; -}; - -/** - * ASS形式の文字列を解析する関数 - * [Events] セクション内の "Dialogue:" 行から、 - * フォーマット "Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" - * に沿って分割する。 - * ここでは Name を actor、Text を text として抽出する。 - */ -export const parseASS = (data) => { - const cues = []; - const lines = data.split(/\r?\n/); - let index = 1; - lines.forEach((line) => { - if (line.startsWith("Dialogue:")) { - const dialogueLine = line.substring("Dialogue:".length).trim(); - const parts = dialogueLine.split(","); - // parts[0]: Layer, parts[1]: Start, parts[2]: End, parts[3]: Style, parts[4]: Name, parts[5]: MarginL, parts[6]: MarginR, parts[7]: MarginV, parts[8]: Effect, parts[9]~: Text - if (parts.length < 10) return; - const startTime = parseASSTime(parts[1].trim()); - const endTime = parseASSTime(parts[2].trim()); - const actor = parts[4].trim(); - const text = parts.slice(9).join(",").trim(); - cues.push({ index: index++, startTime, endTime, actor, text }); - } - }); - return cues; -}; - -/** - * "H:MM:SS.cc" 形式の ASS 時刻文字列を秒数に変換する関数 - * 例: "0:00:10.52" → 10.52 秒 - */ -export const parseASSTime = (timeString) => { - const parts = timeString.split(":"); - if (parts.length !== 3) return 0; - const hours = parseFloat(parts[0]); - const minutes = parseFloat(parts[1]); - const seconds = parseFloat(parts[2]); - return hours * 3600 + minutes * 60 + seconds; -}; - -/** - * "HH:MM:SS,mmm" 形式の SRT 時刻文字列を秒数に変換する関数 - */ -export const parseTime = (timeString) => { - const [hms, ms] = timeString.split(","); - const [hours, minutes, seconds] = hms.split(":").map(Number); - return hours * 3600 + minutes * 60 + seconds + Number(ms) / 1000; -}; - -const padTime = (int) => { - return String(int).padStart(2, "0"); -}; - -export const secToDayTime = (seconds) => { - const day = Math.floor(seconds / 86400); - const hour = Math.floor((seconds % 86400) / 3600); - const min = Math.floor((seconds % 3600) / 60); - const sec = seconds % 60; - let time = ""; - // day が 0 の場合は「日」は出力しない(hour や min も同様) - if (day !== 0) { - time = `${day}日${hour}時間${min}分${sec}秒`; - } else if (hour !== 0) { - time = `${padTime(hour)}:${padTime(min)}:${padTime(sec)}`; - } else { - time = `${padTime(min)}:${padTime(sec)}`; - } - // } else { - // time = `${padTime(sec)}`; - // } - return time; -}; - - -// HH:MM:SS 形式に変換する補助関数 -export const formatTime = (timeInSeconds) => { - const hours = Math.floor(timeInSeconds / 3600); - const minutes = Math.floor((timeInSeconds % 3600) / 60); - const seconds = Math.floor(timeInSeconds % 60); - return ( - String(hours).padStart(2, "0") + - ":" + - String(minutes).padStart(2, "0") + - ":" + - String(seconds).padStart(2, "0") - ); -}; diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.jsx deleted file mode 100644 index 419db219..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.jsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import styles from "./CountdownContainer.module.scss"; -import { secToDayTime } from "../_subtitles_utils"; -import { useSubtitles } from "../_logics/useSubtitles"; - -export const CountdownContainer = () => { - const { - updateCountdownAdjustment, - currentEffectiveCountdown, - currentIsCuesScheduled, - startCountdownInterval, - } = useSubtitles(); - // カウントダウン表示:字幕開始前は常に表示 - - // if (currentEffectiveCountdown.data === 0) return null; - if (currentEffectiveCountdown.data === null && currentIsCuesScheduled.data) return null; - - return ( -
- カウントダウン: {secToDayTime(currentEffectiveCountdown.data)} -
- {/* 1分単位の調整ボタン */} -
- - -
-
- {/* 1秒単位の調整ボタン */} -
- - -
-
-
- ); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.module.scss deleted file mode 100644 index 0ad5a7ff..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/countdown_container/CountdownContainer.module.scss +++ /dev/null @@ -1,47 +0,0 @@ -.container { - margin-top: 1rem; - font-size: 2.6rem; - display: flex; - align-items: center; - gap: 1rem; - flex-direction: column; - - span { - font-weight: bold; - } - -} - -.adjust_button_container { - display: flex; - gap: 10rem; -} - -.adjust_button_wrapper { - display: flex; - flex-direction: column; - gap: 4rem; -} - - - -.adjust_button { - padding: 1rem 1.4rem; - font-size: 1.8rem; - border-radius: 0.4rem; - background: var(--primary_600_color); - color: #fff; - cursor: pointer; - - &:hover { - background: var(--primary_400_color); - } - &:active { - background: var(--primary_650_color); - } -} - -.adjust_button_border { - background-color: var(--dark_600_color); - width: 0.2rem; -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.jsx deleted file mode 100644 index 1e234765..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import styles from "./InputFileContainer.module.scss"; -import { useSubtitles } from "../_logics/useSubtitles"; -import { parseSRT, parseASS } from "../_subtitles_utils"; - -export const InputFileContainer = () => { - const { - updateSubtitleFileName, - currentSubtitleFileName, - updateSubtitleCues, - handleSubtitlesStop - } = useSubtitles(); - - // ファイルアップロード時の処理 - const handleFileUpload = (event) => { - const file = event.target.files[0]; - if (!file) return; - const reader = new FileReader(); - reader.onload = (e) => { - const content = e.target.result; - let parsedCues = []; - // 拡張子により ASS と SRT を判定 - if (file.name.toLowerCase().endsWith(".ass")) { - parsedCues = parseASS(content); - } else { - parsedCues = parseSRT(content); - } - updateSubtitleCues(parsedCues); - console.log("Parsed cues:", parsedCues); - updateSubtitleFileName(file.name); - - }; - reader.readAsText(file); - }; - - - // ファイルクリア - const handleClearFile = () => { - handleSubtitlesStop(); - updateSubtitleFileName("ファイルが選択されていません"); - updateSubtitleCues([]); - }; - - return ( -
-
- - -

{currentSubtitleFileName.data}

-
- -
- ); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.module.scss deleted file mode 100644 index 91966cbb..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/input_file_container/InputFileContainer.module.scss +++ /dev/null @@ -1,42 +0,0 @@ -.container { - display: flex; - align-items: center; - justify-content: space-between; - gap: 6rem; -} - -.input_file_wrapper { - display: flex; - align-items: center; - gap: 1rem; -} -.input_file_label { - font-size: 1.4rem; - border-radius: 0.4rem; - padding: 1rem; - background-color: var(--dark_850_color); - border: 0.1rem solid var(--dark_400_color); - flex-shrink: 0; -} -.input_file_i { - display: none; -} -.file_name { - font-size: 1.6rem; - padding: 0.5rem; - width: 100%; - max-width: 60rem; -} - -.file_clear { - background: var(--dark_800_color); - color: var(--dark_200_color); - border-radius: 0.4rem; - font-size: 1.2rem; - padding: 0.6rem 1rem; - cursor: pointer; - - &:hover { - background: var(--error_bc_color); - } -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.jsx deleted file mode 100644 index e19ddba2..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.jsx +++ /dev/null @@ -1,74 +0,0 @@ -import styles from "./ModeSelectorContainer.module.scss"; -import { useSubtitles } from "../_logics/useSubtitles"; -export const ModeSelectorContainer = () => { - const { - currentSubtitlePlaybackMode, - updateSubtitlePlaybackMode, - currentSubtitleAbsoluteTargetTime, - updateSubtitleAbsoluteTargetTime, - } = useSubtitles(); - - const target_time = currentSubtitleAbsoluteTargetTime.data; - - const handleOnchangeTargetTime = (key, value) => { - updateSubtitleAbsoluteTargetTime((old_value) => { - return { - ...old_value.data, - [key]: value, - } - }); - }; - - - return ( -
-
- -
- - {currentSubtitlePlaybackMode.data === "absolute" && ( -
- -
- - : - -
-
- )} -
- ); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.module.scss deleted file mode 100644 index a3c805d9..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/mode_selector_container/ModeSelectorContainer.module.scss +++ /dev/null @@ -1,50 +0,0 @@ -.container { - // background-color: red; - display: flex; - gap: 4rem; -} -.mode_selector_wrapper { - display: flex; - align-items: center; - gap: 2rem; -} -.absolute_time_label { - font-size: 1.4rem; -} - -.mode_selector { - font-size: 1.6rem; - padding: 0.6rem 1rem; - border-radius: 0.5rem; - border: 0.1rem solid var(--dark_400_color); - cursor: pointer; -} - -.mode_selector_item { - background-color: var(--dark_800_color); -} - - -.time_section { - display: flex; - gap: 2rem; - justify-content: center; - align-items: center; -} - -.time_selects { - display: flex; - align-items: center; - gap: 0.5rem; -} - - -.time_selects_item { - width: 6rem; - text-align: center; - padding: 0.6rem 1rem; - font-size: 1.8rem; - background-color: var(--dark_850_color); - border: 0.1rem solid var(--dark_400_color); - cursor: pointer; -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.jsx deleted file mode 100644 index 05e45e01..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.jsx +++ /dev/null @@ -1,33 +0,0 @@ -// import React, { useState, useRef, useEffect } from "react"; -import styles from "./PlayControlContainer.module.scss"; -import { useSubtitles } from "../_logics/useSubtitles"; -import clsx from "clsx"; - -export const PlayControlContainer = () => { - const { - currentIsSubtitlePlaying, - handleSubtitlesStart, - handleSubtitlesStop, - } = useSubtitles(); - - const is_playing = currentIsSubtitlePlaying.data; - - const playback_button_classname = clsx(styles.playback_button, { - [styles.is_playing]: is_playing, - }); - return ( -
- - {is_playing && - - } -
- ); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.module.scss deleted file mode 100644 index ea5de457..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/play_control_container/PlayControlContainer.module.scss +++ /dev/null @@ -1,31 +0,0 @@ -.container { - display: flex; - gap: 4rem; - display: flex; - justify-content: center; -} - -.playback_button, .playback_stop_button { - font-size: 1.6rem; - padding: 1rem 2rem; - cursor: pointer; - border-radius: 0.4rem; -} - -.playback_button { - background-color: var(--primary_550_color); - &:hover { - background-color: var(--primary_400_color); - } - &.is_playing { - background-color: var(--primary_650_color); - pointer-events: none; - color: var(--dark_400_color); - } -} -.playback_stop_button { - background-color: var(--dark_800_color); - &:hover { - background-color: var(--error_bc_color); - } -} \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.jsx b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.jsx deleted file mode 100644 index b997870e..00000000 --- a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import styles from "./SubtitlesListContainer.module.scss"; -import { useSubtitles } from "../_logics/useSubtitles"; -import { formatTime } from "../_subtitles_utils"; - -export const SubtitlesListContainer = () => { - const { currentSubtitleCues, handleJump } = useSubtitles(); - - if (currentSubtitleCues.data.length < 0 ) return null; - - return ( -
-

字幕一覧

- - - - - - - - - - - - {currentSubtitleCues.data.map((cue) => ( - handleJump(cue)} - className={styles.tableRow} - > - - - - - - - ))} - -
番号開始終了Actorテキスト
{cue.index}{formatTime(cue.startTime)}{formatTime(cue.endTime)}{cue.actor}{cue.text}
-

- ※ 行をクリックすると、その字幕の位置にジャンプします。(相対モードのみ) -

-
- ); -}; \ No newline at end of file diff --git a/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.module.scss b/src-ui/plugins/dev_plugin_subtitles/subtitle_system_container/subtitles_list_container/SubtitlesListContainer.module.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src-ui/plugins/plugins_index.js b/src-ui/plugins/plugins_index.js index ea240627..6c1be762 100644 --- a/src-ui/plugins/plugins_index.js +++ b/src-ui/plugins/plugins_index.js @@ -1,3 +1,3 @@ export const dev_plugins = [ - { entry_path: "dev_plugin_subtitles" } + // { entry_path: "dev_plugin_subtitles" } ]; \ No newline at end of file