diff --git a/src/renderer/inbox/App.tsx b/src/renderer/inbox/App.tsx
index 796c3b9..2451227 100644
--- a/src/renderer/inbox/App.tsx
+++ b/src/renderer/inbox/App.tsx
@@ -12,15 +12,10 @@ import { TagUndoToast } from './components/TagUndoToast.js';
export function App(): React.ReactElement {
const {
- notes,
- loading,
- loadInitial,
- refreshMeta,
- upsertNote,
- removeNote,
- continuity,
- tagFilter,
- setTagFilter
+ notes, trashNotes, trashCount, showTrash,
+ loading, loadInitial, refreshMeta, upsertNote, removeNote,
+ continuity, tagFilter, setTagFilter,
+ toggleShowTrash, restoreNote, permanentDeleteNote, emptyTrash
} = useInbox();
const [recoveryDismissed, setRecoveryDismissed] = useState(isRecoveryDismissedToday());
@@ -38,64 +33,114 @@ export function App(): React.ReactElement {
const showRecovery = continuity.showRecoveryToast && !recoveryDismissed;
const filtered = selectFilteredNotes({ notes, tagFilter });
+ const tabBtnStyle = (active: boolean): React.CSSProperties => ({
+ background: active ? '#0a4b80' : 'transparent',
+ color: active ? '#fff' : '#0a4b80',
+ border: '1px solid #0a4b80',
+ borderRadius: 4,
+ padding: '4px 10px',
+ fontSize: 12,
+ cursor: 'pointer'
+ });
+
return (
<>
Inkling
-
+
+
+
+
+
-
- { markRecoveryDismissed(); setRecoveryDismissed(true); }}
- />
-
- {tagFilter !== null && (
-
- π νν°: #{tagFilter}
- ({filtered.length}κ°)
-
-
+ {!showTrash && (
+ <>
+
+ { markRecoveryDismissed(); setRecoveryDismissed(true); }}
+ />
+
+ {tagFilter !== null && (
+
+ π νν°: #{tagFilter}
+ ({filtered.length}κ°)
+
+
+ )}
+ {loading && notes.length === 0 ? (
+ λΆλ¬μ€λ μ€β¦
+ ) : notes.length === 0 ? (
+ λ¨Έλ¦Ώμμ λ λ€λλ ν μ€μ μ μ΄λ³΄μΈμ. Ctrl+Shift+J
+ ) : filtered.length === 0 ? (
+ μ΄ νκ·Έμ λ
ΈνΈκ° μμ΅λλ€.
+ ) : (
+ filtered.map((n) => (
+ removeNote(n.id)}
+ onUpdated={(u) => upsertNote(u)}
+ />
+ ))
+ )}
+ >
)}
- {loading && notes.length === 0 ? (
- λΆλ¬μ€λ μ€β¦
- ) : notes.length === 0 ? (
- λ¨Έλ¦Ώμμ λ λ€λλ ν μ€μ μ μ΄λ³΄μΈμ. Ctrl+Shift+J
- ) : filtered.length === 0 ? (
- μ΄ νκ·Έμ λ
ΈνΈκ° μμ΅λλ€.
- ) : (
- filtered.map((n) => (
- removeNote(n.id)} onUpdated={(u) => upsertNote(u)} />
- ))
+ {showTrash && (
+ <>
+
+
+ {trashCount === 0 ? 'ν΄μ§ν΅μ΄ λΉμ΄μμ΅λλ€.' : `${trashCount}κ° λ³΄κ΄ μ€`}
+
+
+
+ {trashNotes.length === 0 ? null : (
+ trashNotes.map((n) => (
+ removeNote(n.id)}
+ onUpdated={(u) => upsertNote(u)}
+ onRestore={() => void restoreNote(n.id)}
+ onPermanentDelete={() => void permanentDeleteNote(n.id)}
+ />
+ ))
+ )}
+ >
)}
diff --git a/src/renderer/inbox/components/NoteCard.tsx b/src/renderer/inbox/components/NoteCard.tsx
index f7ca235..7e80bf3 100644
--- a/src/renderer/inbox/components/NoteCard.tsx
+++ b/src/renderer/inbox/components/NoteCard.tsx
@@ -10,6 +10,9 @@ interface Props {
note: Note;
onDeleted: () => void;
onUpdated: (n: Note) => void;
+ mode?: 'inbox' | 'trash'; // default 'inbox'
+ onRestore?: () => void;
+ onPermanentDelete?: () => void;
}
const aiBadgeStyle: React.CSSProperties = {
@@ -104,7 +107,8 @@ function DueDateBadge({
);
}
-export function NoteCard({ note, onDeleted, onUpdated }: Props): React.ReactElement {
+export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore, onPermanentDelete }: Props): React.ReactElement {
+ const isTrash = mode === 'trash';
const [rawOpen, setRawOpen] = useState(note.aiStatus !== 'done');
const [local, setLocal] = useState(note);
@@ -183,7 +187,7 @@ export function NoteCard({ note, onDeleted, onUpdated }: Props): React.ReactElem
{formatted}
- {showIntentBanner && (
+ {!isTrash && showIntentBanner && (
{
@@ -206,86 +210,122 @@ export function NoteCard({ note, onDeleted, onUpdated }: Props): React.ReactElem
)}
{local.aiStatus === 'done' && (
<>
-
-
- {!local.titleEditedByUser && AI}
-
-
-
- {!local.summaryEditedByUser && AI}
-
-
-
-
- {local.tags.length > 0 && (
-
- {local.tags.map((t) => (
-
- filterByTag(t.name)}
- style={{ cursor: 'pointer' }}
- title={`#${t.name} λ
ΈνΈλ§ 보기`}
- >
- {t.name}{t.source === 'ai' && AI}
-
-
-
- ))}
-
- )}
- {local.userIntent !== null && (
-
- π‘
-
-
+ {isTrash ? (
+ <>
+
+
{local.aiTitle ?? '(μ λͺ© μμ)'}
+
+
+ {local.aiSummary ?? '(μμ½ μμ)'}
+
+ {local.dueDate !== null && (
+
+ π
{local.dueDate}
+
+ )}
+ {local.tags.length > 0 && (
+
+ {local.tags.map((t) => (
+
+ {t.name}{t.source === 'ai' && AI}
+
+ ))}
+
+ )}
+ >
+ ) : (
+ <>
+
+
+ {!local.titleEditedByUser && AI}
+
+
+
+ {!local.summaryEditedByUser && AI}
+
+
+
+
+ {local.tags.length > 0 && (
+
+ {local.tags.map((t) => (
+
+ filterByTag(t.name)}
+ style={{ cursor: 'pointer' }}
+ title={`#${t.name} λ
ΈνΈλ§ 보기`}
+ >
+ {t.name}{t.source === 'ai' && AI}
+
+
+
+ ))}
+
+ )}
+ {local.userIntent !== null && (
+
+ π‘
+
+
+ )}
+ >
)}
>
)}
@@ -310,9 +350,32 @@ export function NoteCard({ note, onDeleted, onUpdated }: Props): React.ReactElem
-
+ {isTrash ? (
+
+
+
+
+ ) : (
+
+ )}
);