function get_filename(filePath) {
if (!filePath) return "";
return filePath.split(/[/\\]/).pop();
}
function escapeAttr(s) {
if (s == null) return "";
return String(s).replace(/&/g, "&").replace(/"/g, """).replace(//g, ">");
}
var SOON_EMPTY_IMG = '../assets/images/web/empty-state.png';
function soonEmptyBlock(title, hint, extraHtml) {
var html = '
' +
'' +
'
' + escapeAttr(title) + '
';
if (hint) {
html += '
' + escapeAttr(hint) + '
';
}
if (extraHtml) html += extraHtml;
html += '
';
return html;
}
let s_lan = "zh";
function language_str(str) {
let t = {
"noFile": { zh: "当前文件不存在!", ozh: "This file does not exist!", en: "File not found!" },
"saveTime": { zh: "保存时间:", ozh: "保存時間:", en: "Saved on:" },
"selectFile": { zh: "请选择文件", ozh: "請選擇文件", en: "Please select a file" },
"comfirm": { zh: "确认", ozh: "確認", en: "Confirm" },
"cancel": { zh: "取消", ozh: "取消", en: "Cancel" },
"SDFile": { zh: "SoonDesign模板文件", ozh: "SoonDesign模闆文件", en: "SoonDesign Template File" },
"lost": { zh: "(文件已丢失)", ozh: "(文件已丟失)", en: "(File Lost)" },
"clickToDelete": { zh: "文件已丢失,点击删除此记录", ozh: "文件已丟失,點擊刪除此記錄", en: "File lost, click to remove" },
"deleted": { zh: "已删除", ozh: "已刪除", en: "Deleted" },
"whetherSave": { zh: "是否保存当前文件?", ozh: "是否保存當前文件?", en: "Save current file?" },
"delTitle": { zh: "警告", ozh: "警告", en: "Warning" },
"delContent": { zh: "文件已丢失,确认是否删除?", ozh: "文件已丟失,確認是否刪除?", en: "File lost, confirm delete?" },
"deleteFileConfirm": { zh: "确认删除该文件?删除后无法恢复。", ozh: "確認刪除該文件?刪除後無法恢復。", en: "Delete this file? This cannot be undone." },
"deleteBtn": { zh: "删除", ozh: "刪除", en: "Delete" }
};
return t[str][s_lan] || t[str]['zh'];
}
function openDesign(type, filePath) {
if (window.platformBridge && window.platformBridge.openDesignPage) {
window.platformBridge.openDesignPage(filePath || '', type);
}
}
layui.use(['layer', 'form', 'jquery'], function () {
var $ = layui.$;
var layer = layui.layer;
layer.config({ skin: 'soon-layer' });
if (window.sysAPI && window.sysAPI.getAppVersion) {
window.sysAPI.getAppVersion().then(function (ver) {
$("#app-version").text("v" + ver);
}).catch(function () {});
}
function langua_ge(lan) {
lan = lan || 'zh';
$("[language='m']").each(function () {
$(this).html($(this).attr(lan));
});
$("[language='t']").each(function () {
$(this).attr("title", $(this).attr(lan));
});
}
var lang = localStorage.getItem("lang");
if (lang) {
s_lan = lang;
langua_ge(s_lan);
$("#language_select").val(s_lan);
} else if (window.platformBridge && window.platformBridge.getLocale) {
window.platformBridge.getLocale().then(function (loc) {
if (loc && loc.indexOf('zh') === 0) {
s_lan = loc.indexOf('TW') >= 0 ? 'ozh' : 'zh';
} else {
s_lan = 'en';
}
langua_ge(s_lan);
$("#language_select").val(s_lan);
localStorage.setItem("lang", s_lan);
});
}
$('#language_select').on('change', function () {
langua_ge($(this).find('option:selected').val());
s_lan = $(this).find('option:selected').val();
localStorage.setItem("lang", s_lan);
loadHistory();
});
function hasCloudAuth() {
if (typeof window.soonGetAccessToken === 'function') return !!window.soonGetAccessToken();
try { return !!localStorage.getItem('soon_access'); } catch (e) { return false; }
}
function makeFileKey(id, version) {
return typeof window.soonMakeFileKey === 'function'
? window.soonMakeFileKey(id, version)
: ('soondesign_file:' + id + ':v' + version);
}
var fileListState = { page: 1, size: 12, total: 0, items: [] };
var templateListState = { page: 1, size: 8, total: 0, items: [] };
function displayNameFromPath(path) {
if (!path) return 'design.soon';
var sessionPrefix = 'soondesign_session:';
if (path.indexOf(sessionPrefix) === 0) return path.substring(sessionPrefix.length);
if (path.indexOf('soondesign_file:') === 0) {
var meta = window._soonFileMeta;
if (meta && meta.name) return meta.name;
return path.replace(/^soondesign_file:(\d+).*/, '文件 #$1');
}
return get_filename(path) || 'design.soon';
}
function parseItemTime(value) {
if (!value) return 0;
var d = new Date(String(value).replace(' ', 'T'));
return isNaN(d.getTime()) ? 0 : d.getTime();
}
function mergeRecentItems(localHistory, cloudItems) {
var items = [];
var cloudById = {};
var seenCloudIds = {};
(cloudItems || []).forEach(function (c) {
if (c && c.id != null) cloudById[c.id] = c;
});
(localHistory || []).forEach(function (h) {
if (!h || !h.path) return;
var cloudMatch = String(h.path).match(/^soondesign_file:(\d+)/);
if (cloudMatch) {
var id = parseInt(cloudMatch[1], 10);
var cloud = cloudById[id];
if (cloud) {
seenCloudIds[id] = true;
items.push({
kind: 'cloud',
filePath: makeFileKey(cloud.id, cloud.version),
fileId: cloud.id,
name: cloud.name || ('文件 #' + cloud.id),
type: h.type,
sortTime: parseItemTime(cloud.updated_at || cloud.created_at || h.time),
});
return;
}
}
items.push({
kind: 'local',
filePath: h.path,
name: displayNameFromPath(h.path),
type: h.type,
sortTime: parseItemTime(h.time),
});
});
(cloudItems || []).forEach(function (c) {
if (!c || c.id == null || seenCloudIds[c.id]) return;
items.push({
kind: 'cloud',
filePath: makeFileKey(c.id, c.version),
fileId: c.id,
name: c.name || ('文件 #' + c.id),
type: null,
sortTime: parseItemTime(c.updated_at || c.created_at),
});
});
items.sort(function (a, b) { return (b.sortTime || 0) - (a.sortTime || 0); });
return items;
}
async function fetchLocalHistory() {
if (!window.sysAPI || typeof window.sysAPI.readHistory !== 'function') return [];
try {
var j = await window.sysAPI.readHistory();
return (j && Array.isArray(j.history)) ? j.history : [];
} catch (e) {
return [];
}
}
async function fetchCloudItems() {
if (!hasCloudAuth() || !window.platformBridge || !window.platformBridge.listCloudFiles) return [];
try {
var data = await window.platformBridge.listCloudFiles({ page: 1, size: 50 });
return (data && data.items) ? data.items : [];
} catch (e) {
return [];
}
}
function removeLocalHistoryPath(path) {
if (!path || !window.sysAPI || typeof window.sysAPI.readHistory !== 'function') {
return Promise.resolve();
}
return window.sysAPI.readHistory().then(function (j) {
var list = (j && Array.isArray(j.history)) ? j.history : [];
var next = list.filter(function (item) { return item.path !== path; });
if (next.length === list.length) return null;
return window.sysAPI.writeHistory({ history: next });
}).catch(function () { return null; });
}
function renderFilePager() {
var el = document.getElementById('filePager');
if (!el) return;
var page = fileListState.page;
var size = fileListState.size;
var total = fileListState.total;
var pages = Math.max(1, Math.ceil(total / size));
if (total === 0) {
el.innerHTML = '';
return;
}
el.innerHTML =
'