Update index.html
Browse files- index.html +143 -18
index.html
CHANGED
@@ -931,9 +931,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
931 |
window.alert(`${message}\n\nエラー詳細: ${error.message}`);
|
932 |
}
|
933 |
|
934 |
-
|
935 |
async function registerServiceWorker() {
|
936 |
const statusElement = document.getElementById('sw-status');
|
|
|
937 |
|
938 |
if (!('serviceWorker' in navigator)) {
|
939 |
statusElement.textContent = "このブラウザはService Workerをサポートしていません";
|
@@ -941,34 +942,59 @@ async function registerServiceWorker() {
|
|
941 |
}
|
942 |
|
943 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
944 |
// チェックされたファイルを収集
|
945 |
const filesToCache = [];
|
946 |
|
947 |
-
//
|
948 |
-
|
949 |
-
if (document.getElementById('sw-root').checked) filesToCache.push('/');
|
950 |
|
951 |
// 通常のメディアファイル
|
952 |
-
if (
|
953 |
-
if (
|
954 |
-
if (
|
955 |
-
if (
|
956 |
-
if (
|
957 |
-
if (
|
958 |
|
959 |
// t/ ディレクトリのメディアファイル
|
960 |
-
if (
|
961 |
-
if (
|
962 |
-
if (
|
963 |
-
if (
|
964 |
-
if (
|
965 |
-
if (
|
966 |
-
|
|
|
967 |
statusElement.textContent = "サービスワーカーを登録中...";
|
968 |
|
969 |
// Service Workerを登録
|
970 |
const registration = await navigator.serviceWorker.register('/service-worker.js');
|
971 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
972 |
// Service Workerがアクティブになるのを待つ
|
973 |
await new Promise(resolve => {
|
974 |
if (registration.active) {
|
@@ -985,19 +1011,118 @@ async function registerServiceWorker() {
|
|
985 |
}
|
986 |
});
|
987 |
|
|
|
|
|
988 |
// Service Workerにキャッシュするファイルを送信
|
989 |
registration.active.postMessage({
|
990 |
type: 'CACHE_FILES',
|
991 |
-
files: filesToCache
|
|
|
992 |
});
|
993 |
|
994 |
statusElement.textContent = "サービスワーカーが正常に登録されました";
|
|
|
995 |
} catch (error) {
|
996 |
console.error('Service Worker登録エラー:', error);
|
997 |
statusElement.textContent = `サービスワーカー登録に失敗しました: ${error.message}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
998 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
999 |
}
|
1000 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1001 |
// 登録ボタンにイベントリスナーを追加
|
1002 |
document.getElementById('sw-register-btn').addEventListener('click', registerServiceWorker);
|
1003 |
// 要素を取得
|
|
|
931 |
window.alert(`${message}\n\nエラー詳細: ${error.message}`);
|
932 |
}
|
933 |
|
934 |
+
// サービスワーカー登録関数
|
935 |
async function registerServiceWorker() {
|
936 |
const statusElement = document.getElementById('sw-status');
|
937 |
+
const registerBtn = document.getElementById('sw-register-btn');
|
938 |
|
939 |
if (!('serviceWorker' in navigator)) {
|
940 |
statusElement.textContent = "このブラウザはService Workerをサポートしていません";
|
|
|
942 |
}
|
943 |
|
944 |
try {
|
945 |
+
// チェックボックスの状態を収集
|
946 |
+
const checkboxStates = {
|
947 |
+
'sw-video': document.getElementById('sw-video').checked,
|
948 |
+
'sw-t-video': document.getElementById('sw-t-video').checked,
|
949 |
+
'sw-piano': document.getElementById('sw-piano').checked,
|
950 |
+
'sw-soprano': document.getElementById('sw-soprano').checked,
|
951 |
+
'sw-alto': document.getElementById('sw-alto').checked,
|
952 |
+
'sw-tenor': document.getElementById('sw-tenor').checked,
|
953 |
+
'sw-combined': document.getElementById('sw-combined').checked,
|
954 |
+
'sw-t-piano': document.getElementById('sw-t-piano').checked,
|
955 |
+
'sw-t-soprano': document.getElementById('sw-t-soprano').checked,
|
956 |
+
'sw-t-alto': document.getElementById('sw-t-alto').checked,
|
957 |
+
'sw-t-tenor': document.getElementById('sw-t-tenor').checked,
|
958 |
+
'sw-t-combined': document.getElementById('sw-t-combined').checked
|
959 |
+
};
|
960 |
+
|
961 |
// チェックされたファイルを収集
|
962 |
const filesToCache = [];
|
963 |
|
964 |
+
// index.htmlは常に含める
|
965 |
+
filesToCache.push('/index.html');
|
|
|
966 |
|
967 |
// 通常のメディアファイル
|
968 |
+
if (checkboxStates['sw-video']) filesToCache.push('/v.mp4');
|
969 |
+
if (checkboxStates['sw-piano']) filesToCache.push('/p.mp3');
|
970 |
+
if (checkboxStates['sw-soprano']) filesToCache.push('/s.mp3');
|
971 |
+
if (checkboxStates['sw-alto']) filesToCache.push('/a.mp3');
|
972 |
+
if (checkboxStates['sw-tenor']) filesToCache.push('/t.mp3');
|
973 |
+
if (checkboxStates['sw-combined']) filesToCache.push('/k.mp3');
|
974 |
|
975 |
// t/ ディレクトリのメディアファイル
|
976 |
+
if (checkboxStates['sw-t-video']) filesToCache.push('/t/v.mp4');
|
977 |
+
if (checkboxStates['sw-t-piano']) filesToCache.push('/t/p.mp3');
|
978 |
+
if (checkboxStates['sw-t-soprano']) filesToCache.push('/t/s.mp3');
|
979 |
+
if (checkboxStates['sw-t-alto']) filesToCache.push('/t/a.mp3');
|
980 |
+
if (checkboxStates['sw-t-tenor']) filesToCache.push('/t/t.mp3');
|
981 |
+
if (checkboxStates['sw-t-combined']) filesToCache.push('/t/k.mp3');
|
982 |
+
|
983 |
+
registerBtn.disabled = true;
|
984 |
statusElement.textContent = "サービスワーカーを登録中...";
|
985 |
|
986 |
// Service Workerを登録
|
987 |
const registration = await navigator.serviceWorker.register('/service-worker.js');
|
988 |
|
989 |
+
// 進捗表示用のタイマー
|
990 |
+
let progress = 0;
|
991 |
+
const progressInterval = setInterval(() => {
|
992 |
+
progress += 5;
|
993 |
+
if (progress < 100) {
|
994 |
+
statusElement.textContent = `サービスワーカーを登録中... ${progress}%`;
|
995 |
+
}
|
996 |
+
}, 300);
|
997 |
+
|
998 |
// Service Workerがアクティブになるのを待つ
|
999 |
await new Promise(resolve => {
|
1000 |
if (registration.active) {
|
|
|
1011 |
}
|
1012 |
});
|
1013 |
|
1014 |
+
clearInterval(progressInterval);
|
1015 |
+
|
1016 |
// Service Workerにキャッシュするファイルを送信
|
1017 |
registration.active.postMessage({
|
1018 |
type: 'CACHE_FILES',
|
1019 |
+
files: filesToCache,
|
1020 |
+
checkboxStates: checkboxStates
|
1021 |
});
|
1022 |
|
1023 |
statusElement.textContent = "サービスワーカーが正常に登録されました";
|
1024 |
+
registerBtn.disabled = false;
|
1025 |
} catch (error) {
|
1026 |
console.error('Service Worker登録エラー:', error);
|
1027 |
statusElement.textContent = `サービスワーカー登録に失敗しました: ${error.message}`;
|
1028 |
+
registerBtn.disabled = false;
|
1029 |
+
}
|
1030 |
+
}
|
1031 |
+
|
1032 |
+
// チェックボックスの状態を復元
|
1033 |
+
async function restoreCheckboxStates() {
|
1034 |
+
try {
|
1035 |
+
const cache = await caches.open('settings-cache');
|
1036 |
+
const response = await cache.match('checkbox-states');
|
1037 |
+
|
1038 |
+
if (response) {
|
1039 |
+
const checkboxStates = await response.json();
|
1040 |
+
|
1041 |
+
for (const [id, checked] of Object.entries(checkboxStates)) {
|
1042 |
+
const checkbox = document.getElementById(id);
|
1043 |
+
if (checkbox) {
|
1044 |
+
checkbox.checked = checked;
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
}
|
1048 |
+
} catch (error) {
|
1049 |
+
console.error('チェックボックス状態の復元に失敗:', error);
|
1050 |
+
}
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
// オフライン状態をチェック
|
1054 |
+
function checkOnlineStatus() {
|
1055 |
+
const settingsSection = document.querySelector('.settings');
|
1056 |
+
if (!navigator.onLine) {
|
1057 |
+
settingsSection.style.display = 'none';
|
1058 |
+
} else {
|
1059 |
+
settingsSection.style.display = 'block';
|
1060 |
+
}
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
// 全画面時のUI表示制御
|
1064 |
+
function setupFullscreenUI() {
|
1065 |
+
const videoContainer = document.getElementById('video-container');
|
1066 |
+
const controls = document.querySelector('.video-controls');
|
1067 |
+
let hideTimeout;
|
1068 |
+
let isMouseOverControls = false;
|
1069 |
+
|
1070 |
+
// マウスがコントロール上にあるかどうかを追跡
|
1071 |
+
controls.addEventListener('mouseenter', () => {
|
1072 |
+
isMouseOverControls = true;
|
1073 |
+
clearTimeout(hideTimeout);
|
1074 |
+
controls.style.opacity = '1';
|
1075 |
+
});
|
1076 |
+
|
1077 |
+
controls.addEventListener('mouseleave', () => {
|
1078 |
+
isMouseOverControls = false;
|
1079 |
+
startHideTimeout();
|
1080 |
+
});
|
1081 |
+
|
1082 |
+
function startHideTimeout() {
|
1083 |
+
clearTimeout(hideTimeout);
|
1084 |
+
if (isFullscreen && !isMouseOverControls) {
|
1085 |
+
hideTimeout = setTimeout(() => {
|
1086 |
+
controls.style.opacity = '0';
|
1087 |
+
}, 1500);
|
1088 |
+
}
|
1089 |
}
|
1090 |
+
|
1091 |
+
// 動画コンテナでマウス移動を検出
|
1092 |
+
videoContainer.addEventListener('mousemove', () => {
|
1093 |
+
if (isFullscreen) {
|
1094 |
+
controls.style.opacity = '1';
|
1095 |
+
startHideTimeout();
|
1096 |
+
}
|
1097 |
+
});
|
1098 |
}
|
1099 |
|
1100 |
+
// DOMContentLoaded時の初期化
|
1101 |
+
document.addEventListener('DOMContentLoaded', function() {
|
1102 |
+
// チェックボックスをデフォルトでオフに
|
1103 |
+
document.querySelectorAll('.settings input[type="checkbox"]').forEach(checkbox => {
|
1104 |
+
checkbox.checked = false;
|
1105 |
+
});
|
1106 |
+
|
1107 |
+
// index.htmlのチェックボックスは必須なのでオンに
|
1108 |
+
document.getElementById('sw-index').checked = true;
|
1109 |
+
document.getElementById('sw-index').disabled = true;
|
1110 |
+
|
1111 |
+
// ルートのチェックボックスは非表示に
|
1112 |
+
document.getElementById('sw-root').parentElement.style.display = 'none';
|
1113 |
+
|
1114 |
+
// チェックボックスの状態を復元
|
1115 |
+
restoreCheckboxStates();
|
1116 |
+
|
1117 |
+
// オンライン状態をチェック
|
1118 |
+
checkOnlineStatus();
|
1119 |
+
window.addEventListener('online', checkOnlineStatus);
|
1120 |
+
window.addEventListener('offline', checkOnlineStatus);
|
1121 |
+
|
1122 |
+
// 全画面UI制御を設定
|
1123 |
+
setupFullscreenUI();
|
1124 |
+
|
1125 |
+
});
|
1126 |
// 登録ボタンにイベントリスナーを追加
|
1127 |
document.getElementById('sw-register-btn').addEventListener('click', registerServiceWorker);
|
1128 |
// 要素を取得
|