-
Notifications
You must be signed in to change notification settings - Fork 56
Deep Links
אוצריא רשומה במערכת ההפעלה כמטפלת בסכמת ה־URI otzaria://. כל הפעלה של קישור כזה — מדפדפן, מאפליקציה אחרת, מקיצור דרך או משורת פקודה — פותחת את אוצריא (או מאותתת למופע הרץ) ומבצעת פעולה: ניווט, פתיחת ספר, הפעלת חיפוש, התקנת תוסף.
דף זה מתעד את הכתובות הנתמכות ואת המנגנון הפנימי. המסמך הקנוני במאגר: docs/deep_links.md. למדריך בשפה פשוטה: קישורי עומק למשתמש.
נייד ו־macOS — רישום סטטי בקונפיגורציית הפלטפורמה:
-
Android —
android/app/src/main/AndroidManifest.xml(<intent-filter>עם<data android:scheme="otzaria"/>). -
iOS / macOS —
Info.plist(CFBundleURLSchemes).
דסקטופ (Windows/Linux) — רישום דינמי בזמן ריצה דרך PluginProtocolRegistrationService.ensureRegistered. השם היסטורי ומטעה — השירות רושם את כל סכמת otzaria://, לא רק תוספים:
-
Windows — כתיבה ל־
HKCU\Software\Classes\otzariaעםshell\open\commandשמכוון ל־exe הפעיל. windows/runner/main.cppאחראי רק על מה שקורה אחרי שה־OS הפעיל את אוצריא עם הארגומנט. -
Linux — יצירת
~/.local/share/applications/otzaria.desktopעםMimeType=x-scheme-handler/otzaria;ואזupdate-desktop-database+ xdg-mime default.
| כתובת | תוצאה |
|---|---|
otzaria://open/library |
מסך הספרייה |
otzaria://open/tools |
מסך הכלים (הלשונית האחרונה שהיתה פעילה) |
otzaria://open/calendar / gematria / notes / shamor_zachor / measurements / aramaic_dictionary / acronyms_dictionary
|
פתיחת כלי מובנה |
otzaria://open/search |
מסך החיפוש (ללא הפעלת חיפוש) |
otzaria://open/search?q=<text> |
לשונית חיפוש חדשה + חיפוש מיידי בכל הספרים |
otzaria://open/search?q=<text>&mode=<mode> |
כנ"ל עם מצב: advanced / exact / fuzzy; ערך לא מוכר → מתקדם |
otzaria://open/settings |
הגדרות (הלשונית הנוכחית) |
otzaria://open/settings/<tab> |
הגדרות בלשונית: design / text / library / tools / shortcuts / system / about
|
otzaria://open/history |
דיאלוג ההיסטוריה |
otzaria://open/bookmarks |
דיאלוג הסימניות |
otzaria://open/detection |
דיאלוג איתור מקורות ריק |
otzaria://open/detection?q=<text> |
איתור מקורות עם טקסט מילוי־מראש + חיפוש מיידי |
otzaria://open/inspection |
מסך העיון (הספר האחרון שנפתח) |
otzaria://open/sdk |
דיאלוג ניהול התוספים |
otzaria://open/daily_page |
הדף היומי (PDF תלמוד בבלי בדף הנכון ליום) |
otzaria://open/tool/<tool-id> |
לשונית כלי לפי מזהה מלא (built-in או תוסף מוצמד) |
otzaria://open/plugin/<plugin-id> |
פתיחת תוסף לפי מזהה — גם לא־מוצמד (מצב transient) |
otzaria://open/tab/<index> |
מעבר לטאב פתוח לפי מיקומו (0-based); נבנה אוטומטית ב־Jump List של Windows |
otzaria://open/book/<id> |
ספר טקסט בעיון לפי מזהה DB |
otzaria://open/book/<id>?index=<n> |
פתיחה בסעיף n (לא שלילי) |
otzaria://open/book/<id>?q=<text> |
פתיחה עם מחרוזת חיפוש להדגשה; ניתן לשלב עם index
|
otzaria://open/book/<id>?index=<n>&mark |
הדגשת כל רקע המקטע בצהוב |
otzaria://open/book/<id>?index=<n>&m=<text> |
הדגשת טקסט ספציפי בתוך המקטע |
otzaria://open/pdf/<id> |
ספר PDF לפי מזהה משותף עם ה־TextBook |
otzaria://open/pdf/<id>?index=<n> |
פתיחת ה־PDF בעמוד n (חיובי, 1-based) |
כללי פרסינג:
- הסכמה, ה־host ושמות הפעולה — case-insensitive. הערכים (מזהי ספרים/כלים,
url=) נשמרים כפי שהם. - טקסט עברי ב־
q=/m=חייב URL-encoding (UTF-8). -
indexשלילי/לא מספרי,q=ריק,m=ריק — מתעלמים.detectionללאq=נפתח ריק. -
עדיפות הדגשה ב־
book: m> mark> q— אם יש סימון מקומי (m/mark), qמתעלם לחלוטין (לא תיפתח לשונית חיפוש במקביל). - כתובת לא מוכרת (
otzaria://open/banana) → null, התעלמות שקטה בכוונה. ספר עם ID לא קיים →UiSnack.showError.
| פרמטר | תיאור |
|---|---|
url (חובה) |
כתובת ההורדה של חבילת .otzplugin; רק http/https
|
overwrite (אופציונלי) |
true/1/yes/on — דריסת תוסף קיים בלי לשאול; ברירת מחדל false
|
משמש לשיוך קובץ .otzplugin במערכת ההפעלה (לחיצה כפולה). הנתיב חייב להיות מוחלט, להסתיים ב־.otzplugin, ולא נתיב UNC/התקן — ראו "אבטחה" למטה.
הראוטר מנרמל קישורי zayit:// של אפליקציית זַיִת לפורמט המקביל:
-
zayit://book/{id}← otzaria://open/book/{id} -
zayit://book/{id}/line/{index}← otzaria://open/book/{id}?index={index}
lib/utils/book_link_builder.dart — לוגיקה טהורה (ללא תלות ב־Flutter) לבניית קישורי ספר/מקטע/הדגשה, שמשמשת את פריטי "העתק קישור ישיר" בתפריטי ההקשר של קורא הטקסט וה־PDF, ואת קיצורי המקלדת המוגדרים ב־shortcut_validator.dart. הוספת סוג קישור חדש שמוצג למשתמש מתחילה שם.
לחיצה על otzaria://...
↓
ה-OS מפעיל את אוצריא עם הארגומנט
↓
אוצריא כבר רצה?
לא → הפעלה רגילה + טיפול בארגומנטים
כן → הפרוסס המשני כותב ל-pending_external_activations.jsonl ויוצא;
המופע הקיים מזהה את השינוי דרך file watcher
↓
_handleExternalActivationUriString(uri)
↓
ExternalUriRouter.parseUri → ExternalUriAction (sealed)
↓
_dispatchExternalUriAction — switch יחיד → ניווט / פתיחת ספר / התקנה
ב־windows/runner/main.cpp יש Mutex בשם OtzariaAppSingleInstance. מופע שני שמזהה מופע חי: מחלץ מהארגומנטים URIs שמתחילים ב־otzaria:, מוסיף אותם כשורות JSONL ל־%APPDATA%\otzaria\pending_external_activations.jsonl, ויוצא מיד. המופע הראשון מאזין לקובץ דרך ExternalActivationQueue; הקובץ עובר rename ל־.processing בזמן הקריאה כדי לא לאבד URIs אם המופע נסגר באמצע. ב־Android/iOS יש ערוץ פלטפורמה — external_activation_channel.dart.
ראוטר יחיד — lib/core/external_uri_router.dart — הוא נקודת הכניסה היחידה לפענוח. הוא מנתב את כל הכתובות ל־sealed class ExternalUriAction עם variant לכל סוג פעולה: OpenScreenAction, OpenToolAction, OpenPluginAction, SwitchToTabAction, OpenBookAction, OpenPdfBookAction, OpenSettingsTabAction, OpenHistoryAction, OpenBookmarksAction, RunSearchAction, RunDetectionAction, OpenInspectionAction, OpenSdkAction, OpenDailyPageAction, InstallPluginAction, InstallLocalPluginAction.
לפענוח plugin/install הראוטר מאציל ל־PluginStoreLinkParser.parseUri ועוטף את התוצאה ב־InstallPluginAction.
ל־OpenBookAction/OpenPdfBookAction יש hasExplicitPosition — קישור "חשוף" ללא מיקום לא מזיז טאב שכבר פתוח על הספר.
ב־main_window_screen.dart הפונקציה _handleExternalActivationUriString: מפענחת (אם null — מתעלמת בשקט), מציפה את החלון (_bringWindowToFront), ואז _dispatchExternalUriAction עם switch יחיד על ה־sealed class. נקודות עדינות:
-
OpenToolAction— ניווט ל־Screen.moreואזrequestOpenTool(toolId)עם retry מדורג; ב־ToolsScreenיש תור pending לכלי שה־descriptor שלו עוד לא נטען (תוסף שטרם הגיע מ־PluginSystemBloc). אחרי 5 שניות בלי הצלחה —UiSnack.showError. -
OpenPluginAction— ממתין גם ל־PluginSystemLoaded, מאתר את התוסף וקורא ל־openPluginTransiently— שמטפל גם במוצמד (ניתוב ל־requestOpenTool) וגם בלא־מוצמד (לשונית transient). תוסף חסר/מושבת →UiSnack.showError. -
OpenBookAction— await DataRepository.instance.library, איתור לפיb.id, ואזopenBook(...)עם index/הדגשות. -
RunSearchAction— יוצרSearchingTabחדש, מוסיף ל־HistoryBloc + TabsBloc, מנווט ל־Screen.search; החיפוש מופעל מ־TantivyFullTextSearch.initState. -
InstallLocalPluginAction— InstallPluginRequestedל־PluginSystemBloc; דיאלוג ההרשאות נפתח דרךBlocListener.
-
ראוטר — אם זו פעולה חדשה: variant חדש ב־
ExternalUriAction+ ענף ב־_parseOpen. אם זה כלי מובנה חדש — מספיק alias ב־_toolAliases. -
דיספצ'ר —
caseחדש ב־_dispatchExternalUriAction. הקומפיילר אוכף exhaustive matching על ה־sealed class. -
בדיקות —
test/core/external_uri_router_test.dart: כתובת תקינה, כתובות שנדחות, case-insensitivity. - תיעוד — עדכון טבלת הכתובות ב־docs/deep_links.md ובדף זה.
-
אין התקנת תוסף ללא אישור משתמש — גם עם
overwrite=trueהמשתמש רואה קבצים והרשאות לפני ההתקנה. -
plugin/installמקבל רקhttp/https; file://וכל סכמה אחרת נדחות. -
plugin/install-local— הנתיב חייב מוחלט (ב־Windows כולל אות כונן מפורשת), בסיומת.otzplugin, ולא UNC/התקן (\\server\share, \\.\, \\?\, //host). קישורotzaria://ניתן להפעלה מדף אינטרנט — נתיב UNC היה גורם לחיבור SMB ודליפת אישורי NTLM; נתיב יחסי נפתר מול תיקיית העבודה ולכן אינו מהימן. - כתובת לא מוכרת → התעלמות שקטה (עיצובית, כדי לא להפחיד משתמש שלחץ על קישור מגרסה עתידית); ספר לא קיים → הודעת שגיאה מפורשת.
| קובץ | תפקיד |
|---|---|
lib/core/external_uri_router.dart |
הראוטר האחיד + sealed ExternalUriAction
|
lib/utils/book_link_builder.dart |
בניית קישורי ספר לפעולות "העתק קישור ישיר" |
lib/plugins/services/plugin_store_link_parser.dart |
פענוח plugin/install (משמש את הראוטר) |
lib/plugins/services/plugin_protocol_registration_service.dart |
רישום דינמי של הסכמה ב־Windows/Linux |
lib/core/external_activation_queue.dart |
תור JSONL בין מופעים |
lib/core/external_activation_channel.dart |
ערוץ פלטפורמה ל־URIs בזמן ריצה (Android/iOS) |
lib/navigation/view/main_window_screen.dart |
האזנה, פענוח ודיספצ'ר |
windows/runner/main.cpp |
single-instance והעברת ארגומנטים לתור |
test/core/external_uri_router_test.dart |
בדיקות הראוטר |
📖 מדריך למשתמש
- התחלת העבודה
- הספרייה
- קריאת ספר
- קריאת PDF
- חיפוש
- איתור מקורות
- טאבים ושולחנות
- סימניות והערות
- ספרים אישיים
- הגדרות
- גיבוי ושחזור
- עדכונים
- תוספים
- כלים
- קישורי עומק
🛠️ למפתחים — יסודות
נתונים וספרייה
קריאה
חיפוש
אישי ומערכת
עיצוב ו־UI