tablo_core/column/
image.rs1use derive_where::derive_where;
4use topcoat::{context::Cx, view::*};
5
6use super::{Column, ColumnBase, ColumnWidth};
7use crate::{Lens, values::FormScalar};
8
9#[derive_where(Clone, Debug)]
21pub struct ImageColumn<M, T> {
22 lens: Lens<M, T>,
23 base: ColumnBase,
24 size: u16,
25 circular: bool,
26 remote: bool,
27}
28
29impl<M, T> ImageColumn<M, T>
30where
31 M: toasty::schema::Model,
32{
33 pub fn new(lens: Lens<M, T>) -> Self
35 where
36 T: toasty::schema::Field<Inner = String>,
37 {
38 Self {
39 base: ColumnBase::new(lens.path(), ColumnWidth::Auto),
40 lens,
41 size: 40,
42 circular: false,
43 remote: false,
44 }
45 }
46
47 pub fn size(mut self, pixels: u16) -> Self {
49 self.size = pixels;
50 self
51 }
52
53 pub fn circular(mut self) -> Self {
55 self.circular = true;
56 self
57 }
58
59 pub fn remote(mut self) -> Self {
63 self.remote = true;
64 self
65 }
66
67 base_builders!();
68}
69
70impl<M, T> Column<M> for ImageColumn<M, T>
71where
72 M: toasty::schema::Model + Send + Sync + 'static,
73 T: FormScalar + Send + Sync + 'static,
74{
75 base_column_methods!(binding);
76
77 fn text(&self, _cx: &Cx, row: &M) -> String {
78 self.lens.read(row).to_form()
79 }
80
81 fn cell<'a>(&self, cx: &'a Cx, row: &M) -> BoxView<'a> {
82 let src = self.text(cx, row).trim().to_string();
83 let shown = if self.remote {
84 crate::schema::is_linkable(&src)
85 } else {
86 crate::schema::is_rooted(&src)
87 };
88 if !shown {
89 return crate::schema::value_cell(cx, &src);
90 }
91 let src = crate::schema::file_href(cx, &src);
92 let class = if self.circular {
93 "shrink-0 rounded-full object-cover ring-1 ring-foreground/10"
94 } else {
95 "shrink-0 rounded-md object-cover ring-1 ring-foreground/10"
96 };
97 let size = self.size.to_string();
98 view! {
99 cx =>
100 <img
101 src=(src)
102 alt=""
103 loading="lazy"
104 referrerpolicy="no-referrer"
105 width=(size.clone())
106 height=(size)
107 class=(class)
108 >
109 }
110 .boxed()
111 }
112}