Fossil SCM

Changed the "message in context" animation to something more eye-catching and less stuttery.

stephan 2021-09-24 09:29 chat-user-filter
Commit fc27d6a333f269b0dcfe283bdd9c3b9aaf1491f2b841d9a19ce271b08bf0ebc9
+1 -1
--- src/chat.js
+++ src/chat.js
@@ -987,11 +987,11 @@
987987
"Message in context",
988988
function(){
989989
self.hide();
990990
Chat.setUserFilter(false);
991991
eMsg.scrollIntoView(false);
992
- D.flashNTimes(eMsg, 3);
992
+ D.addClassBriefly(eMsg.firstElementChild, 'anim-rotate-360');
993993
})
994994
)
995995
);
996996
}/*jump-to button*/
997997
}
998998
--- src/chat.js
+++ src/chat.js
@@ -987,11 +987,11 @@
987 "Message in context",
988 function(){
989 self.hide();
990 Chat.setUserFilter(false);
991 eMsg.scrollIntoView(false);
992 D.flashNTimes(eMsg, 3);
993 })
994 )
995 );
996 }/*jump-to button*/
997 }
998
--- src/chat.js
+++ src/chat.js
@@ -987,11 +987,11 @@
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 }
998
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -694,10 +694,13 @@
694694
695695
3 arguments: 3rd may be a flash delay time or a callback
696696
function.
697697
698698
Returns this object but the flashing is asynchronous.
699
+
700
+ Depending on system load and related factors, a multi-flash
701
+ animation might stutter and look suboptimal.
699702
*/
700703
dom.flashNTimes = function(e,n,howLongMs,afterFlashCallback){
701704
const args = argsToArray(arguments);
702705
args.splice(1,1);
703706
if(arguments.length===3 && 'function'===typeof howLongMs){
@@ -717,11 +720,40 @@
717720
}
718721
};
719722
this.flashOnce.apply(this, args);
720723
return this;
721724
};
722
-
725
+
726
+ /**
727
+ Adds the given CSS class or array of CSS classes to the given
728
+ element or forEach-capable list of elements for howLongMs, then
729
+ removes it. If afterCallack is a function, it is called after the
730
+ CSS class is removed from all elements. If called with 3
731
+ arguments and the 3rd is a function, the 3rd is treated as a
732
+ callback and the default time (addClassBriefly.defaultTimeMs) is
733
+ used. If called with only 2 arguments, a time of
734
+ addClassBriefly.defaultTimeMs is used.
735
+
736
+ Returns this object but the CSS removal is asynchronous.
737
+ */
738
+ dom.addClassBriefly = function f(e, className, howLongMs, afterCallback){
739
+ if(arguments.length<4 && 'function'===typeof howLongMs){
740
+ afterCallback = howLongMs;
741
+ howLongMs = f.defaultTimeMs;
742
+ }else if(arguments.length<3 || !+howLongMs){
743
+ howLongMs = f.defaultTimeMs;
744
+ }
745
+ if(!e.forEach) e = [e];
746
+ this.addClass(e, className);
747
+ setTimeout(function(){
748
+ dom.removeClass(e, className);
749
+ if(afterCallback) afterCallback();
750
+ }, howLongMs);
751
+ return this;
752
+ };
753
+ dom.addClassBriefly.defaultTimeMs = 1000;
754
+
723755
/**
724756
Attempts to copy the given text to the system clipboard. Returns
725757
true if it succeeds, else false.
726758
*/
727759
dom.copyTextToClipboard = function(text){
728760
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -694,10 +694,13 @@
694
695 3 arguments: 3rd may be a flash delay time or a callback
696 function.
697
698 Returns this object but the flashing is asynchronous.
 
 
 
699 */
700 dom.flashNTimes = function(e,n,howLongMs,afterFlashCallback){
701 const args = argsToArray(arguments);
702 args.splice(1,1);
703 if(arguments.length===3 && 'function'===typeof howLongMs){
@@ -717,11 +720,40 @@
717 }
718 };
719 this.flashOnce.apply(this, args);
720 return this;
721 };
722
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
723 /**
724 Attempts to copy the given text to the system clipboard. Returns
725 true if it succeeds, else false.
726 */
727 dom.copyTextToClipboard = function(text){
728
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -694,10 +694,13 @@
694
695 3 arguments: 3rd may be a flash delay time or a callback
696 function.
697
698 Returns this object but the flashing is asynchronous.
699
700 Depending on system load and related factors, a multi-flash
701 animation might stutter and look suboptimal.
702 */
703 dom.flashNTimes = function(e,n,howLongMs,afterFlashCallback){
704 const args = argsToArray(arguments);
705 args.splice(1,1);
706 if(arguments.length===3 && 'function'===typeof howLongMs){
@@ -717,11 +720,40 @@
720 }
721 };
722 this.flashOnce.apply(this, args);
723 return this;
724 };
725
726 /**
727 Adds the given CSS class or array of CSS classes to the given
728 element or forEach-capable list of elements for howLongMs, then
729 removes it. If afterCallack is a function, it is called after the
730 CSS class is removed from all elements. If called with 3
731 arguments and the 3rd is a function, the 3rd is treated as a
732 callback and the default time (addClassBriefly.defaultTimeMs) is
733 used. If called with only 2 arguments, a time of
734 addClassBriefly.defaultTimeMs is used.
735
736 Returns this object but the CSS removal is asynchronous.
737 */
738 dom.addClassBriefly = function f(e, className, howLongMs, afterCallback){
739 if(arguments.length<4 && 'function'===typeof howLongMs){
740 afterCallback = howLongMs;
741 howLongMs = f.defaultTimeMs;
742 }else if(arguments.length<3 || !+howLongMs){
743 howLongMs = f.defaultTimeMs;
744 }
745 if(!e.forEach) e = [e];
746 this.addClass(e, className);
747 setTimeout(function(){
748 dom.removeClass(e, className);
749 if(afterCallback) afterCallback();
750 }, howLongMs);
751 return this;
752 };
753 dom.addClassBriefly.defaultTimeMs = 1000;
754
755 /**
756 Attempts to copy the given text to the system clipboard. Returns
757 true if it succeeds, else false.
758 */
759 dom.copyTextToClipboard = function(text){
760
--- src/style.chat.css
+++ src/style.chat.css
@@ -369,5 +369,39 @@
369369
}
370370
body.chat #chat-user-list .chat-user.selected {
371371
font-weight: bold;
372372
text-decoration: underline;
373373
}
374
+
375
+body.chat .anim-rotate-360 {
376
+ animation: rotate-360 1s linear;
377
+}
378
+@keyframes rotate-360 {
379
+ from {
380
+ transform: rotate(0deg);
381
+ }
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
+ 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
+}
374408
--- src/style.chat.css
+++ src/style.chat.css
@@ -369,5 +369,39 @@
369 }
370 body.chat #chat-user-list .chat-user.selected {
371 font-weight: bold;
372 text-decoration: underline;
373 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
--- src/style.chat.css
+++ src/style.chat.css
@@ -369,5 +369,39 @@
369 }
370 body.chat #chat-user-list .chat-user.selected {
371 font-weight: bold;
372 text-decoration: underline;
373 }
374
375 body.chat .anim-rotate-360 {
376 animation: rotate-360 1s linear;
377 }
378 @keyframes rotate-360 {
379 from {
380 transform: rotate(0deg);
381 }
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 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

Keyboard Shortcuts

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