Fossil SCM
When deleting a connection-restored notification, also delete the connection-broken notification it's associated with. Add a button to the message popup for connection-related notifications to delete all connection-related notifications. When running on localhost, reduce the /chat poller timeout to 15s.
Commit
79932a5210bf409cd247c71599639ae81fea707719c5d3b406e30c1a98460f63
Parent
1f97db779dba632…
1 file changed
+40
-10
+40
-10
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -758,24 +758,41 @@ | ||
| 758 | 758 | /** |
| 759 | 759 | LOCALLY deletes a message element by the message ID or passing |
| 760 | 760 | the .message-row element. Returns true if it removes an element, |
| 761 | 761 | else false. |
| 762 | 762 | */ |
| 763 | - cs.deleteMessageElem = function(id){ | |
| 763 | + cs.deleteMessageElem = function(id, silent){ | |
| 764 | 764 | var e; |
| 765 | + //console.warn("Chat.deleteMessageElem",id,silent); | |
| 765 | 766 | if(id instanceof HTMLElement){ |
| 766 | 767 | e = id; |
| 767 | 768 | id = e.dataset.msgid; |
| 768 | - }else{ | |
| 769 | + delete e.dataset.msgid; | |
| 770 | + if( e?.dataset?.alsoRemove ){ | |
| 771 | + const xId = e.dataset.alsoRemove; | |
| 772 | + delete e.dataset.alsoRemove; | |
| 773 | + this.deleteMessageElem( xId ); | |
| 774 | + } | |
| 775 | + }else if(e instanceof Chat.MessageWidget) { | |
| 776 | + if( this.e.eMsgPollError === e.body ){ | |
| 777 | + this.e.eMsgPollError = undefined; | |
| 778 | + } | |
| 779 | + if(e.e.body){ | |
| 780 | + this.deleteMessageElem(e.e.body); | |
| 781 | + } | |
| 782 | + return; | |
| 783 | + } else{ | |
| 769 | 784 | e = this.getMessageElemById(id); |
| 770 | 785 | } |
| 771 | 786 | if(e && id){ |
| 772 | 787 | D.remove(e); |
| 773 | 788 | if(e===this.e.newestMessage){ |
| 774 | 789 | this.fetchLastMessageElem(); |
| 775 | 790 | } |
| 776 | - F.toast.message("Deleted message "+id+"."); | |
| 791 | + if( !silent ){ | |
| 792 | + F.toast.message("Deleted message "+id+"."); | |
| 793 | + } | |
| 777 | 794 | } |
| 778 | 795 | return !!e; |
| 779 | 796 | }; |
| 780 | 797 | |
| 781 | 798 | /** |
| @@ -1107,10 +1124,11 @@ | ||
| 1107 | 1124 | |
| 1108 | 1125 | ctor.prototype = { |
| 1109 | 1126 | scrollIntoView: function(){ |
| 1110 | 1127 | this.e.content.scrollIntoView(); |
| 1111 | 1128 | }, |
| 1129 | + //remove: function(silent){Chat.deleteMessageElem(this, silent);}, | |
| 1112 | 1130 | setMessage: function(m){ |
| 1113 | 1131 | const ds = this.e.body.dataset; |
| 1114 | 1132 | ds.timestamp = m.mtime; |
| 1115 | 1133 | ds.lmtime = m.lmtime; |
| 1116 | 1134 | ds.msgid = m.msgid; |
| @@ -1284,12 +1302,21 @@ | ||
| 1284 | 1302 | const btnDeleteLocal = D.button("Delete locally"); |
| 1285 | 1303 | D.append(toolbar, btnDeleteLocal); |
| 1286 | 1304 | const self = this; |
| 1287 | 1305 | btnDeleteLocal.addEventListener('click', function(){ |
| 1288 | 1306 | self.hide(); |
| 1289 | - Chat.deleteMessageElem(eMsg); | |
| 1307 | + Chat.deleteMessageElem(eMsg) | |
| 1290 | 1308 | }); |
| 1309 | + if( eMsg.classList.contains('poller-connection') ){ | |
| 1310 | + const btnDeletePoll = D.button("Delete poller messages?"); | |
| 1311 | + D.append(toolbar, btnDeletePoll); | |
| 1312 | + btnDeletePoll.addEventListener('click', function(){ | |
| 1313 | + self.hide(); | |
| 1314 | + Chat.e.viewMessages.querySelectorAll('.message-widget.poller-connection') | |
| 1315 | + .forEach(e=>Chat.deleteMessageElem(e, true)); | |
| 1316 | + }); | |
| 1317 | + } | |
| 1291 | 1318 | if(Chat.userMayDelete(eMsg)){ |
| 1292 | 1319 | const btnDeleteGlobal = D.button("Delete globally"); |
| 1293 | 1320 | D.append(toolbar, btnDeleteGlobal); |
| 1294 | 1321 | F.confirmer(btnDeleteGlobal,{ |
| 1295 | 1322 | pinSize: true, |
| @@ -1713,15 +1740,16 @@ | ||
| 1713 | 1740 | clearTimeout(Chat.timer.tidReconnect); |
| 1714 | 1741 | Chat.timer.tidReconnect = 0; |
| 1715 | 1742 | } |
| 1716 | 1743 | Chat.timer.resetDelay(); |
| 1717 | 1744 | if( Chat.e.eMsgPollError ) { |
| 1745 | + const oldErrMsg = Chat.e.eMsgPollError; | |
| 1718 | 1746 | Chat.e.eMsgPollError = undefined; |
| 1719 | 1747 | if( showMsg ){ |
| 1720 | - Chat.reportReconnection( | |
| 1721 | - "Poller connection restored." | |
| 1722 | - ); | |
| 1748 | + const m = Chat.reportReconnection("Poller connection restored."); | |
| 1749 | + m.e.body.dataset.alsoRemove = oldErrMsg?.e?.body?.dataset?.msgid; | |
| 1750 | + D.addClass(m.e.body,'poller-connection'); | |
| 1723 | 1751 | } |
| 1724 | 1752 | } |
| 1725 | 1753 | setTimeout( Chat.poll, 0 ); |
| 1726 | 1754 | }; |
| 1727 | 1755 | |
| @@ -2610,10 +2638,11 @@ | ||
| 2610 | 2638 | Chat.e.eMsgPollError.e.content.innerText = msg; |
| 2611 | 2639 | }else { |
| 2612 | 2640 | /* Set current (new) error MessageWidget */ |
| 2613 | 2641 | Chat.e.eMsgPollError = Chat.reportErrorAsMessage(msg); |
| 2614 | 2642 | //Chat.playNewMessageSound();// browser complains b/c this wasn't via human interaction |
| 2643 | + D.addClass(Chat.e.eMsgPollError.e.body,'poller-connection'); | |
| 2615 | 2644 | } |
| 2616 | 2645 | Chat.timer.tidPoller = setTimeout(()=>{ |
| 2617 | 2646 | poll(); |
| 2618 | 2647 | }, delay); |
| 2619 | 2648 | } |
| @@ -2681,13 +2710,14 @@ | ||
| 2681 | 2710 | 1000 |
| 2682 | 2711 | ); |
| 2683 | 2712 | } |
| 2684 | 2713 | let nErr = 0; |
| 2685 | 2714 | F.fetch("chat-poll",{ |
| 2686 | - timeout: 1 | |
| 2687 | - ? 420 * 1000/*FIXME: get the value from the server*/ | |
| 2688 | - : 15000, | |
| 2715 | + timeout: window.location.hostname.match( | |
| 2716 | + "localhost" /*presumably local dev mode*/ | |
| 2717 | + ) ? 15000 | |
| 2718 | + : 420 * 1000/*FIXME: get the value from the server*/, | |
| 2689 | 2719 | urlParams:{ |
| 2690 | 2720 | name: Chat.mxMsg |
| 2691 | 2721 | }, |
| 2692 | 2722 | responseType: "json", |
| 2693 | 2723 | // Disable the ajax start/end handling for this long-polling op: |
| 2694 | 2724 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -758,24 +758,41 @@ | |
| 758 | /** |
| 759 | LOCALLY deletes a message element by the message ID or passing |
| 760 | the .message-row element. Returns true if it removes an element, |
| 761 | else false. |
| 762 | */ |
| 763 | cs.deleteMessageElem = function(id){ |
| 764 | var e; |
| 765 | if(id instanceof HTMLElement){ |
| 766 | e = id; |
| 767 | id = e.dataset.msgid; |
| 768 | }else{ |
| 769 | e = this.getMessageElemById(id); |
| 770 | } |
| 771 | if(e && id){ |
| 772 | D.remove(e); |
| 773 | if(e===this.e.newestMessage){ |
| 774 | this.fetchLastMessageElem(); |
| 775 | } |
| 776 | F.toast.message("Deleted message "+id+"."); |
| 777 | } |
| 778 | return !!e; |
| 779 | }; |
| 780 | |
| 781 | /** |
| @@ -1107,10 +1124,11 @@ | |
| 1107 | |
| 1108 | ctor.prototype = { |
| 1109 | scrollIntoView: function(){ |
| 1110 | this.e.content.scrollIntoView(); |
| 1111 | }, |
| 1112 | setMessage: function(m){ |
| 1113 | const ds = this.e.body.dataset; |
| 1114 | ds.timestamp = m.mtime; |
| 1115 | ds.lmtime = m.lmtime; |
| 1116 | ds.msgid = m.msgid; |
| @@ -1284,12 +1302,21 @@ | |
| 1284 | const btnDeleteLocal = D.button("Delete locally"); |
| 1285 | D.append(toolbar, btnDeleteLocal); |
| 1286 | const self = this; |
| 1287 | btnDeleteLocal.addEventListener('click', function(){ |
| 1288 | self.hide(); |
| 1289 | Chat.deleteMessageElem(eMsg); |
| 1290 | }); |
| 1291 | if(Chat.userMayDelete(eMsg)){ |
| 1292 | const btnDeleteGlobal = D.button("Delete globally"); |
| 1293 | D.append(toolbar, btnDeleteGlobal); |
| 1294 | F.confirmer(btnDeleteGlobal,{ |
| 1295 | pinSize: true, |
| @@ -1713,15 +1740,16 @@ | |
| 1713 | clearTimeout(Chat.timer.tidReconnect); |
| 1714 | Chat.timer.tidReconnect = 0; |
| 1715 | } |
| 1716 | Chat.timer.resetDelay(); |
| 1717 | if( Chat.e.eMsgPollError ) { |
| 1718 | Chat.e.eMsgPollError = undefined; |
| 1719 | if( showMsg ){ |
| 1720 | Chat.reportReconnection( |
| 1721 | "Poller connection restored." |
| 1722 | ); |
| 1723 | } |
| 1724 | } |
| 1725 | setTimeout( Chat.poll, 0 ); |
| 1726 | }; |
| 1727 | |
| @@ -2610,10 +2638,11 @@ | |
| 2610 | Chat.e.eMsgPollError.e.content.innerText = msg; |
| 2611 | }else { |
| 2612 | /* Set current (new) error MessageWidget */ |
| 2613 | Chat.e.eMsgPollError = Chat.reportErrorAsMessage(msg); |
| 2614 | //Chat.playNewMessageSound();// browser complains b/c this wasn't via human interaction |
| 2615 | } |
| 2616 | Chat.timer.tidPoller = setTimeout(()=>{ |
| 2617 | poll(); |
| 2618 | }, delay); |
| 2619 | } |
| @@ -2681,13 +2710,14 @@ | |
| 2681 | 1000 |
| 2682 | ); |
| 2683 | } |
| 2684 | let nErr = 0; |
| 2685 | F.fetch("chat-poll",{ |
| 2686 | timeout: 1 |
| 2687 | ? 420 * 1000/*FIXME: get the value from the server*/ |
| 2688 | : 15000, |
| 2689 | urlParams:{ |
| 2690 | name: Chat.mxMsg |
| 2691 | }, |
| 2692 | responseType: "json", |
| 2693 | // Disable the ajax start/end handling for this long-polling op: |
| 2694 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -758,24 +758,41 @@ | |
| 758 | /** |
| 759 | LOCALLY deletes a message element by the message ID or passing |
| 760 | the .message-row element. Returns true if it removes an element, |
| 761 | else false. |
| 762 | */ |
| 763 | cs.deleteMessageElem = function(id, silent){ |
| 764 | var e; |
| 765 | //console.warn("Chat.deleteMessageElem",id,silent); |
| 766 | if(id instanceof HTMLElement){ |
| 767 | e = id; |
| 768 | id = e.dataset.msgid; |
| 769 | delete e.dataset.msgid; |
| 770 | if( e?.dataset?.alsoRemove ){ |
| 771 | const xId = e.dataset.alsoRemove; |
| 772 | delete e.dataset.alsoRemove; |
| 773 | this.deleteMessageElem( xId ); |
| 774 | } |
| 775 | }else if(e instanceof Chat.MessageWidget) { |
| 776 | if( this.e.eMsgPollError === e.body ){ |
| 777 | this.e.eMsgPollError = undefined; |
| 778 | } |
| 779 | if(e.e.body){ |
| 780 | this.deleteMessageElem(e.e.body); |
| 781 | } |
| 782 | return; |
| 783 | } else{ |
| 784 | e = this.getMessageElemById(id); |
| 785 | } |
| 786 | if(e && id){ |
| 787 | D.remove(e); |
| 788 | if(e===this.e.newestMessage){ |
| 789 | this.fetchLastMessageElem(); |
| 790 | } |
| 791 | if( !silent ){ |
| 792 | F.toast.message("Deleted message "+id+"."); |
| 793 | } |
| 794 | } |
| 795 | return !!e; |
| 796 | }; |
| 797 | |
| 798 | /** |
| @@ -1107,10 +1124,11 @@ | |
| 1124 | |
| 1125 | ctor.prototype = { |
| 1126 | scrollIntoView: function(){ |
| 1127 | this.e.content.scrollIntoView(); |
| 1128 | }, |
| 1129 | //remove: function(silent){Chat.deleteMessageElem(this, silent);}, |
| 1130 | setMessage: function(m){ |
| 1131 | const ds = this.e.body.dataset; |
| 1132 | ds.timestamp = m.mtime; |
| 1133 | ds.lmtime = m.lmtime; |
| 1134 | ds.msgid = m.msgid; |
| @@ -1284,12 +1302,21 @@ | |
| 1302 | const btnDeleteLocal = D.button("Delete locally"); |
| 1303 | D.append(toolbar, btnDeleteLocal); |
| 1304 | const self = this; |
| 1305 | btnDeleteLocal.addEventListener('click', function(){ |
| 1306 | self.hide(); |
| 1307 | Chat.deleteMessageElem(eMsg) |
| 1308 | }); |
| 1309 | if( eMsg.classList.contains('poller-connection') ){ |
| 1310 | const btnDeletePoll = D.button("Delete poller messages?"); |
| 1311 | D.append(toolbar, btnDeletePoll); |
| 1312 | btnDeletePoll.addEventListener('click', function(){ |
| 1313 | self.hide(); |
| 1314 | Chat.e.viewMessages.querySelectorAll('.message-widget.poller-connection') |
| 1315 | .forEach(e=>Chat.deleteMessageElem(e, true)); |
| 1316 | }); |
| 1317 | } |
| 1318 | if(Chat.userMayDelete(eMsg)){ |
| 1319 | const btnDeleteGlobal = D.button("Delete globally"); |
| 1320 | D.append(toolbar, btnDeleteGlobal); |
| 1321 | F.confirmer(btnDeleteGlobal,{ |
| 1322 | pinSize: true, |
| @@ -1713,15 +1740,16 @@ | |
| 1740 | clearTimeout(Chat.timer.tidReconnect); |
| 1741 | Chat.timer.tidReconnect = 0; |
| 1742 | } |
| 1743 | Chat.timer.resetDelay(); |
| 1744 | if( Chat.e.eMsgPollError ) { |
| 1745 | const oldErrMsg = Chat.e.eMsgPollError; |
| 1746 | Chat.e.eMsgPollError = undefined; |
| 1747 | if( showMsg ){ |
| 1748 | const m = Chat.reportReconnection("Poller connection restored."); |
| 1749 | m.e.body.dataset.alsoRemove = oldErrMsg?.e?.body?.dataset?.msgid; |
| 1750 | D.addClass(m.e.body,'poller-connection'); |
| 1751 | } |
| 1752 | } |
| 1753 | setTimeout( Chat.poll, 0 ); |
| 1754 | }; |
| 1755 | |
| @@ -2610,10 +2638,11 @@ | |
| 2638 | Chat.e.eMsgPollError.e.content.innerText = msg; |
| 2639 | }else { |
| 2640 | /* Set current (new) error MessageWidget */ |
| 2641 | Chat.e.eMsgPollError = Chat.reportErrorAsMessage(msg); |
| 2642 | //Chat.playNewMessageSound();// browser complains b/c this wasn't via human interaction |
| 2643 | D.addClass(Chat.e.eMsgPollError.e.body,'poller-connection'); |
| 2644 | } |
| 2645 | Chat.timer.tidPoller = setTimeout(()=>{ |
| 2646 | poll(); |
| 2647 | }, delay); |
| 2648 | } |
| @@ -2681,13 +2710,14 @@ | |
| 2710 | 1000 |
| 2711 | ); |
| 2712 | } |
| 2713 | let nErr = 0; |
| 2714 | F.fetch("chat-poll",{ |
| 2715 | timeout: window.location.hostname.match( |
| 2716 | "localhost" /*presumably local dev mode*/ |
| 2717 | ) ? 15000 |
| 2718 | : 420 * 1000/*FIXME: get the value from the server*/, |
| 2719 | urlParams:{ |
| 2720 | name: Chat.mxMsg |
| 2721 | }, |
| 2722 | responseType: "json", |
| 2723 | // Disable the ajax start/end handling for this long-polling op: |
| 2724 |