@haykmkrtich/react-native-patriot-native 1.1.2 → 1.3.0

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.
package/README.md CHANGED
@@ -32,7 +32,7 @@ yarn add @haykmkrtich/react-native-patriot-native
32
32
 
33
33
  ## Requirements
34
34
 
35
- - React Native >= 0.60.0
35
+ - React Native >= 0.77.0
36
36
  - Android API level 24+ (Android 7.0+)
37
37
  - Java 17+
38
38
  - Paired WearOS device
@@ -30,15 +30,6 @@ android {
30
30
  }
31
31
  }
32
32
 
33
- sourceSets {
34
- main {
35
- if (project.hasProperty("newArchEnabled") && project.property("newArchEnabled") == "true") {
36
- java.srcDirs += ["src/newarch/java"]
37
- } else {
38
- java.srcDirs += ["src/oldarch/java"]
39
- }
40
- }
41
- }
42
33
  }
43
34
 
44
35
  react {
@@ -14,8 +14,5 @@ org.gradle.daemon=true
14
14
  android.useAndroidX=true
15
15
  android.enableJetifier=true
16
16
 
17
- # New Architecture support (TurboModules and Fabric)
18
- newArchEnabled=false
19
-
20
17
  # 16KB page size support
21
18
  android.bundle.enableUncompressedNativeLibs=false
@@ -20,6 +20,7 @@ import com.google.android.gms.wearable.Wearable;
20
20
  import com.google.android.gms.tasks.Task;
21
21
  import com.google.android.gms.tasks.Tasks;
22
22
 
23
+ import java.util.List;
23
24
  import java.util.Set;
24
25
  import java.util.concurrent.ExecutionException;
25
26
 
@@ -58,8 +59,8 @@ public class PatriotNativeModule extends NativePatriotNativeSpec {
58
59
  Context context = getContext();
59
60
 
60
61
  NodeClient nodeClient = Wearable.getNodeClient(context);
61
- Task<Set<Node>> nodesTask = nodeClient.getConnectedNodes();
62
- Set<Node> nodes = Tasks.await(nodesTask);
62
+ Task<List<Node>> nodesTask = nodeClient.getConnectedNodes();
63
+ List<Node> nodes = Tasks.await(nodesTask);
63
64
 
64
65
  if (nodes.isEmpty()) {
65
66
  promise.reject("NO_NODES", "No connected WearOS devices found");
@@ -106,8 +107,8 @@ public class PatriotNativeModule extends NativePatriotNativeSpec {
106
107
  Context context = getContext();
107
108
 
108
109
  NodeClient nodeClient = Wearable.getNodeClient(context);
109
- Task<Set<Node>> nodesTask = nodeClient.getConnectedNodes();
110
- Set<Node> nodes = Tasks.await(nodesTask);
110
+ Task<List<Node>> nodesTask = nodeClient.getConnectedNodes();
111
+ List<Node> nodes = Tasks.await(nodesTask);
111
112
 
112
113
  CapabilityClient capabilityClient = Wearable.getCapabilityClient(context);
113
114
 
package/index.ts CHANGED
@@ -1,22 +1,14 @@
1
- import { NativeModules, Platform } from 'react-native';
1
+ import { Platform } from 'react-native';
2
+ import NativePatriotNative from './src/NativePatriotNative';
2
3
 
3
- // Import TurboModule spec for RN 0.77+ compatibility
4
- let PatriotNativeModule: any;
5
-
6
- try {
7
- // Try to use TurboModule first (RN 0.77+)
8
- PatriotNativeModule = require('./src/NativePatriotNative').default;
9
- } catch (e) {
10
- // Fallback to legacy NativeModules (RN < 0.77)
11
- PatriotNativeModule = NativeModules.PatriotNative;
12
- }
4
+ const PatriotNativeModule = NativePatriotNative;
13
5
 
14
6
  if (!PatriotNativeModule) {
15
7
  throw new Error(
16
8
  `PatriotNative module is not properly linked. Please check your installation:
17
9
  1. Run 'npx react-native clean' and rebuild
18
10
  2. Ensure Android dependencies are properly installed
19
- 3. Check that your React Native version is 0.60+`
11
+ 3. Check that your React Native version is 0.77+`
20
12
  );
21
13
  }
22
14
 
@@ -74,7 +66,6 @@ export const sendMessageToWatch = (nodeId: string, path: string, data: string =
74
66
  return PatriotNativeModule.sendMessageToWatch(nodeId, path, data);
75
67
  };
76
68
 
77
- // Backward compatibility
78
69
  /** @deprecated Use getConnectedDevices() instead. Returns the first device or { isDisconnected: true }. */
79
70
  export const getConnectedWatchProperties = async (): Promise<ConnectedDevice & { isDisconnected?: boolean }> => {
80
71
  const devices = await getConnectedDevices();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haykmkrtich/react-native-patriot-native",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "main": "index.ts",
5
5
  "files": [
6
6
  "index.ts",
@@ -26,7 +26,7 @@
26
26
  "access": "public"
27
27
  },
28
28
  "peerDependencies": {
29
- "react-native": ">=0.60.0"
29
+ "react-native": ">=0.77.0"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=16.0.0"
@@ -1,47 +0,0 @@
1
- /**
2
- * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
- *
4
- * Do not edit this file as changes may cause incorrect behavior and will be lost
5
- * once the code is regenerated.
6
- *
7
- * @generated by codegen project: GenerateModuleJavaSpec.js
8
- */
9
-
10
- package com.patriotnative;
11
-
12
- import com.facebook.proguard.annotations.DoNotStrip;
13
- import com.facebook.react.bridge.Promise;
14
- import com.facebook.react.bridge.ReactApplicationContext;
15
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
16
- import com.facebook.react.bridge.ReactMethod;
17
- import com.facebook.react.turbomodule.core.interfaces.TurboModule;
18
-
19
- public abstract class NativePatriotNativeSpec extends ReactContextBaseJavaModule implements TurboModule {
20
-
21
- public static final String NAME = "PatriotNative";
22
-
23
- public NativePatriotNativeSpec(ReactApplicationContext reactContext) {
24
- super(reactContext);
25
- }
26
-
27
- @Override
28
- public String getName() {
29
- return NAME;
30
- }
31
-
32
- @ReactMethod
33
- @DoNotStrip
34
- public abstract void installWatchface(String packageName, Promise promise);
35
-
36
- @ReactMethod
37
- @DoNotStrip
38
- public abstract void getConnectedDevices(Promise promise);
39
-
40
- @ReactMethod
41
- @DoNotStrip
42
- public abstract void isAppInstalledOnWatch(String packageName, Promise promise);
43
-
44
- @ReactMethod
45
- @DoNotStrip
46
- public abstract void sendMessageToWatch(String nodeId, String path, String data, Promise promise);
47
- }
@@ -1,198 +0,0 @@
1
- package com.patriotnative;
2
-
3
- import android.content.Context;
4
- import android.widget.Toast;
5
-
6
- import androidx.annotation.NonNull;
7
-
8
- import com.facebook.react.bridge.Arguments;
9
- import com.facebook.react.bridge.Promise;
10
- import com.facebook.react.bridge.ReactApplicationContext;
11
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
12
- import com.facebook.react.bridge.ReactMethod;
13
- import com.facebook.react.bridge.WritableArray;
14
- import com.facebook.react.bridge.WritableMap;
15
-
16
- import com.google.android.gms.wearable.CapabilityClient;
17
- import com.google.android.gms.wearable.CapabilityInfo;
18
- import com.google.android.gms.wearable.Node;
19
- import com.google.android.gms.wearable.NodeClient;
20
- import com.google.android.gms.wearable.Wearable;
21
- import com.google.android.gms.tasks.Task;
22
- import com.google.android.gms.tasks.Tasks;
23
-
24
- import java.util.Set;
25
- import java.util.concurrent.ExecutionException;
26
-
27
- /**
28
- * OldArch implementation of PatriotNative (legacy bridge) for React Native < 0.77
29
- */
30
- public class PatriotNativeModule extends ReactContextBaseJavaModule {
31
- private static final String NAME = "PatriotNative";
32
- private static final String PLAY_STORE_APP_URI = "market://details?id=";
33
-
34
- private final ReactApplicationContext reactContext;
35
-
36
- public PatriotNativeModule(ReactApplicationContext reactContext) {
37
- super(reactContext);
38
- this.reactContext = reactContext;
39
- }
40
-
41
- @Override
42
- @NonNull
43
- public String getName() {
44
- return NAME;
45
- }
46
-
47
- private Context getContext() {
48
- Context context = getCurrentActivity();
49
- if (context == null) {
50
- context = getReactApplicationContext();
51
- }
52
- return context;
53
- }
54
-
55
- @ReactMethod
56
- public void installWatchface(String packageName, Promise promise) {
57
- try {
58
- Context context = getContext();
59
-
60
- NodeClient nodeClient = Wearable.getNodeClient(context);
61
- Task<Set<Node>> nodesTask = nodeClient.getConnectedNodes();
62
- Set<Node> nodes = Tasks.await(nodesTask);
63
-
64
- if (nodes.isEmpty()) {
65
- promise.reject("NO_NODES", "No connected WearOS devices found");
66
- return;
67
- }
68
-
69
- String appUri = PLAY_STORE_APP_URI + packageName;
70
- boolean installationSent = false;
71
-
72
- for (Node node : nodes) {
73
- try {
74
- Task<Integer> sendTask = Wearable.getMessageClient(context)
75
- .sendMessage(node.getId(), "/install_watchface", appUri.getBytes());
76
- Tasks.await(sendTask);
77
- installationSent = true;
78
- } catch (Exception e) {
79
- continue;
80
- }
81
- }
82
-
83
- if (installationSent) {
84
- if (getCurrentActivity() != null) {
85
- final Context finalContext = context;
86
- getCurrentActivity().runOnUiThread(() ->
87
- Toast.makeText(finalContext, "Check your watch for installation prompt", Toast.LENGTH_LONG).show()
88
- );
89
- }
90
- promise.resolve(null);
91
- } else {
92
- promise.reject("INSTALL_FAILED", "Failed to send installation request to any connected device");
93
- }
94
-
95
- } catch (ExecutionException | InterruptedException e) {
96
- promise.reject("INSTALL_FAILED", "Failed to communicate with WearOS device: " + e.getMessage());
97
- } catch (Exception e) {
98
- promise.reject("INSTALL_FAILED", "Unexpected error: " + e.getMessage());
99
- }
100
- }
101
-
102
- @ReactMethod
103
- public void getConnectedDevices(Promise promise) {
104
- try {
105
- Context context = getContext();
106
-
107
- NodeClient nodeClient = Wearable.getNodeClient(context);
108
- Task<Set<Node>> nodesTask = nodeClient.getConnectedNodes();
109
- Set<Node> nodes = Tasks.await(nodesTask);
110
-
111
- CapabilityClient capabilityClient = Wearable.getCapabilityClient(context);
112
-
113
- WritableArray devicesArray = Arguments.createArray();
114
-
115
- for (Node node : nodes) {
116
- WritableMap deviceMap = Arguments.createMap();
117
- deviceMap.putString("id", node.getId());
118
- deviceMap.putString("displayName", node.getDisplayName());
119
- deviceMap.putBoolean("isNearby", node.isNearby());
120
- deviceMap.putString("type", "watch");
121
-
122
- try {
123
- Task<CapabilityInfo> capabilityTask = capabilityClient.getCapability(
124
- "wear_app_runtime", CapabilityClient.FILTER_REACHABLE);
125
- CapabilityInfo capabilityInfo = Tasks.await(capabilityTask);
126
-
127
- boolean isWearOS = false;
128
- for (Node capableNode : capabilityInfo.getNodes()) {
129
- if (capableNode.getId().equals(node.getId())) {
130
- isWearOS = true;
131
- break;
132
- }
133
- }
134
- deviceMap.putString("platform", isWearOS ? "wearOS" : "unknown");
135
- } catch (Exception e) {
136
- deviceMap.putString("platform", "wearOS");
137
- }
138
-
139
- devicesArray.pushMap(deviceMap);
140
- }
141
-
142
- promise.resolve(devicesArray);
143
-
144
- } catch (ExecutionException | InterruptedException e) {
145
- promise.reject("DETECTION_FAILED", "Failed to get connected devices: " + e.getMessage());
146
- } catch (Exception e) {
147
- promise.reject("DETECTION_FAILED", "Unexpected error: " + e.getMessage());
148
- }
149
- }
150
-
151
- @ReactMethod
152
- public void isAppInstalledOnWatch(String packageName, Promise promise) {
153
- try {
154
- Context context = getContext();
155
-
156
- CapabilityClient capabilityClient = Wearable.getCapabilityClient(context);
157
- Task<CapabilityInfo> capabilityTask = capabilityClient.getCapability(
158
- packageName, CapabilityClient.FILTER_ALL);
159
- CapabilityInfo capabilityInfo = Tasks.await(capabilityTask);
160
-
161
- Set<Node> capableNodes = capabilityInfo.getNodes();
162
-
163
- WritableMap result = Arguments.createMap();
164
- result.putBoolean("isInstalled", !capableNodes.isEmpty());
165
-
166
- WritableArray nodeIds = Arguments.createArray();
167
- for (Node node : capableNodes) {
168
- nodeIds.pushString(node.getId());
169
- }
170
- result.putArray("installedOnNodes", nodeIds);
171
-
172
- promise.resolve(result);
173
-
174
- } catch (ExecutionException | InterruptedException e) {
175
- promise.reject("CHECK_FAILED", "Failed to check app installation: " + e.getMessage());
176
- } catch (Exception e) {
177
- promise.reject("CHECK_FAILED", "Unexpected error: " + e.getMessage());
178
- }
179
- }
180
-
181
- @ReactMethod
182
- public void sendMessageToWatch(String nodeId, String path, String data, Promise promise) {
183
- try {
184
- Context context = getContext();
185
-
186
- Task<Integer> sendTask = Wearable.getMessageClient(context)
187
- .sendMessage(nodeId, path, data.getBytes());
188
- Tasks.await(sendTask);
189
-
190
- promise.resolve(null);
191
-
192
- } catch (ExecutionException | InterruptedException e) {
193
- promise.reject("MESSAGE_FAILED", "Failed to send message: " + e.getMessage());
194
- } catch (Exception e) {
195
- promise.reject("MESSAGE_FAILED", "Unexpected error: " + e.getMessage());
196
- }
197
- }
198
- }