Add pomodoro plugin (port from legacy v4 plugin) (#69)
* add pomodoro plugin * add thumbnail.webp * fix translations * fix translation key * add required sections to README, add deps field to manifest * small fixes * fix config keys * review fixes * fix(readme) typos --------- Co-authored-by: Kirill Sergeev <sergeev@ap-team.ru> Co-authored-by: Lemmy <studio@quadbyte.net>
This commit is contained in:
co-authored by
Kirill Sergeev
Lemmy
parent
12532101dd
commit
144e7209ca
@@ -0,0 +1,178 @@
|
||||
local timeFontFamily = noctalia.loadFont("JetBrainsMono-Regular.ttf")
|
||||
|
||||
local function formatTime(seconds, total)
|
||||
local showingHours = total >= 3600 or seconds >= 3600
|
||||
local hours = math.floor(seconds / 3600)
|
||||
local mins = math.floor((seconds % 3600) / 60)
|
||||
local secs = seconds % 60
|
||||
|
||||
if showingHours then
|
||||
return string.format("%d:%02d:%02d", hours, mins, secs)
|
||||
else
|
||||
return string.format("%02d:%02d", mins, secs)
|
||||
end
|
||||
end
|
||||
|
||||
function onStartButtonClick()
|
||||
noctalia.state.set("pomodoro.nextCommand", "toggle")
|
||||
end
|
||||
|
||||
function onSkipButtonClick()
|
||||
noctalia.state.set("pomodoro.nextCommand", "skip")
|
||||
end
|
||||
|
||||
function onResetButtonClick()
|
||||
noctalia.state.set("pomodoro.nextCommand", "reset")
|
||||
end
|
||||
|
||||
function onResetAllButtonClick()
|
||||
noctalia.state.set("pomodoro.nextCommand", "resetAll")
|
||||
end
|
||||
|
||||
local function render(state, sessionData)
|
||||
local sessionNumber = state.sessionPtr.session
|
||||
local session = sessionData[sessionNumber]
|
||||
local stageNumber = state.sessionPtr.stage
|
||||
local stageTotalSeconds = session[stageNumber]
|
||||
|
||||
local stageName =
|
||||
if stageNumber == 1 then
|
||||
noctalia.tr("work")
|
||||
else if sessionNumber < #sessionData then
|
||||
noctalia.tr("short-break")
|
||||
else
|
||||
noctalia.tr("long-break")
|
||||
|
||||
local startButtonText =
|
||||
if state.isRunning then
|
||||
noctalia.tr("button.pause")
|
||||
else if state.secondsLeft > 0 and state.secondsLeft < stageTotalSeconds then
|
||||
noctalia.tr("button.resume")
|
||||
else
|
||||
noctalia.tr("button.start")
|
||||
|
||||
local startButtonGlyph = if state.isRunning then "player-pause" else "player-play"
|
||||
|
||||
local skipButtonEnabled = state.isDirty and (if state.isRunning then state.secondsLeft > 0 else stageTotalSeconds > 0)
|
||||
|
||||
local resetButtonEnabled = state.isDirty and state.secondsLeft > 0
|
||||
|
||||
local resetAllButtonEnabled = state.isDirty and (state.isRunning or state.secondsLeft > 0 or (state.sessionPtr.session > 1 and state.sessionPtr.stage > 1))
|
||||
|
||||
local stageIcon = if state.sessionPtr.stage == 1 then "brain" else "coffee"
|
||||
|
||||
panel.render(
|
||||
ui.column({ flexGrow = 1, gap = 16 }, {
|
||||
-- header
|
||||
ui.row({ align = "center", gap = 8 }, {
|
||||
ui.glyph({ name = stageIcon, color = "primary" }),
|
||||
|
||||
ui.label({
|
||||
text = "Pomodoro",
|
||||
fontSize = 18,
|
||||
fontWeight = "bold",
|
||||
color = "on_surface",
|
||||
flexGrow = 1,
|
||||
}),
|
||||
|
||||
ui.label({
|
||||
text = string.format("%s %d/%d", noctalia.tr("session"), sessionNumber, #sessionData),
|
||||
fontSize = 12,
|
||||
color = "on_surface_variant",
|
||||
}),
|
||||
}),
|
||||
|
||||
-- time
|
||||
ui.column({ flexGrow = 1, align = "center", justify = "center", }, {
|
||||
ui.label({
|
||||
text = stageName,
|
||||
fontSize = 18,
|
||||
fontWeight = "medium",
|
||||
color = "primary",
|
||||
}),
|
||||
|
||||
ui.label({
|
||||
text = formatTime(state.secondsLeft, stageTotalSeconds),
|
||||
fontSize = 42,
|
||||
fontWeight = "bold",
|
||||
fontFamily = timeFontFamily,
|
||||
color = "primary",
|
||||
}),
|
||||
}),
|
||||
|
||||
-- buttons
|
||||
ui.column({ gap = 8 }, {
|
||||
ui.row({ gap = 8, justify = "space_between" }, {
|
||||
ui.button({
|
||||
variant = "primary",
|
||||
text = startButtonText,
|
||||
glyph = startButtonGlyph,
|
||||
onClick = "onStartButtonClick",
|
||||
flexGrow = 1,
|
||||
}),
|
||||
|
||||
ui.button({
|
||||
text = noctalia.tr("button.skip"),
|
||||
glyph = "player-skip-forward",
|
||||
onClick = "onSkipButtonClick",
|
||||
enabled = skipButtonEnabled,
|
||||
flexGrow = 1,
|
||||
}),
|
||||
}),
|
||||
|
||||
ui.row({ gap = 8, justify = "space_between" }, {
|
||||
ui.button({
|
||||
text = noctalia.tr("button.reset"),
|
||||
glyph = "refresh",
|
||||
onClick = "onResetButtonClick",
|
||||
enabled = resetButtonEnabled,
|
||||
flexGrow = 1,
|
||||
}),
|
||||
|
||||
ui.button({
|
||||
text = noctalia.tr("button.reset-all"),
|
||||
glyph = "rotate",
|
||||
onClick = "onResetAllButtonClick",
|
||||
enabled = resetAllButtonEnabled,
|
||||
flexGrow = 1,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}) -- column
|
||||
) -- panel
|
||||
end
|
||||
|
||||
function onOpen(context)
|
||||
local state = noctalia.state.get("pomodoro.state")
|
||||
local sessionData = noctalia.state.get("pomodoro.sessionData")
|
||||
render(state, sessionData)
|
||||
end
|
||||
|
||||
local function notifyStageFinished(state, sessionData)
|
||||
local sessionNumber = state.sessionPtr.session
|
||||
local stageNumber = state.sessionPtr.stage
|
||||
local body =
|
||||
if stageNumber == 1 then
|
||||
noctalia.tr("notification.work-complete")
|
||||
elseif sessionNumber < #sessionData then
|
||||
noctalia.tr("notification.short-break-complete")
|
||||
else
|
||||
noctalia.tr("notification.long-break-complete")
|
||||
noctalia.notify("Pomodoro Timer", body)
|
||||
end
|
||||
|
||||
--- main
|
||||
noctalia.state.watch("pomodoro.state", function(state)
|
||||
local config = noctalia.state.get("pomodoro.config")
|
||||
local sessionData = noctalia.state.get("pomodoro.sessionData")
|
||||
|
||||
if state.secondsLeft == 0 then
|
||||
notifyStageFinished(state, sessionData)
|
||||
noctalia.state.set("pomodoro.nextCommand", "skip")
|
||||
if (config.autoStartWork and state.sessionPtr.stage == 2) or (config.autoStartBreaks and state.sessionPtr.stage == 1) then
|
||||
noctalia.state.set("pomodoro.nextCommand", "toggle")
|
||||
end
|
||||
end
|
||||
|
||||
render(state, sessionData)
|
||||
end)
|
||||
Reference in New Issue
Block a user