117 lines
2.6 KiB
Lua
117 lines
2.6 KiB
Lua
|
|
local mp = require 'mp'
|
||
|
|
local utils = require 'mp.utils'
|
||
|
|
|
||
|
|
local SLEEP_MENU_TYPE = 'medeia_sleep_timer_prompt'
|
||
|
|
|
||
|
|
local _timer = nil
|
||
|
|
|
||
|
|
local function _trim(s)
|
||
|
|
s = tostring(s or '')
|
||
|
|
s = s:gsub('^%s+', '')
|
||
|
|
s = s:gsub('%s+$', '')
|
||
|
|
return s
|
||
|
|
end
|
||
|
|
|
||
|
|
local function _cancel_timer()
|
||
|
|
if _timer ~= nil then
|
||
|
|
pcall(function()
|
||
|
|
_timer:kill()
|
||
|
|
end)
|
||
|
|
_timer = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function _parse_minutes(text)
|
||
|
|
local s = _trim(text)
|
||
|
|
if s == '' then
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local lower = s:lower()
|
||
|
|
|
||
|
|
-- allow: 15, 15m, 1h, 1.5h
|
||
|
|
local hours = lower:match('^([%d%.]+)%s*h$')
|
||
|
|
if hours then
|
||
|
|
local v = tonumber(hours)
|
||
|
|
if v and v > 0 then
|
||
|
|
return v * 60
|
||
|
|
end
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local mins = lower:match('^([%d%.]+)%s*m$')
|
||
|
|
if mins then
|
||
|
|
local v = tonumber(mins)
|
||
|
|
if v and v > 0 then
|
||
|
|
return v
|
||
|
|
end
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local v = tonumber(lower)
|
||
|
|
if v and v > 0 then
|
||
|
|
return v
|
||
|
|
end
|
||
|
|
|
||
|
|
return nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local function _open_prompt()
|
||
|
|
local menu_data = {
|
||
|
|
type = SLEEP_MENU_TYPE,
|
||
|
|
title = 'Sleep Timer',
|
||
|
|
search_style = 'palette',
|
||
|
|
search_debounce = 'submit',
|
||
|
|
on_search = 'callback',
|
||
|
|
footnote = 'Enter minutes (e.g. 30) then press Enter.',
|
||
|
|
callback = { mp.get_script_name(), 'medeia-sleep-timer-event' },
|
||
|
|
items = {},
|
||
|
|
}
|
||
|
|
|
||
|
|
local json = utils.format_json(menu_data)
|
||
|
|
local ok = pcall(function()
|
||
|
|
mp.commandv('script-message-to', 'uosc', 'open-menu', json)
|
||
|
|
end)
|
||
|
|
if not ok then
|
||
|
|
mp.osd_message('Sleep timer: uosc not available', 2.0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function _handle_event(json)
|
||
|
|
local ok, ev = pcall(utils.parse_json, json)
|
||
|
|
if not ok or type(ev) ~= 'table' then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
if ev.type ~= 'search' then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local minutes = _parse_minutes(ev.query or '')
|
||
|
|
if not minutes then
|
||
|
|
mp.osd_message('Sleep timer cancelled', 1.0)
|
||
|
|
_cancel_timer()
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
_cancel_timer()
|
||
|
|
|
||
|
|
local seconds = math.floor(minutes * 60)
|
||
|
|
_timer = mp.add_timeout(seconds, function()
|
||
|
|
mp.osd_message('Sleep timer: closing mpv', 1.5)
|
||
|
|
mp.commandv('quit')
|
||
|
|
end)
|
||
|
|
|
||
|
|
mp.osd_message(string.format('Sleep timer set: %d min', math.floor(minutes + 0.5)), 1.5)
|
||
|
|
|
||
|
|
pcall(function()
|
||
|
|
mp.commandv('script-message-to', 'uosc', 'close-menu', SLEEP_MENU_TYPE)
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
mp.register_script_message('medeia-sleep-timer', _open_prompt)
|
||
|
|
mp.register_script_message('medeia-sleep-timer-event', _handle_event)
|
||
|
|
|
||
|
|
return {
|
||
|
|
open_prompt = _open_prompt,
|
||
|
|
}
|