Fossil SCM

Animation tweaks and more predictable scrolling when the user filter is cleared (always scroll to the button).

stephan 2021-09-24 10:14 chat-user-filter
Commit 3d4101d354708a2661974aef661e68102a46eab61c4b09df2a99de748eac747a
2 files changed +34 -12 +2 -2
+34 -12
--- src/chat.js
+++ src/chat.js
@@ -202,10 +202,11 @@
202202
D.removeClass(this.e.inputCurrent, 'hidden');
203203
const mh2 = m.clientHeight;
204204
m.scrollTo(0, sTop + (mh1-mh2));
205205
this.e.inputCurrent.value = old.value;
206206
old.value = '';
207
+ D.addClassBriefly(this.e.inputCurrent, "anim-flip-v");
207208
return this;
208209
},
209210
/**
210211
If passed true or no arguments, switches to multi-line mode
211212
if currently in single-line mode. If passed false, switches
@@ -503,19 +504,25 @@
503504
setUserFilter: function(uname){
504505
this.filterState.activeUser = uname;
505506
const mw = this.e.viewMessages.querySelectorAll('.message-widget');
506507
const self = this;
507508
let eLast;
508
- mw.forEach(function(w){
509
- if(self.filterState.match(w.dataset.xfrom)){
510
- w.classList.remove('hidden');
511
- eLast = w;
512
- }else{
513
- w.classList.add('hidden');
514
- }
515
- });
509
+ if(!uname){
510
+ D.removeClass(Chat.e.viewMessages.querySelectorAll('.message-widget.hidden'),
511
+ 'hidden');
512
+ }else{
513
+ mw.forEach(function(w){
514
+ if(self.filterState.match(w.dataset.xfrom)){
515
+ w.classList.remove('hidden');
516
+ eLast = w;
517
+ }else{
518
+ w.classList.add('hidden');
519
+ }
520
+ });
521
+ }
516522
if(eLast) eLast.scrollIntoView(false);
523
+ else this.scrollMessagesTo(1);
517524
cs.e.activeUserList.querySelectorAll('.chat-user').forEach(function(e){
518525
e.classList[uname===e.dataset.uname ? 'add' : 'remove']('selected');
519526
});
520527
return this;
521528
}
@@ -987,11 +994,18 @@
987994
"Message in context",
988995
function(){
989996
self.hide();
990997
Chat.setUserFilter(false);
991998
eMsg.scrollIntoView(false);
992
- D.addClassBriefly(eMsg.firstElementChild, 'anim-rotate-360');
999
+ D.addClassBriefly(
1000
+ eMsg.firstElementChild, 'anim-rotate-360'
1001
+ //eMsg.firstElementChild, 'anim-flip-v'
1002
+ //eMsg.childNodes, 'anim-rotate-360'
1003
+ //eMsg.childNodes, 'anim-flip-v'
1004
+ //eMsg, 'anim-flip-v'
1005
+ );
1006
+ //D.addClassBriefly(eMsg.childNodes[1], 'anim-flip-h');
9931007
})
9941008
)
9951009
);
9961010
}/*jump-to button*/
9971011
}
@@ -1208,17 +1222,18 @@
12081222
persistentSetting: 'active-user-list',
12091223
callback: function(){
12101224
D.toggleClass(Chat.e.activeUserListWrapper,'hidden');
12111225
if(Chat.e.activeUserListWrapper.classList.contains('hidden')){
12121226
/* When hiding this element, undo all filtering */
1213
- D.removeClass(Chat.e.viewMessages.querySelectorAll('.message-widget.hidden'), 'hidden');
1227
+ Chat.setUserFilter(false);
12141228
/*Ideally we'd scroll the final message into view
12151229
now, but because viewMessages is currently hidden behind
12161230
viewConfig, scrolling is a no-op. */
12171231
Chat.scrollMessagesTo(1);
12181232
}else{
12191233
Chat.updateActiveUserList();
1234
+ D.addClassBriefly(Chat.e.activeUserListWrapper, "anim-flip-v");
12201235
}
12211236
}
12221237
}
12231238
};
12241239
/* Settings menu entries... Remember that they will be rendered in
@@ -1249,12 +1264,13 @@
12491264
label: "Timestamps in active users list",
12501265
boolValue: ()=>Chat.e.activeUserList.classList.contains('timestamps'),
12511266
persistentSetting: 'active-user-list-timestamps',
12521267
callback: function(){
12531268
D.toggleClass(Chat.e.activeUserList,'timestamps');
1254
- /* If the timestamp option is activated but optActiveUsers is not
1255
- currently checked then toggle that option on as well. */
1269
+ /* If the timestamp option is activated but
1270
+ namedOptions.activeUsers is not currently checked then
1271
+ toggle that option on as well. */
12561272
if(Chat.e.activeUserList.classList.contains('timestamps')
12571273
&& !namedOptions.activeUsers.boolValue()){
12581274
namedOptions.activeUsers.checkbox.checked = true;
12591275
namedOptions.activeUsers.callback();
12601276
}
@@ -1591,8 +1607,14 @@
15911607
Chat._gotServerError = poll.running = false;
15921608
if( window.fossil.config.chat.fromcli ){
15931609
Chat.chatOnlyMode(true);
15941610
}
15951611
Chat.intervalTimer = setInterval(poll, 1000);
1612
+ if(0){
1613
+ const flip = (ev)=>F.dom.addClassBriefly(ev.target,'anim-flip-h');
1614
+ document.querySelectorAll('#chat-edit-buttons button').forEach(function(e){
1615
+ e.addEventListener('click',flip, false);
1616
+ });
1617
+ }
15961618
setTimeout( ()=>Chat.inputFocus(), 0 );
15971619
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
15981620
})();
15991621
--- src/chat.js
+++ src/chat.js
@@ -202,10 +202,11 @@
202 D.removeClass(this.e.inputCurrent, 'hidden');
203 const mh2 = m.clientHeight;
204 m.scrollTo(0, sTop + (mh1-mh2));
205 this.e.inputCurrent.value = old.value;
206 old.value = '';
 
207 return this;
208 },
209 /**
210 If passed true or no arguments, switches to multi-line mode
211 if currently in single-line mode. If passed false, switches
@@ -503,19 +504,25 @@
503 setUserFilter: function(uname){
504 this.filterState.activeUser = uname;
505 const mw = this.e.viewMessages.querySelectorAll('.message-widget');
506 const self = this;
507 let eLast;
508 mw.forEach(function(w){
509 if(self.filterState.match(w.dataset.xfrom)){
510 w.classList.remove('hidden');
511 eLast = w;
512 }else{
513 w.classList.add('hidden');
514 }
515 });
 
 
 
 
 
516 if(eLast) eLast.scrollIntoView(false);
 
517 cs.e.activeUserList.querySelectorAll('.chat-user').forEach(function(e){
518 e.classList[uname===e.dataset.uname ? 'add' : 'remove']('selected');
519 });
520 return this;
521 }
@@ -987,11 +994,18 @@
987 "Message in context",
988 function(){
989 self.hide();
990 Chat.setUserFilter(false);
991 eMsg.scrollIntoView(false);
992 D.addClassBriefly(eMsg.firstElementChild, 'anim-rotate-360');
 
 
 
 
 
 
 
993 })
994 )
995 );
996 }/*jump-to button*/
997 }
@@ -1208,17 +1222,18 @@
1208 persistentSetting: 'active-user-list',
1209 callback: function(){
1210 D.toggleClass(Chat.e.activeUserListWrapper,'hidden');
1211 if(Chat.e.activeUserListWrapper.classList.contains('hidden')){
1212 /* When hiding this element, undo all filtering */
1213 D.removeClass(Chat.e.viewMessages.querySelectorAll('.message-widget.hidden'), 'hidden');
1214 /*Ideally we'd scroll the final message into view
1215 now, but because viewMessages is currently hidden behind
1216 viewConfig, scrolling is a no-op. */
1217 Chat.scrollMessagesTo(1);
1218 }else{
1219 Chat.updateActiveUserList();
 
1220 }
1221 }
1222 }
1223 };
1224 /* Settings menu entries... Remember that they will be rendered in
@@ -1249,12 +1264,13 @@
1249 label: "Timestamps in active users list",
1250 boolValue: ()=>Chat.e.activeUserList.classList.contains('timestamps'),
1251 persistentSetting: 'active-user-list-timestamps',
1252 callback: function(){
1253 D.toggleClass(Chat.e.activeUserList,'timestamps');
1254 /* If the timestamp option is activated but optActiveUsers is not
1255 currently checked then toggle that option on as well. */
 
1256 if(Chat.e.activeUserList.classList.contains('timestamps')
1257 && !namedOptions.activeUsers.boolValue()){
1258 namedOptions.activeUsers.checkbox.checked = true;
1259 namedOptions.activeUsers.callback();
1260 }
@@ -1591,8 +1607,14 @@
1591 Chat._gotServerError = poll.running = false;
1592 if( window.fossil.config.chat.fromcli ){
1593 Chat.chatOnlyMode(true);
1594 }
1595 Chat.intervalTimer = setInterval(poll, 1000);
 
 
 
 
 
 
1596 setTimeout( ()=>Chat.inputFocus(), 0 );
1597 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
1598 })();
1599
--- src/chat.js
+++ src/chat.js
@@ -202,10 +202,11 @@
202 D.removeClass(this.e.inputCurrent, 'hidden');
203 const mh2 = m.clientHeight;
204 m.scrollTo(0, sTop + (mh1-mh2));
205 this.e.inputCurrent.value = old.value;
206 old.value = '';
207 D.addClassBriefly(this.e.inputCurrent, "anim-flip-v");
208 return this;
209 },
210 /**
211 If passed true or no arguments, switches to multi-line mode
212 if currently in single-line mode. If passed false, switches
@@ -503,19 +504,25 @@
504 setUserFilter: function(uname){
505 this.filterState.activeUser = uname;
506 const mw = this.e.viewMessages.querySelectorAll('.message-widget');
507 const self = this;
508 let eLast;
509 if(!uname){
510 D.removeClass(Chat.e.viewMessages.querySelectorAll('.message-widget.hidden'),
511 'hidden');
512 }else{
513 mw.forEach(function(w){
514 if(self.filterState.match(w.dataset.xfrom)){
515 w.classList.remove('hidden');
516 eLast = w;
517 }else{
518 w.classList.add('hidden');
519 }
520 });
521 }
522 if(eLast) eLast.scrollIntoView(false);
523 else this.scrollMessagesTo(1);
524 cs.e.activeUserList.querySelectorAll('.chat-user').forEach(function(e){
525 e.classList[uname===e.dataset.uname ? 'add' : 'remove']('selected');
526 });
527 return this;
528 }
@@ -987,11 +994,18 @@
994 "Message in context",
995 function(){
996 self.hide();
997 Chat.setUserFilter(false);
998 eMsg.scrollIntoView(false);
999 D.addClassBriefly(
1000 eMsg.firstElementChild, 'anim-rotate-360'
1001 //eMsg.firstElementChild, 'anim-flip-v'
1002 //eMsg.childNodes, 'anim-rotate-360'
1003 //eMsg.childNodes, 'anim-flip-v'
1004 //eMsg, 'anim-flip-v'
1005 );
1006 //D.addClassBriefly(eMsg.childNodes[1], 'anim-flip-h');
1007 })
1008 )
1009 );
1010 }/*jump-to button*/
1011 }
@@ -1208,17 +1222,18 @@
1222 persistentSetting: 'active-user-list',
1223 callback: function(){
1224 D.toggleClass(Chat.e.activeUserListWrapper,'hidden');
1225 if(Chat.e.activeUserListWrapper.classList.contains('hidden')){
1226 /* When hiding this element, undo all filtering */
1227 Chat.setUserFilter(false);
1228 /*Ideally we'd scroll the final message into view
1229 now, but because viewMessages is currently hidden behind
1230 viewConfig, scrolling is a no-op. */
1231 Chat.scrollMessagesTo(1);
1232 }else{
1233 Chat.updateActiveUserList();
1234 D.addClassBriefly(Chat.e.activeUserListWrapper, "anim-flip-v");
1235 }
1236 }
1237 }
1238 };
1239 /* Settings menu entries... Remember that they will be rendered in
@@ -1249,12 +1264,13 @@
1264 label: "Timestamps in active users list",
1265 boolValue: ()=>Chat.e.activeUserList.classList.contains('timestamps'),
1266 persistentSetting: 'active-user-list-timestamps',
1267 callback: function(){
1268 D.toggleClass(Chat.e.activeUserList,'timestamps');
1269 /* If the timestamp option is activated but
1270 namedOptions.activeUsers is not currently checked then
1271 toggle that option on as well. */
1272 if(Chat.e.activeUserList.classList.contains('timestamps')
1273 && !namedOptions.activeUsers.boolValue()){
1274 namedOptions.activeUsers.checkbox.checked = true;
1275 namedOptions.activeUsers.callback();
1276 }
@@ -1591,8 +1607,14 @@
1607 Chat._gotServerError = poll.running = false;
1608 if( window.fossil.config.chat.fromcli ){
1609 Chat.chatOnlyMode(true);
1610 }
1611 Chat.intervalTimer = setInterval(poll, 1000);
1612 if(0){
1613 const flip = (ev)=>F.dom.addClassBriefly(ev.target,'anim-flip-h');
1614 document.querySelectorAll('#chat-edit-buttons button').forEach(function(e){
1615 e.addEventListener('click',flip, false);
1616 });
1617 }
1618 setTimeout( ()=>Chat.inputFocus(), 0 );
1619 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
1620 })();
1621
--- src/style.chat.css
+++ src/style.chat.css
@@ -382,11 +382,11 @@
382382
to {
383383
transform: rotate(360deg);
384384
}
385385
}
386386
body.chat .anim-flip-h {
387
- animation: flip-h 1s linear;
387
+ animation: flip-h 750ms linear;
388388
}
389389
@keyframes flip-h{
390390
from{
391391
transform: rotateY(0deg);
392392
}
@@ -393,15 +393,15 @@
393393
to{
394394
transform: rotateY(360deg);
395395
}
396396
}
397397
body.chat .anim-flip-v {
398
- animation: flip-v 1s linear;
398
+ animation: flip-v 750ms linear;
399399
}
400400
@keyframes flip-v{
401401
from{
402402
transform: rotateX(0deg);
403403
}
404404
to{
405405
transform: rotateX(360deg);
406406
}
407407
}
408408
--- src/style.chat.css
+++ src/style.chat.css
@@ -382,11 +382,11 @@
382 to {
383 transform: rotate(360deg);
384 }
385 }
386 body.chat .anim-flip-h {
387 animation: flip-h 1s linear;
388 }
389 @keyframes flip-h{
390 from{
391 transform: rotateY(0deg);
392 }
@@ -393,15 +393,15 @@
393 to{
394 transform: rotateY(360deg);
395 }
396 }
397 body.chat .anim-flip-v {
398 animation: flip-v 1s linear;
399 }
400 @keyframes flip-v{
401 from{
402 transform: rotateX(0deg);
403 }
404 to{
405 transform: rotateX(360deg);
406 }
407 }
408
--- src/style.chat.css
+++ src/style.chat.css
@@ -382,11 +382,11 @@
382 to {
383 transform: rotate(360deg);
384 }
385 }
386 body.chat .anim-flip-h {
387 animation: flip-h 750ms linear;
388 }
389 @keyframes flip-h{
390 from{
391 transform: rotateY(0deg);
392 }
@@ -393,15 +393,15 @@
393 to{
394 transform: rotateY(360deg);
395 }
396 }
397 body.chat .anim-flip-v {
398 animation: flip-v 750ms linear;
399 }
400 @keyframes flip-v{
401 from{
402 transform: rotateX(0deg);
403 }
404 to{
405 transform: rotateX(360deg);
406 }
407 }
408

Keyboard Shortcuts

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