Skip to content

Instantly share code, notes, and snippets.

@jwc20
Last active September 5, 2025 13:53
Show Gist options
  • Save jwc20/ff047e804bb6bdce975e51a7afb82039 to your computer and use it in GitHub Desktop.
Save jwc20/ff047e804bb6bdce975e51a7afb82039 to your computer and use it in GitHub Desktop.
my Ubersicht widget for displaying Things task
Display current task on screen using: https://tracesof.net/uebersicht/
Current tasks are made using: https://culturedcode.com/things/
refreshFrequency: 60000
# homeDir = process.env['HOME']
# sqliteDb = homeDir + '/Library/Containers/com.culturedcode.things/Data/Library/Application\ Support/Cultured\ Code/Things/ThingsLibrary.db'
sqliteDb = '/Users/cjw/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/ThingsData-DC8DV/Things Database.thingsdatabase/main.sqlite'
#todaySql = 'select ZTITLE from ZTHING where ZTRASHED=0 AND ZSTATUS=0 AND ZFOCUSLEVEL IS NULL AND ZSCHEDULER =1 AND ZSTART==1 AND ZTYPE=0 ORDER BY ZTITLE ASC'
# todaySql = 'select title from TMTask where trashed=0 AND status=0 AND start=1 AND type=0 AND todayIndex<>0 ORDER BY todayIndex asc limit 1'
todaySql = 'SELECT title FROM TMTask WHERE trashed = 0 AND status = 0 AND start = 1 AND type = 0 AND todayIndex <> 0 AND title IS NOT NULL AND title<>"" ORDER BY todayIndex ASC LIMIT 1'
command: "sqlite3 '#{sqliteDb}' '#{todaySql}' | awk 'BEGIN {print \"\"} {print substr($0,0)\"<br />\"} /^[*]/ {print \"<blockquote><li>\"substr($0,2)\"</li></blockquote>\"} END {print \"\"}'"
style: """
border-radius: 6px
padding: 0px 20px
top: 1.6rem
left: 0.8rem
color: #fff
font-family: 'JetBrainsMono Nerd Font'
text-align: center
.datetime
font-size: 14px
color: #ffd700
opacity: 0.8
.timer-button
background: none
border: none
color: #ffd700
font-size: 14px
cursor: pointer
opacity: 0.8
transition: opacity 0.2s
font-family: 'JetBrainsMono Nerd Font'
.timer-button:hover
opacity: 1
h
display: block
text-align: center
font-size: 24px
font-weight: 100
div
display: block
ol
padding-left: 20px
.things_icon
float:left
.stopwatch
font-size: 14px
color: #ffd700
font-family: 'JetBrainsMono Nerd Font'
opacity: 0.8
.container
position: fixed
top: 0.14rem
.stopwatch-container
position: fixed
right: 1.8rem
display: flex
align-items: center
gap: 10px
.things-container
position: fixed
left: 1.8rem
transform: none
display: flex
align-items: center
justify-content: flex-start
gap: 5px
z-index: 1000
width: auto
min-width: 300px
max-width: 80vw
background: none
box-shadow: none
border: none
padding: 0
margin: 0
pointer-events: none
/* Ensures it stays above other content */
/* Adjust as needed for your layout */
.thingslist
font-size: 14px
white-space: nowrap
text-overflow: ellipsis
color: #fff
.completed
color: #888
font-weight: regular
text-decoration:line-through
.current-tasks-label
font-size: 15px
white-space: nowrap
text-overflow: ellipsis
font-style: italic
font-weight: 100
color: #ffd700
.current-tasks-label-arrow
font-size: 17px
white-space: nowrap
font-weight: bold
color: #ffd700
"""
# render: -> """
# <div class='container'>
# <div class='stopwatch-container'>
# <div class='datetime'></div>
# <div class='stopwatch'>00:00:00</div>
# <button class='timer-button' id='startPause'></button>
# <button class='timer-button' id='reset'></button>
# </div>
# <div class='things-container'>
# <div class='current-tasks-label'>Current Task</div>
# <div class='current-tasks-label-arrow' style='letter-spacing: 0.5em;'>=></div>
# <div class='thingslist'></div>
# </div>
# </div>
# """
render: -> """
<div class='container'>
<div class='stopwatch-container'>
<div class='datetime'></div>
</div>
<div class='things-container'>
<div class='current-tasks-label'>Current Task</div>
<div class='current-tasks-label-arrow' style='letter-spacing: 0.5em;'>=></div>
<div class='thingslist'></div>
</div>
</div>
"""
update: (output, domEl) ->
$(domEl).find('.thingslist').html(output)
afterRender: (domEl) ->
getPlanetarySymbol = (day) ->
symbols = {
0: '', # Sunday
1: '', # Monday
2: '', # Tuesday
3: '', # Wednesday
4: '', # Thursday
5: '', # Friday
6: '' # Saturday
}
symbols[day]
getDotPattern = (currentDay) ->
dots = []
for i in [0..6]
dots.push(if i == currentDay then '' else '')
dots.join(' ')
getDayOfWeek = (day) ->
days = {
0: 'Sunday',
1: 'Monday',
2: 'Tuesday',
3: 'Wednesday',
4: 'Thursday',
5: 'Friday',
6: 'Saturday',
}
days[day]
updateDateTime = ->
now = new Date()
year = now.getFullYear()
month = (now.getMonth() + 1).toString().padStart(2, '0')
day = now.getDate().toString().padStart(2, '0')
hours = now.getHours()
minutes = now.getMinutes().toString().padStart(2, '0')
ampm = if hours >= 12 then 'PM' else 'AM'
hours = hours % 12
hours = hours ? 12 # Convert 0 to 12
hours = hours.toString().padStart(2, '0') # Ensure two digits
# planetarySymbol = getPlanetarySymbol(now.getDay())
dayOfWeek = getDayOfWeek(now.getDay())
# dotPattern = getDotPattern(now.getDay())
$(domEl).find('.datetime').html("#{hours}.#{minutes}#{ampm} | #{year}-#{month}-#{day} | #{dayOfWeek}")
updateDateTime()
setInterval(updateDateTime, 60000) # Update every minute
startTime = null
isRunning = false
elapsedTime = 0
timerInterval = null
updateTimer = ->
if isRunning
currentTime = new Date()
diff = currentTime - startTime + elapsedTime
hours = Math.floor(diff / 3600000)
minutes = Math.floor((diff % 3600000) / 60000)
seconds = Math.floor((diff % 60000) / 1000)
timeString = "#{hours.toString().padStart(2, '0')}:#{minutes.toString().padStart(2, '0')}:#{seconds.toString().padStart(2, '0')}"
$(domEl).find('.stopwatch').html(timeString)
startPauseTimer = ->
if isRunning
isRunning = false
elapsedTime += new Date() - startTime
clearInterval(timerInterval)
$(domEl).find('#startPause').html('')
else
isRunning = true
startTime = new Date()
timerInterval = setInterval(updateTimer, 1000)
$(domEl).find('#startPause').html('')
resetTimer = ->
isRunning = false
startTime = null
elapsedTime = 0
clearInterval(timerInterval)
$(domEl).find('.stopwatch').html('00:00:00')
$(domEl).find('#startPause').html('')
$(domEl).find('#startPause').on 'click', startPauseTimer
$(domEl).find('#reset').on 'click', resetTimer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment