Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Some flicker reduction when batch loading chat messages. Minor chat layout tweaks. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
5e046b64c73fced861b93dce559545e8 |
| User & Date: | stephan 2020-12-27 09:56:44.618 |
Context
|
2020-12-27
| ||
| 17:42 | Chat: hide message home/end buttons by default in portrait mode and add a menu toggle for them, and swapped the button positions (seems more natural). Minor tweak to the div.content resize algo to make use of CSS calc(). ... (check-in: deb9963ac6 user: stephan tags: trunk) | |
| 09:56 | Some flicker reduction when batch loading chat messages. Minor chat layout tweaks. ... (check-in: 5e046b64c7 user: stephan tags: trunk) | |
| 09:37 | Added an ARIA role=alert to the fossil.toast.message/warning/error() popup, per form request. Toast API doc corrections. ... (check-in: 23d6b4570a user: stephan tags: trunk) | |
Changes
Changes to src/chat.js.
| ︙ | ︙ | |||
204 205 206 207 208 209 210 |
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;
}
| | | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
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;
}
if(!atEnd && !this.isBatchLoading
&& e.dataset.xfrom!==this.me && !isInViewport(e)){
/* If a new non-history message arrives while the user is
scrolled elsewhere, do not scroll to the latest
message, but gently alert the user that a new message
has arrived. */
F.toast.message("New message has arrived.");
}else if(!this.isBatchLoading && e.dataset.xfrom===Chat.me){
this.scheduleScrollOfMsg(e);
}else if(!this.isBatchLoading){
/* When a message from someone else arrives, we have to
figure out whether or not to scroll it into view. Ideally
we'd just stuff it in the UI and let the flexbox layout
DTRT, but Safari has expressed, in no uncertain terms,
some disappointment with that approach, so we'll
heuristicize it: if the previous last message is in view,
assume the user is at or near the input element and
|
| ︙ | ︙ | |||
287 288 289 290 291 292 293 |
*/
scrollMessagesTo: function(where){
if(where<0){
Chat.e.messagesWrapper.scrollTop = 0;
}else if(where>0){
Chat.e.messagesWrapper.scrollTop = Chat.e.messagesWrapper.scrollHeight;
}else if(Chat.e.newestMessage){
| | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
*/
scrollMessagesTo: function(where){
if(where<0){
Chat.e.messagesWrapper.scrollTop = 0;
}else if(where>0){
Chat.e.messagesWrapper.scrollTop = Chat.e.messagesWrapper.scrollHeight;
}else if(Chat.e.newestMessage){
Chat.e.newestMessage.scrollIntoView(false);
}
},
toggleChatOnlyMode: function(){
return this.chatOnlyMode(!this.isChatOnlyMode());
},
settings:{
get: (k,dflt)=>F.storage.get(k,dflt),
|
| ︙ | ︙ | |||
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 |
const toolbar = Chat.e.loadOlderToolbar = D.attr(
D.fieldset(loadLegend), "id", "load-msg-toolbar"
);
Chat.disableDuringAjax.push(toolbar);
/* Loads the next n oldest messages, or all previous history if n is negative. */
const loadOldMessages = function(n){
Chat.ajaxStart();
var gotMessages = false;
fetch("chat-poll?before="+Chat.mnMsg+"&n="+n)
.then(x=>x.json())
.then(function(x){
gotMessages = x.msgs.length;
newcontent(x,true);
})
.catch(e=>Chat.reportError(e))
.finally(function(){
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*/)
| > > > > | | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
const toolbar = Chat.e.loadOlderToolbar = D.attr(
D.fieldset(loadLegend), "id", "load-msg-toolbar"
);
Chat.disableDuringAjax.push(toolbar);
/* Loads the next n oldest messages, or all previous history if n is negative. */
const loadOldMessages = function(n){
Chat.ajaxStart();
Chat.e.messagesWrapper.classList.add('loading');
Chat.isBatchLoading = true;
var gotMessages = false;
fetch("chat-poll?before="+Chat.mnMsg+"&n="+n)
.then(x=>x.json())
.then(function(x){
gotMessages = x.msgs.length;
newcontent(x,true);
})
.catch(e=>Chat.reportError(e))
.finally(function(){
Chat.isBatchLoading = false;
Chat.e.messagesWrapper.classList.remove('loading');
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*/)
|| (false!==gotMessages && 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
via the ajaxStart()/ajaxEnd() mechanism... */
const div = Chat.e.loadOlderToolbar.querySelector('div');
D.append(D.clearElement(div), "All history has been loaded.");
D.addClass(Chat.e.loadOlderToolbar, 'all-done');
|
| ︙ | ︙ | |||
961 962 963 964 965 966 967 |
D.append(Chat.e.messagesWrapper, toolbar);
toolbar.disabled = true /*will be enabled when msg load finishes */;
})()/*end history loading widget setup*/;
async function poll(isFirstCall){
if(poll.running) return;
poll.running = true;
| | > > > | | | | | > | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 |
D.append(Chat.e.messagesWrapper, toolbar);
toolbar.disabled = true /*will be enabled when msg load finishes */;
})()/*end history loading widget setup*/;
async function poll(isFirstCall){
if(poll.running) return;
poll.running = true;
if(isFirstCall){
Chat.ajaxStart();
Chat.e.messagesWrapper.classList.add('loading');
}
Chat.isBatchLoading = isFirstCall;
var p = fetch("chat-poll?name=" + Chat.mxMsg);
p.then(x=>x.json())
.then(y=>newcontent(y))
.catch(e=>console.error(e))
/* ^^^ we don't use Chat.reportError(e) here b/c the polling
fails exepectedly when it times out, but is then immediately
resumed, and reportError() produces a loud error message. */
.finally(function(){
if(isFirstCall){
Chat.isBatchLoading = false;
Chat.ajaxEnd();
setTimeout(function(){
Chat.scrollMessagesTo(1);
Chat.e.messagesWrapper.classList.remove('loading');
}, 250);
}
poll.running=false;
});
}
poll.running = false;
poll(true);
setInterval(poll, 1000);
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
})();
|
Changes to src/default.css.
| ︙ | ︙ | |||
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 |
cursor: inherit;
}
/** Container for the list of /chat messages. */
body.chat #chat-messages-wrapper {
overflow: auto;
/*max-height: 800em*//*will be re-calc'd in JS*/;
flex: 2 1 auto;
}
body.chat div.content {
margin: 0;
padding: 0;
display: flex;
flex-direction: column-reverse;
/* ^^^^ In order to get good automatic scrolling of new messages on
| > > > > | 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 |
cursor: inherit;
}
/** Container for the list of /chat messages. */
body.chat #chat-messages-wrapper {
overflow: auto;
/*max-height: 800em*//*will be re-calc'd in JS*/;
flex: 2 1 auto;
}
body.chat #chat-messages-wrapper.loading > * {
/* An attempt at reducing flicker when loading lots of messages. */
visibility: hidden;
}
body.chat div.content {
margin: 0;
padding: 0;
display: flex;
flex-direction: column-reverse;
/* ^^^^ In order to get good automatic scrolling of new messages on
|
| ︙ | ︙ | |||
1676 1677 1678 1679 1680 1681 1682 |
/* Widget holding the chat message input field, send button, and
settings button. */
body.chat #chat-input-line {
display: flex;
flex-direction: row;
margin-bottom: 0.25em;
| | | 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 |
/* Widget holding the chat message input field, send button, and
settings button. */
body.chat #chat-input-line {
display: flex;
flex-direction: row;
margin-bottom: 0.25em;
align-items: center;
}
body.chat #chat-input-line > input[type=submit],
body.chat #chat-input-line > #chat-settings-button,
body.chat #chat-input-line > button {
flex: 1 5 auto;
max-width: 6em;
margin: 0 0.25em;
|
| ︙ | ︙ |