From 521ffb19ee262f5961c79fd2c9f3be9d5016bbfb Mon Sep 17 00:00:00 2001 From: aeroreyna Date: Tue, 15 Mar 2022 21:22:02 -0700 Subject: [PATCH] Add notifications --- API.js | 3 + App.js | 93 +- ...{Notifications.js => NotificationsView.js} | 18 +- Views/Video.js | 31 + app.json | 6 +- package-lock.json | 803 ++++++++++++++++++ package.json | 5 +- 7 files changed, 932 insertions(+), 27 deletions(-) rename Views/{Notifications.js => NotificationsView.js} (77%) create mode 100644 Views/Video.js diff --git a/API.js b/API.js index 8153cab..5762d4d 100644 --- a/API.js +++ b/API.js @@ -135,6 +135,9 @@ const API = { getVideo(videoId) { return getCall("/post/video/" + videoId); }, + registerToken(token) { + return postCall("/token/", {token}); + }, deletePost(postid){ return deleteCall("/post/" + postid); }, diff --git a/App.js b/App.js index 46707a3..90dcc52 100644 --- a/App.js +++ b/App.js @@ -1,5 +1,5 @@ import { StatusBar } from 'expo-status-bar'; -import React from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs'; @@ -8,8 +8,11 @@ import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import Login from "./Views/Login.js" import Feed from "./Views/Feed.js" import Profile from "./Views/Profile.js" -import Notifications from './Views/Notifications.js'; +import NotificationsView from './Views/NotificationsView.js'; import SinglePost from './Views/SinglePost.js' +import * as Device from 'expo-device'; +import * as Notifications from 'expo-notifications'; +import API from './API.js'; const Tab = createMaterialBottomTabNavigator(); @@ -25,7 +28,77 @@ const theme = { }, }; +Notifications.setNotificationHandler({ + handleNotification: async () => ({ + shouldShowAlert: true, + shouldPlaySound: false, + shouldSetBadge: false, + }), +}); + +async function registerForPushNotificationsAsync() { + let token; + if (Device.isDevice) { + const { status: existingStatus } = await Notifications.getPermissionsAsync(); + let finalStatus = existingStatus; + if (existingStatus !== 'granted') { + const { status } = await Notifications.requestPermissionsAsync(); + finalStatus = status; + } + if (finalStatus !== 'granted') { + alert('Failed to get push token for push notification!'); + return; + } + token = (await Notifications.getExpoPushTokenAsync()).data; + console.log(token); + } else { + alert('Must use physical device for Push Notifications'); + } + + if (Platform.OS === 'android') { + Notifications.setNotificationChannelAsync('default', { + name: 'default', + importance: Notifications.AndroidImportance.MAX, + vibrationPattern: [0, 250, 250, 250], + lightColor: '#FF231F7C', + }); + } + console.log(token); + return token; +} + + + const MainNavigation = () => { + const [expoPushToken, setExpoPushToken] = useState(''); + const [notification, setNotification] = useState(false); + const notificationListener = useRef(); + const responseListener = useRef(); + + useEffect(() => { + registerForPushNotificationsAsync().then(async (token) => { + let isLoggedIn = await API.isLoggedIn(); + if (isLoggedIn) API.registerToken(token); + return setExpoPushToken(token); + }); + + // This listener is fired whenever a notification is received while the app is foregrounded + notificationListener.current = Notifications.addNotificationReceivedListener(notification => { + setNotification(notification); + }); + + // This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed) + responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { + console.log(response); + }); + + return () => { + Notifications.removeNotificationSubscription(notificationListener.current); + Notifications.removeNotificationSubscription(responseListener.current); + }; + }, []); + + return ( { }, })} /> - ( @@ -58,7 +131,7 @@ const MainNavigation = () => { tabBarBadge: false }} /> - + ) @@ -71,10 +144,10 @@ export default function App() { }} theme={theme}> - { - let [post, setPost] = useState({}); - useEffect(async () => { - setPost(await API.getPost(postid)); - }, [postid]); - return (post._id ? : null); -}; - -let Notifications = ({ navigation, route }) => { +let NotificationsView = ({ navigation, route }) => { let [Me, setMeProfile] = useState({}); let [notifications, setNotifications] = useState([]); useEffect(async () => { @@ -24,7 +15,6 @@ let Notifications = ({ navigation, route }) => { setNotifications(r.notifications) }, [route.params]); const renderNotification = (({ item }) => { - //return (); const gotToPost = () => { navigation.navigate('SinglePost', { postid: item.postid, viewer: Me }); }; @@ -55,7 +45,7 @@ let Notifications = ({ navigation, route }) => { ); } -export default Notifications; +export default NotificationsView; const styles = StyleSheet.create({ container: { diff --git a/Views/Video.js b/Views/Video.js new file mode 100644 index 0000000..3eb184b --- /dev/null +++ b/Views/Video.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { View, StyleSheet, Button } from 'react-native'; +import { Video, AVPlaybackStatus } from 'expo-av'; + +export default function App({videoUrl}) { + const video = React.useRef(null); + const [status, setStatus] = React.useState({}); + return ( + +