130 lines
3.9 KiB
Lua
130 lines
3.9 KiB
Lua
--- === BBC Sounds ===
|
|
---
|
|
--- Implementation of https://github.com/moomerman/Sounds in Hammerspoon.
|
|
|
|
local obj = {}
|
|
obj.__index = obj
|
|
|
|
|
|
obj.name = "BBC Sounds"
|
|
obj.version = "0.1"
|
|
obj.author = "Markus Birth <markus@birth-online.de>"
|
|
|
|
function obj:init()
|
|
-- prepare variable for menubar item/icon
|
|
self.mbIcon = nil
|
|
-- prepare variable for media key handler, but don't assign just yet
|
|
self.eventTap = nil
|
|
-- prepare logger
|
|
self.log = hs.logger.new(self.name, "verbose")
|
|
end
|
|
|
|
function obj:start()
|
|
self.log.v('Start')
|
|
-- create global webview to keep it running/playing the whole time
|
|
self.webView = hs.webview.new()
|
|
self.webView:allowNewWindows(false)
|
|
self.webView:windowCallback(self.webViewHide)
|
|
self.webView:navigationCallback(self.webViewMods)
|
|
self.webView:url("https://www.bbc.co.uk/sounds/play/live:bbc_radio_one_dance")
|
|
-- self.webView:magnification(1)
|
|
|
|
-- load menubar icon and prepare menubar item
|
|
local iconImage = hs.image.imageFromPath("Spoons/BbcSounds.spoon/icon_16.png")
|
|
self.mbIcon = hs.menubar.new()
|
|
self.mbIcon:setIcon(iconImage)
|
|
self.mbIcon:setClickCallback(self.showHide)
|
|
|
|
-- create eventtap for handling media keys
|
|
self.eventTap = hs.eventtap.new({hs.eventtap.event.types.systemDefined}, self.handleMediaKey)
|
|
self.eventTap:start()
|
|
self.log.v('Startup complete.')
|
|
return self
|
|
end
|
|
|
|
function obj.handleMediaKey(event)
|
|
local delete = false
|
|
|
|
local data = event:systemKey()
|
|
|
|
if data["down"] == false or data["repeat"] == true then
|
|
obj.log.v("Key event: " .. data["key"])
|
|
if data["key"] == "PLAY" then
|
|
-- Handled automatically by WebView
|
|
-- obj.togglePlay()
|
|
delete = true
|
|
elseif data["key"] == "NEXT" then
|
|
obj.goLive()
|
|
delete = true
|
|
elseif data["key"] == "PREVIOUS" then
|
|
obj.goStart()
|
|
delete = true
|
|
end
|
|
end
|
|
|
|
return delete, nil
|
|
end
|
|
|
|
function obj.webViewHide(action, webview, state)
|
|
obj.log.v("webViewHide: " .. action)
|
|
if action == "focusChange" and not state then
|
|
obj.webView:hide(0.3)
|
|
end
|
|
end
|
|
|
|
function obj.webViewMods(action, webView, navID, error)
|
|
if action == "didFinishNavigation" then
|
|
obj.hideHeader()
|
|
end
|
|
end
|
|
|
|
function obj.hideHeader()
|
|
-- Hide top navbar on BBC page
|
|
obj.webView:evaluateJavaScript("document.getElementById(\"orb-banner\").style.display = \"none\"")
|
|
end
|
|
|
|
function obj.togglePlay()
|
|
obj.webView:evaluateJavaScript("document.getElementById(\"smphtml5iframesmp-wrapper\").contentWindow.document.getElementById(\"p_audioui_playpause\").click()")
|
|
end
|
|
|
|
function obj.goLive()
|
|
obj.webView:evaluateJavaScript("document.getElementById(\"smphtml5iframesmp-wrapper\").contentWindow.document.getElementById(\"p_audioui_toLiveButton\").click()")
|
|
end
|
|
|
|
function obj.goStart()
|
|
obj.webView:evaluateJavaScript("document.getElementById(\"smphtml5iframesmp-wrapper\").contentWindow.document.getElementById(\"p_audioui_backToStartButton\").click()")
|
|
end
|
|
|
|
function obj.showHide(modifierKeys)
|
|
if obj.webView:isVisible() then
|
|
obj.webView:hide(0.3)
|
|
else
|
|
-- get position of menubar item and move webview there, then show it
|
|
local mbPos = obj.mbIcon:frame()
|
|
mbPos.w = 900
|
|
mbPos.h = 716
|
|
-- check if out of bounds
|
|
local desktopFrame = hs.window.desktop():frame()
|
|
if mbPos.x + mbPos.w > desktopFrame.w then
|
|
obj.log.w("webView width larger than desktop. Adjusting position.")
|
|
mbPos.x = desktopFrame.w - mbPos.w
|
|
end
|
|
if mbPos.y + mbPos.h > desktopFrame.h then
|
|
obj.log.w("webView height larger than desktop. Adjusting position.")
|
|
mbPos.y = desktopFrame.h - mbPos.h
|
|
end
|
|
obj.webView:frame(mbPos)
|
|
obj.webView:show(0.3)
|
|
obj.webView:bringToFront()
|
|
end
|
|
end
|
|
|
|
function obj:stop()
|
|
self.eventTap:stop()
|
|
self.webView:delete()
|
|
self.mbIcon:delete()
|
|
end
|
|
|
|
|
|
return obj
|