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