2023-05-04 11:49:25 +00:00
|
|
|
open Nottui
|
|
|
|
open Notty
|
|
|
|
|
2023-05-12 12:37:54 +00:00
|
|
|
type t = { w : int; h : int; }
|
2023-05-04 11:49:25 +00:00
|
|
|
|
|
|
|
let render_message ~width ~width_nicknames msg =
|
2023-05-04 13:39:34 +00:00
|
|
|
(* (* FIXME: split doesn't work *)
|
2023-05-04 11:49:25 +00:00
|
|
|
let width_message =
|
|
|
|
max 1 (width - width_nicknames - 1)
|
|
|
|
in
|
2023-05-04 13:39:34 +00:00
|
|
|
let message = Message.split_at ~len:width_message msg in *)
|
2023-05-12 12:37:54 +00:00
|
|
|
let _ = width in
|
2023-05-04 13:39:34 +00:00
|
|
|
let message = [Message.message msg] in
|
2023-05-04 11:49:25 +00:00
|
|
|
let color = A.white in
|
|
|
|
let rest =
|
|
|
|
List.map @@ fun msg ->
|
|
|
|
I.hcat
|
|
|
|
[ I.void width_nicknames 1
|
|
|
|
; I.strf "│"
|
|
|
|
; I.strf "%s" msg
|
|
|
|
]
|
|
|
|
in
|
|
|
|
I.vcat
|
|
|
|
(I.hcat
|
|
|
|
[ I.strf " "
|
|
|
|
; I.hsnap ~align:`Right width_nicknames
|
|
|
|
(I.strf ~attr:A.(fg color) "%s" (Message.nickname msg))
|
|
|
|
; I.strf "│"
|
|
|
|
; I.strf "%s" (List.hd message)
|
|
|
|
]
|
|
|
|
:: rest (List.tl message))
|
|
|
|
|
|
|
|
let width_nicknames msgs =
|
|
|
|
let f msg acc = max (String.length (Message.nickname msg)) acc in
|
|
|
|
Rb.iter ~f msgs 0
|
|
|
|
|
2023-05-12 12:37:54 +00:00
|
|
|
let render { w; h } msgs =
|
|
|
|
let idx = ref (Rb.length msgs - 1) in
|
2023-05-04 11:49:25 +00:00
|
|
|
let image = ref I.empty in
|
|
|
|
let message = ref I.empty in
|
|
|
|
let width_nicknames = width_nicknames msgs in
|
|
|
|
while
|
|
|
|
!idx >= 0
|
|
|
|
&&
|
|
|
|
(message :=
|
|
|
|
render_message ~width_nicknames ~width:w msgs.Rb.%[!idx];
|
|
|
|
I.height !message + I.height !image <= h)
|
|
|
|
do
|
|
|
|
(image := I.(!message <-> !image));
|
|
|
|
decr idx
|
|
|
|
done;
|
|
|
|
Ui.atom (I.vsnap ~align:`Bottom h !image)
|
|
|
|
|
|
|
|
let make w =
|
|
|
|
let ( let* ) x f = Lwd.bind ~f x in
|
|
|
|
let ( let+ ) x f = Lwd.map ~f x in
|
|
|
|
let ( and+ ) = Lwd.map2 ~f:(fun x y -> (x, y)) in
|
|
|
|
|
2023-05-12 12:39:02 +00:00
|
|
|
let state = Lwd.var { w = 0; h = 0 } in
|
2023-05-04 11:49:25 +00:00
|
|
|
|
|
|
|
let* document =
|
|
|
|
let+ state = Lwd.get state
|
|
|
|
and+ buffer = Lwd.get w in
|
2023-05-12 12:39:02 +00:00
|
|
|
render state buffer
|
2023-05-04 11:49:25 +00:00
|
|
|
in
|
|
|
|
|
|
|
|
let update_size ~w ~h =
|
|
|
|
let state' = Lwd.peek state in
|
2023-05-12 12:39:02 +00:00
|
|
|
if state'.w <> w || state'.h <> h then Lwd.set state { w; h }
|
2023-05-04 11:49:25 +00:00
|
|
|
in
|
|
|
|
|
|
|
|
let measure_size document =
|
|
|
|
Ui.size_sensor update_size (Ui.resize ~sh:1 document)
|
|
|
|
in
|
|
|
|
|
|
|
|
Lwd.return (measure_size document)
|