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

feat: add push notifications #163

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
1c6e544
feat: add push notifications
reneaaron Oct 22, 2024
1184ab3
fix: lint errors
reneaaron Oct 31, 2024
7a42fde
fix: local notifications
reneaaron Oct 31, 2024
41b4299
fix: decrypt content
reneaaron Nov 6, 2024
a572e10
chore: improve notifications support
im-adithya Nov 11, 2024
184548a
feat: add notification service extension
im-adithya Nov 11, 2024
f4bf55d
feat: add messaging service for android notifications
im-adithya Nov 12, 2024
ba47b38
chore: changes
im-adithya Nov 12, 2024
814959e
chore: add message service config plugin
im-adithya Nov 12, 2024
979dfb2
chore: use our own modified package
im-adithya Nov 12, 2024
4957141
chore: import shared preferences only in android
im-adithya Nov 13, 2024
9b4a596
chore: add google services json to env
im-adithya Nov 13, 2024
6a5ccc4
chore: further changes
im-adithya Nov 14, 2024
c84bb84
fix: handle linking hook
im-adithya Nov 14, 2024
572c59a
chore: more changes
im-adithya Nov 14, 2024
0db8b05
chore: add notification handling
im-adithya Nov 15, 2024
5080ea3
chore: use transaction in deep link
im-adithya Nov 15, 2024
b9103c4
chore: add notification icon in android
im-adithya Nov 15, 2024
45908cd
chore: pass wallet id to transaction screen
im-adithya Nov 20, 2024
3f74bcc
chore: set wallet in use effect
im-adithya Nov 20, 2024
9c9c5c7
chore: remove processing from uibackgroundmode
im-adithya Nov 21, 2024
c59e919
Merge branch 'master' into task-notifications
im-adithya Jan 8, 2025
50654c2
Merge pull request #188 from getAlby/task-notifications
im-adithya Jan 9, 2025
e937d2c
chore: rename wallet info library
im-adithya Jan 9, 2025
408b6ec
chore: remove duplication
im-adithya Jan 9, 2025
8ee413e
chore: remove splash from app config
im-adithya Jan 9, 2025
8e089d1
chore: check if notifications are enabled while editing and removing …
im-adithya Jan 9, 2025
06be6ba
chore: check if wallet has notifications capability before registering
im-adithya Jan 9, 2025
ba56cf3
chore: also check for notifications capability
im-adithya Jan 9, 2025
b390f06
chore: allow payment sent notifications
im-adithya Jan 9, 2025
57b7567
feat: prompt for notifications if not enabled
im-adithya Jan 16, 2025
fb64bcf
chore: add comments and organize code
im-adithya Jan 21, 2025
c982b5e
chore: add comment about notification deeplink
im-adithya Jan 21, 2025
c76f519
fix: keep Expo Go working
im-adithya Jan 21, 2025
a02098d
chore: add notifications note to readme
im-adithya Jan 21, 2025
f50fae2
chore: use nip44 and versioning
im-adithya Jan 21, 2025
c71b201
chore: add nip44 decryption in ios
im-adithya Jan 21, 2025
9493d88
chore: add nip44 decryption in android
im-adithya Jan 21, 2025
64ff15e
fix: deep link in ios
im-adithya Jan 23, 2025
760f7a1
chore: add comment to migrate to 1.0 in future
im-adithya Jan 23, 2025
7d28193
chore: further changes and fixes
im-adithya Jan 23, 2025
71b2940
chore: use persisted expo token
im-adithya Jan 24, 2025
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
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ yarn-error.*
# typescript
*.tsbuildinfo

android
ios
/ios
/android

google-services.json
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,17 @@ A simple lightning mobile wallet interface that works great with [Alby Hub](http
`yarn install`

`yarn start`

### Notifications

Push notifications are only available when running the app on a **physical device** using the following commands:

For iOS:

`yarn ios:device`

For Android:

`yarn android:device`

**Note:** Notifications do not work in the Expo Go app. You must run the app on a standalone build or a device using the above commands.
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

1. Update version in

- `app.json`
- `app.config.js`
- `package.json`

2. Create a git tag and push it (a new draft release will be created)
Expand Down
108 changes: 108 additions & 0 deletions app.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import withMessagingServicePlugin from "./plugins/android/withMessageServicePlugin";
import withOpenSSLPlugin from "./plugins/ios/withOpenSSLPlugin";

export default ({ config }) => {
return {
...config,
name: "Alby Go",
slug: "alby-mobile",
version: "1.8.1",
scheme: ["lightning", "bitcoin", "alby", "nostr+walletconnect"],
orientation: "portrait",
icon: "./assets/icon.png",
userInterfaceStyle: "automatic",
newArchEnabled: true,
assetBundlePatterns: ["**/*"],
plugins: [
[
withMessagingServicePlugin,
{
androidFMSFilePath: "./assets/android/MessagingService.kt",
},
],
[withOpenSSLPlugin],
[
"expo-notification-service-extension-plugin",
{
mode: "production",
iosNSEFilePath: "./assets/ios/NotificationService.m",
},
],
[
"expo-splash-screen",
{
backgroundColor: "#0B0930",
image: "./assets/icon.png",
imageWidth: "150",
},
],
[
"expo-local-authentication",
{
faceIDPermission: "Allow Alby Go to use Face ID.",
},
],
[
"expo-camera",
{
cameraPermission:
"Allow Alby Go to use the camera to scan wallet connection and payment QR codes",
recordAudioAndroid: false,
},
],
[
"expo-font",
{
fonts: [
"./assets/fonts/OpenRunde-Regular.otf",
"./assets/fonts/OpenRunde-Medium.otf",
"./assets/fonts/OpenRunde-Semibold.otf",
"./assets/fonts/OpenRunde-Bold.otf",
],
},
],
[
"expo-notifications",
{
icon: "./assets/notification.png",
},
],
"expo-router",
"expo-secure-store",
],
ios: {
supportsTablet: true,
bundleIdentifier: "com.getalby.mobile",
config: {
usesNonExemptEncryption: false,
},
infoPlist: {
LSMinimumSystemVersion: "12.0",
UIBackgroundModes: ["remote-notification"],
},
userInterfaceStyle: "automatic",
},
android: {
package: "com.getalby.mobile",
icon: "./assets/icon.png",
adaptiveIcon: {
foregroundImage: "./assets/adaptive-icon.png",
backgroundImage: "./assets/adaptive-icon-bg.png",
monochromeImage: "./assets/monochromatic.png",
},
permissions: [
"android.permission.CAMERA",
"android.permission.USE_BIOMETRIC",
"android.permission.USE_FINGERPRINT",
],
userInterfaceStyle: "automatic",
googleServicesFile: process.env.GOOGLE_SERVICES_JSON,
},
extra: {
eas: {
projectId: "294965ec-3a67-4994-8794-5cc1117ef155",
},
},
owner: "roland_alby",
};
};
81 changes: 0 additions & 81 deletions app.json

This file was deleted.

5 changes: 5 additions & 0 deletions app/(app)/settings/notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Notifications } from "../../../pages/settings/Notifications";

export default function Page() {
return <Notifications />;
}
58 changes: 37 additions & 21 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ import { SafeAreaView } from "react-native-safe-area-context";
import Toast from "react-native-toast-message";
import { SWRConfig } from "swr";
import { toastConfig } from "~/components/ToastConfig";
import { NotificationProvider } from "~/context/Notification";
import { UserInactivityProvider } from "~/context/UserInactivity";
import "~/global.css";
import { useInfo } from "~/hooks/useInfo";
import { SessionProvider } from "~/hooks/useSession";
import { NAV_THEME } from "~/lib/constants";
import { IS_EXPO_GO, NAV_THEME } from "~/lib/constants";
import { isBiometricSupported } from "~/lib/isBiometricSupported";
import { useAppStore } from "~/lib/state/appStore";
import { useColorScheme } from "~/lib/useColorScheme";
import { registerForPushNotificationsAsync } from "~/services/Notifications";

const LIGHT_THEME: Theme = {
...DefaultTheme,
Expand Down Expand Up @@ -67,6 +69,15 @@ export default function RootLayout() {
}
}

async function checkAndPromptForNotifications() {
const isEnabled = useAppStore.getState().isNotificationsEnabled;
// prompt the user to enable notifications on first open
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this good UX? CC @reneaaron

if (isEnabled === null) {
const enabled = await registerForPushNotificationsAsync();
useAppStore.getState().setNotificationsEnabled(enabled);
}
}

const loadTheme = React.useCallback((): Promise<void> => {
return new Promise((resolve) => {
const theme = useAppStore.getState().theme;
Expand All @@ -85,6 +96,9 @@ export default function RootLayout() {
await Promise.all([loadTheme(), loadFonts(), checkBiometricStatus()]);
} finally {
setResourcesLoaded(true);
if (!IS_EXPO_GO) {
await checkAndPromptForNotifications();
}
SplashScreen.hide();
}
};
Expand All @@ -98,26 +112,28 @@ export default function RootLayout() {

return (
<SWRConfig value={swrConfiguration}>
<ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>
<StatusBar style={isDarkColorScheme ? "light" : "dark"} />
<SafeAreaView
className="w-full h-full bg-background"
edges={["left", "right", "bottom"]}
>
<UserInactivityProvider>
<SessionProvider>
<Slot />
</SessionProvider>
</UserInactivityProvider>
<Toast
config={toastConfig}
position="bottom"
bottomOffset={140}
topOffset={140}
/>
<PortalHost />
</SafeAreaView>
</ThemeProvider>
<NotificationProvider>
im-adithya marked this conversation as resolved.
Show resolved Hide resolved
<ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>
<StatusBar style={isDarkColorScheme ? "light" : "dark"} />
<SafeAreaView
className="w-full h-full bg-background"
edges={["left", "right", "bottom"]}
>
<UserInactivityProvider>
<SessionProvider>
<Slot />
</SessionProvider>
</UserInactivityProvider>
<Toast
config={toastConfig}
position="bottom"
bottomOffset={140}
topOffset={140}
/>
<PortalHost />
</SafeAreaView>
</ThemeProvider>
</NotificationProvider>
</SWRConfig>
);
}
Expand Down
Loading
Loading