Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.
10 changes: 10 additions & 0 deletions electron/main/electron-store/ipcHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ export const registerStoreHandlers = (store: Store<StoreSchema>, windowsManager:
return store.get(StoreKeys.showDocumentStats, false)
})

// File index date visibility
ipcMain.handle('set-file-index-date-visibility', (event, showDates: boolean) => {
store.set(StoreKeys.ShowFileDatesInSidebar, showDates)
event.sender.send('file-index-date-visibility-changed', showDates)
})

ipcMain.handle('get-file-index-date-visibility', () => {
return store.get(StoreKeys.ShowFileDatesInSidebar, true)
})

ipcMain.handle('has-user-opened-app-before', () => store.get(StoreKeys.hasUserOpenedAppBefore))

ipcMain.handle('set-user-has-opened-app-before', () => {
Expand Down
2 changes: 2 additions & 0 deletions electron/main/electron-store/storeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export interface StoreSchema {
spellCheck: string
EditorFlexCenter: boolean
showDocumentStats: boolean
showFileDatesInSidebar: boolean
autoContext: boolean
tamaguiTheme: TamaguiThemeTypes
searchParams: SearchProps
Expand All @@ -86,6 +87,7 @@ export enum StoreKeys {
SpellCheck = 'spellCheck',
EditorFlexCenter = 'editorFlexCenter',
showDocumentStats = 'showDocumentStats',
ShowFileDatesInSidebar = 'showFileDatesInSidebar',
AutoContext = 'autoContext',
TamaguiTheme = 'tamaguiTheme',
SearchParams = 'searchParams',
Expand Down
2 changes: 2 additions & 0 deletions electron/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ const electronStore = {
setSpellCheckMode: createIPCHandler<(isSpellCheck: boolean) => Promise<void>>('set-spellcheck-mode'),
getDocumentStats: createIPCHandler<() => Promise<boolean>>('get-document-stats'),
setDocumentStats: createIPCHandler<(showWordCount: boolean) => Promise<void>>('set-document-stats'),
getFileIndexDateVisibility: createIPCHandler<() => Promise<boolean>>('get-file-index-date-visibility'),
setFileIndexDateVisibility: createIPCHandler<(showDates: boolean) => Promise<void>>('set-file-index-date-visibility'),
getHasUserOpenedAppBefore: createIPCHandler<() => Promise<boolean>>('has-user-opened-app-before'),
setHasUserOpenedAppBefore: createIPCHandler<() => Promise<void>>('set-user-has-opened-app-before'),
getAllChatsMetadata: createIPCHandler<() => Promise<ChatMetadata[]>>('get-all-chats-metadata'),
Expand Down
4 changes: 3 additions & 1 deletion src/components/Editor/EditorManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import InEditorBacklinkSuggestionsDisplay from './BacklinkSuggestionsDisplay'
import { useFileContext } from '@/contexts/FileContext'
import { BlockNoteView, FormattingToolbarPositioner, SlashMenuPositioner, SideMenuPositioner } from '@/lib/blocknote'
import SearchBar from './Search/SearchBar'
import NoteTimestamps from './NoteTimestamps'

const EditorManager: React.FC = () => {
const [editorFlex, setEditorFlex] = useState(true)
Expand Down Expand Up @@ -45,9 +46,10 @@ const EditorManager: React.FC = () => {
{editor && <SearchBar editor={editor._tiptapEditor} />}

<YStack
className={`relative h-full py-4 ${editorFlex ? 'flex justify-center px-24' : 'px-12'} ${showDocumentStats ? 'pb-3' : ''}`}
className={`relative h-full pb-4 pt-1 ${editorFlex ? 'flex justify-center px-24' : 'px-12'} ${showDocumentStats ? 'pb-3' : ''}`}
>
<YStack className="relative size-full">
<NoteTimestamps />
{editor && (
<BlockNoteView editor={editor}>
<FormattingToolbarPositioner editor={editor} />
Expand Down
38 changes: 38 additions & 0 deletions src/components/Editor/NoteTimestamps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useMemo, useState } from 'react'
import { format } from 'date-fns'
import { useFileContext } from '@/contexts/FileContext'

const NoteTimestamps: React.FC = () => {
const { currentlyOpenFilePath, vaultFilesFlattened } = useFileContext()
const [showUpdated, setShowUpdated] = useState(false)

const fileInfo = useMemo(() => {
if (!currentlyOpenFilePath) return null
return vaultFilesFlattened.find((f) => f.path === currentlyOpenFilePath) || null
}, [currentlyOpenFilePath, vaultFilesFlattened])

if (!fileInfo) return null

const createdAt = fileInfo.dateCreated
const updatedAt = fileInfo.dateModified

const label = showUpdated ? 'Updated' : 'Created'
const date = showUpdated ? updatedAt : createdAt
const display = date instanceof Date ? format(date, 'yyyy-MM-dd HH:mm') : String(date)

return (
<div
className="mb-1 mt-2 cursor-pointer select-none pl-4 text-[11px] leading-4 text-neutral-400 opacity-30 transition-opacity hover:text-neutral-300 hover:opacity-80"
onClick={() => setShowUpdated((prev) => !prev)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') setShowUpdated((prev) => !prev)
}}
>
{label}: {display}
</div>
)
}

export default NoteTimestamps
19 changes: 18 additions & 1 deletion src/components/Sidebars/FileSideBar/FileItemRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ListChildComponentProps } from 'react-window'
import posthog from 'posthog-js'
import { isFileNodeDirectory } from '@shared/utils'
import { XStack, Text } from 'tamagui'
import { format } from 'date-fns'
import { ChevronRight, ChevronDown } from '@tamagui/lucide-icons'
import { useFileContext } from '@/contexts/FileContext'
import { removeFileExtension } from '@/lib/file'
Expand All @@ -12,6 +13,7 @@ import NewDirectoryComponent from '@/components/File/NewDirectory'

const FileItemRows: React.FC<ListChildComponentProps> = ({ index, style, data }) => {
const { file, indentation } = data.filesAndIndentations[index]
const showDates: boolean = data.showDates ?? true

const {
handleDirectoryToggle,
Expand All @@ -29,6 +31,8 @@ const FileItemRows: React.FC<ListChildComponentProps> = ({ index, style, data })
const [isDragOver, setIsDragOver] = useState(false)

const isDirectory = isFileNodeDirectory(file)
const formattedDate =
showDates && !isDirectory && file.dateModified instanceof Date ? format(file.dateModified, 'MM-dd-yy') : ''
const isSelected = isDirectory ? file.path === selectedDirectory : file.path === currentlyOpenFilePath

const indentationPadding = indentation ? 10 * indentation : 0
Expand Down Expand Up @@ -132,6 +136,8 @@ const FileItemRows: React.FC<ListChildComponentProps> = ({ index, style, data })
onPress={clickOnFileOrDirectory}
className={itemClasses}
overflow="hidden"
justifyContent="space-between"
width="100%"
>
{isDirectory && (
<span className="mr-2 mt-1">
Expand All @@ -144,9 +150,20 @@ const FileItemRows: React.FC<ListChildComponentProps> = ({ index, style, data })
)}
</span>
)}
<Text color="$gray11" numberOfLines={1}>
<Text color="$gray11" numberOfLines={1} flex={1}>
{isDirectory ? file.name : removeFileExtension(file.name)}
</Text>
{!isDirectory && (
<Text
color="$gray9"
numberOfLines={1}
flexShrink={0}
textAlign="right"
className="ml-2 w-14 whitespace-nowrap text-[10px] opacity-40"
>
{formattedDate}
</Text>
)}
</XStack>
<NewDirectoryComponent
isOpen={isNewDirectoryModalOpen}
Expand Down
31 changes: 30 additions & 1 deletion src/components/Sidebars/FileSideBar/FileSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react'
import { FileInfoNode, FileInfoTree } from 'electron/main/filesystem/types'
import { FixedSizeList } from 'react-window'
import { isFileNodeDirectory } from '@shared/utils'
import { YStack } from 'tamagui'
import { XStack, YStack } from 'tamagui'
import { Calendar } from '@tamagui/lucide-icons'
import { useFileContext } from '@/contexts/FileContext'
import FileItemRows from './FileItemRows'

Expand Down Expand Up @@ -34,6 +35,7 @@ const FileSidebar: React.FC<FileExplorerProps> = ({ lheight }) => {
// const { state, actions } = useThemeManager()
const [listHeight, setListHeight] = useState(lheight ?? window.innerHeight - 50)
const { vaultFilesTree, expandedDirectories, renameFile, setSelectedDirectory } = useFileContext()
const [showDates, setShowDates] = useState<boolean>(true)

const handleDrop = async (e: React.DragEvent) => {
e.preventDefault()
Expand Down Expand Up @@ -63,10 +65,36 @@ const FileSidebar: React.FC<FileExplorerProps> = ({ lheight }) => {
}
}, [lheight])

useEffect(() => {
const init = async () => {
const val = await window.electronStore.getFileIndexDateVisibility()
setShowDates(val)
}
init()

const handler = (_e: any, val: boolean) => setShowDates(val)
window.ipcRenderer.on('file-index-date-visibility-changed', handler)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Missing cleanup for IPC event listener in useEffect - should return a cleanup function to prevent memory leaks

Suggested change
window.ipcRenderer.on('file-index-date-visibility-changed', handler)
useEffect(() => {
const init = async () => {
const val = await window.electronStore.getFileIndexDateVisibility()
setShowDates(val)
}
init()
const handler = (_e: any, val: boolean) => setShowDates(val)
window.ipcRenderer.on('file-index-date-visibility-changed', handler)
return () => {
window.ipcRenderer.off('file-index-date-visibility-changed', handler)
}
}, [])

}, [])

const filesAndIndentations = getFilesAndIndentationsForSidebar(vaultFilesTree, expandedDirectories)
const itemCount = filesAndIndentations.length
return (
<YStack className="h-full grow px-1 pt-2" backgroundColor="$gray3">
<XStack className="mb-1 items-center justify-end px-1">
<YStack
alignItems="center"
justifyContent="center"
hoverStyle={{ backgroundColor: '$gray7' }}
className={`size-5 cursor-pointer rounded ${showDates ? 'opacity-90' : 'opacity-30'}`}
onPress={async () => {
const next = !showDates
setShowDates(next)
await window.electronStore.setFileIndexDateVisibility(next)
}}
>
<Calendar size={14} color={showDates ? '$gray11' : '$gray9'} />
</YStack>
</XStack>
<div onDrop={handleDrop} onDragOver={handleDragOver} onClick={handleClick}>
<FixedSizeList
height={listHeight}
Expand All @@ -75,6 +103,7 @@ const FileSidebar: React.FC<FileExplorerProps> = ({ lheight }) => {
width="100%"
itemData={{
filesAndIndentations,
showDates,
}}
>
{FileItemRows}
Expand Down