diff --git a/client/assets/transparentSend.png b/client/assets/transparentSend.png
new file mode 100644
index 000000000..e3a3380cc
Binary files /dev/null and b/client/assets/transparentSend.png differ
diff --git a/client/package.json b/client/package.json
index 40ebdff7d..8de8eb7a2 100644
--- a/client/package.json
+++ b/client/package.json
@@ -22,6 +22,7 @@
"expo-linear-gradient": "~12.3.0",
"expo-linking": "~5.0.2",
"expo-location": "~16.1.0",
+ "expo-network": "~5.4.0",
"expo-router": "^2.0.0",
"expo-secure-store": "~12.3.1",
"expo-status-bar": "~1.6.0",
@@ -30,14 +31,19 @@
"react": "18.2.0",
"react-native": "0.72.6",
"react-native-dotenv": "^3.4.9",
+ "react-native-feather": "^1.1.2",
"react-native-fs": "^2.20.0",
"react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.0",
"react-native-uuid": "^2.0.1",
"react-native-web": "~0.19.6",
"socket.io-client": "^4.7.4",
+<<<<<<< HEAD
"expo-network": "~5.4.0",
"undefined": "@expo/vector-icons/FontAwesome"
+=======
+ "react-native-svg": "13.9.0"
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/client/src/components/Chat/ChatScreen.tsx b/client/src/components/Chat/ChatScreen.tsx
index 2939a47cb..12c9548e2 100644
--- a/client/src/components/Chat/ChatScreen.tsx
+++ b/client/src/components/Chat/ChatScreen.tsx
@@ -24,6 +24,7 @@ import { useSettings } from "../../contexts/SettingsContext";
import { useLocation } from "../../contexts/LocationContext";
import { useUser } from "../../contexts/UserContext"; // imported for when it needs to be used
import { AuthStore } from "../../services/store";
+import { ChatScreenFooter } from "../Common/ChatScreenFooter"
const ChatScreen = () => {
const settings = useSettings();
@@ -108,13 +109,13 @@ const ChatScreen = () => {
- {
setMessageContent(text);
}}
+ onSend={onHandleSubmit}
/>
-
@@ -147,16 +148,17 @@ const styles = StyleSheet.create({
footerContainer: {
width: "95%",
- minHeight: Dimensions.get("window").height * 0.1,
+
maxHeight: Dimensions.get("window").height * 0.15,
display: "flex",
flexDirection: "row",
alignItems: "flex-end",
justifyContent: "space-evenly",
- paddingBottom: Dimensions.get("window").height * 0.02,
- paddingTop: Dimensions.get("window").height * 0.02,
- marginTop: 10,
- borderTopWidth: 1,
+ paddingBottom: Dimensions.get("window").height * 0.003,
+ paddingTop: Dimensions.get("window").height * 0.004,
+ marginTop: 0,
+ borderTopWidth: 0,
+ borderColor: "#8E8E8E",
},
});
diff --git a/client/src/components/Common/ChatScreenFooter.tsx b/client/src/components/Common/ChatScreenFooter.tsx
new file mode 100644
index 000000000..af9998ed5
--- /dev/null
+++ b/client/src/components/Common/ChatScreenFooter.tsx
@@ -0,0 +1,88 @@
+import React from 'react'
+import { TextInput, View, StyleSheet, Dimensions, Platform, TouchableOpacity } from 'react-native'
+import { ChatSendButton } from './CustomButtons'
+import { Smile, Image } from "react-native-feather";
+
+interface ChatInputProps {
+ value?: string,
+ onChangeText?: (text: string) => void
+ invalid?: boolean,
+ onSend?: () => void,
+}
+
+export const ChatScreenFooter: React.FC = ({ value, onChangeText, onSend }) => {
+
+
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+};
+
+const styles = StyleSheet.create({
+
+ container: {
+ flexDirection: 'row',
+ flex: 1,
+ alignItems: 'center',
+ borderColor: "#8E8E8E",
+ borderWidth: 1,
+ borderRadius: Dimensions.get('window').width * 0.058,
+ marginHorizontal: Dimensions.get('window').width * 0.005,
+ marginBottom: Platform.OS === 'ios' ? 0 : 5,
+ minHeight: Dimensions.get('window').width * 0.113,
+ maxHeight: Dimensions.get('window').width * 0.3,
+ },
+ messageInput: {
+ fontSize: 16,
+ flex: 1,
+ marginBottom: Platform.OS === 'ios' ? 5 : 4,
+ marginTop: Platform.OS === 'ios' ? 2 : 4,
+ marginHorizontal: Dimensions.get('window').width * 0.018,
+
+
+ },
+ icons: {
+ marginHorizontal: Dimensions.get('window').width * 0.008,
+ },
+ iconContainer: {
+ marginLeft: Dimensions.get('window').width * 0.02,
+ marginBottom: Dimensions.get('window').width * 0.025,
+ marginTop: Dimensions.get('window').width * 0.025,
+ flexDirection: 'row',
+ alignItems: "flex-end",
+ justifyContent: "flex-end",
+ alignSelf: "stretch",
+
+
+ },
+ sendButtonContainer: {
+ alignItems: "flex-end",
+ justifyContent: "flex-end",
+ flexDirection: "row",
+ alignSelf: "stretch",
+ marginRight: Dimensions.get('window').width * 0.01,
+ marginBottom: Dimensions.get('window').width * 0.01,
+ marginTop: Dimensions.get('window').width * 0.01,
+ }
+
+});
\ No newline at end of file
diff --git a/client/src/components/Common/CustomButtons.tsx b/client/src/components/Common/CustomButtons.tsx
index 6474e4c56..1b9cd5cb7 100644
--- a/client/src/components/Common/CustomButtons.tsx
+++ b/client/src/components/Common/CustomButtons.tsx
@@ -8,25 +8,26 @@ interface ChatSendButtonProps {
export const ChatSendButton: React.FC = ({ onPress }) => {
return (
-
+
)
}
const styles = StyleSheet.create({
sendButton: {
- height: Dimensions.get('window').height * 0.055,
- width: Dimensions.get('window').height * 0.055,
- borderRadius: 30,
- backgroundColor: 'blue',
+ height: Dimensions.get('window').width * 0.09,
+ width: Dimensions.get('window').width * 0.09,
+ borderRadius: 100,
+ backgroundColor: '#34D1BF',
justifyContent: 'center',
alignItems: 'center',
},
sendButtonImage:{
- height: Dimensions.get('window').height * 0.033,
- width: Dimensions.get('window').height * 0.033,
- marginLeft: Dimensions.get('window').width * 0.01,
+ height: "64%",
+ width: "64%",
+ marginLeft: "13%",
+ tintColor: 'white',
},
})
diff --git a/client/src/components/Common/CustomInputs.tsx b/client/src/components/Common/CustomInputs.tsx
index 525258263..71871be41 100644
--- a/client/src/components/Common/CustomInputs.tsx
+++ b/client/src/components/Common/CustomInputs.tsx
@@ -1,10 +1,12 @@
import React from 'react'
import { TextInput, View, StyleSheet, Dimensions, Platform } from 'react-native'
+import { ChatSendButton } from './CustomButtons'
interface ChatInputProps {
value?: string,
onChangeText?: (text: string) => void
invalid?: boolean,
+ onSend?: () => void,
}
export const WelcomeEmailInput: React.FC = ({ value, onChangeText }) => {
@@ -80,17 +82,23 @@ export const SignUpConfirmPasswordInput: React.FC = ({ value, on
)
}
-export const ChatInput: React.FC = ({ value, onChangeText }) => {
+export const ChatInput: React.FC = ({ value, onChangeText, onSend }) => {
return (
-
+
+
+
+
+
+
)
};
@@ -115,7 +123,24 @@ const styles = StyleSheet.create({
paddingLeft: 15,
paddingRight: 15,
},
-
+ messsageContainer: {
+ width: Dimensions.get('window').width * 0.75,
+ borderWidth: 1,
+ borderRadius: 30,
+ paddingTop: Dimensions.get('window').height * 0.006,
+ paddingBottom: Dimensions.get('window').height * 0.006,
+ paddingLeft: 15,
+ paddingRight: Dimensions.get('window').height * 0.006,
+ flexDirection: 'row',
+ flex: 1,
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ borderColor: "#8E8E8E"
+ },
+ messageInput: {
+ width: Dimensions.get('window').height * 0.35,
+ fontSize: 16,
+ },
invalidLoginInput: {
borderColor: 'red',
},
diff --git a/client/src/contexts/SocketContext.tsx b/client/src/contexts/SocketContext.tsx
index a51fdf4ad..7dfa1ea23 100644
--- a/client/src/contexts/SocketContext.tsx
+++ b/client/src/contexts/SocketContext.tsx
@@ -31,6 +31,10 @@ export const SocketProvider = ({ children }: { children: React.ReactNode }) => {
}
});
+<<<<<<< HEAD
+=======
+ socketIo.connect()
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
setSocket(socketIo);
setMounted(true);
}
diff --git a/server/config_example.md b/server/config_example.md
index 184fd8709..8ffb34245 100644
--- a/server/config_example.md
+++ b/server/config_example.md
@@ -1,13 +1,10 @@
# dotenv config file (copy config to a new file named `.env`)
# **Do not delete this file**
-# Firebase config
-API_KEY = place_your_apiKey_here
-AUTH_DOMAIN = place_your_authDomain_here
-PROJECT_ID = place_your_projectId_here
-STORAGE_BUCKET = place_your_storageBucket_here
-MESSAGING_SENDER_ID = place_your_messagingSenderId_here
-APP_ID = place_your_appId_here
+# To configure firebase:
+# - Go to project settings > service accounts,
+# - Make a new private key for the Node.js SDK
+# - Paste all contents into ".firebase-secrets.json" in server/
# Location
message_outreach_radius = 100 # meters
diff --git a/server/src/actions/createConnectedUser.ts b/server/src/actions/createConnectedUser.ts
index d06cf6854..f47fc38bf 100644
--- a/server/src/actions/createConnectedUser.ts
+++ b/server/src/actions/createConnectedUser.ts
@@ -1,6 +1,10 @@
// Uploads a new document in the ConnectedUsers collection.
import { ConnectedUser } from '../types/User'
+<<<<<<< HEAD
import { connectedUsersCollection } from '../utilities/adminInit';
+=======
+import { connectedUsersCollection } from '../utilities/firebaseInit';
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
export const createUser = async (connectedUser: ConnectedUser) => {
try {
diff --git a/server/src/actions/createMessage.ts b/server/src/actions/createMessage.ts
index 8494db672..f9ea0726b 100644
--- a/server/src/actions/createMessage.ts
+++ b/server/src/actions/createMessage.ts
@@ -1,6 +1,10 @@
// Uploads a new document in the Messages collection.
import { Message } from '../types/Message'
+<<<<<<< HEAD
import { messagesCollection } from '../utilities/adminInit'
+=======
+import { messagesCollection } from '../utilities/firebaseInit'
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
export const createMessage = async (msg : Message) => {
try {
diff --git a/server/src/actions/deleteConnectedUser.ts b/server/src/actions/deleteConnectedUser.ts
index a6a968780..a4398a529 100644
--- a/server/src/actions/deleteConnectedUser.ts
+++ b/server/src/actions/deleteConnectedUser.ts
@@ -1,5 +1,9 @@
// Delete a ConnectedUser document given a document's index. This should typically be a socketId, but it can also be something else.
+<<<<<<< HEAD
import { connectedUsersCollection } from '../utilities/adminInit'
+=======
+import { connectedUsersCollection } from '../utilities/firebaseInit'
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
export const deleteConnectedUserByUID = async (socketID: string) => {
try {
diff --git a/server/src/actions/getConnectedUsers.ts b/server/src/actions/getConnectedUsers.ts
index c2567abd0..06856e493 100644
--- a/server/src/actions/getConnectedUsers.ts
+++ b/server/src/actions/getConnectedUsers.ts
@@ -1,5 +1,9 @@
import { distanceBetween, geohashForLocation, geohashQueryBounds } from 'geofire-common'
+<<<<<<< HEAD
import { connectedUsersCollection } from '../utilities/adminInit'
+=======
+import { connectedUsersCollection } from '../utilities/firebaseInit'
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
export const findNearbyUsers = async (centerLat: number, centerLon: number, radius: number) => {
// Return an array of nearby userIds (which are also socket ids) given a center latitude and longitude.
diff --git a/server/src/actions/updateConnectedUser.ts b/server/src/actions/updateConnectedUser.ts
index c935ae7c6..47da535a8 100644
--- a/server/src/actions/updateConnectedUser.ts
+++ b/server/src/actions/updateConnectedUser.ts
@@ -1,5 +1,9 @@
import { geohashForLocation} from 'geofire-common'
+<<<<<<< HEAD
import { connectedUsersCollection } from '../utilities/adminInit'
+=======
+import { connectedUsersCollection } from '../utilities/firebaseInit'
+>>>>>>> a15bd2c79af0ae980877f70f54f541fc55ae7ff0
export const toggleUserConnectionStatus = async (socketID: string) => {
try {
diff --git a/server/src/types/Message.ts b/server/src/types/Message.ts
index 64af59b4c..41b6e0966 100644
--- a/server/src/types/Message.ts
+++ b/server/src/types/Message.ts
@@ -8,4 +8,5 @@ export interface Message {
lon: number
geohash?: string
}
+ visibleToUids?: Array
}
diff --git a/server/src/utilities/firebaseInit.ts b/server/src/utilities/firebaseInit.ts
new file mode 100644
index 000000000..beeb3f717
--- /dev/null
+++ b/server/src/utilities/firebaseInit.ts
@@ -0,0 +1,15 @@
+const admin = require('firebase-admin');
+const serviceAccount = require("../../.firebase-secrets.json");
+
+export const adminApp = admin.initializeApp({
+ credential: admin.credential.cert(serviceAccount),
+});
+
+export const db = admin.firestore();
+export const connectedUsersCollection = db.collection('ConnectedUsers');
+export const messagesCollection = db.collection('Messages');
+
+console.log("[FIREBASE] Firestore synced.")
+
+// TODO: refactor file name to 'firebase' for accuracy.
+// TODO: move key info to .env