Fossil SCM

Removed the cumbersome and platform-dependent file selection widget from view and now proxy its activation via a new toolbar button. Saves space and looks nicer.

stephan 2021-10-01 17:40 UTC chat-input-rework
Commit 2b07b66d5942c69844c43710abc960f77dd8f0bc7e2dc51be76bc0bc33851624
+4 -7
--- src/chat.c
+++ src/chat.c
@@ -164,23 +164,20 @@
164164
@ data-placeholder="%h(zInputPlaceholder0)" \
165165
@ class=""></div>
166166
@ <div id='chat-edit-buttons'>
167167
@ <button id="chat-preview-button" \
168168
@ title="Preview message (Shift-Enter)">&#128065;</button>
169
+ @ <button id="chat-message-attach" \
170
+ @ title="Attach file to message">&#128206;</button>
169171
@ <button id="chat-settings-button" \
170172
@ title="Configure chat">&#9881;</button>
171173
@ <button id="chat-message-submit" \
172174
@ title="Send message (Ctrl-Enter)">&#128228;</button>
173175
@ </div>
174176
@ </div>
175
- @ <div id='chat-input-file-area' class='hidden'>
176
- @ <div class='file-selection-wrapper'>
177
- @ <div class='help-buttonlet'>
178
- @ Select a file to upload, drag/drop a file into this spot,
179
- @ or paste an image from the clipboard if supported by
180
- @ your environment.
181
- @ </div>
177
+ @ <div id='chat-input-file-area'>
178
+ @ <div class='file-selection-wrapper hidden'>
182179
@ <input type="file" name="file" id="chat-input-file">
183180
@ </div>
184181
@ <div id="chat-drop-details"></div>
185182
@ </div>
186183
@ </div>
187184
--- src/chat.c
+++ src/chat.c
@@ -164,23 +164,20 @@
164 @ data-placeholder="%h(zInputPlaceholder0)" \
165 @ class=""></div>
166 @ <div id='chat-edit-buttons'>
167 @ <button id="chat-preview-button" \
168 @ title="Preview message (Shift-Enter)">&#128065;</button>
 
 
169 @ <button id="chat-settings-button" \
170 @ title="Configure chat">&#9881;</button>
171 @ <button id="chat-message-submit" \
172 @ title="Send message (Ctrl-Enter)">&#128228;</button>
173 @ </div>
174 @ </div>
175 @ <div id='chat-input-file-area' class='hidden'>
176 @ <div class='file-selection-wrapper'>
177 @ <div class='help-buttonlet'>
178 @ Select a file to upload, drag/drop a file into this spot,
179 @ or paste an image from the clipboard if supported by
180 @ your environment.
181 @ </div>
182 @ <input type="file" name="file" id="chat-input-file">
183 @ </div>
184 @ <div id="chat-drop-details"></div>
185 @ </div>
186 @ </div>
187
--- src/chat.c
+++ src/chat.c
@@ -164,23 +164,20 @@
164 @ data-placeholder="%h(zInputPlaceholder0)" \
165 @ class=""></div>
166 @ <div id='chat-edit-buttons'>
167 @ <button id="chat-preview-button" \
168 @ title="Preview message (Shift-Enter)">&#128065;</button>
169 @ <button id="chat-message-attach" \
170 @ title="Attach file to message">&#128206;</button>
171 @ <button id="chat-settings-button" \
172 @ title="Configure chat">&#9881;</button>
173 @ <button id="chat-message-submit" \
174 @ title="Send message (Ctrl-Enter)">&#128228;</button>
175 @ </div>
176 @ </div>
177 @ <div id='chat-input-file-area'>
178 @ <div class='file-selection-wrapper hidden'>
 
 
 
 
 
179 @ <input type="file" name="file" id="chat-input-file">
180 @ </div>
181 @ <div id="chat-drop-details"></div>
182 @ </div>
183 @ </div>
184
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -127,10 +127,11 @@
127127
inputWrapper: E1("#chat-input-area"),
128128
inputLine: E1('#chat-input-line'),
129129
fileSelectWrapper: E1('#chat-input-file-area'),
130130
viewMessages: E1('#chat-messages-wrapper'),
131131
btnSubmit: E1('#chat-message-submit'),
132
+ btnAttach: E1('#chat-message-attach'),
132133
inputField: E1('#chat-input-field'),
133134
inputFile: E1('#chat-input-file'),
134135
contentDiv: E1('div.content'),
135136
viewConfig: E1('#chat-config'),
136137
viewPreview: E1('#chat-preview'),
@@ -381,12 +382,11 @@
381382
"edit-compact-mode": true,
382383
"monospace-messages": true,
383384
"chat-only-mode": false,
384385
"audible-alert": true,
385386
"active-user-list": false,
386
- "active-user-list-timestamps": false,
387
- "hide-attachment-widget": false
387
+ "active-user-list-timestamps": false
388388
}
389389
},
390390
/** Plays a new-message notification sound IF the audible-alert
391391
setting is true, else this is a no-op. Returns this.
392392
*/
@@ -1036,11 +1036,11 @@
10361036
}/*_handleLegendClicked()*/
10371037
};
10381038
return cf;
10391039
})()/*MessageWidget*/;
10401040
1041
- const BlobXferState = (function(){/*drag/drop bits...*/
1041
+ const BlobXferState = (function(){
10421042
/* State for paste and drag/drop */
10431043
const bxs = {
10441044
dropDetails: document.querySelector('#chat-drop-details'),
10451045
blob: undefined,
10461046
clear: function(){
@@ -1059,22 +1059,22 @@
10591059
D.clearElement(dd);
10601060
if(!blob){
10611061
Chat.e.inputFile.value = '';
10621062
return;
10631063
}
1064
- D.append(dd, "Name: ", blob.name,
1064
+ D.append(dd, "Attached: ", blob.name,
10651065
D.br(), "Size: ",blob.size);
1066
+ const btn = D.button("Cancel");
1067
+ D.append(dd, D.br(), btn);
1068
+ btn.addEventListener('click', ()=>updateDropZoneContent(), false);
10661069
if(blob.type && (blob.type.startsWith("image/") || blob.type==='BITMAP')){
10671070
const img = D.img();
10681071
D.append(dd, D.br(), img);
10691072
const reader = new FileReader();
10701073
reader.onload = (e)=>img.setAttribute('src', e.target.result);
10711074
reader.readAsDataURL(blob);
10721075
}
1073
- const btn = D.button("Cancel");
1074
- D.append(dd, D.br(), btn);
1075
- btn.addEventListener('click', ()=>updateDropZoneContent(), false);
10761076
};
10771077
Chat.e.inputFile.addEventListener('change', function(ev){
10781078
updateDropZoneContent(this.files && this.files[0] ? this.files[0] : undefined)
10791079
});
10801080
/* Handle image paste from clipboard. TODO: figure out how we can
@@ -1107,53 +1107,27 @@
11071107
ev.preventDefault();
11081108
return false;
11091109
};
11101110
Chat.e.inputField.addEventListener('paste', onPastePlainText, false);
11111111
}
1112
- /* Add help button for drag/drop/paste zone */
1113
- Chat.e.inputFile.parentNode.insertBefore(
1114
- F.helpButtonlets.create(
1115
- Chat.e.fileSelectWrapper.querySelector('.help-buttonlet')
1116
- ), Chat.e.inputFile
1117
- );
1118
- ////////////////////////////////////////////////////////////
1119
- // File drag/drop visual notification.
1120
- const dropHighlight = Chat.e.inputFile /* target zone */;
1121
- const dropEvents = {
1122
- drop: function(ev){
1123
- D.removeClass(dropHighlight, 'dragover');
1124
- },
1125
- dragenter: function(ev){
1126
- ev.preventDefault();
1127
- ev.dataTransfer.dropEffect = "copy";
1128
- D.addClass(dropHighlight, 'dragover');
1129
- return false;
1130
- },
1131
- dragleave: function(ev){
1132
- D.removeClass(dropHighlight, 'dragover');
1133
- },
1134
- dragend: function(ev){
1135
- D.removeClass(dropHighlight, 'dragover');
1136
- }
1137
- };
11381112
const noDragDropEvents = function(ev){
11391113
/* contenteditable tries to do its own thing with dropped data,
11401114
which is not compatible with how we use it, so... */
11411115
ev.dataTransfer.effectAllowed = 'none';
11421116
ev.dataTransfer.dropEffect = 'none';
11431117
ev.preventDefault();
11441118
ev.stopPropagation();
11451119
return false;
11461120
};
1147
- Object.keys(dropEvents).forEach(
1121
+
1122
+ ['drop','dragenter','dragleave','dragend'].forEach(
11481123
(k)=>{
1149
- Chat.e.inputFile.addEventListener(k, dropEvents[k], true);
11501124
Chat.inputElement().addEventListener(k, noDragDropEvents, false);
11511125
}
11521126
);
11531127
return bxs;
1154
- })()/*drag/drop*/;
1128
+ })()/*drag/drop/paste*/;
11551129
11561130
const tzOffsetToString = function(off){
11571131
const hours = Math.round(off/60), min = Math.round(off % 30);
11581132
return ''+(hours + (min ? '.5' : ''));
11591133
};
@@ -1286,10 +1260,12 @@
12861260
Chat.e.btnSubmit.addEventListener('click',(e)=>{
12871261
e.preventDefault();
12881262
Chat.submitMessage();
12891263
return false;
12901264
});
1265
+ Chat.e.btnAttach.addEventListener(
1266
+ 'click', ()=>Chat.e.inputFile.click(), false);
12911267
12921268
(function(){/*Set up #chat-settings-button and related bits */
12931269
if(window.innerWidth<window.innerHeight){
12941270
// Must be set up before config view is...
12951271
/* Alignment of 'my' messages: right alignment is conventional
@@ -1399,16 +1375,11 @@
13991375
},{
14001376
label: "Timestamps in active users list",
14011377
hint: "Whether to show last-message timestamps.",
14021378
boolValue: 'active-user-list-timestamps'
14031379
},
1404
- namedOptions.activeUsers,{
1405
- label: "Hide file attachment widget",
1406
- boolValue: "hide-attachment-widget",
1407
- hint: "Hides the file attachment widget, gaining more "+
1408
- "screen space for messages."
1409
- }];
1380
+ namedOptions.activeUsers];
14101381
14111382
/** Set up selection list of notification sounds. */
14121383
if(1){
14131384
const selectSound = D.select();
14141385
D.option(selectSound, "", "(no audio)");
@@ -1530,15 +1501,10 @@
15301501
Chat.settings.addListener('edit-compact-mode',function(s){
15311502
Chat.e.inputLine.classList[
15321503
s.value ? 'add' : 'remove'
15331504
]('compact');
15341505
});
1535
- Chat.settings.addListener('hide-attachment-widget',function(s){
1536
- Chat.e.fileSelectWrapper.classList[
1537
- s.value ? 'add' : 'remove'
1538
- ]('hidden');
1539
- });
15401506
Chat.settings.addListener('edit-ctrl-send',function(s){
15411507
const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
15421508
const eInput = Chat.inputElement();
15431509
eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
15441510
Chat.e.btnSubmit.title = label;
15451511
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -127,10 +127,11 @@
127 inputWrapper: E1("#chat-input-area"),
128 inputLine: E1('#chat-input-line'),
129 fileSelectWrapper: E1('#chat-input-file-area'),
130 viewMessages: E1('#chat-messages-wrapper'),
131 btnSubmit: E1('#chat-message-submit'),
 
132 inputField: E1('#chat-input-field'),
133 inputFile: E1('#chat-input-file'),
134 contentDiv: E1('div.content'),
135 viewConfig: E1('#chat-config'),
136 viewPreview: E1('#chat-preview'),
@@ -381,12 +382,11 @@
381 "edit-compact-mode": true,
382 "monospace-messages": true,
383 "chat-only-mode": false,
384 "audible-alert": true,
385 "active-user-list": false,
386 "active-user-list-timestamps": false,
387 "hide-attachment-widget": false
388 }
389 },
390 /** Plays a new-message notification sound IF the audible-alert
391 setting is true, else this is a no-op. Returns this.
392 */
@@ -1036,11 +1036,11 @@
1036 }/*_handleLegendClicked()*/
1037 };
1038 return cf;
1039 })()/*MessageWidget*/;
1040
1041 const BlobXferState = (function(){/*drag/drop bits...*/
1042 /* State for paste and drag/drop */
1043 const bxs = {
1044 dropDetails: document.querySelector('#chat-drop-details'),
1045 blob: undefined,
1046 clear: function(){
@@ -1059,22 +1059,22 @@
1059 D.clearElement(dd);
1060 if(!blob){
1061 Chat.e.inputFile.value = '';
1062 return;
1063 }
1064 D.append(dd, "Name: ", blob.name,
1065 D.br(), "Size: ",blob.size);
 
 
 
1066 if(blob.type && (blob.type.startsWith("image/") || blob.type==='BITMAP')){
1067 const img = D.img();
1068 D.append(dd, D.br(), img);
1069 const reader = new FileReader();
1070 reader.onload = (e)=>img.setAttribute('src', e.target.result);
1071 reader.readAsDataURL(blob);
1072 }
1073 const btn = D.button("Cancel");
1074 D.append(dd, D.br(), btn);
1075 btn.addEventListener('click', ()=>updateDropZoneContent(), false);
1076 };
1077 Chat.e.inputFile.addEventListener('change', function(ev){
1078 updateDropZoneContent(this.files && this.files[0] ? this.files[0] : undefined)
1079 });
1080 /* Handle image paste from clipboard. TODO: figure out how we can
@@ -1107,53 +1107,27 @@
1107 ev.preventDefault();
1108 return false;
1109 };
1110 Chat.e.inputField.addEventListener('paste', onPastePlainText, false);
1111 }
1112 /* Add help button for drag/drop/paste zone */
1113 Chat.e.inputFile.parentNode.insertBefore(
1114 F.helpButtonlets.create(
1115 Chat.e.fileSelectWrapper.querySelector('.help-buttonlet')
1116 ), Chat.e.inputFile
1117 );
1118 ////////////////////////////////////////////////////////////
1119 // File drag/drop visual notification.
1120 const dropHighlight = Chat.e.inputFile /* target zone */;
1121 const dropEvents = {
1122 drop: function(ev){
1123 D.removeClass(dropHighlight, 'dragover');
1124 },
1125 dragenter: function(ev){
1126 ev.preventDefault();
1127 ev.dataTransfer.dropEffect = "copy";
1128 D.addClass(dropHighlight, 'dragover');
1129 return false;
1130 },
1131 dragleave: function(ev){
1132 D.removeClass(dropHighlight, 'dragover');
1133 },
1134 dragend: function(ev){
1135 D.removeClass(dropHighlight, 'dragover');
1136 }
1137 };
1138 const noDragDropEvents = function(ev){
1139 /* contenteditable tries to do its own thing with dropped data,
1140 which is not compatible with how we use it, so... */
1141 ev.dataTransfer.effectAllowed = 'none';
1142 ev.dataTransfer.dropEffect = 'none';
1143 ev.preventDefault();
1144 ev.stopPropagation();
1145 return false;
1146 };
1147 Object.keys(dropEvents).forEach(
 
1148 (k)=>{
1149 Chat.e.inputFile.addEventListener(k, dropEvents[k], true);
1150 Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1151 }
1152 );
1153 return bxs;
1154 })()/*drag/drop*/;
1155
1156 const tzOffsetToString = function(off){
1157 const hours = Math.round(off/60), min = Math.round(off % 30);
1158 return ''+(hours + (min ? '.5' : ''));
1159 };
@@ -1286,10 +1260,12 @@
1286 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1287 e.preventDefault();
1288 Chat.submitMessage();
1289 return false;
1290 });
 
 
1291
1292 (function(){/*Set up #chat-settings-button and related bits */
1293 if(window.innerWidth<window.innerHeight){
1294 // Must be set up before config view is...
1295 /* Alignment of 'my' messages: right alignment is conventional
@@ -1399,16 +1375,11 @@
1399 },{
1400 label: "Timestamps in active users list",
1401 hint: "Whether to show last-message timestamps.",
1402 boolValue: 'active-user-list-timestamps'
1403 },
1404 namedOptions.activeUsers,{
1405 label: "Hide file attachment widget",
1406 boolValue: "hide-attachment-widget",
1407 hint: "Hides the file attachment widget, gaining more "+
1408 "screen space for messages."
1409 }];
1410
1411 /** Set up selection list of notification sounds. */
1412 if(1){
1413 const selectSound = D.select();
1414 D.option(selectSound, "", "(no audio)");
@@ -1530,15 +1501,10 @@
1530 Chat.settings.addListener('edit-compact-mode',function(s){
1531 Chat.e.inputLine.classList[
1532 s.value ? 'add' : 'remove'
1533 ]('compact');
1534 });
1535 Chat.settings.addListener('hide-attachment-widget',function(s){
1536 Chat.e.fileSelectWrapper.classList[
1537 s.value ? 'add' : 'remove'
1538 ]('hidden');
1539 });
1540 Chat.settings.addListener('edit-ctrl-send',function(s){
1541 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1542 const eInput = Chat.inputElement();
1543 eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
1544 Chat.e.btnSubmit.title = label;
1545
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -127,10 +127,11 @@
127 inputWrapper: E1("#chat-input-area"),
128 inputLine: E1('#chat-input-line'),
129 fileSelectWrapper: E1('#chat-input-file-area'),
130 viewMessages: E1('#chat-messages-wrapper'),
131 btnSubmit: E1('#chat-message-submit'),
132 btnAttach: E1('#chat-message-attach'),
133 inputField: E1('#chat-input-field'),
134 inputFile: E1('#chat-input-file'),
135 contentDiv: E1('div.content'),
136 viewConfig: E1('#chat-config'),
137 viewPreview: E1('#chat-preview'),
@@ -381,12 +382,11 @@
382 "edit-compact-mode": true,
383 "monospace-messages": true,
384 "chat-only-mode": false,
385 "audible-alert": true,
386 "active-user-list": false,
387 "active-user-list-timestamps": false
 
388 }
389 },
390 /** Plays a new-message notification sound IF the audible-alert
391 setting is true, else this is a no-op. Returns this.
392 */
@@ -1036,11 +1036,11 @@
1036 }/*_handleLegendClicked()*/
1037 };
1038 return cf;
1039 })()/*MessageWidget*/;
1040
1041 const BlobXferState = (function(){
1042 /* State for paste and drag/drop */
1043 const bxs = {
1044 dropDetails: document.querySelector('#chat-drop-details'),
1045 blob: undefined,
1046 clear: function(){
@@ -1059,22 +1059,22 @@
1059 D.clearElement(dd);
1060 if(!blob){
1061 Chat.e.inputFile.value = '';
1062 return;
1063 }
1064 D.append(dd, "Attached: ", blob.name,
1065 D.br(), "Size: ",blob.size);
1066 const btn = D.button("Cancel");
1067 D.append(dd, D.br(), btn);
1068 btn.addEventListener('click', ()=>updateDropZoneContent(), false);
1069 if(blob.type && (blob.type.startsWith("image/") || blob.type==='BITMAP')){
1070 const img = D.img();
1071 D.append(dd, D.br(), img);
1072 const reader = new FileReader();
1073 reader.onload = (e)=>img.setAttribute('src', e.target.result);
1074 reader.readAsDataURL(blob);
1075 }
 
 
 
1076 };
1077 Chat.e.inputFile.addEventListener('change', function(ev){
1078 updateDropZoneContent(this.files && this.files[0] ? this.files[0] : undefined)
1079 });
1080 /* Handle image paste from clipboard. TODO: figure out how we can
@@ -1107,53 +1107,27 @@
1107 ev.preventDefault();
1108 return false;
1109 };
1110 Chat.e.inputField.addEventListener('paste', onPastePlainText, false);
1111 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1112 const noDragDropEvents = function(ev){
1113 /* contenteditable tries to do its own thing with dropped data,
1114 which is not compatible with how we use it, so... */
1115 ev.dataTransfer.effectAllowed = 'none';
1116 ev.dataTransfer.dropEffect = 'none';
1117 ev.preventDefault();
1118 ev.stopPropagation();
1119 return false;
1120 };
1121
1122 ['drop','dragenter','dragleave','dragend'].forEach(
1123 (k)=>{
 
1124 Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1125 }
1126 );
1127 return bxs;
1128 })()/*drag/drop/paste*/;
1129
1130 const tzOffsetToString = function(off){
1131 const hours = Math.round(off/60), min = Math.round(off % 30);
1132 return ''+(hours + (min ? '.5' : ''));
1133 };
@@ -1286,10 +1260,12 @@
1260 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1261 e.preventDefault();
1262 Chat.submitMessage();
1263 return false;
1264 });
1265 Chat.e.btnAttach.addEventListener(
1266 'click', ()=>Chat.e.inputFile.click(), false);
1267
1268 (function(){/*Set up #chat-settings-button and related bits */
1269 if(window.innerWidth<window.innerHeight){
1270 // Must be set up before config view is...
1271 /* Alignment of 'my' messages: right alignment is conventional
@@ -1399,16 +1375,11 @@
1375 },{
1376 label: "Timestamps in active users list",
1377 hint: "Whether to show last-message timestamps.",
1378 boolValue: 'active-user-list-timestamps'
1379 },
1380 namedOptions.activeUsers];
 
 
 
 
 
1381
1382 /** Set up selection list of notification sounds. */
1383 if(1){
1384 const selectSound = D.select();
1385 D.option(selectSound, "", "(no audio)");
@@ -1530,15 +1501,10 @@
1501 Chat.settings.addListener('edit-compact-mode',function(s){
1502 Chat.e.inputLine.classList[
1503 s.value ? 'add' : 'remove'
1504 ]('compact');
1505 });
 
 
 
 
 
1506 Chat.settings.addListener('edit-ctrl-send',function(s){
1507 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1508 const eInput = Chat.inputElement();
1509 eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
1510 Chat.e.btnSubmit.title = label;
1511
--- src/style.chat.css
+++ src/style.chat.css
@@ -266,11 +266,11 @@
266266
min-width: 4ex;
267267
}
268268
body.chat #chat-input-line:not(.compact) #chat-edit-buttons > * {
269269
max-width: 6ex;
270270
min-width: 6ex;
271
- min-height: 6ex;
271
+ min-height: 5ex;
272272
max-height: 6ex;
273273
margin: 0.125em;
274274
}
275275
276276
body.chat #chat-input-line:not(.compact) #chat-input-field {
@@ -325,25 +325,21 @@
325325
}
326326
/* Widget holding the file selection control and preview */
327327
body.chat #chat-input-file-area {
328328
display: flex;
329329
flex-direction: row;
330
+ margin: 0;
331
+ justify-content: flex-end;
330332
align-items: center;
331
- flex-wrap: wrap;
332
- margin: 0.25em 0 0 0 /* avoid nudging input area */;
333333
}
334334
body.chat #chat-input-file-area > .file-selection-wrapper {
335335
align-self: flex-start;
336336
margin-right: 0.5em;
337337
flex: 0 1 auto;
338338
padding: 0.25em 0.5em;
339339
white-space: nowrap;
340340
}
341
-body.chat #chat-input-file-area .file-selection-wrapper > * {
342
- vertical-align: middle;
343
- margin: 0;
344
-}
345341
body.chat #chat-input-file {
346342
border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
347343
border-radius: 0.25em;
348344
padding: 0.25em;
349345
}
@@ -354,11 +350,10 @@
354350
body.chat #chat-input-file.dragover {
355351
border: 1px dashed green;
356352
}
357353
/* Widget holding the details of a selected/dropped file/image. */
358354
body.chat #chat-drop-details {
359
- flex: 0 1 auto;
360355
padding: 0.5em 1em;
361356
margin-left: 0.5em;
362357
white-space: pre;
363358
font-family: monospace;
364359
}
365360
--- src/style.chat.css
+++ src/style.chat.css
@@ -266,11 +266,11 @@
266 min-width: 4ex;
267 }
268 body.chat #chat-input-line:not(.compact) #chat-edit-buttons > * {
269 max-width: 6ex;
270 min-width: 6ex;
271 min-height: 6ex;
272 max-height: 6ex;
273 margin: 0.125em;
274 }
275
276 body.chat #chat-input-line:not(.compact) #chat-input-field {
@@ -325,25 +325,21 @@
325 }
326 /* Widget holding the file selection control and preview */
327 body.chat #chat-input-file-area {
328 display: flex;
329 flex-direction: row;
 
 
330 align-items: center;
331 flex-wrap: wrap;
332 margin: 0.25em 0 0 0 /* avoid nudging input area */;
333 }
334 body.chat #chat-input-file-area > .file-selection-wrapper {
335 align-self: flex-start;
336 margin-right: 0.5em;
337 flex: 0 1 auto;
338 padding: 0.25em 0.5em;
339 white-space: nowrap;
340 }
341 body.chat #chat-input-file-area .file-selection-wrapper > * {
342 vertical-align: middle;
343 margin: 0;
344 }
345 body.chat #chat-input-file {
346 border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
347 border-radius: 0.25em;
348 padding: 0.25em;
349 }
@@ -354,11 +350,10 @@
354 body.chat #chat-input-file.dragover {
355 border: 1px dashed green;
356 }
357 /* Widget holding the details of a selected/dropped file/image. */
358 body.chat #chat-drop-details {
359 flex: 0 1 auto;
360 padding: 0.5em 1em;
361 margin-left: 0.5em;
362 white-space: pre;
363 font-family: monospace;
364 }
365
--- src/style.chat.css
+++ src/style.chat.css
@@ -266,11 +266,11 @@
266 min-width: 4ex;
267 }
268 body.chat #chat-input-line:not(.compact) #chat-edit-buttons > * {
269 max-width: 6ex;
270 min-width: 6ex;
271 min-height: 5ex;
272 max-height: 6ex;
273 margin: 0.125em;
274 }
275
276 body.chat #chat-input-line:not(.compact) #chat-input-field {
@@ -325,25 +325,21 @@
325 }
326 /* Widget holding the file selection control and preview */
327 body.chat #chat-input-file-area {
328 display: flex;
329 flex-direction: row;
330 margin: 0;
331 justify-content: flex-end;
332 align-items: center;
 
 
333 }
334 body.chat #chat-input-file-area > .file-selection-wrapper {
335 align-self: flex-start;
336 margin-right: 0.5em;
337 flex: 0 1 auto;
338 padding: 0.25em 0.5em;
339 white-space: nowrap;
340 }
 
 
 
 
341 body.chat #chat-input-file {
342 border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
343 border-radius: 0.25em;
344 padding: 0.25em;
345 }
@@ -354,11 +350,10 @@
350 body.chat #chat-input-file.dragover {
351 border: 1px dashed green;
352 }
353 /* Widget holding the details of a selected/dropped file/image. */
354 body.chat #chat-drop-details {
 
355 padding: 0.5em 1em;
356 margin-left: 0.5em;
357 white-space: pre;
358 font-family: monospace;
359 }
360

Keyboard Shortcuts

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