commit 91767b9d67c3530f7c80cca263600e0936cc915f Author: Quiint Date: Thu Feb 8 09:10:53 2024 -0500 inital diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5bfec58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,81 @@ +node_modules/ +.expo/ +dist/ +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ + +# macOS +.DS_Store + +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# @generated expo-cli sync-647791c5bd841d5c91864afb91c302553d300921 +# The following patterns were generated by expo-cli + +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +*.hprof +.cxx/ +*.keystore +!debug.keystore + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# Bundle artifacts +*.jsbundle + +# CocoaPods +/ios/Pods/ + +# Temporary files created by Metro to check the health of the file watcher +.metro-health-check* + +# Expo +.expo/ +web-build/ +dist/ + +# @end expo-cli +ios +android +out diff --git a/App.js b/App.js new file mode 100644 index 0000000..be92d42 --- /dev/null +++ b/App.js @@ -0,0 +1,159 @@ +import React, { useEffect, useState } from 'react'; +import { NavigationContainer } from '@react-navigation/native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; +import HomeScreen from './Home'; +import ProfileScreen from './Profile'; +import LoginScreen from './Login'; +import SignupScreen from './Signup'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import SwitScreen from './Swit'; +import UserProfileScreen from './UserProfile'; +import { createNativeStackNavigator } from '@react-navigation/native-stack' +import {TailwindProvider} from 'tailwind-rn'; +import utilities from './tailwind.json'; +import FollowingScreen from './Following'; +import SwitDetailScreen from './SwitDetail'; +import SettingsScreen from './Settings'; +import SearchScreen from './Search'; +import Toast from 'react-native-toast-message' +import Notifications from './Notification'; +import LikesScreen from './LikesScreen'; +import { socket } from './services/socket'; +import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; +import { SafeAreaView } from 'react-native-safe-area-context'; +import EditProfileScreen from './EditProfileScreen'; +import DirectMessagesScreen from './DirectMessagesScreen'; +import ConversationScreen from './ConversationScreen'; + + + + +const Tab = createBottomTabNavigator(); +const HomeStack = createNativeStackNavigator(); +const HomeTopTab = createMaterialTopTabNavigator(); + +function HomeTopTabNavigator() { + return ( + + + + + + + ); +} + + +function HomeStackScreen() { + return ( + + + + ({ title: route.params.username })} + /> + + + } + /> + + + + ({ title: route.params.username })} + /> + + + ); +} + + +export default function App() { + const [userToken, setUserToken] = useState(null); + // Listen for 'notification' messages + + + + const checkUserToken = async () => { + const token = await AsyncStorage.getItem('token'); + setUserToken(token); + }; + + useEffect(() => { + checkUserToken(); + }, []); + + useEffect(() => { + const setDefaultAPI = async () => { + const apiEndpoint = await AsyncStorage.getItem('apiEndpoint'); + if (!apiEndpoint) { + await AsyncStorage.setItem('apiEndpoint', 'http://staging.swifter.win'); + } + }; + + setDefaultAPI(); + }, []); + + return ( + <> + + + {userToken ? ( + + + + + + + + + + ) : ( + + } /> + + + + )} + + + + + ); +} diff --git a/ConversationScreen.js b/ConversationScreen.js new file mode 100644 index 0000000..1a043e3 --- /dev/null +++ b/ConversationScreen.js @@ -0,0 +1,117 @@ +import React, { useState, useEffect } from 'react'; +import { View, Text, TextInput, Button, FlatList, ActivityIndicator } from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import io from 'socket.io-client' +import { useTailwind } from 'tailwind-rn'; + +function ConversationScreen({ route, navigation }) { + const { otherUserId } = route.params; + const [directMessages, setDirectMessages] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); + const [newMessage, setNewMessage] = useState(''); + const tailwind = useTailwind(); + + async function fetchDirectMessages() { + setIsLoading(true); + try { + const token = await AsyncStorage.getItem('token'); + const apiUrl = await AsyncStorage.getItem('apiEndpoint') + const response = await fetch(`${apiUrl}/api/v1/app/dms/${otherUserId}`, { + headers: { 'Authorization': token }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch direct messages: ${response.status}`); + } + + const messages = await response.json(); + setDirectMessages(messages); + } catch (error) { + console.error('Error:', error); + setErrorMessage(error.message); + } finally { + setIsLoading(false); + } + } + + async function handleSendMessage() { + const token = await AsyncStorage.getItem('token'); + const senderId = await AsyncStorage.getItem('userID'); + const apiUrl = await AsyncStorage.getItem('apiEndpoint') + const response = await fetch(`${apiUrl}/api/v1/app/dms/send`, { + method: 'POST', + headers: { + 'Authorization': token, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ recipientId: otherUserId, text: newMessage, senderId: senderId }), + }); + + if (!response.ok) { + throw new Error(`Failed to send message: ${response.status}`); + } + + const message = await response.json(); + setNewMessage(''); + } + + useEffect(() => { + async function setupSocket() { + const senderId = await AsyncStorage.getItem('userID'); + console.log('Sender ID:', senderId); + const apiUrl = await AsyncStorage.getItem('apiEndpoint') + const socket = io(apiUrl); + socket.emit('user connected', senderId); + socket.on('new_dm', (newDm) => { + setDirectMessages(prevMessages => [...prevMessages, newDm]); + }); + } + + async function setup() { + await fetchDirectMessages(); + await setupSocket(); + } + + setup(); + }, []); + + + + return ( + + {/* Display a loading indicator while the messages are being fetched */} + {isLoading && } + {errorMessage !== '' && {errorMessage}} + + {/* Render the list of direct messages */} + + item._id} + renderItem={({ item }) => ( + + {item.sender.username}: {item.content} + + )} + /> + + + {/* Render the text input and send button */} + + +