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 subheader_row,
214 leave_call: interactive({
215 base: {
216 background: background(layer),
217 border: border(layer),
218 corner_radius: 6,
219 margin: {
220 top: 1,
221 },
222 padding: {
223 top: 1,
224 bottom: 1,
225 left: 7,
226 right: 7,
227 },
228 ...text(layer, "sans", "variant", { size: "xs" }),
229 },
230 state: {
231 hovered: {
232 ...text(layer, "sans", "hovered", { size: "xs" }),
233 background: background(layer, "hovered"),
234 border: border(layer, "hovered"),
235 },
236 },
237 }),
238 contact_row: toggleable({
239 base: interactive({
240 base: {
241 padding: {
242 left: SPACING,
243 right: SPACING,
244 },
245 },
246 state: {
247 clicked: {
248 background: background(layer, "pressed"),
249 },
250 },
251 }),
252 state: {
253 inactive: {
254 hovered: {
255 background: background(layer, "hovered"),
256 },
257 },
258 active: {
259 default: {
260 ...text(theme.lowest, "sans", { size: "sm" }),
261 background: background(theme.lowest),
262 },
263 clicked: {
264 background: background(layer, "pressed"),
265 },
266 },
267 },
268 }),
269 channel_row: item_row,
270 channel_name: {
271 active: {
272 ...text(layer, "sans", { size: "sm", weight: "bold" }),
273 margin: {
274 left: CHANNEL_SPACING,
275 },
276 },
277 inactive: {
278 ...text(layer, "sans", { size: "sm" }),
279 margin: {
280 left: CHANNEL_SPACING,
281 },
282 }
283 },
284 list_empty_label_container: {
285 margin: {
286 left: NAME_MARGIN,
287 },
288 },
289 list_empty_icon: {
290 color: foreground(layer, "variant"),
291 width: 14,
292 },
293 list_empty_state: toggleable({
294 base: interactive({
295 base: {
296 ...text(layer, "sans", "variant", { size: "sm" }),
297 padding: {
298 top: SPACING / 2,
299 bottom: SPACING / 2,
300 left: SPACING,
301 right: SPACING,
302 },
303 },
304 state: {
305 clicked: {
306 background: background(layer, "pressed"),
307 },
308 },
309 }),
310 state: {
311 inactive: {
312 hovered: {
313 background: background(layer, "hovered"),
314 },
315 },
316 active: {
317 default: {
318 ...text(theme.lowest, "sans", { size: "sm" }),
319 background: background(theme.lowest),
320 },
321 clicked: {
322 background: background(layer, "pressed"),
323 },
324 },
325 },
326 }),
327 contact_avatar: {
328 corner_radius: 10,
329 width: 20,
330 },
331 channel_avatar: {
332 corner_radius: 10,
333 width: 20,
334 },
335 extra_participant_label: {
336 corner_radius: 10,
337 padding: {
338 left: 10,
339 right: 4,
340 },
341 background: background(layer, "hovered"),
342 ...text(layer, "sans", "hovered", { size: "xs" }),
343 },
344 contact_status_free: indicator({ layer, color: "positive" }),
345 contact_status_busy: indicator({ layer, color: "negative" }),
346 contact_username: {
347 ...text(layer, "sans", { size: "sm" }),
348 margin: {
349 left: NAME_MARGIN,
350 },
351 },
352 contact_button_spacing: NAME_MARGIN,
353 contact_button: icon_button({
354 variant: "ghost",
355 color: "variant",
356 size: "sm",
357 }),
358 disabled_button: {
359 ...contact_button,
360 background: background(layer, "on"),
361 color: foreground(layer, "on"),
362 },
363 calling_indicator: {
364 ...text(layer, "sans", "variant", { size: "xs" }),
365 },
366 tree_branch: toggleable({
367 base: interactive({
368 base: {
369 color: border_color(layer),
370 width: 1,
371 },
372 state: {
373 hovered: {
374 color: border_color(layer),
375 },
376 },
377 }),
378 state: {
379 active: {
380 default: {
381 color: border_color(layer),
382 },
383 },
384 },
385 }),
386 project_row: toggleable({
387 base: interactive({
388 base: {
389 ...project_row,
390 icon: {
391 margin: { left: NAME_MARGIN },
392 color: foreground(layer, "variant"),
393 width: 14,
394 },
395 name: {
396 ...project_row.name,
397 ...text(layer, "sans", { size: "sm" }),
398 },
399 },
400 state: {
401 hovered: {
402 background: background(layer, "hovered"),
403 },
404 },
405 }),
406 state: {
407 active: {
408 default: { background: background(theme.lowest) },
409 },
410 },
411 }),
412 face_overlap: 8,
413 channel_editor: {
414 padding: {
415 left: NAME_MARGIN,
416 },
417 },
418 }
419}