Fossil SCM

fossil-scm / src / style.chat.css
Blame History Raw 711 lines
1
/* Chat-related */
2
body.chat span.at-name { /* for @USERNAME references */
3
text-decoration: underline;
4
font-weight: bold;
5
}
6
/* A wrapper for a single single chat message (one row of the UI) */
7
body.chat .message-widget {
8
margin-bottom: 0.75em;
9
border: none;
10
display: flex;
11
flex-direction: column;
12
border: none;
13
align-items: flex-start;
14
}
15
body.chat button,
16
body.chat input[type=button] {
17
line-height: inherit/*undo skin-specific funkiness*/;
18
}
19
body.chat .message-widget:last-of-type {
20
/* Latest message: reduce bottom gap */
21
margin-bottom: 0.1em;
22
}
23
body.chat.my-messages-right .message-widget.mine {
24
/* Right-aligns a user's own chat messages, similar to how
25
most/some mobile messaging apps do it. */
26
align-items: flex-end;
27
}
28
body.chat.my-messages-right .message-widget.notification {
29
/* Center-aligns a system-level notification message. */
30
align-items: center;
31
}
32
/* The content area of a message. */
33
body.chat .message-widget-content {
34
border-radius: 0.25em;
35
border: 1px solid rgba(0,0,0,0.2);
36
box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
37
padding: 0.25em 0.5em;
38
margin-top: 0;
39
min-width: 9em /*avoid unsightly "underlap" with the neighboring
40
.message-widget-tab element*/;
41
white-space: normal;
42
word-break: break-word /* so that full hashes wrap on narrow screens */;
43
}
44
45
body.chat .message-widget-content.wide {
46
/* Special case for when embedding content which we really want to
47
expand, namely iframes. */
48
width: 98%;
49
}
50
body.chat .message-widget-content label[for] {
51
margin-left: 0.25em;
52
cursor: pointer;
53
}
54
body.chat .message-widget-content > .attachment-link {
55
display: flex;
56
flex-direction: row;
57
}
58
body.chat .message-widget-content > .attachment-link > a {
59
margin-right: 1em;
60
}
61
body.chat .message-widget-content > iframe {
62
width: 100%;
63
max-width: 100%;
64
resize: both;
65
}
66
body.chat .message-widget-content> a {
67
/* Cosmetic: keep skin-induced on-hover underlining from shifting
68
content placed below this. */
69
border-bottom: 1px transparent;
70
}
71
body.chat.monospace-messages .message-widget-content,
72
body.chat.monospace-messages .chat-input-field{
73
font-family: monospace;
74
}
75
body.chat .message-widget-content > * {
76
margin: 0;
77
padding: 0;
78
}
79
body.chat .message-widget-content > pre {
80
white-space: pre-wrap;
81
}
82
body.chat .message-widget-content > .markdown > *:first-child {
83
margin-top: 0;
84
}
85
body.chat .message-widget-content > .markdown > *:last-child {
86
margin-bottom: 0;
87
}
88
body.chat .message-widget-content.error .buttons {
89
display: flex;
90
flex-direction: row;
91
justify-content: space-around;
92
flex-wrap: wrap;
93
}
94
body.chat .message-widget-content.error .buttons > button {
95
margin: 0.25em;
96
}
97
98
body.chat .message-widget-content.error a {
99
color: inherit;
100
}
101
body.chat .message-widget-content.error .failed-message {
102
display: flex;
103
flex-direction: column;
104
}
105
body.chat .message-widget-content.error .failed-message textarea {
106
min-height: 5rem;
107
}
108
109
/* User name and timestamp (a LEGEND-like element) */
110
body.chat .message-widget .message-widget-tab {
111
border-radius: 0.25em 0.25em 0 0;
112
margin: 0 0.25em 0em 0.15em;
113
padding: 0 0.5em 0.15em 0.5em;
114
cursor: pointer;
115
white-space: nowrap;
116
}
117
body.chat .fossil-tooltip.help-buttonlet-content {
118
font-size: 80%;
119
}
120
121
body.chat .message-widget .message-widget-tab {
122
/* Element which renders the main metadata for a given message. */
123
}
124
body.chat .message-widget .message-widget-tab .xfrom {
125
/* xfrom part of the message tab */
126
font-style: italic;
127
font-weight: bold;
128
}
129
130
body.chat .message-widget .message-widget-tab .mtime {
131
/* mtime part of the message tab */
132
}
133
134
body.chat .message-widget .message-widget-tab .msgid {
135
/* msgid part of the message tab */
136
}
137
138
body.chat .message-widget .match {
139
font-weight: bold;
140
background-color: yellow;
141
}
142
143
body.chat.fossil-dark-style .message-widget .match {
144
background-color: #ff4800;
145
}
146
147
/* The popup element for displaying message timestamps
148
and deletion controls. */
149
body.chat .chat-message-popup {
150
font-family: monospace;
151
font-size: 0.9em;
152
text-align: left;
153
display: flex;
154
flex-direction: column;
155
align-items: stretch;
156
padding: 0.25em;
157
margin-top: 0.25em;
158
border: 1px outset;
159
border-radius: 0.5em;
160
}
161
/* Full message timestamps. */
162
body.chat .chat-message-popup > span { white-space: nowrap; }
163
/* Container for the message deletion buttons. */
164
body.chat .chat-message-popup > .toolbar {
165
padding: 0;
166
margin: 0;
167
border: 2px inset rgba(0,0,0,0.3);
168
border-radius: 0.25em;
169
display: flex;
170
flex-direction: row;
171
justify-content: stretch;
172
flex-wrap: wrap;
173
align-items: center;
174
}
175
body.chat .chat-message-popup > .toolbar > * {
176
margin: 0.35em;
177
}
178
body.chat .chat-message-popup > .toolbar > button {
179
flex: 1 1 auto;
180
}
181
/* The widget for loading more/older chat messages. */
182
body.chat #load-msg-toolbar {
183
border-radius: 0.25em;
184
padding: 0.1em 0.2em;
185
margin-bottom: 1em;
186
}
187
/* .all-done is set when chat has loaded all of the available
188
historical messages */
189
body.chat #load-msg-toolbar.all-done {
190
opacity: 0.5;
191
}
192
body.chat #load-msg-toolbar > div {
193
display: flex;
194
flex-direction: row;
195
justify-content: stretch;
196
flex-wrap: wrap;
197
}
198
body.chat #load-msg-toolbar > div > button {
199
flex: 1 1 auto;
200
}
201
/* "Chat-only mode" hides the site header/footer, showing only
202
the chat app. */
203
body.chat.chat-only-mode{
204
padding: 0;
205
margin: 0 auto;
206
}
207
body.chat #chat-button-settings {}
208
209
/** Container for the list of /chat messages. */
210
body.chat #chat-messages-wrapper {
211
overflow: auto;
212
padding: 0 0.25em;
213
}
214
body.chat #chat-messages-wrapper.loading > * {
215
/* An attempt at reducing flicker when loading lots of messages. */
216
visibility: hidden;
217
}
218
219
/* Provide a visual cue when polling is offline. */
220
body.chat.connection-error #chat-input-line-wrapper {
221
border-top: medium dotted red;
222
}
223
body.chat.fossil-dark-style.connection-error #chat-input-line-wrapper {
224
border-color: yellow;
225
}
226
227
body.chat div.content {
228
margin: 0;
229
padding: 0;
230
display: flex;
231
flex-direction: column-reverse;
232
/* ^^^^ In order to get good automatic scrolling of new messages on
233
the BOTTOM in bottom-up chat mode, such that they scroll up
234
instead of down, we have to use column-reverse layout, which
235
changes #chat-messages-wrapper's "gravity" for purposes of
236
scrolling! If we instead use flex-direction:column then each new
237
message pushes #chat-input-area down further off the screen!
238
*/
239
align-items: stretch;
240
}
241
/* Wrapper for /chat user input controls */
242
body.chat #chat-input-area {
243
display: flex;
244
flex-direction: column;
245
padding: 0;
246
margin: 0;
247
flex: 0 1 auto;
248
}
249
body.chat:not(.chat-only-mode) #chat-input-area{
250
/* Safari user reports that 2em is necessary to keep the file selection
251
widget from overlapping the page footer, whereas a margin of 0 is fine
252
for FF/Chrome (and 2em is a *huge* waste of space for those). */
253
margin-bottom: 0;
254
}
255
256
body.chat .chat-input-field {
257
flex: 10 1 auto;
258
margin: 0;
259
}
260
body.chat #chat-input-field-x,
261
body.chat #chat-input-field-multi {
262
overflow: auto;
263
resize: vertical;
264
}
265
body.chat #chat-input-field-x {
266
display: inline-block/*supposed workaround for Chrome weirdness*/;
267
padding: 0.2em;
268
background-color: rgba(156,156,156,0.3);
269
white-space: pre-wrap;
270
/* ^^^ Firefox, when pasting plain text into a contenteditable field,
271
loses all newlines unless we explicitly set this. Chrome does not. */
272
cursor: text;
273
/* ^^^ In some browsers the cursor may not change for a contenteditable
274
element until it has focus, causing potential confusion. */
275
}
276
body.chat #chat-input-field-x:empty::before {
277
content: attr(data-placeholder);
278
opacity: 0.6;
279
}
280
body.chat .chat-input-field:not(:focus){
281
border-width: 1px;
282
border-style: solid;
283
border-radius: 0.25em;
284
}
285
body.chat .chat-input-field:focus{
286
/* This transparent border helps avoid the text shifting around
287
when the contenteditable attribute causes a border (which we
288
apparently cannot style) to be added. */
289
border-width: 1px;
290
border-style: solid;
291
border-color: transparent;
292
border-radius: 0.25em;
293
}
294
/* Widget holding the chat message input field, send button, and
295
settings button. */
296
body.chat #chat-input-line-wrapper {
297
display: flex;
298
flex-direction: row;
299
align-items: stretch;
300
flex-wrap: nowrap;
301
}
302
body.chat.chat-only-mode #chat-input-line-wrapper {
303
padding: 0 0.25em;
304
}
305
306
/*body.chat #chat-input-line-wrapper:not(.compact) {
307
flex-wrap: nowrap;
308
}*/
309
body.chat #chat-input-line-wrapper.compact {
310
/* "The problem" with wrapping, together with a contenteditable input
311
field, is that the latter grows as the user types, so causes
312
wrapping to happen while they type, then to unwrap as soon as the
313
input field is cleared (when the message is sent). When we stay
314
wrapped in compact mode, the wrapped buttons simply take up too
315
much space. */
316
/*flex-wrap: wrap;
317
justify-content: flex-end;*/
318
flex-direction: column;
319
/**
320
We "really do" need column orientation here because it's the
321
only way to eliminate the possibility that (A) the buttons
322
get truncated in very narrow windows and (B) that they keep
323
stable positions.
324
*/
325
}
326
body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
327
}
328
329
body.chat #chat-buttons-wrapper {
330
flex: 0 1 auto;
331
display: flex;
332
flex-direction: column;
333
align-items: center;
334
min-width: 4em;
335
min-height: 1.5em;
336
align-self: flex-end
337
/*keep buttons stable at bottom/right even when input field
338
resizes */;
339
}
340
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
341
flex-direction: row;
342
flex: 1 1 auto;
343
align-self: stretch;
344
justify-content: flex-end;
345
/*flex-wrap: wrap;*/
346
/* Wrapping would be ideal except that the edit widget
347
grows in width as the user types, moving the buttons
348
around */
349
}
350
body.chat #chat-buttons-wrapper > .cbutton {
351
padding: 0;
352
display: inline-block;
353
border-width: 1px;
354
border-style: solid;
355
border-radius: 0.25em;
356
min-width: 4ex;
357
max-width: 4ex;
358
min-height: 3ex;
359
max-height: 3ex;
360
margin: 0.125em;
361
display: inline-flex;
362
justify-content: center;
363
align-items: center;
364
cursor: pointer;
365
font-size: 130%;
366
}
367
body.chat #chat-buttons-wrapper > .cbutton:hover {
368
background-color: rgba(200,200,200,0.3);
369
}
370
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
371
margin: 2px 0.125em 0 0.125em;
372
min-width: 4.5ex;
373
max-width: 4.5ex;
374
min-height: 2.3ex;
375
max-height: 2.3ex;
376
font-size: 120%;
377
}
378
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
379
min-width: 10ex;
380
}
381
.chat-input-field {
382
font-family: inherit
383
}
384
body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
385
body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
386
min-height: 4rem;
387
/*
388
Problems related to max-height:
389
390
- If we do NOT set a max-height then pasting/typing a large amount
391
of text can cause this element to grow without bounds, larger than
392
the window, and there's no way to navigate it sensibly. In this
393
case, manually resizing the element (desktop only - mobile doesn't
394
offer that) will force it to stay at the selected size even if more
395
content is added to it later.
396
397
- If we DO set a max-height then its growth is bounded but it also
398
cannot manually expanded by the user.
399
400
The lesser of the two evils seems to be to rely on the browser
401
feature that a manual resize of the element will pin its size.
402
*/
403
}
404
405
body.chat #chat-input-line-wrapper > #chat-button-settings{
406
margin: 0 0 0 0.25em;
407
max-width: 2em;
408
}
409
body.chat #chat-input-line-wrapper > input[type=text],
410
body.chat #chat-input-line-wrapper > textarea {
411
flex: 20 1 auto;
412
max-width: revert;
413
min-width: 20em;
414
}
415
body.chat #chat-input-line-wrapper.compact > input[type=text] {
416
margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
417
}
418
/* Widget holding the file selection control and preview */
419
body.chat #chat-input-file-area {
420
display: flex;
421
flex-direction: row;
422
margin: 0;
423
}
424
body.chat #chat-input-file-area > .file-selection-wrapper {
425
align-self: flex-start;
426
margin-right: 0.5em;
427
flex: 0 1 auto;
428
padding: 0.25em 0.5em;
429
white-space: nowrap;
430
}
431
body.chat #chat-input-file {
432
border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
433
border-radius: 0.25em;
434
padding: 0.25em;
435
}
436
body.chat #chat-input-file > input {
437
flex: 1 0 auto;
438
}
439
/* Indicator when a drag/drop is in progress */
440
body.chat #chat-input-file.dragover {
441
border: 1px dashed green;
442
}
443
/* Widget holding the details of a selected/dropped file/image. */
444
body.chat #chat-drop-details {
445
padding: 0 1em;
446
white-space: pre;
447
font-family: monospace;
448
margin: auto;
449
flex: 0;
450
}
451
body.chat #chat-drop-details:empty {
452
padding: 0;
453
margin: 0;
454
}
455
body.chat #chat-drop-details img {
456
max-width: 45%;
457
max-height: 45%;
458
}
459
body.chat .chat-view {
460
flex: 20 1 auto
461
/*ensure that these grow more than the non-.chat-view elements.
462
Note that setting flex shrink to 0 breaks/disables scrolling!*/;
463
margin-bottom: 0.2em;
464
}
465
body.chat #chat-config,
466
body.chat #chat-search,
467
body.chat #chat-preview,
468
body.chat #chat-zoom {
469
/* /chat configuration widget */
470
display: flex;
471
flex-direction: column;
472
overflow: auto;
473
padding: 0;
474
margin: 0;
475
align-items: stretch;
476
min-height: 6em;
477
}
478
body.chat #chat-zoom {
479
justify-content: space-between;
480
}
481
body.chat #chat-zoom-content {
482
display: flex;
483
overflow: auto;
484
}
485
body.chat #chat-zoom-content > .message-widget {
486
flex-grow: 1;
487
}
488
body.chat #chat-zoom-content > .message-widget > .message-widget-content {
489
width: 99%;
490
}
491
body.chat #chat-zoom-content > .message-widget .toolbar.hide-in-zoom {
492
/* The various Delete buttons misinteract with zoom mode's moving-around
493
of message widgets, so hide them in zoom mode. */
494
position: absolute !important;
495
opacity: 0 !important;
496
pointer-events: none !important;
497
display: none !important;
498
}
499
body.chat #chat-config #chat-config-options {
500
/* /chat config options go here */
501
flex: 1 1 auto;
502
display: flex;
503
flex-direction: column;
504
overflow: auto;
505
align-items: stretch;
506
}
507
body.chat #chat-config #chat-config-options .menu-entry {
508
display: flex;
509
align-items: center;
510
flex-direction: row-reverse;
511
flex-wrap: nowrap;
512
padding: 1em;
513
flex: 1 1 auto;
514
align-self: stretch;
515
}
516
body.chat #chat-config #chat-config-options .menu-entry.parent{
517
border-radius: 1em 1em 0 1em;
518
margin-top: 1em;
519
}
520
body.chat #chat-config #chat-config-options .menu-entry.child {
521
/*padding-left: 2.5em;*/
522
margin-left: 2em;
523
}
524
body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
525
background-color: rgba(175,175,175,0.15);
526
}
527
body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
528
background-color: rgba(175,175,175,0.35);
529
}
530
body.chat #chat-config #chat-config-options .menu-entry:first-child {
531
/* Config list header */
532
border-radius: 0 0 1em 1em;
533
}
534
body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
535
align-items: start;
536
}
537
body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
538
/* Holder for a checkbox, if any */
539
min-width: 1.5rem;
540
margin-right: 1rem;
541
}
542
body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
543
/* Wrapper for a LABEL and a .hint element. */
544
display: flex;
545
flex-direction: column;
546
align-self: baseline;
547
flex: 1 1 auto;
548
}
549
body.chat #chat-config #chat-config-options .menu-entry label {
550
/* Config option label. */
551
font-weight: bold;
552
white-space: initial;
553
}
554
body.chat #chat-config #chat-config-options .menu-entry label[for] {
555
cursor: pointer;
556
}
557
body.chat #chat-config #chat-config-options .menu-entry .hint {
558
/* Config menu hint text */
559
font-size: 85%;
560
font-weight: normal;
561
white-space: pre-wrap;
562
display: inline-block;
563
opacity: 0.85;
564
}
565
body.chat #chat-config #chat-config-options .menu-entry select {
566
}
567
body.chat #chat-preview #chat-preview-content,
568
body.chat #chat-search #chat-search-content {
569
overflow: auto;
570
flex: 1 1 auto;
571
padding: 0.5em;
572
border: 1px dotted;
573
}
574
575
body.chat #chat-preview #chat-preview-content > * {
576
margin: 0;
577
padding: 0;
578
}
579
body.chat .chat-view .button-bar {
580
flex: 0 1 auto;
581
display: flex;
582
flex-direction: column;
583
}
584
body.chat .chat-view .button-bar button {
585
padding: 0.5em;
586
flex: 1 1 auto;
587
margin: 0.25em 0;
588
}
589
590
body.chat #chat-search .button-bar {
591
flex: 0 1 auto;
592
display: flex;
593
flex-direction: row;
594
}
595
596
body.chat #chat-user-list-wrapper {
597
/* Safari can't do fieldsets right, so we emulate one. */
598
border-radius: 0.5em;
599
margin: 1em 0 0.2em 0;
600
padding: 0 0.5em;
601
border-style: inset;
602
border-width: 0 1px 1px 1px/*else collides with the LEGEND*/;
603
}
604
body.chat #chat-user-list-wrapper.collapsed {
605
padding: 0;
606
}
607
body.chat #chat-user-list-wrapper > .legend {
608
font-weight: initial;
609
padding: 0 0.5em 0 0.5em;
610
position: relative;
611
top: -1.75ex/* place it like a fieldset legend */;
612
cursor: pointer;
613
}
614
body.chat #chat-user-list-wrapper > .legend > * {
615
vertical-align: middle;
616
}
617
body.chat #chat-user-list-wrapper > .legend > *:nth-child(2){
618
/* Title label */
619
opacity: 0.6;
620
font-size: 0.8em;
621
}
622
body.chat #chat-user-list-wrapper.collapsed > .legend > *:nth-child(2)::after {
623
content: " (tap to toggle)";
624
}
625
body.chat #chat-user-list-wrapper .help-buttonlet {
626
margin: 0;
627
}
628
body.chat #chat-user-list-wrapper.collapsed #chat-user-list {
629
position: absolute !important;
630
opacity: 0 !important;
631
pointer-events: none !important;
632
display: none !important;
633
}
634
body.chat #chat-user-list {
635
margin-top: -1.25ex;
636
display: flex;
637
flex-direction: row;
638
flex-wrap: wrap;
639
align-items: center;
640
}
641
body.chat #chat-user-list .chat-user {
642
margin: 0.2em;
643
padding: 0.1em 0.5em 0.2em 0.5em;
644
border-radius: 0.5em;
645
cursor: pointer;
646
text-align: center;
647
white-space: pre;
648
}
649
body.chat #chat-user-list .timestamp {
650
font-size: 85%;
651
font-family: monospace;
652
}
653
body.chat #chat-user-list:not(.timestamps) .timestamp {
654
display: none;
655
}
656
body.chat #chat-user-list .chat-user.selected {
657
font-weight: bold;
658
text-decoration: underline;
659
}
660
661
body.chat .searchForm {
662
margin-top: 1em;
663
}
664
body.chat .spacer-widget button {
665
margin-left: 1ex;
666
margin-right: 1ex;
667
display: block;
668
margin-top: 0.5em;
669
margin-bottom: 0.5em;
670
}
671
672
body.chat .anim-rotate-360 {
673
animation: rotate-360 750ms linear;
674
}
675
@keyframes rotate-360 {
676
from { transform: rotate(0deg); }
677
to { transform: rotate(360deg); }
678
}
679
body.chat .anim-flip-h {
680
animation: flip-h 750ms linear;
681
}
682
@keyframes flip-h{
683
from { transform: rotateY(0deg); }
684
to { transform: rotateY(360deg); }
685
}
686
body.chat .anim-flip-v {
687
animation: flip-v 750ms linear;
688
}
689
@keyframes flip-v{
690
from { transform: rotateX(0deg); }
691
to { transform: rotateX(360deg); }
692
}
693
body.chat .anim-fade-in {
694
animation: fade-in 750ms linear;
695
}
696
body.chat .anim-fade-in-fast {
697
animation: fade-in 350ms linear;
698
}
699
@keyframes fade-in {
700
from { opacity: 0; }
701
to { opacity: 1; }
702
}
703
body.chat .anim-fade-out-fast {
704
animation: fade-out 250ms linear;
705
}
706
@keyframes fade-out {
707
from { opacity: 1; }
708
to { opacity: 0; }
709
}
710
711

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button