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 { icon_button, 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 variant: "ghost",
66 size: "sm",
67 active_layer: theme.lowest,
68 })
69
70 const subheader_row = toggleable({
71 base: interactive({
72 base: {
73 ...text(layer, "ui_sans", { size: "sm" }),
74 padding: {
75 left: SPACING,
76 right: SPACING,
77 },
78 },
79 state: {
80 hovered: {
81 background: background(layer, "hovered"),
82 },
83 clicked: {
84 background: background(layer, "pressed"),
85 },
86 },
87 }),
88 state: {
89 active: {
90 default: {
91 ...text(theme.lowest, "ui_sans", { size: "sm" }),
92 background: background(theme.lowest),
93 },
94 clicked: {
95 background: background(layer, "pressed"),
96 },
97 },
98 },
99 })
100
101 const filter_input = {
102 background: background(layer, "on"),
103 corner_radius: 6,
104 text: text(layer, "ui_sans", "base"),
105 placeholder_text: text(layer, "ui_sans", "base", "disabled", {
106 size: "xs",
107 }),
108 selection: theme.players[0],
109 border: border(layer, "on"),
110 padding: {
111 bottom: 4,
112 left: 8,
113 right: 8,
114 top: 4,
115 },
116 margin: {
117 left: SPACING,
118 right: SPACING,
119 },
120 }
121
122 const item_row = toggleable({
123 base: interactive({
124 base: {
125 padding: {
126 left: SPACING,
127 right: SPACING,
128 },
129 },
130 state: {
131 clicked: {
132 background: background(layer, "pressed"),
133 },
134 },
135 }),
136 state: {
137 inactive: {
138 hovered: {
139 background: background(layer, "hovered"),
140 },
141 },
142 active: {
143 default: {
144 ...text(theme.lowest, "ui_sans", { size: "sm" }),
145 background: background(theme.lowest),
146 },
147 clicked: {
148 background: background(layer, "pressed"),
149 },
150 },
151 },
152 })
153
154 return {
155 ...collab_modals(),
156 log_in_button: interactive({
157 base: {
158 background: background(theme.middle),
159 border: border(theme.middle, "active"),
160 corner_radius: 4,
161 margin: {
162 top: 4,
163 left: 16,
164 right: 16,
165 },
166 padding: {
167 top: 3,
168 bottom: 3,
169 left: 7,
170 right: 7,
171 },
172 ...text(theme.middle, "sans", "default", { size: "sm" }),
173 },
174 state: {
175 hovered: {
176 ...text(theme.middle, "sans", "default", { size: "sm" }),
177 background: background(theme.middle, "hovered"),
178 border: border(theme.middle, "active"),
179 },
180 clicked: {
181 ...text(theme.middle, "sans", "default", { size: "sm" }),
182 background: background(theme.middle, "pressed"),
183 border: border(theme.middle, "active"),
184 },
185 },
186 }),
187 background: background(layer),
188 padding: {
189 top: SPACING,
190 },
191 user_query_editor: filter_input,
192 channel_hash: icon_style,
193 user_query_editor_height: 33,
194 add_contact_button: header_icon_button,
195 add_channel_button: header_icon_button,
196 leave_call_button: header_icon_button,
197 row_height: ITEM_HEIGHT,
198 channel_indent: INDENT_SIZE,
199 section_icon_size: 14,
200 header_row: {
201 ...text(layer, "ui_sans", { size: "sm", weight: "bold" }),
202 margin: { top: SPACING },
203 padding: {
204 left: SPACING,
205 right: SPACING,
206 },
207 },
208 subheader_row,
209 leave_call: interactive({
210 base: {
211 background: background(layer),
212 border: border(layer),
213 corner_radius: 6,
214 margin: {
215 top: 1,
216 },
217 padding: {
218 top: 1,
219 bottom: 1,
220 left: 7,
221 right: 7,
222 },
223 ...text(layer, "sans", "variant", { size: "xs" }),
224 },
225 state: {
226 hovered: {
227 ...text(layer, "sans", "hovered", { size: "xs" }),
228 background: background(layer, "hovered"),
229 border: border(layer, "hovered"),
230 },
231 },
232 }),
233 contact_row: toggleable({
234 base: interactive({
235 base: {
236 padding: {
237 left: SPACING,
238 right: SPACING,
239 },
240 },
241 state: {
242 clicked: {
243 background: background(layer, "pressed"),
244 },
245 },
246 }),
247 state: {
248 inactive: {
249 hovered: {
250 background: background(layer, "hovered"),
251 },
252 },
253 active: {
254 default: {
255 ...text(theme.lowest, "ui_sans", { size: "sm" }),
256 background: background(theme.lowest),
257 },
258 clicked: {
259 background: background(layer, "pressed"),
260 },
261 },
262 },
263 }),
264 channel_row: item_row,
265 channel_name: {
266 ...text(layer, "ui_sans", { size: "sm" }),
267 margin: {
268 left: NAME_MARGIN,
269 },
270 },
271 list_empty_label_container: {
272 margin: {
273 left: NAME_MARGIN,
274 }
275 },
276 list_empty_icon: {
277 color: foreground(layer, "variant"),
278 width: 14,
279 },
280 list_empty_state: toggleable({
281 base: interactive({
282 base: {
283 ...text(layer, "ui_sans", "variant", { size: "sm" }),
284 padding: {
285 top: SPACING / 2,
286 bottom: SPACING / 2,
287 left: SPACING,
288 right: SPACING
289 },
290 },
291 state: {
292 clicked: {
293 background: background(layer, "pressed"),
294 },
295 },
296 }),
297 state: {
298 inactive: {
299 hovered: {
300 background: background(layer, "hovered"),
301 },
302 },
303 active: {
304 default: {
305 ...text(theme.lowest, "ui_sans", { size: "sm" }),
306 background: background(theme.lowest),
307 },
308 clicked: {
309 background: background(layer, "pressed"),
310 },
311 },
312 },
313 }),
314 contact_avatar: {
315 corner_radius: 10,
316 width: 20,
317 },
318 channel_avatar: {
319 corner_radius: 10,
320 width: 20,
321 },
322 extra_participant_label: {
323 corner_radius: 10,
324 padding: {
325 left: 10,
326 right: 4,
327 },
328 background: background(layer, "hovered"),
329 ...text(layer, "ui_sans", "hovered", { size: "xs" })
330 },
331 contact_status_free: indicator({ layer, color: "positive" }),
332 contact_status_busy: indicator({ layer, color: "negative" }),
333 contact_username: {
334 ...text(layer, "ui_sans", { size: "sm" }),
335 margin: {
336 left: NAME_MARGIN,
337 },
338 },
339 contact_button_spacing: NAME_MARGIN,
340 contact_button: icon_button({
341 variant: "ghost",
342 color: "variant",
343 size: "sm",
344 }),
345 disabled_button: {
346 ...contact_button,
347 background: background(layer, "on"),
348 color: foreground(layer, "on"),
349 },
350 calling_indicator: {
351 ...text(layer, "mono", "variant", { size: "xs" }),
352 },
353 tree_branch: toggleable({
354 base: interactive({
355 base: {
356 color: border_color(layer),
357 width: 1,
358 },
359 state: {
360 hovered: {
361 color: border_color(layer),
362 },
363 },
364 }),
365 state: {
366 active: {
367 default: {
368 color: border_color(layer),
369 },
370 },
371 },
372 }),
373 project_row: toggleable({
374 base: interactive({
375 base: {
376 ...project_row,
377 icon: {
378 margin: { left: NAME_MARGIN },
379 color: foreground(layer, "variant"),
380 width: 14,
381 },
382 name: {
383 ...project_row.name,
384 ...text(layer, "mono", { size: "sm" }),
385 },
386 },
387 state: {
388 hovered: {
389 background: background(layer, "hovered"),
390 },
391 },
392 }),
393 state: {
394 active: {
395 default: { background: background(theme.lowest) },
396 },
397 },
398 }),
399 face_overlap: 8,
400 channel_editor: {
401 padding: {
402 left: NAME_MARGIN,
403 }
404 }
405 }
406}