Is your feature request related to a problem? Please describe.
In the current tag-picker such a widget would solve an issue with tags not animating when deleting a state-tiddler right after / before adding a tag
Describe the solution you'd like
An action widget like action-settimeout that invokes its actions given to the $actions attribute after the period given to the $timeout attribute
<$action-settimeout $actions="""<$action-deletetiddler $tiddler="my-state-tiddler"/>""" $timeout={{$:/config/AnimationDuration}}/>
@BurningTreeC Would it be accurate to describe the underlying problem as a need to be able to invoke some actions after the refresh cycle?
I've struggled with a similar problem at times. For example, a button that should show an input field (hidden in a reveal widget) and set focus to the input field with tm-focus-selector. The problem is that when tm-focus-selector is invoked, the input field does not exist yet.
\define myactions()
<$action-setfield $tiddler="mystate" text="show"/>
<$action-sendmessage $message="tm-focus-selector" $param=".myclass"/>
\end
<$reveal type="match" stateTitle="mystate" text="show" default="hide">
<$edit-text tiddler="temp" class="myclass"/>
</$reveal>
<$button actions=<<myactions>>>show input</$button>
In some situations you can work around this with triggering some actions in the body of a button and others in the actions attribute, but that is a clunky solution at best.
Hi @saqimtiaz
Would it be accurate to describe the underlying problem as a need to be able to invoke some actions after the refresh cycle?
No, in my usecase not. I have to wait for the Animation Duration to finish before I can delete a state Tiddler, which would cause the animation to fail if done earlier
@BurningTreeC thank you for clarifying. It's a similar though distinct problem. I've had some ideas for how to trigger actions after the refresh cycle but had not considered animations.
In some situations you can work around this with triggering some actions in the body of a button and others in the actions attribute, but that is a clunky solution at best.
That's right. .. I did have a similar problem once, where I used this as a workaround.
I've seen, that you did add a lot of animations lately. .... I personally don't like "some of them" too much.
I think animations are OK to guide the users visual attention.
If I'm adding or deleting tags in the edit template, I'm totally focused to that area on the screen. So I think this animation is not needed.
I'm OK with the view-mode animation of tags. Eg: if you click a "done" button, somewhere in the tiddler text.
I did create a "trigger - widget", which triggers some user actions whenever the trigger-widget is rendered.
see: https://wikilabs.github.io/editions/trigger/
IMO it should be relatively simple to add a timeout..
I've seen, that you did add a lot of animations lately. .... I personally don't like "some of them" too much.
@pmario - I didn't add that many animations, I just fixed them mostly with a \whitespace trim ... they should've already been there, the storyview="pop" was already set, apart from the animation in the $:/Manager - that one is new
Hi @BurningTreeC @saqimtiaz @pmario the fundamental problem with widgets triggering asynchronous actions is that widgets are volatile, and are created and deleted all the time. And so there's no guarantee that the widget instance that triggered a task is still around when the task comes to be executed
We've got away with widgets firing asynchronous tasks to update the DOM, but the inconsistencies mount as the tasks have more side effects, and are more long lived.
So, I think any mechanism for asynchronous tasks needs to be based around a startup module that manages and dispatches the tasks. Furthermore, we need to be able to capture variable values at the time the task is created and provide them to the task each time it is executed.
I've got a rough prototype of a task daemon below but I don't think it's sufficient (it doesn't do the variable capture for example).
/*\
title: $:/core/modules/startup/task-daemon.js
type: application/javascript
module-type: startup
Task daemon for widgets
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
// Export name and synchronous status
exports.name = "task-daemon";
exports.platforms = ["browser"];
exports.after = ["startup"];
exports.synchronous = true;
exports.startup = function() {
$tw.taskDaemon = new TaskDaemon();
};
function TaskDaemon() {
this.lastInvocationTime = {}; // Hashmap by task name of dates
}
/*
Options include:
widget: reference to the widget triggering the task
name: name for this task
actions: actions comprising the task
minimumInterval: minimum interval between invocations in milliseconds
*/
TaskDaemon.prototype.invoke = function(options) {
var now = new Date();
if(options.name) {
if(options.minimumInterval && this.lastInvocationTime[options.name]) {
if((now - this.lastInvocationTime[options.name]) < options.minimumInterval) {
return;
}
}
this.lastInvocationTime[options.name] = now;
}
console.log("Invoking actions",options.actions)
options.widget.invokeActionString(options.actions,options.widget,{});
}
})();
@Jermolene , this looks like a good starting point :smile:
Most helpful comment
Hi @BurningTreeC @saqimtiaz @pmario the fundamental problem with widgets triggering asynchronous actions is that widgets are volatile, and are created and deleted all the time. And so there's no guarantee that the widget instance that triggered a task is still around when the task comes to be executed
We've got away with widgets firing asynchronous tasks to update the DOM, but the inconsistencies mount as the tasks have more side effects, and are more long lived.
So, I think any mechanism for asynchronous tasks needs to be based around a startup module that manages and dispatches the tasks. Furthermore, we need to be able to capture variable values at the time the task is created and provide them to the task each time it is executed.
I've got a rough prototype of a task daemon below but I don't think it's sufficient (it doesn't do the variable capture for example).