diff --git a/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NativeEventChannelHandler.kt b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NativeEventChannelHandler.kt new file mode 100644 index 00000000..07d12957 --- /dev/null +++ b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NativeEventChannelHandler.kt @@ -0,0 +1,52 @@ +package com.nkming.nc_photos.plugin + +import io.flutter.plugin.common.EventChannel +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel + +class NativeEventChannelHandler : MethodChannel.MethodCallHandler, + EventChannel.StreamHandler { + companion object { + const val EVENT_CHANNEL = "${K.LIB_ID}/native_event" + const val METHOD_CHANNEL = "${K.LIB_ID}/native_event_method" + + private val eventSinks = mutableMapOf() + private var nextId = 0 + } + + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { + when (call.method) { + "fire" -> { + try { + fire( + call.argument("event")!!, call.argument("data"), result + ) + } catch (e: Throwable) { + result.error("systemException", e.toString(), null) + } + } + } + } + + override fun onListen(arguments: Any?, events: EventChannel.EventSink) { + eventSinks[id] = events + } + + override fun onCancel(arguments: Any?) { + eventSinks.remove(id) + } + + private fun fire( + event: String, data: String?, result: MethodChannel.Result + ) { + for (s in eventSinks.values) { + s.success(buildMap { + put("event", event) + if (data != null) put("data", data) + }) + } + result.success(null) + } + + private val id = nextId++ +} diff --git a/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt index 500256dd..67148ef1 100644 --- a/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt +++ b/plugin/android/src/main/kotlin/com/nkming/nc_photos/plugin/NcPhotosPlugin.kt @@ -2,12 +2,14 @@ package com.nkming.nc_photos.plugin import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.EventChannel import io.flutter.plugin.common.MethodChannel class NcPhotosPlugin : FlutterPlugin { override fun onAttachedToEngine( @NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding ) { + // this may get called more than once lockChannel = MethodChannel( flutterPluginBinding.binaryMessenger, LockChannelHandler.CHANNEL ) @@ -22,6 +24,18 @@ class NcPhotosPlugin : FlutterPlugin { flutterPluginBinding.applicationContext ) ) + + val nativeEventHandler = NativeEventChannelHandler() + nativeEventChannel = EventChannel( + flutterPluginBinding.binaryMessenger, + NativeEventChannelHandler.EVENT_CHANNEL + ) + nativeEventChannel.setStreamHandler(nativeEventHandler) + nativeEventMethodChannel = MethodChannel( + flutterPluginBinding.binaryMessenger, + NativeEventChannelHandler.METHOD_CHANNEL + ) + nativeEventMethodChannel.setMethodCallHandler(nativeEventHandler) } override fun onDetachedFromEngine( @@ -29,8 +43,12 @@ class NcPhotosPlugin : FlutterPlugin { ) { lockChannel.setMethodCallHandler(null) notificationChannel.setMethodCallHandler(null) + nativeEventChannel.setStreamHandler(null) + nativeEventMethodChannel.setMethodCallHandler(null) } private lateinit var lockChannel: MethodChannel private lateinit var notificationChannel: MethodChannel + private lateinit var nativeEventChannel: EventChannel + private lateinit var nativeEventMethodChannel: MethodChannel } diff --git a/plugin/lib/nc_photos_plugin.dart b/plugin/lib/nc_photos_plugin.dart index 823d1aa7..29afa79d 100644 --- a/plugin/lib/nc_photos_plugin.dart +++ b/plugin/lib/nc_photos_plugin.dart @@ -1,4 +1,5 @@ library nc_photos_plugin; export 'src/lock.dart'; +export 'src/native_event.dart'; export 'src/notification.dart'; diff --git a/plugin/lib/src/native_event.dart b/plugin/lib/src/native_event.dart new file mode 100644 index 00000000..90002537 --- /dev/null +++ b/plugin/lib/src/native_event.dart @@ -0,0 +1,34 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:nc_photos_plugin/src/k.dart' as k; + +class NativeEventObject { + NativeEventObject(this.event, this.data); + + final String event; + final String? data; +} + +class NativeEvent { + static Future fire(NativeEventObject ev) => + _methodChannel.invokeMethod("fire", { + "event": ev.event, + if (ev.data != null) "data": ev.data, + }); + + static Stream get stream => _eventStream; + + static const _eventChannel = EventChannel("${k.libId}/native_event"); + static const _methodChannel = MethodChannel("${k.libId}/native_event_method"); + + static late final _eventStream = _eventChannel + .receiveBroadcastStream() + .map((event) { + if (event is Map) { + return NativeEventObject(event["event"], event["data"]); + } else { + return event; + } + }); +}