Skip to content

Commit

Permalink
Per TODO, implement scene-automated timers (schedule-automated still …
Browse files Browse the repository at this point in the history
…to come)
  • Loading branch information
Rosuav committed May 20, 2024
1 parent 3f680d6 commit 58eb761
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
14 changes: 13 additions & 1 deletion httpstatic/chan_monitors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import choc, {set_content, DOM, on} from "https://rosuav.github.io/choc/factory.js";
const {A, BR, BUTTON, CODE, DIV, FIELDSET, INPUT, LABEL, LEGEND, OPTGROUP, OPTION, SELECT, SPAN, TABLE, TD, TEXTAREA, TH, TR} = choc; //autoimport
const {A, BR, BUTTON, CODE, DIV, FIELDSET, INPUT, LABEL, LEGEND, OPTGROUP, OPTION, P, SELECT, SPAN, TABLE, TD, TEXTAREA, TH, TR} = choc; //autoimport
import {update_display, formatters} from "$$static||monitor.js$$";
import {simpleconfirm, TEXTFORMATTING} from "$$static||utils.js$$";

Expand Down Expand Up @@ -99,6 +99,18 @@ set_content("#editcountdown form div", [
{name: "textcompleted", label: "Completed", desc: " If blank, same as Active"},
{name: "textinactive", label: "Inactive", desc: " If blank, same as Active"},
]}),
TABLE({border: 1}, [
TR(TH({colspan: 2}, "Automate timer based on...")),
TR([TH("Scene"), TD([
LABEL([INPUT({name: "startonscene", type: "checkbox"}),
" Start the countdown when this scene is selected"]),
P(["If this countdown is in an OBS scene and it becomes visible, the timer", BR(),
"will be started or reset. Good for break/BRB scenes."]),
LABEL(["Initial time ", INPUT({name: "startonscene_time", type: "number"}),
" Will count down from this time (eg 600 = ten minutes)"]),
])]),
TR([TH("Schedule"), TD("TODO: Link this timer to your Twitch schedule (maybe w/ offset)")]),
]),
]);

set_content("#editgoalbar form div", TABLE({border: 1}, [
Expand Down
12 changes: 12 additions & 0 deletions httpstatic/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ function countdown_ticker(elem, id) {
set_content(elem, parts.join(":"));
}

let lastvis = "hidden";
function vischange() {
if (lastvis === "hidden" && document.visibilityState === "visible") {
//We've just become visible. Signal the server to start the timer.
ws_sync.send({cmd: "sceneactive"});
}
lastvis = document.visibilityState;
}

export function render(data) {update_display(DOM("#display"), data.data);}
export function update_display(elem, data) { //Used for the preview as well as the live display
//Update styles. The server provides a single "text_css" attribute covering most of the easy
Expand Down Expand Up @@ -104,6 +113,9 @@ export function update_display(elem, data) { //Used for the preview as well as t
elem._stillebot_countdown_format = m[2];
elem._stillebot_countdown_interval = setInterval(countdown_ticker, 1000, elem, data.id);
countdown_ticker(elem, data.id);
if (data.startonscene && ws_group[0] !== '#') //Don't do this on the control/preview connection
(document.onvisibilitychange = vischange)();
else document.onvisibilitychange = null; //Note: Using this instead of on() for idempotency
}
else set_content(elem, data.display);
}
14 changes: 11 additions & 3 deletions modules/http/chan_monitors.pike
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ inherit hook;
inherit builtin_command;

/* Subset of functionality from mustard-mine.herokuapp.com:
* It can be autostarted on page activation - good for a break timer.
- On WS connection, if timer not active, start with a known countdown
* It can be linked to your Twitch schedule (see get_stream_schedule()) to define the target.
- Note that this will likely mean that schedule updates become crucial.
- Obviously will require a call to get_stream_schedule inside get_chan_state
Expand Down Expand Up @@ -44,7 +42,7 @@ constant vars_provided = ([
//Some of these attributes make sense only with certain types (eg needlesize is only for goal bars).
constant saveable_attributes = "previewbg barcolor fillcolor needlesize thresholds progressive lvlupcmd format width height "
"active bit sub_t1 sub_t2 sub_t3 exclude_gifts tip follow kofi_dono kofi_member kofi_renew kofi_shop "
"fw_dono fw_member fw_shop fw_gift textcompleted textinactive" / " " + TEXTFORMATTING_ATTRS;
"fw_dono fw_member fw_shop fw_gift textcompleted textinactive startonscene startonscene_time" / " " + TEXTFORMATTING_ATTRS;
constant valid_types = (<"text", "goalbar", "countdown">);

__async__ mapping(string:mixed) http_request(Protocols.HTTP.Server.Request req) {
Expand Down Expand Up @@ -128,6 +126,7 @@ mapping _get_monitor(object channel, mapping monitors, string id) {
"text_css": textformatting_css(text),
]);
}

bool need_mod(string grp) {return grp == "";} //Require mod status for the master socket
mapping get_chan_state(object channel, string grp, string|void id) {
mapping monitors = G->G->DB->load_cached_config(channel->userid, "monitors");
Expand Down Expand Up @@ -172,6 +171,15 @@ void websocket_cmd_setvar(mapping(string:mixed) conn, mapping(string:mixed) msg)
channel->set_variable(msg->varname, (string)(int)msg->val, "set");
}

//NOTE: This is a very rare message - a mutator that does not require mod powers or even a login.
//The *only* thing you can do with it is (re)start a countdown configured to start on scene.
void wscmd_sceneactive(object channel, mapping(string:mixed) conn, mapping(string:mixed) msg) {
mapping mon = G->G->DB->load_cached_config(channel->userid, "monitors")[conn->subgroup];
if (!mon->?startonscene) return;
sscanf(mon->text, "$%s$:", string varname);
channel->set_variable(varname, (string)(time() + (int)mon->startonscene_time));
}

@hook_allmsgs:
int message(object channel, mapping person, string msg)
{
Expand Down

0 comments on commit 58eb761

Please sign in to comment.