Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement watch example and basic send message api #1

Merged
merged 7 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ android/keystores/debug.keystore

# generated by bob
lib/
example/.env
watch-example/.env
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ dependencies {
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation 'com.google.android.gms:play-services-wearable:18.1.0'
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
package com.wearconnectivity;

import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.android.gms.wearable.MessageClient;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeClient;
import com.google.android.gms.wearable.Wearable;

import java.util.List;
import java.util.concurrent.ExecutionException;

public class WearConnectivityModule extends WearConnectivitySpec {
public class WearConnectivityModule extends WearConnectivitySpec implements MessageClient.OnMessageReceivedListener, LifecycleEventListener {
public static final String NAME = "WearConnectivity";

WearConnectivityModule(ReactApplicationContext context) {
super(context);
context.addLifecycleEventListener(this);
Wearable.getMessageClient(context).addListener(this);
}

@Override
Expand All @@ -26,4 +44,74 @@ public String getName() {
public void multiply(double a, double b, Promise promise) {
promise.resolve(a * b);
}

// catch the ExecutionException
@ReactMethod
public void increaseWearCounter(Promise promise) {
try {
// add a check that it has permissions for that scope
// https://android-developers.googleblog.com/2017/11/moving-past-googleapiclient_21.html
NodeClient nodeClient = Wearable.getNodeClient(getReactApplicationContext());
List<Node> nodes = Tasks.await(nodeClient.getConnectedNodes());
if (nodes.size() > 0) {
for (Node node : nodes) {
sendMessageToClient(node);
}
promise.resolve(true);
} else {
Toast.makeText(getReactApplicationContext(), "No connected nodes found", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
Log.w("TESTING", "EXCEPTION: " + e);
}
}

private void sendMessageToClient(Node node) {
try {
Task<Integer> sendTask =
Wearable.getMessageClient(getReactApplicationContext()).sendMessage(
node.getId(), "/increase_wear_counter", null);
OnSuccessListener<Object> onSuccessListener = new OnSuccessListener<Object>() {
@Override
public void onSuccess(Object object) {
Log.w("TESTING: ", "from Phone onSuccess");
}
};
sendTask.addOnSuccessListener(onSuccessListener);
OnFailureListener onFailureListener = new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w("TESTING: ", "from Phone onFailure with e: " + e);
}
};
sendTask.addOnFailureListener(onFailureListener);
} catch (Exception e) {
Log.w("TESTING: ", "from Phone e: " + e);
}
}

public void onMessageReceived(MessageEvent messageEvent) {
Log.w("TESTING: ", "from Phone onMessageReceived");
/*
if (messageEvent.getPath().equals("/increase_phone_counter")) {
sendEvent(getReactApplicationContext(), "increaseCounter", null);
}
*/
}

@Override
public void onHostResume() {
// implement it
}


@Override
public void onHostPause() {
// implement it
}

@Override
public void onHostDestroy() {
Wearable.getMessageClient(getReactApplicationContext()).removeListener(this);
}
}
1 change: 1 addition & 0 deletions android/src/oldarch/WearConnectivitySpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ abstract class WearConnectivitySpec extends ReactContextBaseJavaModule {
}

public abstract void multiply(double a, double b, Promise promise);
public abstract void increaseWearCounter(Promise promise);
}
6 changes: 4 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "react-native-wear-connectivity-example",
"name": "react-native-phone-connectivity-example",
"version": "0.0.1",
"private": true,
"scripts": {
Expand All @@ -10,8 +10,10 @@
"build:ios": "cd ios && xcodebuild -workspace WearConnectivityExample.xcworkspace -scheme WearConnectivityExample -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"
},
"dependencies": {
"@react-native-google-signin/google-signin": "^11.0.0",
"react": "18.2.0",
"react-native": "0.73.4"
"react-native": "0.73.4",
"react-native-config": "^1.5.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
26 changes: 16 additions & 10 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import * as React from 'react';

import { StyleSheet, View, Text } from 'react-native';
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import LoginScreen from './LoginScreen';
import WearScreen from './WearScreen';
import { GoogleSignin } from '@react-native-google-signin/google-signin';

Check failure on line 5 in example/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

'GoogleSignin' is defined but never used
import { multiply } from 'react-native-wear-connectivity';

export default function App() {
const App = () => {
const [result, setResult] = React.useState<number | undefined>();

React.useEffect(() => {
multiply(3, 7).then(setResult);
}, []);

return (
<View style={styles.container}>
<Text>Result: {result}</Text>
</View>
<>
<LoginScreen />
<WearScreen />
<View style={styles.container}>
<Text>Result: {result}</Text>
</View>
</>
);
}
};

const styles = StyleSheet.create({
container: {
Expand All @@ -29,3 +33,5 @@
marginVertical: 20,
},
});

export default App;
31 changes: 31 additions & 0 deletions example/src/LoginScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import {
View,
StyleSheet,

Check failure on line 4 in example/src/LoginScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'StyleSheet' is defined but never used
Text,

Check failure on line 5 in example/src/LoginScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'Text' is defined but never used
TextInput,

Check failure on line 6 in example/src/LoginScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'TextInput' is defined but never used
NativeModules,

Check failure on line 7 in example/src/LoginScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'NativeModules' is defined but never used
Button,
} from 'react-native';
import {GoogleSignin} from '@react-native-google-signin/google-signin';

Check failure on line 10 in example/src/LoginScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `GoogleSignin` with `·GoogleSignin·`
import Config from 'react-native-config';

export default function LoginScreen() {
const signIn = async () => {
try {
GoogleSignin.configure({
androidClientId: Config.GOOGLE_ANDROID_CLIENT_ID,
});
const userInfo = await GoogleSignin.signIn();
console.log(JSON.stringify(userInfo));
} catch (error) {
console.log('ERROR IS: ' + JSON.stringify(error));
}
};

return (
<View>
<Button title={'Sign in with Google'} onPress={signIn} />
</View>
);
}
58 changes: 58 additions & 0 deletions example/src/WearScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useEffect } from 'react';
import {
DeviceEventEmitter,

Check failure on line 3 in example/src/WearScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'DeviceEventEmitter' is defined but never used
NativeEventEmitter,
View,
StyleSheet,
Text,
NativeModules,
Button,
} from 'react-native';
import { multiply, increaseWearCounter } from 'react-native-wear-connectivity';

Check failure on line 11 in example/src/WearScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

'multiply' is defined but never used

const INCREASE_COUNTER_EVENT = 'increaseCounter';

export default function WearCounter() {
const [count, setCount] = React.useState(0);

useEffect(() => {
const eventEmitter = new NativeEventEmitter(
NativeModules.AndroidWearCommunication
);
let eventListener = eventEmitter.addListener(INCREASE_COUNTER_EVENT, () => {
setCount((prevCount) => prevCount + 1);
});

return () => {
eventListener.remove();
};
}, []);

const onPressHandler = () => {
console.log('onPressHandler');
increaseWearCounter();
};

return (
<View style={styles.container}>
<Text style={styles.counter}>{count}</Text>
<Button title="increase counter" onPress={onPressHandler} />
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 8,
backgroundColor: 'yellow',
},
counter: {
height: 100,
width: 400,
textAlign: 'center',
fontSize: 50,
fontWeight: 'bold',
},
});
14 changes: 0 additions & 14 deletions lefthook.yml

This file was deleted.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"!**/.*"
],
"scripts": {
"example": "yarn workspace react-native-wear-connectivity-example",
"example": "yarn workspace react-native-phone-connectivity-example",
"watch-example": "yarn workspace react-native-wear-connectivity-example",
"test": "jest",
"typecheck": "tsc --noEmit",
"lint": "eslint \"**/*.{js,ts,tsx}\"",
Expand Down Expand Up @@ -54,7 +55,6 @@
},
"devDependencies": {
"@commitlint/config-conventional": "^17.0.2",
"@evilmartians/lefthook": "^1.5.0",
"@react-native/eslint-config": "^0.72.2",
"@release-it/conventional-changelog": "^5.0.0",
"@types/jest": "^28.1.2",
Expand Down Expand Up @@ -83,7 +83,8 @@
"react-native": "*"
},
"workspaces": [
"example"
"example",
"watch-example"
],
"packageManager": "yarn@3.6.1",
"engines": {
Expand Down
1 change: 1 addition & 0 deletions src/NativeWearConnectivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
multiply(a: number, b: number): Promise<number>;
increaseWearCounter(): Promise<boolean>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('WearConnectivity');
4 changes: 4 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ const WearConnectivity = WearConnectivityModule
export function multiply(a: number, b: number): Promise<number> {
return WearConnectivity.multiply(a, b);
}

export function increaseWearCounter(): Promise<boolean> {
return WearConnectivity.increaseWearCounter();
}
2 changes: 2 additions & 0 deletions watch-example/.bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
1 change: 1 addition & 0 deletions watch-example/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
9 changes: 9 additions & 0 deletions watch-example/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source 'https://rubygems.org'

# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"

# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
# bound in the template on Cocoapods with next React Native release.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
Loading
Loading