Trim duplicated UI helpers

This commit is contained in:
ajp_anton
2026-07-15 19:34:42 +00:00
parent a4bb9a98c2
commit 2968412374
5 changed files with 52 additions and 56 deletions
@@ -515,12 +515,7 @@
} }
} }
function prop(obj, pascal, camel, fallback) { var prop = M.prop;
if (!obj) return fallback;
if (obj[pascal] !== undefined) return obj[pascal];
if (obj[camel] !== undefined) return obj[camel];
return fallback;
}
function formatUnixTime(value) { function formatUnixTime(value) {
value = Number(value || 0); value = Number(value || 0);
@@ -629,13 +624,7 @@
} }
} }
function formatBytes(bytes) { var formatBytes = M.formatBytes;
bytes = Number(bytes || 0);
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KiB";
if (bytes < 1024 * 1024 * 1024) return (bytes / 1024 / 1024).toFixed(1) + " MiB";
return (bytes / 1024 / 1024 / 1024).toFixed(1) + " GiB";
}
async function loadExportInfo() { async function loadExportInfo() {
try { try {
@@ -652,14 +641,6 @@
} }
} }
function showModal(id) {
document.getElementById(id).hidden = false;
}
function hideModals() {
Array.prototype.slice.call(document.querySelectorAll(".ml-modal")).forEach(function (modal) { modal.hidden = true; });
}
function syncAssetCheckboxes() { function syncAssetCheckboxes() {
document.getElementById("ml-export-assets").disabled = !document.getElementById("ml-export-db").checked; document.getElementById("ml-export-assets").disabled = !document.getElementById("ml-export-db").checked;
if (document.getElementById("ml-export-assets").disabled) document.getElementById("ml-export-assets").checked = false; if (document.getElementById("ml-export-assets").disabled) document.getElementById("ml-export-assets").checked = false;
@@ -689,15 +670,8 @@
}); });
if (!response.ok) throw new Error("HTTP " + response.status); if (!response.ok) throw new Error("HTTP " + response.status);
var blob = await response.blob(); var blob = await response.blob();
var url = URL.createObjectURL(blob); M.downloadBlob(blob, "multilang-export.zip");
var a = document.createElement("a"); M.hideModals();
a.href = url;
a.download = "multilang-export.zip";
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
hideModals();
M.setStatus(status, "Export created."); M.setStatus(status, "Export created.");
} }
@@ -719,7 +693,7 @@
}); });
if (!response.ok) throw new Error("HTTP " + response.status); if (!response.ok) throw new Error("HTTP " + response.status);
var result = await response.json(); var result = await response.json();
hideModals(); M.hideModals();
await load(); await load();
M.setStatus(status, "Import complete. Users: " + (result.UserSettingsImported ?? result.userSettingsImported ?? 0) + ", translations: " + (result.TranslationsImported ?? result.translationsImported ?? 0) + "."); M.setStatus(status, "Import complete. Users: " + (result.UserSettingsImported ?? result.userSettingsImported ?? 0) + ", translations: " + (result.TranslationsImported ?? result.translationsImported ?? 0) + ".");
} }
@@ -731,7 +705,7 @@
} }
M.setStatus(status, "Cleaning up..."); M.setStatus(status, "Cleaning up...");
await M.post("/Multilang/CleanupAll", { Confirm: true }); await M.post("/Multilang/CleanupAll", { Confirm: true });
hideModals(); M.hideModals();
await load(); await load();
M.setStatus(status, "Multilang data cleaned up."); M.setStatus(status, "Multilang data cleaned up.");
} }
@@ -893,16 +867,16 @@
document.getElementById("ml-cache-refresh").addEventListener("click", loadCacheDiagnostics); document.getElementById("ml-cache-refresh").addEventListener("click", loadCacheDiagnostics);
document.getElementById("ml-cache-clear").addEventListener("click", clearCacheEntries); document.getElementById("ml-cache-clear").addEventListener("click", clearCacheEntries);
document.getElementById("ml-refresh-activity-refresh").addEventListener("click", loadRefreshDiagnostics); document.getElementById("ml-refresh-activity-refresh").addEventListener("click", loadRefreshDiagnostics);
document.getElementById("ml-export-open").addEventListener("click", function () { loadExportInfo(); syncAssetCheckboxes(); showModal("ml-export-modal"); }); document.getElementById("ml-export-open").addEventListener("click", function () { loadExportInfo(); syncAssetCheckboxes(); M.showModal("ml-export-modal"); });
document.getElementById("ml-import-open").addEventListener("click", function () { loadExportInfo(); syncAssetCheckboxes(); showModal("ml-import-modal"); }); document.getElementById("ml-import-open").addEventListener("click", function () { loadExportInfo(); syncAssetCheckboxes(); M.showModal("ml-import-modal"); });
document.getElementById("ml-cleanup-open").addEventListener("click", function () { document.getElementById("ml-cleanup-confirm").checked = false; showModal("ml-cleanup-modal"); }); document.getElementById("ml-cleanup-open").addEventListener("click", function () { document.getElementById("ml-cleanup-confirm").checked = false; M.showModal("ml-cleanup-modal"); });
document.getElementById("ml-export-db").addEventListener("change", syncAssetCheckboxes); document.getElementById("ml-export-db").addEventListener("change", syncAssetCheckboxes);
document.getElementById("ml-import-db").addEventListener("change", syncAssetCheckboxes); document.getElementById("ml-import-db").addEventListener("change", syncAssetCheckboxes);
document.getElementById("ml-export-run").addEventListener("click", function () { downloadExport().catch(function (err) { M.setStatus(status, String(err), true); }); }); document.getElementById("ml-export-run").addEventListener("click", function () { downloadExport().catch(function (err) { M.setStatus(status, String(err), true); }); });
document.getElementById("ml-import-run").addEventListener("click", function () { runImport().catch(function (err) { M.setStatus(status, String(err), true); }); }); document.getElementById("ml-import-run").addEventListener("click", function () { runImport().catch(function (err) { M.setStatus(status, String(err), true); }); });
document.getElementById("ml-cleanup-run").addEventListener("click", function () { runCleanupAll().catch(function (err) { M.setStatus(status, String(err), true); }); }); document.getElementById("ml-cleanup-run").addEventListener("click", function () { runCleanupAll().catch(function (err) { M.setStatus(status, String(err), true); }); });
Array.prototype.slice.call(document.querySelectorAll("[data-modal-close]")).forEach(function (button) { Array.prototype.slice.call(document.querySelectorAll("[data-modal-close]")).forEach(function (button) {
button.addEventListener("click", hideModals); button.addEventListener("click", function () { M.hideModals(); });
}); });
document.getElementById("ml-log-enabled").addEventListener("change", function () { document.getElementById("ml-log-enabled").addEventListener("change", function () {
if (!this.checked) document.getElementById("ml-log-verbose").checked = false; if (!this.checked) document.getElementById("ml-log-verbose").checked = false;
@@ -37,6 +37,7 @@
var mode = document.getElementById("ml-debug-mode"); var mode = document.getElementById("ml-debug-mode");
var meta = document.getElementById("ml-debug-meta"); var meta = document.getElementById("ml-debug-meta");
var lastJson = ""; var lastJson = "";
var prop = M.prop;
function itemId() { function itemId() {
var match = location.pathname.match(/\/Multilang\/DebugUi\/([^/?#]+)/i); var match = location.pathname.match(/\/Multilang\/DebugUi\/([^/?#]+)/i);
@@ -63,13 +64,6 @@
].join("\n"); ].join("\n");
} }
function prop(obj, pascal, camel, fallback) {
if (!obj) return fallback;
if (obj[pascal] !== undefined) return obj[pascal];
if (obj[camel] !== undefined) return obj[camel];
return fallback;
}
function make(tag, className, text) { function make(tag, className, text) {
var el = document.createElement(tag); var el = document.createElement(tag);
if (className) el.className = className; if (className) el.className = className;
@@ -61,6 +61,40 @@
el.style.color = error ? "#ff9b9b" : ""; el.style.color = error ? "#ff9b9b" : "";
} }
function prop(obj, pascal, camel, fallback) {
if (!obj) return fallback;
if (obj[pascal] !== undefined) return obj[pascal];
if (obj[camel] !== undefined) return obj[camel];
return fallback;
}
function formatBytes(bytes) {
bytes = Number(bytes || 0);
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KiB";
if (bytes < 1024 * 1024 * 1024) return (bytes / 1024 / 1024).toFixed(1) + " MiB";
return (bytes / 1024 / 1024 / 1024).toFixed(1) + " GiB";
}
function showModal(id) {
document.getElementById(id).hidden = false;
}
function hideModals(selector) {
[...document.querySelectorAll(selector || ".ml-modal")].forEach((modal) => { modal.hidden = true; });
}
function downloadBlob(blob, name) {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
function chip(label) { function chip(label) {
const el = document.createElement("span"); const el = document.createElement("span");
el.className = "ml-chip"; el.className = "ml-chip";
@@ -105,6 +139,11 @@
authHeaders, authHeaders,
splitList, splitList,
setStatus, setStatus,
prop,
formatBytes,
showModal,
hideModals,
downloadBlob,
chip, chip,
bucketValues, bucketValues,
renderBucket, renderBucket,
@@ -1164,14 +1164,7 @@
}); });
if (!response.ok) throw new Error("HTTP " + response.status); if (!response.ok) throw new Error("HTTP " + response.status);
var blob = await response.blob(); var blob = await response.blob();
var url = URL.createObjectURL(blob); M.downloadBlob(blob, "multilang-user-settings.zip");
var a = document.createElement("a");
a.href = url;
a.download = "multilang-user-settings.zip";
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
M.setStatus(status, "Export created."); M.setStatus(status, "Export created.");
} }
@@ -6,7 +6,6 @@ using Jellyfin.Plugin.Multilang.Configuration;
using Jellyfin.Plugin.Multilang.Data; using Jellyfin.Plugin.Multilang.Data;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.Multilang.Services.Backup; namespace Jellyfin.Plugin.Multilang.Services.Backup;
@@ -21,18 +20,15 @@ public sealed class MultilangBackupService
private readonly TranslationStore _store; private readonly TranslationStore _store;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
private readonly ILogger<MultilangBackupService> _logger;
public MultilangBackupService( public MultilangBackupService(
TranslationStore store, TranslationStore store,
ILibraryManager libraryManager, ILibraryManager libraryManager,
IUserManager userManager, IUserManager userManager)
ILogger<MultilangBackupService> logger)
{ {
_store = store; _store = store;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_userManager = userManager; _userManager = userManager;
_logger = logger;
} }
public BackupStorageInfo GetStorageInfo() public BackupStorageInfo GetStorageInfo()