diff options
| author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2026-01-16 17:23:32 -0800 |
|---|---|---|
| committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2026-01-16 17:23:32 -0800 |
| commit | b3ec50d92451b99dd08b6030b08854c8cc77524b (patch) | |
| tree | af8c8adc994478de00ce4f3be8601b64a2d0dfdf /main.lua | |
| parent | 671e5934a9400b722210d4d243dd83c0755a4fa3 (diff) | |
| download | mpv-iptv-menu-b3ec50d92451b99dd08b6030b08854c8cc77524b.tar.gz mpv-iptv-menu-b3ec50d92451b99dd08b6030b08854c8cc77524b.tar.xz | |
track and flush OSD changes for fewer redraws
Diffstat (limited to 'main.lua')
| -rw-r--r-- | main.lua | 147 |
1 files changed, 81 insertions, 66 deletions
@@ -60,12 +60,17 @@ local osd = _osd.new({ end, }) -local function update_osd() - osd:redraw(state) -end - -local function osd_menu_lines() - return osd:menu_lines(state) +local function cache_miss_status_msg(str) + -- doesn't redraw after clearing message + return { + before_miss = function() + osd:set_status(str) + osd:redraw(state) + end, + after_miss = function() + osd:set_status() + end, + } end local function set_key_mapping(m) @@ -73,27 +78,46 @@ local function set_key_mapping(m) end local function load_data() - osd:set_status('Loading catalogue...') - update_osd() local arr = { {id = 'live', name = 'Live TV', type = 'live'}, {id = 'movie', name = 'Movies', type = 'vod'}, {id = 'series', name = 'Series', type = 'series'}, } + + local base_str = 'Loading catalogue' + local sect_str + local disp_str + local call_opts = { + before_hit = function() + if disp_str ~= base_str and disp_str ~= sect_str then + osd:set_status(base_str .. '...') + osd:redraw(state) + disp_str = base_str + end + end, + before_miss = function() + if disp_str ~= sect_str then + osd:set_status(sect_str .. '...') + osd:redraw(state) + disp_str = sect_str + end + end, + } for _, v in ipairs(arr) do - v.categories = xc['get_' .. v.type .. '_categories'](xc) - v.elements = xc[ + sect_str = base_str .. ' ยป ' .. v.name + v.categories = xc:with_opts( + 'get_' .. v.type .. '_categories', call_opts) + v.elements = xc:with_opts( v.type == 'series' and 'get_series' or - ('get_' .. v.type .. '_streams')](xc) + ('get_' .. v.type .. '_streams'), + call_opts) + catalogue:load_xc_section(v) end - catalogue:load_xc_data(arr) osd:set_status('Loading EPG...') - update_osd() + osd:redraw(state) epg:load_xc_data(xc:get_epg()) - osd:set_status() - update_osd() local t = util.read_json_file(config.favourites_file) state.favourites = t.favourites or {} @@ -105,10 +129,9 @@ local function save_favourites() end local function set_cursor(pos, opts) - local moved = state:menu():set_cursor(pos, osd_menu_lines(), opts) - - if moved and not (opts and opts.skip_redraw) then - update_osd() + local moved = state:menu():set_cursor(pos, osd:menu_lines(state), opts) + if moved then + osd:dirty() end end @@ -130,20 +153,20 @@ end local function cursor_page_up() set_cursor( - state:menu().cursor - osd_menu_lines(), + state:menu().cursor - osd:menu_lines(state), {keep_offset = true, margin = config.scroll_margin}) end local function cursor_page_down() set_cursor( - state:menu().cursor + osd_menu_lines(), + state:menu().cursor + osd:menu_lines(state), {keep_offset = true, margin = config.scroll_margin}) end local function cursor_to_object(id) for i, v in ipairs(state:menu().options) do if v.id == id then - set_cursor(i, {centre = true, skip_redraw = true}) + set_cursor(i, {centre = true}) return end end @@ -157,7 +180,6 @@ local function move_option(pos, opts) local prev_cursor = menu.cursor local opts = opts or {} - opts.skip_redraw = true set_cursor(pos, opts) if menu.cursor == prev_cursor then return @@ -173,7 +195,7 @@ local function move_option(pos, opts) save_favourites() end - update_osd() + osd:dirty() end local function move_option_up() @@ -194,13 +216,13 @@ end local function move_option_page_up() move_option( - state:menu().cursor - osd_menu_lines(), + state:menu().cursor - osd:menu_lines(state), {keep_offset = true, margin = config.scroll_margin}) end local function move_option_page_down() move_option( - state:menu().cursor + osd_menu_lines(), + state:menu().cursor + osd:menu_lines(state), {keep_offset = true, margin = config.scroll_margin}) end @@ -299,11 +321,8 @@ local function favourites_group_menu_options(group) end local function series_group_menu_options(series) - osd:set_status('Loading series info...') - update_osd() - local info = xc:get_series_info(series.series_id) - osd:set_status() - update_osd() + local info = xc:with_opts('get_series_info', series.series_id, + cache_miss_status_msg('Loading series info...')) if not info or not info.seasons then return {} end @@ -460,7 +479,7 @@ local function prev_menu() end end - update_osd() + osd:dirty() end local function play_stream(stream) @@ -485,7 +504,7 @@ local function select_option() if opt.type == 'group' then push_group_menu(opt) - update_osd() + osd:dirty() elseif opt.type == 'stream' then play_stream(opt) end @@ -508,7 +527,7 @@ local function favourite_option() end save_favourites() - update_osd() + osd:dirty() end local function goto_option() @@ -534,7 +553,7 @@ local function goto_option() end end cursor_to_object(opt.id) - update_osd() + osd:dirty() end local function goto_playing() @@ -565,7 +584,7 @@ local function goto_playing() end cursor_to_object(obj.id) - update_osd() + osd:dirty() end local function open_epg_programme(prog, img_url) @@ -590,7 +609,7 @@ local function open_epg_programme(prog, img_url) if img_url then menu.img_url = img_url end - update_osd() + osd:dirty() end local function open_option_epg(opt) @@ -627,8 +646,8 @@ local function open_option_epg(opt) if opt.img_url then menu.img_url = opt.img_url end - set_cursor(curr, {centre = true, skip_redraw = true}) - update_osd() + set_cursor(curr, {centre = true}) + osd:dirty() end local function add_info_field(dst, k, v, fmt) @@ -742,25 +761,19 @@ local function open_option_title_info(title, info) end state:push_menu(m) - update_osd() + osd:dirty() end local function open_option_movie_info(opt) - osd:set_status('Loading movie info...') - update_osd() - local data = xc:get_vod_info(opt.stream_id) - osd:set_status() - update_osd() - open_option_title_info('Movie Info: ' .. opt.name, data) + local info = xc:with_opts('get_vod_info', opt.stream_id, + cache_miss_status_msg('Loading movie info...')) + open_option_title_info('Movie Info: ' .. opt.name, info) end local function open_option_series_info(opt) - osd:set_status('Loading series info...') - update_osd() - local data = xc:get_series_info(opt.series_id) - osd:set_status() - update_osd() - open_option_title_info('Series Info: ' .. opt.name, data) + local info = xc:with_opts('get_series_info', opt.series_id, + cache_miss_status_msg('Loading series info...')) + open_option_title_info('Series Info: ' .. opt.name, info) end local function open_option_season_info(opt) @@ -843,7 +856,7 @@ local function search_input_char(ev) ev.key_text .. menu.search_text:sub(menu.search_cursor)) menu:set_search_cursor(menu.search_cursor + #ev.key_text) - update_osd() + osd:dirty() end local function search_input_bs() @@ -857,7 +870,7 @@ local function search_input_bs() menu.search_text:sub(1, pos - 1) .. menu.search_text:sub(menu.search_cursor)) menu:set_search_cursor(pos) - update_osd() + osd:dirty() end local function search_input_del() @@ -870,12 +883,12 @@ local function search_input_del() menu.search_text:sub(1, menu.search_cursor - 1) .. menu.search_text:sub(util.utf8_seek( menu.search_text, menu.search_cursor, 1))) - update_osd() + osd:dirty() end local function set_search_cursor(pos) if state:menu():set_search_cursor(pos) then - update_osd() + osd:dirty() end end @@ -923,7 +936,7 @@ local function start_search() }) end - update_osd() + osd:dirty() set_key_mapping('SEARCH') end @@ -932,7 +945,7 @@ local function end_search() menu.search_active = false menu.title = 'Search results: <text>' .. ' <colours.info>(<num_matches>/<num_total>)' - update_osd() + osd:dirty() set_key_mapping('MENU') end @@ -950,7 +963,7 @@ local function cancel_search() menu.search_active = false state.depth = state.depth - 1 - update_osd() + osd:dirty() set_key_mapping('MENU') end @@ -961,7 +974,7 @@ local function toggle_menu_sort() end menu:set_sort(not menu.sorted, sort_options) - update_osd() + osd:dirty() end local function mouse_has_drifted(x1, y1, x2, y2) @@ -1037,7 +1050,7 @@ local function process_mouse_click(ev) local line = osd:get_mouse_line(mpos) if line then - line = line - (osd.lines - osd_menu_lines()) + line = line - (osd.lines - osd:menu_lines(state)) end local key, dbl = handle_mouse_click(ev, mpos, line) @@ -1060,7 +1073,7 @@ local function mouse_click_left(ev) set_cursor(1) else state.depth = state.depth + line + 1 - update_osd() + osd:dirty() end return end @@ -1193,6 +1206,8 @@ local function handle_key(ev) (ev.event == 'repeat' and flag == 'repeat') then f() end + + osd:flush(state) end -- uses enable-section and disable-section to disable builtin key bindings @@ -1242,17 +1257,17 @@ end) mp.observe_property('osd-dimensions', 'native', function(_, val) osd:resize(val.w, val.h) - update_osd() + osd:redraw(state) end) mp.register_event('start-file', function() state.playing_id = mp.get_opt('iptv_menu.playing_id') - update_osd() + osd:redraw(state) end) mp.register_event('end-file', function() state.playing_id = nil - update_osd() + osd:redraw(state) end) state:push_menu({title = 'mpv-iptv-menu'}) @@ -1268,5 +1283,5 @@ mp.add_timeout(0, function() load_data() state.depth = 0 push_group_menu(catalogue:get('root')) - update_osd() + osd:redraw(state) end) |
