/
raiden
/
obsidian-git-encrypt
Обзор
Документация
Войти
/
raiden
/
obsidian-git-encrypt
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/ui/trackedFilesModal.ts
111 строк
4 KB
Robert Kuzhin
feat: add tracked files screen
09 авг 2026, 15:14
09 авг 2026, 15:14
01fc7ce
Код
Авторство
О чём код?
import { Modal, type App } from "obsidian"; import type { TrackedFileInfo } from "../session/index.js"; export function openTrackedFilesModal( app: App, files: readonly TrackedFileInfo[], ): void { new TrackedFilesModal(app, files).open(); } class TrackedFilesModal extends Modal { public constructor( app: App, private readonly files: readonly TrackedFileInfo[], ) { super(app); } public override onOpen(): void { this.setTitle("Tracked encrypted files"); this.contentEl.empty(); const activeCount = this.files.filter((file) => !file.deleted).length; const deletedCount = this.files.length - activeCount; this.contentEl.createEl("p", { cls: "encrypted-git-tracked-summary", text: `${activeCount} active · ${deletedCount} deleted`, }); const controls = this.contentEl.createEl("div", { cls: "encrypted-git-tracked-controls", }); const search = controls.createEl("input", { attr: { type: "search", placeholder: "Filter by vault path", "aria-label": "Filter tracked files by vault path", }, }); const deletedLabel = controls.createEl("label", { cls: "encrypted-git-tracked-deleted-toggle", }); const showDeleted = deletedLabel.createEl("input", { attr: { type: "checkbox" } }); deletedLabel.createEl("span", { text: "Show deleted" }); const list = this.contentEl.createEl("div", { cls: "encrypted-git-tracked-list", attr: { role: "list" }, }); const render = (): void => { list.empty(); const query = normalizeSearch(search.value); const visible = this.files.filter( (file) => (showDeleted.checked || !file.deleted) && (query === "" || normalizeSearch(file.path).includes(query)), ); if (visible.length === 0) { list.createEl("p", { cls: "encrypted-git-tracked-empty", text: query === "" ? "No tracked files yet." : "No tracked files match this filter.", }); return; } for (const file of visible) renderTrackedFile(list, file); }; search.addEventListener("input", render); showDeleted.addEventListener("change", render); render(); this.contentEl.createEl("p", { cls: "encrypted-git-tracked-help", text: "This list comes from the decrypted manifest. Existing vault files appear after they are created or edited while unlocked. .obsidian metadata is excluded.", }); search.focus(); } public override onClose(): void { this.contentEl.empty(); } } function renderTrackedFile(container: HTMLElement, file: TrackedFileInfo): void { const row = container.createEl("div", { cls: `encrypted-git-tracked-row${file.deleted ? " is-deleted" : ""}`, attr: { role: "listitem" }, }); const title = row.createEl("div", { cls: "encrypted-git-tracked-path" }); title.createEl("span", { text: file.path }); if (file.deleted) title.createEl("span", { cls: "encrypted-git-tracked-badge", text: "Deleted" }); row.createEl("div", { cls: "encrypted-git-tracked-meta", text: `${formatBytes(file.size)} · version ${file.objectVersion} · ${formatDate(file.modifiedAt)}`, }); } function normalizeSearch(value: string): string { return value.normalize("NFC").toLocaleLowerCase("en-US").trim(); } function formatBytes(bytes: number): string { if (bytes < 1_024) return `${bytes} B`; if (bytes < 1_024 * 1_024) return `${(bytes / 1_024).toFixed(1)} KiB`; return `${(bytes / 1_024 / 1_024).toFixed(1)} MiB`; } function formatDate(timestamp: number): string { const date = new Date(timestamp); return Number.isNaN(date.getTime()) ? "unknown modification time" : date.toLocaleString(); }