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 { icon_button, toggleable_icon_button } from "../component/icon_button"
12import { indicator } from "../component/indicator"
13
14export default function contacts_panel(): any {
15 const theme = useTheme()
16
17 const CHANNEL_SPACING = 4 as const
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, "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({
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, "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, "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, "sans", "base"),
105 placeholder_text: text(layer, "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, "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 disclosure: {
157 button: icon_button({ variant: "ghost", size: "sm" }),
158 spacing: CHANNEL_SPACING,
159 },
160 log_in_button: interactive({
161 base: {
162 background: background(theme.middle),
163 border: border(theme.middle, "active"),
164 corner_radius: 4,
165 margin: {
166 top: 4,
167 left: 16,
168 right: 16,
169 },
170 padding: {
171 top: 3,
172 bottom: 3,
173 left: 7,
174 right: 7,
175 },
176 ...text(theme.middle, "sans", "default", { size: "sm" }),
177 },
178 state: {
179 hovered: {
180 ...text(theme.middle, "sans", "default", { size: "sm" }),
181 background: background(theme.middle, "hovered"),
182 border: border(theme.middle, "active"),
183 },
184 clicked: {
185 ...text(theme.middle, "sans", "default", { size: "sm" }),
186 background: background(theme.middle, "pressed"),
187 border: border(theme.middle, "active"),
188 },
189 },
190 }),
191 background: background(layer),
192 padding: {
193 top: SPACING,
194 },
195 user_query_editor: filter_input,
196 channel_hash: icon_style,
197 channel_note_active_color: foreground(layer, "active"),
198 user_query_editor_height: 33,
199 add_contact_button: header_icon_button,
200 add_channel_button: header_icon_button,
201 leave_call_button: header_icon_button,
202 row_height: ITEM_HEIGHT,
203 channel_indent: INDENT_SIZE * 2 + 2,
204 section_icon_size: 14,
205 header_row: {
206 ...text(layer, "sans", { size: "sm", weight: "bold" }),
207 margin: { top: SPACING },
208 padding: {
209 left: SPACING,
210 right: SPACING,
211 },
212 },
213 dragged_over_header: {
214 margin: { top: SPACING },
215 padding: {
216 left: SPACING,
217 right: SPACING,
218 },
219 background: background(layer, "hovered"),
220 },
221 subheader_row,
222 leave_call: interactive({
223 base: {
224 background: background(layer),
225 border: border(layer),
226 corner_radius: 6,
227 margin: {
228 top: 1,
229 },
230 padding: {
231 top: 1,
232 bottom: 1,
233 left: 7,
234 right: 7,
235 },
236 ...text(layer, "sans", "variant", { size: "xs" }),
237 },
238 state: {
239 hovered: {
240 ...text(layer, "sans", "hovered", { size: "xs" }),
241 background: background(layer, "hovered"),
242 border: border(layer, "hovered"),
243 },
244 },
245 }),
246 contact_row: toggleable({
247 base: interactive({
248 base: {
249 padding: {
250 left: SPACING,
251 right: SPACING,
252 },
253 },
254 state: {
255 clicked: {
256 background: background(layer, "pressed"),
257 },
258 },
259 }),
260 state: {
261 inactive: {
262 hovered: {
263 background: background(layer, "hovered"),
264 },
265 },
266 active: {
267 default: {
268 ...text(theme.lowest, "sans", { size: "sm" }),
269 background: background(theme.lowest),
270 },
271 clicked: {
272 background: background(layer, "pressed"),
273 },
274 },
275 },
276 }),
277 channel_row: item_row,
278 channel_name: {
279 active: {
280 ...text(layer, "sans", { size: "sm", weight: "bold" }),
281 margin: {
282 left: CHANNEL_SPACING,
283 },
284 },
285 inactive: {
286 ...text(layer, "sans", { size: "sm" }),
287 margin: {
288 left: CHANNEL_SPACING,
289 },
290 },
291 },
292 list_empty_label_container: {
293 margin: {
294 left: NAME_MARGIN,
295 },
296 },
297 list_empty_icon: {
298 color: foreground(layer, "variant"),
299 width: 14,
300 },
301 list_empty_state: toggleable({
302 base: interactive({
303 base: {
304 ...text(layer, "sans", "variant", { size: "sm" }),
305 padding: {
306 top: SPACING / 2,
307 bottom: SPACING / 2,
308 left: SPACING,
309 right: SPACING,
310 },
311 },
312 state: {
313 clicked: {
314 background: background(layer, "pressed"),
315 },
316 },
317 }),
318 state: {
319 inactive: {
320 hovered: {
321 background: background(layer, "hovered"),
322 },
323 },
324 active: {
325 default: {
326 ...text(theme.lowest, "sans", { size: "sm" }),
327 background: background(theme.lowest),
328 },
329 clicked: {
330 background: background(layer, "pressed"),
331 },
332 },
333 },
334 }),
335 contact_avatar: {
336 corner_radius: 10,
337 width: 20,
338 },
339 channel_avatar: {
340 corner_radius: 10,
341 width: 20,
342 },
343 extra_participant_label: {
344 corner_radius: 10,
345 padding: {
346 left: 10,
347 right: 4,
348 },
349 background: background(layer, "hovered"),
350 ...text(layer, "sans", "hovered", { size: "xs" }),
351 },
352 contact_status_free: indicator({ layer, color: "positive" }),
353 contact_status_busy: indicator({ layer, color: "negative" }),
354 contact_username: {
355 ...text(layer, "sans", { size: "sm" }),
356 margin: {
357 left: NAME_MARGIN,
358 },
359 },
360 contact_button_spacing: NAME_MARGIN,
361 contact_button: icon_button({
362 variant: "ghost",
363 color: "variant",
364 size: "sm",
365 }),
366 disabled_button: {
367 ...contact_button,
368 background: background(layer, "on"),
369 color: foreground(layer, "on"),
370 },
371 calling_indicator: {
372 ...text(layer, "sans", "variant", { size: "xs" }),
373 },
374 tree_branch: toggleable({
375 base: interactive({
376 base: {
377 color: border_color(layer),
378 width: 1,
379 },
380 state: {
381 hovered: {
382 color: border_color(layer),
383 },
384 },
385 }),
386 state: {
387 active: {
388 default: {
389 color: border_color(layer),
390 },
391 },
392 },
393 }),
394 project_row: toggleable({
395 base: interactive({
396 base: {
397 ...project_row,
398 icon: {
399 margin: { left: NAME_MARGIN },
400 color: foreground(layer, "variant"),
401 width: 14,
402 },
403 name: {
404 ...project_row.name,
405 ...text(layer, "sans", { size: "sm" }),
406 },
407 },
408 state: {
409 hovered: {
410 background: background(layer, "hovered"),
411 },
412 },
413 }),
414 state: {
415 active: {
416 default: { background: background(theme.lowest) },
417 },
418 },
419 }),
420 face_overlap: 8,
421 channel_editor: {
422 padding: {
423 left: NAME_MARGIN,
424 },
425 },
426 }
427}