Fossil SCM

chat: changed layout from table-based to one fieldset per row of chat (fieldset rather than a custom construct because browsers have special support for placement of the LEGEND tag which we cannot easily reproduce in other element). The overall look is approximately the same, but saves some space.

stephan 2020-12-22 12:02 chatroom-dev
Commit a0ebe0ead1fa237c2ded9714650d65167a288a65732a61938190892ce7d81bd2
1 file changed +75 -41
+75 -41
--- tools/chat.tcl
+++ tools/chat.tcl
@@ -48,40 +48,19 @@
4848
<span>File:</span>
4949
<input type="file" name="file">
5050
</div>
5151
</div>
5252
</form>
53
-
5453
<hr>
55
- <table id="dialog">
56
- </table>
57
- </div>
54
+ <span id='message-inject-point'></span>
55
+
56
+ </div><!-- .fossil-doc -->
5857
<hr>
5958
<p>
6059
<a href="chat/env">CGI environment</a> |
6160
<a href="chat/self">Wapp script</a>
6261
<style>
63
-.chat-message {/*style common to .chat-mx and .chat-ms*/
64
- padding: 0.5em;
65
- border-radius: 0.5em;
66
- border: 1px solid black;
67
- box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
68
- /* Bob Ross might approve of... */
69
- /*
70
- background-image: linear-gradient(45deg, #FFC107 0%, #ff8b5f 100%);
71
- border-bottom: solid 3px #c58668;
72
- */
73
-}
74
-.chat-mx {
75
- float: left;
76
- margin-right: 3em;
77
-}
78
-.chat-ms {
79
- float: right;
80
- margin-left: 3em;
81
- background-color: #d2dde1;
82
-}
8362
\#dialog {
8463
width: 97%;
8564
}
8665
\#chat-input-area {
8766
width: 100%;
@@ -110,10 +89,57 @@
11089
flex: 1 0 auto;
11190
}
11291
span.at-name { /* for @USERNAME references */
11392
text-decoration: underline;
11493
font-weight: bold;
94
+}
95
+/* A wrapper for a single single message (one row of the UI) */
96
+.message-row {
97
+ margin-bottom: 0.5em;
98
+ border: none;
99
+ display: flex;
100
+ flex-direction: row;
101
+ justify-content: flex-start;
102
+ /*border: 1px solid rgba(0,0,0,0.2);
103
+ border-radius: 0.25em;
104
+ box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);*/
105
+ border: none;
106
+}
107
+/* Rows for the current user have the .user-is-me CSS class
108
+ and get right-aligned. */
109
+.message-row.user-is-me {
110
+ justify-content: flex-end;
111
+ /*background-color: #d2dde1;*/
112
+}
113
+/* The content area of a message (the body element of a FIELDSET) */
114
+.message-content {
115
+ display: inline-block;
116
+ border-radius: 0.25em;
117
+ border: 1px solid rgba(0,0,0,0.2);
118
+ box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
119
+ padding: 0.25em 1em;
120
+ margin-top: -0.75em;
121
+}
122
+.message-row.user-is-me .message-content {
123
+ background-color: #d2dde1;
124
+}
125
+/* User name for the post (a LEGEND element) */
126
+.message-row .message-user {
127
+ background: inherit;
128
+ border-radius: 0.25em 0.25em 0 0;
129
+ padding: 0 0.5em;
130
+ /*text-align: left; Firefox requires the 'align' attribute */
131
+ margin-left: 0.25em;
132
+ padding: 0 0.5em 0em 0.5em;
133
+ margin-bottom: 0.4em;
134
+ background-color: #d2dde1;
135
+}
136
+/* Reposition "my" posts to the right */
137
+.message-row.user-is-me .message-user {
138
+ /*text-align: right; Firefox requires the 'align' attribute */
139
+ margin-left: 0;
140
+ margin-right: 0.25em;
115141
}
116142
</style>
117143
}
118144
set nonce [wapp-param FOSSIL_NONCE]
119145
set submiturl [wapp-param SCRIPT_NAME]/send
@@ -213,27 +239,40 @@
213239
span.appendChild(e);
214240
});
215241
//console.debug("span =",span.innerHTML);
216242
return span;
217243
}/*end messageToDOM()*/;
244
+ const injectMessage = function f(e){
245
+ if(!f.injectPoint){
246
+ f.injectPoint = document.querySelector('#message-inject-point');
247
+ }
248
+ f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
249
+ };
218250
function newcontent(jx){
219
- var tab = document.getElementById("dialog");
220251
var i;
221252
for(i=0; i<jx.msgs.length; ++i){
222253
let m = jx.msgs[i];
223
- let r = document.createElement("tr");
254
+ let row = document.createElement("fieldset");
224255
if( m.msgid>mxMsg ) mxMsg = m.msgid;
225
- tab.insertBefore(r, tab.childNodes[0]);
226
- let td = document.createElement("td");
227
- r.appendChild(td);
228
- if( m.xfrom!=_me ){
229
- td.appendChild(document.createTextNode(m.xfrom));
230
- }
231
- td = document.createElement("td");
232
- r.appendChild(td);
233
- let span = document.createElement("span");
234
- td.appendChild(span);
256
+ row.classList.add('message-row');
257
+ injectMessage(row);
258
+ const eWho = document.createElement('legend');
259
+ eWho.setAttribute('align', (m.xfrom===_me ? 'right' : 'left'));
260
+ row.appendChild(eWho);
261
+ eWho.classList.add('message-user');
262
+ let whoName;
263
+ if( m.xfrom===_me ){
264
+ whoName = 'me';
265
+ //eWho.classList.add('user-is-me');
266
+ row.classList.add('user-is-me');
267
+ }else{
268
+ whoName = m.xfrom;
269
+ }
270
+ eWho.append(document.createTextNode(whoName));
271
+ let span = document.createElement("div");
272
+ span.classList.add('message-content');
273
+ row.appendChild(span);
235274
if( m.fsize>0 ){
236275
if( m.fmime && m.fmime.startsWith("image/") ){
237276
let img = document.createElement("img");
238277
img.src = "%string($downloadurl)/" + m.msgid;
239278
span.appendChild(img);
@@ -255,15 +294,10 @@
255294
if( m.xfrom!=_me ){
256295
span.classList.add('chat-mx');
257296
}else{
258297
span.classList.add('chat-ms');
259298
}
260
- td = document.createElement("td");
261
- r.appendChild(td);
262
- if( m.xfrom==_me ){
263
- td.appendChild(document.createTextNode('me'))
264
- }
265299
}
266300
}
267301
async function poll(){
268302
if(poll.running) return;
269303
poll.running = true;
270304
--- tools/chat.tcl
+++ tools/chat.tcl
@@ -48,40 +48,19 @@
48 <span>File:</span>
49 <input type="file" name="file">
50 </div>
51 </div>
52 </form>
53
54 <hr>
55 <table id="dialog">
56 </table>
57 </div>
58 <hr>
59 <p>
60 <a href="chat/env">CGI environment</a> |
61 <a href="chat/self">Wapp script</a>
62 <style>
63 .chat-message {/*style common to .chat-mx and .chat-ms*/
64 padding: 0.5em;
65 border-radius: 0.5em;
66 border: 1px solid black;
67 box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
68 /* Bob Ross might approve of... */
69 /*
70 background-image: linear-gradient(45deg, #FFC107 0%, #ff8b5f 100%);
71 border-bottom: solid 3px #c58668;
72 */
73 }
74 .chat-mx {
75 float: left;
76 margin-right: 3em;
77 }
78 .chat-ms {
79 float: right;
80 margin-left: 3em;
81 background-color: #d2dde1;
82 }
83 \#dialog {
84 width: 97%;
85 }
86 \#chat-input-area {
87 width: 100%;
@@ -110,10 +89,57 @@
110 flex: 1 0 auto;
111 }
112 span.at-name { /* for @USERNAME references */
113 text-decoration: underline;
114 font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115 }
116 </style>
117 }
118 set nonce [wapp-param FOSSIL_NONCE]
119 set submiturl [wapp-param SCRIPT_NAME]/send
@@ -213,27 +239,40 @@
213 span.appendChild(e);
214 });
215 //console.debug("span =",span.innerHTML);
216 return span;
217 }/*end messageToDOM()*/;
 
 
 
 
 
 
218 function newcontent(jx){
219 var tab = document.getElementById("dialog");
220 var i;
221 for(i=0; i<jx.msgs.length; ++i){
222 let m = jx.msgs[i];
223 let r = document.createElement("tr");
224 if( m.msgid>mxMsg ) mxMsg = m.msgid;
225 tab.insertBefore(r, tab.childNodes[0]);
226 let td = document.createElement("td");
227 r.appendChild(td);
228 if( m.xfrom!=_me ){
229 td.appendChild(document.createTextNode(m.xfrom));
230 }
231 td = document.createElement("td");
232 r.appendChild(td);
233 let span = document.createElement("span");
234 td.appendChild(span);
 
 
 
 
 
 
 
 
235 if( m.fsize>0 ){
236 if( m.fmime && m.fmime.startsWith("image/") ){
237 let img = document.createElement("img");
238 img.src = "%string($downloadurl)/" + m.msgid;
239 span.appendChild(img);
@@ -255,15 +294,10 @@
255 if( m.xfrom!=_me ){
256 span.classList.add('chat-mx');
257 }else{
258 span.classList.add('chat-ms');
259 }
260 td = document.createElement("td");
261 r.appendChild(td);
262 if( m.xfrom==_me ){
263 td.appendChild(document.createTextNode('me'))
264 }
265 }
266 }
267 async function poll(){
268 if(poll.running) return;
269 poll.running = true;
270
--- tools/chat.tcl
+++ tools/chat.tcl
@@ -48,40 +48,19 @@
48 <span>File:</span>
49 <input type="file" name="file">
50 </div>
51 </div>
52 </form>
 
53 <hr>
54 <span id='message-inject-point'></span>
55
56 </div><!-- .fossil-doc -->
57 <hr>
58 <p>
59 <a href="chat/env">CGI environment</a> |
60 <a href="chat/self">Wapp script</a>
61 <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62 \#dialog {
63 width: 97%;
64 }
65 \#chat-input-area {
66 width: 100%;
@@ -110,10 +89,57 @@
89 flex: 1 0 auto;
90 }
91 span.at-name { /* for @USERNAME references */
92 text-decoration: underline;
93 font-weight: bold;
94 }
95 /* A wrapper for a single single message (one row of the UI) */
96 .message-row {
97 margin-bottom: 0.5em;
98 border: none;
99 display: flex;
100 flex-direction: row;
101 justify-content: flex-start;
102 /*border: 1px solid rgba(0,0,0,0.2);
103 border-radius: 0.25em;
104 box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);*/
105 border: none;
106 }
107 /* Rows for the current user have the .user-is-me CSS class
108 and get right-aligned. */
109 .message-row.user-is-me {
110 justify-content: flex-end;
111 /*background-color: #d2dde1;*/
112 }
113 /* The content area of a message (the body element of a FIELDSET) */
114 .message-content {
115 display: inline-block;
116 border-radius: 0.25em;
117 border: 1px solid rgba(0,0,0,0.2);
118 box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
119 padding: 0.25em 1em;
120 margin-top: -0.75em;
121 }
122 .message-row.user-is-me .message-content {
123 background-color: #d2dde1;
124 }
125 /* User name for the post (a LEGEND element) */
126 .message-row .message-user {
127 background: inherit;
128 border-radius: 0.25em 0.25em 0 0;
129 padding: 0 0.5em;
130 /*text-align: left; Firefox requires the 'align' attribute */
131 margin-left: 0.25em;
132 padding: 0 0.5em 0em 0.5em;
133 margin-bottom: 0.4em;
134 background-color: #d2dde1;
135 }
136 /* Reposition "my" posts to the right */
137 .message-row.user-is-me .message-user {
138 /*text-align: right; Firefox requires the 'align' attribute */
139 margin-left: 0;
140 margin-right: 0.25em;
141 }
142 </style>
143 }
144 set nonce [wapp-param FOSSIL_NONCE]
145 set submiturl [wapp-param SCRIPT_NAME]/send
@@ -213,27 +239,40 @@
239 span.appendChild(e);
240 });
241 //console.debug("span =",span.innerHTML);
242 return span;
243 }/*end messageToDOM()*/;
244 const injectMessage = function f(e){
245 if(!f.injectPoint){
246 f.injectPoint = document.querySelector('#message-inject-point');
247 }
248 f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
249 };
250 function newcontent(jx){
 
251 var i;
252 for(i=0; i<jx.msgs.length; ++i){
253 let m = jx.msgs[i];
254 let row = document.createElement("fieldset");
255 if( m.msgid>mxMsg ) mxMsg = m.msgid;
256 row.classList.add('message-row');
257 injectMessage(row);
258 const eWho = document.createElement('legend');
259 eWho.setAttribute('align', (m.xfrom===_me ? 'right' : 'left'));
260 row.appendChild(eWho);
261 eWho.classList.add('message-user');
262 let whoName;
263 if( m.xfrom===_me ){
264 whoName = 'me';
265 //eWho.classList.add('user-is-me');
266 row.classList.add('user-is-me');
267 }else{
268 whoName = m.xfrom;
269 }
270 eWho.append(document.createTextNode(whoName));
271 let span = document.createElement("div");
272 span.classList.add('message-content');
273 row.appendChild(span);
274 if( m.fsize>0 ){
275 if( m.fmime && m.fmime.startsWith("image/") ){
276 let img = document.createElement("img");
277 img.src = "%string($downloadurl)/" + m.msgid;
278 span.appendChild(img);
@@ -255,15 +294,10 @@
294 if( m.xfrom!=_me ){
295 span.classList.add('chat-mx');
296 }else{
297 span.classList.add('chat-ms');
298 }
 
 
 
 
 
299 }
300 }
301 async function poll(){
302 if(poll.running) return;
303 poll.running = true;
304

Keyboard Shortcuts

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