@@ -749,6 +749,9 @@ class OpenNotebook {
749749 // Also remove token cookie
750750 document . cookie = 'token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' ;
751751
752+ // Clear cache
753+ this . cache . delete ( 'notebooks' ) ;
754+
752755 this . updateAuthUI ( ) ;
753756
754757 // Clear data
@@ -759,6 +762,9 @@ class OpenNotebook {
759762
760763 // 笔记本方法
761764 async loadNotebooks ( ) {
765+ // Always load public notebooks showcase (regardless of private notebooks)
766+ await this . loadPublicNotebooksShowcase ( ) ;
767+
762768 try {
763769 // 先尝试从缓存获取
764770 const cached = this . cache . get ( 'notebooks' ) ;
@@ -778,7 +784,12 @@ class OpenNotebook {
778784 this . renderNotebooks ( ) ;
779785 this . updateFooter ( ) ;
780786 } catch ( error ) {
781- this . showError ( '加载笔记本失败' ) ;
787+ // 401 Unauthorized is expected for non-logged-in users, don't show error
788+ if ( error . message && ! error . message . includes ( '401' ) ) {
789+ console . warn ( '用户未登录,跳过私有笔记本加载' ) ;
790+ } else {
791+ this . showError ( '加载笔记本失败' ) ;
792+ }
782793 }
783794 }
784795
@@ -859,6 +870,10 @@ class OpenNotebook {
859870
860871 // Load and render public notebooks showcase
861872 async loadPublicNotebooksShowcase ( ) {
873+ // Prevent duplicate calls
874+ if ( this . _publicNotebooksLoaded ) return ;
875+ this . _publicNotebooksLoaded = true ;
876+
862877 try {
863878 const response = await fetch ( '/public/notebooks' ) ;
864879 if ( ! response . ok ) return ;
@@ -870,6 +885,9 @@ class OpenNotebook {
870885 }
871886 }
872887
888+ // Cache to avoid duplicate calls
889+ _publicNotebooksLoaded = false ;
890+
873891 renderPublicNotebooksShowcase ( notebooks ) {
874892 const container = document . getElementById ( 'publicShowcase' ) ;
875893 const grid = document . getElementById ( 'publicShowcaseGrid' ) ;
@@ -890,25 +908,17 @@ class OpenNotebook {
890908 card . className = 'public-showcase-card' ;
891909 card . href = `/public/${ nb . public_token } ` ;
892910
911+ // Generate background style if cover image exists
912+ if ( nb . cover_image_url ) {
913+ card . style . backgroundImage = `url('${ nb . cover_image_url } ')` ;
914+ card . style . backgroundSize = 'cover' ;
915+ card . style . backgroundPosition = 'center' ;
916+ card . classList . add ( 'has-cover-image' ) ;
917+ }
918+
893919 card . innerHTML = `
894- <div class="public-showcase-card-header">
895- <div class="public-showcase-card-icon">
896- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
897- <rect x="3" y="3" width="18" height="18" rx="2"/>
898- <path d="M3 9h18"/>
899- <path d="M9 21V9"/>
900- </svg>
901- </div>
902- <div>
903- <h3 class="public-showcase-card-title">${ this . escapeHtml ( nb . name ) } </h3>
904- </div>
905- </div>
906- <p class="public-showcase-card-desc">${ this . escapeHtml ( nb . description || '暂无描述' ) } </p>
907- <div class="public-showcase-card-footer">
908- <div class="public-showcase-card-stats">
909- <span>${ nb . source_count || 0 } 来源</span>
910- <span>${ nb . note_count || 0 } 笔记</span>
911- </div>
920+ <div class="public-showcase-card-content">
921+ <h3 class="public-showcase-card-title">${ this . escapeHtml ( nb . name ) } </h3>
912922 </div>
913923 ` ;
914924
0 commit comments