Skip to content
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
45 changes: 40 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,56 @@ name: CI
on: [pull_request]

jobs:
test:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: 'npm'

- run: npm ci

# AirshipConfig.ts holds credentials and is gitignored, so the example
# cannot typecheck or bundle without one.
- name: Provide the example's Airship config
run: cp example/src/AirshipConfig.ts.example example/src/AirshipConfig.ts

- run: npm run typecheck
- run: npm run lint
- run: npm test

# The native jobs build Debug, which loads JS from Metro at runtime and
# never compiles it. Bundling is what fails on a missing import.
- name: Bundle the example
working-directory: example
run: |
npx react-native bundle \
--platform android \
--dev false \
--entry-file index.js \
--bundle-output "$RUNNER_TEMP/index.android.bundle" \
--assets-dest "$RUNNER_TEMP/assets"

native:
runs-on: macos-26-xlarge
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0.1'
ruby-version: '3.3'

- name: Setup Node.js
uses: actions/setup-node@v4
with:
Expand All @@ -26,4 +61,4 @@ jobs:

- run: npm ci
- run: bash ./scripts/run_ci_tasks.sh -i
- run: bash ./scripts/run_ci_tasks.sh -a
- run: bash ./scripts/run_ci_tasks.sh -a
10 changes: 10 additions & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ target 'AirshipExample' do
:mac_catalyst_enabled => false,
# :ccache_enabled => true
)

# RNCClipboard calls UTType APIs but its podspec declares only React-Core,
# so the framework carrying them is never linked and the pod fails to link.
installer.pods_project.targets.each do |target|
next unless target.name == 'RNCClipboard'
target.build_configurations.each do |config|
config.build_settings['OTHER_LDFLAGS'] =
"#{config.build_settings['OTHER_LDFLAGS'] || '$(inherited)'} -framework MobileCoreServices"
end
end
end
end

Expand Down
7 changes: 6 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
"build:ios": "react-native build-ios --mode Debug"
},
"dependencies": {
"@react-native-clipboard/clipboard": "^1.16.3",
"@react-native-vector-icons/material-icons": "^13.1.4",
"@react-navigation/native": "^7.5.0",
"@react-navigation/stack": "^7.12.0",
"moment": "^2.30.1",
"react": "19.2.3",
"react-native": "0.87.1",
"react-native-safe-area-context": "^5.10.0"
"react-native-gesture-handler": "^3.3.0",
"react-native-safe-area-context": "^5.10.0",
"react-native-screens": "^4.28.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down
9 changes: 9 additions & 0 deletions example/src/Styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ export default StyleSheet.create({
padding: Spacing.xl,
backgroundColor: Colors.background,
},
loadingIndicator: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
},
centered: {
flex: 1,
alignItems: 'center',
Expand Down
1 change: 0 additions & 1 deletion example/src/navigation/AppNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* Copyright Airship and Contributors */

import React from 'react';
import { Platform, UIManager } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
Expand Down
2 changes: 1 addition & 1 deletion example/src/navigation/TabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

// Create a mock navigation object for screens - must exactly match what screens expect
const navigation = {
navigate: (routeName: string, params?: Record<string, any>) => {

Check warning on line 55 in example/src/navigation/TabNavigator.tsx

View workflow job for this annotation

GitHub Actions / checks

'params' is already declared in the upper scope on line 38 column 10
if (routeName === 'MessageDetails') {
setActiveScreen(TabScreens.MESSAGE_DETAILS);
if (params) {
Expand All @@ -75,10 +75,10 @@
}
},
addListener: () => ({ remove: () => {} }),
push: (routeName: string, params?: Record<string, any>) => {

Check warning on line 78 in example/src/navigation/TabNavigator.tsx

View workflow job for this annotation

GitHub Actions / checks

'params' is already declared in the upper scope on line 38 column 10
navigate(routeName as TabScreens, params);
},
replace: (routeName: string, params?: Record<string, any>) => {

Check warning on line 81 in example/src/navigation/TabNavigator.tsx

View workflow job for this annotation

GitHub Actions / checks

'params' is already declared in the upper scope on line 38 column 10
navigate(routeName as TabScreens, params);
},
setParams: (newParams: Record<string, any>) => {
Expand All @@ -103,7 +103,7 @@
case TabScreens.MESSAGE_CENTER:
return <MessageCenterScreen navigation={navigation} route={route} />;
case TabScreens.PREFERENCE_CENTER:
return <PreferenceCenterScreen navigation={navigation} route={route} />;
return <PreferenceCenterScreen navigation={navigation} />;
case TabScreens.EMBEDDED_VIEWS:
return <EmbeddedViewsScreen navigation={navigation} />;
case TabScreens.MESSAGE_DETAILS:
Expand Down
16 changes: 12 additions & 4 deletions example/src/screens/CustomEventsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright Airship and Contributors */

import React, { useState } from 'react';
import { useState } from 'react';
import {
View,
Text,
Expand Down Expand Up @@ -32,13 +32,21 @@

const updatePropertyKey = (text: string, index: number) => {
const updatedProperties = [...eventProperties];
updatedProperties[index].key = text;
const entry = updatedProperties[index];
if (!entry) {
return;
}
entry.key = text;
setEventProperties(updatedProperties);
};

const updatePropertyValue = (text: string, index: number) => {
const updatedProperties = [...eventProperties];
updatedProperties[index].value = text;
const entry = updatedProperties[index];
if (!entry) {
return;
}
entry.value = text;
setEventProperties(updatedProperties);
};

Expand Down Expand Up @@ -72,7 +80,7 @@
await Airship.analytics.addCustomEvent({
eventName: eventName,
eventValue: value,
properties: Object.keys(properties).length > 0 ? properties : undefined,
properties,
});

Alert.alert('Success', 'Custom event sent successfully');
Expand All @@ -90,7 +98,7 @@

return (
<KeyboardAvoidingView
style={{ flex: 1 }}

Check warning on line 101 in example/src/screens/CustomEventsScreen.tsx

View workflow job for this annotation

GitHub Actions / checks

Inline style: { flex: 1 }
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
keyboardVerticalOffset={Platform.OS === 'ios' ? 100 : 0}
>
Expand Down
1 change: 0 additions & 1 deletion example/src/screens/Home Elements/ChannelCell.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';

Expand All @@ -10,11 +9,11 @@
};

return (
<View style={{ marginLeft: 0, marginRight: 0 }}>

Check warning on line 12 in example/src/screens/Home Elements/ChannelCell.tsx

View workflow job for this annotation

GitHub Actions / checks

Inline style: { marginLeft: 0, marginRight: 0 }
<TouchableHighlight onPress={copyToClipboard} style={{ borderRadius: 8 }}>

Check warning on line 13 in example/src/screens/Home Elements/ChannelCell.tsx

View workflow job for this annotation

GitHub Actions / checks

Inline style: { borderRadius: 8 }
<View style={styles.channelCellContents}>
<Text style={{ fontWeight: 'bold' }}>Channel ID</Text>

Check warning on line 15 in example/src/screens/Home Elements/ChannelCell.tsx

View workflow job for this annotation

GitHub Actions / checks

Inline style: { fontWeight: 'bold' }
<Text style={{ marginTop: 0 }}>{channelId}</Text>

Check warning on line 16 in example/src/screens/Home Elements/ChannelCell.tsx

View workflow job for this annotation

GitHub Actions / checks

Inline style: { marginTop: 0 }
</View>
</TouchableHighlight>
</View>
Expand Down
1 change: 0 additions & 1 deletion example/src/screens/Home Elements/NamedUserInputCell.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import { View, TextInput } from 'react-native';
import styles from '../../Styles';

Expand Down
11 changes: 7 additions & 4 deletions example/src/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright Airship and Contributors */

import React, { useState, useEffect, useCallback } from 'react';
import { useState, useEffect, useCallback } from 'react';
import {
View,
Text,
Expand All @@ -15,6 +15,7 @@ import {
} from 'react-native';
import styles from '../Styles';
import Airship, {
PromptPermissionFallback,
EventType,
AirshipEmbeddedView,
SmsRegistrationOptions,
Expand Down Expand Up @@ -54,7 +55,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {
const refreshNamedUser = useCallback(async () => {
try {
const fetchedNamedUser = await Airship.contact.getNamedUserId();
setNamedUser(fetchedNamedUser);
setNamedUser(fetchedNamedUser ?? undefined);
} catch {
// Ignore errors fetching named user
}
Expand Down Expand Up @@ -143,7 +144,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {
try {
if (enabled) {
await Airship.push.enableUserNotifications({
fallback: 'systemSettings',
fallback: PromptPermissionFallback.SystemSettings,
});
} else {
await Airship.push.setUserNotificationsEnabled(false);
Expand Down Expand Up @@ -194,6 +195,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {
const activities = await Airship.iOS.liveActivityManager.listAll();
for (const element of activities) {
await Airship.iOS.liveActivityManager.end({
attributesType: 'ExampleWidgetsAttributes',
activityId: element.id,
dismissalPolicy: {
type: 'immediate',
Expand Down Expand Up @@ -222,6 +224,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {
const activities = await Airship.iOS.liveActivityManager.listAll();
for (const element of activities) {
await Airship.iOS.liveActivityManager.update({
attributesType: 'ExampleWidgetsAttributes',
activityId: element.id,
content: {
state: {
Expand Down Expand Up @@ -272,7 +275,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) {

// Get named user
const fetchedNamedUser = await Airship.contact.getNamedUserId();
setNamedUser(fetchedNamedUser);
setNamedUser(fetchedNamedUser ?? undefined);
} catch {
// Expected error when Airship is not initialized
} finally {
Expand Down
4 changes: 2 additions & 2 deletions example/src/screens/MessageCenterScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright Airship and Contributors */

import React, { useState, useEffect, useCallback } from 'react';
import { useState, useEffect, useCallback } from 'react';
import {
Text,
View,
Expand All @@ -20,7 +20,7 @@ type MessageCenterScreenProps = {
type MessageItem = {
id: string;
title: string;
sentDate: string;
sentDate: number;
};

const Item = ({
Expand Down
11 changes: 8 additions & 3 deletions example/src/screens/MessageDetailsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* Copyright Airship and Contributors */

import React, { useState, useEffect } from 'react';
import { useState, useEffect } from 'react';
import {
View,
Text,
ActivityIndicator,
Alert,
Button,
StyleSheet,
} from 'react-native';
Expand Down Expand Up @@ -41,7 +42,7 @@ export default function MessageDetailsScreen({

const failedLoading = () => {
setAnimating(false);
alert('Unable to load message. Please try again later');
Alert.alert('Unable to load message. Please try again later');
navigation.goBack();
};
return (
Expand Down Expand Up @@ -92,7 +93,11 @@ const styles = StyleSheet.create({
position: 'relative',
},
loadingContainer: {
...StyleSheet.absoluteFillObject,
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.7)',
Expand Down
2 changes: 1 addition & 1 deletion example/src/screens/MessageScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright Airship and Contributors */

import React, { useState, useEffect } from 'react';
import { useState, useEffect } from 'react';
import { View, ActivityIndicator, Alert } from 'react-native';
import { MessageView } from '@ua/react-native-airship';
import type { StackNavigationProp } from '@react-navigation/stack';
Expand Down
Loading
Loading