feat: add profile language preferences and refine toast, dropdown and history UI
This commit is contained in:
+17
-14
@@ -7,6 +7,8 @@
|
||||
* See LICENSE file in repository root for details.
|
||||
*/
|
||||
|
||||
import { formatDateTime, formatNumber, tp } from "@rustpad/i18n";
|
||||
|
||||
import { api, uploadWithProgress } from "@rustpad/api";
|
||||
import { copyText } from "@rustpad/clipboard";
|
||||
import { prepareImageFile } from "@rustpad/image-upload";
|
||||
@@ -20,14 +22,14 @@ function escapeHtml(value) {
|
||||
|
||||
function formatBytes(value) {
|
||||
const bytes = Number(value) || 0;
|
||||
if (bytes < 1024) return `${bytes} B`;
|
||||
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
||||
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
if (bytes < 1024) return `${formatNumber(bytes)} B`;
|
||||
if (bytes < 1024 * 1024) return `${formatNumber(bytes / 1024, { maximumFractionDigits: 1 })} KB`;
|
||||
return `${formatNumber(bytes / (1024 * 1024), { maximumFractionDigits: 1 })} MB`;
|
||||
}
|
||||
|
||||
function formatDate(value) {
|
||||
const date = new Date(value);
|
||||
return Number.isNaN(date.getTime()) ? "" : date.toLocaleString("pl-PL");
|
||||
return Number.isNaN(date.getTime()) ? "" : formatDateTime(date);
|
||||
}
|
||||
|
||||
function isVideo(mimeType) {
|
||||
@@ -114,6 +116,7 @@ function createVideoInsertDialog() {
|
||||
}
|
||||
|
||||
export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxSize = () => 0, canDelete, canUpload, canEdit = () => true, getDeleteRestrictionMessage = () => "", toast, onFilesChanged = () => { } }) {
|
||||
const notify = (type, message, options = {}) => toast(message, { ...options, type });
|
||||
const dialog = document.querySelector("#files-dialog");
|
||||
const list = document.querySelector("#files-list");
|
||||
const input = document.querySelector("#file-input");
|
||||
@@ -173,7 +176,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
try {
|
||||
const files = await api(endpoints.list, { method: "PUT", body: JSON.stringify({ access_token: getAccessToken() || null }) });
|
||||
const totalSize = files.reduce((sum, file) => sum + (Number(file.size_bytes) || 0), 0);
|
||||
footer.textContent = `${files.length} ${files.length === 1 ? "file" : "files"} · ${formatBytes(totalSize)}`;
|
||||
footer.textContent = tp("files.summary", files.length, { size: formatBytes(totalSize) }, `${files.length} ${files.length === 1 ? "file" : "files"} · ${formatBytes(totalSize)}`);
|
||||
const restrictionMessage = getDeleteRestrictionMessage();
|
||||
const restrictionNotice = restrictionMessage
|
||||
? `<p class="file-delete-notice">${escapeHtml(restrictionMessage)}</p>`
|
||||
@@ -191,7 +194,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
onFilesChanged(files);
|
||||
if (open && !dialog.open) dialog.showModal();
|
||||
} catch (error) {
|
||||
if (open) toast(error.message);
|
||||
if (open) notify("danger", error.message, { title: "Could not load files" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +261,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
|
||||
function requestUpload() {
|
||||
if (!canUpload() || !canEdit()) {
|
||||
toast("You need read-write access and upload permission to upload files.");
|
||||
notify("warning", "Read-write access and file uploads are required to upload files.", { title: "Upload unavailable" });
|
||||
return;
|
||||
}
|
||||
input.click();
|
||||
@@ -276,7 +279,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
try {
|
||||
file = await prepareImageFile(file);
|
||||
} catch (error) {
|
||||
toast(error.message);
|
||||
notify("danger", error.message, { title: "Could not prepare image" });
|
||||
return;
|
||||
}
|
||||
if (!file) return;
|
||||
@@ -293,7 +296,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
if (!files.length) return;
|
||||
event.preventDefault();
|
||||
if (!canUpload() || !canEdit()) {
|
||||
toast("You need read-write access and upload permission to paste files.");
|
||||
notify("warning", "Read-write access and file uploads are required to paste files.", { title: "Paste upload unavailable" });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -333,7 +336,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
const text = aliasCode(addButton.dataset.name, addButton.dataset.name, addButton.dataset.mime, mode);
|
||||
if (mode === "player") insertVideoPlayer(text);
|
||||
else insertAttachmentText(text);
|
||||
toast("Added to note");
|
||||
notify("success", "The file reference was inserted into the note.", { title: "Added to note" });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -366,9 +369,9 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
if (copyButton) {
|
||||
try {
|
||||
await copyText(copyButton.closest(".file-code").querySelector("textarea").value);
|
||||
toast("Copied");
|
||||
notify("success", "Generated file code copied to the clipboard.", { title: "Copied" });
|
||||
} catch (error) {
|
||||
toast(error.message);
|
||||
notify("danger", error.message, { title: "Could not copy file code" });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -378,10 +381,10 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS
|
||||
if (!await askConfirm(`Delete file "${deleteButton.dataset.fileName}" permanently?`, { title: "Delete file", confirmText: "Delete", danger: true })) return;
|
||||
try {
|
||||
await api(endpoints.remove(deleteButton.dataset.deleteFile), { method: "DELETE", headers: {}, body: JSON.stringify({ access_token: getAccessToken() || null }) });
|
||||
toast("File deleted");
|
||||
notify("success", "The file was permanently deleted.", { title: "File deleted" });
|
||||
await loadFiles();
|
||||
} catch (error) {
|
||||
toast(error.message);
|
||||
notify("danger", error.message, { title: "Could not delete file" });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user