Skip to content

Commit

Permalink
Merge branch 'main' into store-types-seperately
Browse files Browse the repository at this point in the history
  • Loading branch information
aaditkamat authored Mar 1, 2024
2 parents cfd1584 + c747b8b commit a1d189f
Show file tree
Hide file tree
Showing 25 changed files with 1,639 additions and 792 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ jobs:
run: npm ci
working-directory: server/

- name: Set up environment variables
- name: Create subdirectory for service account JSON
run: |
mkdir private_key
echo "${{ secrets.SERVICE_ACCOUNT_SECRET }}" > private_key/private.json
working-directory: server/src

- name: Create service account JSON
id: create-service-account-json
uses: jsdaniell/[email protected]
with:
name: "private.json"
json: ${{ secrets.SERVICE_ACCOUNT_SECRET }}
dir: 'server/src/private_key/'

- name: Compile TypeScript files
run: npx tsc
working-directory: server/
Expand Down
Binary file added client/assets/transparentSend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -30,13 +31,14 @@
"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",
"expo-network": "~5.4.0"
"react-native-svg": "13.9.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
70 changes: 38 additions & 32 deletions client/src/components/Auth/AuthenticationResponse.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React from "react";
import { StyleSheet, Text, Dimensions, TouchableOpacity} from "react-native";
import { StyleSheet, Text, Dimensions, TouchableOpacity } from "react-native";
import { FirebaseError } from "firebase/app";
import { User } from "firebase/auth";

//Type to handle Authentication Responses from firebase
export type AuthenticationResponse = {
user: User | null;
error?: undefined;
} | {
user?: undefined;
error: unknown;
}
export type AuthenticationResponse =
| {
user: User | null;
error?: undefined;
}
| {
user?: undefined;
error: unknown;
};

export class CustomError {
public code: string;
Expand All @@ -23,7 +25,10 @@ export class CustomError {
}

//Custom responses
export const inValidEmailResponse = new CustomError("Invalid Email", "Please provide a valid email address")
export const inValidEmailResponse = new CustomError(
"Invalid Email",
"Please provide a valid email address"
);

//Function that decodes the error code
const decodeFirebaseError = (error: FirebaseError) => {
Expand All @@ -47,54 +52,56 @@ const decodeFirebaseError = (error: FirebaseError) => {

const decodeCustomError = (error: CustomError) => {
return error.message;
}
};

//Function that handles the response depending on type
function handleResponse(response: AuthenticationResponse) {
if(response?.user) {
const handleResponse = (response: AuthenticationResponse) => {
if (response?.user) {
// If the user is not undefined
return "";
}

console.log(response.error)

if(response.error instanceof FirebaseError) {
if (response.error instanceof FirebaseError) {
// If the error is a firebase error
return decodeFirebaseError(response.error);
}

if(response.error instanceof CustomError) {
// If the error is a custom error
if (response.error instanceof CustomError) {
// If the error is a custom error
return decodeCustomError(response.error);
}

return "Unknown error"
}
return "Unknown error";
};

//Something
// Authentication Message Component Props
interface AuthenticationErrorMessageProps {
response: AuthenticationResponse | undefined;
onPress?: () => void;
}

export const AuthenticationErrorMessage: React.FC<AuthenticationErrorMessageProps> = ({ response, onPress }) => {
if( response === undefined ) {
export const AuthenticationErrorMessage: React.FC<
AuthenticationErrorMessageProps
> = ({ response, onPress }) => {
if (response === undefined) {
return null;
}

const errorMessage = handleResponse(response)
const errorMessage = handleResponse(response);

return (
errorMessage &&
<TouchableOpacity style={styles.error_container} onPressIn={onPress}>
errorMessage && (
<TouchableOpacity style={styles.error_container} onPressIn={onPress}>
<Text style={styles.error_text}>{errorMessage}</Text>
</TouchableOpacity>
</TouchableOpacity>
)
);
}

};

const styles = StyleSheet.create({
error_text: {
color: "white",
fontSize: Dimensions.get("window").height * 0.02,

},
error_container: {
display: "flex",
Expand All @@ -105,7 +112,6 @@ const styles = StyleSheet.create({
marginTop: Dimensions.get("window").height * 0.005,
width: Dimensions.get("window").width * 0.9,
borderRadius: 10,
padding: 10
}
padding: 10,
},
});

15 changes: 12 additions & 3 deletions client/src/components/Auth/LoginScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@ const LoginScreen = () => {
const [email, setEmail] = React.useState<string>("");
const [password, setPassword] = React.useState<string>("");
const [authResponse, setAuthResponse] = React.useState<AuthenticationResponse>();
const [invalidLogin, invalidateLogin] = React.useState<boolean>(false);
const [invalidLogin, invalidateLogin] = React.useState<boolean>(false); // Possbily change this?

// Sign in function with email and password
const onHandleSubmit = async () => {
Keyboard.dismiss();
setAuthResponse(await appSignIn(email, password));
};

// Listens for the response from the sign in function
useEffect(() => {
if (authResponse?.user) {
router.replace("(home)/chatchannel");
} else if (authResponse?.error) {
console.log(authResponse.error);
invalidateLogin(true);
}
};
}, [authResponse])

useEffect(() => {
setEmail(inputEmail?.toString() || ""); // On load of the page, set the email to the inputEmail if they entered it!
Expand Down Expand Up @@ -76,7 +82,10 @@ const LoginScreen = () => {
</KeyboardAvoidingView>

<View style={styles.error_container}>
<AuthenticationErrorMessage response={authResponse} onPress={() => setAuthResponse(undefined)} />
<AuthenticationErrorMessage response={authResponse} onPress={() => {
setAuthResponse(undefined)
invalidateLogin(false)
}} />
</View>

</View>
Expand Down
16 changes: 9 additions & 7 deletions client/src/components/Chat/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -108,13 +109,13 @@ const ChatScreen = () => {
<MessageChannel messages={messages} />
</View>
<View style={styles.footerContainer}>
<ChatInput
<ChatScreenFooter
value={messageContent}
onChangeText={(text: string) => {
setMessageContent(text);
}}
onSend={onHandleSubmit}
/>
<ChatSendButton onPress={onHandleSubmit} />
</View>
</View>
</KeyboardAvoidingView>
Expand Down Expand Up @@ -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",
},
});

Expand Down
88 changes: 88 additions & 0 deletions client/src/components/Common/ChatScreenFooter.tsx
Original file line number Diff line number Diff line change
@@ -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<ChatInputProps> = ({ value, onChangeText, onSend }) => {



return (
<View style={styles.container}>
<View style={styles.iconContainer}>
<TouchableOpacity>
<Image color={"black"} strokeWidth={1.8} style={styles.icons}/>
</TouchableOpacity>
<TouchableOpacity>
<Smile color={"black"} strokeWidth={1.8} style={styles.icons}/>
</TouchableOpacity>
</View>
<TextInput
placeholder='Say Something...'
multiline={true}
value={value}
onChangeText={onChangeText}
maxLength={500}
style={styles.messageInput}/>
<View style={styles.sendButtonContainer}>
<ChatSendButton onPress={(onSend)} />
</View>
</View>
)
};

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,
}

});
17 changes: 9 additions & 8 deletions client/src/components/Common/CustomButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@ import { ChatSendButtonProps } from '../../types/Props';
export const ChatSendButton: React.FC<ChatSendButtonProps> = ({ onPress }) => {
return (
<TouchableOpacity style={styles.sendButton} onPress={onPress}>
<Image style={styles.sendButtonImage} source={require('../../../assets/send.png')}/>
<Image style={styles.sendButtonImage} source={require('../../../assets/transparentSend.png')}/>
</TouchableOpacity>
)
}

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',
},
})

Loading

0 comments on commit a1d189f

Please sign in to comment.