Lo
var root_2$4 = /* @__PURE__ */ from_html(`
`);
var root_4$4 = /* @__PURE__ */ from_html(`
`);
var root_3$4 = /* @__PURE__ */ from_html(`
`);
-var root_6$4 = /* @__PURE__ */ from_html(`matching "
"`, 1);
-var root_7$2 = /* @__PURE__ */ from_html(`
| â ŋ | | | |
`);
-var root_5$3 = /* @__PURE__ */ from_html(`
`, 1);
+var root_6$3 = /* @__PURE__ */ from_html(`matching "
"`, 1);
+var root_7$4 = /* @__PURE__ */ from_html(`
| `);
+var root_9$1 = /* @__PURE__ */ from_html(`
â ŋ`);
+var root_10$1 = /* @__PURE__ */ from_html(`
| `);
+var root_8$1 = /* @__PURE__ */ from_html(`
| | | | |
`);
+var root_5$3 = /* @__PURE__ */ from_html(`
`, 1);
var root$5 = /* @__PURE__ */ from_html(`
`);
function EntryList($$anchor, $$props) {
push($$props, true);
@@ -6101,21 +6179,31 @@ function EntryList($$anchor, $$props) {
let error = /* @__PURE__ */ state("");
let resultCount = /* @__PURE__ */ state(0);
let dragging = /* @__PURE__ */ state(false);
+ const isTrashView = /* @__PURE__ */ user_derived(() => search.activeGroupId === "trash");
async function loadEntries() {
set(loading, true);
set(error, "");
try {
const query = search.debouncedQuery.trim();
const groupId = search.activeGroupId;
- if (query) set(entries, await searchEntries(query, groupId !== "all" ? { groupId } : {}), true);
- else if (groupId !== "all") set(entries, await getEntries({ groupId }), true);
- else set(entries, await getEntries(), true);
+ const resolvedGroupId = groupId === "trash" ? TRASH_GROUP_ID : groupId;
+ if (query) set(entries, await searchEntries(query, resolvedGroupId !== "all" ? { groupId: resolvedGroupId } : {}), true);
+ else if (resolvedGroupId !== "all") set(entries, await getEntries({ groupId: resolvedGroupId }), true);
+ else set(entries, (await getEntries()).filter((e) => e.groupId !== TRASH_GROUP_ID), true);
set(resultCount, get(entries).length, true);
} catch (e) {
set(error, "Failed to load entries: " + e.message);
}
set(loading, false);
}
+ async function handleRestore(entryId) {
+ try {
+ await restoreEntry(entryId);
+ search.refresh();
+ } catch (e) {
+ set(error, "Failed to restore: " + e.message);
+ }
+ }
user_effect(() => {
search.debouncedQuery;
search.activeGroupId;
@@ -6154,13 +6242,13 @@ function EntryList($$anchor, $$props) {
append($$anchor, button);
};
if_block(node_1, ($$render) => {
- if (!search.query) $$render(consequent_2);
+ if (!search.query && !get(isTrashView)) $$render(consequent_2);
});
reset(div_3);
template_effect(() => {
- set_text(text_1, search.query ? "đ" : "đ");
- set_text(text_2, search.query ? "No results found" : "No entries yet");
- set_text(text_3, search.query ? "Try a different search term" : "Add your first login credential to get started");
+ set_text(text_1, search.query ? "đ" : get(isTrashView) ? "đ" : "đ");
+ set_text(text_2, search.query ? "No results found" : get(isTrashView) ? "Trash is empty" : "No entries yet");
+ set_text(text_3, search.query ? "Try a different search term" : get(isTrashView) ? "Deleted entries will appear here" : "Add your first login credential to get started");
});
append($$anchor, div_3);
};
@@ -6171,7 +6259,7 @@ function EntryList($$anchor, $$props) {
var text_4 = child(span);
var node_2 = sibling(text_4);
var consequent_4 = ($$anchor) => {
- var fragment_1 = root_6$4();
+ var fragment_1 = root_6$3();
var strong = sibling(first_child(fragment_1));
var text_5 = child(strong, true);
reset(strong);
@@ -6185,48 +6273,82 @@ function EntryList($$anchor, $$props) {
reset(span);
reset(div_4);
var table = sibling(div_4, 2);
- var tbody = sibling(child(table));
+ var thead = child(table);
+ var tr = child(thead);
+ var node_3 = sibling(child(tr), 4);
+ var consequent_5 = ($$anchor) => {
+ append($$anchor, root_7$4());
+ };
+ if_block(node_3, ($$render) => {
+ if (get(isTrashView)) $$render(consequent_5);
+ });
+ reset(tr);
+ reset(thead);
+ var tbody = sibling(thead);
each(tbody, 21, () => get(entries), (entry) => entry.id, ($$anchor, entry) => {
- var tr = root_7$2();
- set_attribute(tr, "draggable", true);
- var td = child(tr);
- var span_1 = sibling(child(td), 2);
- var text_6 = child(span_1, true);
- reset(span_1);
+ var tr_1 = root_8$1();
+ var td = child(tr_1);
+ var node_4 = child(td);
+ var consequent_6 = ($$anchor) => {
+ append($$anchor, root_9$1());
+ };
+ if_block(node_4, ($$render) => {
+ if (!get(isTrashView)) $$render(consequent_6);
+ });
+ var span_2 = sibling(node_4, 2);
+ var text_6 = child(span_2, true);
+ reset(span_2);
reset(td);
var td_1 = sibling(td);
- var span_2 = child(td_1);
- var text_7 = child(span_2, true);
- reset(span_2);
+ var span_3 = child(td_1);
+ var text_7 = child(span_3, true);
+ reset(span_3);
reset(td_1);
var td_2 = sibling(td_1);
- var span_3 = child(td_2);
- var text_8 = child(span_3, true);
- reset(span_3);
+ var span_4 = child(td_2);
+ var text_8 = child(span_4, true);
+ reset(span_4);
reset(td_2);
var td_3 = sibling(td_2);
- var span_4 = child(td_3);
- var text_9 = child(span_4, true);
- reset(span_4);
+ var span_5 = child(td_3);
+ var text_9 = child(span_5, true);
+ reset(span_5);
reset(td_3);
- reset(tr);
+ var node_5 = sibling(td_3);
+ var consequent_7 = ($$anchor) => {
+ var td_4 = root_10$1();
+ var button_1 = child(td_4);
+ reset(td_4);
+ delegated("click", button_1, (e) => {
+ e.stopPropagation();
+ handleRestore(get(entry).id);
+ });
+ append($$anchor, td_4);
+ };
+ if_block(node_5, ($$render) => {
+ if (get(isTrashView)) $$render(consequent_7);
+ });
+ reset(tr_1);
template_effect(() => {
- set_class(tr, 1, `entry-row ${get(dragging) ? "dragging" : ""}`, "svelte-13s7gu4");
+ set_attribute(tr_1, "draggable", !get(isTrashView));
+ set_class(tr_1, 1, `entry-row ${get(dragging) ? "dragging" : ""}`, "svelte-13s7gu4");
set_text(text_6, get(entry).title);
set_text(text_7, get(entry).username || "â");
set_text(text_8, get(entry).url || "â");
set_text(text_9, get(entry).notes || "â");
});
- delegated("click", tr, () => $$props.onSelect(get(entry).id));
- event("dragstart", tr, (e) => {
- set(dragging, true);
- e.dataTransfer.setData("text/plain", get(entry).id);
- e.dataTransfer.effectAllowed = "move";
+ delegated("click", tr_1, () => $$props.onSelect(get(entry).id));
+ event("dragstart", tr_1, (e) => {
+ if (!get(isTrashView)) {
+ set(dragging, true);
+ e.dataTransfer.setData("text/plain", get(entry).id);
+ e.dataTransfer.effectAllowed = "move";
+ }
});
- event("dragend", tr, () => {
+ event("dragend", tr_1, () => {
set(dragging, false);
});
- append($$anchor, tr);
+ append($$anchor, tr_1);
});
reset(tbody);
reset(table);
@@ -6250,11 +6372,14 @@ var root_1$5 = /* @__PURE__ */ from_html(`
Loading...
`);
var root_3$3 = /* @__PURE__ */ from_html(`
`);
var root_4$3 = /* @__PURE__ */ from_html(`
Entry not found
`);
-var root_6$3 = /* @__PURE__ */ from_html(`
`);
-var root_7$1 = /* @__PURE__ */ from_html(`
`);
-var root_8 = /* @__PURE__ */ from_html(`
`);
-var root_9 = /* @__PURE__ */ from_html(`
Delete Entry
Are you sure you want to delete " "? This cannot be undone.
`);
-var root_5$2 = /* @__PURE__ */ from_html(`
`, 1);
+var root_6$2 = /* @__PURE__ */ from_html(`
`, 1);
+var root_7$3 = /* @__PURE__ */ from_html(`
`, 1);
+var root_8 = /* @__PURE__ */ from_html(`
`);
+var root_9 = /* @__PURE__ */ from_html(`
`);
+var root_10 = /* @__PURE__ */ from_html(`
`);
+var root_11$1 = /* @__PURE__ */ from_html(`
Move to Trash
Move " " to the trash? You can restore it later.
`);
+var root_12 = /* @__PURE__ */ from_html(`
Delete Forever
Permanently delete " "? This cannot be undone.
`);
+var root_5$2 = /* @__PURE__ */ from_html(`
`, 1);
var root$4 = /* @__PURE__ */ from_html(`
`);
function EntryDetail($$anchor, $$props) {
push($$props, true);
@@ -6264,8 +6389,10 @@ function EntryDetail($$anchor, $$props) {
let loading = /* @__PURE__ */ state(true);
let error = /* @__PURE__ */ state("");
let showDeleteConfirm = /* @__PURE__ */ state(false);
+ let showPermanentDeleteConfirm = /* @__PURE__ */ state(false);
let deleting = /* @__PURE__ */ state(false);
let toast = /* @__PURE__ */ state("");
+ const isInTrash = /* @__PURE__ */ user_derived(() => get(entry) && isTrashGroup(get(entry).groupId));
let toastTimer = null;
async function loadEntry() {
set(loading, true);
@@ -6307,17 +6434,29 @@ function EntryDetail($$anchor, $$props) {
showToast(`â ${label} copied`);
}
}
- async function handleDelete() {
+ async function handleMoveToTrash() {
set(deleting, true);
try {
- await deleteEntry($$props.entryId);
+ await moveToTrash($$props.entryId);
$$props.onBack();
} catch (e) {
- set(error, "Failed to delete: " + e.message);
+ set(error, "Failed to move to trash: " + e.message);
}
set(deleting, false);
set(showDeleteConfirm, false);
}
+ async function handlePermanentDelete() {
+ set(deleting, true);
+ try {
+ await moveToTrash($$props.entryId);
+ await emptyTrash();
+ $$props.onBack();
+ } catch (e) {
+ set(error, "Failed to permanently delete: " + e.message);
+ }
+ set(deleting, false);
+ set(showPermanentDeleteConfirm, false);
+ }
var div = root$4();
var node = child(div);
var consequent = ($$anchor) => {
@@ -6344,7 +6483,7 @@ function EntryDetail($$anchor, $$props) {
var consequent_3 = ($$anchor) => {
append($$anchor, root_4$3());
};
- var alternate = ($$anchor) => {
+ var alternate_1 = ($$anchor) => {
var fragment = root_5$2();
var div_5 = first_child(fragment);
var div_6 = child(div_5);
@@ -6352,62 +6491,81 @@ function EntryDetail($$anchor, $$props) {
var text_3 = child(h2, true);
reset(h2);
var div_7 = sibling(h2, 2);
- var button = child(div_7);
- var button_1 = sibling(button, 2);
+ var node_2 = child(div_7);
+ var consequent_4 = ($$anchor) => {
+ var fragment_1 = root_6$2();
+ var button = first_child(fragment_1);
+ var button_1 = sibling(button, 2);
+ delegated("click", button, () => $$props.onEdit(get(entry).id));
+ delegated("click", button_1, () => set(showPermanentDeleteConfirm, true));
+ append($$anchor, fragment_1);
+ };
+ var alternate = ($$anchor) => {
+ var fragment_2 = root_7$3();
+ var button_2 = first_child(fragment_2);
+ var button_3 = sibling(button_2, 2);
+ delegated("click", button_2, () => $$props.onEdit(get(entry).id));
+ delegated("click", button_3, () => set(showDeleteConfirm, true));
+ append($$anchor, fragment_2);
+ };
+ if_block(node_2, ($$render) => {
+ if (get(isInTrash)) $$render(consequent_4);
+ else $$render(alternate, -1);
+ });
reset(div_7);
reset(div_6);
var div_8 = sibling(div_6, 2);
- var node_2 = child(div_8);
- var consequent_4 = ($$anchor) => {
- var div_9 = root_6$3();
+ var node_3 = child(div_8);
+ var consequent_5 = ($$anchor) => {
+ var div_9 = root_8();
var div_10 = sibling(child(div_9), 2);
var span = child(div_10);
var text_4 = child(span, true);
reset(span);
- var button_2 = sibling(span, 2);
+ var button_4 = sibling(span, 2);
reset(div_10);
reset(div_9);
template_effect(() => set_text(text_4, get(entry).username));
- delegated("click", button_2, () => copyToClipboard(get(entry).username, "Username"));
+ delegated("click", button_4, () => copyToClipboard(get(entry).username, "Username"));
append($$anchor, div_9);
};
- if_block(node_2, ($$render) => {
- if (get(entry).username) $$render(consequent_4);
+ if_block(node_3, ($$render) => {
+ if (get(entry).username) $$render(consequent_5);
});
- var div_11 = sibling(node_2, 2);
+ var div_11 = sibling(node_3, 2);
var div_12 = sibling(child(div_11), 2);
var span_1 = child(div_12);
var text_5 = child(span_1, true);
reset(span_1);
- var button_3 = sibling(span_1, 2);
- var text_6 = child(button_3, true);
- reset(button_3);
- var button_4 = sibling(button_3, 2);
+ var button_5 = sibling(span_1, 2);
+ var text_6 = child(button_5, true);
+ reset(button_5);
+ var button_6 = sibling(button_5, 2);
reset(div_12);
reset(div_11);
- var node_3 = sibling(div_11, 2);
- var consequent_5 = ($$anchor) => {
- var div_13 = root_7$1();
+ var node_4 = sibling(div_11, 2);
+ var consequent_6 = ($$anchor) => {
+ var div_13 = root_9();
var div_14 = sibling(child(div_13), 2);
var a = child(div_14);
var text_7 = child(a, true);
reset(a);
- var button_5 = sibling(a, 2);
+ var button_7 = sibling(a, 2);
reset(div_14);
reset(div_13);
template_effect(() => {
set_attribute(a, "href", get(entry).url);
set_text(text_7, get(entry).url);
});
- delegated("click", button_5, () => copyToClipboard(get(entry).url, "URL"));
+ delegated("click", button_7, () => copyToClipboard(get(entry).url, "URL"));
append($$anchor, div_13);
};
- if_block(node_3, ($$render) => {
- if (get(entry).url) $$render(consequent_5);
+ if_block(node_4, ($$render) => {
+ if (get(entry).url) $$render(consequent_6);
});
- var node_4 = sibling(node_3, 2);
- var consequent_6 = ($$anchor) => {
- var div_15 = root_8();
+ var node_5 = sibling(node_4, 2);
+ var consequent_7 = ($$anchor) => {
+ var div_15 = root_10();
var div_16 = sibling(child(div_15), 2);
var text_8 = child(div_16, true);
reset(div_16);
@@ -6415,8 +6573,8 @@ function EntryDetail($$anchor, $$props) {
template_effect(() => set_text(text_8, get(entry).notes));
append($$anchor, div_15);
};
- if_block(node_4, ($$render) => {
- if (get(entry).notes) $$render(consequent_6);
+ if_block(node_5, ($$render) => {
+ if (get(entry).notes) $$render(consequent_7);
});
reset(div_8);
var div_17 = sibling(div_8, 2);
@@ -6428,9 +6586,9 @@ function EntryDetail($$anchor, $$props) {
reset(span_3);
reset(div_17);
reset(div_5);
- var node_5 = sibling(div_5, 2);
- var consequent_7 = ($$anchor) => {
- var div_18 = root_9();
+ var node_6 = sibling(div_5, 2);
+ var consequent_8 = ($$anchor) => {
+ var div_18 = root_11$1();
var div_19 = child(div_18);
var p = sibling(child(div_19), 2);
var strong = sibling(child(p));
@@ -6439,26 +6597,58 @@ function EntryDetail($$anchor, $$props) {
next();
reset(p);
var div_20 = sibling(p, 2);
- var button_6 = child(div_20);
- var text_12 = child(button_6, true);
- reset(button_6);
- var button_7 = sibling(button_6, 2);
+ var button_8 = child(div_20);
+ var text_12 = child(button_8, true);
+ reset(button_8);
+ var button_9 = sibling(button_8, 2);
reset(div_20);
reset(div_19);
reset(div_18);
template_effect(() => {
set_text(text_11, get(entry).title);
- button_6.disabled = get(deleting);
- set_text(text_12, get(deleting) ? "Deleting..." : "Yes, delete");
+ button_8.disabled = get(deleting);
+ set_text(text_12, get(deleting) ? "Moving..." : "Move to Trash");
});
delegated("click", div_18, () => set(showDeleteConfirm, false));
delegated("click", div_19, (e) => e.stopPropagation());
- delegated("click", button_6, handleDelete);
- delegated("click", button_7, () => set(showDeleteConfirm, false));
+ delegated("click", button_8, handleMoveToTrash);
+ delegated("click", button_9, () => set(showDeleteConfirm, false));
append($$anchor, div_18);
};
- if_block(node_5, ($$render) => {
- if (get(showDeleteConfirm)) $$render(consequent_7);
+ if_block(node_6, ($$render) => {
+ if (get(showDeleteConfirm)) $$render(consequent_8);
+ });
+ var node_7 = sibling(node_6, 2);
+ var consequent_9 = ($$anchor) => {
+ var div_21 = root_12();
+ var div_22 = child(div_21);
+ var p_1 = sibling(child(div_22), 2);
+ var strong_1 = sibling(child(p_1));
+ var text_13 = child(strong_1, true);
+ reset(strong_1);
+ next();
+ reset(p_1);
+ var div_23 = sibling(p_1, 2);
+ var button_10 = child(div_23);
+ var text_14 = child(button_10, true);
+ reset(button_10);
+ var button_11 = sibling(button_10, 2);
+ reset(div_23);
+ reset(div_22);
+ reset(div_21);
+ template_effect(() => {
+ set_text(text_13, get(entry).title);
+ button_10.disabled = get(deleting);
+ set_text(text_14, get(deleting) ? "Deleting..." : "Delete Forever");
+ });
+ delegated("click", div_21, () => set(showPermanentDeleteConfirm, false));
+ delegated("click", div_22, (e) => e.stopPropagation());
+ delegated("click", button_10, handlePermanentDelete);
+ delegated("click", button_11, () => set(showPermanentDeleteConfirm, false));
+ append($$anchor, div_21);
+ };
+ if_block(node_7, ($$render) => {
+ if (get(showPermanentDeleteConfirm)) $$render(consequent_9);
});
template_effect(($0, $1) => {
set_text(text_3, get(entry).title);
@@ -6467,17 +6657,15 @@ function EntryDetail($$anchor, $$props) {
set_text(text_9, `Created: ${$0 ?? ""}`);
set_text(text_10, `Updated: ${$1 ?? ""}`);
}, [() => new Date(get(entry).createdAt).toLocaleString(), () => new Date(get(entry).updatedAt).toLocaleString()]);
- delegated("click", button, () => $$props.onEdit(get(entry).id));
- delegated("click", button_1, () => set(showDeleteConfirm, true));
- delegated("click", button_3, () => set(passwordVisible, !get(passwordVisible)));
- delegated("click", button_4, () => copyToClipboard(get(decryptedPassword), "Password"));
+ delegated("click", button_5, () => set(passwordVisible, !get(passwordVisible)));
+ delegated("click", button_6, () => copyToClipboard(get(decryptedPassword), "Password"));
append($$anchor, fragment);
};
if_block(node_1, ($$render) => {
if (get(loading)) $$render(consequent_1);
else if (get(error)) $$render(consequent_2, 1);
else if (!get(entry)) $$render(consequent_3, 2);
- else $$render(alternate, -1);
+ else $$render(alternate_1, -1);
});
reset(div);
append($$anchor, div);
@@ -6491,7 +6679,7 @@ var root_1$3 = /* @__PURE__ */ from_html(`
Loa
var root_3$2 = /* @__PURE__ */ from_html(`
`);
var root_5$1 = /* @__PURE__ */ from_html(`
`);
var root_4$2 = /* @__PURE__ */ from_html(`
`);
-var root_6$2 = /* @__PURE__ */ from_html(`
`);
+var root_7$2 = /* @__PURE__ */ from_html(`
`);
var root_2$2 = /* @__PURE__ */ from_html(`
`, 1);
var root$2 = /* @__PURE__ */ from_html(`
`);
function EntryForm($$anchor, $$props) {
@@ -6633,15 +6821,24 @@ function EntryForm($$anchor, $$props) {
var option = child(select);
option.value = option.__value = "";
each(sibling(option), 17, () => get(groups), index, ($$anchor, group) => {
- var option_1 = root_6$2();
- var text_3 = child(option_1, true);
- reset(option_1);
- var option_1_value = {};
- template_effect(() => {
- set_text(text_3, get(group).name);
- if (option_1_value !== (option_1_value = get(group).id)) option_1.value = (option_1.__value = get(group).id) ?? "";
+ var fragment_1 = comment();
+ var node_4 = first_child(fragment_1);
+ var consequent_3 = ($$anchor) => {
+ var option_1 = root_7$2();
+ var text_3 = child(option_1, true);
+ reset(option_1);
+ var option_1_value = {};
+ template_effect(() => {
+ set_text(text_3, get(group).name);
+ if (option_1_value !== (option_1_value = get(group).id)) option_1.value = (option_1.__value = get(group).id) ?? "";
+ });
+ append($$anchor, option_1);
+ };
+ var d = /* @__PURE__ */ user_derived(() => !isTrashGroup(get(group).id));
+ if_block(node_4, ($$render) => {
+ if (get(d)) $$render(consequent_3);
});
- append($$anchor, option_1);
+ append($$anchor, fragment_1);
});
reset(select);
reset(div_10);
@@ -6693,7 +6890,7 @@ var root_1$2 = /* @__PURE__ */ from_html(`
`);
var root_4$1 = /* @__PURE__ */ from_html(`
`);
var root_6$1 = /* @__PURE__ */ from_html(`
File loaded. Enter the source vault's master password to decrypt and re-encrypt entries under your current vault.
`, 1);
-var root_7 = /* @__PURE__ */ from_html(`
Select how to handle existing data:
`, 1);
+var root_7$1 = /* @__PURE__ */ from_html(`
Select how to handle existing data:
`, 1);
var root_2$1 = /* @__PURE__ */ from_html(`
`);
var root$1 = /* @__PURE__ */ from_html(`
`);
function ImportExport($$anchor, $$props) {
@@ -6866,7 +7063,7 @@ function ImportExport($$anchor, $$props) {
append($$anchor, fragment_1);
};
var alternate = ($$anchor) => {
- var fragment_2 = root_7();
+ var fragment_2 = root_7$1();
var div_11 = sibling(first_child(fragment_2), 2);
var label_2 = child(div_11);
var input_3 = child(label_2);
@@ -6923,16 +7120,21 @@ delegate(["click", "change"]);
//#region src/components/MainLayout.svelte
var root_1$1 = /* @__PURE__ */ from_html(``);
var root_2 = /* @__PURE__ */ from_html(`
`);
-var root_3 = /* @__PURE__ */ from_html(`
All Entries
`);
+var root_3 = /* @__PURE__ */ from_html(`
`);
var root_4 = /* @__PURE__ */ from_html(`
Entry Details
`);
var root_5 = /* @__PURE__ */ from_html(`
`);
-var root_6 = /* @__PURE__ */ from_html(`
`);
-var root = /* @__PURE__ */ from_html(`
`);
+var root_6 = /* @__PURE__ */ from_html(`
`);
+var root_7 = /* @__PURE__ */ from_html(`
`);
+var root_11 = /* @__PURE__ */ from_html(`
Empty Trash
Permanently delete all entries from the trash? This cannot be undone.
`);
+var root = /* @__PURE__ */ from_html(`
`);
function MainLayout($$anchor, $$props) {
push($$props, true);
let sidebarOpen = /* @__PURE__ */ state(false);
let viewMode = /* @__PURE__ */ state("list");
let selectedEntryId = /* @__PURE__ */ state(null);
+ let showEmptyTrashConfirm = /* @__PURE__ */ state(false);
+ let emptyingTrash = /* @__PURE__ */ state(false);
+ const isTrashView = /* @__PURE__ */ user_derived(() => search.activeGroupId === "trash");
function goList() {
set(viewMode, "list");
set(selectedEntryId, null);
@@ -6952,6 +7154,17 @@ function MainLayout($$anchor, $$props) {
if (get(viewMode) === "form") goDetail(get(selectedEntryId));
else goList();
}
+ async function handleEmptyTrash() {
+ set(emptyingTrash, true);
+ try {
+ await emptyTrash();
+ search.activeGroupId = "all";
+ set(showEmptyTrashConfirm, false);
+ } catch (e) {
+ console.error("Failed to empty trash:", e);
+ }
+ set(emptyingTrash, false);
+ }
function handleLock() {
app$1.lockVault();
}
@@ -6986,16 +7199,20 @@ function MainLayout($$anchor, $$props) {
var div_3 = sibling(node_2, 2);
var node_3 = child(div_3);
var consequent_2 = ($$anchor) => {
- append($$anchor, root_3());
+ var h1 = root_3();
+ var text = child(h1, true);
+ reset(h1);
+ template_effect(() => set_text(text, search.activeGroupId === "trash" ? TRASH_GROUP_NAME : "All Entries"));
+ append($$anchor, h1);
};
var consequent_3 = ($$anchor) => {
append($$anchor, root_4());
};
var consequent_4 = ($$anchor) => {
var h1_2 = root_5();
- var text = child(h1_2, true);
+ var text_1 = child(h1_2, true);
reset(h1_2);
- template_effect(() => set_text(text, get(selectedEntryId) ? "Edit Entry" : "New Entry"));
+ template_effect(() => set_text(text_1, get(selectedEntryId) ? "Edit Entry" : "New Entry"));
append($$anchor, h1_2);
};
if_block(node_3, ($$render) => {
@@ -7008,26 +7225,41 @@ function MainLayout($$anchor, $$props) {
var node_4 = child(div_4);
var consequent_5 = ($$anchor) => {
var button_4 = root_6();
- delegated("click", button_4, () => goForm(null));
+ var text_2 = child(button_4, true);
+ reset(button_4);
+ template_effect(() => {
+ button_4.disabled = get(emptyingTrash);
+ set_text(text_2, get(emptyingTrash) ? "Emptying..." : "đ Empty Trash");
+ });
+ delegated("click", button_4, () => set(showEmptyTrashConfirm, true));
append($$anchor, button_4);
};
if_block(node_4, ($$render) => {
- if (get(viewMode) === "list") $$render(consequent_5);
+ if (get(viewMode) === "list" && get(isTrashView)) $$render(consequent_5);
});
var node_5 = sibling(node_4, 2);
- ImportExport(node_5, {});
- var button_5 = sibling(node_5, 2);
+ var consequent_6 = ($$anchor) => {
+ var button_5 = root_7();
+ delegated("click", button_5, () => goForm(null));
+ append($$anchor, button_5);
+ };
+ if_block(node_5, ($$render) => {
+ if (get(viewMode) === "list" && !get(isTrashView)) $$render(consequent_6);
+ });
+ var node_6 = sibling(node_5, 2);
+ ImportExport(node_6, {});
+ var button_6 = sibling(node_6, 2);
reset(div_4);
reset(div_2);
var div_5 = sibling(div_2, 2);
- var node_6 = child(div_5);
- var consequent_6 = ($$anchor) => {
+ var node_7 = child(div_5);
+ var consequent_7 = ($$anchor) => {
EntryList($$anchor, {
onSelect: goDetail,
onAdd: () => goForm(null)
});
};
- var consequent_7 = ($$anchor) => {
+ var consequent_8 = ($$anchor) => {
EntryDetail($$anchor, {
get entryId() {
return get(selectedEntryId);
@@ -7036,7 +7268,7 @@ function MainLayout($$anchor, $$props) {
onBack: goList
});
};
- var consequent_8 = ($$anchor) => {
+ var consequent_9 = ($$anchor) => {
EntryForm($$anchor, {
get entryId() {
return get(selectedEntryId);
@@ -7045,18 +7277,43 @@ function MainLayout($$anchor, $$props) {
onCancel: handleBack
});
};
- if_block(node_6, ($$render) => {
- if (get(viewMode) === "list") $$render(consequent_6);
- else if (get(viewMode) === "detail" && get(selectedEntryId)) $$render(consequent_7, 1);
- else if (get(viewMode) === "form") $$render(consequent_8, 2);
+ if_block(node_7, ($$render) => {
+ if (get(viewMode) === "list") $$render(consequent_7);
+ else if (get(viewMode) === "detail" && get(selectedEntryId)) $$render(consequent_8, 1);
+ else if (get(viewMode) === "form") $$render(consequent_9, 2);
});
reset(div_5);
reset(main);
+ var node_8 = sibling(main, 2);
+ var consequent_10 = ($$anchor) => {
+ var div_6 = root_11();
+ var div_7 = child(div_6);
+ var div_8 = sibling(child(div_7), 4);
+ var button_7 = child(div_8);
+ var text_3 = child(button_7, true);
+ reset(button_7);
+ var button_8 = sibling(button_7, 2);
+ reset(div_8);
+ reset(div_7);
+ reset(div_6);
+ template_effect(() => {
+ button_7.disabled = get(emptyingTrash);
+ set_text(text_3, get(emptyingTrash) ? "Emptying..." : "Yes, empty trash");
+ });
+ delegated("click", div_6, () => set(showEmptyTrashConfirm, false));
+ delegated("click", div_7, (e) => e.stopPropagation());
+ delegated("click", button_7, handleEmptyTrash);
+ delegated("click", button_8, () => set(showEmptyTrashConfirm, false));
+ append($$anchor, div_6);
+ };
+ if_block(node_8, ($$render) => {
+ if (get(showEmptyTrashConfirm)) $$render(consequent_10);
+ });
reset(div);
template_effect(() => set_class(aside, 1, `sidebar ${get(sidebarOpen) ? "open" : ""}`, "svelte-1ybayt"));
delegated("click", button, () => set(sidebarOpen, !get(sidebarOpen)));
delegated("click", button_1, handleLock);
- delegated("click", button_5, handleLock);
+ delegated("click", button_6, handleLock);
append($$anchor, div);
pop();
}
@@ -7455,6 +7712,11 @@ label {
opacity: 1;
}
+ .trash-section.svelte-181dlmc {
+ padding: 8px;
+ border-top: 1px solid var(--color-border);
+ }
+
.group-action-btn.svelte-181dlmc {
background: none;
border: none;
@@ -7634,6 +7896,11 @@ label {
opacity: 0.7;
}
+ .restore-btn.svelte-13s7gu4 {
+ font-size: 0.85rem;
+ padding: 4px 6px;
+ }
+
.entry-title.svelte-13s7gu4 {
font-weight: 500;
}
@@ -8093,6 +8360,43 @@ label {
height: 100%;
}
+ /* Modal */
+ .modal-overlay.svelte-1ybayt {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.6);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 200;
+ padding: 1rem;
+ }
+
+ .modal.svelte-1ybayt {
+ background: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ padding: 24px;
+ max-width: 380px;
+ width: 100%;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
+ }
+
+ .modal.svelte-1ybayt h3:where(.svelte-1ybayt) {
+ margin-bottom: 16px;
+ }
+
+ .modal.svelte-1ybayt p:where(.svelte-1ybayt) {
+ color: var(--color-text-muted);
+ font-size: 0.9rem;
+ margin-bottom: 20px;
+ }
+
+ .modal-actions.svelte-1ybayt {
+ display: flex;
+ gap: 8px;
+ }
+
/* Responsive */
@media (max-width: 768px) {
.mobile-header.svelte-1ybayt {
diff --git a/src/components/EntryDetail.svelte b/src/components/EntryDetail.svelte
index ce3ae76..dd47fd2 100644
--- a/src/components/EntryDetail.svelte
+++ b/src/components/EntryDetail.svelte
@@ -1,7 +1,8 @@
@@ -94,8 +111,13 @@
@@ -145,22 +167,39 @@
-
+
{#if showDeleteConfirm}
showDeleteConfirm = false}>
-
e.stopPropagation()}>
-
Delete Entry
-
Are you sure you want to delete "{entry.title}"? This cannot be undone.
+
e.stopPropagation()}>
+
Move to Trash
+
Move "{entry.title}" to the trash? You can restore it later.
-
{/if}
+
+
+ {#if showPermanentDeleteConfirm}
+
showPermanentDeleteConfirm = false}>
+
+
e.stopPropagation()}>
+
Delete Forever
+
Permanently delete "{entry.title}"? This cannot be undone.
+
+
+ {deleting ? 'Deleting...' : 'Delete Forever'}
+
+ showPermanentDeleteConfirm = false}>Cancel
+
+
+
+ {/if}
{/if}
diff --git a/src/components/EntryForm.svelte b/src/components/EntryForm.svelte
index 18abc1c..575a6ec 100644
--- a/src/components/EntryForm.svelte
+++ b/src/components/EntryForm.svelte
@@ -1,7 +1,7 @@