Fossil

Check-in [8e12b61b50]
Login

Check-in [8e12b61b50]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | chat-mode-bottom-up
Files: files | file ages | folders
SHA3-256: 8e12b61b50bf90dd70aa37a6fb1129af925cb90b57598530f79c02623ed20d25
User & Date: stephan 2020-12-26 16:20:46.667
Context
2020-12-26
16:21
Disabled a dangling part of the search for a solution for the bottom-scrolling problem. ... (Closed-Leaf check-in: 7f4000a62c user: stephan tags: chat-mode-bottom-up)
16:20
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. ... (check-in: 8e12b61b50 user: stephan tags: chat-mode-bottom-up)
15:40
Implement bottom-up and top-down chat layouts in chat-only mode and normal mode. There is a minor scroll-on-new-message quirk or two to resolve, but it otherwise seems to work. ... (check-in: dfc20f4297 user: stephan tags: chat-mode-bottom-up)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/chat.js.
13
14
15
16
17
18
19

20
21
22
23
24
25
26
  const Chat = (function(){
    const cs = {
      e:{/*map of certain DOM elements.*/
        messageInjectPoint: E1('#message-inject-point'),
        pageTitle: E1('head title'),
        loadToolbar: undefined /* the load-posts toolbar (dynamically created) */,
        inputWrapper: E1("#chat-input-area"),

        messagesWrapper: E1('#chat-messages-wrapper'),
        inputForm: E1('#chat-form'),
        btnSubmit: E1('#chat-message-submit'),
        inputSingle: E1('#chat-input-single'),
        inputMulti: E1('#chat-input-multi'),
        inputCurrent: undefined/*one of inputSingle or inputMulti*/,
        inputFile: E1('#chat-input-file'),







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  const Chat = (function(){
    const cs = {
      e:{/*map of certain DOM elements.*/
        messageInjectPoint: E1('#message-inject-point'),
        pageTitle: E1('head title'),
        loadToolbar: undefined /* the load-posts toolbar (dynamically created) */,
        inputWrapper: E1("#chat-input-area"),
        fileSelectWrapper: E1('#chat-input-file-area'),
        messagesWrapper: E1('#chat-messages-wrapper'),
        inputForm: E1('#chat-form'),
        btnSubmit: E1('#chat-message-submit'),
        inputSingle: E1('#chat-input-single'),
        inputMulti: E1('#chat-input-multi'),
        inputCurrent: undefined/*one of inputSingle or inputMulti*/,
        inputFile: E1('#chat-input-file'),
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128















129







130
131
132
133
134
135
136
         list if atEnd is falsy, else at the end of the list, before
         the load-history widget. */
      injectMessageElem: function f(e, atEnd){
        const mip = atEnd ? this.e.loadToolbar : this.e.messageInjectPoint;
        if(atEnd){
          mip.parentNode.insertBefore(e, mip);
        }else{
          if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
          else mip.parentNode.appendChild(e);
          if(this.isUiFlipped()){
            /* When UI is flipped, new messages start out under the
               text input area because of its position:sticky
               style. We have to scroll them up. When the page footer
               is not hidden but is not on-screen, this causes a
               slight amount of UI jarring as the footer is *also*
               scrolled into view (for whatever reason). */















            setTimeout(()=>e.scrollIntoView(), 0);







          }
        }
      },
      /** Returns true if chat-only mode is enabled. */
      isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'),
      /** Returns true if the UI seems to be in "bottom-up" mode. */
      isUiFlipped: function(){







|
<
|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>







114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
         list if atEnd is falsy, else at the end of the list, before
         the load-history widget. */
      injectMessageElem: function f(e, atEnd){
        const mip = atEnd ? this.e.loadToolbar : this.e.messageInjectPoint;
        if(atEnd){
          mip.parentNode.insertBefore(e, mip);
        }else{
          const self = this;

          if(false && this.isUiFlipped()){
            /* When UI is flipped, new messages start out under the
               text input area because of its position:sticky
               style. We have to scroll them up. When the page footer
               is not hidden but is not on-screen, this causes a
               slight amount of UI jarring as the footer is *also*
               scrolled into view (for whatever reason).

               The remaining problem here is messages with IMG tags.
               At this point in the process their IMG.src has not yet
               been loaded - that's async. We scroll the message into
               view, but then the downstream loading of IMG.src pushes
               the message content back down, sliding the message
               behind the input field. This can be verified by delaying the
               message scroll by a second or so to give the image time
               to load (from a local server instance).
            */
            D.addClass(self.e.inputWrapper,'unsticky');
          }
          if(mip.nextSibling) mip.parentNode.insertBefore(e, mip.nextSibling);
          else mip.parentNode.appendChild(e);
          if(this.isUiFlipped()){
            //e.scrollIntoView();
            setTimeout(function(){
              //self.e.inputWrapper.scrollIntoView();
              //self.e.fileSelectWrapper.scrollIntoView();
              //e.scrollIntoView();
              //D.removeClass(self.e.inputWrapper,'unsticky');
              self.e.inputWrapper.scrollIntoView();
            },0);
          }
        }
      },
      /** Returns true if chat-only mode is enabled. */
      isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'),
      /** Returns true if the UI seems to be in "bottom-up" mode. */
      isUiFlipped: function(){
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
        updateDropZoneContent(false/*clear prev state*/);
        updateDropZoneContent(items[0].getAsFile());
      }
    }, false);
    /* Add help button for drag/drop/paste zone */
    Chat.e.inputFile.parentNode.insertBefore(
      F.helpButtonlets.create(
        document.querySelector('#chat-input-file-area .help-buttonlet')
      ), Chat.e.inputFile
    );
    ////////////////////////////////////////////////////////////
    // File drag/drop visual notification.
    const dropHighlight = Chat.e.inputFile /* target zone */;
    const dropEvents = {
      drop: function(ev){







|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
        updateDropZoneContent(false/*clear prev state*/);
        updateDropZoneContent(items[0].getAsFile());
      }
    }, false);
    /* Add help button for drag/drop/paste zone */
    Chat.e.inputFile.parentNode.insertBefore(
      F.helpButtonlets.create(
        Chat.e.fileSelectWrapper.querySelector('.help-buttonlet')
      ), Chat.e.inputFile
    );
    ////////////////////////////////////////////////////////////
    // File drag/drop visual notification.
    const dropHighlight = Chat.e.inputFile /* target zone */;
    const dropEvents = {
      drop: function(ev){
818
819
820
821
822
823
824
825



826
827
828
829
830
831
832
833
    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(x){
        if(isFirstCall) Chat.ajaxEnd();



        poll.running=false;
      });
  }
  poll.running = false;
  poll(true);
  setInterval(poll, 1000);
  F.page.chat = Chat/* enables testing the APIs via the dev tools */;
})();







|
>
>
>








840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
    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(x){
        if(isFirstCall){
          Chat.ajaxEnd();
          Chat.e.inputWrapper.scrollIntoView();
        }
        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.
1670
1671
1672
1673
1674
1675
1676
1677
1678





1679
1680
1681
1682
1683
1684
1685
       z-index higher than this one. */;
}
body.chat.chat-bottom-up #chat-input-area {
  border-bottom: none;
  border-top: 1px solid black;
  margin-bottom: 0;
  margin-top: 0.5em;
  position: sticky;
  bottom: 0;





}
/* 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;







|

>
>
>
>
>







1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
       z-index higher than this one. */;
}
body.chat.chat-bottom-up #chat-input-area {
  border-bottom: none;
  border-top: 1px solid black;
  margin-bottom: 0;
  margin-top: 0.5em;
  position: initial /*sticky currently disabled due to scrolling-related issues*/;
  bottom: 0;
}
/* An internal hack to try to help resolve a message-scrolling quirk
   when #chat-input-area is sticky on the bottom of the screen. */
body.chat.chat-bottom-up #chat-input-area.unsticky {
  position: initial;
}
/* 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;