diff --git a/Makefile b/Makefile index 432b010..ecde566 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos print-dirs pretty ensure-bun generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop +.PHONY: help deps build build-launcher install build-linux build-macos build-macos-unsigned clean install-linux install-macos install-plugin uninstall uninstall-linux uninstall-macos uninstall-plugin print-dirs pretty ensure-bun generate-config generate-example-config docs-dev docs docs-preview dev-start dev-start-macos dev-toggle dev-stop APP_NAME := subminer THEME_SOURCE := assets/themes/subminer.rasi @@ -66,6 +66,7 @@ help: " deps Install JS dependencies (root + texthooker-ui)" \ " uninstall-linux Remove Linux install artifacts" \ " uninstall-macos Remove macOS install artifacts" \ + " uninstall-plugin Remove mpv Lua plugin and plugin config" \ " print-dirs Show resolved install locations" \ "" \ "Variables:" \ @@ -223,15 +224,19 @@ install-plugin: @install -m 0644 "./$(PLUGIN_CONF)" "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf" @printf '%s\n' "Installed to:" " $(MPV_SCRIPTS_DIR)/subminer/main.lua" " $(MPV_SCRIPTS_DIR)/subminer/" " $(MPV_SCRIPT_OPTS_DIR)/subminer.conf" -# Uninstall behavior kept unchanged by default. uninstall: uninstall-linux -uninstall-linux: +uninstall-plugin: + @rm -rf "$(MPV_SCRIPTS_DIR)/subminer" + @rm -f "$(MPV_SCRIPT_OPTS_DIR)/subminer.conf" + @printf '%s\n' "Removed:" " $(MPV_SCRIPTS_DIR)/subminer/" " $(MPV_SCRIPT_OPTS_DIR)/subminer.conf" + +uninstall-linux: uninstall-plugin @rm -f "$(BINDIR)/subminer" "$(BINDIR)/SubMiner.AppImage" @rm -f "$(LINUX_DATA_DIR)/themes/$(THEME_FILE)" @printf '%s\n' "Removed:" " $(BINDIR)/subminer" " $(BINDIR)/SubMiner.AppImage" " $(LINUX_DATA_DIR)/themes/$(THEME_FILE)" -uninstall-macos: +uninstall-macos: uninstall-plugin @rm -f "$(BINDIR)/subminer" @rm -f "$(MACOS_DATA_DIR)/themes/$(THEME_FILE)" @rm -rf "$(MACOS_APP_DEST)" diff --git a/plugin/subminer/environment.lua b/plugin/subminer/environment.lua index 0f94fe5..56dbff6 100644 --- a/plugin/subminer/environment.lua +++ b/plugin/subminer/environment.lua @@ -43,7 +43,7 @@ function M.create(ctx) end local process_list = result.stdout:lower() - for line in process_list:gmatch("[^\\n]+") do + for line in process_list:gmatch("[^\n]+") do if is_windows() then local image = line:match('^"([^"]+)","') if not image then diff --git a/plugin/subminer/hover.lua b/plugin/subminer/hover.lua index 3db9db0..c3a7788 100644 --- a/plugin/subminer/hover.lua +++ b/plugin/subminer/hover.lua @@ -91,7 +91,7 @@ function M.create(ctx) border = sub_border_size * window_scale, shadow = sub_shadow_offset * window_scale, base_color = fix_ass_color(mp.get_property("sub-color"), DEFAULT_HOVER_BASE_COLOR), - hover_color = fix_ass_color(mp.get_property("sub-color"), DEFAULT_HOVER_COLOR), + hover_color = fix_ass_color(DEFAULT_HOVER_COLOR, DEFAULT_HOVER_COLOR), } end diff --git a/scripts/test-plugin-start-gate.lua b/scripts/test-plugin-start-gate.lua index 198b59b..072ceb2 100644 --- a/scripts/test-plugin-start-gate.lua +++ b/scripts/test-plugin-start-gate.lua @@ -5,6 +5,7 @@ local function run_plugin_scenario(config) async_calls = {}, sync_calls = {}, script_messages = {}, + events = {}, osd = {}, logs = {}, } @@ -69,7 +70,12 @@ local function run_plugin_scenario(config) end function mp.add_key_binding(_keys, _name, _fn) end - function mp.register_event(_name, _fn) end + function mp.register_event(name, fn) + if not recorded.events[name] then + recorded.events[name] = {} + end + recorded.events[name][#recorded.events[name] + 1] = fn + end function mp.add_hook(_name, _prio, _fn) end function mp.observe_property(_name, _kind, _fn) end function mp.osd_message(message, _duration) @@ -193,6 +199,11 @@ local function run_plugin_scenario(config) if not ok then return nil, err, recorded end + if config.trigger_file_loaded and recorded.events["file-loaded"] then + for _, callback in ipairs(recorded.events["file-loaded"]) do + callback() + end + end return recorded, nil, recorded end @@ -237,6 +248,88 @@ local function has_sync_command(sync_calls, executable) return false end +local function make_hover_context(config) + local state = require("state").new() + local captured = { + osd_ass = nil, + } + local mp = {} + + function mp.get_property(name) + if name == "sub-text/ass" then + return config.ass_text or "" + end + if name == "sub-text-ass" then + return "" + end + if name == "sub-color" then + return config.sub_color + end + if name == "sub-font" then + return "sans-serif" + end + if name == "sub-visibility" or name == "secondary-sub-visibility" then + return "yes" + end + return "" + end + + function mp.get_property_number(_name, default) + return default + end + + function mp.get_property_bool(_name, default) + return default + end + + function mp.get_property_native(name) + if name == "osd-dimensions" then + return { w = 1280, h = 720, ml = 0, mr = 0, mt = 0, mb = 0 } + end + return nil + end + + function mp.set_property(_name, _value) end + + function mp.set_osd_ass(_w, _h, text) + captured.osd_ass = text + end + + function mp.get_time() + return 0 + end + + function mp.add_timeout(_seconds, callback) + if callback then + callback() + end + return { + kill = function() end, + } + end + + return { + ctx = { + mp = mp, + msg = { warn = function(_) end }, + utils = { + parse_json = function(_) + return { + revision = 1, + hoveredTokenIndex = 0, + subtitle = "hello world", + tokens = { + { index = 0, text = "hello", startPos = 0, endPos = 5 }, + }, + }, nil + end, + }, + state = state, + }, + captured = captured, + } +end + local binary_path = "/tmp/subminer-binary" do @@ -260,4 +353,36 @@ do ) end +do + local recorded, err = run_plugin_scenario({ + process_list = "python\nSubMiner\n", + filename_no_ext = "Some Show - S01E01", + trigger_file_loaded = true, + binary_path = binary_path, + files = { + [binary_path] = true, + }, + }) + assert_true(recorded ~= nil, "plugin failed to load for process split scenario: " .. tostring(err)) + assert_true(has_sync_command(recorded.sync_calls, "ps"), "expected file-loaded hook to read process list") + assert_true( + has_sync_command(recorded.sync_calls, "curl"), + "expected file-loaded hook to run AniSkip lookup when SubMiner process is present in ps output" + ) +end + +do + local hover_context = make_hover_context({ + ass_text = "hello world", + sub_color = "112233", + }) + local hover = require("hover").create(hover_context.ctx) + hover.handle_hover_message("{}") + assert_true(type(hover_context.captured.osd_ass) == "string", "expected hover overlay render to write ASS output") + assert_true( + hover_context.captured.osd_ass:find("\\1c&HF6A0C6&", 1, true) ~= nil, + "expected hover render to keep accent hover color when sub-color is configured" + ) +end + print("plugin start gate regression tests: OK")