react-native-kookit 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -803,7 +803,7 @@ public class ReactNativeKookitModule: Module {
803
803
  private var volumeObserver: NSKeyValueObservation?
804
804
  private var isVolumeKeyInterceptionEnabled = false
805
805
  private var previousVolume: Float = 0.0
806
- private var ftpClient: FtpClient?
806
+ private var ftpClients: [String: FtpClient] = [:] // Store multiple FTP clients by ID
807
807
 
808
808
  // Each module class must implement the definition function. The definition consists of components
809
809
  // that describes the module's functionality and behavior.
@@ -846,8 +846,31 @@ public class ReactNativeKookitModule: Module {
846
846
  self.disableVolumeKeyInterception()
847
847
  }
848
848
 
849
- // FTP Functions
850
- AsyncFunction("ftpConnect") { (config: [String: Any], promise: Promise) in
849
+ // New FTP Client API - Create new FTP client instance
850
+ AsyncFunction("createFtpClient") { (clientId: String, promise: Promise) in
851
+ if self.ftpClients[clientId] != nil {
852
+ promise.reject("FTP_CLIENT_EXISTS", "FTP client with ID '\(clientId)' already exists")
853
+ return
854
+ }
855
+
856
+ let ftpClient = FtpClient()
857
+ let progressDelegate = FtpProgressDelegateImpl(module: self, clientId: clientId)
858
+ ftpClient.setProgressDelegate(progressDelegate)
859
+ self.ftpClients[clientId] = ftpClient
860
+
861
+ promise.resolve([
862
+ "clientId": clientId,
863
+ "created": true
864
+ ])
865
+ }
866
+
867
+ // Connect FTP client
868
+ AsyncFunction("ftpClientConnect") { (clientId: String, config: [String: Any], promise: Promise) in
869
+ guard let ftpClient = self.ftpClients[clientId] else {
870
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
871
+ return
872
+ }
873
+
851
874
  Task {
852
875
  do {
853
876
  let ftpConfig = FtpConnectionConfig(
@@ -859,30 +882,60 @@ public class ReactNativeKookitModule: Module {
859
882
  timeout: config["timeout"] as? TimeInterval ?? 30.0
860
883
  )
861
884
 
862
- self.ftpClient = FtpClient()
863
- let progressDelegate = FtpProgressDelegateImpl(module: self)
864
- self.ftpClient?.setProgressDelegate(progressDelegate)
865
-
866
- try await self.ftpClient?.connect(config: ftpConfig)
867
- promise.resolve()
885
+ try await ftpClient.connect(config: ftpConfig)
886
+ promise.resolve([
887
+ "clientId": clientId,
888
+ "connected": true
889
+ ])
868
890
  } catch {
869
891
  promise.reject("FTP_CONNECT_ERROR", error.localizedDescription)
870
892
  }
871
893
  }
872
894
  }
873
895
 
874
- AsyncFunction("ftpDisconnect") { (promise: Promise) in
896
+ // Disconnect FTP client
897
+ AsyncFunction("ftpClientDisconnect") { (clientId: String, promise: Promise) in
898
+ guard let ftpClient = self.ftpClients[clientId] else {
899
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
900
+ return
901
+ }
902
+
903
+ Task {
904
+ await ftpClient.disconnect()
905
+ promise.resolve([
906
+ "clientId": clientId,
907
+ "disconnected": true
908
+ ])
909
+ }
910
+ }
911
+
912
+ // Dispose FTP client
913
+ AsyncFunction("disposeFtpClient") { (clientId: String, promise: Promise) in
914
+ guard let ftpClient = self.ftpClients[clientId] else {
915
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
916
+ return
917
+ }
918
+
875
919
  Task {
876
- await self.ftpClient?.disconnect()
877
- self.ftpClient = nil
878
- promise.resolve()
920
+ await ftpClient.disconnect()
921
+ self.ftpClients.removeValue(forKey: clientId)
922
+ promise.resolve([
923
+ "clientId": clientId,
924
+ "disposed": true
925
+ ])
879
926
  }
880
927
  }
881
928
 
882
- AsyncFunction("ftpList") { (path: String?, promise: Promise) in
929
+ // List files
930
+ AsyncFunction("ftpClientList") { (clientId: String, path: String?, promise: Promise) in
931
+ guard let ftpClient = self.ftpClients[clientId] else {
932
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
933
+ return
934
+ }
935
+
883
936
  Task {
884
937
  do {
885
- let files = try await self.ftpClient?.listFiles(path: path) ?? []
938
+ let files = try await ftpClient.listFiles(path: path)
886
939
  let result = files.map { file in
887
940
  [
888
941
  "name": file.name,
@@ -899,72 +952,163 @@ public class ReactNativeKookitModule: Module {
899
952
  }
900
953
  }
901
954
 
902
- AsyncFunction("ftpDownload") { (remotePath: String, localPath: String, promise: Promise) in
955
+ // Download file
956
+ AsyncFunction("ftpClientDownload") { (clientId: String, remotePath: String, localPath: String, promise: Promise) in
957
+ guard let ftpClient = self.ftpClients[clientId] else {
958
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
959
+ return
960
+ }
961
+
903
962
  Task {
904
963
  do {
905
- try await self.ftpClient?.downloadFile(remotePath: remotePath, localPath: localPath)
906
- promise.resolve()
964
+ try await ftpClient.downloadFile(remotePath: remotePath, localPath: localPath)
965
+ promise.resolve([
966
+ "clientId": clientId,
967
+ "remotePath": remotePath,
968
+ "localPath": localPath,
969
+ "downloaded": true
970
+ ])
907
971
  } catch {
908
972
  promise.reject("FTP_DOWNLOAD_ERROR", error.localizedDescription)
909
973
  }
910
974
  }
911
975
  }
912
976
 
913
- AsyncFunction("ftpUpload") { (localPath: String, remotePath: String, promise: Promise) in
977
+ // Upload file
978
+ AsyncFunction("ftpClientUpload") { (clientId: String, localPath: String, remotePath: String, promise: Promise) in
979
+ guard let ftpClient = self.ftpClients[clientId] else {
980
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
981
+ return
982
+ }
983
+
914
984
  Task {
915
985
  do {
916
- try await self.ftpClient?.uploadFile(localPath: localPath, remotePath: remotePath)
917
- promise.resolve()
986
+ try await ftpClient.uploadFile(localPath: localPath, remotePath: remotePath)
987
+ promise.resolve([
988
+ "clientId": clientId,
989
+ "localPath": localPath,
990
+ "remotePath": remotePath,
991
+ "uploaded": true
992
+ ])
918
993
  } catch {
919
994
  promise.reject("FTP_UPLOAD_ERROR", error.localizedDescription)
920
995
  }
921
996
  }
922
997
  }
923
998
 
924
- AsyncFunction("ftpDelete") { (remotePath: String, isDirectory: Bool?, promise: Promise) in
999
+ // Delete file
1000
+ AsyncFunction("ftpClientDelete") { (clientId: String, remotePath: String, isDirectory: Bool?, promise: Promise) in
1001
+ guard let ftpClient = self.ftpClients[clientId] else {
1002
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
1003
+ return
1004
+ }
1005
+
925
1006
  Task {
926
1007
  do {
927
- try await self.ftpClient?.deleteFile(remotePath: remotePath, isDirectory: isDirectory ?? false)
928
- promise.resolve()
1008
+ try await ftpClient.deleteFile(remotePath: remotePath, isDirectory: isDirectory ?? false)
1009
+ promise.resolve([
1010
+ "clientId": clientId,
1011
+ "remotePath": remotePath,
1012
+ "deleted": true
1013
+ ])
929
1014
  } catch {
930
1015
  promise.reject("FTP_DELETE_ERROR", error.localizedDescription)
931
1016
  }
932
1017
  }
933
1018
  }
934
1019
 
935
- AsyncFunction("ftpCreateDirectory") { (remotePath: String, promise: Promise) in
1020
+ // Create directory
1021
+ AsyncFunction("ftpClientCreateDirectory") { (clientId: String, remotePath: String, promise: Promise) in
1022
+ guard let ftpClient = self.ftpClients[clientId] else {
1023
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
1024
+ return
1025
+ }
1026
+
936
1027
  Task {
937
1028
  do {
938
- try await self.ftpClient?.createDirectory(remotePath: remotePath)
939
- promise.resolve()
1029
+ try await ftpClient.createDirectory(remotePath: remotePath)
1030
+ promise.resolve([
1031
+ "clientId": clientId,
1032
+ "remotePath": remotePath,
1033
+ "created": true
1034
+ ])
940
1035
  } catch {
941
1036
  promise.reject("FTP_CREATE_DIR_ERROR", error.localizedDescription)
942
1037
  }
943
1038
  }
944
1039
  }
945
1040
 
946
- AsyncFunction("ftpChangeDirectory") { (remotePath: String, promise: Promise) in
1041
+ // Change directory
1042
+ AsyncFunction("ftpClientChangeDirectory") { (clientId: String, remotePath: String, promise: Promise) in
1043
+ guard let ftpClient = self.ftpClients[clientId] else {
1044
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
1045
+ return
1046
+ }
1047
+
947
1048
  Task {
948
1049
  do {
949
- try await self.ftpClient?.changeDirectory(remotePath: remotePath)
950
- promise.resolve()
1050
+ try await ftpClient.changeDirectory(remotePath: remotePath)
1051
+ promise.resolve([
1052
+ "clientId": clientId,
1053
+ "currentDirectory": remotePath,
1054
+ "changed": true
1055
+ ])
951
1056
  } catch {
952
1057
  promise.reject("FTP_CHANGE_DIR_ERROR", error.localizedDescription)
953
1058
  }
954
1059
  }
955
1060
  }
956
1061
 
957
- AsyncFunction("ftpGetCurrentDirectory") { (promise: Promise) in
1062
+ // Get current directory
1063
+ AsyncFunction("ftpClientGetCurrentDirectory") { (clientId: String, promise: Promise) in
1064
+ guard let ftpClient = self.ftpClients[clientId] else {
1065
+ promise.reject("FTP_CLIENT_NOT_FOUND", "FTP client with ID '\(clientId)' not found")
1066
+ return
1067
+ }
1068
+
958
1069
  Task {
959
1070
  do {
960
- let currentDir = try await self.ftpClient?.getCurrentDirectory() ?? "/"
961
- promise.resolve(currentDir)
1071
+ let currentDir = try await ftpClient.getCurrentDirectory()
1072
+ promise.resolve([
1073
+ "clientId": clientId,
1074
+ "currentDirectory": currentDir
1075
+ ])
962
1076
  } catch {
963
1077
  promise.reject("FTP_PWD_ERROR", error.localizedDescription)
964
1078
  }
965
1079
  }
966
1080
  }
967
1081
 
1082
+ // Get FTP client status
1083
+ AsyncFunction("getFtpClientStatus") { (clientId: String, promise: Promise) in
1084
+ guard let ftpClient = self.ftpClients[clientId] else {
1085
+ promise.resolve([
1086
+ "exists": false,
1087
+ "connected": false
1088
+ ])
1089
+ return
1090
+ }
1091
+
1092
+ promise.resolve([
1093
+ "exists": true,
1094
+ "connected": ftpClient.isConnected
1095
+ ])
1096
+ }
1097
+
1098
+ // List all FTP clients
1099
+ AsyncFunction("listFtpClients") { (promise: Promise) in
1100
+ let clientsInfo = self.ftpClients.mapValues { client in
1101
+ [
1102
+ "connected": client.isConnected
1103
+ ]
1104
+ }
1105
+
1106
+ promise.resolve([
1107
+ "clients": clientsInfo,
1108
+ "count": self.ftpClients.count
1109
+ ])
1110
+ }
1111
+
968
1112
  // Enables the module to be used as a native view. Definition components that are accepted as part of
969
1113
  // the view definition: Prop, Events.
970
1114
  View(ReactNativeKookitView.self) {
@@ -1063,14 +1207,17 @@ public class ReactNativeKookitModule: Module {
1063
1207
  // Helper class to handle FTP progress callbacks
1064
1208
  private class FtpProgressDelegateImpl: FtpProgressDelegate {
1065
1209
  weak var module: ReactNativeKookitModule?
1210
+ let clientId: String
1066
1211
 
1067
- init(module: ReactNativeKookitModule) {
1212
+ init(module: ReactNativeKookitModule, clientId: String) {
1068
1213
  self.module = module
1214
+ self.clientId = clientId
1069
1215
  }
1070
1216
 
1071
1217
  func onProgress(transferred: Int64, total: Int64) {
1072
1218
  let percentage = total > 0 ? Int((transferred * 100) / total) : 0
1073
1219
  module?.sendEvent("onFtpProgress", [
1220
+ "clientId": clientId,
1074
1221
  "transferred": transferred,
1075
1222
  "total": total,
1076
1223
  "percentage": percentage
@@ -1078,10 +1225,15 @@ private class FtpProgressDelegateImpl: FtpProgressDelegate {
1078
1225
  }
1079
1226
 
1080
1227
  func onComplete() {
1081
- module?.sendEvent("onFtpComplete")
1228
+ module?.sendEvent("onFtpComplete", [
1229
+ "clientId": clientId
1230
+ ])
1082
1231
  }
1083
1232
 
1084
1233
  func onError(error: String) {
1085
- module?.sendEvent("onFtpError", ["error": error])
1234
+ module?.sendEvent("onFtpError", [
1235
+ "clientId": clientId,
1236
+ "error": error
1237
+ ])
1086
1238
  }
1087
1239
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-kookit",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "React Native module for intercepting volume button presses on iOS and Android, with FTP client functionality",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",