Skip to content

Commit

Permalink
[RN, fluter] fixed bug about stopLivePreview.
Browse files Browse the repository at this point in the history
  • Loading branch information
LassicYM authored Oct 29, 2024
1 parent b58ad4a commit d686df8
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class ThetaClientFlutterPlugin : FlutterPlugin, MethodCallHandler {
const val messageNotInit: String = "Not initialized."
const val messageNoResult: String = "Result is Null."
const val messageNoArgument: String = "No Argument."
const val messageLivePreviewRunning: String = "Live preview is running."

const val eventNameNotify = "theta_client_flutter/theta_notify"
const val notifyIdLivePreview = 10001
Expand Down Expand Up @@ -617,6 +618,11 @@ class ThetaClientFlutterPlugin : FlutterPlugin, MethodCallHandler {
}

suspend fun getLivePreview(result: Result) {
if (previewing) {
result.error(errorCode, messageLivePreviewRunning, null)
return
}

val theta = thetaRepository
if (theta == null) {
result.error(errorCode, messageNotInit, null)
Expand All @@ -633,13 +639,14 @@ class ThetaClientFlutterPlugin : FlutterPlugin, MethodCallHandler {
}
result.success(null)
} catch (e: Exception) {
previewing = false
result.error(e.javaClass.simpleName, e.message, null)
}
}

fun stopLivePreview(result: Result) {
previewing = false
result.success(null)
result.success(true)
}

fun getPhotoCaptureBuilder(result: Result) {
Expand Down
14 changes: 13 additions & 1 deletion flutter/ios/Classes/SwiftThetaClientFlutterPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre
static let messageNotInit: String = "Not initialized."
static let messageNoResult: String = "Result is Null."
static let messageNoArgument: String = "No Argument."
static let messageLivePreviewRunning = "Live preview is running."
static var endPoint: String = "http://192.168.1.1"
var eventSink: FlutterEventSink? = nil
var previewing = false
Expand Down Expand Up @@ -114,7 +115,7 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre
case "getLivePreview":
getLivePreview(result: result)
case "stopLivePreview":
previewing = false
stopLivePreview(result: result)
case "listFiles":
listFiles(call: call, result: result)
case "deleteFiles":
Expand Down Expand Up @@ -383,6 +384,12 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre
}

func getLivePreview(result: @escaping FlutterResult) {
if previewing {
let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: SwiftThetaClientFlutterPlugin.messageLivePreviewRunning, details: nil)
result(flutterError)
return
}

if thetaRepository == nil {
let flutterError = FlutterError(code: SwiftThetaClientFlutterPlugin.errorCode, message: SwiftThetaClientFlutterPlugin.messageNotInit, details: nil)
result(flutterError)
Expand Down Expand Up @@ -418,6 +425,11 @@ public class SwiftThetaClientFlutterPlugin: NSObject, FlutterPlugin, FlutterStre
}
}
}

func stopLivePreview(result: @escaping FlutterResult) {
previewing = false
result(true)
}

func listFiles(call: FlutterMethodCall, result: @escaping FlutterResult) {
guard let thetaRepository = thetaRepository else {
Expand Down
10 changes: 7 additions & 3 deletions flutter/lib/theta_client_flutter_method_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,18 @@ class MethodChannelThetaClientFlutter extends ThetaClientFlutterPlatform {
final image = params?['image'] as Uint8List?;
if (image != null && !frameHandler(image)) {
removeNotify(notifyIdLivePreview);
methodChannel.invokeMethod<String>('stopLivePreview');
methodChannel.invokeMethod<bool>('stopLivePreview');
}
});
await methodChannel.invokeMethod<void>('getLivePreview');
completer.complete(null);
} catch (e) {
removeNotify(notifyIdLivePreview);
completer.completeError(e);
if (e is PlatformException && e.message == "Live preview is running.") {
completer.completeError(e);
} else {
removeNotify(notifyIdLivePreview);
completer.completeError(e);
}
}
return completer.future;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@ class ThetaRepositoryTest {

// execute
val timeout = ThetaRepository.Timeout(
connectTimeout = 1L,
requestTimeout = 2L,
socketTimeout = 3L
connectTimeout = 10L,
requestTimeout = 20L,
socketTimeout = 30L
)
ThetaRepository.newInstance(endpoint, timeout = timeout)
assertNotNull(ThetaRepository.restoreConfig, "restoreConfig")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ThetaClientReactNativeModule(
}

var previewing: Boolean = false
var stopLivePreviewPromise: Promise? = null
var photoCaptureBuilder: PhotoCapture.Builder? = null
var photoCapture: PhotoCapture? = null
var timeShiftCaptureBuilder: TimeShiftCapture.Builder? = null
Expand Down Expand Up @@ -53,6 +54,7 @@ class ThetaClientReactNativeModule(
var listenerCount: Int = 0

val messageNotInit: String = "Not initialized."
val messageLivePreviewRunning: String = "Live preview is running."

/**
* add event listener for [eventName]
Expand Down Expand Up @@ -97,6 +99,7 @@ class ThetaClientReactNativeModule(
try {
theta = null
previewing = false
stopLivePreviewPromise = null
photoCaptureBuilder = null
photoCapture = null
timeShiftCaptureBuilder = null
Expand Down Expand Up @@ -427,6 +430,11 @@ class ThetaClientReactNativeModule(
*/
@ReactMethod
fun getLivePreview(promise: Promise) {
if (previewing) {
promise.reject(Exception(messageLivePreviewRunning))
return
}

val theta = theta
if (theta == null) {
promise.reject(Exception(messageNotInit))
Expand All @@ -435,7 +443,7 @@ class ThetaClientReactNativeModule(
fun ByteArray.toBase64(): String = String(Base64.getEncoder().encode(this))
suspend fun callFrameHandler(packet: Pair<ByteArray, Int>): Boolean {
if (listenerCount == 0) {
return previewing
return stopLivePreviewPromise == null
}
val param = Arguments.createMap()
param.putString(
Expand All @@ -446,12 +454,19 @@ class ThetaClientReactNativeModule(
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(EVENT_NAME, param)
return previewing
return stopLivePreviewPromise == null
}

previewing = true
execAndResetStopLivePreviewResolve(false)

launch {
try {
theta.getLivePreview(::callFrameHandler)

execAndResetStopLivePreviewResolve(true)
previewing = false

promise.resolve(true)
} catch (t: Throwable) {
promise.reject(t)
Expand All @@ -461,13 +476,26 @@ class ThetaClientReactNativeModule(

/**
* stopLivePreview - stop live previewing
* @param promise promise to set result
*/
@ReactMethod
fun stopLivePreview() {
fun stopLivePreview(promise: Promise) {
if (theta == null) {
throw Exception(messageNotInit)
promise.reject(Exception(messageNotInit))
return
}
previewing = false

if (!previewing || stopLivePreviewPromise != null) {
promise.resolve(false)
return
}

stopLivePreviewPromise = promise
}

private fun execAndResetStopLivePreviewResolve(flag: Boolean) {
stopLivePreviewPromise?.resolve(flag)
stopLivePreviewPromise = null
}

/**
Expand Down
32 changes: 27 additions & 5 deletions react-native/ios/ThetaClientReactNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import THETAClient

let ERROR_CODE_ERROR = "error"
let MESSAGE_NOT_INIT = "Not initialized."
let MESSAGE_LIVE_PREVIEW_RUNNING = "Live Preview is running."
let MESSAGE_NO_RESULT = "No result."
let MESSAGE_NO_ARGUMENT = "No Argument."
let MESSAGE_NO_PHOTO_CAPTURE = "No photoCapture."
Expand Down Expand Up @@ -35,6 +36,7 @@ let MESSAGE_NO_EVENT_WEBSOCKET = "no eventWebSocket."
class ThetaClientReactNative: RCTEventEmitter {
var thetaRepository: ThetaRepository?
var previewing = false
var stopLivePreviewResolve: RCTPromiseResolveBlock?
var photoCaptureBuilder: PhotoCapture.Builder?
var photoCapture: PhotoCapture?
var timeShiftCaptureBuilder: TimeShiftCapture.Builder?
Expand Down Expand Up @@ -143,6 +145,7 @@ class ThetaClientReactNative: RCTEventEmitter {
continuousCaptureBuilder = nil
continuousCapture = nil
previewing = false
stopLivePreviewResolve = nil
eventWebSocket?.stop(completionHandler: { _ in })
eventWebSocket = nil

Expand Down Expand Up @@ -451,6 +454,11 @@ class ThetaClientReactNative: RCTEventEmitter {
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock
) {
if previewing {
reject(ERROR_CODE_ERROR, MESSAGE_LIVE_PREVIEW_RUNNING, nil)
return
}

class FrameHandler: KotlinSuspendFunction1 {
let thetaClientReactNative: ThetaClientReactNative
static let FrameInterval = CFTimeInterval(1.0 / 10.0)
Expand All @@ -477,7 +485,7 @@ class ThetaClientReactNative: RCTEventEmitter {
}
}
}
return thetaClientReactNative.previewing
return thetaClientReactNative.stopLivePreviewResolve == nil
}
}

Expand All @@ -486,23 +494,37 @@ class ThetaClientReactNative: RCTEventEmitter {
return
}
let frameHandler = FrameHandler(self)

previewing = true
execAndResetStopLivePreviewResolve(false)

thetaRepository.getLivePreview(frameHandler: frameHandler) { error in
if let error {
reject(ERROR_CODE_ERROR, error.localizedDescription, error)
} else {
self.execAndResetStopLivePreviewResolve(true)
self.previewing = false

resolve(true)
}
}
}

@objc(stopLivePreview:withRejecter:)
func stopLivePreview(
resolve: RCTPromiseResolveBlock,
reject _: RCTPromiseRejectBlock
resolve: @escaping RCTPromiseResolveBlock,
reject _: @escaping RCTPromiseRejectBlock
) {
previewing = false
resolve(nil)
if !previewing || stopLivePreviewResolve != nil {
resolve(false)
return
}
stopLivePreviewResolve = resolve
}

private func execAndResetStopLivePreviewResolve(_ flag: Bool) {
stopLivePreviewResolve?(flag)
stopLivePreviewResolve = nil
}

@objc(getPhotoCaptureBuilder:withRejecter:)
Expand Down
5 changes: 3 additions & 2 deletions react-native/src/theta-repository/theta-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,10 @@ export function getLivePreview(): Promise<boolean> {
* Stop live preview.
*
* @function StopLivePreview
* @return promise of boolean result
*/
export function stopLivePreview() {
ThetaClientReactNative.stopLivePreview();
export function stopLivePreview(): Promise<boolean> {
return ThetaClientReactNative.stopLivePreview();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ const LivePreviewScreen: React.FC<
const onStop = () => {
isInitialized().then((isInit) => {
if (isInit) {
stopLivePreview();
stopLivePreview().then((isStopped) => {
console.log(`isStop = ${isStopped}`);
});
} else {
Alert.alert('stopLivePreview', 'error: Not initialized.', [
{ text: 'OK' },
Expand Down

0 comments on commit d686df8

Please sign in to comment.