自动缩略图插件审核修改
This commit is contained in:
1 parent
f4e69707c3
commit
d02370d6bd
28 files changed
+2308
-50
No files matched your search
@@ -0,0 +1,127 @@
|
||||
// 多个 Eagle 插件窗口共用 localStorage,用它协调唯一的活动监听实例。
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const KEY = 'spine-thumbnail-active-instance';
|
||||
const STALE_MS = 3500;
|
||||
|
||||
function createFileStorage(file) {
|
||||
return {
|
||||
file,
|
||||
getItem(key) {
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
return typeof data[key] === 'string' ? data[key] : null;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
setItem(key, value) {
|
||||
let data = {};
|
||||
try {
|
||||
const existing = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
if (existing && typeof existing === 'object') data = existing;
|
||||
} catch (error) { /* first write or damaged file */ }
|
||||
data[key] = String(value);
|
||||
fs.mkdirSync(path.dirname(file), { recursive: true });
|
||||
const temp = file + '.' + process.pid + '.' + Date.now() + '.' + Math.random().toString(16).slice(2) + '.tmp';
|
||||
fs.writeFileSync(temp, JSON.stringify(data), 'utf8');
|
||||
fs.renameSync(temp, file);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function readState(storage) {
|
||||
try {
|
||||
const state = JSON.parse(storage.getItem(KEY));
|
||||
if (!state || typeof state.id !== 'string' || !Number.isFinite(state.updatedAt)) return null;
|
||||
return state;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function writeState(storage, id, visible, now) {
|
||||
const state = { id, visible, updatedAt: now };
|
||||
try { storage.setItem(KEY, JSON.stringify(state)); } catch (error) { /* 无本地存储时仍可运行 */ }
|
||||
return state;
|
||||
}
|
||||
|
||||
function createCoordinator(options) {
|
||||
const storage = options.storage;
|
||||
const id = options.id;
|
||||
const visible = options.isVisible || (() => true);
|
||||
const hide = options.hide || (() => {});
|
||||
const now = options.now || Date.now;
|
||||
const staleMs = options.staleMs || STALE_MS;
|
||||
const intervalMs = options.intervalMs || 1000;
|
||||
let active = false;
|
||||
let started = false;
|
||||
let hiddenForDuplicate = false;
|
||||
let timer = null;
|
||||
|
||||
function claim() {
|
||||
writeState(storage, id, visible(), now());
|
||||
hiddenForDuplicate = false;
|
||||
if (!active) {
|
||||
active = true;
|
||||
if (options.onActiveChanged) options.onActiveChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
function evaluate() {
|
||||
const state = readState(storage);
|
||||
const currentVisible = visible();
|
||||
const canClaim = !state ||
|
||||
state.id === id ||
|
||||
now() - state.updatedAt > staleMs;
|
||||
const nextActive = canClaim;
|
||||
if (nextActive) {
|
||||
claim();
|
||||
} else if (currentVisible && !hiddenForDuplicate) {
|
||||
hiddenForDuplicate = true;
|
||||
try { hide(); } catch (error) { /* 隐藏失败不影响主窗口 */ }
|
||||
}
|
||||
if (nextActive !== active) {
|
||||
active = nextActive;
|
||||
if (options.onActiveChanged) options.onActiveChanged(active);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
function handleVisibility() {
|
||||
if (visible()) claim();
|
||||
else evaluate();
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (started) return active;
|
||||
started = true;
|
||||
const state = readState(storage);
|
||||
const canStart = visible() ||
|
||||
!state ||
|
||||
state.id === id ||
|
||||
now() - state.updatedAt > staleMs;
|
||||
if (canStart) claim();
|
||||
else evaluate();
|
||||
timer = setInterval(evaluate, intervalMs);
|
||||
return active;
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (timer) clearInterval(timer);
|
||||
timer = null;
|
||||
started = false;
|
||||
}
|
||||
|
||||
return { start, stop, evaluate, handleVisibility, isActive: () => active };
|
||||
}
|
||||
|
||||
const api = { createCoordinator, createFileStorage, KEY, STALE_MS };
|
||||
if (typeof window !== 'undefined') window.SpineThumbInstanceCoordinator = api;
|
||||
else if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
||||
|
||||
})();
|
||||
Reference in new issue
Block a user