mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-30 04:19:27 +00:00
feat: add ForceSync mode selector (Jump to Others / Jump to Me)
This commit is contained in:
@@ -289,7 +289,13 @@
|
|||||||
<button id="pauseBtn" class="primary" style="flex:1; background: var(--error);">⏸ Pause</button>
|
<button id="pauseBtn" class="primary" style="flex:1; background: var(--error);">⏸ Pause</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="forceSyncBtn" class="primary" style="background: linear-gradient(135deg, #6366f1, #a855f7); width: 100%; margin-bottom: 15px;">⚡ Force Sync Everyone</button>
|
<div style="display: flex; gap: 8px; margin-bottom: 15px; align-items: stretch;">
|
||||||
|
<button id="forceSyncBtn" class="primary" style="background: linear-gradient(135deg, #6366f1, #a855f7); flex: 1;">⚡ Force Sync</button>
|
||||||
|
<select id="forceSyncMode" style="width: auto; min-width: 130px; background: var(--card); border: 1px solid #334155; color: white; padding: 10px 8px; border-radius: 8px; font-size: 11px; font-family: inherit; cursor: pointer; align-self: stretch;" title="Choose sync target">
|
||||||
|
<option value="jump-to-others">Jump to Others</option>
|
||||||
|
<option value="jump-to-me">Jump to Me</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- NEW: Last Action Status Card -->
|
<!-- NEW: Last Action Status Card -->
|
||||||
<label>Last Activity Status</label>
|
<label>Last Activity Status</label>
|
||||||
|
|||||||
+52
-24
@@ -8,6 +8,7 @@ const elements = {
|
|||||||
copyInvite: document.getElementById('copyInvite'),
|
copyInvite: document.getElementById('copyInvite'),
|
||||||
targetTab: document.getElementById('targetTab'),
|
targetTab: document.getElementById('targetTab'),
|
||||||
forceSyncBtn: document.getElementById('forceSyncBtn'),
|
forceSyncBtn: document.getElementById('forceSyncBtn'),
|
||||||
|
forceSyncMode: document.getElementById('forceSyncMode'),
|
||||||
peerList: document.getElementById('peerList'),
|
peerList: document.getElementById('peerList'),
|
||||||
logList: document.getElementById('logList'),
|
logList: document.getElementById('logList'),
|
||||||
clearLogs: document.getElementById('clearLogs'),
|
clearLogs: document.getElementById('clearLogs'),
|
||||||
@@ -53,7 +54,7 @@ let lastPeersJson = null;
|
|||||||
// --- Initialization ---
|
// --- Initialization ---
|
||||||
async function init() {
|
async function init() {
|
||||||
// Load Settings
|
// Load Settings
|
||||||
const data = await chrome.storage.sync.get(['serverUrl', 'useCustomServer', 'roomId', 'password', 'filterNoise', 'username', 'autoSyncNextEpisode']);
|
const data = await chrome.storage.sync.get(['serverUrl', 'useCustomServer', 'roomId', 'password', 'filterNoise', 'username', 'autoSyncNextEpisode', 'forceSyncMode']);
|
||||||
let username = data.username;
|
let username = data.username;
|
||||||
if (!username) {
|
if (!username) {
|
||||||
const adjs = ['Happy', 'Cool', 'Fast', 'Smart', 'Brave', 'Calm', 'Sneaky', 'Lazy', 'Wild', 'Chill', 'Lucky', 'Epic'];
|
const adjs = ['Happy', 'Cool', 'Fast', 'Smart', 'Brave', 'Calm', 'Sneaky', 'Lazy', 'Wild', 'Chill', 'Lucky', 'Epic'];
|
||||||
@@ -68,6 +69,7 @@ async function init() {
|
|||||||
elements.username.value = username;
|
elements.username.value = username;
|
||||||
elements.filterNoise.checked = data.filterNoise !== false;
|
elements.filterNoise.checked = data.filterNoise !== false;
|
||||||
elements.autoSyncNextEpisode.checked = data.autoSyncNextEpisode !== false;
|
elements.autoSyncNextEpisode.checked = data.autoSyncNextEpisode !== false;
|
||||||
|
elements.forceSyncMode.value = data.forceSyncMode || 'jump-to-others';
|
||||||
|
|
||||||
// Set Version Info
|
// Set Version Info
|
||||||
const versionEl = document.getElementById('appVersion');
|
const versionEl = document.getElementById('appVersion');
|
||||||
@@ -483,7 +485,7 @@ function applyConnectionStatus(status) {
|
|||||||
// Preserve icons for Remote Control buttons
|
// Preserve icons for Remote Control buttons
|
||||||
elements.playBtn.textContent = '▶ Play';
|
elements.playBtn.textContent = '▶ Play';
|
||||||
elements.pauseBtn.textContent = '⏸ Pause';
|
elements.pauseBtn.textContent = '⏸ Pause';
|
||||||
elements.forceSyncBtn.textContent = '⚡ Force Sync Everyone';
|
elements.forceSyncBtn.textContent = '⚡ Force Sync';
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateHistory(history) {
|
function updateHistory(history) {
|
||||||
@@ -650,6 +652,10 @@ elements.autoSyncNextEpisode.addEventListener('change', () => {
|
|||||||
chrome.storage.sync.set({ autoSyncNextEpisode: elements.autoSyncNextEpisode.checked });
|
chrome.storage.sync.set({ autoSyncNextEpisode: elements.autoSyncNextEpisode.checked });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
elements.forceSyncMode.addEventListener('change', () => {
|
||||||
|
chrome.storage.sync.set({ forceSyncMode: elements.forceSyncMode.value });
|
||||||
|
});
|
||||||
|
|
||||||
elements.serverUrl.addEventListener('input', () => {
|
elements.serverUrl.addEventListener('input', () => {
|
||||||
chrome.storage.sync.set({ serverUrl: elements.serverUrl.value });
|
chrome.storage.sync.set({ serverUrl: elements.serverUrl.value });
|
||||||
});
|
});
|
||||||
@@ -783,10 +789,28 @@ elements.forceSyncBtn.addEventListener('click', async () => {
|
|||||||
const status = await new Promise(r => chrome.runtime.sendMessage({ type: 'GET_STATUS' }, r));
|
const status = await new Promise(r => chrome.runtime.sendMessage({ type: 'GET_STATUS' }, r));
|
||||||
if (!status || !status.targetTabId) return;
|
if (!status || !status.targetTabId) return;
|
||||||
|
|
||||||
// Lockout to prevent spamming
|
const mode = elements.forceSyncMode.value;
|
||||||
|
let targetTime = null;
|
||||||
|
|
||||||
|
if (mode === 'jump-to-others') {
|
||||||
|
const peers = status.peers || [];
|
||||||
|
const otherTimes = peers
|
||||||
|
.filter(p => typeof p === 'object' && p.peerId !== localPeerId && p.currentTime != null && !isNaN(p.currentTime))
|
||||||
|
.map(p => p.currentTime);
|
||||||
|
|
||||||
|
if (otherTimes.length === 0) {
|
||||||
|
showError('No other peers with a known time. Switch to "Jump to Me".');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
otherTimes.sort((a, b) => a - b);
|
||||||
|
const mid = Math.floor(otherTimes.length / 2);
|
||||||
|
targetTime = otherTimes.length % 2 !== 0 ? otherTimes[mid] : (otherTimes[mid - 1] + otherTimes[mid]) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
const originalText = elements.forceSyncBtn.textContent;
|
const originalText = elements.forceSyncBtn.textContent;
|
||||||
elements.forceSyncBtn.disabled = true;
|
elements.forceSyncBtn.disabled = true;
|
||||||
elements.forceSyncBtn.textContent = 'Syncing...';
|
elements.forceSyncBtn.textContent = mode === 'jump-to-others' ? `Syncing to group (${formatTime(targetTime)})...` : 'Syncing...';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
elements.forceSyncBtn.disabled = false;
|
elements.forceSyncBtn.disabled = false;
|
||||||
elements.forceSyncBtn.textContent = originalText;
|
elements.forceSyncBtn.textContent = originalText;
|
||||||
@@ -802,26 +826,30 @@ elements.forceSyncBtn.addEventListener('click', async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.tabs.sendMessage(tabId, { action: 'get_current_time' }, (response) => {
|
if (mode === 'jump-to-me') {
|
||||||
if (chrome.runtime.lastError || !response || response.currentTime === undefined) {
|
chrome.tabs.sendMessage(tabId, { action: 'get_current_time' }, (response) => {
|
||||||
chrome.scripting.executeScript({
|
if (chrome.runtime.lastError || !response || response.currentTime === undefined) {
|
||||||
target: { tabId },
|
chrome.scripting.executeScript({
|
||||||
files: ['content.js']
|
target: { tabId },
|
||||||
}).then(() => {
|
files: ['content.js']
|
||||||
setTimeout(() => {
|
}).then(() => {
|
||||||
chrome.tabs.sendMessage(tabId, { action: 'get_current_time' }, (retryResponse) => {
|
setTimeout(() => {
|
||||||
if (retryResponse && retryResponse.currentTime !== undefined) {
|
chrome.tabs.sendMessage(tabId, { action: 'get_current_time' }, (retryResponse) => {
|
||||||
sendForceSync(retryResponse.currentTime);
|
if (retryResponse && retryResponse.currentTime !== undefined) {
|
||||||
}
|
sendForceSync(retryResponse.currentTime);
|
||||||
});
|
}
|
||||||
}, 500);
|
});
|
||||||
}).catch(() => {
|
}, 500);
|
||||||
showError('Could not connect to video tab.');
|
}).catch(() => {
|
||||||
});
|
showError('Could not connect to video tab.');
|
||||||
return;
|
});
|
||||||
}
|
return;
|
||||||
sendForceSync(response.currentTime);
|
}
|
||||||
});
|
sendForceSync(response.currentTime);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sendForceSync(targetTime);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
elements.playBtn.addEventListener('click', () => {
|
elements.playBtn.addEventListener('click', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user