mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-09-04 15:05:20 +00:00
refactor(extension): extract tab management logic into independent module
This commit is contained in:
+17
-66
@@ -2,6 +2,7 @@ import { EVENTS, PROTOCOL_VERSION, OFFICIAL_SERVER_URL, OFFICIAL_SERVER_TOKEN, E
|
|||||||
import { generateUsername } from './shared/names.js';
|
import { generateUsername } from './shared/names.js';
|
||||||
import { loadLocale, getMessage, getSystemLanguage } from './i18n.js';
|
import { loadLocale, getMessage, getSystemLanguage } from './i18n.js';
|
||||||
import { sameEpisode } from './episode-utils.js';
|
import { sameEpisode } from './episode-utils.js';
|
||||||
|
import { initTabManager } from './modules/tab-manager.js';
|
||||||
|
|
||||||
// --- Uninstall URL Initialization ---
|
// --- Uninstall URL Initialization ---
|
||||||
chrome.runtime.onInstalled.addListener((details) => {
|
chrome.runtime.onInstalled.addListener((details) => {
|
||||||
@@ -1899,72 +1900,22 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener(async (changes, area) => {
|
initTabManager({
|
||||||
if (area !== 'local' || !changes.audioSettings) return;
|
getCurrentTabId: () => currentTabId,
|
||||||
await ensureState();
|
setCurrentTabId: (val) => { currentTabId = val; },
|
||||||
if (!currentTabId) return;
|
setCurrentTabTitle: (val) => { currentTabTitle = val; },
|
||||||
|
setLastContentHeartbeatAt: (val) => { lastContentHeartbeatAt = val; },
|
||||||
chrome.tabs.sendMessage(currentTabId, {
|
setRoomIdleSince: (val) => { roomIdleSince = val; },
|
||||||
action: 'APPLY_AUDIO_SETTINGS',
|
getCurrentRoom: () => currentRoom,
|
||||||
settings: changes.audioSettings.newValue
|
getPeerId: () => peerId,
|
||||||
}).catch(() => {});
|
getStorageInitialized: () => storageInitialized,
|
||||||
});
|
updateBadgeStatus,
|
||||||
|
addLog,
|
||||||
// Tab removal listener
|
getSettings,
|
||||||
chrome.tabs.onRemoved.addListener(async (tabId) => {
|
emit,
|
||||||
await ensureState();
|
applyAudioSettingsToTab,
|
||||||
if (tabId === currentTabId) {
|
ensureState,
|
||||||
const wasInRoom = !!currentRoom;
|
EVENTS
|
||||||
currentTabId = null;
|
|
||||||
currentTabTitle = null;
|
|
||||||
lastContentHeartbeatAt = null;
|
|
||||||
roomIdleSince = Date.now();
|
|
||||||
chrome.storage.session.set({ currentTabId: null, currentTabTitle: null, roomIdleSince, lastContentHeartbeatAt });
|
|
||||||
updateBadgeStatus();
|
|
||||||
addLog('Target tab closed.', 'warn');
|
|
||||||
|
|
||||||
if (wasInRoom) {
|
|
||||||
const roomAtClose = currentRoom;
|
|
||||||
getSettings().then(settings => {
|
|
||||||
if (currentRoom !== roomAtClose) return;
|
|
||||||
|
|
||||||
emit(EVENTS.PEER_STATUS, {
|
|
||||||
peerId,
|
|
||||||
playbackState: 'paused',
|
|
||||||
currentTime: null,
|
|
||||||
mediaTitle: null,
|
|
||||||
username: settings.username,
|
|
||||||
tabTitle: null
|
|
||||||
});
|
|
||||||
|
|
||||||
if (currentRoom && Array.isArray(currentRoom.peers)) {
|
|
||||||
const me = currentRoom.peers.find(p => (p.peerId || p) === peerId);
|
|
||||||
if (me && typeof me === 'object') {
|
|
||||||
me.playbackState = 'paused';
|
|
||||||
me.currentTime = null;
|
|
||||||
me.mediaTitle = null;
|
|
||||||
me.tabTitle = null;
|
|
||||||
me.lastHeartbeat = Date.now();
|
|
||||||
if (storageInitialized) chrome.storage.session.set({ currentRoom });
|
|
||||||
chrome.runtime.sendMessage({ type: 'PEER_UPDATE', peers: currentRoom.peers }).catch(() => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(() => {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Re-inject on full page refresh
|
|
||||||
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, _tab) => {
|
|
||||||
await ensureState();
|
|
||||||
if (currentTabId && tabId === parseInt(currentTabId) && changeInfo.status === 'complete') {
|
|
||||||
chrome.scripting.executeScript({
|
|
||||||
target: { tabId },
|
|
||||||
files: ['content.js']
|
|
||||||
})
|
|
||||||
.then(() => applyAudioSettingsToTab(tabId))
|
|
||||||
.catch(() => {});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial Connect — only if user has an active room configuration
|
// Initial Connect — only if user has an active room configuration
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
export function initTabManager({
|
||||||
|
getCurrentTabId,
|
||||||
|
setCurrentTabId,
|
||||||
|
setCurrentTabTitle,
|
||||||
|
setLastContentHeartbeatAt,
|
||||||
|
setRoomIdleSince,
|
||||||
|
getCurrentRoom,
|
||||||
|
getPeerId,
|
||||||
|
getStorageInitialized,
|
||||||
|
updateBadgeStatus,
|
||||||
|
addLog,
|
||||||
|
getSettings,
|
||||||
|
emit,
|
||||||
|
applyAudioSettingsToTab,
|
||||||
|
ensureState,
|
||||||
|
EVENTS
|
||||||
|
}) {
|
||||||
|
chrome.storage.onChanged.addListener(async (changes, area) => {
|
||||||
|
if (area !== 'local' || !changes.audioSettings) return;
|
||||||
|
await ensureState();
|
||||||
|
const tabId = getCurrentTabId();
|
||||||
|
if (!tabId) return;
|
||||||
|
|
||||||
|
chrome.tabs.sendMessage(tabId, {
|
||||||
|
action: 'APPLY_AUDIO_SETTINGS',
|
||||||
|
settings: changes.audioSettings.newValue
|
||||||
|
}).catch(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.tabs.onRemoved.addListener(async (tabId) => {
|
||||||
|
await ensureState();
|
||||||
|
if (tabId === getCurrentTabId()) {
|
||||||
|
const wasInRoom = !!getCurrentRoom();
|
||||||
|
setCurrentTabId(null);
|
||||||
|
setCurrentTabTitle(null);
|
||||||
|
setLastContentHeartbeatAt(null);
|
||||||
|
const now = Date.now();
|
||||||
|
setRoomIdleSince(now);
|
||||||
|
chrome.storage.session.set({
|
||||||
|
currentTabId: null,
|
||||||
|
currentTabTitle: null,
|
||||||
|
roomIdleSince: now,
|
||||||
|
lastContentHeartbeatAt: null
|
||||||
|
});
|
||||||
|
updateBadgeStatus();
|
||||||
|
addLog('Target tab closed.', 'warn');
|
||||||
|
|
||||||
|
if (wasInRoom) {
|
||||||
|
const roomAtClose = getCurrentRoom();
|
||||||
|
getSettings().then(settings => {
|
||||||
|
if (getCurrentRoom() !== roomAtClose) return;
|
||||||
|
|
||||||
|
emit(EVENTS.PEER_STATUS, {
|
||||||
|
peerId: getPeerId(),
|
||||||
|
playbackState: 'paused',
|
||||||
|
currentTime: null,
|
||||||
|
mediaTitle: null,
|
||||||
|
username: settings.username,
|
||||||
|
tabTitle: null
|
||||||
|
});
|
||||||
|
|
||||||
|
const room = getCurrentRoom();
|
||||||
|
if (room && Array.isArray(room.peers)) {
|
||||||
|
const me = room.peers.find(p => (p.peerId || p) === getPeerId());
|
||||||
|
if (me && typeof me === 'object') {
|
||||||
|
me.playbackState = 'paused';
|
||||||
|
me.currentTime = null;
|
||||||
|
me.mediaTitle = null;
|
||||||
|
me.tabTitle = null;
|
||||||
|
me.lastHeartbeat = Date.now();
|
||||||
|
if (getStorageInitialized()) {
|
||||||
|
chrome.storage.session.set({ currentRoom: room });
|
||||||
|
}
|
||||||
|
chrome.runtime.sendMessage({ type: 'PEER_UPDATE', peers: room.peers }).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, _tab) => {
|
||||||
|
await ensureState();
|
||||||
|
const curTabId = getCurrentTabId();
|
||||||
|
if (curTabId && tabId === parseInt(curTabId) && changeInfo.status === 'complete') {
|
||||||
|
chrome.scripting.executeScript({
|
||||||
|
target: { tabId },
|
||||||
|
files: ['content.js']
|
||||||
|
})
|
||||||
|
.then(() => applyAudioSettingsToTab(tabId))
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user