generated from nhcarrigan/template
feat: surface memory file last-modified timestamps in MemoryBrowserPanel (#230)
Extends MemoryFileInfo with last_modified (Unix timestamp) populated via fs::metadata on native platforms, and displays a formatted date in the file list as secondary text.
This commit is contained in:
@@ -1464,6 +1464,7 @@ pub async fn close_application(app_handle: AppHandle) -> Result<(), String> {
|
||||
pub struct MemoryFileInfo {
|
||||
pub path: String,
|
||||
pub heading: Option<String>,
|
||||
pub last_modified: Option<String>, // Unix timestamp in seconds as a string
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
@@ -1535,7 +1536,11 @@ async fn list_memory_files_via_wsl() -> Result<MemoryFilesResponse, String> {
|
||||
let mut files = Vec::new();
|
||||
for path in paths {
|
||||
let heading = read_wsl_file_first_heading(&path);
|
||||
files.push(MemoryFileInfo { path, heading });
|
||||
files.push(MemoryFileInfo {
|
||||
path,
|
||||
heading,
|
||||
last_modified: None,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(MemoryFilesResponse { files })
|
||||
@@ -1605,14 +1610,23 @@ async fn list_memory_files_native() -> Result<MemoryFilesResponse, String> {
|
||||
// Sort files alphabetically
|
||||
memory_paths.sort();
|
||||
|
||||
// Read first heading from each file
|
||||
// Read first heading and modification time from each file
|
||||
let files = memory_paths
|
||||
.into_iter()
|
||||
.map(|path| {
|
||||
let heading = fs::read_to_string(&path)
|
||||
.ok()
|
||||
.and_then(|content| extract_first_heading(&content));
|
||||
MemoryFileInfo { path, heading }
|
||||
let last_modified = fs::metadata(&path)
|
||||
.ok()
|
||||
.and_then(|m| m.modified().ok())
|
||||
.and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
|
||||
.map(|d| d.as_secs().to_string());
|
||||
MemoryFileInfo {
|
||||
path,
|
||||
heading,
|
||||
last_modified,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
interface MemoryFileInfo {
|
||||
path: string;
|
||||
heading: string | null;
|
||||
last_modified?: string; // Unix timestamp in seconds as a string, optional for backwards compat
|
||||
}
|
||||
|
||||
interface MemoryFilesResponse {
|
||||
@@ -65,6 +66,16 @@
|
||||
return file.heading ?? getFileName(file.path);
|
||||
}
|
||||
|
||||
function formatLastModified(ts: string | undefined): string {
|
||||
if (!ts) return "";
|
||||
const date = new Date(Number(ts) * 1000);
|
||||
return date.toLocaleDateString(undefined, {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
async function sendMemoryCommand() {
|
||||
const conversationId = get(claudeStore.activeConversationId);
|
||||
if (!conversationId) return;
|
||||
@@ -205,7 +216,12 @@
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="file-name">{getDisplayName(file)}</span>
|
||||
<div class="file-info">
|
||||
<span class="file-name">{getDisplayName(file)}</span>
|
||||
{#if file.last_modified}
|
||||
<span class="file-date">{formatLastModified(file.last_modified)}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -416,7 +432,7 @@
|
||||
|
||||
.file-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--bg-secondary);
|
||||
@@ -445,6 +461,13 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.125rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
@@ -453,6 +476,15 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.file-date {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.file-item.active .file-date {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.file-viewer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user