90 lines
3.4 KiB
JavaScript
90 lines
3.4 KiB
JavaScript
'use strict';
|
|
|
|
// Eagle's item API has no arbitrary custom fields. Keep plugin metadata in
|
|
// userData, keyed by library + item ID, without editing Eagle metadata.json.
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
|
|
function identity(sourcePath, itemId) {
|
|
const directory = path.dirname(path.resolve(sourcePath));
|
|
const match = path.basename(directory).match(/^(.+)\.info$/i);
|
|
return match
|
|
? path.dirname(directory) + ':' + (itemId || match[1])
|
|
: path.resolve(sourcePath);
|
|
}
|
|
|
|
function createStore(userDataPath, sourcePath, itemId) {
|
|
const key = crypto.createHash('sha256').update(identity(sourcePath, itemId)).digest('hex');
|
|
const directory = path.join(userDataPath, 'SpineViewer', 'preview-settings');
|
|
const file = path.join(directory, key + '.json');
|
|
return {
|
|
file,
|
|
read() {
|
|
try {
|
|
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
return typeof data.premultipliedAlpha === 'boolean' ? data.premultipliedAlpha : undefined;
|
|
} catch (e) {
|
|
if (e.code === 'ENOENT') return undefined;
|
|
throw e;
|
|
}
|
|
},
|
|
// This method is called only by the user's checkbox change event.
|
|
write(premultipliedAlpha) {
|
|
if (typeof premultipliedAlpha !== 'boolean') throw new TypeError('预乘设置必须为布尔值');
|
|
fs.mkdirSync(directory, { recursive: true });
|
|
const temp = file + '.' + crypto.randomBytes(8).toString('hex') + '.tmp';
|
|
try {
|
|
fs.writeFileSync(temp, JSON.stringify({ premultipliedAlpha }, null, 2) + '\n', { flag: 'wx' });
|
|
fs.renameSync(temp, file);
|
|
} finally {
|
|
try { fs.unlinkSync(temp); } catch (e) { if (e.code !== 'ENOENT') throw e; }
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
async function resolveDataPath(app) {
|
|
try {
|
|
const value = app && (app.userDataPath || (typeof app.getPath === 'function' && await app.getPath('userData')));
|
|
if (typeof value === 'string' && value) return value;
|
|
} catch (e) { /* Some Eagle format-view windows reject app.getPath IPC. */ }
|
|
const home = require('os').homedir();
|
|
if (process.platform === 'darwin') return path.join(home, 'Library', 'Application Support', 'Eagle');
|
|
if (process.platform === 'win32') return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Eagle');
|
|
return path.join(process.env.XDG_CONFIG_HOME || path.join(home, '.config'), 'Eagle');
|
|
}
|
|
|
|
// 尾缀表是全局偏好(不是每个素材一份):同一台机器上所有素材、所有库共用。
|
|
// 查看器在加载资源前读取它,用户的增删都会立即落盘。
|
|
function createSuffixStore(userDataPath) {
|
|
const directory = path.join(userDataPath, 'SpineViewer');
|
|
const file = path.join(directory, 'suffix-settings.json');
|
|
return {
|
|
file,
|
|
read() {
|
|
try {
|
|
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
return Array.isArray(data.suffixes) ? data.suffixes : [];
|
|
} catch (e) {
|
|
if (e.code === 'ENOENT') return [];
|
|
throw e;
|
|
}
|
|
},
|
|
// 仅在用户通过下拉列表增删尾缀时调用。
|
|
write(suffixes) {
|
|
if (!Array.isArray(suffixes)) throw new TypeError('尾缀设置必须为数组');
|
|
fs.mkdirSync(directory, { recursive: true });
|
|
const temp = file + '.' + crypto.randomBytes(8).toString('hex') + '.tmp';
|
|
try {
|
|
fs.writeFileSync(temp, JSON.stringify({ suffixes }, null, 2) + '\n', { flag: 'wx' });
|
|
fs.renameSync(temp, file);
|
|
} finally {
|
|
try { fs.unlinkSync(temp); } catch (e) { if (e.code !== 'ENOENT') throw e; }
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = { createStore, createSuffixStore, resolveDataPath };
|