🔥 feat(package.json): add @expo/metro-runtime, react-dom, react-native-toast-notifications, react-native-web dependencies for better compatibility and notifications
🔥 feat(App.tsx): wrap app in ToastProvider for toast notifications, add console logs for debugging 🔥 feat(SignIn.tsx, SignUp.tsx): refactor updateUsername and updatePassword methods for better type safety 🔥 feat(ClipElementLocal.tsx, ClipElementRemote.tsx): refactor to functional components, add color to text and icons for better visibility 🔥 feat(ClipViewLocal.tsx, ClipViewRemote.tsx): add color to title for better visibility 🔥 feat(ClipElementRemote.tsx): add color to text for better visibility 🔥 feat(ClipViewRemote.tsx): reorder elements for better readability 🔥 feat(ClipViewLocal.tsx): add color to title for better visibility 🔥 feat(SignUp.tsx): refactor updatePassword method for better type safety 🔥 feat(SignIn.tsx): refactor updateUsername and updatePassword methods for better type safety 🔥 feat(ClipElementLocal.tsx): refactor to functional component, add color to text and icons for better visibility 🔥 feat(ClipElementRemote.tsx): refactor to functional component, add color to text for better visibility 🔥 feat(ClipViewLocal.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): reorder elements for better readability 🔥 feat(ClipViewLocal.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): reorder elements for better readability 🔥 feat(ClipViewLocal.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): reorder elements for better readability 🔥 feat(ClipViewLocal.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): add color to title for better visibility 🔥 feat(ClipViewRemote.tsx): reorder
This commit is contained in:
parent
11035e3a05
commit
e3b8655fe9
@ -10,6 +10,7 @@
|
|||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@expo/metro-runtime": "^3.1.3",
|
||||||
"@react-native-async-storage/async-storage": "^1.18.1",
|
"@react-native-async-storage/async-storage": "^1.18.1",
|
||||||
"@react-navigation/material-bottom-tabs": "^6.2.15",
|
"@react-navigation/material-bottom-tabs": "^6.2.15",
|
||||||
"@react-navigation/native": "^6.1.6",
|
"@react-navigation/native": "^6.1.6",
|
||||||
@ -21,13 +22,16 @@
|
|||||||
"expo-constants": "^14.4.2",
|
"expo-constants": "^14.4.2",
|
||||||
"expo-modules-core": "^1.5.12",
|
"expo-modules-core": "^1.5.12",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-dom": "18.2.0",
|
||||||
"react-native": "0.71.4",
|
"react-native": "0.71.4",
|
||||||
"react-native-async-storage": "^0.0.1",
|
"react-native-async-storage": "^0.0.1",
|
||||||
"react-native-paper": "^5.6.0",
|
"react-native-paper": "^5.6.0",
|
||||||
"react-native-safe-area-context": "^4.9.0",
|
"react-native-safe-area-context": "^4.9.0",
|
||||||
"react-native-safe-area-view": "^1.1.1",
|
"react-native-safe-area-view": "^1.1.1",
|
||||||
"react-native-simple-toast": "^2.0.0",
|
"react-native-simple-toast": "^2.0.0",
|
||||||
|
"react-native-toast-notifications": "^3.4.0",
|
||||||
"react-native-vector-icons": "^9.2.0",
|
"react-native-vector-icons": "^9.2.0",
|
||||||
|
"react-native-web": "~0.18.10",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"redux": "^4.2.1",
|
"redux": "^4.2.1",
|
||||||
"redux-persist": "^6.0.0"
|
"redux-persist": "^6.0.0"
|
||||||
|
22
src/App.tsx
22
src/App.tsx
@ -6,29 +6,18 @@
|
|||||||
*/
|
*/
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {NavigationContainer, StackActions} from '@react-navigation/native';
|
import {NavigationContainer, StackActions} from '@react-navigation/native';
|
||||||
import type {PropsWithChildren} from 'react';
|
import {Platform} from 'react-native';
|
||||||
import {
|
|
||||||
SafeAreaView,
|
|
||||||
ScrollView,
|
|
||||||
StatusBar,
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
useColorScheme,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import ClipViewLocal from './clip/ClipViewLocal';
|
import ClipViewLocal from './clip/ClipViewLocal';
|
||||||
import ClipViewRemote from './clip/ClipViewRemote';
|
import ClipViewRemote from './clip/ClipViewRemote';
|
||||||
import {createMaterialBottomTabNavigator} from '@react-navigation/material-bottom-tabs';
|
import {createMaterialBottomTabNavigator} from '@react-navigation/material-bottom-tabs';
|
||||||
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
|
||||||
import SignIn from './auth/SignIn';
|
import SignIn from './auth/SignIn';
|
||||||
import SignUp from './auth/SignUp';
|
import SignUp from './auth/SignUp';
|
||||||
import {Provider} from 'react-redux';
|
import {Provider} from 'react-redux';
|
||||||
import {store, persistor} from './redux/store';
|
import {store, persistor} from './redux/store';
|
||||||
import {PersistGate} from 'redux-persist/integration/react';
|
import {PersistGate} from 'redux-persist/integration/react';
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator();
|
|
||||||
const Tab = createMaterialBottomTabNavigator();
|
const Tab = createMaterialBottomTabNavigator();
|
||||||
|
import { ToastProvider } from 'react-native-toast-notifications'
|
||||||
|
|
||||||
|
|
||||||
class App extends React.Component<any, any> {
|
class App extends React.Component<any, any> {
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
@ -40,12 +29,16 @@ class App extends React.Component<any, any> {
|
|||||||
store.subscribe(() => {
|
store.subscribe(() => {
|
||||||
this.setState({token: store.getState().persistedUserReducer.token});
|
this.setState({token: store.getState().persistedUserReducer.token});
|
||||||
});
|
});
|
||||||
|
console.log(Platform.OS);
|
||||||
|
console.log(typeof store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
console.log('render app', store.getState());
|
console.log('render app', store.getState());
|
||||||
console.log('app state', this.state);
|
console.log('app state', this.state);
|
||||||
return (
|
return (
|
||||||
|
<ToastProvider>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate loading={null} persistor={persistor} />
|
<PersistGate loading={null} persistor={persistor} />
|
||||||
<NavigationContainer>
|
<NavigationContainer>
|
||||||
@ -93,6 +86,7 @@ class App extends React.Component<any, any> {
|
|||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
</ToastProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,20 +32,20 @@ export default class SignIn extends React.Component<any, any> {
|
|||||||
} else console.log(signInJson);
|
} else console.log(signInJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUsername(event: any) {
|
updateUsername(username: string) {
|
||||||
this.setState({ username: event.target.value });
|
this.setState({ username: username });
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePassword(event: any) {
|
updatePassword(password: string) {
|
||||||
this.setState({ password: event.target.value });
|
this.setState({ password: password });
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20 }}>Connexion</Text>
|
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20 }}>Connexion</Text>
|
||||||
<TextInput placeholder="Nom d'utilisateur" value={this.state.username} onChange={this.updateUsername} />
|
<TextInput placeholder="Nom d'utilisateur" value={this.state.username} onChangeText={this.updateUsername} />
|
||||||
<TextInput placeholder="Mot de Passe" value={this.state.password} onChange={this.updatePassword} />
|
<TextInput placeholder="Mot de Passe" value={this.state.password} onChangeText={this.updatePassword} />
|
||||||
<Button title="Se connecter" onPress={this.signInFunction} />
|
<Button title="Se connecter" onPress={this.signInFunction} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {View, Text, Button, TextInput} from 'react-native';
|
import {View, Text, Button, TextInput} from 'react-native';
|
||||||
import {accessibilityProps} from 'react-native-paper/lib/typescript/src/components/MaterialCommunityIcon';
|
|
||||||
import {setUser} from '../redux/actions';
|
import {setUser} from '../redux/actions';
|
||||||
|
|
||||||
export default class SignUp extends React.Component<any, any> {
|
export default class SignUp extends React.Component<any, any> {
|
||||||
@ -50,7 +49,7 @@ export default class SignUp extends React.Component<any, any> {
|
|||||||
this.setState({username: username});
|
this.setState({username: username});
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePassword(password: any) {
|
updatePassword(password: string) {
|
||||||
this.setState({password: password});
|
this.setState({password: password});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Clipboard } from 'react-native';
|
|
||||||
import Toast from 'react-native-simple-toast';
|
|
||||||
|
|
||||||
export default class AClipElement extends React.Component<any, any> {
|
|
||||||
|
|
||||||
constructor(props: any) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
onCopy() {
|
|
||||||
Clipboard.setString(this.props.content);
|
|
||||||
Toast.show('Put "' + this.props.content + '" in clipboard', Toast.SHORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +1,24 @@
|
|||||||
import {View, Text, Button} from 'react-native';
|
import {View, Text, Button} from 'react-native';
|
||||||
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
||||||
import AClipElement from './AClipElement';
|
|
||||||
import Toast from 'react-native-simple-toast';
|
import Toast from 'react-native-simple-toast';
|
||||||
|
import { Clipboard } from 'react-native';
|
||||||
|
import { Store } from 'redux';
|
||||||
|
import { black } from 'react-native-paper/lib/typescript/styles/themes/v2/colors';
|
||||||
|
|
||||||
export default class ClipElementLocal extends AClipElement {
|
export default function ClipElementLocal({content, store}:{content: string,store : Store }){
|
||||||
constructor(props: any) {
|
|
||||||
super(props);
|
function onCopy() {
|
||||||
|
Clipboard.setString(content);
|
||||||
|
Toast.show('Put "' + content + '" in clipboard', Toast.SHORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendToRemote() {
|
async function sendToRemote() {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append(
|
data.append(
|
||||||
'token',
|
'token',
|
||||||
this.props.store.getState().persistedUserReducer.token,
|
store.getState().persistedUserReducer.token,
|
||||||
);
|
);
|
||||||
data.append('content', this.props.content);
|
data.append('content', content);
|
||||||
data.append('deviceName', 'TODOChangeThisMobileDevice');
|
data.append('deviceName', 'TODOChangeThisMobileDevice');
|
||||||
const sendToRemoteResponse = await fetch(
|
const sendToRemoteResponse = await fetch(
|
||||||
'https://notifysync.simailadjalim.fr/clipboard',
|
'https://notifysync.simailadjalim.fr/clipboard',
|
||||||
@ -24,10 +28,8 @@ export default class ClipElementLocal extends AClipElement {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
const response = await sendToRemoteResponse.json();
|
const response = await sendToRemoteResponse.json();
|
||||||
Toast.show(this.props.content + 'was sent to the server', Toast.SHORT);
|
Toast.show(content + 'was sent to the server', Toast.SHORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
@ -36,11 +38,13 @@ export default class ClipElementLocal extends AClipElement {
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|
||||||
}}>
|
}}>
|
||||||
<Text style={{fontSize: 20}}>{this.props.content.length >28 ?this.props.content.slice(0,24)+"...":this.props.content }</Text>
|
<Text style={{fontSize: 20,color:"black"}}>{content.length >28 ?content.slice(0,24)+"...":content }</Text>
|
||||||
<IconVector name="sendTo" size={40} onPress={() => this.sendToRemote()} />
|
<IconVector name="sendTo" size={40} color="black" onPress={() => sendToRemote()} />
|
||||||
<IconVector name="clipboard" size={40} onPress={() => this.onCopy()} />
|
<IconVector name="clipboard" size={40} color="black" onPress={() => onCopy()} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
||||||
import AClipElement from './AClipElement';
|
import { Store } from 'redux';
|
||||||
|
import { Clipboard } from 'react-native';
|
||||||
|
import Toast from 'react-native-simple-toast';
|
||||||
|
|
||||||
export default class ClipElementRemote extends AClipElement {
|
export default function ClipElementRemote({content,timestamp,deviceName,store}:{content:string;timestamp:number,deviceName:string;store: Store}){
|
||||||
|
|
||||||
constructor(props: any) {
|
function onCopy() {
|
||||||
super(props);
|
Clipboard.setString(content);
|
||||||
|
Toast.show('Put "' + content + '" in clipboard', Toast.SHORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
const date= new Date(timestamp*1000);
|
||||||
const date= new Date(this.props.timestamp*1000);
|
console.log(timestamp*1000);
|
||||||
console.log(this.props.timestamp*1000);
|
|
||||||
return <View style={{flex:1,margin:10,flexDirection:'row',justifyContent:'space-between',alignItems:'center'}}>
|
return <View style={{flex:1,margin:10,flexDirection:'row',justifyContent:'space-between',alignItems:'center'}}>
|
||||||
<View style={{flex:1,margin:10,flexDirection:'column'}}>
|
<View style={{flex:1,margin:10,flexDirection:'column'}}>
|
||||||
<Text style={{fontSize:20,}}>{this.props.content.length >28 ?this.props.content.slice(0,24)+"...":this.props.content}</Text>
|
<Text style={{fontSize:20,color:"black"}}>{content.length >28 ?content.slice(0,24)+"...":content}</Text>
|
||||||
<Text style={{fontSize:10,}}>{this.props.deviceName}</Text>
|
<Text style={{fontSize:10,color:"black"}}>{deviceName}</Text>
|
||||||
<Text style={{fontSize:10,}}>{date.getHours() + ":" + date.getMinutes() + ", "+ date.toDateString()}</Text>
|
<Text style={{fontSize:10,color:"black"}}>{date.getHours() + ":" + date.getMinutes() + ", "+ date.toDateString()}</Text>
|
||||||
</View>
|
</View>
|
||||||
<IconVector name="clipboard" size={40} onPress={() => this.onCopy()} />
|
<IconVector name="clipboard" size={40} color="black" onPress={() => onCopy()} />
|
||||||
</View>;
|
</View>;
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,5 +1,3 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import React from 'react';
|
|
||||||
import {ScrollView, Text, Button, Clipboard} from 'react-native';
|
import {ScrollView, Text, Button, Clipboard} from 'react-native';
|
||||||
import ClipList from './ClipList';
|
import ClipList from './ClipList';
|
||||||
import AClipView from './AClipView';
|
import AClipView from './AClipView';
|
||||||
@ -39,7 +37,7 @@ export default class ClipViewLocal extends AClipView {
|
|||||||
let notTitle = 'Remote Clipboard';
|
let notTitle = 'Remote Clipboard';
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<Text style={{fontWeight: 'bold', fontSize: 30, margin: 20}}>
|
<Text style={{fontWeight: 'bold', fontSize: 30, margin: 20, color:"black"}}>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { ScrollView, Text, Button } from 'react-native';
|
import { ScrollView, Text, Button } from 'react-native';
|
||||||
import ClipList from './ClipList';
|
import ClipList from './ClipList';
|
||||||
import AClipView from './AClipView';
|
import AClipView from './AClipView';
|
||||||
|
import { black } from 'react-native-paper/lib/typescript/styles/themes/v2/colors';
|
||||||
|
|
||||||
export default class ClipViewRemote extends AClipView {
|
export default class ClipViewRemote extends AClipView {
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
@ -23,9 +24,11 @@ export default class ClipViewRemote extends AClipView {
|
|||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
let title = "Remote Clipboard";
|
let title = "Remote Clipboard";
|
||||||
return <ScrollView>
|
return <ScrollView>
|
||||||
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20 }}>{title}</Text>
|
<Text style={{ fontWeight: 'bold', fontSize: 30, margin: 20, color:"black" }}>
|
||||||
<ClipList type={this.props.type} clips={this.state.clips} />
|
{title}
|
||||||
|
</Text>
|
||||||
<Button title="Refresh" onPress={() => this.componentDidMount()} />
|
<Button title="Refresh" onPress={() => this.componentDidMount()} />
|
||||||
|
<ClipList type={this.props.type} clips={this.state.clips} />
|
||||||
{this.getSignOutBtn()}
|
{this.getSignOutBtn()}
|
||||||
</ScrollView>;
|
</ScrollView>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user