Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch no-joy Excluding Merge-Ins
This is equivalent to a diff from 421d6570 to 7c3cf7a1
2020-12-27
| ||
06:48 | chat: next round of Safari-friendly baby steps, developed in conjunction with Safari user mgagnon via chat session. ... (check-in: a1161fa9 user: stephan tags: trunk) | |
04:50 | chat: reintegrated partial changes from [b0ab6cbd3] and [670732a6]: remove skin-induced div.content margins in chat-only mode and cap image preview size to avoid screen overflow. Moved #dbgMessage element out of the way at app startup to avoid it potentially influencing our flexbox layout, and include that element in the to-hide list for chat-only mode. Edit: Martin G. reports that this one also causes Grief with Safari, but in different ways that before. ... (Closed-Leaf check-in: 7c3cf7a1 user: stephan tags: no-joy) | |
04:30 | chat: re-integrated JS-based div.content resizer to do approximately what the preferred 'vh' CSS units would, but upon which Safari apparently chokes. Message area now gets a scrollbar. This works reasonably well on FF/Chrome on both Linux and Android. The jury is still out on Safari. Edit: Martin G. confirmed this one also suffers from the "collapsing messages" problem on Safari. ... (check-in: d488f5c6 user: stephan tags: no-joy) | |
03:39 | Eliminated top-down chat mode altogether in an attempt to eliminate some complexity and cruft. Re-added the toast-on-new-invisible-message from [0a00a103]. ... (check-in: 421d6570 user: stephan tags: trunk) | |
2020-12-26
| ||
22:09 | Disabled automatic scrolling when a new chat message arrives, as it is unnecessary when the user input fields are not sticky. To revisit later with sticky input fields. ... (check-in: b75ce865 user: stephan tags: trunk) | |
Changes to src/chat.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** This file contains the client-side implementation of fossil's /chat application. */ (function(){ const F = window.fossil, D = F.dom; const E1 = function(selector){ const e = document.querySelector(selector); if(!e) throw new Error("missing required DOM element: "+selector); return e; }; const isInViewport = function(e) { const rect = e.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; const Chat = (function(){ const cs = { e:{/*map of certain DOM elements.*/ messageInjectPoint: E1('#message-inject-point'), pageTitle: E1('head title'), loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */, inputWrapper: E1("#chat-input-area"), | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** This file contains the client-side implementation of fossil's /chat application. */ (function(){ const F = window.fossil, D = F.dom; const E1 = function(selector){ const e = document.querySelector(selector); if(!e) throw new Error("missing required DOM element: "+selector); return e; }; (function(){ let dbg = document.querySelector('#debugMsg'); if(dbg){ /* This can inadvertently influence our flexbox layouts, so move it out of the way. */ D.append(document.body,dbg); } })(); const isInViewport = function(e) { const rect = e.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; const ForceResizeKludge = 0 ? function(){} : (function(){ /* Workaround for Safari mayhem regarding use of vh CSS units.... We tried to use vh units to set the content area size for the chat layout, but Safari chokes on that, so we calculate that height here: 85% when in "normal" mode and 95% in chat-only mode. Larger than ~95% is too big for Firefox on Android, causing the input area to move off-screen. */ const contentArea = E1('div.content'), bcl = document.body.classList; const resized = function(){ const wh = window.innerHeight, mult = bcl.contains('chat-only-mode') ? 0.95 : 0.85; contentArea.style.maxHeight = (wh * mult)+"px"; //console.debug("resized.",wh, mult, window.getComputedStyle(contentArea).maxHeight); }; var doit; window.addEventListener('resize',function(ev){ clearTimeout(doit); doit = setTimeout(resized, 100); }, false); resized(); return resized; })(); const Chat = (function(){ const cs = { e:{/*map of certain DOM elements.*/ messageInjectPoint: E1('#message-inject-point'), pageTitle: E1('head title'), loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */, inputWrapper: E1("#chat-input-area"), |
︙ | ︙ | |||
118 119 120 121 122 123 124 | to avoid various race conditions in the UI and long-running network requests. */ ], /* Injects element e as a new row in the chat, at the top of the list if atEnd is falsy, else at the end of the list, before the load-history widget. */ injectMessageElem: function f(e, atEnd){ | | > | > > > < < > > > | > > > | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | to avoid various race conditions in the UI and long-running network requests. */ ], /* Injects element e as a new row in the chat, at the top of the 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.loadOlderToolbar : this.e.messageInjectPoint; /* Reminder: this placement is kinda odd because of the flex-direction:column-reverse in this.e.messagesWrapper, which reverses our directions. */ if(atEnd){ mip.parentNode.insertBefore(e, mip); }else{ const fe = mip.nextElementSibling; if(fe) mip.parentNode.insertBefore(e, fe); else D.append(mip.parentNode, e); } if(!atEnd && !this.isMassLoading && e.dataset.xfrom!==Chat.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(e.dataset.xfrom===Chat.me){ e.scrollIntoView(); } }, /** Returns true if chat-only mode is enabled. */ isChatOnlyMode: ()=>document.body.classList.contains('chat-only-mode'), /** Enters (if passed a truthy value or no arguments) or leaves "chat-only" mode. That mode hides the page's header and footer, leaving only the chat application visible to the user. */ chatOnlyMode: function f(yes){ if(undefined === f.elemsToToggle){ f.elemsToToggle = []; document.querySelectorAll( ["body > div.header", "body > div.mainmenu", "body > div.footer", "#debugMsg"].join(',') ).forEach((e)=>f.elemsToToggle.push(e)); } if(!arguments.length) yes = true; if(yes === this.isChatOnlyMode()) return this; if(yes){ D.addClass(f.elemsToToggle, 'hidden'); D.addClass(document.body, 'chat-only-mode'); document.body.scroll(0,document.body.height); }else{ D.removeClass(f.elemsToToggle, 'hidden'); D.removeClass(document.body, 'chat-only-mode'); } const msg = document.querySelector('.message-widget'); if(msg) setTimeout(()=>msg.scrollIntoView(),0); ForceResizeKludge(); return this; }, toggleChatOnlyMode: function(){ return this.chatOnlyMode(!this.isChatOnlyMode()); }, settings:{ get: (k,dflt)=>F.storage.get(k,dflt), |
︙ | ︙ |
Changes to src/default.css.
︙ | ︙ | |||
1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 | flex: 1 1 auto/*eliminates dead no-click zones on the right*/; } body.chat .chat-settings-popup > span.menu-entry > input[type=checkbox] { cursor: inherit; } /** Container for the list of /chat messages. */ body.chat #chat-messages-wrapper { } 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 the BOTTOM in bottom-up chat mode, such that they scroll up instead of down, we have to use column-reverse layout, which changes #chat-messages-wrapper's "gravity" for purposes of scrolling! If we instead use flex-direction:column then each new message pushes #chat-input-area down further off the screen! */ align-items: stretch; } /* Wrapper for /chat user input controls */ body.chat #chat-input-area { display: flex; flex-direction: column; padding: 0.5em 1em; border-bottom: none; border-top: 1px solid black; margin-bottom: 0; margin-top: 0.5em; | > > > > > > > > > > > > < < | 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 | flex: 1 1 auto/*eliminates dead no-click zones on the right*/; } body.chat .chat-settings-popup > span.menu-entry > input[type=checkbox] { cursor: inherit; } /** Container for the list of /chat messages. */ body.chat #chat-messages-wrapper { overflow: auto; max-height: 200em/*we *really* want approx. 85vh*/; display: flex; flex-direction: column-reverse/*necessary for scrolling gravity!*/; } 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 the BOTTOM in bottom-up chat mode, such that they scroll up instead of down, we have to use column-reverse layout, which changes #chat-messages-wrapper's "gravity" for purposes of scrolling! If we instead use flex-direction:column then each new message pushes #chat-input-area down further off the screen! */ align-items: stretch; } body.chat.chat-only-mode div.content { /*max-height: 95vh*//*larger than approx. this is too big for Firefox on Android*/; /* Some skins set margins and a max-width on div.content, but we needn't(?) honor those in chat-only mode. */ margin: 0; width: 100%; max-width: 100%; } /* Wrapper for /chat user input controls */ body.chat #chat-input-area { display: flex; flex-direction: column; padding: 0.5em 1em; border-bottom: none; border-top: 1px solid black; margin-bottom: 0; margin-top: 0.5em; } /* 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; |
︙ | ︙ | |||
1714 1715 1716 1717 1718 1719 1720 1721 | /* Widget holding the details of a selected/dropped file/image. */ body.chat #chat-drop-details { flex: 0 1 auto; padding: 0.5em 1em; margin-left: 0.5em; white-space: pre; font-family: monospace; } | > > > > | 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 | /* Widget holding the details of a selected/dropped file/image. */ body.chat #chat-drop-details { flex: 0 1 auto; padding: 0.5em 1em; margin-left: 0.5em; white-space: pre; font-family: monospace; } body.chat #chat-drop-details img { max-width: 45%; max-height: 45%; } |