module ExampleWebExt.NativeMessage where import Prelude import Browser.WebExt.Listener (mkListener) import Browser.WebExt.Message (Message, mkMessage, unwrapMessage) import Browser.WebExt.Port (Port, onMessageAddListener) import Browser.WebExt.Port as Port import Browser.WebExt.Runtime (Application, connectNative) import Data.Argonaut.Core (Json) import Data.Argonaut.Decode (class DecodeJson, JsonDecodeError, decodeJson, printJsonDecodeError) import Data.Argonaut.Decode.Generic (genericDecodeJson) import Data.Argonaut.Encode (class EncodeJson) import Data.Argonaut.Encode.Generic (genericEncodeJson) import Data.Either (Either(..)) import Data.Generic.Rep (class Generic) import Data.Show.Generic (genericShow) import Effect (Effect) import Effect.Class.Console (log) data NativeMessage = NativeMessageBackground String | NativeMessageLog {level :: String, content :: String} type NativePythonMessage m = {tag :: String | m} type NativePythonMessageLog = NativePythonMessage (level :: String, content :: String) derive instance Generic NativeMessage _ instance Show NativeMessage where show = genericShow instance EncodeJson NativeMessage where encodeJson a = genericEncodeJson a instance DecodeJson NativeMessage where decodeJson json = case decodeNative json of Right {level, content} -> Right (NativeMessageLog {level, content}) Left _ -> genericDecodeJson json where decodeNative :: Json -> Either JsonDecodeError NativePythonMessageLog decodeNative = decodeJson connectToNativeApplication ∷ Application → Effect Port connectToNativeApplication = connectNative decodeNativeMessage ∷ Message → Either String NativeMessage decodeNativeMessage m = case unwrapMessage m of Left err -> Left $ printJsonDecodeError err Right m' -> Right m' onNativeMessageAddListener ∷ Port → (NativeMessage → Effect Unit) → Effect Unit onNativeMessageAddListener port f = onMessageAddListener port $ runtimeMessageHandler where runtimeMessageHandler = mkListener \m -> do case decodeNativeMessage m of Left err -> log err Right m' -> f m' sendMessageToNative :: Port -> NativeMessage -> Effect Unit sendMessageToNative port msg = do _ <- Port.postMessage port $ mkMessage msg pure unit