Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | /chat experiment, per chat discussion: when a given user posts multiple messages in a row, indent the 2nd and subsequent messages. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | chat-indent-messages |
| Files: | files | file ages | folders |
| SHA3-256: |
609bcd32c85fd10f5492a515ff7835c7 |
| User & Date: | stephan 2021-04-07 14:46:04.446 |
Context
|
2021-04-07
| ||
| 14:46 | /chat experiment, per chat discussion: when a given user posts multiple messages in a row, indent the 2nd and subsequent messages. ... (Closed-Leaf check-in: 609bcd32c8 user: stephan tags: chat-indent-messages) | |
| 10:09 | The 'placeholder' attribute of the two /chat text input fields how includes the project name to help avoid confusion about which /chat one is typing into without requiring new screen real estate for a project-name label. ... (check-in: 69135e4f61 user: stephan tags: trunk) | |
Changes
Changes to src/chat.js.
| ︙ | ︙ | |||
224 225 226 227 228 229 230 |
'load', ()=>(this.e.newestMessage || eMsg).scrollIntoView(false)
);
}else{
eMsg.scrollIntoView(false);
}
return this;
},
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > > > | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
'load', ()=>(this.e.newestMessage || eMsg).scrollIntoView(false)
);
}else{
eMsg.scrollIntoView(false);
}
return this;
},
/**
Recalculates the ".subsequent" CSS class tag for all
messages. When a user posts multiple messages in a row, the
2nd and subsequent ones get the "subsequent" tag added to
them for additional styling. We cannot do this easily as
messages arrive in batch mode because they can arrive out of
order (they arrive, and are processed, in reverse order for
the "load older messages" buttons). We do this handling in
injectMessageElem() for "interactive" use but have to
recalculate them en mass after receiving a batch of messages
right after this app loads or via the "load older messages"
buttons.
*/
recalcMessageIndents: function(){
var prevXFrom;
this.e.messagesWrapper.querySelectorAll('.message-widget').forEach(function(e,ndx){
if(e.classList.contains('notification')){
// Obligatory special case.
prevXFrom = undefined;
D.removeClass(e, 'subsequent');
return;
}
const xfrom = e.dataset.xfrom;
if(ndx && xfrom === prevXFrom){
D.addClass(e,'subsequent');
}else{
D.removeClass(e, 'subsequent');
}
prevXFrom = xfrom;
});
},
/* Injects element e as a new row in the chat, at the oldest end
of the list if atEnd is truthy, else at the newest end of the
list. */
injectMessageElem: function f(e, atEnd){
const mip = atEnd ? this.e.loadOlderToolbar : this.e.messageInjectPoint,
holder = this.e.messagesWrapper,
prevMessage = this.e.newestMessage;
if(!atEnd && !this._isBatchLoading
&& e.dataset.xfrom && !e.classList.contains('notification')){
if(prevMessage && prevMessage.dataset.xfrom===e.dataset.xfrom){
D.addClass(e, 'subsequent');
}
}
if(atEnd){
const fe = mip.nextElementSibling;
if(fe) mip.parentNode.insertBefore(e, fe);
else D.append(mip.parentNode, e);
}else{
D.append(holder,e);
this.e.newestMessage = e;
|
| ︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 |
let gotMessages = x.msgs.length;
newcontent(x,true);
Chat._isBatchLoading = false;
if(Chat._gotServerError){
Chat._gotServerError = false;
return;
}
if(n<0/*we asked for all history*/
|| 0===gotMessages/*we found no history*/
|| (n>0 && gotMessages<n /*we got fewer history entries than requested*/)
|| (n===0 && gotMessages<Chat.loadMessageCount
/*we asked for default amount and got fewer than that.*/)){
/* We've loaded all history. Permanently disable the
history-load toolbar and keep it from being re-enabled
| > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
let gotMessages = x.msgs.length;
newcontent(x,true);
Chat._isBatchLoading = false;
if(Chat._gotServerError){
Chat._gotServerError = false;
return;
}
Chat.recalcMessageIndents();
if(n<0/*we asked for all history*/
|| 0===gotMessages/*we found no history*/
|| (n>0 && gotMessages<n /*we got fewer history entries than requested*/)
|| (n===0 && gotMessages<Chat.loadMessageCount
/*we asked for default amount and got fewer than that.*/)){
/* We've loaded all history. Permanently disable the
history-load toolbar and keep it from being re-enabled
|
| ︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 |
})()/*end history loading widget setup*/;
const afterFetch = function f(){
if(true===f.isFirstCall){
f.isFirstCall = false;
Chat.ajaxEnd();
Chat.e.messagesWrapper.classList.remove('loading');
setTimeout(function(){
Chat.scrollMessagesTo(1);
}, 250);
}
if(Chat._gotServerError && Chat.intervalTimer){
clearInterval(Chat.intervalTimer);
Chat.reportErrorAsMessage(
| > | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 |
})()/*end history loading widget setup*/;
const afterFetch = function f(){
if(true===f.isFirstCall){
f.isFirstCall = false;
Chat.ajaxEnd();
Chat.e.messagesWrapper.classList.remove('loading');
Chat.recalcMessageIndents();
setTimeout(function(){
Chat.scrollMessagesTo(1);
}, 250);
}
if(Chat._gotServerError && Chat.intervalTimer){
clearInterval(Chat.intervalTimer);
Chat.reportErrorAsMessage(
|
| ︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 |
console.error(err);
/* ^^^ we don't use Chat.reportError() here b/c the polling
fails exepectedly when it times out, but is then immediately
resumed, and reportError() produces a loud error message. */
afterFetch();
},
onload:function(y){
| | | 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 |
console.error(err);
/* ^^^ we don't use Chat.reportError() here b/c the polling
fails exepectedly when it times out, but is then immediately
resumed, and reportError() produces a loud error message. */
afterFetch();
},
onload:function(y){
newcontent(y);
Chat._isBatchLoading = false;
afterFetch();
}
});
};
poll.isFirstCall = true;
Chat._gotServerError = poll.running = false;
if( window.fossil.config.chat.fromcli ){
Chat.chatOnlyMode(true);
}
Chat.intervalTimer = setInterval(poll, 1000);
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
})();
|
Changes to src/default.css.
| ︙ | ︙ | |||
1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 |
padding: 0 0.5em 0.15em 0.5em;
cursor: pointer;
white-space: nowrap;
}
body.chat .fossil-tooltip.help-buttonlet-content {
font-size: 80%;
}
/* The popup element for displaying message timestamps
and deletion controls. */
body.chat .chat-message-popup {
font-family: monospace;
font-size: 0.8em;
text-align: left;
display: flex;
| > > > > > > > > > > > > > > > > > | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 |
padding: 0 0.5em 0.15em 0.5em;
cursor: pointer;
white-space: nowrap;
}
body.chat .fossil-tooltip.help-buttonlet-content {
font-size: 80%;
}
body.chat .message-widget.subsequent {
/* When a single user posts multiple messages in a row,
the 2nd and subsequent ones get the 'subsequent' class
added to them. */
margin-left: 2.5em;
margin-right: 2.5em;
}
body.chat .message-widget.subsequent .message-widget-tab:before {
content: "↳ ";
}
body.chat.my-messages-right .message-widget.subsequent.mine .message-widget-tab:before {
content: revert;
}
body.chat.my-messages-right .message-widget.subsequent.mine .message-widget-tab:after {
content: " ↲";
}
/* The popup element for displaying message timestamps
and deletion controls. */
body.chat .chat-message-popup {
font-family: monospace;
font-size: 0.8em;
text-align: left;
display: flex;
|
| ︙ | ︙ |