@@ -52,6 +52,13 @@ export class TimelineSidebarView extends ItemView {
5252 private events : TimelineEvent [ ] = [ ] ;
5353 private isAutoScrolling : boolean = false ;
5454
55+ // Collapse state management
56+ private isInputCollapsed : boolean = false ;
57+ private tempEditorContent : string = "" ;
58+ private isAnimating : boolean = false ;
59+ private collapsedHeaderEl : HTMLElement | null = null ;
60+ private quickInputHeaderEl : HTMLElement | null = null ;
61+
5562 // Debounced methods
5663 private debouncedRender = debounce ( async ( ) => {
5764 await this . loadEvents ( ) ;
@@ -81,6 +88,9 @@ export class TimelineSidebarView extends ItemView {
8188 this . containerEl . empty ( ) ;
8289 this . containerEl . addClass ( "timeline-sidebar-container" ) ;
8390
91+ // Restore collapsed state from settings
92+ this . isInputCollapsed = this . plugin . settings . timelineSidebar . quickInputCollapsed ;
93+
8494 this . createHeader ( ) ;
8595 this . createTimelineArea ( ) ;
8696 this . createQuickInputArea ( ) ;
@@ -177,14 +187,30 @@ export class TimelineSidebarView extends ItemView {
177187 "timeline-quick-input"
178188 ) ;
179189
190+ // Create collapsed header (always exists but hidden when expanded)
191+ this . collapsedHeaderEl = this . quickInputContainerEl . createDiv (
192+ "quick-input-header-collapsed"
193+ ) ;
194+ this . createCollapsedHeader ( ) ;
195+
180196 // Input header with target info
181- const inputHeaderEl =
197+ this . quickInputHeaderEl =
182198 this . quickInputContainerEl . createDiv ( "quick-input-header" ) ;
183199
184- const headerTitle = inputHeaderEl . createDiv ( "quick-input-title" ) ;
200+ // Add collapse button to header
201+ const headerLeft = this . quickInputHeaderEl . createDiv ( "quick-input-header-left" ) ;
202+
203+ const collapseBtn = headerLeft . createDiv ( "quick-input-collapse-btn" ) ;
204+ setIcon ( collapseBtn , "chevron-down" ) ;
205+ collapseBtn . setAttribute ( "aria-label" , t ( "Collapse quick input" ) ) ;
206+ this . registerDomEvent ( collapseBtn , "click" , ( ) => {
207+ this . toggleInputCollapse ( ) ;
208+ } ) ;
209+
210+ const headerTitle = headerLeft . createDiv ( "quick-input-title" ) ;
185211 headerTitle . setText ( t ( "Quick Capture" ) ) ;
186212
187- const targetInfo = inputHeaderEl . createDiv ( "quick-input-target-info" ) ;
213+ const targetInfo = this . quickInputHeaderEl . createDiv ( "quick-input-target-info" ) ;
188214 this . updateTargetInfo ( targetInfo ) ;
189215
190216 // Editor container
@@ -218,8 +244,10 @@ export class TimelineSidebarView extends ItemView {
218244 }
219245 ) ;
220246
221- // Focus the editor
222- this . markdownEditor ?. editor ?. focus ( ) ;
247+ // Focus the editor if not collapsed
248+ if ( ! this . isInputCollapsed ) {
249+ this . markdownEditor ?. editor ?. focus ( ) ;
250+ }
223251 } , 50 ) ;
224252
225253 // Action buttons
@@ -242,6 +270,14 @@ export class TimelineSidebarView extends ItemView {
242270 this . registerDomEvent ( fullModalBtn , "click" , ( ) => {
243271 new QuickCaptureModal ( this . app , this . plugin , { } , true ) . open ( ) ;
244272 } ) ;
273+
274+ // Apply initial collapsed state
275+ if ( this . isInputCollapsed ) {
276+ this . quickInputContainerEl . addClass ( "is-collapsed" ) ;
277+ this . collapsedHeaderEl ?. show ( ) ;
278+ } else {
279+ this . collapsedHeaderEl ?. hide ( ) ;
280+ }
245281 }
246282
247283 private loadEvents ( ) : void {
@@ -636,8 +672,13 @@ export class TimelineSidebarView extends ItemView {
636672 await this . loadEvents ( ) ;
637673 this . renderTimeline ( ) ;
638674
639- // Focus back to input
640- this . markdownEditor . editor ?. focus ( ) ;
675+ // Check if we should collapse after capture
676+ if ( this . plugin . settings . timelineSidebar . quickInputCollapseOnCapture ) {
677+ this . toggleInputCollapse ( ) ;
678+ } else {
679+ // Focus back to input
680+ this . markdownEditor . editor ?. focus ( ) ;
681+ }
641682 } catch ( error ) {
642683 console . error ( "Failed to capture:" , error ) ;
643684 }
@@ -782,4 +823,125 @@ export class TimelineSidebarView extends ItemView {
782823 await this . loadEvents ( ) ;
783824 this . renderTimeline ( ) ;
784825 }
826+
827+ // Create collapsed header content
828+ private createCollapsedHeader ( ) : void {
829+ if ( ! this . collapsedHeaderEl ) return ;
830+
831+ // Expand button
832+ const expandBtn = this . collapsedHeaderEl . createDiv ( "collapsed-expand-btn" ) ;
833+ setIcon ( expandBtn , "chevron-right" ) ;
834+ expandBtn . setAttribute ( "aria-label" , t ( "Expand quick input" ) ) ;
835+ this . registerDomEvent ( expandBtn , "click" , ( ) => {
836+ this . toggleInputCollapse ( ) ;
837+ } ) ;
838+
839+ // Title
840+ const titleEl = this . collapsedHeaderEl . createDiv ( "collapsed-title" ) ;
841+ titleEl . setText ( t ( "Quick Capture" ) ) ;
842+
843+ // Quick actions
844+ if ( this . plugin . settings . timelineSidebar . quickInputShowQuickActions ) {
845+ const quickActionsEl = this . collapsedHeaderEl . createDiv ( "collapsed-quick-actions" ) ;
846+
847+ // Quick capture button
848+ const quickCaptureBtn = quickActionsEl . createDiv ( "collapsed-quick-capture" ) ;
849+ setIcon ( quickCaptureBtn , "plus" ) ;
850+ quickCaptureBtn . setAttribute ( "aria-label" , t ( "Quick capture" ) ) ;
851+ this . registerDomEvent ( quickCaptureBtn , "click" , ( ) => {
852+ // Expand and focus editor
853+ if ( this . isInputCollapsed ) {
854+ this . toggleInputCollapse ( ) ;
855+ setTimeout ( ( ) => {
856+ this . markdownEditor ?. editor ?. focus ( ) ;
857+ } , 350 ) ; // Wait for animation
858+ }
859+ } ) ;
860+
861+ // More options button
862+ const moreOptionsBtn = quickActionsEl . createDiv ( "collapsed-more-options" ) ;
863+ setIcon ( moreOptionsBtn , "more-horizontal" ) ;
864+ moreOptionsBtn . setAttribute ( "aria-label" , t ( "More options" ) ) ;
865+ this . registerDomEvent ( moreOptionsBtn , "click" , ( ) => {
866+ new QuickCaptureModal ( this . app , this . plugin , { } , true ) . open ( ) ;
867+ } ) ;
868+ }
869+ }
870+
871+ // Toggle collapse state
872+ private toggleInputCollapse ( ) : void {
873+ if ( this . isAnimating ) return ;
874+
875+ this . isAnimating = true ;
876+ this . isInputCollapsed = ! this . isInputCollapsed ;
877+
878+ // Save state to settings
879+ this . plugin . settings . timelineSidebar . quickInputCollapsed = this . isInputCollapsed ;
880+ this . plugin . saveSettings ( ) ;
881+
882+ if ( this . isInputCollapsed ) {
883+ this . handleCollapseEditor ( ) ;
884+ } else {
885+ this . handleExpandEditor ( ) ;
886+ }
887+
888+ // Reset animation flag after animation completes
889+ setTimeout ( ( ) => {
890+ this . isAnimating = false ;
891+ } , this . plugin . settings . timelineSidebar . quickInputAnimationDuration ) ;
892+ }
893+
894+ // Handle collapsing the editor
895+ private handleCollapseEditor ( ) : void {
896+ // Save current editor content
897+ if ( this . markdownEditor ) {
898+ this . tempEditorContent = this . markdownEditor . value ;
899+ }
900+
901+ // Add collapsed class for animation
902+ this . quickInputContainerEl . addClass ( "is-collapsing" ) ;
903+ this . quickInputContainerEl . addClass ( "is-collapsed" ) ;
904+
905+ // Show collapsed header after a slight delay
906+ setTimeout ( ( ) => {
907+ this . collapsedHeaderEl ?. show ( ) ;
908+ this . quickInputContainerEl . removeClass ( "is-collapsing" ) ;
909+ } , 50 ) ;
910+
911+ // Update collapse button icon
912+ const collapseBtn = this . quickInputHeaderEl ?. querySelector ( ".quick-input-collapse-btn" ) ;
913+ if ( collapseBtn ) {
914+ setIcon ( collapseBtn as HTMLElement , "chevron-right" ) ;
915+ collapseBtn . setAttribute ( "aria-label" , t ( "Expand quick input" ) ) ;
916+ }
917+ }
918+
919+ // Handle expanding the editor
920+ private handleExpandEditor ( ) : void {
921+ // Hide collapsed header immediately
922+ this . collapsedHeaderEl ?. hide ( ) ;
923+
924+ // Remove collapsed class for animation
925+ this . quickInputContainerEl . addClass ( "is-expanding" ) ;
926+ this . quickInputContainerEl . removeClass ( "is-collapsed" ) ;
927+
928+ // Restore editor content
929+ if ( this . markdownEditor && this . tempEditorContent ) {
930+ this . markdownEditor . set ( this . tempEditorContent , false ) ;
931+ this . tempEditorContent = "" ;
932+ }
933+
934+ // Focus editor after animation
935+ setTimeout ( ( ) => {
936+ this . quickInputContainerEl . removeClass ( "is-expanding" ) ;
937+ this . markdownEditor ?. editor ?. focus ( ) ;
938+ } , 50 ) ;
939+
940+ // Update collapse button icon
941+ const collapseBtn = this . quickInputHeaderEl ?. querySelector ( ".quick-input-collapse-btn" ) ;
942+ if ( collapseBtn ) {
943+ setIcon ( collapseBtn as HTMLElement , "chevron-down" ) ;
944+ collapseBtn . setAttribute ( "aria-label" , t ( "Collapse quick input" ) ) ;
945+ }
946+ }
785947}
0 commit comments