mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-15 01:05:42 +02:00
enhance(frontend): preferenceのタブ間同期にBroadcast Channelを使用するように (#16819)
* enhance(frontend): preferenceのタブ間同期にBroadcast Channelを使用するように * fix * refactor: EventEmitterをextendする形に変更
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { BroadcastChannel } from 'broadcast-channel';
|
||||
import type { StorageProvider } from '@/preferences/manager.js';
|
||||
import { cloudBackup } from '@/preferences/utility.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
@@ -12,6 +13,7 @@ import { $i } from '@/i.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { TAB_ID } from '@/tab-id.js';
|
||||
|
||||
// クラウド同期用グループ名
|
||||
const syncGroup = 'default';
|
||||
|
||||
const io: StorageProvider = {
|
||||
@@ -26,7 +28,6 @@ const io: StorageProvider = {
|
||||
|
||||
save: (ctx) => {
|
||||
miLocalStorage.setItem('preferences', JSON.stringify(ctx.profile));
|
||||
miLocalStorage.setItem('latestPreferencesUpdate', `${TAB_ID}/${Date.now()}`);
|
||||
},
|
||||
|
||||
cloudGet: async (ctx) => {
|
||||
@@ -99,33 +100,47 @@ const io: StorageProvider = {
|
||||
|
||||
export const prefer = new PreferencesManager(io, $i);
|
||||
|
||||
let latestSyncedAt = Date.now();
|
||||
//#region タブ間同期
|
||||
let latestPreferencesUpdate: {
|
||||
tabId: string;
|
||||
timestamp: number;
|
||||
} | null = null;
|
||||
|
||||
function syncBetweenTabs() {
|
||||
const latest = miLocalStorage.getItem('latestPreferencesUpdate');
|
||||
if (latest == null) return;
|
||||
const preferencesChannel = new BroadcastChannel<{
|
||||
type: 'preferencesUpdate';
|
||||
tabId: string;
|
||||
timestamp: number;
|
||||
}>('preferences');
|
||||
|
||||
const latestTab = latest.split('/')[0];
|
||||
const latestAt = parseInt(latest.split('/')[1]);
|
||||
|
||||
if (latestTab === TAB_ID) return;
|
||||
if (latestAt <= latestSyncedAt) return;
|
||||
|
||||
prefer.reloadProfile();
|
||||
|
||||
latestSyncedAt = Date.now();
|
||||
|
||||
if (_DEV_) console.log('prefer:synced');
|
||||
}
|
||||
|
||||
window.setInterval(syncBetweenTabs, 5000);
|
||||
|
||||
window.document.addEventListener('visibilitychange', () => {
|
||||
if (window.document.visibilityState === 'visible') {
|
||||
syncBetweenTabs();
|
||||
}
|
||||
prefer.on('committed', () => {
|
||||
latestPreferencesUpdate = {
|
||||
tabId: TAB_ID,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
preferencesChannel.postMessage({
|
||||
type: 'preferencesUpdate',
|
||||
tabId: TAB_ID,
|
||||
timestamp: latestPreferencesUpdate.timestamp,
|
||||
});
|
||||
});
|
||||
|
||||
preferencesChannel.addEventListener('message', (msg) => {
|
||||
if (msg.type === 'preferencesUpdate') {
|
||||
if (msg.tabId === TAB_ID) return;
|
||||
if (latestPreferencesUpdate != null) {
|
||||
if (msg.timestamp <= latestPreferencesUpdate.timestamp) return;
|
||||
}
|
||||
prefer.reloadProfile();
|
||||
if (_DEV_) console.log('prefer:received update from other tab');
|
||||
latestPreferencesUpdate = {
|
||||
tabId: msg.tabId,
|
||||
timestamp: msg.timestamp,
|
||||
};
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region 定期クラウドバックアップ
|
||||
let latestBackupAt = 0;
|
||||
|
||||
window.setInterval(() => {
|
||||
@@ -138,6 +153,7 @@ window.setInterval(() => {
|
||||
latestBackupAt = Date.now();
|
||||
});
|
||||
}, 1000 * 60 * 3);
|
||||
//#endregion
|
||||
|
||||
if (_DEV_) {
|
||||
(window as any).prefer = prefer;
|
||||
|
||||
Reference in New Issue
Block a user