-
Notifications
You must be signed in to change notification settings - Fork 56
App Startup
דף זה מתאר מה קורה מרגע הפעלת אוצריא ועד שהחלון הראשי מוצג — תחום שבו הושקע מאמץ רב בביצועים (הצגה מהירה של החלון).
הפונקציה main(List<String> args) מבצעת, לפי הסדר:
-
פקודות CLI —
_maybeRunCliCommandבודק אם זו הרצת שורת־פקודה (למשלpack-pluginלאריזת תוסף.otzplugin). אם כן — התהליך מסתיים בלי לפתוח חלון. -
אתחול Bindings —
SentryWidgetsFlutterBinding.ensureInitialized(). -
סמן דטרמיניסטי —
EditableText.debugDeterministicCursor = true, כדי ש־RtlTextFieldינהל את הבהוב הסמן בעצמו. -
לוגים מוקדמים — אתחול data root ומטא־דטה של גרסה (
PackageInfo). -
תור הפעלות חיצוניות — זיהוי
otzaria://וקבצי.otzpluginבארגומנטים והכנסתם לתור. -
מטפלי שגיאות —
FlutterError.onErrorו־PlatformDispatcher.onError, כולל סינון "רעש" ידוע (שגיאות AXTree ב־Windows, אסרשןHardwareKeyboard, באג_notifyMissingFontsשל pdfrx). בגרסת production השגיאות נכתבות ל־ErrorLogFile(logs/errors.txtבתיקיית הנתונים; נמחק בשדרוג גרסה). -
Sentry — אתחול אסינכרוני (
unawaited); דיווח רק מגרסה שפורסמה, sampling נמוך, ללא PII. -
_runAppBootstrap— שומר מופע יחיד (single instance, מדולג ב־macOS/iOS), רושםAppBlocObserver, מאתחלwindowManager(החלון נשאר מוסתר!), וקוראrunApp.
עץ ה־runApp: SentryWidget → RestartWidget → AppBootstrap.
- ה־splash הוא נייטיבי — חלק מה־runner של כל פלטפורמת דסקטופ. החלון הראשי של Flutter מוסתר עד הקריאה ל־
presentMainWindow(). -
_mainWindowRevealedCompleterמסנכרן: חימומי מטמון כבדים ממתינים לחשיפת החלון כדי לא להתחרות בטעינת הספר הפעיל על ה־main isolate ועלseforim.db. -
presentMainWindow()מבצע cloak נייטיבי,show/focus, מחיל maximize/fullscreen שנדחו, וסוגר את ה־splash דרךMethodChannel('otzaria/splash'). - ב־
MainWindowScreen: אם המסך ההתחלתי הוא "עיון" עם ספר טקסט שעדיין נטען — החשיפה ממתינה ל־TextBookLoaded/TextBookError. קיים failsafe של 8 שניות.
מריץ במקביל (Future.wait):
-
RustLib.init()— FFI של מנוע החיפוש (Tantivy). -
loadCerts()— טעינת תעודת NetFree (רשתות מסוננות). -
initSettingsAndWindow()— אתחולSettingsעםHiveCache, שחזור גבולות חלון.
לאחר מכן: initHive() (פתיחת ה־boxes: tabs, workspaces, history, bookmarks, error_reports_queue), PortablePaths.migrateIfMoved() (מצב נייד — שכתוב נתיבים אם התיקייה הועברה), ושירותים דחויים.
- שחזור עדכון ספרייה שנקטע באמצע (
_recoverInterruptedLibraryUpdate). -
SqliteDataProvider.initialize. - אתחול מקורות תוספים +
PluginCrashGuard. - רישום פרוטוקול ו־pre-warm של WebView2 (הכל
unawaited).
השלב הזה ניתן להרצה חוזרת — זה מה שמאפשר "restart" של ה־runtime דרך RestartWidget בלי לסגור את התהליך.
ממתין לחשיפת החלון (timeout 15 שניות) ורק אז מחמם מטמונים: DictionaryLookupRepository, BooksCache, AcronymsCache, GenerationCache, גופני מערכת, ReferenceBooksCache, ספרי HebrewBooks מקומיים.
AppBootstrap (StatefulWidget) מציג SplashApp עד שהאתחול הסתיים (ובמקרה שגיאה — מסך שגיאה RTL). כשמוכן, נבנה:
-
MultiRepositoryProvider— FocusRepository, SettingsRepository. -
MultiBlocProvider— כל ה־BLoCs הראשיים. שימו לב:LibraryBlocנרשם בליLoadLibrary— הטעינה נדחית ל־MainWindowScreenכדי לא לחנוק את טעינת הספר הפעיל.
עוטף את MaterialApp ב־BlocBuilder<SettingsBloc> שנבנה מחדש רק על שינויי צבע ראשי / מצב כהה / תפריט קומפקטי. מגדיר:
-
navigatorKeyגלובלי (מ־ui_snack.dart) — משמש אתUiSnack. - locale קבוע
he_ILעם לוקליזציות Global — זה מה שקובע RTL גלובלי. - ערכות נושא מ־
AppThemeData.light/dark. - בדסקטופ — עטיפה ב־
VirtualWindowFrame(שורת כותרת מותאמת). -
home: MainWindowScreen.
lib/navigation/view/startup_work_gate.dart — מתאם שמונע הרצת עבודות רקע כבדות (סנכרון קבצים, עדכון ספרייה) עד שמתקיימים כל התנאים: הספרייה נטענה, התקבלה החלטת אינדוקס, והאינדוקס אינו רץ. consumeStartPermission() מחזיר true פעם אחת בלבד.
החלטת האינדוקס עצמה היא פונקציה טהורה — decideStartupIndexing ב־lib/navigation/startup_indexing_decision.dart, שמחזירה אחת מ: autoReindexThenStart / promptManualReindex / startIndexing / checkIndexStatus.
-
WindowPersistence— שמירה ושחזור של גבולות החלון עם debounce;splashModeמונע שמירת גודל ה־splash בטעות; maximize/fullscreen נדחים עד לחשיפה. -
AppWindowListener— האזנה לאירועי חלון. -
FocusRepository— שחזור פוקוס אחרי אירועי חלון (maximize/fullscreen/resize) במודל שתי שכבות: שכבת מסך ושכבת דיאלוג (stack).
📖 מדריך למשתמש
- התחלת העבודה
- הספרייה
- קריאת ספר
- קריאת PDF
- חיפוש
- איתור מקורות
- טאבים ושולחנות
- סימניות והערות
- ספרים אישיים
- הגדרות
- גיבוי ושחזור
- עדכונים
- תוספים
- כלים
- קישורי עומק
🛠️ למפתחים — יסודות
נתונים וספרייה
קריאה
חיפוש
אישי ומערכת
עיצוב ו־UI