Fossil SCM

Moved chat.c inline CSS style to default.css. Various chat layout tweaks.

stephan 2020-12-25 11:06 trunk
Commit 467dbc8fd7881af4b2ea01eb23c2633fa7fdb888c5f605f09ba206679a362f75
3 files changed +4 -60 +23 -13 +89 -4
+4 -60
--- src/chat.c
+++ src/chat.c
@@ -92,69 +92,12 @@
9292
iPingTcp = atoi(PD("ping","0"));
9393
if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0;
9494
if( iPingTcp ) style_disable_csp();
9595
style_set_current_feature("chat");
9696
style_header("Chat");
97
- @ <style>
98
- @ #dialog {
99
- @ width: 97%%;
100
- @ }
101
- @ #chat-input-area {
102
- @ width: 100%%;
103
- @ display: flex;
104
- @ flex-direction: column;
105
- @ }
106
- @ #chat-input-line {
107
- @ display: flex;
108
- @ flex-direction: row;
109
- @ margin-bottom: 0.25em;
110
- @ align-items: center;
111
- @ }
112
- @ #chat-input-line > input[type=submit] {
113
- @ flex: 1 5 auto;
114
- @ max-width: 6em;
115
- @ }
116
- @ #chat-input-line > input[type=text] {
117
- @ flex: 5 1 auto;
118
- @ }
119
- @ #chat-input-file-area {
120
- @ display: flex;
121
- @ flex-direction: row;
122
- @ align-items: center;
123
- @ }
124
- @ #chat-input-file-area > .file-selection-wrapper {
125
- @ align-self: flex-start;
126
- @ margin-right: 0.5em;
127
- @ flex: 0 1 auto;
128
- @ padding: 0.25em 0.25em 0.25em 0;
129
- @ }
130
- @ #chat-input-file-area .file-selection-wrapper > * {
131
- @ vertical-align: middle;
132
- @ margin: 0;
133
- @ }
134
- @ #chat-input-file {
135
- @ border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
136
- @ border-radius: 0.25em;
137
- @ padding: 0.25em;
138
- @ }
139
- @ #chat-input-file > input {
140
- @ flex: 1 0 auto;
141
- @ }
142
- @ #chat-input-file.dragover {
143
- @ border: 1px dashed green;
144
- @ }
145
- @ #chat-drop-details {
146
- @ flex: 0 1 auto;
147
- @ padding: 0.5em 1em;
148
- @ margin-left: 0.5em;
149
- @ white-space: pre;
150
- @ font-family: monospace;
151
- @ max-width: 50%%;
152
- @ }
153
- @ </style>
154
- @ <form accept-encoding="utf-8" id="chat-form" autocomplete="off">
15597
@ <div id='chat-input-area'>
98
+ @ <form accept-encoding="utf-8" id="chat-form" autocomplete="off">
15699
@ <div id='chat-input-line'>
157100
@ <input type="text" name="msg" id="sbox" \
158101
@ placeholder="Type message here.">
159102
@ <input type="submit" value="Send">
160103
@ <span id="chat-settings-button" class="settings-icon"></span>
@@ -168,16 +111,17 @@
168111
@ </div>
169112
@ <input type="file" name="file" id="chat-input-file">
170113
@ </div>
171114
@ <div id="chat-drop-details"></div>
172115
@ </div>
173
- @ </div>
174116
@ </form>
175
- @ <hr>
117
+ @ </div>
176118
177119
/* New chat messages get inserted immediately after this element */
120
+ @ <div id='chat-messages-wrapper'>
178121
@ <span id='message-inject-point'></span>
122
+ @ </div>
179123
180124
builtin_fossil_js_bundle_or("popupwidget", NULL);
181125
/* Always in-line the javascript for the chat page */
182126
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
183127
/* We need an onload handler to ensure that window.fossil is
184128
--- src/chat.c
+++ src/chat.c
@@ -92,69 +92,12 @@
92 iPingTcp = atoi(PD("ping","0"));
93 if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0;
94 if( iPingTcp ) style_disable_csp();
95 style_set_current_feature("chat");
96 style_header("Chat");
97 @ <style>
98 @ #dialog {
99 @ width: 97%%;
100 @ }
101 @ #chat-input-area {
102 @ width: 100%%;
103 @ display: flex;
104 @ flex-direction: column;
105 @ }
106 @ #chat-input-line {
107 @ display: flex;
108 @ flex-direction: row;
109 @ margin-bottom: 0.25em;
110 @ align-items: center;
111 @ }
112 @ #chat-input-line > input[type=submit] {
113 @ flex: 1 5 auto;
114 @ max-width: 6em;
115 @ }
116 @ #chat-input-line > input[type=text] {
117 @ flex: 5 1 auto;
118 @ }
119 @ #chat-input-file-area {
120 @ display: flex;
121 @ flex-direction: row;
122 @ align-items: center;
123 @ }
124 @ #chat-input-file-area > .file-selection-wrapper {
125 @ align-self: flex-start;
126 @ margin-right: 0.5em;
127 @ flex: 0 1 auto;
128 @ padding: 0.25em 0.25em 0.25em 0;
129 @ }
130 @ #chat-input-file-area .file-selection-wrapper > * {
131 @ vertical-align: middle;
132 @ margin: 0;
133 @ }
134 @ #chat-input-file {
135 @ border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
136 @ border-radius: 0.25em;
137 @ padding: 0.25em;
138 @ }
139 @ #chat-input-file > input {
140 @ flex: 1 0 auto;
141 @ }
142 @ #chat-input-file.dragover {
143 @ border: 1px dashed green;
144 @ }
145 @ #chat-drop-details {
146 @ flex: 0 1 auto;
147 @ padding: 0.5em 1em;
148 @ margin-left: 0.5em;
149 @ white-space: pre;
150 @ font-family: monospace;
151 @ max-width: 50%%;
152 @ }
153 @ </style>
154 @ <form accept-encoding="utf-8" id="chat-form" autocomplete="off">
155 @ <div id='chat-input-area'>
 
156 @ <div id='chat-input-line'>
157 @ <input type="text" name="msg" id="sbox" \
158 @ placeholder="Type message here.">
159 @ <input type="submit" value="Send">
160 @ <span id="chat-settings-button" class="settings-icon"></span>
@@ -168,16 +111,17 @@
168 @ </div>
169 @ <input type="file" name="file" id="chat-input-file">
170 @ </div>
171 @ <div id="chat-drop-details"></div>
172 @ </div>
173 @ </div>
174 @ </form>
175 @ <hr>
176
177 /* New chat messages get inserted immediately after this element */
 
178 @ <span id='message-inject-point'></span>
 
179
180 builtin_fossil_js_bundle_or("popupwidget", NULL);
181 /* Always in-line the javascript for the chat page */
182 @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
183 /* We need an onload handler to ensure that window.fossil is
184
--- src/chat.c
+++ src/chat.c
@@ -92,69 +92,12 @@
92 iPingTcp = atoi(PD("ping","0"));
93 if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0;
94 if( iPingTcp ) style_disable_csp();
95 style_set_current_feature("chat");
96 style_header("Chat");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97 @ <div id='chat-input-area'>
98 @ <form accept-encoding="utf-8" id="chat-form" autocomplete="off">
99 @ <div id='chat-input-line'>
100 @ <input type="text" name="msg" id="sbox" \
101 @ placeholder="Type message here.">
102 @ <input type="submit" value="Send">
103 @ <span id="chat-settings-button" class="settings-icon"></span>
@@ -168,16 +111,17 @@
111 @ </div>
112 @ <input type="file" name="file" id="chat-input-file">
113 @ </div>
114 @ <div id="chat-drop-details"></div>
115 @ </div>
 
116 @ </form>
117 @ </div>
118
119 /* New chat messages get inserted immediately after this element */
120 @ <div id='chat-messages-wrapper'>
121 @ <span id='message-inject-point'></span>
122 @ </div>
123
124 builtin_fossil_js_bundle_or("popupwidget", NULL);
125 /* Always in-line the javascript for the chat page */
126 @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
127 /* We need an onload handler to ensure that window.fossil is
128
+23 -13
--- src/chat.js
+++ src/chat.js
@@ -3,16 +3,22 @@
33
application.
44
*/
55
(function(){
66
const form = document.querySelector('#chat-form');
77
const F = window.fossil, D = F.dom;
8
+ const E1 = function(selector){
9
+ const e = document.querySelector(selector);
10
+ if(!e) throw new Error("missing required DOM element: "+selector);
11
+ return e;
12
+ };
813
const Chat = (function(){
914
const cs = {
1015
e:{/*map of certain DOM elements.*/
11
- messageInjectPoint: document.querySelector('#message-inject-point'),
12
- pageTitle: document.querySelector('head title'),
13
- loadToolbar: undefined /* the load-posts toolbar (dynamically created) */
16
+ messageInjectPoint: E1('#message-inject-point'),
17
+ pageTitle: E1('head title'),
18
+ loadToolbar: undefined /* the load-posts toolbar (dynamically created) */,
19
+ messagesWrapper: E1('#chat-messages-wrapper')
1420
},
1521
me: F.user.name,
1622
mxMsg: F.config.chatInitSize ? -F.config.chatInitSize : -50,
1723
mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
1824
pageIsActive: 'visible'===document.visibilityState,
@@ -355,19 +361,24 @@
355361
var popupSize = undefined/*placement workaround*/;
356362
const settingsPopup = new F.PopupWidget({
357363
cssClass: ['fossil-tooltip', 'chat-settings-popup'],
358364
adjustY: function(y){
359365
const rect = settingsButton.getBoundingClientRect();
360
- return rect.top + rect.height;
366
+ return rect.top + rect.height + 2;
361367
}
362368
});
363369
settingsPopup.installClickToHide();
364370
const btnToggleBody = D.button("Toggle page body");
365371
D.append(settingsPopup.e, btnToggleBody);
366372
const toggleBody = function f(){
367
- if(f.isHidden) D.removeClass(f.elemsToToggle, 'hidden');
368
- else D.addClass(f.elemsToToggle, 'hidden');
373
+ if(f.isHidden){
374
+ D.removeClass(f.elemsToToggle, 'hidden');
375
+ D.removeClass(document.body, 'chat-only-mode');
376
+ }else{
377
+ D.addClass(f.elemsToToggle, 'hidden');
378
+ D.addClass(document.body, 'chat-only-mode');
379
+ }
369380
f.isHidden = !f.isHidden;
370381
};
371382
toggleBody.elemsToToggle = [];
372383
toggleBody.isHidden = false;
373384
document.body.childNodes.forEach(function(e){
@@ -386,11 +397,10 @@
386397
settingsPopup.show(document.body);
387398
popupSize = settingsPopup.e.getBoundingClientRect();
388399
settingsPopup.hide();
389400
settingsPopup.options.adjustX = function(x){
390401
const rect = settingsButton.getBoundingClientRect();
391
- console.debug("popupSize = ",popupSize);
392402
return rect.right - popupSize.width;
393403
};
394404
})()/*#chat-settings-button setup*/;
395405
396406
@@ -484,18 +494,18 @@
484494
if(jx.msgs.length && F.config.pingTcp){
485495
fetch("http:/"+"/localhost:"+window.fossil.config.pingTcp+"/chat-ping");
486496
}
487497
}/*newcontent()*/;
488498
489
- if(true){
499
+ (function(){
490500
/** Add toolbar for loading older messages. We use a FIELDSET here
491501
because a fieldset is the only parent element type which can
492502
automatically enable/disable its children by
493503
enabling/disabling the parent element. */
494504
const loadLegend = D.legend("Load...");
495
- const toolbar = Chat.e.loadToolbar = D.addClass(
496
- D.fieldset(loadLegend), "load-msg-toolbar"
505
+ const toolbar = Chat.e.loadToolbar = D.attr(
506
+ D.fieldset(loadLegend), "id", "load-msg-toolbar"
497507
);
498508
Chat.disableDuringAjax.push(toolbar);
499509
/* Loads the next n oldest messages, or all previous history if n is negative. */
500510
const loadOldMessages = function(n){
501511
Chat.ajaxStart();
@@ -535,13 +545,13 @@
535545
D.append(wrapper, btn);
536546
btn.addEventListener('click',()=>loadOldMessages(Chat.loadMessageCount));
537547
btn = D.button("All previous messages");
538548
D.append(wrapper, btn);
539549
btn.addEventListener('click',()=>loadOldMessages(-1));
540
- D.append(document.querySelector('body.chat > div.content'), toolbar);
541
- toolbar.disabled = true /*will be enabled when msg load finishes */;
542
- }/*end history loading widget setup*/
550
+ D.append(Chat.e.messagesWrapper, toolbar);
551
+ toolbar.disabled = true /*will be enabled when msg load finishes */;
552
+ })()/*end history loading widget setup*/;
543553
544554
async function poll(isFirstCall){
545555
if(poll.running) return;
546556
poll.running = true;
547557
if(isFirstCall) Chat.ajaxStart();
548558
--- src/chat.js
+++ src/chat.js
@@ -3,16 +3,22 @@
3 application.
4 */
5 (function(){
6 const form = document.querySelector('#chat-form');
7 const F = window.fossil, D = F.dom;
 
 
 
 
 
8 const Chat = (function(){
9 const cs = {
10 e:{/*map of certain DOM elements.*/
11 messageInjectPoint: document.querySelector('#message-inject-point'),
12 pageTitle: document.querySelector('head title'),
13 loadToolbar: undefined /* the load-posts toolbar (dynamically created) */
 
14 },
15 me: F.user.name,
16 mxMsg: F.config.chatInitSize ? -F.config.chatInitSize : -50,
17 mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
18 pageIsActive: 'visible'===document.visibilityState,
@@ -355,19 +361,24 @@
355 var popupSize = undefined/*placement workaround*/;
356 const settingsPopup = new F.PopupWidget({
357 cssClass: ['fossil-tooltip', 'chat-settings-popup'],
358 adjustY: function(y){
359 const rect = settingsButton.getBoundingClientRect();
360 return rect.top + rect.height;
361 }
362 });
363 settingsPopup.installClickToHide();
364 const btnToggleBody = D.button("Toggle page body");
365 D.append(settingsPopup.e, btnToggleBody);
366 const toggleBody = function f(){
367 if(f.isHidden) D.removeClass(f.elemsToToggle, 'hidden');
368 else D.addClass(f.elemsToToggle, 'hidden');
 
 
 
 
 
369 f.isHidden = !f.isHidden;
370 };
371 toggleBody.elemsToToggle = [];
372 toggleBody.isHidden = false;
373 document.body.childNodes.forEach(function(e){
@@ -386,11 +397,10 @@
386 settingsPopup.show(document.body);
387 popupSize = settingsPopup.e.getBoundingClientRect();
388 settingsPopup.hide();
389 settingsPopup.options.adjustX = function(x){
390 const rect = settingsButton.getBoundingClientRect();
391 console.debug("popupSize = ",popupSize);
392 return rect.right - popupSize.width;
393 };
394 })()/*#chat-settings-button setup*/;
395
396
@@ -484,18 +494,18 @@
484 if(jx.msgs.length && F.config.pingTcp){
485 fetch("http:/"+"/localhost:"+window.fossil.config.pingTcp+"/chat-ping");
486 }
487 }/*newcontent()*/;
488
489 if(true){
490 /** Add toolbar for loading older messages. We use a FIELDSET here
491 because a fieldset is the only parent element type which can
492 automatically enable/disable its children by
493 enabling/disabling the parent element. */
494 const loadLegend = D.legend("Load...");
495 const toolbar = Chat.e.loadToolbar = D.addClass(
496 D.fieldset(loadLegend), "load-msg-toolbar"
497 );
498 Chat.disableDuringAjax.push(toolbar);
499 /* Loads the next n oldest messages, or all previous history if n is negative. */
500 const loadOldMessages = function(n){
501 Chat.ajaxStart();
@@ -535,13 +545,13 @@
535 D.append(wrapper, btn);
536 btn.addEventListener('click',()=>loadOldMessages(Chat.loadMessageCount));
537 btn = D.button("All previous messages");
538 D.append(wrapper, btn);
539 btn.addEventListener('click',()=>loadOldMessages(-1));
540 D.append(document.querySelector('body.chat > div.content'), toolbar);
541 toolbar.disabled = true /*will be enabled when msg load finishes */;
542 }/*end history loading widget setup*/
543
544 async function poll(isFirstCall){
545 if(poll.running) return;
546 poll.running = true;
547 if(isFirstCall) Chat.ajaxStart();
548
--- src/chat.js
+++ src/chat.js
@@ -3,16 +3,22 @@
3 application.
4 */
5 (function(){
6 const form = document.querySelector('#chat-form');
7 const F = window.fossil, D = F.dom;
8 const E1 = function(selector){
9 const e = document.querySelector(selector);
10 if(!e) throw new Error("missing required DOM element: "+selector);
11 return e;
12 };
13 const Chat = (function(){
14 const cs = {
15 e:{/*map of certain DOM elements.*/
16 messageInjectPoint: E1('#message-inject-point'),
17 pageTitle: E1('head title'),
18 loadToolbar: undefined /* the load-posts toolbar (dynamically created) */,
19 messagesWrapper: E1('#chat-messages-wrapper')
20 },
21 me: F.user.name,
22 mxMsg: F.config.chatInitSize ? -F.config.chatInitSize : -50,
23 mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
24 pageIsActive: 'visible'===document.visibilityState,
@@ -355,19 +361,24 @@
361 var popupSize = undefined/*placement workaround*/;
362 const settingsPopup = new F.PopupWidget({
363 cssClass: ['fossil-tooltip', 'chat-settings-popup'],
364 adjustY: function(y){
365 const rect = settingsButton.getBoundingClientRect();
366 return rect.top + rect.height + 2;
367 }
368 });
369 settingsPopup.installClickToHide();
370 const btnToggleBody = D.button("Toggle page body");
371 D.append(settingsPopup.e, btnToggleBody);
372 const toggleBody = function f(){
373 if(f.isHidden){
374 D.removeClass(f.elemsToToggle, 'hidden');
375 D.removeClass(document.body, 'chat-only-mode');
376 }else{
377 D.addClass(f.elemsToToggle, 'hidden');
378 D.addClass(document.body, 'chat-only-mode');
379 }
380 f.isHidden = !f.isHidden;
381 };
382 toggleBody.elemsToToggle = [];
383 toggleBody.isHidden = false;
384 document.body.childNodes.forEach(function(e){
@@ -386,11 +397,10 @@
397 settingsPopup.show(document.body);
398 popupSize = settingsPopup.e.getBoundingClientRect();
399 settingsPopup.hide();
400 settingsPopup.options.adjustX = function(x){
401 const rect = settingsButton.getBoundingClientRect();
 
402 return rect.right - popupSize.width;
403 };
404 })()/*#chat-settings-button setup*/;
405
406
@@ -484,18 +494,18 @@
494 if(jx.msgs.length && F.config.pingTcp){
495 fetch("http:/"+"/localhost:"+window.fossil.config.pingTcp+"/chat-ping");
496 }
497 }/*newcontent()*/;
498
499 (function(){
500 /** Add toolbar for loading older messages. We use a FIELDSET here
501 because a fieldset is the only parent element type which can
502 automatically enable/disable its children by
503 enabling/disabling the parent element. */
504 const loadLegend = D.legend("Load...");
505 const toolbar = Chat.e.loadToolbar = D.attr(
506 D.fieldset(loadLegend), "id", "load-msg-toolbar"
507 );
508 Chat.disableDuringAjax.push(toolbar);
509 /* Loads the next n oldest messages, or all previous history if n is negative. */
510 const loadOldMessages = function(n){
511 Chat.ajaxStart();
@@ -535,13 +545,13 @@
545 D.append(wrapper, btn);
546 btn.addEventListener('click',()=>loadOldMessages(Chat.loadMessageCount));
547 btn = D.button("All previous messages");
548 D.append(wrapper, btn);
549 btn.addEventListener('click',()=>loadOldMessages(-1));
550 D.append(Chat.e.messagesWrapper, toolbar);
551 toolbar.disabled = true /*will be enabled when msg load finishes */;
552 })()/*end history loading widget setup*/;
553
554 async function poll(isFirstCall){
555 if(poll.running) return;
556 poll.running = true;
557 if(isFirstCall) Chat.ajaxStart();
558
+89 -4
--- src/default.css
+++ src/default.css
@@ -1529,25 +1529,25 @@
15291529
}
15301530
body.chat .chat-message-popup > .toolbar > button {
15311531
flex: 1 1 auto;
15321532
}
15331533
1534
-body.chat .load-msg-toolbar {
1534
+body.chat #load-msg-toolbar {
15351535
border-radius: 0.25em;
15361536
padding: 0.1em 0.2em;
15371537
margin-bottom: 1em;
15381538
}
1539
-body.chat .load-msg-toolbar.all-done {
1539
+body.chat #load-msg-toolbar.all-done {
15401540
opacity: 0.5;
15411541
}
1542
-body.chat .load-msg-toolbar > div {
1542
+body.chat #load-msg-toolbar > div {
15431543
display: flex;
15441544
flex-direction: row;
15451545
justify-content: stretch;
15461546
flex-wrap: wrap;
15471547
}
1548
-body.chat .load-msg-toolbar > div > button {
1548
+body.chat #load-msg-toolbar > div > button {
15491549
flex: 1 1 auto;
15501550
}
15511551
15521552
.settings-icon {
15531553
/* Icon source: https://de.wikipedia.org/wiki/Datei:OOjs_UI_icon_settings.svg
@@ -1560,10 +1560,13 @@
15601560
max-height: 1em;
15611561
min-width: 1em;
15621562
max-width: 1em;
15631563
margin: 0;
15641564
padding: 0.2em/*needed to avoid image truncation*/;
1565
+}
1566
+body.fossil-dark-style .settings-icon {
1567
+ filter: invert(100%);
15651568
}
15661569
body.chat #chat-settings-button {
15671570
}
15681571
body.chat .chat-settings-popup {
15691572
font-size: 0.8em;
@@ -1571,6 +1574,88 @@
15711574
opacity: 0.8;
15721575
display: flex;
15731576
flex-direction: column;
15741577
align-items: stretch;
15751578
padding: 0.25em;
1579
+}
1580
+body.chat #chat-messages-wrapper {
1581
+ display: flex;
1582
+ flex-direction: column;
1583
+}
1584
+body.chat.chat-only-mode{
1585
+}
1586
+body.chat.chat-only-mode > div.content {
1587
+ margin: 0;
1588
+ padding: 0;
1589
+ display: flex;
1590
+ flex-direction: column;
1591
+ align-items: stretch;
1592
+}
1593
+body.chat.chat-only-mode #chat-input-area {
1594
+ /* would like to pin this to the top so that it stays in place when
1595
+ scrolling, but doing so causes #chat-messages-wrapper to scroll
1596
+ behind it visibly, which is really ugly. Only current workaround is
1597
+ to force an opaque background color on this element, but that's not
1598
+ skin-friendly. */
1599
+ /*position: fixed;
1600
+ top: 0;
1601
+ left: 0;*/
1602
+ padding: 0.5em 1em;
1603
+}
1604
+body.chat.chat-only-mode #chat-messages-wrapper {
1605
+}
1606
+
1607
+body.chat #chat-input-area {
1608
+ display: flex;
1609
+ flex-direction: column;
1610
+ border-bottom: 1px solid black;
1611
+ margin-bottom: 0.5em;
1612
+}
1613
+body.chat #chat-input-line {
1614
+ display: flex;
1615
+ flex-direction: row;
1616
+ margin-bottom: 0.25em;
1617
+ align-items: center;
1618
+}
1619
+body.chat #chat-input-line > input[type=submit] {
1620
+ flex: 1 5 auto;
1621
+ max-width: 6em;
1622
+ margin-right: 1em;
1623
+}
1624
+body.chat #chat-input-line > input[type=text] {
1625
+ flex: 5 1 auto;
1626
+}
1627
+body.chat #chat-input-file-area {
1628
+ display: flex;
1629
+ flex-direction: row;
1630
+ align-items: center;
1631
+ flex-wrap: wrap;
1632
+}
1633
+body.chat #chat-input-file-area > .file-selection-wrapper {
1634
+ align-self: flex-start;
1635
+ margin-right: 0.5em;
1636
+ flex: 0 1 auto;
1637
+ padding: 0.25em 0.25em 0.25em 0;
1638
+}
1639
+body.chat #chat-input-file-area .file-selection-wrapper > * {
1640
+ vertical-align: middle;
1641
+ margin: 0;
1642
+}
1643
+body.chat #chat-input-file {
1644
+ border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
1645
+ border-radius: 0.25em;
1646
+ padding: 0.25em;
1647
+}
1648
+body.chat #chat-input-file > input {
1649
+ flex: 1 0 auto;
1650
+}
1651
+body.chat #chat-input-file.dragover {
1652
+ border: 1px dashed green;
1653
+}
1654
+body.chat #chat-drop-details {
1655
+ flex: 0 1 auto;
1656
+ padding: 0.5em 1em;
1657
+ margin-left: 0.5em;
1658
+ white-space: pre;
1659
+ font-family: monospace;
1660
+ max-width: 50%;
15761661
}
15771662
--- src/default.css
+++ src/default.css
@@ -1529,25 +1529,25 @@
1529 }
1530 body.chat .chat-message-popup > .toolbar > button {
1531 flex: 1 1 auto;
1532 }
1533
1534 body.chat .load-msg-toolbar {
1535 border-radius: 0.25em;
1536 padding: 0.1em 0.2em;
1537 margin-bottom: 1em;
1538 }
1539 body.chat .load-msg-toolbar.all-done {
1540 opacity: 0.5;
1541 }
1542 body.chat .load-msg-toolbar > div {
1543 display: flex;
1544 flex-direction: row;
1545 justify-content: stretch;
1546 flex-wrap: wrap;
1547 }
1548 body.chat .load-msg-toolbar > div > button {
1549 flex: 1 1 auto;
1550 }
1551
1552 .settings-icon {
1553 /* Icon source: https://de.wikipedia.org/wiki/Datei:OOjs_UI_icon_settings.svg
@@ -1560,10 +1560,13 @@
1560 max-height: 1em;
1561 min-width: 1em;
1562 max-width: 1em;
1563 margin: 0;
1564 padding: 0.2em/*needed to avoid image truncation*/;
 
 
 
1565 }
1566 body.chat #chat-settings-button {
1567 }
1568 body.chat .chat-settings-popup {
1569 font-size: 0.8em;
@@ -1571,6 +1574,88 @@
1571 opacity: 0.8;
1572 display: flex;
1573 flex-direction: column;
1574 align-items: stretch;
1575 padding: 0.25em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1576 }
1577
--- src/default.css
+++ src/default.css
@@ -1529,25 +1529,25 @@
1529 }
1530 body.chat .chat-message-popup > .toolbar > button {
1531 flex: 1 1 auto;
1532 }
1533
1534 body.chat #load-msg-toolbar {
1535 border-radius: 0.25em;
1536 padding: 0.1em 0.2em;
1537 margin-bottom: 1em;
1538 }
1539 body.chat #load-msg-toolbar.all-done {
1540 opacity: 0.5;
1541 }
1542 body.chat #load-msg-toolbar > div {
1543 display: flex;
1544 flex-direction: row;
1545 justify-content: stretch;
1546 flex-wrap: wrap;
1547 }
1548 body.chat #load-msg-toolbar > div > button {
1549 flex: 1 1 auto;
1550 }
1551
1552 .settings-icon {
1553 /* Icon source: https://de.wikipedia.org/wiki/Datei:OOjs_UI_icon_settings.svg
@@ -1560,10 +1560,13 @@
1560 max-height: 1em;
1561 min-width: 1em;
1562 max-width: 1em;
1563 margin: 0;
1564 padding: 0.2em/*needed to avoid image truncation*/;
1565 }
1566 body.fossil-dark-style .settings-icon {
1567 filter: invert(100%);
1568 }
1569 body.chat #chat-settings-button {
1570 }
1571 body.chat .chat-settings-popup {
1572 font-size: 0.8em;
@@ -1571,6 +1574,88 @@
1574 opacity: 0.8;
1575 display: flex;
1576 flex-direction: column;
1577 align-items: stretch;
1578 padding: 0.25em;
1579 }
1580 body.chat #chat-messages-wrapper {
1581 display: flex;
1582 flex-direction: column;
1583 }
1584 body.chat.chat-only-mode{
1585 }
1586 body.chat.chat-only-mode > div.content {
1587 margin: 0;
1588 padding: 0;
1589 display: flex;
1590 flex-direction: column;
1591 align-items: stretch;
1592 }
1593 body.chat.chat-only-mode #chat-input-area {
1594 /* would like to pin this to the top so that it stays in place when
1595 scrolling, but doing so causes #chat-messages-wrapper to scroll
1596 behind it visibly, which is really ugly. Only current workaround is
1597 to force an opaque background color on this element, but that's not
1598 skin-friendly. */
1599 /*position: fixed;
1600 top: 0;
1601 left: 0;*/
1602 padding: 0.5em 1em;
1603 }
1604 body.chat.chat-only-mode #chat-messages-wrapper {
1605 }
1606
1607 body.chat #chat-input-area {
1608 display: flex;
1609 flex-direction: column;
1610 border-bottom: 1px solid black;
1611 margin-bottom: 0.5em;
1612 }
1613 body.chat #chat-input-line {
1614 display: flex;
1615 flex-direction: row;
1616 margin-bottom: 0.25em;
1617 align-items: center;
1618 }
1619 body.chat #chat-input-line > input[type=submit] {
1620 flex: 1 5 auto;
1621 max-width: 6em;
1622 margin-right: 1em;
1623 }
1624 body.chat #chat-input-line > input[type=text] {
1625 flex: 5 1 auto;
1626 }
1627 body.chat #chat-input-file-area {
1628 display: flex;
1629 flex-direction: row;
1630 align-items: center;
1631 flex-wrap: wrap;
1632 }
1633 body.chat #chat-input-file-area > .file-selection-wrapper {
1634 align-self: flex-start;
1635 margin-right: 0.5em;
1636 flex: 0 1 auto;
1637 padding: 0.25em 0.25em 0.25em 0;
1638 }
1639 body.chat #chat-input-file-area .file-selection-wrapper > * {
1640 vertical-align: middle;
1641 margin: 0;
1642 }
1643 body.chat #chat-input-file {
1644 border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
1645 border-radius: 0.25em;
1646 padding: 0.25em;
1647 }
1648 body.chat #chat-input-file > input {
1649 flex: 1 0 auto;
1650 }
1651 body.chat #chat-input-file.dragover {
1652 border: 1px dashed green;
1653 }
1654 body.chat #chat-drop-details {
1655 flex: 0 1 auto;
1656 padding: 0.5em 1em;
1657 margin-left: 0.5em;
1658 white-space: pre;
1659 font-family: monospace;
1660 max-width: 50%;
1661 }
1662

Keyboard Shortcuts

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