Check-in [160d26923b]
Not logged in

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

Overview
Comment:Minor cosmetic tweaks to the poll-in-distress indicator. Make it yellow in dark-mode skins, as red blends in too well. No functional changes.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 160d26923b0d6370feb5a991d8e79ca456a38860bd49d82086d6ffc20a857b8a
User & Date: stephan 2025-04-11 16:09:05.098
Context
2025-04-11
18:52
Further refinements of the chat poll connection detection. The first N ignored errors are now spaced out unevenly. Use the server's configured chat-poll-timeout as the basis for calculating our client-side timeout time. check-in: e8bbaf924f user: stephan tags: trunk
16:09
Minor cosmetic tweaks to the poll-in-distress indicator. Make it yellow in dark-mode skins, as red blends in too well. No functional changes. check-in: 160d26923b user: stephan tags: trunk
15:30
Teach /chat to not be so verbose about connection errors. The first 3 will be subtly signaled via a tiny red line between the input field and message list, which will go away once the poller connection is re-established. After that, it will resort to the more verbose notifications. check-in: e3eb83997b user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/fossil.page.chat.js.
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
        viewSearch: E1('#chat-search'),
        searchContent: E1('#chat-search-content'),
        btnPreview: E1('#chat-button-preview'),
        views: document.querySelectorAll('.chat-view'),
        activeUserListWrapper: E1('#chat-user-list-wrapper'),
        activeUserList: E1('#chat-user-list'),
        eMsgPollError: undefined /* current connection error MessageMidget */,
        pollErrorMarker: undefined /* element to toggle 'connection-error' CSS class on */
      },
      me: F.user.name,
      mxMsg: F.config.chat.initSize ? -F.config.chat.initSize : -50,
      mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
      pageIsActive: 'visible'===document.visibilityState,
      changesSincePageHidden: 0,
      notificationBubbleColor: 'white',







|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
        viewSearch: E1('#chat-search'),
        searchContent: E1('#chat-search-content'),
        btnPreview: E1('#chat-button-preview'),
        views: document.querySelectorAll('.chat-view'),
        activeUserListWrapper: E1('#chat-user-list-wrapper'),
        activeUserList: E1('#chat-user-list'),
        eMsgPollError: undefined /* current connection error MessageMidget */,
        pollErrorMarker: document.body /* element to toggle 'connection-error' CSS class on */
      },
      me: F.user.name,
      mxMsg: F.config.chat.initSize ? -F.config.chat.initSize : -50,
      mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
      pageIsActive: 'visible'===document.visibilityState,
      changesSincePageHidden: 0,
      notificationBubbleColor: 'white',
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
        maxDelay: 60000 * 5 /* max interval when backing off for
                              connection errors */,
        minDelay: 5000 /* minimum delay time */,
        tidReconnect: undefined /*timer id for reconnection determination*/,
        errCount: 0 /* Current poller connection error count */,
        minErrForNotify: 4 /* Don't warn for connection errors until this
                              many have occurred */,
        skipErrDelay: 3500 /* time to wait/retry for the first minErrForNotify'th
                              connection errors. */,
        randomInterval: function(factor){
          return Math.floor(Math.random() * factor);
        },
        incrDelay: function(){
          if( this.maxDelay > this.currentDelay ){
            if(this.currentDelay < this.minDelay){
              this.currentDelay = this.minDelay + this.randomInterval(this.minDelay);







<
<







204
205
206
207
208
209
210


211
212
213
214
215
216
217
        maxDelay: 60000 * 5 /* max interval when backing off for
                              connection errors */,
        minDelay: 5000 /* minimum delay time */,
        tidReconnect: undefined /*timer id for reconnection determination*/,
        errCount: 0 /* Current poller connection error count */,
        minErrForNotify: 4 /* Don't warn for connection errors until this
                              many have occurred */,


        randomInterval: function(factor){
          return Math.floor(Math.random() * factor);
        },
        incrDelay: function(){
          if( this.maxDelay > this.currentDelay ){
            if(this.currentDelay < this.minDelay){
              this.currentDelay = this.minDelay + this.randomInterval(this.minDelay);
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
    if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
      cs.$browserHasPlaintextOnly = true;
    }else{
      /* Only the Chrome family supports contenteditable=plaintext-only */
      cs.$browserHasPlaintextOnly = false;
      D.attr(cs.e.inputX,'contenteditable','true');
    }
    cs.e.pollErrorMarker = cs.e.viewMessages;
    cs.animate.$disabled = true;
    F.fetch.beforesend = ()=>cs.ajaxStart();
    F.fetch.aftersend = ()=>cs.ajaxEnd();
    cs.pageTitleOrig = cs.e.pageTitle.innerText;
    const qs = (e)=>document.querySelector(e);
    const argsToArray = function(args){
      return Array.prototype.slice.call(args,0);







<







672
673
674
675
676
677
678

679
680
681
682
683
684
685
    if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
      cs.$browserHasPlaintextOnly = true;
    }else{
      /* Only the Chrome family supports contenteditable=plaintext-only */
      cs.$browserHasPlaintextOnly = false;
      D.attr(cs.e.inputX,'contenteditable','true');
    }

    cs.animate.$disabled = true;
    F.fetch.beforesend = ()=>cs.ajaxStart();
    F.fetch.aftersend = ()=>cs.ajaxEnd();
    cs.pageTitleOrig = cs.e.pageTitle.innerText;
    const qs = (e)=>document.querySelector(e);
    const argsToArray = function(args){
      return Array.prototype.slice.call(args,0);
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
           UI message about the outage. */
        let delay;
        D.addClass(Chat.e.pollErrorMarker, 'connection-error');
        if( ++Chat.timer.errCount < Chat.timer.minErrForNotify ){
          if(Chat.beVerbose){
            console.warn("Ignoring polling error #", Chat.timer.errCount);
          }
          delay = Chat.timer.resetDelay(Chat.timer.skipErrDelay);
        } else {
          delay = Chat.timer.incrDelay();
          //console.warn("afterPollFetch Chat.e.eMsgPollError",Chat.e.eMsgPollError);
          const msg = "Poller connection error. Retrying in "+delay+ " ms.";
          /* Replace the current/newest connection error widget. We could also
             just update its body with the new message, but then its timestamp
             never updates. OTOH, if we replace the message, we lose the







|







2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
           UI message about the outage. */
        let delay;
        D.addClass(Chat.e.pollErrorMarker, 'connection-error');
        if( ++Chat.timer.errCount < Chat.timer.minErrForNotify ){
          if(Chat.beVerbose){
            console.warn("Ignoring polling error #", Chat.timer.errCount);
          }
          delay = Chat.timer.resetDelay(Chat.timer.minDelay);
        } else {
          delay = Chat.timer.incrDelay();
          //console.warn("afterPollFetch Chat.e.eMsgPollError",Chat.e.eMsgPollError);
          const msg = "Poller connection error. Retrying in "+delay+ " ms.";
          /* Replace the current/newest connection error widget. We could also
             just update its body with the new message, but then its timestamp
             never updates. OTOH, if we replace the message, we lose the
Changes to src/style.chat.css.
211
212
213
214
215
216
217
218





219
220
221
222
223
224
225
226
  overflow: auto;
  padding: 0 0.25em;
}
body.chat #chat-messages-wrapper.loading > * {
  /* An attempt at reducing flicker when loading lots of messages. */
  visibility: hidden;
}
body.chat #chat-messages-wrapper.connection-error {





  border-bottom: thin dotted red;
}

body.chat div.content {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column-reverse;







|
>
>
>
>
>
|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  overflow: auto;
  padding: 0 0.25em;
}
body.chat #chat-messages-wrapper.loading > * {
  /* An attempt at reducing flicker when loading lots of messages. */
  visibility: hidden;
}

/* Provide a visual cue when polling is offline. */
body.chat.connection-error #chat-input-line-wrapper {
  border-top: medium dotted red;
}
body.chat.fossil-dark-style.connection-error #chat-input-line-wrapper {
  border-color: yellow;
}

body.chat div.content {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column-reverse;