1import {
2 background,
3 border,
4 border_color,
5 foreground,
6 text,
7} from "./components"
8import { interactive, toggleable } from "../element"
9import { useTheme } from "../theme"
10import collab_modals from "./collab_modals"
11import { text_button } from "../component/text_button"
12import { toggleable_icon_button } from "../component/icon_button"
13import { indicator } from "../component/indicator"
14
15export default function contacts_panel(): any {
16 const theme = useTheme()
17
18 const NAME_MARGIN = 6 as const
19 const SPACING = 12 as const
20 const INDENT_SIZE = 8 as const
21 const ITEM_HEIGHT = 28 as const
22
23 const layer = theme.middle
24
25 const contact_button = {
26 background: background(layer, "on"),
27 color: foreground(layer, "on"),
28 icon_width: 14,
29 button_width: 16,
30 corner_radius: 8,
31 }
32
33 const project_row = {
34 guest_avatar_spacing: 4,
35 height: 24,
36 guest_avatar: {
37 corner_radius: 8,
38 width: 14,
39 },
40 name: {
41 ...text(layer, "ui_sans", { size: "sm" }),
42 margin: {
43 left: NAME_MARGIN,
44 right: 4,
45 },
46 },
47 guests: {
48 margin: {
49 left: NAME_MARGIN,
50 right: NAME_MARGIN,
51 },
52 },
53 padding: {
54 left: SPACING,
55 right: SPACING,
56 },
57 }
58
59 const icon_style = {
60 color: foreground(layer, "variant"),
61 width: 14,
62 }
63
64 const header_icon_button = toggleable_icon_button(theme, {
65 layer: theme.middle,
66 variant: "ghost",
67 })
68
69 const subheader_row = toggleable({
70 base: interactive({
71 base: {
72 ...text(layer, "ui_sans", { size: "sm" }),
73 padding: {
74 left: SPACING,
75 right: SPACING,
76 },
77 },
78 state: {
79 hovered: {
80 background: background(layer, "hovered"),
81 },
82 clicked: {
83 background: background(layer, "pressed"),
84 },
85 },
86 }),
87 state: {
88 active: {
89 default: {
90 ...text(layer, "ui_sans", "active", { size: "sm" }),
91 background: background(layer, "active"),
92 },
93 clicked: {
94 background: background(layer, "pressed"),
95 },
96 },
97 },
98 })
99
100 const filter_input = {
101 background: background(layer, "on"),
102 corner_radius: 6,
103 text: text(layer, "ui_sans", "base"),
104 placeholder_text: text(layer, "ui_sans", "base", "disabled", {
105 size: "xs",
106 }),
107 selection: theme.players[0],
108 border: border(layer, "on"),
109 padding: {
110 bottom: 4,
111 left: 8,
112 right: 8,
113 top: 4,
114 },
115 margin: {
116 left: SPACING,
117 right: SPACING,
118 },
119 }
120
121 const item_row = toggleable({
122 base: interactive({
123 base: {
124 padding: {
125 left: SPACING,
126 right: SPACING,
127 },
128 },
129 state: {
130 clicked: {
131 background: background(layer, "pressed"),
132 },
133 },
134 }),
135 state: {
136 inactive: {
137 hovered: {
138 background: background(layer, "hovered"),
139 },
140 },
141 active: {
142 default: {
143 ...text(layer, "ui_sans", "active", { size: "sm" }),
144 background: background(layer, "active"),
145 },
146 clicked: {
147 background: background(layer, "pressed"),
148 },
149 },
150 },
151 })
152
153 return {
154 ...collab_modals(),
155 log_in_button: text_button(),
156 background: background(layer),
157 padding: {
158 top: SPACING,
159 },
160 user_query_editor: filter_input,
161 channel_hash: icon_style,
162 user_query_editor_height: 33,
163 add_contact_button: header_icon_button,
164 add_channel_button: header_icon_button,
165 leave_call_button: header_icon_button,
166 row_height: ITEM_HEIGHT,
167 channel_indent: INDENT_SIZE,
168 section_icon_size: 14,
169 header_row: {
170 ...text(layer, "ui_sans", { size: "sm", weight: "bold" }),
171 margin: { top: SPACING },
172 padding: {
173 left: SPACING,
174 right: SPACING,
175 },
176 },
177 subheader_row,
178 leave_call: interactive({
179 base: {
180 background: background(layer),
181 border: border(layer),
182 corner_radius: 6,
183 margin: {
184 top: 1,
185 },
186 padding: {
187 top: 1,
188 bottom: 1,
189 left: 7,
190 right: 7,
191 },
192 ...text(layer, "sans", "variant", { size: "xs" }),
193 },
194 state: {
195 hovered: {
196 ...text(layer, "sans", "hovered", { size: "xs" }),
197 background: background(layer, "hovered"),
198 border: border(layer, "hovered"),
199 },
200 },
201 }),
202 contact_row: toggleable({
203 base: interactive({
204 base: {
205 padding: {
206 left: SPACING,
207 right: SPACING,
208 },
209 },
210 state: {
211 clicked: {
212 background: background(layer, "pressed"),
213 },
214 },
215 }),
216 state: {
217 inactive: {
218 hovered: {
219 background: background(layer, "hovered"),
220 },
221 },
222 active: {
223 default: {
224 ...text(layer, "ui_sans", "active", { size: "sm" }),
225 background: background(layer, "active"),
226 },
227 clicked: {
228 background: background(layer, "pressed"),
229 },
230 },
231 },
232 }),
233 channel_row: item_row,
234 channel_name: {
235 ...text(layer, "ui_sans", { size: "sm" }),
236 margin: {
237 left: NAME_MARGIN,
238 },
239 },
240 list_empty_label_container: {
241 margin: {
242 left: NAME_MARGIN,
243 }
244 },
245 list_empty_icon: {
246 color: foreground(layer, "variant"),
247 width: 14,
248 },
249 list_empty_state: toggleable({
250 base: interactive({
251 base: {
252 ...text(layer, "ui_sans", "variant", { size: "sm" }),
253 padding: {
254 top: SPACING / 2,
255 bottom: SPACING / 2,
256 left: SPACING,
257 right: SPACING
258 },
259 },
260 state: {
261 clicked: {
262 background: background(layer, "pressed"),
263 },
264 },
265 }),
266 state: {
267 inactive: {
268 hovered: {
269 background: background(layer, "hovered"),
270 },
271 },
272 active: {
273 default: {
274 ...text(layer, "ui_sans", "active", { size: "sm" }),
275 background: background(layer, "active"),
276 },
277 clicked: {
278 background: background(layer, "pressed"),
279 },
280 },
281 },
282 }),
283 contact_avatar: {
284 corner_radius: 10,
285 width: 20,
286 },
287 channel_avatar: {
288 corner_radius: 10,
289 width: 20,
290 },
291 extra_participant_label: {
292 corner_radius: 10,
293 padding: {
294 left: 10,
295 right: 4,
296 },
297 background: background(layer, "hovered"),
298 ...text(layer, "ui_sans", "hovered", { size: "xs" })
299 },
300 contact_status_free: indicator({ layer, color: "positive" }),
301 contact_status_busy: indicator({ layer, color: "negative" }),
302 contact_username: {
303 ...text(layer, "ui_sans", { size: "sm" }),
304 margin: {
305 left: NAME_MARGIN,
306 },
307 },
308 contact_button_spacing: NAME_MARGIN,
309 contact_button: interactive({
310 base: { ...contact_button },
311 state: {
312 hovered: {
313 background: background(layer, "hovered"),
314 },
315 },
316 }),
317 disabled_button: {
318 ...contact_button,
319 background: background(layer, "on"),
320 color: foreground(layer, "on"),
321 },
322 calling_indicator: {
323 ...text(layer, "mono", "variant", { size: "xs" }),
324 },
325 tree_branch: toggleable({
326 base: interactive({
327 base: {
328 color: border_color(layer),
329 width: 1,
330 },
331 state: {
332 hovered: {
333 color: border_color(layer),
334 },
335 },
336 }),
337 state: {
338 active: {
339 default: {
340 color: border_color(layer),
341 },
342 },
343 },
344 }),
345 project_row: toggleable({
346 base: interactive({
347 base: {
348 ...project_row,
349 icon: {
350 margin: { left: NAME_MARGIN },
351 color: foreground(layer, "variant"),
352 width: 14,
353 },
354 name: {
355 ...project_row.name,
356 ...text(layer, "mono", { size: "sm" }),
357 },
358 },
359 state: {
360 hovered: {
361 background: background(layer, "hovered"),
362 },
363 },
364 }),
365 state: {
366 active: {
367 default: { background: background(layer, "active") },
368 },
369 },
370 }),
371 face_overlap: 8,
372 channel_editor: {
373 padding: {
374 left: NAME_MARGIN,
375 }
376 }
377 }
378}