├── .gitattributes
├── .gitignore
├── .prettierrc
├── App.tsx
├── LICENSE
├── README.md
├── app.json
├── assets
├── adaptive-icon.png
├── chatgpt-4.png
├── chatgpt-5.png
├── chatgpt.png
├── download (1).png
├── download.png
├── favicon.png
├── icon.png
├── message-icon.png
├── message.jfif
└── splash.png
├── components
├── InputMessage.tsx
├── Layout.tsx
├── ListMessage.tsx
└── Message.tsx
├── constants
└── constants.ts
├── context
└── DataProvider.tsx
├── data
└── messages.ts
├── helpers
└── getMessage.ts
├── hooks
└── useFetchMessage.ts
├── others
└── screen.png
├── package-lock.json
├── package.json
├── screens
├── ExplorerScreen.tsx
├── Footer.tsx
├── HomeScreen.tsx
└── Infomation.tsx
├── server
├── .gitignore
├── config.js
├── index.js
├── package-lock.json
└── package.json
├── tsconfig.json
└── types
└── types.d.ts
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
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 |
13 | # macOS
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "arrowParens": "always",
3 | "bracketSameLine": false,
4 | "bracketSpacing": true,
5 | "embeddedLanguageFormatting": "auto",
6 | "htmlWhitespaceSensitivity": "css",
7 | "insertPragma": false,
8 | "jsxSingleQuote": false,
9 | "printWidth": 90,
10 | "proseWrap": "preserve",
11 | "quoteProps": "as-needed",
12 | "requirePragma": false,
13 | "semi": true,
14 | "singleQuote": true,
15 | "tabWidth": 4,
16 | "trailingComma": "es5",
17 | "useTabs": true,
18 | "vueIndentScriptAndStyle": false
19 | }
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native'
2 | import { NavigationContainer } from '@react-navigation/native';
3 | import { createNativeStackNavigator } from '@react-navigation/native-stack';
4 |
5 | import { DataProvider } from './context/DataProvider';
6 |
7 | import HomeScreen from './screens/HomeScreen';
8 | import Infomation from './screens/Infomation';
9 | import ExplorerScreen from './screens/ExplorerScreen';
10 |
11 | const Stack = createNativeStackNavigator();
12 |
13 | export default function App() {
14 | return (
15 |
16 |
17 |
18 | ({
22 | title: 'Explore',
23 | headerStyle: styles.headerstyle,
24 | headerTitleStyle: styles.headertitlestyle,
25 | headerTintColor: '#000000',
26 | })}
27 | />
28 | ({
32 | title: 'Chat',
33 | headerStyle: styles.headerstyle,
34 | headerTitleStyle: styles.headertitlestyle,
35 | headerTintColor: '#000000',
36 | headerBackButtonMenuEnabled: false,
37 | headerBackVisible: false
38 | })}
39 | />
40 |
52 |
53 |
54 |
55 | );
56 | }
57 |
58 | const styles = StyleSheet.create({
59 | headerstyle: {
60 | backgroundColor: '#ffffff'
61 | },
62 | headertitlestyle: {
63 | fontSize: 32,
64 | color: '#000000',
65 | fontWeight: 'bold'
66 | },
67 | })
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Yeferson Yuberley Guerrero Castro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ChatGPT-App-React-Native-TypeScript
2 |
3 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "ChatGPT-App",
4 | "slug": "ChatGPT-App",
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 | "updates": {
15 | "fallbackToCacheTimeout": 0
16 | },
17 | "assetBundlePatterns": [
18 | "**/*"
19 | ],
20 | "ios": {
21 | "supportsTablet": true
22 | },
23 | "android": {
24 | "adaptiveIcon": {
25 | "foregroundImage": "./assets/adaptive-icon.png",
26 | "backgroundColor": "#FFFFFF"
27 | }
28 | },
29 | "web": {
30 | "favicon": "./assets/favicon.png"
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/chatgpt-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/chatgpt-4.png
--------------------------------------------------------------------------------
/assets/chatgpt-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/chatgpt-5.png
--------------------------------------------------------------------------------
/assets/chatgpt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/chatgpt.png
--------------------------------------------------------------------------------
/assets/download (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/download (1).png
--------------------------------------------------------------------------------
/assets/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/download.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/favicon.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/icon.png
--------------------------------------------------------------------------------
/assets/message-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/message-icon.png
--------------------------------------------------------------------------------
/assets/message.jfif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/message.jfif
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/newstar121/ChatGPT-App-React-Native-TypeScript/739ae0062fc03eceae1dbc68743542ec02e1edac/assets/splash.png
--------------------------------------------------------------------------------
/components/InputMessage.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from 'react';
2 | import uuid from 'react-uuid';
3 | import { FontAwesome } from '@expo/vector-icons';
4 | import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
5 |
6 | import { DataContext } from '../context/DataProvider';
7 |
8 | const InputMessage = () => {
9 |
10 | const { setTextInput } = useContext(DataContext);
11 | const [text, setText] = useState('');
12 |
13 | const handleSendMessage = () => {
14 |
15 | if (!text.trim()) return;
16 |
17 | setTextInput({
18 | id: uuid(),
19 | create: new Date().getTime(),
20 | model: 'youchat',
21 | text: text.trim(),
22 | user: {
23 | name: 'you',
24 | avatar: 'https://i.pravatar.cc/100?u=A08',
25 | },
26 | usage: {
27 | prompt_tokens: 0,
28 | completion_tokens: 0,
29 | total_tokens: 0,
30 | },
31 | });
32 | setText('');
33 | };
34 |
35 | return (
36 |
37 | setText(text)}
40 | value={text}
41 | />
42 | handleSendMessage()}>
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default InputMessage;
50 |
51 | const styles = StyleSheet.create({
52 | inputMessage: {
53 | // flex: 1,
54 | flexDirection: 'row',
55 | justifyContent: 'center',
56 | alignItems: 'center',
57 | width: '100%',
58 | },
59 | input: {
60 | width: '75%',
61 | height: 50,
62 | padding: 10,
63 | fontSize: 14,
64 | textAlign: 'center',
65 | color: '#000',
66 | borderColor: '#10ac84',
67 | borderWidth: 1,
68 | borderRadius: 10,
69 | },
70 | button: {
71 | flex: 0,
72 | justifyContent: 'center',
73 | alignItems: 'center',
74 | width: '15%',
75 | height: 50,
76 | marginLeft: 10,
77 | textAlign: 'center',
78 | borderColor: '#10ac84',
79 | borderWidth: 1,
80 | borderRadius: 5,
81 | backgroundColor: '#10ac84',
82 | },
83 | });
84 |
--------------------------------------------------------------------------------
/components/Layout.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, View, StatusBar } from 'react-native';
3 |
4 | interface Props {
5 | children: React.ReactNode;
6 | }
7 |
8 | const Layout = ({ children }: Props) => {
9 | return (
10 |
11 | {/* */}
12 | {children}
13 |
14 | );
15 | };
16 |
17 | export default Layout;
18 |
19 | const styles = StyleSheet.create({
20 | container: {
21 | flex: 1,
22 | flexDirection:'column',
23 | padding: 10,
24 | justifyContent: 'space-between',
25 | alignItems: 'center',
26 | },
27 | });
28 |
--------------------------------------------------------------------------------
/components/ListMessage.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext, useEffect } from 'react';
2 | import { StyleSheet, View, FlatList, RefreshControl } from 'react-native';
3 |
4 | import { useFetchMessage } from '../hooks/useFetchMessage';
5 | import Message from './Message';
6 | import { DataContext } from '../context/DataProvider';
7 | import { MessageType } from '../types/types';
8 | import uuid from 'react-uuid';
9 |
10 | const ListMessage = () => {
11 |
12 | const [messages, setMessages] = useState([
13 | {
14 | id: "1",
15 | create: (new Date()).getTime(),
16 | model: 'tx-3',
17 | text: "sdsfsdf sdfsdfs dfsdfsdfsd fsdf sdfsdfs ",
18 | user: {
19 | name: 'you',
20 | avatar: 'sdfsdf'
21 | },
22 | usage: {
23 | prompt_tokens: 1000,
24 | completion_tokens: 10000,
25 | total_tokens: 30000,
26 | },
27 | },
28 | {
29 | id: "2",
30 | create: (new Date()).getTime(),
31 | model: 'tx-3',
32 | text: "sdsfs dfsdfsdf sdfsdfsdf sdfsdfsdfsd fsdfds fsddfs",
33 | user: {
34 | name: 'newstar',
35 | avatar: 'sdfsdf'
36 | },
37 | usage: {
38 | prompt_tokens: 1000,
39 | completion_tokens: 10000,
40 | total_tokens: 30000,
41 | },
42 | },
43 | {
44 | id: "3",
45 | create: (new Date()).getTime(),
46 | model: 'tx-3',
47 | text: "sdsfsdf sdfsdf sdfsdfsdf sdfsdfsdf sdfsdfd sfsddfs",
48 | user: {
49 | name: 'you',
50 | avatar: 'sdfsdf'
51 | },
52 | usage: {
53 | prompt_tokens: 1000,
54 | completion_tokens: 10000,
55 | total_tokens: 30000,
56 | },
57 | },
58 | {
59 | id: "4",
60 | create: (new Date()).getTime(),
61 | model: 'tx-3',
62 | text: "sdsfsd fsdfsdfs dfsdfsdfsd fsdfsdfsdfsd fdsfsddfssd sfsdfs dfsdfsd fsdfsdfsd fsdf sd fsd fsd fd sfsddf ssdsfs dfsdfs dfsdfs dfsdf sdfs dfsdfsdfsdf dsfsddfs",
63 | user: {
64 | name: 'newstar',
65 | avatar: 'sdfsdf'
66 | },
67 | usage: {
68 | prompt_tokens: 1000,
69 | completion_tokens: 10000,
70 | total_tokens: 30000,
71 | },
72 | },
73 | {
74 | id: "5",
75 | create: (new Date()).getTime(),
76 | model: 'tx-3',
77 | text: "sdsfs dfsdfsd fsdfsdf sdfsd fsdfsdf sdf sdf dsf sddfs",
78 | user: {
79 | name: 'you',
80 | avatar: 'sdfsdf'
81 | },
82 | usage: {
83 | prompt_tokens: 1000,
84 | completion_tokens: 10000,
85 | total_tokens: 30000,
86 | },
87 | }
88 | ]);
89 | console.log('messagesSide', messages.length);
90 |
91 | const { textInput } = useContext(DataContext);
92 |
93 | console.log('textInput', textInput.text);
94 |
95 | const { data, isLoading } = useFetchMessage(textInput.text);
96 |
97 | console.log('getMessageOutput: ', data.text);
98 |
99 | useEffect(() => {
100 |
101 | if (textInput?.text) {
102 | setMessages((messages: any) => [...messages, textInput]);
103 | }
104 |
105 | if (!!data?.text) {
106 | setMessages((messages: any) => [...messages, data]);
107 | }
108 |
109 | setMessages((messages: any) => [...messages, {
110 | id: uuid(),
111 | create: (new Date()).getTime(),
112 | model: 'tx-3',
113 | text: "sdsfsdfsd fsdfsdfsdfsd fsdfsdf sdfsd fsdfdsf sddfs",
114 | user: {
115 | name: 'newstar',
116 | avatar: 'sdfsdf'
117 | },
118 | usage: {
119 | prompt_tokens: 1000,
120 | completion_tokens: 10000,
121 | total_tokens: 30000,
122 | },
123 | }])
124 | }, [data, data.text]);
125 |
126 | console.log('messagesDown', messages.length);
127 | console.log('isLoading', isLoading);
128 |
129 | return (
130 |
131 | }
135 | keyExtractor={(item: { id: { toString: () => any; }; }) => item.id.toString()}
136 | refreshControl={
137 | setMessages([])}
140 | />
141 | }
142 | />
143 |
144 | );
145 | };
146 |
147 | export default ListMessage;
148 |
149 | const styles = StyleSheet.create({
150 | container: {
151 | flex: 1,
152 | width: '100%',
153 | marginLeft: 10,
154 | marginRight: 10,
155 | paddingLeft: 10,
156 | paddingRight: 10,
157 | overflow: 'scroll',
158 | },
159 | listContainer: {
160 | flex: 1,
161 | width: '100%',
162 | },
163 | });
164 |
--------------------------------------------------------------------------------
/components/Message.tsx:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 | import { StyleSheet, Text, View, TouchableOpacity, ToastAndroid, Image } from 'react-native';
3 | import { Avatar } from 'react-native-elements'
4 | import * as Clipboard from 'expo-clipboard';
5 |
6 | import { MessageType } from '../types/types';
7 |
8 | type MessageProps = {
9 | message: MessageType;
10 | };
11 |
12 | const Message = ({ message }: MessageProps) => {
13 |
14 | const copyToClipboard = async () => {
15 | try {
16 | await Clipboard.setStringAsync(message.text);
17 | ToastAndroid.show('Copied to clipboard', ToastAndroid.SHORT);
18 | } catch (error) {
19 | console.log('toast error', error)
20 | }
21 |
22 | };
23 |
24 | return (
25 | //
26 | //
27 | // {message.user.name === 'you' ? (
28 | // <>
29 | // {message.user.name}
30 | //
31 |
32 | // >
33 | // ) : (
34 | // <>
35 | //
36 | // {message.user.name}
37 | // >
38 | // )}
39 |
40 | //
41 | // copyToClipboard()}>
42 | // {message.text}
43 | //
44 | //
45 | <>
46 | {message.user.name === 'you' ? (
47 |
48 |
49 | {(new Date(message.create).toISOString())}
50 |
51 | copyToClipboard()}>
52 | {message.text}
53 |
54 |
55 |
56 |
57 |
58 | ) : (
59 |
60 |
61 |
62 |
63 | {/* {(new Date(message.create).toISOString())} */}
64 |
65 | copyToClipboard()}>
66 | {message.text}
67 |
68 |
69 |
70 |
71 | )}
72 | >
73 |
74 | );
75 | };
76 |
77 | export default Message;
78 |
79 | const styles = StyleSheet.create({
80 | nova: {
81 | flexDirection: 'row',
82 | },
83 | messagechatgpt: {
84 | backgroundColor: '#d2f9d1',
85 | padding: 10,
86 | margin: 10,
87 | borderRadius: 10,
88 | flexBasis:'auto',
89 | maxWidth: '70%'
90 |
91 | },
92 | messageyou: {
93 | backgroundColor: '#dddddd',
94 | padding: 10,
95 | margin: 10,
96 | borderRadius: 10,
97 | flexBasis: 'auto',
98 | alignSelf: 'flex-end',
99 | maxWidth: '70%',
100 | },
101 | textyou: {
102 | color: '#000',
103 | fontSize: 16,
104 | alignSelf: 'flex-end',
105 | },
106 | textchatgpt: {
107 | color: '#000',
108 | fontSize: 16,
109 | alignSelf: 'flex-end',
110 | },
111 | profileyou: {
112 | flexDirection: 'row',
113 | alignItems: 'center',
114 | justifyContent: 'flex-end',
115 | marginBottom: 5,
116 | },
117 | profilechatgpt: {
118 | flexDirection: 'row',
119 | alignItems: 'center',
120 | marginBottom: 5,
121 | justifyContent: 'flex-start'
122 | },
123 | author: {
124 | color: '#fff',
125 | fontSize: 12,
126 | marginLeft: 8,
127 | },
128 | Image: {
129 | width: 25,
130 | height: 25,
131 | borderRadius: 8,
132 | },
133 | });
134 |
--------------------------------------------------------------------------------
/constants/constants.ts:
--------------------------------------------------------------------------------
1 | export const API_URL = 'http://localhost:5050';
2 |
3 | export const SELECTED_TYPE = {
4 | explorer: 'Explorer',
5 | chat: 'Chat',
6 | more: 'More',
7 | }
8 |
9 | export const CATEGORY_DATA = [
10 | {
11 | id: 1,
12 | name: 'Travel & Explore',
13 | topics: ['Rent a House', 'Ticket Purchase', 'Restaurant Advice']
14 | },
15 | {
16 | id: 2,
17 | name: 'Travel & Explore',
18 | topics: ['Rent a House', 'Ticket Purchase', 'Restaurant Advice']
19 | },
20 | {
21 | id: 3,
22 | name: 'Travel & Explore',
23 | topics: ['Rent a House', 'Ticket Purchase', 'Restaurant Advice']
24 | },
25 | {
26 | id: 4,
27 | name: 'Travel & Explore',
28 | topics: ['Rent a House', 'Ticket Purchase', 'Restaurant Advice']
29 | },
30 | ];
--------------------------------------------------------------------------------
/context/DataProvider.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState,createContext } from 'react';
2 |
3 | import { MessageType } from '../types/types';
4 | import { SELECTED_TYPE } from '../constants/constants';
5 |
6 | export const DataContext = createContext({});
7 |
8 | interface Props {
9 | children: React.ReactNode;
10 | }
11 |
12 | export const DataProvider = ({ children }: Props) => {
13 |
14 | const [textInput, setTextInput] = useState({} as MessageType);
15 | const [selected, setSelected] = useState(SELECTED_TYPE.explorer)
16 | const [category, setCategory] = useState