Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
553 changes: 387 additions & 166 deletions app/application.ml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions app/application.mli
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ module Root_navigation : sig
| Capture_discarded
| Capture_picker_requested of Journal_asset_import.source
| Capture_asset_picked of Journal_asset_import.staged * int option
| Capture_assets_picked of
Journal_asset_import.staged list * int option * string option
| Capture_native_edit of Journal_view.Event.Payload.text_edit
| Capture_task_intent of bool
| Capture_edited of string
Expand Down
56 changes: 52 additions & 4 deletions app/journal_asset_import.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ type request =
{ id : int
; source : source
; staged : bool
; max_selections : int option
}

let file_request ~id = { id; source = Files; staged = false }
let staged_request ~id ~source = { id; source; staged = true }
let file_request ~id = { id; source = Files; staged = false; max_selections = Some 1 }

let staged_request ?max_selections ~id ~source () =
{ id; source; staged = true; max_selections }
;;

(* A picked asset held for a later import: the wire pick fields plus [token],
which identifies the pending item for the extension's remove event. *)
Expand All @@ -35,12 +39,14 @@ type staged =
; source_file : string
; title : string
; file_type : string
; source_identity : string option
}

let staged_token (staged : staged) = staged.token
let staged_path (staged : staged) = staged.source_file
let staged_title (staged : staged) = staged.title
let staged_type (staged : staged) = staged.file_type
let staged_source_identity (staged : staged) = staged.source_identity

let parse payload =
let ( let* ) = Result.bind in
Expand Down Expand Up @@ -79,6 +85,10 @@ let parse payload =
; source_file
; title
; file_type
; source_identity =
(match Yojson.Basic.Util.member "sourceIdentity" json with
| `String value -> Some value
| _ -> None)
}
, request_id )
with
Expand Down Expand Up @@ -117,8 +127,10 @@ let to_import (staged : staged) ~target : Logseq_db_types.Asset_import.t =

type event =
| Picked of staged * int option
| Picked_batch of staged list * int option * string option
| Removed of string
| Dismissed
| Picker_dismissed of int option
| Unavailable of string

let decode_event payload =
Expand All @@ -128,7 +140,35 @@ let decode_event payload =
with
| `Assoc fields ->
(match List.assoc_opt "action" fields with
| Some (`String "dismissed") -> Ok Dismissed
| Some (`String "picked-batch") ->
let request_id =
match Yojson.Basic.Util.member "request" (`Assoc fields) with
| `Assoc request ->
(match List.assoc_opt "id" request with
| Some (`Int id) -> Some id
| _ -> None)
| _ -> None
in
let error =
match List.assoc_opt "error" fields with
| Some (`String message) -> Some message
| _ -> None
in
(match List.assoc_opt "items" fields with
| Some (`List items) ->
let rec decode reversed = function
| [] -> Ok (Picked_batch (List.rev reversed, request_id, error))
| item :: rest ->
(match parse (Yojson.Basic.to_string item) with
| Ok (staged, _) -> decode (staged :: reversed) rest
| Error message -> Error message)
in
decode [] items
| _ -> Error "Invalid attachment batch")
| Some (`String "dismissed") ->
(match List.assoc_opt "request" fields with
| Some (`Int id) -> Ok (Picker_dismissed (Some id))
| _ -> Ok Dismissed)
| Some (`String "unavailable") ->
Ok
(Unavailable
Expand Down Expand Up @@ -167,7 +207,7 @@ let discard_staged_file (staged : staged) =

let is_dismissal payload =
match decode_event payload with
| Ok Dismissed -> true
| Ok Dismissed | Ok (Picker_dismissed _) -> true
| _ -> false
;;

Expand All @@ -194,6 +234,10 @@ let view ~key ~enabled ~completion ~request ~pending ~on_select body =
[ "id", `Int request.id
; "source", `String (source_to_string request.source)
; "staged", `Bool request.staged
; ( "maxSelections"
, match request.max_selections with
| None -> `Null
| Some count -> `Int count )
] )
; ( "pending"
, `List
Expand All @@ -204,6 +248,10 @@ let view ~key ~enabled ~completion ~request ~pending ~on_select body =
; "path", `String item.source_file
; "title", `String item.title
; "type", `String item.file_type
; ( "sourceIdentity"
, match item.source_identity with
| None -> `Null
| Some identity -> `String identity )
])
pending) )
])
Expand Down
7 changes: 5 additions & 2 deletions app/journal_asset_import.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ type source =
| Photos
| Camera


(** Picker arm request: [source] selects the picker, [staged] makes the host
copy the pick into a temp file so it survives until a later import. *)
type request =
{ id : int
; source : source
; staged : bool
; max_selections : int option
}

(** In-place import request (detail page): file picker, no staging copy. *)
val file_request : id:int -> request

(** Staged request for deferred import (composer): the host copies the pick
into a temp file and reports it for the pending-attachment strip. *)
val staged_request : id:int -> source:source -> request
val staged_request : ?max_selections:int -> id:int -> source:source -> unit -> request

(** A picked asset kept for a later attach-on-save import. *)
type staged
Expand All @@ -26,6 +26,7 @@ val staged_token : staged -> string
val staged_path : staged -> string
val staged_title : staged -> string
val staged_type : staged -> string
val staged_source_identity : staged -> string option

(** Build the worker import for a staged pick targeting [target]. *)
val to_import
Expand All @@ -40,8 +41,10 @@ val decode

type event =
| Picked of staged * int option (** the pick and the request id that armed it *)
| Picked_batch of staged list * int option * string option
| Removed of string
| Dismissed
| Picker_dismissed of int option
| Unavailable of string

val decode_event : string -> (event, string) result
Expand Down
Loading
Loading