diff --git a/app/application.ml b/app/application.ml index 633e6d39..020de3d8 100644 --- a/app/application.ml +++ b/app/application.ml @@ -284,8 +284,6 @@ type state = ; task_status_page : int ; reference_sources : string Reference_sources.t ; import_completion : (string * string option) option - ; asset_import_request : int - ; asset_import_owner : (string * int64) option ; capture_pick_request : int ; capture_picker_armed : bool ; capture_pick_owner : composer_owner option @@ -434,8 +432,6 @@ let initial_state = ; task_status_page = 0 ; reference_sources = Reference_sources.empty ; import_completion = None - ; asset_import_request = 0 - ; asset_import_owner = None ; capture_pick_request = 0 ; capture_picker_armed = false ; capture_pick_owner = None @@ -2731,11 +2727,7 @@ let detail_page ~media_store ?(on_region = fun _ -> ()) ~state ~on_scroll_comple | Copying -> "Copying block and descendants…" | Copied -> "Copied block and descendants" | Copy_failed_detail message -> "Copy failed: " ^ message)) - ; import_request = Journal_asset_import.file_request - ~id:(if state.asset_import_owner - = Option.map (fun id -> id, Journal_routes.detail_request_generation state.routes) - (Journal_routes.active_entry_id state.routes) - then state.asset_import_request else 0) + ; import_request = Journal_asset_import.file_request ~id:0 ; import_completion = state.import_completion ; render_title = Journal_model.Title.render ~lookup:(fun id -> Reference_sources.find_opt id sources) @@ -6263,8 +6255,6 @@ let start && left.reference_sources == right.reference_sources && left.task_catalog.definitions == right.task_catalog.definitions && left.import_completion = right.import_completion - && left.asset_import_request = right.asset_import_request - && left.asset_import_owner = right.asset_import_owner && left.graph_ready = right.graph_ready && left.detail_copy_feedback = right.detail_copy_feedback && operation_failure left.timeline_notice = operation_failure right.timeline_notice @@ -6406,6 +6396,33 @@ let start (Some (capture_assets state ~camera:(state.environment.platform = "ios")))) (Journal_detail.child_capture detail)) in + let capture_composer state ~render = + Option.map + (fun capture -> + render + ~kind:Journal_composer_view.Capture + ~capture + ~saving:(Journal_capture.phase capture = Journal_capture.Saving) + ~enabled:state.write_enabled + ~on_edit:dispatch + ~on_toggle: + (Ui.Event.Handler.create (function + | Ui.Event.Payload.Bool selected -> + dispatch.send + (if selected then Capture_task_on else Capture_task_off) + | _ -> ())) + ~on_save:(bind_action dispatch Capture_submit) + ~error: + (match composer_error state Timeline_composer with + | Some failure -> Some (capture_failure_message failure) + | None -> + (match Journal_capture.phase capture with + | Failed message -> Some message + | Editing | Saving -> None)) + ~assets: + (Some (capture_assets state ~camera:(state.environment.platform = "ios")))) + state.direct_capture + in let floating_capture state = (* On iOS the capture composer expands directly into the bottom bar instead of presenting a sheet. It is mounted through the body @@ -6415,32 +6432,8 @@ let start match state.modal with | Capture_sheet when state.environment.platform = "ios" -> Option.map - (fun capture -> - V.column - ~spacing:0. - [ composer_content - ~kind:Journal_composer_view.Capture - ~saving:(Journal_capture.phase capture = Journal_capture.Saving) - ~capture - ~enabled:state.write_enabled - ~on_edit:dispatch - ~on_toggle: - (Ui.Event.Handler.create (function - | Ui.Event.Payload.Bool selected -> - dispatch.send - (if selected then Capture_task_on else Capture_task_off) - | _ -> ())) - ~on_save:(bind_action dispatch Capture_submit) - ~error: - (match composer_error state Timeline_composer with - | Some failure -> Some (capture_failure_message failure) - | None -> - (match Journal_capture.phase capture with - | Failed message -> Some message - | Editing | Saving -> None)) - ~assets:(Some (capture_assets state ~camera:true)) - ]) - state.direct_capture + (fun content -> V.column ~spacing:0. [ content ]) + (capture_composer state ~render:composer_content) | Append_sheet when state.environment.platform = "ios" -> append_composer state ~render:composer_content | _ -> None @@ -6708,33 +6701,9 @@ let start if state.environment.platform = "ios" then None else - Option.map - (fun capture -> - composer_page - ~kind:Journal_composer_view.Capture - ~saving:(Journal_capture.phase capture = Journal_capture.Saving) - ~capture - ~enabled:state.write_enabled - ~on_edit:dispatch - ~on_toggle: - (Ui.Event.Handler.create (function - | Ui.Event.Payload.Bool selected -> - dispatch.send - (if selected then Capture_task_on else Capture_task_off) - | _ -> ())) - ~on_save:(bind_action dispatch Capture_submit) - ~on_close:(bind_action dispatch Close_composer) - ~error: - (match composer_error state Timeline_composer with - | Some failure -> Some (capture_failure_message failure) - | None -> - (match Journal_capture.phase capture with - | Failed message -> Some message - | Editing | Saving -> None)) - ~assets: - (Some - (capture_assets state ~camera:(state.environment.platform = "ios")))) - state.direct_capture + capture_composer + state + ~render:(composer_page ~on_close:(bind_action dispatch Close_composer)) | Append_sheet -> append_composer state diff --git a/app/journal_asset_import.ml b/app/journal_asset_import.ml index f25f25fc..7065335e 100644 --- a/app/journal_asset_import.ml +++ b/app/journal_asset_import.ml @@ -158,8 +158,6 @@ let decode_event payload = let extension = Ui.Native_widget.Extension.create ~kind_id:(Journal_ids.Native_widget.Kind_id.of_int 2104) - ~version:1 - ~capabilities:[ Stateful; Resource; Semantics ] ~encode_props:(fun props -> Json.props_to_yojson props |> Yojson.Safe.to_string |> Bytes.of_string) ~decode_event:(fun ~event_id:_ bytes -> Ok (Bytes.to_string bytes)) () diff --git a/app/journal_asset_settings.ml b/app/journal_asset_settings.ml index adc2c410..7b3bc21b 100644 --- a/app/journal_asset_settings.ml +++ b/app/journal_asset_settings.ml @@ -36,8 +36,6 @@ end let extension = Ui.Native_widget.Extension.create ~kind_id:(Journal_ids.Native_widget.Kind_id.of_int 2106) - ~version:1 - ~capabilities:[ Stateful; Semantics ] ~encode_props:(fun props -> Json.props_to_yojson props |> Yojson.Safe.to_string |> Bytes.of_string) ~decode_event:(fun ~event_id:_ bytes -> Ok (Bytes.to_string bytes)) () diff --git a/app/journal_header.ml b/app/journal_header.ml index 6e28fed2..933ffaee 100644 --- a/app/journal_header.ml +++ b/app/journal_header.ml @@ -34,8 +34,6 @@ let props ~mode ?title ?connecting ?controls ?text ?id ?level ?loading ?initial let chrome = Ui.Native_widget.Extension.create ~kind_id:(Journal_ids.Native_widget.Kind_id.of_int 2103) - ~version:2 - ~capabilities:[ Stateful; Semantics ] ~encode_props:(fun props -> Json.props_to_yojson props |> Yojson.Safe.to_string |> Bytes.of_string) ~decode_event:(fun ~event_id:_ _ -> Error "Chrome uses child control events") () diff --git a/app/journal_manager_view.ml b/app/journal_manager_view.ml index f8c6629c..f1169bc0 100644 --- a/app/journal_manager_view.ml +++ b/app/journal_manager_view.ml @@ -351,8 +351,6 @@ let view ?picker_signal props ~on_action = let chrome = Ui.Native_widget.Extension.create ~kind_id:(Journal_ids.Native_widget.Kind_id.of_int 2103) - ~version:2 - ~capabilities:[ Stateful; Semantics ] ~encode_props:(fun props -> unlock_chrome_props_to_yojson props |> Yojson.Safe.to_string |> Bytes.of_string) ~decode_event:(fun ~event_id:_ _ -> Error "Unlock uses child control events") () diff --git a/app/journal_view.ml b/app/journal_view.ml index ec1dcee5..7e069546 100644 --- a/app/journal_view.ml +++ b/app/journal_view.ml @@ -175,13 +175,6 @@ module Event = struct ; last_exclusive : int64 } - type native_event = - { kind_id : Journal_ids.Native_widget.Kind_id.t - ; version : int - ; event_id : int - ; payload : bytes - } - type confirmation_result = | Action of string | Dismissed @@ -223,7 +216,6 @@ module Event = struct | Scroll of scroll | Visible_range of visible_range | Navigation_path_changed of Journal_ids.Navigation.Page_key.t list - | Native_event of native_event | Native_list_completion of native_list_completion | Event of Lui_protocol.event end @@ -2049,36 +2041,9 @@ module View = struct end module Native_widget = struct - module Capability = struct - type t = - | Stateful - | Resource - | Semantics - | Semantics_canvas - | Virtualized - - let bit = function - | Stateful -> 0L - | Resource -> 1L - | Semantics -> 2L - | Semantics_canvas -> 3L - | Virtualized -> 4L - ;; - - let bits capabilities = - List.fold_left - (fun acc capability -> - Int64.logor acc (Int64.shift_left 1L (Int64.to_int (bit capability)))) - 0L - capabilities - ;; - end - module Extension = struct type ('props, 'event) t = { identifier : string - ; kind_id : Journal_ids.Native_widget.Kind_id.t - ; version : int ; encode_props : 'props -> bytes ; decode_event : event_id:Journal_ids.Native_widget.Event_id.t @@ -2094,10 +2059,8 @@ module Native_widget = struct | other -> invalid_arg ("unregistered journal extension kind " ^ string_of_int other) ;; - let create ~kind_id ~version ~capabilities:_ ~encode_props ~decode_event () = + let create ~kind_id ~encode_props ~decode_event () = { identifier = identifier_of_kind_id kind_id - ; kind_id - ; version ; encode_props ; decode_event } @@ -2111,20 +2074,6 @@ module Native_widget = struct (Bytes.of_string event.Journal_lui_native.payload) ;; - let event_handler ?name:_ extension callback = - Event.Handler.create (fun payload -> - match payload with - | Event.Payload.Native_event { event_id; payload; _ } -> - (match - extension.Extension.decode_event - ~event_id:(Journal_ids.Native_widget.Event_id.of_int event_id) - payload - with - | Ok event -> callback event - | Error source -> report_event_error "decodeExtensionEvent" source) - | _ -> ()) - ;; - let mount extension ?key ~props ~on_event ~children context parent = let payload = Bytes.to_string (extension.Extension.encode_props props) in Journal_lui_native.mount @@ -2158,25 +2107,4 @@ module Native_widget = struct props_signal; node) ;; - - let widget_with_handler extension ?key ~props ~on_event ?(children = []) () = - element ?key (fun context parent -> - let payload = Bytes.to_string (extension.Extension.encode_props props) in - Journal_lui_native.mount - ?key - ~payload - ~children:(List.map (fun element -> element.mount) children) - ~on_event:(fun event -> - Event.Handler.Private.invoke - on_event - (Event.Payload.Native_event - { kind_id = extension.Extension.kind_id - ; version = extension.Extension.version - ; event_id = event.Journal_lui_native.event_id - ; payload = Bytes.of_string event.Journal_lui_native.payload - })) - extension.Extension.identifier - context - parent) - ;; end diff --git a/app/journal_view.mli b/app/journal_view.mli index 655e3a95..272ec59f 100644 --- a/app/journal_view.mli +++ b/app/journal_view.mli @@ -49,13 +49,6 @@ module Event : sig ; last_exclusive : int64 } - type native_event = - { kind_id : Journal_ids.Native_widget.Kind_id.t - ; version : int - ; event_id : int - ; payload : bytes - } - type confirmation_result = | Action of string | Dismissed @@ -97,7 +90,6 @@ module Event : sig | Scroll of scroll | Visible_range of visible_range | Navigation_path_changed of Journal_ids.Navigation.Page_key.t list - | Native_event of native_event | Native_list_completion of native_list_completion | Event of Lui_protocol.event end @@ -805,25 +797,11 @@ module View : sig end module Native_widget : sig - module Capability : sig - type t = - | Stateful - | Resource - | Semantics - | Semantics_canvas - | Virtualized - - val bit : t -> int64 - val bits : t list -> int64 - end - module Extension : sig type ('props, 'event) t val create : kind_id:Journal_ids.Native_widget.Kind_id.t - -> version:int - -> capabilities:Capability.t list -> encode_props:('props -> bytes) -> decode_event: (event_id:Journal_ids.Native_widget.Event_id.t @@ -833,12 +811,6 @@ module Native_widget : sig -> ('props, 'event) t end - val event_handler - : ?name:string - -> ('props, 'event) Extension.t - -> ('event -> unit) - -> Event.handler - val widget : ('props, 'event) Extension.t -> ?key:Key.t @@ -848,13 +820,4 @@ module Native_widget : sig -> ?children:View.t list -> unit -> View.t - - val widget_with_handler - : ('props, 'event) Extension.t - -> ?key:Key.t - -> props:'props - -> on_event:Event.handler - -> ?children:View.t list - -> unit - -> View.t end diff --git a/logseq_db_storage/lib/mutation_receipt_store.ml b/logseq_db_storage/lib/mutation_receipt_store.ml index f0d6d413..083af6e5 100644 --- a/logseq_db_storage/lib/mutation_receipt_store.ml +++ b/logseq_db_storage/lib/mutation_receipt_store.ml @@ -87,6 +87,21 @@ let read_mutation db key = | exn -> Error (Printexc.to_string exn))) ;; +let insert_receipts db statement receipts = + let rec insert = function + | [] -> Ok () + | (key, receipt) :: rest -> + Sqlite3.Rc.check (Sqlite3.reset statement); + Sqlite3.Rc.check (Sqlite3.bind_text statement 1 key); + Sqlite3.Rc.check (Sqlite3.bind_text statement 2 receipt); + (match rc_result db (Sqlite3.step statement) with + | Error _ as error -> error + | Ok () -> insert rest) + in + try insert receipts with + | exn -> Error (Printexc.to_string exn) +;; + let upsert_mutations db receipts = match List.find_opt (fun (key, _) -> not (valid_key key)) receipts with | Some _ -> Error "mutation receipt key must be a lowercase SHA-256 value" @@ -99,19 +114,7 @@ let upsert_mutations db receipts = in Fun.protect ~finally:(fun () -> ignore (Sqlite3.finalize statement)) - (fun () -> - let rec insert = function - | [] -> Ok () - | (key, receipt) :: rest -> - Sqlite3.Rc.check (Sqlite3.reset statement); - Sqlite3.Rc.check (Sqlite3.bind_text statement 1 key); - Sqlite3.Rc.check (Sqlite3.bind_text statement 2 receipt); - (match rc_result db (Sqlite3.step statement) with - | Error _ as error -> error - | Ok () -> insert rest) - in - try insert receipts with - | exn -> Error (Printexc.to_string exn)) + (fun () -> insert_receipts db statement receipts) ;; let read_terminal_batch db key = @@ -150,17 +153,5 @@ let upsert_terminal_batches db receipts = in Fun.protect ~finally:(fun () -> ignore (Sqlite3.finalize statement)) - (fun () -> - let rec insert = function - | [] -> Ok () - | (key, receipt) :: rest -> - Sqlite3.Rc.check (Sqlite3.reset statement); - Sqlite3.Rc.check (Sqlite3.bind_text statement 1 key); - Sqlite3.Rc.check (Sqlite3.bind_text statement 2 receipt); - (match rc_result db (Sqlite3.step statement) with - | Error _ as error -> error - | Ok () -> insert rest) - in - try insert receipts with - | exn -> Error (Printexc.to_string exn)) + (fun () -> insert_receipts db statement receipts) ;; diff --git a/logseq_db_storage/lib/sync_checkpoint_store.ml b/logseq_db_storage/lib/sync_checkpoint_store.ml index c7bc7907..20ecf8a6 100644 --- a/logseq_db_storage/lib/sync_checkpoint_store.ml +++ b/logseq_db_storage/lib/sync_checkpoint_store.ml @@ -4,6 +4,38 @@ let rc_result db rc = if Sqlite3.Rc.is_success rc then Ok () else Error (Sqlite3.errmsg db) ;; +let bind_checkpoint statement checkpoint = + Sqlite3.Rc.check + (Sqlite3.bind_int statement 1 checkpoint.Sync_checkpoint.format_version); + Sqlite3.Rc.check + (Sqlite3.bind_text + statement + 2 + (Graph_types.Uuid.to_string checkpoint.graph_id)); + Sqlite3.Rc.check (Sqlite3.bind_int statement 3 checkpoint.schema.major); + Sqlite3.Rc.check (Sqlite3.bind_int statement 4 checkpoint.schema.minor); + Sqlite3.Rc.check + (Sqlite3.bind_int64 + statement + 5 + (Server_cursor.to_int64 checkpoint.applied_server_t)); + Sqlite3.Rc.check (Sqlite3.bind_text statement 6 checkpoint.checksum); + Sqlite3.Rc.check + (Sqlite3.bind_text + statement + 7 + (match checkpoint.status with + | Sync_checkpoint.Active -> "active" + | Sync_checkpoint.Paused -> "paused")); + Sqlite3.Rc.check + (Sqlite3.bind + statement + 8 + (match checkpoint.last_error with + | None -> Sqlite3.Data.NULL + | Some value -> TEXT value)) +;; + let initialize_database db checkpoint = let create_sql = "CREATE TABLE sync_meta(singleton INTEGER PRIMARY KEY CHECK(singleton = \ @@ -28,35 +60,7 @@ let initialize_database db checkpoint = Fun.protect ~finally:(fun () -> ignore (Sqlite3.finalize statement)) (fun () -> - Sqlite3.Rc.check - (Sqlite3.bind_int statement 1 checkpoint.Sync_checkpoint.format_version); - Sqlite3.Rc.check - (Sqlite3.bind_text - statement - 2 - (Graph_types.Uuid.to_string checkpoint.graph_id)); - Sqlite3.Rc.check (Sqlite3.bind_int statement 3 checkpoint.schema.major); - Sqlite3.Rc.check (Sqlite3.bind_int statement 4 checkpoint.schema.minor); - Sqlite3.Rc.check - (Sqlite3.bind_int64 - statement - 5 - (Server_cursor.to_int64 checkpoint.applied_server_t)); - Sqlite3.Rc.check (Sqlite3.bind_text statement 6 checkpoint.checksum); - Sqlite3.Rc.check - (Sqlite3.bind_text - statement - 7 - (match checkpoint.status with - | Sync_checkpoint.Active -> "active" - | Sync_checkpoint.Paused -> "paused")); - Sqlite3.Rc.check - (Sqlite3.bind - statement - 8 - (match checkpoint.last_error with - | None -> Sqlite3.Data.NULL - | Some value -> TEXT value)); + bind_checkpoint statement checkpoint; rc_result db (Sqlite3.step statement)) ;; @@ -172,35 +176,7 @@ let update_database db checkpoint = Fun.protect ~finally:(fun () -> ignore (Sqlite3.finalize statement)) (fun () -> - Sqlite3.Rc.check - (Sqlite3.bind_int statement 1 checkpoint.Sync_checkpoint.format_version); - Sqlite3.Rc.check - (Sqlite3.bind_text - statement - 2 - (Graph_types.Uuid.to_string checkpoint.graph_id)); - Sqlite3.Rc.check (Sqlite3.bind_int statement 3 checkpoint.schema.major); - Sqlite3.Rc.check (Sqlite3.bind_int statement 4 checkpoint.schema.minor); - Sqlite3.Rc.check - (Sqlite3.bind_int64 - statement - 5 - (Server_cursor.to_int64 checkpoint.applied_server_t)); - Sqlite3.Rc.check (Sqlite3.bind_text statement 6 checkpoint.checksum); - Sqlite3.Rc.check - (Sqlite3.bind_text - statement - 7 - (match checkpoint.status with - | Sync_checkpoint.Active -> "active" - | Sync_checkpoint.Paused -> "paused")); - Sqlite3.Rc.check - (Sqlite3.bind - statement - 8 - (match checkpoint.last_error with - | None -> Sqlite3.Data.NULL - | Some value -> TEXT value)); + bind_checkpoint statement checkpoint; rc_result db (Sqlite3.step statement)) with | exn -> Error (Printexc.to_string exn)