Fossil SCM

Disabled position:sticky on the input area when in bottom-up chat mode pending resolution of a scrolling misbehaviour for messages with IMG tags. IMG.src is loaded async, so the scrolling is actually working but loading of the IMG.src is then pushing the message back down behind/under the input field.

stephan 2020-12-26 16:20 chat-mode-bottom-up
Commit 8e12b61b50bf90dd70aa37a6fb1129af925cb90b57598530f79c02623ed20d25
2 files changed +32 -7 +6 -1
+32 -7
--- src/chat.js
+++ src/chat.js
@@ -15,10 +15,11 @@
1515
e:{/*map of certain DOM elements.*/
1616
messageInjectPoint: E1('#message-inject-point'),
1717
pageTitle: E1('head title'),
1818
loadToolbar: undefined /* the load-posts toolbar (dynamically created) */,
1919
inputWrapper: E1("#chat-input-area"),
20
+ fileSelectWrapper: E1('#chat-input-file-area'),
2021
messagesWrapper: E1('#chat-messages-wrapper'),
2122
inputForm: E1('#chat-form'),
2223
btnSubmit: E1('#chat-message-submit'),
2324
inputSingle: E1('#chat-input-single'),
2425
inputMulti: E1('#chat-input-multi'),
@@ -115,20 +116,41 @@
115116
injectMessageElem: function f(e, atEnd){
116117
const mip = atEnd ? this.e.loadToolbar : this.e.messageInjectPoint;
117118
if(atEnd){
118119
mip.parentNode.insertBefore(e, mip);
119120
}else{
120
- if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
121
- else mip.parentNode.appendChild(e);
122
- if(this.isUiFlipped()){
121
+ const self = this;
122
+ if(false && this.isUiFlipped()){
123123
/* When UI is flipped, new messages start out under the
124124
text input area because of its position:sticky
125125
style. We have to scroll them up. When the page footer
126126
is not hidden but is not on-screen, this causes a
127127
slight amount of UI jarring as the footer is *also*
128
- scrolled into view (for whatever reason). */
129
- setTimeout(()=>e.scrollIntoView(), 0);
128
+ scrolled into view (for whatever reason).
129
+
130
+ The remaining problem here is messages with IMG tags.
131
+ At this point in the process their IMG.src has not yet
132
+ been loaded - that's async. We scroll the message into
133
+ view, but then the downstream loading of IMG.src pushes
134
+ the message content back down, sliding the message
135
+ behind the input field. This can be verified by delaying the
136
+ message scroll by a second or so to give the image time
137
+ to load (from a local server instance).
138
+ */
139
+ D.addClass(self.e.inputWrapper,'unsticky');
140
+ }
141
+ if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
142
+ else mip.parentNode.appendChild(e);
143
+ if(this.isUiFlipped()){
144
+ //e.scrollIntoView();
145
+ setTimeout(function(){
146
+ //self.e.inputWrapper.scrollIntoView();
147
+ //self.e.fileSelectWrapper.scrollIntoView();
148
+ //e.scrollIntoView();
149
+ //D.removeClass(self.e.inputWrapper,'unsticky');
150
+ self.e.inputWrapper.scrollIntoView();
151
+ },0);
130152
}
131153
}
132154
},
133155
/** Returns true if chat-only mode is enabled. */
134156
isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'),
@@ -447,11 +469,11 @@
447469
}
448470
}, false);
449471
/* Add help button for drag/drop/paste zone */
450472
Chat.e.inputFile.parentNode.insertBefore(
451473
F.helpButtonlets.create(
452
- document.querySelector('#chat-input-file-area .help-buttonlet')
474
+ Chat.e.fileSelectWrapper.querySelector('.help-buttonlet')
453475
), Chat.e.inputFile
454476
);
455477
////////////////////////////////////////////////////////////
456478
// File drag/drop visual notification.
457479
const dropHighlight = Chat.e.inputFile /* target zone */;
@@ -820,14 +842,17 @@
820842
.catch(e=>console.error(e))
821843
/* ^^^ we don't use Chat.reportError(e) here b/c the polling
822844
fails exepectedly when it times out, but is then immediately
823845
resumed, and reportError() produces a loud error message. */
824846
.finally(function(x){
825
- if(isFirstCall) Chat.ajaxEnd();
847
+ if(isFirstCall){
848
+ Chat.ajaxEnd();
849
+ Chat.e.inputWrapper.scrollIntoView();
850
+ }
826851
poll.running=false;
827852
});
828853
}
829854
poll.running = false;
830855
poll(true);
831856
setInterval(poll, 1000);
832857
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
833858
})();
834859
--- src/chat.js
+++ src/chat.js
@@ -15,10 +15,11 @@
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 inputWrapper: E1("#chat-input-area"),
 
20 messagesWrapper: E1('#chat-messages-wrapper'),
21 inputForm: E1('#chat-form'),
22 btnSubmit: E1('#chat-message-submit'),
23 inputSingle: E1('#chat-input-single'),
24 inputMulti: E1('#chat-input-multi'),
@@ -115,20 +116,41 @@
115 injectMessageElem: function f(e, atEnd){
116 const mip = atEnd ? this.e.loadToolbar : this.e.messageInjectPoint;
117 if(atEnd){
118 mip.parentNode.insertBefore(e, mip);
119 }else{
120 if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
121 else mip.parentNode.appendChild(e);
122 if(this.isUiFlipped()){
123 /* When UI is flipped, new messages start out under the
124 text input area because of its position:sticky
125 style. We have to scroll them up. When the page footer
126 is not hidden but is not on-screen, this causes a
127 slight amount of UI jarring as the footer is *also*
128 scrolled into view (for whatever reason). */
129 setTimeout(()=>e.scrollIntoView(), 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130 }
131 }
132 },
133 /** Returns true if chat-only mode is enabled. */
134 isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'),
@@ -447,11 +469,11 @@
447 }
448 }, false);
449 /* Add help button for drag/drop/paste zone */
450 Chat.e.inputFile.parentNode.insertBefore(
451 F.helpButtonlets.create(
452 document.querySelector('#chat-input-file-area .help-buttonlet')
453 ), Chat.e.inputFile
454 );
455 ////////////////////////////////////////////////////////////
456 // File drag/drop visual notification.
457 const dropHighlight = Chat.e.inputFile /* target zone */;
@@ -820,14 +842,17 @@
820 .catch(e=>console.error(e))
821 /* ^^^ we don't use Chat.reportError(e) here b/c the polling
822 fails exepectedly when it times out, but is then immediately
823 resumed, and reportError() produces a loud error message. */
824 .finally(function(x){
825 if(isFirstCall) Chat.ajaxEnd();
 
 
 
826 poll.running=false;
827 });
828 }
829 poll.running = false;
830 poll(true);
831 setInterval(poll, 1000);
832 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
833 })();
834
--- src/chat.js
+++ src/chat.js
@@ -15,10 +15,11 @@
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 inputWrapper: E1("#chat-input-area"),
20 fileSelectWrapper: E1('#chat-input-file-area'),
21 messagesWrapper: E1('#chat-messages-wrapper'),
22 inputForm: E1('#chat-form'),
23 btnSubmit: E1('#chat-message-submit'),
24 inputSingle: E1('#chat-input-single'),
25 inputMulti: E1('#chat-input-multi'),
@@ -115,20 +116,41 @@
116 injectMessageElem: function f(e, atEnd){
117 const mip = atEnd ? this.e.loadToolbar : this.e.messageInjectPoint;
118 if(atEnd){
119 mip.parentNode.insertBefore(e, mip);
120 }else{
121 const self = this;
122 if(false && this.isUiFlipped()){
 
123 /* When UI is flipped, new messages start out under the
124 text input area because of its position:sticky
125 style. We have to scroll them up. When the page footer
126 is not hidden but is not on-screen, this causes a
127 slight amount of UI jarring as the footer is *also*
128 scrolled into view (for whatever reason).
129
130 The remaining problem here is messages with IMG tags.
131 At this point in the process their IMG.src has not yet
132 been loaded - that's async. We scroll the message into
133 view, but then the downstream loading of IMG.src pushes
134 the message content back down, sliding the message
135 behind the input field. This can be verified by delaying the
136 message scroll by a second or so to give the image time
137 to load (from a local server instance).
138 */
139 D.addClass(self.e.inputWrapper,'unsticky');
140 }
141 if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
142 else mip.parentNode.appendChild(e);
143 if(this.isUiFlipped()){
144 //e.scrollIntoView();
145 setTimeout(function(){
146 //self.e.inputWrapper.scrollIntoView();
147 //self.e.fileSelectWrapper.scrollIntoView();
148 //e.scrollIntoView();
149 //D.removeClass(self.e.inputWrapper,'unsticky');
150 self.e.inputWrapper.scrollIntoView();
151 },0);
152 }
153 }
154 },
155 /** Returns true if chat-only mode is enabled. */
156 isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'),
@@ -447,11 +469,11 @@
469 }
470 }, false);
471 /* Add help button for drag/drop/paste zone */
472 Chat.e.inputFile.parentNode.insertBefore(
473 F.helpButtonlets.create(
474 Chat.e.fileSelectWrapper.querySelector('.help-buttonlet')
475 ), Chat.e.inputFile
476 );
477 ////////////////////////////////////////////////////////////
478 // File drag/drop visual notification.
479 const dropHighlight = Chat.e.inputFile /* target zone */;
@@ -820,14 +842,17 @@
842 .catch(e=>console.error(e))
843 /* ^^^ we don't use Chat.reportError(e) here b/c the polling
844 fails exepectedly when it times out, but is then immediately
845 resumed, and reportError() produces a loud error message. */
846 .finally(function(x){
847 if(isFirstCall){
848 Chat.ajaxEnd();
849 Chat.e.inputWrapper.scrollIntoView();
850 }
851 poll.running=false;
852 });
853 }
854 poll.running = false;
855 poll(true);
856 setInterval(poll, 1000);
857 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
858 })();
859
+6 -1
--- src/default.css
+++ src/default.css
@@ -1672,12 +1672,17 @@
16721672
body.chat.chat-bottom-up #chat-input-area {
16731673
border-bottom: none;
16741674
border-top: 1px solid black;
16751675
margin-bottom: 0;
16761676
margin-top: 0.5em;
1677
- position: sticky;
1677
+ position: initial /*sticky currently disabled due to scrolling-related issues*/;
16781678
bottom: 0;
1679
+}
1680
+/* An internal hack to try to help resolve a message-scrolling quirk
1681
+ when #chat-input-area is sticky on the bottom of the screen. */
1682
+body.chat.chat-bottom-up #chat-input-area.unsticky {
1683
+ position: initial;
16791684
}
16801685
/* Widget holding the chat message input field, send button, and
16811686
settings button. */
16821687
body.chat #chat-input-line {
16831688
display: flex;
16841689
--- src/default.css
+++ src/default.css
@@ -1672,12 +1672,17 @@
1672 body.chat.chat-bottom-up #chat-input-area {
1673 border-bottom: none;
1674 border-top: 1px solid black;
1675 margin-bottom: 0;
1676 margin-top: 0.5em;
1677 position: sticky;
1678 bottom: 0;
 
 
 
 
 
1679 }
1680 /* Widget holding the chat message input field, send button, and
1681 settings button. */
1682 body.chat #chat-input-line {
1683 display: flex;
1684
--- src/default.css
+++ src/default.css
@@ -1672,12 +1672,17 @@
1672 body.chat.chat-bottom-up #chat-input-area {
1673 border-bottom: none;
1674 border-top: 1px solid black;
1675 margin-bottom: 0;
1676 margin-top: 0.5em;
1677 position: initial /*sticky currently disabled due to scrolling-related issues*/;
1678 bottom: 0;
1679 }
1680 /* An internal hack to try to help resolve a message-scrolling quirk
1681 when #chat-input-area is sticky on the bottom of the screen. */
1682 body.chat.chat-bottom-up #chat-input-area.unsticky {
1683 position: initial;
1684 }
1685 /* Widget holding the chat message input field, send button, and
1686 settings button. */
1687 body.chat #chat-input-line {
1688 display: flex;
1689

Keyboard Shortcuts

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