···22open Picos_std_structured
33open Jj_tui.Logging
4455+type detail_state =
66+ | Loading
77+ | Loaded of Notty.image
88+ | Failed
99+510type status_state =
611 | File_preview of (string * string) (*revision,filepath*)
712 | Graph_preview of string (*revision*)
···2833 open Global_vars
2934 open Jj_tui
30353131- let viewState = Lwd.var I.empty
3636+ type view_state = {
3737+ summary : Notty.image
3838+ ; detail : detail_state
3939+ }
32403333- let render_file_preview (rev, file) =
3434- (* we yield a bunch here to provide places for the computation to be terminated*)
3535- if file != ""
3636- then (
3737- let log = jj_no_log [ "diff"; "-r"; rev; file ] in
4141+ let viewState = Lwd.var { summary = I.empty; detail = Loading }
4242+4343+ let render_summary = function
4444+ | File_preview (rev, file) ->
4545+ let command =
4646+ if file != ""
4747+ then [ "diff"; "--summary"; "-r"; rev; file ]
4848+ else [ "show"; "--summary"; "-r"; rev ]
4949+ in
5050+ let log = jj_no_log command in
3851 Control.yield ();
3952 let res = log |> AnsiReverse.colored_string in
4053 Control.yield ();
4141- res)
4242- else I.string A.empty ""
5454+ res
5555+ | Graph_preview rev ->
5656+ let log = jj_no_log ~snapshot:false [ "show"; "--summary"; "-r"; rev ] in
5757+ Control.yield ();
5858+ let res = log |> AnsiReverse.colored_string in
5959+ Control.yield ();
6060+ res
4361 ;;
44624545- let render_graph_preview rev =
4646- let log = jj_no_log ~snapshot:false [ "show"; "-s"; "--color-words"; "-r"; rev ] in
4747- Control.yield ();
4848- let res = log |> AnsiReverse.colored_string in
4949- Control.yield ();
5050- res
6363+ let render_detail = function
6464+ | File_preview (rev, file) ->
6565+ let command =
6666+ if file != "" then [ "diff"; "-r"; rev; file ] else [ "show"; "-r"; rev ]
6767+ in
6868+ let log = jj_no_log command in
6969+ Control.yield ();
7070+ let res = log |> AnsiReverse.colored_string in
7171+ Control.yield ();
7272+ res
7373+ | Graph_preview rev ->
7474+ let log = jj_no_log ~snapshot:false [ "diff"; "--color-words"; "-r"; rev ] in
7575+ Control.yield ();
7676+ let res = log |> AnsiReverse.colored_string in
7777+ Control.yield ();
7878+ res
5179 ;;
52805381 (* Wait for messages to come in the stream.
···5583 If a new message comes, we cancel the current computation and then start the new rendering
5684 *)
5785 let render_loop stream =
5858- let current_computation = ref (Promise.of_value ()) in
8686+ let current_summary_computation = ref (Promise.of_value ()) in
8787+ let current_detail_computation = ref (Promise.of_value ()) in
8888+ let current_loading_computation = ref (Promise.of_value ()) in
5989 let cursor = ref (Stream.tap stream) in
6090 while true do
6191 let msg, new_cursor = !cursor |> Stream.read in
6292 cursor := new_cursor;
6363- Promise.terminate_after ~seconds:0. !current_computation;
6464- current_computation
9393+ Promise.terminate_after ~seconds:0. !current_summary_computation;
9494+ Promise.terminate_after ~seconds:0. !current_detail_computation;
9595+ Promise.terminate_after ~seconds:0. !current_loading_computation;
9696+ current_summary_computation
6597 := Flock.fork_as_promise (fun () ->
6698 try
6767- [%log debug "Rendering status view with: %a" pp_status_state msg];
6868- viewState
6969- $=
7070- match msg with
7171- | File_preview (rev, file) ->
7272- render_file_preview (rev, file)
7373- | Graph_preview rev ->
7474- render_graph_preview rev
9999+ [%log debug "Rendering status summary with: %a" pp_status_state msg];
100100+ let summary = render_summary msg in
101101+ viewState $= { (Lwd.peek viewState) with summary }
75102 with
76103 | _ ->
77104 [%log
78105 warn
7979- "preview render failed. If this happens once it's probably just because \
8080- a node was deleted. If it keeps happening and the user can't see anything, obviously this is important"])
106106+ "summary render failed. If this happens once it's probably just because \
107107+ a node was deleted. If it keeps happening and the user can't see \
108108+ anything, obviously this is important"]);
109109+ current_loading_computation
110110+ := Flock.fork_as_promise (fun () ->
111111+ (* If it's been more than half a second, show the state as loading*)
112112+ Control.sleep ~seconds:0.3;
113113+ viewState $= { (Lwd.peek viewState) with detail = Loading });
114114+ current_detail_computation
115115+ := Flock.fork_as_promise (fun () ->
116116+ try
117117+ [%log debug "Rendering status detail with: %a" pp_status_state msg];
118118+ let detail = Loaded (render_detail msg) in
119119+ (*Make sure the loading is done*)
120120+ !current_loading_computation |> Promise.terminate;
121121+ viewState $= { (Lwd.peek viewState) with detail }
122122+ with
123123+ | _ ->
124124+ [%log
125125+ warn
126126+ "detail render failed. If this happens once it's probably just because \
127127+ a node was deleted. If it keeps happening and the user can't see \
128128+ anything, obviously this is important"];
129129+ viewState $= { (Lwd.peek viewState) with detail = Failed })
81130 done
82131 ;;
8313284133 let render focus =
85134 Flock.fork (fun () -> render_loop statusStream);
8686- Lwd.get viewState |>$ fun x ->
8787- x
135135+ Lwd.get viewState |>$ fun { summary; detail } ->
136136+ let detail_view =
137137+ match detail with
138138+ | Loading ->
139139+ I.string A.empty "Loading..."
140140+ | Loaded image ->
141141+ image
142142+ | Failed ->
143143+ I.string A.empty "Failed to load diff"
144144+ in
145145+ I.vcat [ summary; I.void 0 1; detail_view ]
88146 |> Ui.atom
89147 |> Ui.keyboard_area (function
90148 | `Escape, [] ->