├── .env
├── .gitignore
├── .idea
├── chatbot-frontend.iml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── App.js
├── adapters
├── chats
│ └── chats.js
├── language
│ └── language.js
└── tabs
│ └── tabs.js
├── app.json
├── assets
├── adaptive-icon.png
├── avatar.png
├── banner.jpg
├── favicon.png
├── icon.png
├── icons
│ ├── BackArrow.jsx
│ ├── CameraIcon.jsx
│ ├── CommunityIcon.jsx
│ ├── Loader.jsx
│ ├── MenuIcon.jsx
│ └── SearchIcon.jsx
└── splash.png
├── babel.config.js
├── components
├── ChatBox.jsx
├── ChatMessages.jsx
├── GetcontactAccess.jsx
├── LanguageItem.jsx
├── Navbar.jsx
├── Paths.jsx
├── TabLists.jsx
└── Waiting.jsx
├── ipconfig.js
├── main.js
├── package.json
├── redux
├── authentication
│ ├── auth.action.js
│ ├── auth.types.js
│ └── reducer.js
├── redux.js
├── room
│ ├── reducer.js
│ ├── room.action.js
│ └── room.types.js
└── user
│ ├── reducer.js
│ ├── user.action.js
│ └── user.types.js
├── view
├── AgreeAndContinue.jsx
├── Authentication.jsx
├── CallScreen.jsx
├── ChatPanel.jsx
├── ChatScreen.jsx
├── OtpAndFormFilling.jsx
├── StatusScreen.jsx
└── Welcome.jsx
└── yarn.lock
/.env:
--------------------------------------------------------------------------------
1 | API_BASE_URL_DEV = "http://192.168.68.110:3000"
2 | API_BASE_URL_PROD = "https://whatsapp-clone-hvpn.onrender.com/"
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | dist/
4 | npm-debug.*
5 | *.jks
6 | *.p8
7 | *.p12
8 | *.key
9 | *.mobileprovision
10 | *.orig.*
11 | web-build/
12 | yarn.lock
13 | package-lock.json
14 |
15 | # macOS
16 | .DS_Store
17 |
18 | # Temporary files created by Metro to check the health of the file watcher
19 | .metro-health-check*
20 |
--------------------------------------------------------------------------------
/.idea/chatbot-frontend.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
36 |
37 |
38 |
39 |
40 | 1679682263495
41 |
42 |
43 | 1679682263495
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import { Provider } from "react-redux";
2 | import Main from "./main";
3 | import store from "./redux/redux";
4 |
5 | export default function App() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/adapters/chats/chats.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | id: 1,
4 | chatfrom: 1,
5 | chatto: 2,
6 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
7 | lastMessage: "this is the last",
8 | avatar: "",
9 | title: "fake user",
10 | ispin: false,
11 | lastSeen: "4:53pm",
12 | },
13 | {
14 | id: 2,
15 | chatfrom: 1,
16 | chatto: 2,
17 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
18 | lastMessage: "this is the last",
19 | avatar: "",
20 | title: "fake user",
21 | ispin: false,
22 | lastSeen: "4:53pm",
23 | },
24 | {
25 | id: 3,
26 | chatfrom: 1,
27 | chatto: 2,
28 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
29 | lastMessage: "this is the last",
30 | avatar: "",
31 | title: "fake user",
32 | ispin: false,
33 | lastSeen: "4:53pm",
34 | },
35 | {
36 | id: 4,
37 | chatfrom: 1,
38 | chatto: 2,
39 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
40 | lastMessage: "this is the last",
41 | avatar: "",
42 | title: "fake user",
43 | ispin: false,
44 | lastSeen: "4:53pm",
45 | },
46 | {
47 | id: 5,
48 | chatfrom: 1,
49 | chatto: 2,
50 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
51 | lastMessage: "this is the last",
52 | avatar: "",
53 | title: "fake user",
54 | ispin: false,
55 | lastSeen: "4:53pm",
56 | },
57 | {
58 | id: 6,
59 | chatfrom: 1,
60 | chatto: 2,
61 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
62 | lastMessage: "this is the last",
63 | avatar: "",
64 | title: "fake user",
65 | ispin: false,
66 | lastSeen: "4:53pm",
67 | },
68 | {
69 | id: 7,
70 | chatfrom: 1,
71 | chatto: 2,
72 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
73 | lastMessage: "this is the last",
74 | avatar: "",
75 | title: "fake user",
76 | ispin: false,
77 | lastSeen: "4:53pm",
78 | },
79 | {
80 | id: 8,
81 | chatfrom: 1,
82 | chatto: 2,
83 | data: [{ key: "value" }, { key: "value" }, { key: "value" }],
84 | lastMessage: "this is the last",
85 | avatar: "",
86 | title: "fake user",
87 | ispin: false,
88 | lastSeen: "4:53pm",
89 | },
90 | ];
91 |
--------------------------------------------------------------------------------
/adapters/language/language.js:
--------------------------------------------------------------------------------
1 | export default [
2 | { primaryLanguage: "English", secondaryLanguage: "English" },
3 | { primaryLanguage: "हिन्दी", secondaryLanguage: "Hindi" },
4 | { primaryLanguage: "বাংলা", secondaryLanguage: "Bengali" },
5 | { primaryLanguage: "मराठी", secondaryLanguage: "Marathi" },
6 | { primaryLanguage: "తెలుగు", secondaryLanguage: "Telugu" },
7 | { primaryLanguage: "தமிழ்", secondaryLanguage: "Tamil" },
8 | { primaryLanguage: "ગુજરાતી", secondaryLanguage: "Gujarati" },
9 | { primaryLanguage: "ಕನ್ನಡ", secondaryLanguage: "Kannada" },
10 | { primaryLanguage: "ଓଡ଼ିଆ", secondaryLanguage: "Odia" },
11 | { primaryLanguage: "ਪੰਜਾਬੀ", secondaryLanguage: "Punjabi" },
12 | { primaryLanguage: "മലയാളം", secondaryLanguage: "Malayalam" },
13 | { primaryLanguage: "اردو", secondaryLanguage: "Urdu" },
14 | { primaryLanguage: "संस्कृतम्", secondaryLanguage: "Sanskrit" },
15 | { primaryLanguage: "नेपाली", secondaryLanguage: "Nepali" },
16 | { primaryLanguage: "सिन्धी", secondaryLanguage: "Sindhi" },
17 | { primaryLanguage: "କାଶ୍ମିରୀ", secondaryLanguage: "Kashmiri" },
18 | { primaryLanguage: "मैथिली", secondaryLanguage: "Maithili" },
19 | { primaryLanguage: "संताली", secondaryLanguage: "Santali" },
20 | { primaryLanguage: "गोंडी", secondaryLanguage: "Gondi" },
21 | { primaryLanguage: "મરાઠી", secondaryLanguage: "Marathi" },
22 | { primaryLanguage: "कोंकणी", secondaryLanguage: "Konkani" },
23 | { primaryLanguage: "कर्नाटका", secondaryLanguage: "Karnataka" },
24 | { primaryLanguage: "तुलु", secondaryLanguage: "Tulu" },
25 | { primaryLanguage: "मणिपुरी", secondaryLanguage: "Manipuri" },
26 | { primaryLanguage: "खड़ी बोली", secondaryLanguage: "Khasi" },
27 | { primaryLanguage: "मिजो", secondaryLanguage: "Mizo" },
28 | { primaryLanguage: "नागा", secondaryLanguage: "Naga" },
29 | ];
30 |
--------------------------------------------------------------------------------
/adapters/tabs/tabs.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | id: 1,
4 | areaName: "Chats",
5 | isDot: false,
6 | notSeen: {
7 | is: false,
8 | count: 0,
9 | },
10 | chatRoute : "chatScreen"
11 | },
12 | {
13 | id: 2,
14 | areaName: "Status",
15 | isDot: false,
16 | notSeen: {
17 | is: false,
18 | count: 0,
19 | },
20 | chatRoute : "StatusScreen"
21 |
22 | },
23 | {
24 | id: 3,
25 | areaName: "Calls",
26 | isDot: false,
27 | notSeen: {
28 | is: false,
29 | count: 0,
30 | },
31 | chatRoute : "CallScreen"
32 |
33 | },
34 | ];
35 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "chatbot-frontend",
4 | "slug": "chatbot-frontend",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "light",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#ffffff"
13 | },
14 | "assetBundlePatterns": [
15 | "**/*"
16 | ],
17 | "ios": {
18 | "supportsTablet": true
19 | },
20 | "android": {
21 | "adaptiveIcon": {
22 | "foregroundImage": "./assets/adaptive-icon.png",
23 | "backgroundColor": "#ffffff"
24 | }
25 | },
26 | "web": {
27 | "favicon": "./assets/favicon.png"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/avatar.png
--------------------------------------------------------------------------------
/assets/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/banner.jpg
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/favicon.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/icon.png
--------------------------------------------------------------------------------
/assets/icons/BackArrow.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React from "react";
3 | import Icon from "react-native-vector-icons/AntDesign";
4 |
5 | const BackArrow = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default BackArrow;
14 |
--------------------------------------------------------------------------------
/assets/icons/CameraIcon.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import Icon from "react-native-vector-icons/SimpleLineIcons";
4 |
5 | const CameraIcon = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
13 | export default CameraIcon;
14 |
--------------------------------------------------------------------------------
/assets/icons/CommunityIcon.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, View } from "react-native";
3 | import Icon from "react-native-vector-icons/Ionicons";
4 |
5 | const CommunityIcon = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 | const styles = StyleSheet.create({
13 | icon: {
14 | width: "10%",
15 | display: "flex",
16 | justifyContent : "center",
17 | alignItems : "center",
18 | },
19 | });
20 |
21 | export default CommunityIcon;
22 |
--------------------------------------------------------------------------------
/assets/icons/Loader.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { ActivityIndicator, MD2Colors } from "react-native-paper";
3 |
4 | const Loader = () => (
5 |
6 | );
7 |
8 | export default Loader;
9 |
--------------------------------------------------------------------------------
/assets/icons/MenuIcon.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View } from "react-native";
3 | import Icon from "react-native-vector-icons/Entypo";
4 |
5 | const MenuIcon = ({ color }) => {
6 | return (
7 |
8 |
13 |
14 | );
15 | };
16 |
17 | export default MenuIcon;
18 |
--------------------------------------------------------------------------------
/assets/icons/SearchIcon.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View } from "react-native";
3 | import Icon from "react-native-vector-icons/Feather";
4 |
5 | const SearchIcon = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default SearchIcon;
14 |
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepumandal/chatbot-frontend/6eafabc0bb5e231aeecdf5179d6a01692a03c7e3/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/components/ChatBox.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native";
3 | import img from "../assets/avatar.png";
4 | import { useNavigation } from "@react-navigation/native";
5 | import { useDispatch } from "react-redux";
6 | import { activeRoom } from "../redux/room/room.action";
7 | const ChatBox = ({ title, lastMessage, isActive, user }) => {
8 | const navigate = useNavigation();
9 | const [press, setPress] = useState(false);
10 | const dispatch = useDispatch();
11 | const pressMyevent = () => {
12 | setPress((press) => !press);
13 | };
14 |
15 | return (
16 | {
20 | navigate.navigate("chatpanel", user);
21 | dispatch(activeRoom(user));
22 | }}
23 | style={[style.Container, press ? style.pressContainer : null]}
24 | >
25 |
26 |
27 |
28 |
29 | {title}
30 | {lastMessage}
31 |
32 | {
33 | isActive ? "online" : "offline"
34 | }
35 |
36 | );
37 | };
38 |
39 | const style = StyleSheet.create({
40 | lastSeen: {
41 | position: "absolute",
42 | top: 10,
43 | right: 13,
44 | fontSize: 12,
45 | fontWeight: 600,
46 | color: "#8696a0",
47 | },
48 | pressContainer: {
49 | backgroundColor: "#D6D5D4",
50 | },
51 | Container: {
52 | width: "100%",
53 | height: 80,
54 | paddingLeft: 6,
55 | paddingRight: 6,
56 | display: "flex",
57 | justifyContent: "flex-start",
58 | alignItems: "center",
59 | flexDirection: "row",
60 | paddingTop: 10,
61 | paddingBottom: 10,
62 | marginTop: 4,
63 | },
64 | avatarBox: {
65 | borderRadius: 50,
66 | overflow: "hidden",
67 | width: "16%",
68 | marginRight: 16,
69 | marginLeft: 12,
70 | },
71 | avatar: {
72 | width: 60,
73 | height: 60,
74 | },
75 | textContainer: {
76 | // borderWidth: 1,
77 | // borderColor: "black",
78 | width: "70%",
79 | height: 48,
80 | justifyContent: "space-between",
81 | },
82 | header: {
83 | fontSize: 18,
84 | fontWeight: 700,
85 | color: "#111b21",
86 | },
87 | lastmessage: {
88 | fontSize: 15,
89 | fontWeight: 400,
90 | color: "#3b4a54",
91 | },
92 | });
93 |
94 | export default ChatBox;
95 |
--------------------------------------------------------------------------------
/components/ChatMessages.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React, { useEffect } from "react";
3 | import { useDispatch, useSelector } from "react-redux";
4 | import { socket } from "../view/ChatScreen";
5 | import { getlateschat } from "../redux/room/room.action";
6 |
7 | const ChatMessages = () => {
8 | const socketObj = useSelector((store) => store.socket);
9 | const store = useSelector((store) => store.auth);
10 | const user = useSelector((store) => store.user);
11 | const dispatch = useDispatch();
12 | useEffect(() => {
13 | socket.on("getMessage", (msg) => alert(msg));
14 | let id = store.userData.body._id;
15 | let subject = socketObj.subjectSocket;
16 | socket.on("getMessage", (msg) => dispatch(getlateschat(id, subject)));
17 | }, []);
18 |
19 | // useEffect(() => {
20 | // // trigger last message here
21 | // socket.on("getMessage", (msg) => dispatch(getlateschat(id, subject)));
22 | // }, []);
23 |
24 | return (
25 |
26 | {socketObj.currentChat?.data?.map((item, index) => {
27 | return (
28 |
37 | {item.value}
38 |
39 | );
40 | })}
41 |
42 | );
43 | };
44 |
45 | export default ChatMessages;
46 |
--------------------------------------------------------------------------------
/components/GetcontactAccess.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TouchableOpacity,
5 | Alert,
6 | PermissionsAndroid,
7 | } from "react-native";
8 | import React, { useEffect } from "react";
9 |
10 | const GetcontactAccess = ({ ContactAccess, setContactAccess }) => {
11 | const onPressEvent = async () => {
12 | try {
13 | const granted = await PermissionsAndroid.request(
14 | PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
15 | // PermissionsAndroid.PERMISSIONS.READ_MEDIA_IMAGES,
16 | {
17 | title: "Contacts Permission",
18 | message:
19 | "This app needs access to your contacts to be able to function properly.",
20 | buttonNeutral: "Ask Me Later",
21 | buttonNegative: "Cancel",
22 | buttonPositive: "OK",
23 | }
24 | );
25 |
26 | if (granted === PermissionsAndroid.RESULTS.GRANTED) {
27 | console.log("Contacts permission granted");
28 | setContactAccess(() => !ContactAccess);
29 | } else {
30 | console.log("Contacts permission denied");
31 | }
32 | } catch (err) {
33 | console.warn(err);
34 | }
35 | };
36 |
37 | return (
38 |
49 |
58 |
66 | {" "}
67 | Contacts and media{" "}
68 |
69 |
70 |
78 | To easily sene messages and photos to friends and family, allow
79 | chatify to access your contact, photos and other media.
80 |
81 |
82 |
95 |
96 |
102 | {" "}
103 | Not now
104 |
105 |
106 |
107 |
113 | Continue
114 |
115 |
116 |
117 |
118 |
119 | );
120 | };
121 |
122 | export default GetcontactAccess;
123 |
--------------------------------------------------------------------------------
/components/LanguageItem.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
2 | import React from "react";
3 | import { RadioButton } from "react-native-paper";
4 |
5 | const LanguageItem = ({ setLanguage, primaryLanguage, secondaryLanguage }) => {
6 | return (
7 |
8 |
9 | setLanguage(primaryLanguage)}
12 | style={style.textcontainer}
13 | >
14 | {primaryLanguage}
15 | {secondaryLanguage}
16 |
17 |
18 | );
19 | };
20 |
21 | const style = StyleSheet.create({
22 | itemBox: {
23 | width: "100%",
24 | height: 70,
25 | marginTop: 6,
26 | paddingLeft: 14,
27 | paddingRight: 14,
28 | display: "flex",
29 | flexDirection: "row",
30 | alignItems: "center",
31 | },
32 | textcontainer: {
33 | marginLeft: 18,
34 | width: "100%",
35 | height: "100%",
36 | paddingTop: 15,
37 | },
38 | primary: {
39 | fontSize: 16,
40 | fontWeight: 500,
41 | color: "#111b21",
42 | },
43 | secondary: {
44 | fontSize: 16,
45 | fontWeight: 300,
46 | color: "#3b4a54",
47 | },
48 | });
49 |
50 | export default LanguageItem;
51 |
--------------------------------------------------------------------------------
/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React, { Children } from "react";
2 | import { StyleSheet, Text, View } from "react-native";
3 | import CameraIcon from "../assets/icons/CameraIcon";
4 | import SearchIcon from "../assets/icons/SearchIcon";
5 | import MenuIcon from "../assets/icons/MenuIcon";
6 | import TabLists from "./TabLists";
7 | import Paths from "./Paths";
8 |
9 | const Navbar = ({ children }) => {
10 | return (
11 |
12 |
13 |
14 | WhatsApp
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | };
25 |
26 | const styles = StyleSheet.create({
27 | Headers: {
28 | width: "100%",
29 | height: "14%",
30 | paddingTop: 53,
31 | backgroundColor: "#00a884",
32 | justifyContent: "space-between",
33 | },
34 | NavSection: {
35 | height: 90,
36 | justifyContent: "space-between",
37 | },
38 | navbar: {
39 | width: "100%",
40 | display: "flex",
41 | flexDirection: "row",
42 | paddingLeft: 17,
43 | paddingRight: 17,
44 | justifyContent: "space-between",
45 | },
46 | heading: {
47 | color: "white",
48 | fontFamily: "Roboto",
49 | fontSize: 24,
50 | fontWeight: 700,
51 | },
52 | features: {
53 | display: "flex",
54 | flexDirection: "row",
55 | justifyContent: "space-between",
56 | alignItems: "center",
57 | gap: 25,
58 | },
59 | });
60 |
61 | export default Navbar;
62 |
--------------------------------------------------------------------------------
/components/Paths.jsx:
--------------------------------------------------------------------------------
1 | // import React from "react";
2 | // // import { NativeRouter, Route, Routes } from "react-router-native";
3 | // import ChatLists from "../view/ChatLists";
4 | // import StatusComp from "../view/StatusComp";
5 |
6 | // const Paths = () => {
7 | // return (
8 | // //
9 | // //
10 | // //
11 | // //
12 | // //
13 | // //
14 | // );
15 | // };
16 |
17 | // export default Paths;
18 |
--------------------------------------------------------------------------------
/components/TabLists.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
3 | import tabs from "../adapters/tabs/tabs.js";
4 | import CommunityIcon from "../assets/icons/CommunityIcon.jsx";
5 | import { useSelector } from "react-redux";
6 | import { useNavigation } from "@react-navigation/native";
7 | const TabLists = () => {
8 | const store = useSelector((store) => store);
9 | const navigate = useNavigation();
10 | return (
11 |
12 |
13 | {tabs.map((item) => {
14 | return (
15 | navigate.navigate(item.chatRoute)}
17 | key={item.id}
18 | style={TabStyle.Tab}
19 | >
20 | {item.areaName}
21 |
22 | );
23 | })}
24 |
25 | );
26 | };
27 |
28 | const TabStyle = StyleSheet.create({
29 | TabContainer: {
30 | width: "100%",
31 | height: 35,
32 | display: "flex",
33 | flexDirection: "row",
34 | justifyContent: "space-between",
35 | backgroundColor: "#00a884",
36 | },
37 | Tab: {
38 | width: "27%",
39 | display: "flex",
40 | justifyContent: "center",
41 | alignItems: "center",
42 | paddingRight: 10,
43 | },
44 | areaName: {
45 | color: "white",
46 | fontWeight: 700,
47 | fontSize: 16,
48 | },
49 | });
50 |
51 | export default TabLists;
52 |
--------------------------------------------------------------------------------
/components/Waiting.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text, StyleSheet } from "react-native";
2 | import React from "react";
3 | import Loader from "../assets/icons/Loader";
4 |
5 | const Waiting = ({ name }) => {
6 | return (
7 |
8 |
9 |
16 |
17 |
18 | {name}
19 |
20 |
21 | );
22 | };
23 | const styles = StyleSheet.create({
24 | loadercontainer: {
25 | backgroundColor: "rgb(210, 210, 210)",
26 | position: "absolute",
27 | width: "100%",
28 | height: "100%",
29 | display: "flex",
30 | flexDirection: "row",
31 | justifyContent: "center",
32 | alignItems: "center",
33 | },
34 | loader: {
35 | width: "70%",
36 | backgroundColor: "white",
37 | textAlign: "center",
38 | display: "flex",
39 | flexDirection: "row",
40 | justifyContent: "space-between",
41 | },
42 | name: {
43 | fontSize: 15,
44 | fontWeight: 700,
45 | borderRadius: 10,
46 | width: "70%",
47 | paddingVertical: 20,
48 | },
49 | });
50 |
51 | export default Waiting;
52 |
--------------------------------------------------------------------------------
/ipconfig.js:
--------------------------------------------------------------------------------
1 | // import NetworkUtility from "react-native-network-utility";
2 | // export default getIp = async () => {
3 | // const ip = await NetworkUtility.getIPAddress();
4 | // return ip;
5 | // }
6 |
7 | // export default `http://192.168.1.22:3000`;
8 | // export default `http://192.168.68.118:3000`;
9 | export default `http://192.168.68.108:3000`;
10 | // 192.168.1.22
11 | // 192.168.1.22
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import { StatusBar } from "expo-status-bar";
2 | import { AppState, StyleSheet, Text, View } from "react-native";
3 | import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
4 | import { createNativeStackNavigator } from "@react-navigation/native-stack";
5 |
6 | import Navbar from "./components/Navbar";
7 | import TabLists from "./components/TabLists";
8 | import { NavigationContainer } from "@react-navigation/native";
9 | import ChatScreen, { socket } from "./view/ChatScreen";
10 | import StatusScreen from "./view/StatusScreen";
11 | import CallScreen from "./view/CallScreen";
12 | import Welcome from "./view/Welcome";
13 | import { useSelector } from "react-redux";
14 | import AgreeAndContinue from "./view/AgreeAndContinue";
15 | import Authentication from "./view/Authentication";
16 | import OtpAndFormFilling from "./view/OtpAndFormFilling";
17 | import ChatPanel from "./view/ChatPanel";
18 | import React, { useEffect } from "react";
19 | function ChatTabStack() {
20 | const Stack = createNativeStackNavigator();
21 |
22 | return (
23 | <>
24 |
31 |
32 |
33 |
34 | >
35 | );
36 | }
37 |
38 | const Main = () => {
39 | const Tab = createMaterialTopTabNavigator();
40 | const store = useSelector((store) => store.auth);
41 | const Stack = createNativeStackNavigator();
42 | const { isActive } = useSelector((store) => store.socket);
43 | const isAuthenticated = store?.userData?.isAuthenticated;
44 |
45 | useEffect(() => {
46 | return () => {
47 | console.log("second i am out");
48 | };
49 | }, []);
50 |
51 | return (
52 |
53 | {isAuthenticated && !isActive && }
54 |
55 | {isAuthenticated && !isActive && }
56 | {!isAuthenticated ? (
57 |
64 |
69 |
74 |
79 |
84 |
85 | ) : (
86 |
96 |
101 |
106 |
111 |
112 | )}
113 |
114 |
115 |
116 |
117 | );
118 | };
119 |
120 | const styles = StyleSheet.create({
121 | container: {
122 | flex: 2,
123 | },
124 | Headers: {
125 | width: "100%",
126 | height: "18%",
127 | paddingTop: 53,
128 | backgroundColor: "#00a884",
129 | justifyContent: "space-between",
130 | },
131 | navbar: {
132 | width: "100%",
133 | display: "flex",
134 | flexDirection: "row",
135 | paddingLeft: 17,
136 | paddingRight: 17,
137 | justifyContent: "space-between",
138 | },
139 | heading: {
140 | color: "white",
141 | fontFamily: "Roboto",
142 | fontSize: 24,
143 | fontWeight: 700,
144 | },
145 | features: {
146 | display: "flex",
147 | flexDirection: "row",
148 | justifyContent: "space-between",
149 | alignItems: "center",
150 | gap: 25,
151 | },
152 | });
153 | export default Main;
154 |
155 | // return (
156 | //
157 | //
158 | //
165 | //
170 | //
175 | //
180 | //
181 | //
182 | //
183 | // );
184 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chatbot-frontend",
3 | "version": "1.0.0",
4 | "main": "node_modules/expo/AppEntry.js",
5 | "scripts": {
6 | "start": "expo start",
7 | "android": "expo start --android",
8 | "ios": "expo start --ios",
9 | "web": "expo start --web"
10 | },
11 | "dependencies": {
12 | "@react-native-community/netinfo": "^9.3.7",
13 | "@react-navigation/material-top-tabs": "^6.6.2",
14 | "@react-navigation/native": "^6.1.6",
15 | "@react-navigation/native-stack": "^6.9.12",
16 | "axios": "^1.3.4",
17 | "cross-spawn": "^7.0.3",
18 | "dotenv": "^16.0.3",
19 | "expo": "~48.0.6",
20 | "expo-linear-gradient": "~12.1.2",
21 | "expo-status-bar": "~1.4.4",
22 | "react": "18.2.0",
23 | "react-native": "^0.71.4",
24 | "react-native-linear-gradient": "^2.6.2",
25 | "react-native-pager-view": "6.1.2",
26 | "react-native-paper": "^5.5.0",
27 | "react-native-safe-area-context": "4.5.0",
28 | "react-native-screens": "~3.20.0",
29 | "react-native-tab-view": "^3.5.1",
30 | "react-native-translation": "^1.1.0",
31 | "react-native-vector-icons": "^9.2.0",
32 | "react-redux": "^8.0.5",
33 | "redux": "^4.2.1",
34 | "redux-thunk": "^2.4.2",
35 | "socket.io-client": "^4.6.1"
36 | },
37 | "devDependencies": {
38 | "@babel/core": "^7.20.0",
39 | "remote-redux-devtools": "^0.5.16"
40 | },
41 | "private": true
42 | }
43 |
--------------------------------------------------------------------------------
/redux/authentication/auth.action.js:
--------------------------------------------------------------------------------
1 | import {
2 | LOGIN_ERROR,
3 | LOGIN_LOADING,
4 | LOGIN_SUCCESS,
5 | OTP_ERROR,
6 | OTP_LOADING,
7 | OTP_SUCCESS,
8 | } from "./auth.types";
9 | import axios from "axios";
10 |
11 | import url from "../../ipconfig.js";
12 | import { io } from "socket.io-client";
13 | import { socket } from "../../view/ChatScreen";
14 |
15 | // process.env.NODE_ENV == "production"
16 | // ? process.env.API_BASE_URL_PROD
17 | // : process.env.API_BASE_URL_DEV;
18 |
19 | export const GetOtp = (number) => (dispatch) => {
20 | dispatch({ type: OTP_LOADING });
21 | setTimeout(() => {
22 | dispatch({ type: OTP_SUCCESS, payload: number });
23 | // dispatch({ type: OTP_ERROR });
24 | }, 1000);
25 | };
26 |
27 | export const CreateNewAccount = (body) => (dispatch) => {
28 | dispatch({ type: LOGIN_LOADING });
29 | axios
30 | .post(`${url}/authentication/newuser`, body)
31 | .then((response) => {
32 | let body = response.data;
33 |
34 | dispatch({ type: LOGIN_SUCCESS, payload: body });
35 |
36 | getConnection();
37 |
38 | console.log(body);
39 | })
40 | .catch((error) => {
41 | dispatch({ type: LOGIN_ERROR, payload: error.message });
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/redux/authentication/auth.types.js:
--------------------------------------------------------------------------------
1 | export const LOGIN_LOADING = "LOGIN_LOADING";
2 | export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
3 | export const LOGIN_ERROR = "LOGIN_ERROR";
4 | export const LOGOUT = "LOGOUT";
5 |
6 | export const OTP_LOADING = "OTP_LOADING";
7 | export const OTP_SUCCESS = "OTP_SUCCESS";
8 | export const OTP_ERROR = "OTP_ERROR";
9 |
--------------------------------------------------------------------------------
/redux/authentication/reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | LOGIN_ERROR,
3 | LOGIN_LOADING,
4 | LOGIN_SUCCESS,
5 | OTP_ERROR,
6 | OTP_LOADING,
7 | OTP_SUCCESS,
8 | } from "./auth.types";
9 |
10 | const initialState = {
11 | loginLoading: false,
12 | loginError: false,
13 | errorMessage: "nil",
14 | userData: {
15 | isAuthenticated: false,
16 | number: "",
17 | body: {}
18 | },
19 | otpLoading: false,
20 | otpError: false,
21 | otpMessage: "nil",
22 | };
23 |
24 | const myReducer = (state = initialState, action) => {
25 | switch (action.type) {
26 | // otp here
27 | case OTP_LOADING: {
28 | return {
29 | ...state,
30 | otpLoading: true,
31 | otpError: false,
32 | };
33 | }
34 | case OTP_SUCCESS: {
35 | alert("Otp");
36 | console.log("Otp", action.payload);
37 | return {
38 | ...state,
39 | otpLoading: false,
40 | otpMessage: "validation successfully",
41 | userData: {
42 | ...state.userData,
43 | number: action.payload,
44 | },
45 | };
46 | }
47 | case OTP_ERROR: {
48 | return {
49 | ...state,
50 | otpError: true,
51 | otpLoading: false,
52 | otpMessage: "wrong otp entered",
53 | };
54 | }
55 | case LOGIN_LOADING: {
56 | return {
57 | ...state,
58 | loginLoading: true,
59 | loginError: false,
60 | };
61 | }
62 | case LOGIN_SUCCESS: {
63 | return {
64 | ...state,
65 | loginLoading: false,
66 | errorMessage: "validation successfully",
67 | userData: {
68 | ...state.userData,
69 | body: action.payload,
70 | isAuthenticated: true,
71 | },
72 | };
73 | }
74 | case LOGIN_ERROR: {
75 | return {
76 | ...state,
77 | loginError: true,
78 | loginLoading: false,
79 | errorMessage: "wrong otp entered",
80 | };
81 | }
82 | default:
83 | return state;
84 | }
85 | };
86 |
87 | export default myReducer;
88 |
--------------------------------------------------------------------------------
/redux/redux.js:
--------------------------------------------------------------------------------
1 | import { legacy_createStore, applyMiddleware, combineReducers } from "redux";
2 | import authReducer from "./authentication/reducer";
3 | import UserReducer from "./user/reducer.js";
4 | // import { composeWithDevTools } from "remote-redux-devtools";
5 | import thunkMiddleware from "redux-thunk";
6 | import socketReducer from "./room/reducer";
7 |
8 | const rootReducer = combineReducers({
9 | auth: authReducer,
10 | user: UserReducer,
11 | socket: socketReducer,
12 | });
13 |
14 | const store = legacy_createStore(rootReducer, applyMiddleware(thunkMiddleware));
15 |
16 | export default store;
17 |
--------------------------------------------------------------------------------
/redux/room/reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | CLOSE_ROOM,
3 | GET_CHAT,
4 | ROOM_ACTIVE,
5 | ROOM_ERROR,
6 | ROOM_LOADING,
7 | ROOM_SUCCESS,
8 | } from "./room.types.js";
9 |
10 | const initialState = {
11 | Loading: false,
12 | Error: false,
13 | errorMessage: "nil",
14 | activeSocket: "",
15 | subjectSocket: "",
16 | isActive: false,
17 | currentChat: {},
18 | };
19 |
20 | const socketReducer = (state = initialState, action) => {
21 | switch (action.type) {
22 | case ROOM_LOADING: {
23 | return {
24 | ...state,
25 | Loading: true,
26 | Error: false,
27 | };
28 | }
29 | case ROOM_SUCCESS: {
30 | return {
31 | ...state,
32 | Loading: false,
33 | errorMessage: "validation successfully",
34 | activeSocket: action.payload,
35 | isActive: false,
36 | };
37 | }
38 | case ROOM_ERROR: {
39 | return {
40 | ...state,
41 | Error: true,
42 | Loading: false,
43 | errorMessage: "something went wrong",
44 | };
45 | }
46 | case ROOM_ACTIVE: {
47 | return {
48 | ...state,
49 | subjectSocket: action.payload,
50 | isActive: true,
51 | };
52 | }
53 | case CLOSE_ROOM: {
54 | return {
55 | ...state,
56 | subjectSocket: "",
57 | isActive: false,
58 | };
59 | }
60 | case GET_CHAT: {
61 | console.log(JSON.stringify(action.payload, null, 2));
62 | return {
63 | ...state,
64 | currentChat: action.payload[0],
65 | };
66 | }
67 | default:
68 | return state;
69 | }
70 | };
71 |
72 | export default socketReducer;
73 |
--------------------------------------------------------------------------------
/redux/room/room.action.js:
--------------------------------------------------------------------------------
1 | import {
2 | GET_CHAT,
3 | ROOM_ACTIVE,
4 | ROOM_ERROR,
5 | ROOM_LOADING,
6 | ROOM_SUCCESS,
7 | } from "./room.types.js";
8 | import axios from "axios";
9 |
10 | import url from "../../ipconfig.js";
11 |
12 | export const activeRoom = (user) => (dispatch) => {
13 | dispatch({ type: ROOM_ACTIVE, payload: user._id });
14 | };
15 | export const sendMessage = (userId) => (dispatch) => {
16 | dispatch({ type: ROOM_LOADING });
17 | // socket connection here
18 | };
19 |
20 | export const getlateschat = (id, subject) => (dispatch) => {
21 | // GET_CHAT
22 | axios
23 | .post(`${url}/user/getdata`, {
24 | id,
25 | subject,
26 | })
27 | .then((response) => {
28 | // console.log("GET_CHAT", JSON.stringify(response.data, null, 2));
29 | dispatch({ type: GET_CHAT, payload: response.data });
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/redux/room/room.types.js:
--------------------------------------------------------------------------------
1 | export const ROOM_LOADING = "ROOM_LOADING";
2 | export const ROOM_SUCCESS = "ROOM_SUCCESS";
3 | export const ROOM_ERROR = "ROOM_ERROR";
4 | export const ROOM_LOGOUT = "ROOM_LOGOUT";
5 | export const ROOM_ACTIVE = "ROOM_ACTIVE";
6 | export const CLOSE_ROOM = "CLOSE_ROOM";
7 | export const GET_CHAT = "GET_CHAT";
8 |
--------------------------------------------------------------------------------
/redux/user/reducer.js:
--------------------------------------------------------------------------------
1 | import { USER_ERROR, USER_LOADING, USER_SUCCESS } from "./user.types.js";
2 |
3 | const initialState = {
4 | Loading: false,
5 | Error: false,
6 | errorMessage: "nil",
7 | data: [],
8 | };
9 |
10 | const UserReducer = (state = initialState, action) => {
11 | switch (action.type) {
12 | case USER_LOADING: {
13 | return {
14 | ...state,
15 | Loading: true,
16 | Error: false,
17 | };
18 | }
19 | case USER_SUCCESS: {
20 | return {
21 | ...state,
22 | Loading: false,
23 | errorMessage: "validation successfully",
24 | data: action.payload,
25 | };
26 | }
27 | case USER_ERROR: {
28 | return {
29 | ...state,
30 | Error: true,
31 | Loading: false,
32 | errorMessage: "wrong otp entered",
33 | };
34 | }
35 | default:
36 | return state;
37 | }
38 | };
39 |
40 | export default UserReducer;
41 |
--------------------------------------------------------------------------------
/redux/user/user.action.js:
--------------------------------------------------------------------------------
1 | import { USER_ERROR, USER_LOADING, USER_SUCCESS } from "./user.types.js";
2 | import axios from "axios";
3 |
4 | import url from "../../ipconfig.js";
5 |
6 | export const GetAllUser = (user) => (dispatch) => {
7 | dispatch({ type: USER_LOADING });
8 | axios
9 | .get(`${url}/user`)
10 | .then((response) => {
11 | let body = response.data;
12 | let data = body?.filter((item) => item._id !== user._id);
13 | dispatch({ type: USER_SUCCESS, payload: data });
14 | // console.log(JSON.stringify(response.data, null, 2));
15 | })
16 | .catch((error) => {
17 | dispatch({ type: USER_ERROR, payload: error.message });
18 | });
19 | };
20 |
--------------------------------------------------------------------------------
/redux/user/user.types.js:
--------------------------------------------------------------------------------
1 | export const LOGIN_LOADING = "LOGIN_LOADING";
2 | export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
3 | export const LOGIN_ERROR = "LOGIN_ERROR";
4 | export const LOGOUT = "LOGOUT";
5 |
6 | export const USER_LOADING = "USER_LOADING";
7 | export const USER_SUCCESS = "USER_SUCCESS";
8 | export const USER_ERROR = "USER_ERROR";
9 |
10 | export const OTP_LOADING = "OTP_LOADING";
11 | export const OTP_SUCCESS = "OTP_SUCCESS";
12 | export const OTP_ERROR = "OTP_ERROR";
13 |
--------------------------------------------------------------------------------
/view/AgreeAndContinue.jsx:
--------------------------------------------------------------------------------
1 | import { useNavigation } from "@react-navigation/native";
2 | import React from "react";
3 | import {
4 | View,
5 | Text,
6 | StyleSheet,
7 | ImageBackground,
8 | TouchableOpacity,
9 | } from "react-native";
10 |
11 | const AgreeAndContinue = () => {
12 | const navigate = useNavigation();
13 | return (
14 |
15 |
16 |
25 |
26 | Welcome to Chatify
27 |
28 |
34 | Read our
35 |
36 | Privacy policy
37 |
38 | . Tap "Agree and continue"
39 |
40 |
47 | to accept the
48 |
49 |
54 | Terms of Service
55 |
56 |
57 |
58 |
59 | navigate.navigate("authentication")}
61 | // onPressIn={onclick}
62 | // onPressOut={onclick}
63 | activeOpacity={1}
64 | style={style.button}
65 | >
66 |
73 | Agree and Continue
74 |
75 |
76 |
77 | );
78 | };
79 |
80 | const style = StyleSheet.create({
81 | container: {
82 | width: "100%",
83 | height: "100%",
84 | display: "flex",
85 | flexDirection: "column",
86 | justifyContent: "flex-start",
87 | alignItems: "center",
88 | backgroundColor: "white",
89 | },
90 | imageContainer: {
91 | width: "100%",
92 | height: "55%",
93 | display: "flex",
94 | justifyContent: "flex-end",
95 | alignItems: "center",
96 | },
97 | heading: {
98 | fontSize: 25,
99 | lineHeight: 50,
100 | fontWeight: 600,
101 | color: "#111b21",
102 | // backgroundColor: "white",
103 | },
104 | instruction: {
105 | fontSize: 15,
106 | lineHeight: 20,
107 | fontWeight: 400,
108 | color: "#3b4a54",
109 | backgroundColor: "white",
110 | },
111 | button: {
112 | backgroundColor: "green",
113 | borderRadius: 50,
114 | width: "70%",
115 | paddingVertical: 10,
116 | alignItems: "center",
117 | justifyContent: "center",
118 | marginTop: 60,
119 | },
120 | text: {
121 | color: "white",
122 | fontSize: 14,
123 | fontWeight: "bold",
124 | },
125 | });
126 |
127 | export default AgreeAndContinue;
128 |
--------------------------------------------------------------------------------
/view/Authentication.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | StyleSheet,
5 | TextInput,
6 | TouchableOpacity,
7 | } from "react-native";
8 | import React, { useState } from "react";
9 | import { useDispatch, useSelector } from "react-redux";
10 | import { GetOtp } from "../redux/authentication/auth.action";
11 | import { useNavigation } from "@react-navigation/native";
12 | import Waiting from "../components/Waiting";
13 |
14 | let otp = 1234;
15 |
16 | const Authentication = () => {
17 | const [value, setValue] = useState("");
18 | const auth = useSelector((store) => store.auth);
19 | const dispatch = useDispatch();
20 | const navigate = useNavigation();
21 | const handleInputChange = (text) => {
22 | setValue(text.replace(/[^0-9]/g, ""));
23 | };
24 | const submitVaue = () => {
25 | if (value.length !== 10) return alert("Please enter 10 digit number");
26 | dispatch(GetOtp(value));
27 | setTimeout(() => {
28 | navigate.navigate("OtpVarification");
29 | }, 1000);
30 | };
31 | return (
32 |
33 | Enter your Phone number
34 | {auth.otpLoading && }
35 |
36 |
37 | India
38 |
39 |
40 |
45 | {" "}
46 | +{" "}
47 |
48 |
53 | {" "}
54 | 91{" "}
55 |
56 |
57 |
65 |
66 | submitVaue()}
68 | style={style.button}
69 | activeOpacity={1}
70 | >
71 | {/* */}
72 | Next
73 |
74 |
75 |
76 | );
77 | };
78 |
79 | const style = StyleSheet.create({
80 | container: {
81 | width: "100%",
82 | height: "100%",
83 | backgroundColor: "white",
84 | },
85 | Title: {
86 | width: "100%",
87 | paddingVertical: 15,
88 | marginTop: 50,
89 | textAlign: "center",
90 | fontSize: 16,
91 | fontWeight: 600,
92 | color: "green",
93 | },
94 |
95 | inputContainer: {
96 | paddingVertical: 17,
97 | display: "flex",
98 | flexDirection: "column",
99 | alignItems: "center",
100 | width: "100%",
101 | height: "85%",
102 | },
103 | contary: {
104 | paddingVertical: 10,
105 | width: "60%",
106 | textAlign: "center",
107 | fontSize: 17,
108 | fontWeight: 600,
109 | borderBottomWidth: 2,
110 | borderBottomColor: "green",
111 | },
112 | input: {
113 | width: "60%",
114 | paddingVertical: 10,
115 | display: "flex",
116 | flexDirection: "row",
117 | justifyContent: "space-between",
118 | },
119 | code: {
120 | width: "25%",
121 | paddingVertical: 10,
122 | borderBottomWidth: 2,
123 | borderBottomColor: "green",
124 | display: "flex",
125 | flexDirection: "row",
126 | justifyContent: "space-between",
127 | paddingRight: 10,
128 | },
129 | inputField: {
130 | borderBottomColor: "green",
131 | borderBottomWidth: 0.3,
132 | width: "70%",
133 | paddingLeft: 5,
134 | },
135 | button: {
136 | width: 90,
137 | margin: "auto",
138 | position: "absolute",
139 | bottom: 38,
140 | borderRadius: 50,
141 | },
142 | text: {
143 | backgroundColor: "green",
144 | paddingVertical: 10,
145 | textAlign: "center",
146 | fontSize: 15,
147 | fontWeight: 700,
148 | color: "white",
149 | borderRadius: 50,
150 | },
151 | });
152 |
153 | export default Authentication;
154 |
--------------------------------------------------------------------------------
/view/CallScreen.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text, StyleSheet } from "react-native";
2 | import React from "react";
3 |
4 |
5 | const CallScreen = ({ navigation }) => {
6 | return (
7 |
8 | CallScreen
9 |
10 | );
11 | };
12 |
13 | const style = StyleSheet.create({
14 | ScrollView: {
15 | backgroundColor: "#FFFFFF",
16 | minHeight: "100%",
17 | },
18 | });
19 |
20 | export default CallScreen;
21 |
--------------------------------------------------------------------------------
/view/ChatPanel.jsx:
--------------------------------------------------------------------------------
1 | import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
2 | import React, { useEffect, useState } from "react";
3 | import BackArrow from "../assets/icons/BackArrow";
4 | import { useNavigation } from "@react-navigation/native";
5 | import { TextInput } from "react-native-paper";
6 | import ChatMessages from "../components/ChatMessages";
7 | import { socket } from "./ChatScreen";
8 | import { useDispatch, useSelector } from "react-redux";
9 | import { getlateschat } from "../redux/room/room.action";
10 |
11 | const ChatPanel = ({ route }) => {
12 | const navigation = useNavigation();
13 | const subject = route.params;
14 | const store = useSelector((store) => store.auth);
15 |
16 | const [inputText, setInputText] = useState("");
17 | const dispatch = useDispatch();
18 | const [send, setSend] = useState(true);
19 |
20 | const socketObj = useSelector((store) => store.socket);
21 |
22 | const handleSendMessage = () => {
23 | socket.emit(
24 | "sendMessage",
25 | subject._id,
26 | new Promise((res) => res(store?.userData?.body)),
27 | inputText
28 | );
29 | setSend((prev) => !prev);
30 | alert("send");
31 | };
32 |
33 | useEffect(() => {
34 | socket.on("getMessage", () => {
35 | let id = store.userData.body._id;
36 | let subject = socketObj.subjectSocket;
37 | console.log();
38 | dispatch(getlateschat(id, subject));
39 | });
40 | }, [handleSendMessage]);
41 |
42 | return (
43 |
54 |
67 | navigation.goBack()}
69 | style={{
70 | width: "15%",
71 | justifyContent: "center",
72 | alignItems: "center",
73 | }}
74 | >
75 |
76 |
77 |
84 | {subject.name}
85 |
86 |
87 |
95 |
96 |
97 |
98 |
99 | setInputText(text)}
104 | underlineColorAndroid="transparent"
105 | />
106 |
110 | Send
111 |
112 |
113 |
114 |
115 | );
116 | };
117 | const styles = StyleSheet.create({
118 | container: {
119 | width: "100%",
120 | },
121 | inputContainer: {
122 | flexDirection: "row",
123 | alignItems: "center",
124 | backgroundColor: "#f2f2f2",
125 | borderRadius: 25,
126 | paddingHorizontal: 15,
127 | paddingVertical: 8,
128 | },
129 | textInput: {
130 | flex: 1,
131 | fontSize: 16,
132 | color: "#000",
133 | borderRadius: 20,
134 | borderTopLeftRadius: 20,
135 | borderTopRightRadius: 20,
136 | borderBottomColor: "white",
137 | underlineColorAndroid: "transparent",
138 | },
139 | sendButton: {
140 | marginLeft: 10,
141 | backgroundColor: "#ff5c5c",
142 | borderRadius: 15,
143 | paddingHorizontal: 15,
144 | paddingVertical: 10,
145 | },
146 | sendButtonText: {
147 | color: "#fff",
148 | fontSize: 16,
149 | fontWeight: "bold",
150 | },
151 | });
152 |
153 | export default ChatPanel;
154 |
--------------------------------------------------------------------------------
/view/ChatScreen.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { AppState, ScrollView, StyleSheet, Text } from "react-native";
3 | import chatOptions from "../adapters/chats/chats";
4 | import ChatBox from "../components/ChatBox.jsx";
5 | import { useDispatch, useSelector } from "react-redux";
6 | import { GetAllUser } from "../redux/user/user.action.js";
7 | import { useNavigation } from "@react-navigation/native";
8 | import { CLOSE_ROOM } from "../redux/room/room.types";
9 | import { io } from "socket.io-client";
10 | import url from "../ipconfig.js";
11 |
12 | export const socket = io(url);
13 | const ChatScreen = ({ navigation }) => {
14 | const store = useSelector((store) => store.user);
15 | const { userData } = useSelector((store) => store.auth);
16 | const dispatch = useDispatch();
17 |
18 | useEffect(() => {
19 | socket.emit("connection established", userData.body._id, (mysocketid) => {
20 | dispatch(GetAllUser(userData?.body));
21 | });
22 | socket.on("newUser", () => {
23 | dispatch(GetAllUser(userData?.body));
24 | });
25 | }, []);
26 |
27 | const navigate = useNavigation();
28 |
29 | useEffect(() => {
30 | const unsubscribe = navigate.addListener("focus", () => {
31 | dispatch({
32 | type: CLOSE_ROOM,
33 | });
34 | });
35 |
36 | return unsubscribe;
37 | }, [navigation]);
38 |
39 | const handleAppStateChange = (nextAppState) => {
40 | if (nextAppState.match(/inactive|background/)) {
41 | socket.emit("disconnectMe", "");
42 | } else {
43 | setTimeout(() => {
44 | socket.emit(
45 | "reconnectMe",
46 | new Promise((res, rej) => {
47 | let _id = userData?.body?._id;
48 | res(_id);
49 | }) || ""
50 | );
51 | }, 500);
52 | }
53 | };
54 |
55 | useEffect(() => {
56 | AppState.addEventListener("change", handleAppStateChange);
57 | return () => {
58 | AppState.removeEventListener("change", handleAppStateChange);
59 | };
60 | }, []);
61 |
62 | return (
63 |
64 | {store?.data?.map((user, index) => {
65 | return (
66 |
73 | );
74 | })}
75 |
76 | );
77 | };
78 |
79 | const style = StyleSheet.create({
80 | ScrollView: {
81 | backgroundColor: "#FFFFFF",
82 | minHeight: "90%",
83 | },
84 | });
85 |
86 | export default ChatScreen;
87 |
--------------------------------------------------------------------------------
/view/OtpAndFormFilling.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | StyleSheet,
5 | TextInput,
6 | TouchableOpacity,
7 | Image,
8 | } from "react-native";
9 | import React, { useState } from "react";
10 | import MenuIcon from "../assets/icons/MenuIcon";
11 | import { useNavigation } from "@react-navigation/native";
12 | import GetcontactAccess from "../components/GetcontactAccess";
13 | import { useDispatch, useSelector } from "react-redux";
14 | import { CreateNewAccount } from "../redux/authentication/auth.action";
15 |
16 | const OtpAndFormFilling = () => {
17 | const [querry, setQuerry] = useState("");
18 | const [otpVerifyed, setOtpVerifyed] = useState(false);
19 | const [ContactAccess, setContactAccess] = useState(false);
20 |
21 | const state = useSelector((store) => store.auth);
22 | const dispatch = useDispatch();
23 | const navigate = useNavigation();
24 | const handleInputChange = (text) => {
25 | setQuerry(text.replace(/[^0-9]/g, ""));
26 | };
27 |
28 | const verifyOtp = () => {
29 | console.log(querry);
30 | if (querry !== "1234") return alert("Invalid OTP");
31 | setOtpVerifyed(true);
32 | };
33 |
34 | const [name, setName] = useState("");
35 |
36 | const handleTextChange = (inputText) => {
37 | setName(inputText);
38 | };
39 |
40 | const CreateAccount = () => {
41 | let body = {
42 | name,
43 | user_id: +state?.userData?.number,
44 | avatar_url: '',
45 | };
46 | dispatch(CreateNewAccount(body));
47 | };
48 |
49 | return (
50 |
51 | {otpVerifyed ? (
52 | <>
53 |
54 | {!ContactAccess && (
55 |
59 | )}
60 |
61 |
72 |
79 | {" "}
80 | Profile info{" "}
81 |
82 |
89 |
90 |
91 |
92 |
93 |
99 | Please Provide your name and an optional profile photo
100 |
101 |
102 |
111 |
118 |
119 |
126 |
138 |
139 |
140 |
154 |
159 | Next
160 |
161 |
162 |
163 | >
164 | ) : (
165 | <>
166 |
167 | Verifying your number
168 |
169 |
170 |
171 |
172 | User will recieve otp at {"number"}
173 |
179 |
184 | verify
185 |
186 | >
187 | )}
188 |
189 | );
190 | };
191 |
192 | const styles = StyleSheet.create({
193 | container: {
194 | width: "100%",
195 | height: "100%",
196 | alignItems: "center",
197 | },
198 | navbar: {
199 | width: "100%",
200 | height: "8%",
201 | marginTop: 42,
202 | display: "flex",
203 | flexDirection: "row",
204 | justifyContent: "space-between",
205 | alignItems: "center",
206 | },
207 | headding: {
208 | width: "90%",
209 | textAlign: "center",
210 | paddingLeft: 52,
211 | fontSize: 22,
212 | color: "green",
213 | fontWeight: 700,
214 | },
215 | menuIcon: {
216 | width: "20%",
217 | justifyContent: "center",
218 | },
219 | otpContainer: {
220 | width: "40%",
221 | height: 40,
222 | borderBottomColor: "green",
223 | borderBottomWidth: 1,
224 | },
225 | button: {
226 | width: 90,
227 | height: 50,
228 | backgroundColor: "green",
229 | justifyContent: "center",
230 | alignItems: "center",
231 | borderRadius: 50,
232 | position: "absolute",
233 | bottom: 50,
234 | },
235 | buttonText: {
236 | color: "white",
237 | fontSize: 14,
238 | fontWeight: 500,
239 | },
240 | });
241 |
242 | export default OtpAndFormFilling;
243 |
--------------------------------------------------------------------------------
/view/StatusScreen.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, Text, View } from "react-native";
3 |
4 | const StatusScreen = ({ navigation }) => {
5 | return (
6 |
7 | Status
8 |
9 | );
10 | };
11 |
12 | const style = StyleSheet.create({
13 | ScrollView: {
14 | backgroundColor: "#FFFFFF",
15 | minHeight: "100%",
16 | },
17 | });
18 |
19 | export default StatusScreen;
20 |
--------------------------------------------------------------------------------
/view/Welcome.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | StyleSheet,
5 | ScrollView,
6 | Image,
7 | ImageBackground,
8 | Button,
9 | TouchableOpacity,
10 | } from "react-native";
11 | import React, { useState, useEffect } from "react";
12 | import Lang from "../adapters/language/language";
13 | import LanguageItem from "../components/LanguageItem";
14 | import { LinearGradient } from "expo-linear-gradient";
15 | import { RadioButton } from "react-native-paper";
16 | import { Ionicons } from "@expo/vector-icons";
17 | import { useNavigation } from "@react-navigation/native";
18 |
19 | const Welcome = () => {
20 | const navigate = useNavigation();
21 | const [language, setLanguage] = useState(Lang[0].primaryLanguage);
22 | console.log(`Welcome`, language);
23 | const handlePress = () => {
24 | navigate.navigate("aggreandcontinue");
25 | };
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
41 |
53 |
54 | Welcome to Chatify
55 |
56 | Choose your language to get started
57 |
58 |
59 |
60 | setLanguage(value)}
62 | value={language}
63 | >
64 | {Lang.map((item, index) => {
65 | return (
66 |
73 | );
74 | })}
75 |
76 |
77 |
78 | );
79 | };
80 |
81 | const style = StyleSheet.create({
82 | container: {
83 | width: "100%",
84 | height: "100%",
85 | display: "flex",
86 | flexDirection: "column",
87 | justifyContent: "center",
88 | alignItems: "center",
89 | backgroundColor: "white",
90 | },
91 | imageContainer: {
92 | width: "100%",
93 | height: "35%",
94 | display: "flex",
95 | justifyContent: "flex-end",
96 | alignItems: "center",
97 | },
98 | image: {
99 | width: 300,
100 | height: 300,
101 | marginTop: 250,
102 | },
103 |
104 | heading: {
105 | fontSize: 25,
106 | lineHeight: 50,
107 | fontWeight: 600,
108 | color: "#111b21",
109 | backgroundColor: "white",
110 | },
111 | instruction: {
112 | fontSize: 15,
113 | lineHeight: 20,
114 | fontWeight: 400,
115 | color: "#3b4a54",
116 | backgroundColor: "white",
117 | },
118 | languageScroll: {
119 | backgroundColor: "white",
120 | borderColor: "black",
121 | width: "100%",
122 | marginTop: 10,
123 | },
124 | button: {
125 | width: 60,
126 | height: 60,
127 | borderRadius: 30,
128 | backgroundColor: "#00a884",
129 | justifyContent: "center",
130 | alignItems: "center",
131 | position: "absolute",
132 | right: 15,
133 | bottom: 15,
134 | zIndex: 1,
135 | },
136 | });
137 |
138 | export default Welcome;
139 |
--------------------------------------------------------------------------------