# Porting timer widget from the Touch Bar to a floating menu

**URL:** <https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658>\
**Category:** Floating Menus / Widgets\
**Tags:** floating-menu\
**Created:** [October 12, 2024, 4:43pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658 "2024-10-12T16:43:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jhncbrwn](https://community.folivora.ai/letter_avatar_proxy/v4/letter/j/58f4c7/32.png) [@jhncbrwn](https://community.folivora.ai/u/jhncbrwn)\
**Post date:** [October 12, 2024, 4:43pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/1 "2024-10-12T16:43:04Z")

</div>

Can somebody help to adapt the Simple timer Widget for the Touch Bar mentioned in [this thread](https://community.folivora.ai/t/simple-efficient-timer-widget/7927) to work as a floating menu, ideally putting it together in a preset?

I have extracted the scripts but don't know how to adapt them to the floating menus.

The scripts use for the original widget:

Script extracted from the Touch Bar widget json

```auto
tell application "BetterTouchTool"
	
	set remainingSeconds to get_number_variable remainingSeconds
	
	if (remainingSeconds is equal to 99999) or (remainingSeconds is equal to missing value) then --timer is not running and should be started
		
		--ask for the duration via a dialog popup
		set dialogAnswer to display dialog "Please set timer using HH:MM:SS (max. 24 hours):" default answer "00:00:05" --edit this to change the default time
		set answer to text returned of dialogAnswer
		set answerHours to text 1 thru 2 of answer as text
		set answerMinutes to text 4 thru 5 of answer as text
		set answerSeconds to text 7 thru 8 of answer as text
		
		set totalSeconds to (answerHours * 3600) + (answerMinutes * 60) + answerSeconds
		
		set_number_variable remainingSeconds to 99998
		
		repeat totalSeconds times --count
			
			if (get_number_variable remainingSeconds) ≠ 99999 then -- if the variable is 99999, that means the timer was pressed again and should be stopped
				
				set totalSeconds to (totalSeconds - 1)
				
				
				set_number_variable remainingSeconds to totalSeconds
				
				
				refresh_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10"
				
				
				
				delay 1
				
			end if
		end repeat
		
		if (get_number_variable remainingSeconds) ≠ 99999 then
			
			repeat 10 times --blink to signal that the time is up
				
				
				--update_touch_bar_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10" background_color 0,0,0,0
				
				
				delay 0.5
				
				
				-- update_touch_bar_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10" background_color 255,38,0,255
				
				
				
				delay 0.5
				
			end repeat
		end if
		
	else --timer is running and should be stopped
		set_number_variable remainingSeconds to 99999
		refresh_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10"
		
	end if
end tell

```

Script when widget is pressed

```auto
--https://community.folivora.ai/t/simple-efficient-timer-widget/7927

tell application "BetterTouchTool"
	
	set remainingSeconds to get_number_variable "remainingSeconds"
	
	if (remainingSeconds is equal to 99999) or (remainingSeconds is equal to missing value) then --timer is not running and should be started
		
		--ask for the duration via a dialog popup
		set dialogAnswer to display dialog "Please set timer using HH:MM:SS (max. 24 hours):" default answer "00:00:05" --edit this to change the default time
		set answer to text returned of dialogAnswer
		set answerHours to text 1 thru 2 of answer as text
		set answerMinutes to text 4 thru 5 of answer as text
		set answerSeconds to text 7 thru 8 of answer as text
		
		set totalSeconds to (answerHours * 3600) + (answerMinutes * 60) + answerSeconds
		
		set_number_variable "remainingSeconds" to 99998
		
		repeat totalSeconds times --count
			if (get_number_variable "remainingSeconds") ≠ 99999 then -- if the variable is 99999, that means the timer was pressed again and should be stopped
				set totalSeconds to (totalSeconds - 1)
				set_number_variable "remainingSeconds" to totalSeconds
				refresh_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10"
				delay 1
			end if
		end repeat
		
		if (get_number_variable "remainingSeconds") ≠ 99999 then
			repeat 10 times --blink to signal that the time is up
				update_touch_bar_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10" background_color "0,0,0,0"
				delay 0.5
				update_touch_bar_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10" background_color "255,38,0,255"
				delay 0.5
			end repeat
		end if
		
	else --timer is running and should be stopped
		set_number_variable "remainingSeconds" to 99999
		refresh_widget "2CA20DFA-8DAC-4E9A-A095-8BCC75ABAD10"
	end if
	
end tell

```

Script with the return value

```auto
--https://community.folivora.ai/t/simple-efficient-timer-widget/7927

tell application "BetterTouchTool"
	set remainingSeconds to get_number_variable "remainingSeconds"
	
	if (remainingSeconds is equal to 99999) or (remainingSeconds is equal to missing value) then -- the timer is not running
		return "timer"
	else -- the timer is running or is finished
		
		--create return text
		set outputSeconds to ((remainingSeconds mod 3600) mod 60) as integer
		set outputMinutes to (((remainingSeconds - outputSeconds) mod 3600) / 60) as integer
		set outputHours to ((remainingSeconds - outputMinutes * 60 - outputSeconds) / 3600) as integer
		if length of (outputSeconds as string) is equal to 1 then
			set outputSeconds to "0" & outputSeconds as string
		end if
		if length of (outputMinutes as string) is equal to 1 then
			set outputMinutes to "0" & outputMinutes as string
		end if
		
		--return text
		if outputHours is greater than 0 then
			return (outputHours & ":" & outputMinutes & ":" & outputSeconds) as string
		else
			return (outputMinutes & ":" & outputSeconds) as string
		end if
	end if
end tell

```

Thanks in advance for any help.

---

<div class="post-metadata">

**Author:** ![Andreas\_Hegenberg](https://community.folivora.ai/user_avatar/community.folivora.ai/andreas_hegenberg/32/39221_2.png) [@Andreas\_Hegenberg](https://community.folivora.ai/u/Andreas_Hegenberg)\
**Post date:** [October 12, 2024, 8:44pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/2 "2024-10-12T20:44:51Z")

</div>

So this should ask for the time, then just do a countdown?

---

<div class="post-metadata">

**Author:** ![Andreas\_Hegenberg](https://community.folivora.ai/user_avatar/community.folivora.ai/andreas_hegenberg/32/39221_2.png) [@Andreas\_Hegenberg](https://community.folivora.ai/u/Andreas_Hegenberg)\
**Post date:** [October 12, 2024, 9:00pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/3 "2024-10-12T21:00:32Z")

</div>

Here is a simple timer example:  
[timer\_example.bttpreset](https://community.folivora.ai/uploads/short-url/rt6kwA6g4e4b9GfkWOKfhiDjYDj.bttpreset) (46.2 KB)

The time is input in this format (examples):

1min

1h

1h 10min 5s

10min

30s

 ![image](https://community.folivora.ai/uploads/default/original/3X/6/1/6123fe615bba0fdc1ab730327e1a9b453b5cb687.png)

![image](https://community.folivora.ai/uploads/default/original/3X/c/d/cd5e8b7fc4f8bd99925e570b9bd6c73d73091bd5.png)

```auto
function parseDuration(duration) {
    const units = {
        h: 3600,
        min: 60,
        s: 1
    };
    
    // Regex to match the number followed by the unit (h, min, s)
    const regex = /(\d+)(h|min|s)/g;
    let totalSeconds = 0;
    let match;

    while ((match = regex.exec(duration)) !== null) {
        const value = parseInt(match[1], 10);
        const unit = match[2];
        totalSeconds += value * units[unit];
    }

    return totalSeconds;
}

function formatDuration(seconds) {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;

    // Pad with zeros to ensure two digits for minutes and seconds
    const formattedHours = String(hours).padStart(2, '0');
    const formattedMinutes = String(minutes).padStart(2, '0');
    const formattedSeconds = String(secs).padStart(2, '0');

    return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
}

async function startTimer() {
	let duration = await get_string_variable("timerTime");
 	let durationInSeconds = parseDuration(duration);
	timer(durationInSeconds);
}

async function timer(durationInSeconds = 10) {

	if(durationInSeconds == 0) {
		const updateDescription = {"BTTMenuItemText": "Time is up!", "BTTMenuItemBackgroundColor": "233, 0, 0, 255"};
   await update_menu_item({"item_uuid": "1D974882-9376-4B09-81FC-E427F79CBD25", "json": JSON.stringify(updateDescription), "persist": true})
   
	} else {

	const updateDescription = {"BTTMenuItemText": formatDuration(durationInSeconds), "BTTMenuItemBackgroundColor": "0, 0, 0, 255"};
   await update_menu_item({"item_uuid": "1D974882-9376-4B09-81FC-E427F79CBD25", "json": JSON.stringify(updateDescription), "persist": true})
   

   setTimeout(() => {
   	timer(durationInSeconds-1);	
   }, 1000);

}
	return "done"
}

```

---

<div class="post-metadata">

**Author:** ![jhncbrwn](https://community.folivora.ai/letter_avatar_proxy/v4/letter/j/58f4c7/32.png) [@jhncbrwn](https://community.folivora.ai/u/jhncbrwn)\
**Post date:** [October 12, 2024, 9:34pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/4 "2024-10-12T21:34:07Z")

</div>

Thanks for that, the presets help a lot in understanding how to do things.

In case it helps anybody I have uploaded my own my own attempt below:

[Stopwatch.bttpreset](https://community.folivora.ai/uploads/short-url/bKsJJe3XIf82IOmxPsh67oYH3Ii.bttpreset) (40.6 KB)

it is a very simple stopwatch showing elapsed minutes and it works with a temporary variable written to BetterTouchTool and it changes color at 5, 10 and 15 minutes.

![Screenshot 2024-10-12 at 16.26.41](https://community.folivora.ai/uploads/default/original/3X/f/9/f9ae657a0f3ed7264c3241dc3af84a43c75b3afe.png)

Please leave a comment if you find it useful! 😃

---

<div class="post-metadata">

**Author:** ![Andreas\_Hegenberg](https://community.folivora.ai/user_avatar/community.folivora.ai/andreas_hegenberg/32/39221_2.png) [@Andreas\_Hegenberg](https://community.folivora.ai/u/Andreas_Hegenberg)\
**Post date:** [October 12, 2024, 10:13pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/5 "2024-10-12T22:13:00Z")

</div>

Nice!! I’m currently working on documenting all the new scripting possibilities for floating menus with as many examples as possible. I’ll add this example as well

---

<div class="post-metadata">

**Author:** ![jhncbrwn](https://community.folivora.ai/letter_avatar_proxy/v4/letter/j/58f4c7/32.png) [@jhncbrwn](https://community.folivora.ai/u/jhncbrwn)\
**Post date:** [October 12, 2024, 10:14pm UTC](https://community.folivora.ai/t/porting-timer-widget-from-the-touch-bar-to-a-floating-menu/39658/6 "2024-10-12T22:14:10Z")

</div>

Great, and thank you for a great app and all your effort!
