Skip to content

Tabs and Workspaces

palmoni5 edited this page Jul 17, 2026 · 1 revision

טאבים ושולחנות עבודה

מערכת הטאבים (lib/tabs/) היא הליבה של חוויית הקריאה: כל ספר, חיפוש או תצוגה משולבת נפתחים בטאב. שולחנות העבודה (lib/workspaces/) מאפשרים להחזיק כמה אוספי טאבים במקביל.

מודל הטאב — OpenedTab

lib/tabs/models/tab.dart — מחלקת בסיס אבסטרקטית עם title, ‏isPinned, ‏dedupeKey, ומתודות dispose() ו־clone().

בנאי factory מרכזיים:

  • OpenedTab.from(tab) — יוצר עותק עצמאי (שיבוט אמיתי, לא הפניה) כולל שימור מצב מה־bloc: תצוגה מפוצלת, צורת הדף, מפרשים פעילים, hightlight ממוקד. קריטי לשולחנות עבודה ולתצוגה זו־לצד־זו.
  • OpenedTab.fromBook(book, index) — בוחר סוג טאב לפי סוג הספר: ‏PdfBook ← ‏PdfBookTab, ‏DocxBook ← ‏TextBookTab (דרך toTextBook), ‏TextBook ← ‏TextBookTab.
  • OpenedTab.fromJson — שחזור מ־persistence לפי שדה type.

סוגי הטאבים

מחלקה קובץ תוכן
TextBookTab models/text_tab.dart ספר טקסט. מחזיק TextBookBloc, ‏controllers של גלילה (scrollable_positioned_list), ‏ValueNotifiers לניווט מקיצורי מקלדת, מצב חיפוש בספר, הדגשות (כולל permanentHighlightLine מ־deep link עם ?mark)
PdfBookTab models/pdf_tab.dart ספר PDF. מחזיק PdfViewerController, ‏outline, מצב חלונית צד, תוצאות חיפוש PDF, קישורים
SearchingTab models/searching_tab.dart חלון חיפוש מלא־טקסט. מחזיק SearchBloc, אפשרויות חיפוש פר־מילה וגלובליות, מילים חלופיות, מרווחים
CombinedTab models/combined_tab.dart שני ספרים זה לצד זה — עוטף rightTab+leftTab עם splitRatio
CommentatorsTab / PdfCommentatorsTab כרטיסיית מפרשים עצמאית

TabsBloc — ‏lib/tabs/bloc/

כל ה־handlers רצים עם transformer: sequential() (מניעת מרוצים). אירועים עיקריים:

  • ניהול בסיסי: LoadTabs, ‏AddTab, ‏RemoveTab, ‏SetCurrentTab, ‏MoveTab, ‏CloneTab, ‏SaveTabs, ‏TogglePinTab.
  • סגירה: CloseCurrentTab / CloseOtherTabs / CloseAllTabs (טאבים מוצמדים שורדים "סגור הכל").
  • שחזור: RestoreLastClosedTab — מחסנית _recentlyClosedTabs.
  • ניווט: NavigateToNextTab / NavigateToPreviousTab.
  • תצוגה זו־לצד־זו: EnableSideBySideMode, ‏DisableSideBySideMode, ‏UpdateSplitRatio, ‏SwapSideBySideTabs.
  • RemapBookPaths — עדכון נתיבים בהעברת ספרייה (ראו בהמשך).

מיחזור טאבים חכם — OpenOrFocusTab

כשמבקשים לפתוח ספר, ה־bloc קודם מחפש טאב קיים תואם (_findMatchingTopLevelTabIndex → ‏_isSameBook לפי מזהה ספר/קטגוריה/קובץ, בדיקת dedupeKey). אם נמצא — הפוקוס עובר אליו, ה־highlight הממוקד מוחל עליו, ומבוצע ניווט למיקום המבוקש — כולל המתנה ל־TextBookLoaded וניסיונות חוזרים לחיבור ה־scrollController.

פרטים עדינים

  • dispose דחוי (350ms‏, _disposeTabLater) — כדי לא לפרק controllers של טאב שעדיין באנימציית יציאה.
  • TabsState כולל updateCounter לכפיית רענון UI.

שמירה ושחזור — TabsRepository

lib/tabs/tabs_repository.dart — ‏Hive box בשם tabs, מפתחות key-tabs, ‏key-current-tab, ‏key-side-by-side-mode.

  • loadTabs() — פענוח עמיד לשגיאות: טאב פגום מדולג, השאר נטענים.
  • saveCurrentTabIndex — שמירה קלת־משקל של האינדקס בלבד בכל מעבר טאב.
  • remapBookPaths — בהעברת מיקום הספרייה (או שינוי אות כונן), משכתב path/filePath של ספרי PDF/DOCX בכל עומק המבנה השמור.

מסך הקריאה — ReadingScreen

lib/tabs/reading_screen.dart — מציג את הטאב הפעיל. משתמש ב־PageView מנוהל ידנית (ולא TabBarView) כדי לשמר את ה־State של תצוגות PDF. תומך בהחלקה אופקית למעבר בין טאבים (סף 80 פיקסלים).

ב־Windows קיים גם WindowsJumpListService (lib/tabs/services/) — רשימת קפיצה בשורת המשימות.

שולחנות עבודה — lib/workspaces/

המודל — Workspace

‏Immutable ‏(Equatable): ‏id (ייחודי — microseconds + מונה), name, ‏tabs, ‏activeTabIndex.

WorkspaceBloc — ארכיטקטורה מנותקת

ה־bloc אינו מכיר את TabsBloc. ה־UI מתאם ביניהם: נתוני טאבים מגיעים דרך אירועים, והתקשורת חזרה נעשית דרך callback‏ onWorkspaceTabsChanged שנקבע ב־AppBootstrap (וממופה ל־TabsBloc.ReplaceAllTabs).

זרימת החלפת שולחן עבודה (SwitchToWorkspace):

  1. שמירת הטאבים הנוכחיים לשולחן הנוכחי.
  2. קריאת טאבי היעד (עם שיבוט מלא דרך OpenedTab.from — שום שיתוף controllers).
  3. פליטת state ← הודעה ל־UI דרך ה־callback ← שמירה ל־repository.

כללים: נוצר שולחן ברירת מחדל ("שולחן עבודה 1") אם אין; אי־אפשר למחוק שולחן פעיל.

WorkspaceRepository

‏Hive box בשם workspaces עם מיגרציה ממפתח legacy מבוסס־אינדקס. פענוח עמיד לשגיאות — שולחן פגום מדולג, ובכשל טעינה הנתונים הגולמיים לא נדרסים.

UI

view/workspace_switcher_dialog.dart — דיאלוג החלפה, נפתח גם בקיצור Ctrl+K.

דפים קשורים

Clone this wiki locally