alarms: 
caption: Alarms
created: 20200811043857487
modified: 20220725122018915
tags: 
title: $:/plugins/linonetwo/tw-calendar/lib/TiddlyTools/Time/Alarms
type: text/vnd.tiddlywiki
original-source: http://TiddlyTools.com
author: EricShulman

\define alarms_input()      $:/temp/time/alarms_input/$(currentTiddler)$
\define alarms_msg()        $:/temp/time/alarms_msg/$(freq)$/$(this_time)$
\define alarms_defaultmsg() BEEP! BEEP! BEEP!

\define alarms_form()
<style> .alarmEdit { width:3em; text-align:center; } </style>
<<alarms_form_freq>>
 at 
<<alarms_form_time>>
<span style={{{ [<alarms_input>get[freq]match[monthly]then[position:absolute]else[display:none;]] }}}>
   on the <<alarms_form_day>> day of the month</span>
<span style={{{ [<alarms_input>!has[freq]] [<alarms_input>get[freq]match[once]] +[limit[1]] +[else[visibility:hidden;]] }}}>
   on <<alarms_form_year>> <<alarms_form_month>> <<alarms_form_day>></span>
<br>
<<alarms_form_msg>>
<br>
<div style="display:flex;flex-direction:row;align-items:center;justify-content:center; margin-top: 0.5em;">
   <<alarms_add>> <<alarms_reset>>
</div>
\end

\define alarms_form_freq()
<$select tiddler=<<alarms_input>> field="freq" default="once" actions="<$action-deletefield $tiddler=<<alarms_input>> year month day />">
   <option value="once">Once</option>
   <option value="monthly">Monthly</option>
   <option value="daily">Daily</option>
   <$list filter="[all[shadows]prefix[$:/language/Date/Long/Day/]]">
      <option value={{{ [<currentTiddler>get[text]] }}}>
         {{{ [<currentTiddler>get[text]] }}}s
      </option>
   </$list>
</$select>
\end

\define alarms_form_year()
<$edit-text tag="input" class="alarmEdit alarmEditYear" tiddler=<<alarms_input>> field="year" default=<<now YYYY>> placeholder=<<now YYYY>> />
\end

\define alarms_form_month()
<$select tiddler=<<alarms_input>> field="month" default=<<now 0MM>>>
   <$list filter="[range[1,12]]">
      <option value={{{ [<currentTiddler>pad[2]] }}}>
         {{{ [<currentTiddler>addprefix[$:/language/Date/Long/Month/]get[text]] }}}
      </option>
   </$list>
</$select>
\end

\define alarms_form_day()
<!-- CALCULATE DAYS FOR SELECTED MONTH (ADJUST FOR LEAP YEARS) -->
<$set name="freq"  value={{{ [<alarms_input>get[freq]]               }}}>
<$set name="year"  value={{{ [<alarms_input>get[year]] ~[<now YYYY>] }}}>
<$set name="month" value={{{ [<alarms_input>get[month]] ~[<now MM>]  }}}>
<$set name="leap"  value={{{ [<year>remainder[4]match[0]then[yes]]   }}}>
<$set name="dpm"   value="31 28 31 30 31 30 31 31 30 31 30 31"> <!-- days per month -->
<$set name="dpm"   filter="[<leap>!match[]]" value="31 29 31 30 31 30 31 31 30 31 30 31" emptyValue=<<dpm>>>
<$set name="dm"    value={{{ [<dpm>split[ ]nth<month>] }}}> <!-- days in this month -->
<$set name="dm"    filter="[<freq>match[monthly]]" value="31" emptyValue=<<dm>>>
<$select tiddler=<<alarms_input>> field="day" default=<<now 0DD>>>
   <$list filter="[range<dm>]">
      <option value={{{ [<currentTiddler>pad[2]] }}}>
         <<currentTiddler>><$transclude tiddler={{{ [[$:/language/Date/DaySuffix/]addsuffix<currentTiddler>] }}}/>
      </option>
   </$list>
</$select>
\end

\define alarms_form_time()
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="hour"
  default={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0hh]]}}}
  placeholder="hh"
/>
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="min"
  default={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0mm]]}}}
  placeholder="mm"
/>
<$edit-text
  tag="input"
  class="alarmEdit"
  tiddler=<<alarms_input>>
  field="sec"
  default="00"
  placeholder="ss"
/>
\end

\define alarms_form_msg()
<style> .alarmMsg { width:calc(100% - 4.5em); } </style>
<$edit-text tag="input" class="alarmMsg" tiddler=<<alarms_input>> field="msg" default="" placeholder="enter a message" />
\end

\define alarms_add()
<!-- DEFAULTS -->
<$vars freq="once" year=<<now YYYY>> month=<<now 0MM>> day=<<now 0DD>> hour={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0hh]]}}} min={{{[<currentTiddler>get[startDate]format:date[TIMESTAMP]subtract[900000]parsedate:number[0mm]]}}} sec="00">
<!-- INPUTS -->
<$vars  freq={{{ [<alarms_input>get[freq]]  ~[<freq>]  }}}>
<$vars  year={{{ [<alarms_input>get[year]]  ~[<year>]  }}}>
<$vars month={{{ [<alarms_input>get[month]] ~[<month>] }}}>
<$vars   day={{{ [<alarms_input>get[day]]   ~[<day>]   }}}>
<$vars  hour={{{ [<alarms_input>get[hour]]  ~[<hour>]  }}}>
<$vars   min={{{ [<alarms_input>get[min]]   ~[<min>]   }}}>
<$vars   sec={{{ [<alarms_input>get[sec]]   ~[<sec>]   }}}>
<$vars   msg={{{ [<alarms_input>get[msg]]   +[encodeuricomponent[]search-replace:g[%20],[ ]] }}}>
<!-- ASSEMBLE NEW DATE -->
<$vars  date={{{ [<year>addsuffix[-]addsuffix<month>addsuffix[-]addsuffix<day>] }}}>
<$set   name="date" filter="[<freq>match[once]]"    value=<<date>>  emptyValue="">
<$set   name="date" filter="[<freq>match[monthly]]" value={{{ [[....-..-]addsuffix<day>] }}} emptyValue=<<date>>>
<!-- ASSEMBLE NEW TIME (ZERO-PADDED) -->
<$vars  hour={{{ [<hour>pad[2]] }}} min={{{ [<min>pad[2]] }}} sec={{{ [<sec>pad[2]] }}}>
<$vars  time={{{ [<hour>addsuffix[:]addsuffix<min>addsuffix[:]addsuffix<sec>]       }}}>
<$vars  time={{{ [<time>!match[--:--:--]search-replace:g[--],[00]else<time>]        }}}>
<!-- ASSEMBLE NEW ALARM -->
<$vars newalarm={{{ [<freq>addsuffix[;]addsuffix<date>addsuffix[;]addsuffix<time>addsuffix[;]addsuffix<msg>] }}}>
<!-- ADD/UPDATE ALARMS -->
<$vars old_alarm={{{ [<alarms_input>get[old_alarm]] }}}>
<$reveal default=<<old_alarm>> type="match" text="" style="flex:1;margin-right:1em;">
   <$button class="tc-button tt-button" style="width:100%" tooltip="add alarm">
      {{$:/core/images/new-button}}
      <$action-listops $tiddler=<<currentTiddler>> $field="alarms" $subfilter="[<newalarm>]" />
      <$action-deletetiddler $tiddler=<<alarms_input>> />
   </$button>
</$reveal>
<$reveal default=<<old_alarm>> type="nomatch" text="" style="flex:1;margin-right:1em;">
   <$button class="tc-button tt-button" tooltip="update alarm" style="width:100%">
      {{$:/core/images/done-button}}
      <$action-listops $tiddler=<<currentTiddler>> $field="alarms" $subfilter="[<newalarm>] +[replace<old_alarm>]" />
      <$action-deletetiddler $tiddler=<<alarms_input>> />
   </$button>
</$reveal>
</$vars>
\end

\define alarms_reset()
<$button class="tc-button tt-button" style="flex:1;margin-left:1em" tooltip="reset input">
   {{$:/core/images/close-button}}
   <$action-deletetiddler $tiddler=<<alarms_input>> />
</$button>
\end

\define alarms_edit()
<$button class="tc-button tt-button" tooltip="edit this alarm" actions=<<alarms_edit_actions>>>
   {{$:/core/images/edit-button}}
</$button>
\end

\define alarms_edit_actions()
<$vars this_year=<<now "YYYY">> this_month=<<now "0MM">> this_day=<<now "0DD">>>
<$vars  freq={{{ [<this_alarm>split[;]nth[1]split[@]nth[1]] }}}>
<$vars  year={{{ [<this_alarm>split[;]nth[2]split[-]nth[1]] ~[<this_year>]  +[!match[....]] }}}>
<$vars month={{{ [<this_alarm>split[;]nth[2]split[-]nth[2]] ~[<this_month>] +[!match[..]] }}}>
<$vars   day={{{ [<this_alarm>split[;]nth[2]split[-]nth[3]] ~[<this_day>]   +[!match[..]] }}}>
<$vars  hour={{{ [<this_alarm>split[;]nth[3]split[:]nth[1]]                 +[!match[--]] }}}>
<$vars   min={{{ [<this_alarm>split[;]nth[3]split[:]nth[2]]                 +[!match[--]] }}}>
<$vars   sec={{{ [<this_alarm>split[;]nth[3]split[:]nth[3]]                 +[!match[--]] }}}>
<$vars   msg={{{ [<this_alarm>split[;]nth[4]]                               +[decodeuricomponent[]] }}}>
<$action-setfield $tiddler=<<alarms_input>> old_alarm=<<this_alarm>> freq=<<freq>>
   year=<<year>> month=<<month>> day=<<day>> hour=<<hour>> min=<<min>> sec=<<sec>> msg=<<msg>> />
\end

\define alarms_delete()
<$button class="tc-button tt-button" tooltip="delete this alarm"> {{$:/core/images/delete-button}}
   <$action-setfield $tiddler="$(alarms_msg)$"
      subtitle="""Confirm: delete alarm"""
      text="""
         <$vars this_alarm="$(this_alarm)$">
         <$vars msg={{{ [<this_alarm>split[;]nth[4]] }}}>
         <$importvariables filter="TiddlyTools/Time/Alarms">
         @@font-size:2em; ''<<alarms_show>>'' @@<br>
         @@font-size:1.25em; ''<$text text={{{ [<msg>!match[]else<alarms_defaultmsg>] }}} />''@@
         </$importvariables>
         </$vars>
         </$vars>
         <br>&nbsp;<br>
         @@font-size:1.5em; Are you sure you want to delete this alarm? @@
      """
      footer="""
         <$button class="tc-button tt-button" message="tm-close-tiddler"> cancel
            <$action-deletetiddler $tiddler="$(alarms_msg)$" />
         </$button>
         <$button class="tc-button tt-button" message="tm-close-tiddler"> delete
            <$action-listops $tiddler="$(currentTiddler)$" $field="alarms" $subfilter="-[[$(this_alarm)$]]" />
            <$action-deletetiddler $tiddler="$(alarms_msg)$" />
         </$button>
      """ />
   <$action-sendmessage $message="tm-modal" $param="$(alarms_msg)$" />
</$button>
\end

\define alarms_deleteall()
<$list filter="[<currentTiddler>!has[alarms]!has[draft.of]]">
   <$button class="tc-btn-invisible" tooltip="delete all alarms"> @@fill:gray;{{$:/core/images/delete-button}}@@ </$button>
</$list>
<$list filter="[<currentTiddler>has[alarms]!has[draft.of]]">
<$button class="tc-btn-invisible" tooltip="delete all alarms"> {{$:/core/images/delete-button}}
   <$action-setfield $tiddler="$(alarms_msg)$"
      subtitle="""Confirm: delete all alarms"""
      text="""@@font-size:1.5em; Are you sure you want to delete all alarms?@@"""
      footer="""
         <$button class="tc-button tt-button" message="tm-close-tiddler"> cancel
            <$action-deletetiddler $tiddler="$(alarms_msg)$" />
         </$button>
         <$button class="tc-button tt-button" message="tm-close-tiddler"> delete
            <$action-setfield      $tiddler="$(currentTiddler)$" alarms="" />
            <$action-deletetiddler $tiddler="$(alarms_input)$"             />
            <$action-deletetiddler $tiddler="$(alarms_msg)$"               />
         </$button>
      """ />
   <$action-sendmessage $message="tm-modal" $param="$(alarms_msg)$" />
</$button>
\end

\define alarms_toggle()
\whitespace trim
<$vars freq={{{ [<this_alarm>split[;]nth[1]split[@]first[]] }}}
     paused={{{ [<this_alarm>split[;]nth[1]split[@]rest[]]  }}}
       date={{{ [<this_alarm>split[;]nth[2]] }}}
       time={{{ [<this_alarm>split[;]nth[3]] }}}
        msg={{{ [<this_alarm>split[;]nth[4]] }}}>
<$reveal default=<<paused>> type="match" text="">
   <$button class="tc-btn-invisible" tooltip="this alarm is active... click to pause" actions=<<alarms_pause>>>
      ''<<alarms_show>>'' {{$:/core/images/timestamp-on}}
   </$button>
</$reveal>
<$reveal default=<<paused>> type="nomatch" text="">
   <$reveal default=<<paused>> type="match" text="paused">
      <$button class="tc-btn-invisible" tooltip="this alarm is paused... click to resume" actions=<<alarms_resume>>>
         @@color:#999;fill:#999; ''<<alarms_show>>''@@ {{$:/core/images/timestamp-off}}
      </$button>
   </$reveal>
   <$reveal default=<<paused>> type="match" text="expired">
      <$button class="tc-btn-invisible" tooltip="this alarm has expired... click to edit" actions=<<alarms_edit_actions>>>
         @@color:#999;fill:#999; ''<<alarms_show>>''@@ {{$:/core/images/done-button}}
      </$button>
   </$reveal>
</$reveal>
\end

\define alarms_pause()
<$vars new_alarm={{{ [<freq>addsuffix[@paused]] [<date>] [<time>] [<msg>] +[join[;]] }}}>
<$action-setfield $timestamp="no" $tiddler=<<currentTiddler>> $field="alarms" $value={{{ [<currentTiddler>get[alarms]search-replace<this_alarm>,<new_alarm>] }}} />
\end

\define alarms_expire()
<$vars new_alarm={{{ [<freq>addsuffix[@expired]] [<date>] [<time>] [<msg>] +[join[;]] }}}>
<$action-setfield $timestamp="no" $tiddler=<<currentTiddler>> $field="alarms" $value={{{ [<currentTiddler>get[alarms]search-replace<this_alarm>,<new_alarm>] }}} />
\end

\define alarms_resume()
<$vars new_alarm={{{ [<freq>] [<date>] [<time>] [<msg>] +[join[;]] }}}>
<$action-setfield $timestamp="no" $tiddler=<<currentTiddler>> $field="alarms" $value={{{ [<currentTiddler>get[alarms]search-replace<this_alarm>,<new_alarm>] }}} />
\end

\define alarms_heading()
<$vars time=<<now "DDD, MMM DDth YYYY 0hh:0mm:0ss">>>
<span style="float:right;font-size:80%;">''<<time>>''</span>
<span title={{{ [[open ]addsuffix<currentTiddler>] }}}>
<$link>''<$view field="caption">Alarms</$view>''</$link>
<<alarms_deleteall>>
\end

\define alarms_list()
<style> .alarmTable table, .alarmTable tr, .alarmTable td { border:0;padding:0;margin:0; } </style>
<div class="alarmTable tt-shadowbox inset">
<table>
<$list filter={{!!alarms}} variable="this_alarm">
   <tr style="vertical-align:top;">
   <td style="white-space:nowrap;"> <<alarms_edit>> <<alarms_delete>> </td>
   <td style="white-space:nowrap;text-align:right;padding:0 0.5em;"> <<alarms_toggle>> </td>
   <td>
      <$vars msg={{{ [<this_alarm>split[;]nth[4]decodeuricomponent[]] }}}>
      <$list filter="[<msg>is[tiddler]]">  Action: <$link to=<<msg>> />                                  </$list>
      <$list filter="[<msg>!is[tiddler]]"> <$text text={{{ [<msg>!match[]else<alarms_defaultmsg>] }}} /> </$list>
      </$vars>
   </td>
   </tr>
</$list>
</table>
</div>
\end

\define alarms_show()
<$vars freq={{{ [<this_alarm>split[;]nth[1]split[@]first[]] }}}
       date={{{ [<this_alarm>split[;]nth[2]] }}}
        day={{{ [<this_alarm>split[;]nth[2]split[-]nth[3]trim:prefix[0]] }}}
       time={{{ [<this_alarm>split[;]nth[3]] }}}>
<$vars suffix={{{ [[$:/language/Date/DaySuffix/]addsuffix<day>get[text]] }}}>
<$list filter="[<freq>match[once]]"     >  <<date>> at </$list>
<$list filter="[<freq>match[daily]]"    > Every day at </$list>
<$list filter="[<freq>match[monthly]]"  > <<day>><<suffix>> of the month at </$list>
<$list filter="[<freq>!match[once]then<freq>!match[monthly]then<freq>!match[daily]]"> <<freq>>s at </$list>
<$list filter="[<time>!match[--:--:--]]"> <<time>> </$list>
<$list filter="[<time>match[--:--:--]]">  startup  </$list>
\end

\define alarms_tick()
<!-- CALLED EVERY SECOND FROM TiddlyTools/Time/Ticker -->
<$vars this_date=<<now "YYYY-0MM-0DD">> this_time=<<now "0hh:0mm:0ss">> this_day=<<now "DDD">> this_daynum=<<now "0DD">>>
<$list filter="[has[alarms]!has[draft.of]]">
<$list filter="[<currentTiddler>enlist{!!alarms}]" variable="this_alarm">
   <$vars freq={{{ [<this_alarm>split[;]nth[1]] }}}
          date={{{ [<this_alarm>split[;]nth[2]] }}}
        daynum={{{ [<this_alarm>split[;]nth[2]split[-]nth[3]] }}}
          time={{{ [<this_alarm>split[;]nth[3]] }}}
           msg={{{ [<this_alarm>split[;]nth[4]decodeuricomponent[]] }}}>
   <$reveal default=<<freq>> type="match" text="once">
      <$reveal default=<<date>> type="match" text=<<this_date>>>
         <$reveal default=<<time>> type="match" text=<<this_time>>> <<alarms_trigger>> </$reveal>
      </$reveal>
      <$vars when={{{ [<date>search-replace:g[-],[]] [<time>search-replace:g[--],[00]search-replace:g[:],[]] +[join[]addsuffix[000]] }}}>
      <$reveal default=<<when>> type="lt" text=<<now "YYYY0MM0DD0hh0mm0ss000">>> <<alarms_expire>> </$reveal>
      </$vars>
   </$reveal>
   <$reveal default=<<freq>> type="match" text="monthly">
      <$reveal default=<<daynum>> type="match" text=<<this_daynum>>>
         <$reveal default=<<time>> type="match" text=<<this_time>>> <<alarms_trigger>> </$reveal>
      </$reveal>
   </$reveal>
   <$reveal default=<<freq>> type="match" text="daily">
      <$reveal default=<<time>> type="match" text=<<this_time>>> <<alarms_trigger>> </$reveal>
   </$reveal>
   <$reveal default=<<freq>> type="match" text=<<this_day>>>
      <$reveal default=<<time>> type="match" text=<<this_time>>> <<alarms_trigger>> </$reveal>
   </$reveal>
   </$vars>
</$list>
</$list>
\end

\define alarms_startup()
<!-- CALLED AT STARTUP FROM TiddlyTools/Time/Ticker -->
<$vars this_date=<<now "YYYY-0MM-0DD">> this_day=<<now "DDD">> this_daynum=<<now "0DD">>>
<$list filter="[has[alarms]!has[draft.of]]">
<$list filter="[<currentTiddler>enlist{!!alarms}]" variable="this_alarm">
   <$vars freq={{{ [<this_alarm>split[;]nth[1]] }}}
          date={{{ [<this_alarm>split[;]nth[2]] }}}
        daynum={{{ [<this_alarm>split[;]nth[2]split[-]nth[3]] }}}
          time={{{ [<this_alarm>split[;]nth[3]] }}}
           msg={{{ [<this_alarm>split[;]nth[4]decodeuricomponent[]] }}}>
   <$reveal default=<<time>> type="match" text="--:--:--">
      <$reveal default=<<freq>> type="match" text="once">
         <$reveal default=<<date>> type="match" text=<<this_date>>> <<alarms_trigger>> </$reveal>
         <$vars when={{{ [<date>search-replace:g[-],[]addsuffix[000000000]] }}}>
         <$reveal default=<<when>> type="lt" text=<<now "YYYY0MM0DD0hh0mm0ss000">>> <<alarms_expire>> </$reveal>
         </$vars>
      </$reveal>
      <$reveal default=<<freq>> type="match" text="monthly">
         <$reveal default=<<daynum>> type="match" text=<<this_daynum>>> <<alarms_trigger>> </$reveal>
      </$reveal>
      <$reveal default=<<freq>> type="match" text="daily"     > <<alarms_trigger>> </$reveal>
      <$reveal default=<<freq>> type="match" text=<<this_day>>> <<alarms_trigger>> </$reveal>
   </$reveal>
   </$vars>
</$list>
</$list>
\end

\define alarms_trigger()
<$vars when=<<now "DDD, YYYY-0MM-0DD at 0hh:0mm:0ss">>>
<$list filter="[<msg>is[tiddler]]"  variable="do_action">  <$transclude tiddler=<<msg>> />      </$list>
<$list filter="[<msg>!is[tiddler]]" variable="do_message"> <<alarms_message msg:"""$(msg)$""">> </$list>
<$vars>
\end

\define alarms_message(msg)
<$reveal state=<<alarms_msg>> type="match" text="">
   <$action-setfield $tiddler=<<alarms_msg>>
      subtitle="""<span style="font-size:1.5em;"> <$text text={{{ [[$(currentTiddler)$]get[caption]else[$(currentTiddler)$]] }}} /> </span>"""
          text={{{ [[$msg$]!match[]else<alarms_defaultmsg>addprefix[@@font-size:2em;]addsuffix[@@]addprefix[<br>&nbsp;<br>]addprefix<when>] }}}
        footer="""
           <$button class="tc-button tt-button" message="tm-close-tiddler">
              view <$action-deletetiddler $tiddler="$(alarms_msg)$" />
              <$list filter="[[$:/StoryList]!contains[$(currentTiddler)$]]">
                 <$action-listops $subfilter="[[$(currentTiddler)$]] +[putfirst[]]" />
              </$list>
              <$action-navigate $to="$(currentTiddler)$"/>
           </$button>
           <$button class="tc-button tt-button" message="tm-close-tiddler">
              close <$action-deletetiddler $tiddler="$(alarms_msg)$" />
           </$button>
        """ />
   <$action-sendmessage $message="tm-modal" $param=<<alarms_msg>> />
   <$action-sendmessage $message="tm-notify" $param=<<alarms_msg>> />
</$reveal>
\end

<div style="display:inline-block;white-space:nowrap;margin-bottom:0.25em;">
   <<alarms_heading>><br>
   <<alarms_form>>
</div>
<$list filter="[{!!alarms}!match[]]" variable="has_alarms">
   <<alarms_list>>
</$list>