timeline with a folding effect

$:/core/ui/SideBar/Recent How to turn this sidebar button into a timeline with a folding effect。

Roughly as follows: time is preceded by a collapse button

The contents of $:/core/ui/SideBar/Recent (and $:/core/ui/MoreSideBar/Recent) is:

<$macrocall $name="timeline" format={{$:/language/RecentChanges/DateFormat}}/>

Thus, both of these lists use the “timeline” macro, which is defined in $:/core/macros/timeline, like this:

<!-- Override one or both of the following two macros with a global or local macro of the same name 
if you need to change how titles are displayed on a timeline -->

\define timeline-title() <$view field="title"/>
\define timeline-link() <$link to={{!!title}}><<timeline-title>></$link>
\define timeline(limit:"100",format:"DDth MMM YYYY",subfilter:"",dateField:"modified")
\whitespace trim
<div class="tc-timeline">
<$list filter="[!is[system]$subfilter$has[$dateField$]!sort[$dateField$]limit[$limit$]eachday[$dateField$]]">
<div class="tc-menu-list-item">
<$view field="$dateField$" format="date" template="$format$"/>
<$list filter="[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]">
<div class="tc-menu-list-subitem">
<<timeline-link>>
</div>
</$list>
</div>
</$list>
</div>
\end

To add a “folding effect” to this code, make the following changes in $:/core/macros/timeline:

First, just above \define timeline-title() <$view field="title"/>, add

\define state() $:/state/Recent

This tiddler will be used to store the hide/show setting for each date in the list. Note that these settings will be saved with the file, so they will be applied each time you open your TiddlyWiki. If you want these settings to be reset each time you reload your TiddlyWiki, then change $:/state/Recent to $:/temp/Recent (which will automatically be discarded when you save the file).

Next, replace

<$view field="$dateField$" format="date" template="$format$"/>

with:

<$let date={{!!$dateField$}}
      hide={{{ [<state>has:index<date>then[hide]else[show]] }}}
       tip={{{ [<hide>match[show]then[hide]else[show] [<date>format:date[$format$]] +[join[ ]] }}}>
<$button class="tc-btn-invisible" tooltip=<<tip>>>
   <$view field="$dateField$" format="date" template="$format$"/> &nbsp;
   <$list filter="[<hide>match[hide]]"> {{$:/core/images/right-arrow}}
      <$action-setfield $tiddler=<<state>> $index=<<date>>/>
   </$list>
   <$list filter="[<hide>match[show]]"> {{$:/core/images/down-arrow}}
      <$action-setfield $tiddler=<<state>> $index=<<date>> $value="hide"/>
   </$list>
</$button>

This gets the current show/hide state for a given date, based on whether or not there is an index entry for that date in the $:/state/Recent tiddler. It then shows a $button that displays the formatted date followed by either a “right-arrow” or a “down-arrow”, with an appropriate tooltip. Clicking on this button adds/removes an index entry for that date in the $:/state/Recent tiddler. Note that I placed the right/down arrow icon AFTER the date text, so that it doesn’t alter the existing indentation for the sidebar list.

Lastly, replace these lines

<$list filter="[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]">
<div class="tc-menu-list-subitem">
<<timeline-link>>
</div>
</$list>

with:

<$list filter="[<hide>match[show]]" variable="show">
   <$list filter="[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]">
      <div class="tc-menu-list-subitem"><<timeline-link>></div>
   </$list>
</$list>
</$let>

This uses the value of the show/hide setting stored in the $:/state/Recent tiddler to conditionally display/omit the list of tiddlers for that date. Note that the final </$let> is needed to end the <$let date=...> widget that was added above.

Putting it all together, the new contents of $:/core/macros/timeline should be:

<!-- Override one or both of the following two macros with a global or local macro of the same name 
if you need to change how titles are displayed on a timeline -->

\define state() $:/state/Recent
\define timeline-title() <$view field="title"/>
\define timeline-link() <$link to={{!!title}}><<timeline-title>></$link>
\define timeline(limit:"100",format:"DDth MMM YYYY",subfilter:"",dateField:"modified")
\whitespace trim
<div class="tc-timeline">
<$list filter="[!is[system]$subfilter$has[$dateField$]!sort[$dateField$]limit[$limit$]eachday[$dateField$]]">
<div class="tc-menu-list-item">
<$let date={{!!$dateField$}}
      hide={{{ [<state>has:index<date>then[hide]else[show]] }}}
       tip={{{ [<hide>match[show]then[hide]else[show]] [<date>format:date[$format$]] +[join[ ]] }}}>
<$button class="tc-btn-invisible" tooltip=<<tip>>>
   <$view field="$dateField$" format="date" template="$format$"/> &nbsp;
   <$list filter="[<hide>match[hide]]"> {{$:/core/images/right-arrow}}
      <$action-setfield $tiddler=<<state>> $index=<<date>>/>
   </$list>
   <$list filter="[<hide>match[show]]"> {{$:/core/images/down-arrow}}
      <$action-setfield $tiddler=<<state>> $index=<<date>> $value="hide"/>
   </$list>
</$button>
<$list filter="[<hide>match[show]]" variable="show">
   <$list filter="[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]">
      <div class="tc-menu-list-subitem"><<timeline-link>></div>
   </$list>
</$list>
</$let>
</div>
</$list>
</div>
\end

Let me know how it goes…

enjoy,
-e

5 Likes

Thank you very much for your reply and guidance. I have successfully used it.