Prettier Refactor

This commit is contained in:
Djalim Simaila 2024-04-05 00:53:05 +02:00
parent 94df141d06
commit c89cfcf4fa
25 changed files with 1122 additions and 869 deletions

94
App.tsx
View File

@ -1,64 +1,72 @@
import 'react-native-gesture-handler';
// ^ le bouge pas ca casse tout ^
import { AppRegistry, Platform } from 'react-native'
import {AppRegistry, Platform} from 'react-native';
import { useState } from "react";
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Provider } from 'react-redux';
import { store,persistor } from './src/redux/store';
import { PaperProvider } from 'react-native-paper';
import { ToastProvider } from 'react-native-toast-notifications'
import {useState} from 'react';
import {NavigationContainer, DefaultTheme} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {Provider} from 'react-redux';
import {store, persistor} from './src/redux/store';
import {PaperProvider} from 'react-native-paper';
import {ToastProvider} from 'react-native-toast-notifications';
import AuthPage from './src/pages/Auth';
import ClipPage from './src/pages/Clips';
import IntroPage from './src/pages/Intro';
import { StatusBar } from 'expo-status-bar';
import { Material3Dracula, ReactNavigationDracula } from './src/themes';
import { PixelRatio, useWindowDimensions } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import {StatusBar} from 'expo-status-bar';
import {Material3Dracula, ReactNavigationDracula} from './src/themes';
import {PixelRatio, useWindowDimensions} from 'react-native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
const Stack = createNativeStackNavigator();
import { PersistGate } from 'redux-persist/integration/react';
import {PersistGate} from 'redux-persist/integration/react';
function App() {
const [token, setToken] = useState(store.getState().user.token);
const [username, setUsername] = useState('');
function App(){
const [token,setToken] = useState(store.getState().user.token);
const [username,setUsername] = useState("");
const {height,width} = useWindowDimensions();
const {height, width} = useWindowDimensions();
console.log(width);
console.log(PixelRatio.get())
store.subscribe(()=>{
let newToken = store.getState().user.token;
console.log(PixelRatio.get());
store.subscribe(() => {
let newToken = store.getState().user.token;
setToken(newToken);
})
});
return (
<PaperProvider theme={Material3Dracula}>
<ToastProvider>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<StatusBar style="light"/>
<SafeAreaProvider>
<NavigationContainer theme={ReactNavigationDracula}>
<Stack.Navigator>
{
token !== "" ? (
<>
<Stack.Screen name="Home" component={ClipPage} options={{ headerShown: false }}/>
</>
) : (
<StatusBar style="light" />
<SafeAreaProvider>
<NavigationContainer theme={ReactNavigationDracula}>
<Stack.Navigator>
{token !== '' ? (
<>
<Stack.Screen name="Intro" component={IntroPage} options={{ headerShown: false }} />
<Stack.Screen name="SignIn" component={AuthPage} options={{ headerShown: false }} />
<Stack.Screen
name="Home"
component={ClipPage}
options={{headerShown: false}}
/>
</>
)
}
</Stack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
</PersistGate>
) : (
<>
<Stack.Screen
name="Intro"
component={IntroPage}
options={{headerShown: false}}
/>
<Stack.Screen
name="SignIn"
component={AuthPage}
options={{headerShown: false}}
/>
</>
)}
</Stack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
</PersistGate>
</Provider>
</ToastProvider>
</PaperProvider>

View File

@ -1,83 +1,88 @@
import axios from 'axios';
import React from 'react';
import { View, Text, Platform, useWindowDimensions } from 'react-native';
import { useToast } from "react-native-toast-notifications";
import { Button, TextInput } from 'react-native-paper';
import { login } from '../../redux/reducers';
import { useDispatch } from 'react-redux';
import { ReactNavigationDracula as t } from '../../themes';
import { ps } from '../../utils';
import {View, Text, Platform, useWindowDimensions} from 'react-native';
import {useToast} from 'react-native-toast-notifications';
import {Button, TextInput} from 'react-native-paper';
import {login} from '../../redux/reducers';
import {useDispatch} from 'react-redux';
import {ReactNavigationDracula as t} from '../../themes';
import {ps} from '../../utils';
export default function SignIn(){
const [username, setUsername] = React.useState("");
const [password, setPassword] = React.useState("");
const [token,setToken] = React.useState("");
export default function SignIn() {
const [username, setUsername] = React.useState('');
const [password, setPassword] = React.useState('');
const [token, setToken] = React.useState('');
const toast = useToast();
const dispatch = useDispatch();
const {height, width} = useWindowDimensions();
async function signInFunction(dispatch) {
axios.post("https://notifysync.simailadjalim.fr/user",{
username:username,
password:password
},{
headers: {'Content-Type': 'multipart/form-data'}})
.then((response, status) => {
async function signInFunction(dispatch) {
axios
.post(
'https://notifysync.simailadjalim.fr/user',
{
username: username,
password: password,
},
{
headers: {'Content-Type': 'multipart/form-data'},
},
)
.then((response, status) => {
let token = response.data.token;
dispatch(login({username:username,token:token}));
toast.show("login successful .w.",{
type:"success"
dispatch(login({username: username, token: token}));
toast.show('login successful .w.', {
type: 'success',
});
})
.catch(response =>{
.catch(response => {
toast.show(response.response.data.status);
});
}
return <View style={[{
borderRadius:12,
height:"100%"
},{
flex:1,
margin:ps(8),
padding:ps(8),
paddingTop:ps(8),
gap:10,
flexDirection:'column',
justifyContent:"center",
alignItems:"center",
return (
<View
style={[
{
borderRadius: 12,
height: '100%',
},
{
flex: 1,
margin: ps(8),
padding: ps(8),
paddingTop: ps(8),
gap: 10,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: width > 600 ? t.colors.card : t.colors.background,
}]}>
<Text style={{ fontWeight: 'bold', fontSize: 30, color:t.colors.text }}>
Connexion
</Text>
<TextInput
label="Nom d'utilisateur"
mode='outlined'
value={username}
onChangeText={setUsername}
style={{
width: 300
}}
/>
<TextInput
label="Mot de Passe"
mode='outlined'
value={password}
onChangeText={setPassword}
style={{
width: 300
}}
/>
<Button
mode="contained"
onPress={()=>dispatch(signInFunction)}
>
Se connecter
</Button>
</View>
},
]}>
<Text style={{fontWeight: 'bold', fontSize: 30, color: t.colors.text}}>
Connexion
</Text>
<TextInput
label="Nom d'utilisateur"
mode="outlined"
value={username}
onChangeText={setUsername}
style={{
width: 300,
}}
/>
<TextInput
label="Mot de Passe"
mode="outlined"
value={password}
onChangeText={setPassword}
style={{
width: 300,
}}
/>
<Button mode="contained" onPress={() => dispatch(signInFunction)}>
Se connecter
</Button>
</View>
);
}

View File

@ -1,106 +1,124 @@
import React from 'react';
import {View, Text, Platform, useWindowDimensions } from 'react-native';
import {View, Text, Platform, useWindowDimensions} from 'react-native';
import axios from 'axios';
import { useToast } from "react-native-toast-notifications";
import { Button, TextInput } from 'react-native-paper';
import { useDispatch } from 'react-redux';
import { login } from '../../redux/reducers';
import { ReactNavigationDracula as t } from '../../themes';
import { ps } from '../../utils';
import {useToast} from 'react-native-toast-notifications';
import {Button, TextInput} from 'react-native-paper';
import {useDispatch} from 'react-redux';
import {login} from '../../redux/reducers';
import {ReactNavigationDracula as t} from '../../themes';
import {ps} from '../../utils';
export default function SignUp(){
const [username, setUsername] = React.useState("");
const [password, setPassword] = React.useState("");
const [confirm, setConfirm] = React.useState("");
export default function SignUp() {
const [username, setUsername] = React.useState('');
const [password, setPassword] = React.useState('');
const [confirm, setConfirm] = React.useState('');
const toast = useToast();
const dispatch = useDispatch();
const {height, width} = useWindowDimensions();
function signUpFunction(dispatch) {
if (confirm != password){
toast.show("The password and its confirmation are not the same",{
type:"warning"
if (confirm != password) {
toast.show('The password and its confirmation are not the same', {
type: 'warning',
});
return;
}
axios.put("https://notifysync.simailadjalim.fr/user",{
username:username,
password:password
},{
headers: {'Content-Type': 'multipart/form-data'}})
axios
.put(
'https://notifysync.simailadjalim.fr/user',
{
username: username,
password: password,
},
{
headers: {'Content-Type': 'multipart/form-data'},
},
)
.then((response, status) => {
toast.show("Account created, logging in !",{type:"success"});
axios.post("https://notifysync.simailadjalim.fr/user",{
username:username,
password:password
},{
headers: {'Content-Type': 'multipart/form-data'}})
toast.show('Account created, logging in !', {type: 'success'});
axios
.post(
'https://notifysync.simailadjalim.fr/user',
{
username: username,
password: password,
},
{
headers: {'Content-Type': 'multipart/form-data'},
},
)
.then((response, status) => {
let token = response.data.token;
dispatch(login({username:username,token:token}));
toast.show("login successful .w.",{type:"success"});
dispatch(login({username: username, token: token}));
toast.show('login successful .w.', {type: 'success'});
})
.catch(response =>{
toast.show(response.response.data.status);
.catch(response => {
toast.show(response.response.data.status);
});
//
})
.catch(response =>{
.catch(response => {
toast.show(response.response.data.status);
});
}
return (
<View style={[{
borderRadius:12,
height:"100%"
},{
flex:1,
margin:ps(8),
padding:ps(8),
paddingTop:ps(8),
gap:10,
flexDirection:'column',
justifyContent:"center",
alignItems:"center",
<View
style={[
{
borderRadius: 12,
height: '100%',
},
{
flex: 1,
margin: ps(8),
padding: ps(8),
paddingTop: ps(8),
gap: 10,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: width > 600 ? t.colors.card : t.colors.background,
}]}>
<Text style={{fontWeight: 'bold', fontSize: 30 ,color:t.colors.text}}>
Créer un compte
</Text>
<TextInput
label="Nom d'utilisateur"
mode='outlined'
value={username}
onChangeText={setUsername}
style={{
width:300
}}
/>
<TextInput
label="Mot de passe"
mode='outlined'
value={password}
onChangeText={setPassword}
style={{
width:300
}}
/>
<TextInput
label="Confirmer le mot de passe"
mode='outlined'
value={confirm}
onChangeText={setConfirm}
style={{
width:300
}}
/>
<Button mode="contained" onPress={()=>{dispatch(signUpFunction)}}>
S'enregistrer
</Button>
</View>
},
]}>
<Text style={{fontWeight: 'bold', fontSize: 30, color: t.colors.text}}>
Créer un compte
</Text>
<TextInput
label="Nom d'utilisateur"
mode="outlined"
value={username}
onChangeText={setUsername}
style={{
width: 300,
}}
/>
<TextInput
label="Mot de passe"
mode="outlined"
value={password}
onChangeText={setPassword}
style={{
width: 300,
}}
/>
<TextInput
label="Confirmer le mot de passe"
mode="outlined"
value={confirm}
onChangeText={setConfirm}
style={{
width: 300,
}}
/>
<Button
mode="contained"
onPress={() => {
dispatch(signUpFunction);
}}>
S'enregistrer
</Button>
</View>
);
}

View File

@ -1,34 +1,43 @@
import axios from 'axios';
import {View} from 'react-native';
import IconVector from 'react-native-vector-icons/FontAwesome5';
import { useToast } from "react-native-toast-notifications";
import * as Clipboard from 'expo-clipboard';
import { Avatar, Card, Text } from 'react-native-paper';
import { store } from '../../redux/store';
import { Button } from 'react-native-paper';
import {useToast} from 'react-native-toast-notifications';
import * as Clipboard from 'expo-clipboard';
import {Avatar, Card, Text} from 'react-native-paper';
import {store} from '../../redux/store';
import {Button, Menu} from 'react-native-paper';
import {useState} from 'react';
export default function ClipElementLocal({content}:{content: string}){
export default function ClipElementLocal({content}: {content: string}) {
const [visible, setVisible] = useState(false);
const [coords, setCoords] = useState({x: 0, y: 0});
const toast = useToast();
function onCopy() {
Clipboard.setStringAsync(content)
.then(()=>{
toast.show('copied "'+content+'" into the clipboard');
});
Clipboard.setStringAsync(content).then(() => {
toast.show('copied "' + content + '" into the clipboard');
});
}
function sendToRemote() {
axios.put("https://notifysync.simailadjalim.fr/clipboard",{
content:content,
deviceName:"TestNative",
token: store.getState().user.token
},{
headers: {'Content-Type': 'multipart/form-data'}}
).then((response,status)=>{
toast.show('"'+content+'" was sent to the server');
}).catch(response => {
toast.show('error');
})
function sendToRemote() {
axios
.put(
'https://notifysync.simailadjalim.fr/clipboard',
{
content: content,
deviceName: 'TestNative',
token: store.getState().user.token,
},
{
headers: {'Content-Type': 'multipart/form-data'},
},
)
.then((response, status) => {
toast.show('"' + content + '" was sent to the server');
})
.catch(response => {
toast.show('error');
});
}
return (
<View
@ -39,12 +48,28 @@ export default function ClipElementLocal({content}:{content: string}){
justifyContent: 'space-between',
alignItems: 'center',
}}>
<Card style={{width:"100%"}} onPress={onCopy}>
<Card.Title title={content} right={() =>
<Button mode="contained" onPress={() => sendToRemote()} >
<IconVector name="paper-plane" size={20} color="black" />
</Button>
}
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={coords}>
<Menu.Item onPress={() => {}} title="View" />
<Menu.Item onPress={() => {}} title="Share" />
<Menu.Item onPress={() => {}} title="Delete" />
</Menu>
<Card
style={{width: '100%'}}
onPressIn={evt =>
setCoords({x: evt.nativeEvent.pageX, y: evt.nativeEvent.pageY})
}
onPress={onCopy}
onLongPress={() => setVisible(true)}>
<Card.Title
title={content}
right={() => (
<Button mode="contained" onPress={() => sendToRemote()}>
<IconVector name="paper-plane" size={20} color="black" />
</Button>
)}
/>
<Card.Content>
<Text></Text>
@ -53,5 +78,3 @@ export default function ClipElementLocal({content}:{content: string}){
</View>
);
}

View File

@ -1,33 +1,67 @@
import { View } from 'react-native';
import {View} from 'react-native';
import IconVector from 'react-native-vector-icons/FontAwesome5';
import * as Clipboard from 'expo-clipboard';
import { useToast } from "react-native-toast-notifications";
import { Card, Text, Button } from 'react-native-paper';
import {useToast} from 'react-native-toast-notifications';
import {Card, Text, Menu} from 'react-native-paper';
import {useState} from 'react';
export default function ClipElementRemote({content,timestamp,deviceName}:{content:string;timestamp:number,deviceName:string}){
export default function ClipElementRemote({
content,
timestamp,
deviceName,
}: {
content: string;
timestamp: number;
deviceName: string;
}) {
const [visible, setVisible] = useState(false);
const [coords, setCoords] = useState({x: 0, y: 0});
const toast = useToast();
function onCopy() {
Clipboard.setStringAsync(content)
.then(()=>{
toast.show('copied "'+content+'" into the clipboard');
});
Clipboard.setStringAsync(content).then(() => {
toast.show('copied "' + content + '" into the clipboard');
});
}
const date= new Date(timestamp*1000);
return(
<View style={{flex:1,
padding:10,
width:"100%",
flexDirection:'row',
justifyContent:'center',
alignItems:'center'}}>
<Card style={{width:"100%"}} onPress={onCopy} >
<Card.Title title={content}/>
const date = new Date(timestamp * 1000);
return (
<View
style={{
flex: 1,
padding: 10,
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}>
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={coords}>
<Menu.Item onPress={() => {}} title="View" />
<Menu.Item onPress={() => {}} title="Share" />
<Menu.Item onPress={() => {}} title="Delete" />
</Menu>
<Card
style={{width: '100%'}}
onPressIn={evt =>
setCoords({x: evt.nativeEvent.pageX, y: evt.nativeEvent.pageY})
}
onPress={onCopy}
onLongPress={() => setVisible(true)}>
<Card.Title title={content} />
<Card.Content>
<Text variant="bodyMedium">{date.getHours() + ":" + date.getMinutes() + ", "+ date.toDateString()}</Text>
<Text variant="bodyMedium">
{date.getHours() +
':' +
date.getMinutes() +
', ' +
date.toDateString()}
</Text>
<Text variant="bodyMedium">{deviceName}</Text>
</Card.Content>
</Card>
</View>);
</Card>
</View>
);
}

View File

@ -2,7 +2,7 @@ import React from 'react';
import {FlatList, ScrollView} from 'react-native';
import ClipElementLocal from './ClipElementLocal';
import ClipElementRemote from './ClipElementRemote';
import { nanoid } from '@reduxjs/toolkit';
import {nanoid} from '@reduxjs/toolkit';
export default class ClipList extends React.Component<any, any> {
constructor(props: any) {
@ -11,21 +11,29 @@ export default class ClipList extends React.Component<any, any> {
render(): JSX.Element {
if (this.props.type === 'local') {
return <FlatList
return (
<FlatList
data={this.props.clips}
renderItem={({item}) => <ClipElementLocal content={item.content} />}
keyExtractor={item => nanoid()}
inverted={true}
/>
);
} else {
return <FlatList
return (
<FlatList
data={this.props.clips}
renderItem={({item}) => <ClipElementRemote content={item.content} deviceName={item.device_name} timestamp={item.timestamp}/>}
renderItem={({item}) => (
<ClipElementRemote
content={item.content}
deviceName={item.device_name}
timestamp={item.timestamp}
/>
)}
keyExtractor={item => nanoid()}
inverted={true}
/>
;
);
}
}
}

View File

@ -1,58 +1,72 @@
import React from "react";
import { useWindowDimensions, ScrollView, View } from "react-native";
import { Searchbar, Button } from "react-native-paper"
import ClipViewLocal from "./ClipViewLocal";
import ClipViewRemote from "./ClipViewRemote";
import { ps } from "../../utils";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
import React from 'react';
import {useWindowDimensions, ScrollView, View} from 'react-native';
import {Searchbar, Button} from 'react-native-paper';
import ClipViewLocal from './ClipViewLocal';
import ClipViewRemote from './ClipViewRemote';
import {ps} from '../../utils';
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
export default function ClipView(){
export default function ClipView() {
const [searchQuery, setSearchQuery] = React.useState('');
const {height, width} = useWindowDimensions();
const Tab = createMaterialTopTabNavigator();
let layout = ""
let layout = '';
if (width < 600) layout = "compact";
else if (width < 1200 ) layout = "medium";
else layout = "expanded";
return ( <>
<View style={{flexDirection:"row",justifyContent:"center",alignItems:"center", gap:5, margin:ps(4)}}>
{layout == "compact" ?
<Button children={<></>} icon="dots-vertical" mode="contained" style={{width:"auto"}} onPress={() => console.log('Pressed')}/>
: <></>}
<Searchbar
placeholder="Clipboards"
onChangeText={setSearchQuery}
value={searchQuery}
if (width < 600) layout = 'compact';
else if (width < 1200) layout = 'medium';
else layout = 'expanded';
return (
<>
<View
style={{
flex:1
}}
/>
</View>
{
layout == "compact"? (
<Tab.Navigator tabBarPosition="bottom">
<Tab.Screen name="Local" options={{title: 'local'}}>
{() => (
<ClipViewLocal/>
)}
</Tab.Screen>
<Tab.Screen name="Remote" options={{title: 'distant'}}>
{()=> (
<ClipViewRemote/>
)}
</Tab.Screen>
</Tab.Navigator>
):(
<ScrollView contentContainerStyle={{flexDirection:"row",justifyContent:"center",height:"100%",padding:ps(30)}}>
<ClipViewLocal/>
<ClipViewRemote/>
</ScrollView>
)
}
</>
)
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: 5,
margin: ps(4),
}}>
{layout == 'compact' ? (
<Button
children={<></>}
icon="dots-vertical"
mode="contained"
style={{width: 'auto'}}
onPress={() => console.log('Pressed')}
/>
) : (
<></>
)}
<Searchbar
placeholder="Clipboards"
onChangeText={setSearchQuery}
value={searchQuery}
style={{
flex: 1,
}}
/>
</View>
{layout == 'compact' ? (
<Tab.Navigator tabBarPosition="bottom">
<Tab.Screen name="Local" options={{title: 'local'}}>
{() => <ClipViewLocal />}
</Tab.Screen>
<Tab.Screen name="Remote" options={{title: 'distant'}}>
{() => <ClipViewRemote />}
</Tab.Screen>
</Tab.Navigator>
) : (
<ScrollView
contentContainerStyle={{
flexDirection: 'row',
justifyContent: 'center',
height: '100%',
padding: ps(30),
}}>
<ClipViewLocal />
<ClipViewRemote />
</ScrollView>
)}
</>
);
}

View File

@ -1,57 +1,55 @@
import React from 'react';
import {ScrollView, View, Text, useWindowDimensions} from 'react-native';
import { Button } from 'react-native-paper';
import {Button} from 'react-native-paper';
import ClipList from './ClipList';
import { useDispatch } from 'react-redux';
import { localClipAddToList } from '../../redux/reducers';
import { useToast } from 'react-native-toast-notifications';
import {useDispatch} from 'react-redux';
import {localClipAddToList} from '../../redux/reducers';
import {useToast} from 'react-native-toast-notifications';
import * as Clipboard from 'expo-clipboard';
import { ps } from '../../utils';
import { store } from '../../redux/store';
import {ps} from '../../utils';
import {store} from '../../redux/store';
export default function ClipViewLocal({}){
const [clips, setClips] = React.useState([...store.getState().localClip.localClip]);
export default function ClipViewLocal({}) {
const [clips, setClips] = React.useState([
...store.getState().localClip.localClip,
]);
const dispatch = useDispatch();
const toast = useToast();
const {height,width} = useWindowDimensions();
const {height, width} = useWindowDimensions();
async function addToLocal(dispatch) {
Clipboard.getStringAsync()
.then(value =>{
let newClip = {"content":value};
console.log(value);
dispatch(localClipAddToList(newClip));
setClips([...clips,newClip]);
toast.show('copied "'+value+'" into history');
})
.catch((error)=>{
console.log(error);
toast.show("could not retreive last copied element :(")
})
.then(value => {
let newClip = {content: value};
console.log(value);
dispatch(localClipAddToList(newClip));
setClips([...clips, newClip]);
toast.show('copied "' + value + '" into history');
})
.catch(error => {
console.log(error);
toast.show('could not retreive last copied element :(');
});
}
return (
<View style={{
width:"100%",
height:"100%",
flex:1,
margin: width > 600 ? ps(10) : 0
}}>
<View
style={{
width: '100%',
height: '100%',
flex: 1,
margin: width > 600 ? ps(10) : 0,
}}>
<Button
mode="elevated"
onPress={() => {
dispatch(addToLocal);
}}
>
Coller depuis le presse papier
</Button>
mode="elevated"
onPress={() => {
dispatch(addToLocal);
}}>
Coller depuis le presse papier
</Button>
<ScrollView>
<ClipList
type={"local"}
clips={clips}
/>
<ClipList type={'local'} clips={clips} />
</ScrollView>
</View>
);
</View>
);
}

View File

@ -1,52 +1,64 @@
import React from 'react';
import axios from 'axios';
import { ScrollView,View, Text, useWindowDimensions } from 'react-native';
import {ScrollView, View, Text, useWindowDimensions} from 'react-native';
import ClipList from './ClipList';
import { store } from '../../redux/store';
import { useToast } from 'react-native-toast-notifications';
import { Button } from 'react-native-paper';
import { ps } from '../../utils';
import { useDispatch } from 'react-redux';
import { remoteClipAddToList } from '../../redux/reducers';
import {store} from '../../redux/store';
import {useToast} from 'react-native-toast-notifications';
import {Button} from 'react-native-paper';
import {ps} from '../../utils';
import {useDispatch} from 'react-redux';
import {remoteClipAddToList} from '../../redux/reducers';
export default function ClipViewRemote(){
const [clips,setClips] = React.useState(store.getState().remoteClip.remoteClip);
export default function ClipViewRemote() {
const [clips, setClips] = React.useState(
store.getState().remoteClip.remoteClip,
);
const toast = useToast();
const dispatch = useDispatch();
const {height,width} = useWindowDimensions();
const {height, width} = useWindowDimensions();
async function getClips(dispatch) {
axios.get("http://notifysync.simailadjalim.fr/clipboard?token="+store.getState().user.token)
.then((response,status) => {
let remoteclips = Object.values(response["data"]['clipboard']);
axios
.get(
'http://notifysync.simailadjalim.fr/clipboard?token=' +
store.getState().user.token,
)
.then((response, status) => {
let remoteclips = Object.values(response['data']['clipboard']);
setClips(remoteclips);
dispatch(remoteClipAddToList(remoteclips))
toast.show("fetched latest clips from remote");
dispatch(remoteClipAddToList(remoteclips));
toast.show('fetched latest clips from remote');
})
.catch(response =>{
.catch(response => {
console.log(response);
toast.show("failed to fetch latest clips");
toast.show('failed to fetch latest clips');
});
}
function getSignOutBtn() {
return <Button mode="elevated" onPress={() => {}}>Sign out</Button>
return (
<Button mode="elevated" onPress={() => {}}>
Sign out
</Button>
);
}
let title = "Remote Clipboard";
return <View style={{
width:"100%",
height:"100%",
flex:1,
margin: width > 600 ? ps(10) : 0
}}>
<Button mode="elevated" onPress={() => dispatch(getClips)}>
Refresh
</Button>
<ScrollView>
<ClipList type="remote" clips={clips} />
</ScrollView>
</View>;
let title = 'Remote Clipboard';
return (
<View
style={{
width: '100%',
height: '100%',
flex: 1,
margin: width > 600 ? ps(10) : 0,
}}>
<Button mode="elevated" onPress={() => dispatch(getClips)}>
Refresh
</Button>
<ScrollView>
<ClipList type="remote" clips={clips} />
</ScrollView>
</View>
);
}

View File

@ -1,35 +1,50 @@
import axios from 'axios';
import {View} from 'react-native';
import IconVector from 'react-native-vector-icons/FontAwesome5';
import { useToast } from "react-native-toast-notifications";
import * as Clipboard from 'expo-clipboard';
import { Avatar, Card, Text } from 'react-native-paper';
import { store } from '../../redux/store';
import { Button } from 'react-native-paper';
import {useToast} from 'react-native-toast-notifications';
import * as Clipboard from 'expo-clipboard';
import {Avatar, Card, Text} from 'react-native-paper';
import {store} from '../../redux/store';
import {Button, Menu} from 'react-native-paper';
import {useState} from 'react';
export default function NotifElementLocal({title,content}:{title:string;content: string}){
export default function NotifElementLocal({
title,
content,
}: {
title: string;
content: string;
}) {
const [visible, setVisible] = useState(false);
const [coords, setCoords] = useState({x: 0, y: 0});
const toast = useToast();
function onCopy() {
Clipboard.setStringAsync(content)
.then(()=>{
toast.show('copied "'+content+'" into the clipboard');
});
Clipboard.setStringAsync(content).then(() => {
toast.show('copied "' + content + '" into the clipboard');
});
}
function sendToRemote() {
axios.put("https://notifysync.simailadjalim.fr/notification",{
title:title,
content:content,
deviceName:"TestNative",
token: store.getState().user.token
},{
headers: {'Content-Type': 'multipart/form-data'}}
).then((response,status)=>{
function sendToRemote() {
axios
.put(
'https://notifysync.simailadjalim.fr/notification',
{
title: title,
content: content,
deviceName: 'TestNative',
token: store.getState().user.token,
},
{
headers: {'Content-Type': 'multipart/form-data'},
},
)
.then((response, status) => {
toast.show('the notification was sent to the server');
}).catch(response => {
toast.show('error');
})
})
.catch(response => {
toast.show('error');
});
}
return (
<View
@ -40,12 +55,28 @@ export default function NotifElementLocal({title,content}:{title:string;content:
justifyContent: 'space-between',
alignItems: 'center',
}}>
<Card style={{width:"100%"}} onPress={onCopy}>
<Card.Title title={title} right={() =>
<Button mode="contained" onPress={() => sendToRemote()} >
<IconVector name="paper-plane" size={20} color="black" />
</Button>
}
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={coords}>
<Menu.Item onPress={() => {}} title="View" />
<Menu.Item onPress={() => {}} title="Share" />
<Menu.Item onPress={() => {}} title="Delete" />
</Menu>
<Card
style={{width: '100%'}}
onPressIn={evt =>
setCoords({x: evt.nativeEvent.pageX, y: evt.nativeEvent.pageY})
}
onPress={onCopy}
onLongPress={() => setVisible(true)}>
<Card.Title
title={title}
right={() => (
<Button mode="contained" onPress={() => sendToRemote()}>
<IconVector name="paper-plane" size={20} color="black" />
</Button>
)}
/>
<Card.Content>
<Text variant="bodyMedium">{content}</Text>
@ -54,5 +85,3 @@ export default function NotifElementLocal({title,content}:{title:string;content:
</View>
);
}

View File

@ -1,34 +1,69 @@
import { View } from 'react-native';
import {View} from 'react-native';
import * as Clipboard from 'expo-clipboard';
import { useToast } from "react-native-toast-notifications";
import { Card, Text, Button } from 'react-native-paper';
import {useToast} from 'react-native-toast-notifications';
import {Card, Text, Menu} from 'react-native-paper';
import {useState} from 'react';
export default function NotifElementRemote({title,content,timestamp,deviceName}:{title:string;content:string;timestamp:number;deviceName:string}){
export default function NotifElementRemote({
title,
content,
timestamp,
deviceName,
}: {
title: string;
content: string;
timestamp: number;
deviceName: string;
}) {
const [visible, setVisible] = useState(false);
const [coords, setCoords] = useState({x: 0, y: 0});
const toast = useToast();
function onCopy() {
Clipboard.setStringAsync(content)
.then(()=>{
toast.show('copied "'+content+'" into the clipboard');
});
Clipboard.setStringAsync(content).then(() => {
toast.show('copied "' + content + '" into the clipboard');
});
}
const date= new Date(timestamp*1000);
return(
<View style={{flex:1,
padding:10,
width:"100%",
flexDirection:'row',
justifyContent:'center',
alignItems:'center'}}>
<Card style={{width:"100%"}} onPress={onCopy} >
<Card.Title title={title}/>
const date = new Date(timestamp * 1000);
return (
<View
style={{
flex: 1,
padding: 10,
width: '100%',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}>
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={coords}>
<Menu.Item onPress={() => {}} title="View" />
<Menu.Item onPress={() => {}} title="Share" />
<Menu.Item onPress={() => {}} title="Delete" />
</Menu>
<Card
style={{width: '100%'}}
onPressIn={evt =>
setCoords({x: evt.nativeEvent.pageX, y: evt.nativeEvent.pageY})
}
onPress={onCopy}
onLongPress={() => setVisible(true)}>
<Card.Title title={title} />
<Card.Content>
<Text variant="bodyMedium">{content}</Text>
<Text variant="bodyMedium">{date.getHours() + ":" + date.getMinutes() + ", "+ date.toDateString()}</Text>
<Text variant="bodyMedium">
{date.getHours() +
':' +
date.getMinutes() +
', ' +
date.toDateString()}
</Text>
<Text variant="bodyMedium">{deviceName}</Text>
</Card.Content>
</Card>
</View>);
</Card>
</View>
);
}

View File

@ -1,23 +1,40 @@
import React from 'react';
import {FlatList, ScrollView} from 'react-native';
import { nanoid } from '@reduxjs/toolkit';
import {nanoid} from '@reduxjs/toolkit';
import NotifElementLocal from './NotifElementLocal';
import NotifElementRemote from './NotifElementRemote';
export default function NotifList({type,notifs}:{type:string,notifs:Array<object>}) {
if (type === 'local') {
return <FlatList
data={notifs}
renderItem={({item}) => <NotifElementLocal title={item.title} content={item.content} />}
keyExtractor={item => nanoid()}
/>
} else {
return <FlatList
data={notifs}
renderItem={({item}) => <NotifElementRemote title={item.title} content={item.content} deviceName={item.device_name} timestamp={item.timestamp}/>}
keyExtractor={item => nanoid()}
/>
;
}
export default function NotifList({
type,
notifs,
}: {
type: string;
notifs: Array<object>;
}) {
if (type === 'local') {
return (
<FlatList
data={notifs}
renderItem={({item}) => (
<NotifElementLocal title={item.title} content={item.content} />
)}
keyExtractor={item => nanoid()}
/>
);
} else {
return (
<FlatList
data={notifs}
renderItem={({item}) => (
<NotifElementRemote
title={item.title}
content={item.content}
deviceName={item.device_name}
timestamp={item.timestamp}
/>
)}
keyExtractor={item => nanoid()}
/>
);
}
}

View File

@ -1,58 +1,72 @@
import React from "react";
import { useWindowDimensions, ScrollView, View } from "react-native";
import { Searchbar, Button } from "react-native-paper"
import NotifViewLocal from "./NotifViewLocal";
import NotifViewRemote from "./NotifViewRemote";
import { ps } from "../../utils";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
import React from 'react';
import {useWindowDimensions, ScrollView, View} from 'react-native';
import {Searchbar, Button} from 'react-native-paper';
import NotifViewLocal from './NotifViewLocal';
import NotifViewRemote from './NotifViewRemote';
import {ps} from '../../utils';
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
export default function NotifView(){
export default function NotifView() {
const [searchQuery, setSearchQuery] = React.useState('');
const {height, width} = useWindowDimensions();
const Tab = createMaterialTopTabNavigator();
let layout = ""
let layout = '';
if (width < 600) layout = "compact";
else if (width < 1200 ) layout = "medium";
else layout = "expanded";
return ( <>
<View style={{flexDirection:"row",justifyContent:"center",alignItems:"center", gap:5, margin:ps(4)}}>
{layout == "compact" ?
<Button children={<></>} icon="dots-vertical" mode="contained" style={{width:"auto"}} onPress={() => console.log('Pressed')}/>
: <></>}
<Searchbar
placeholder="Notifications"
onChangeText={setSearchQuery}
value={searchQuery}
if (width < 600) layout = 'compact';
else if (width < 1200) layout = 'medium';
else layout = 'expanded';
return (
<>
<View
style={{
flex:1
}}
/>
</View>
{
layout == "compact"? (
<Tab.Navigator tabBarPosition="bottom">
<Tab.Screen name="Local" options={{title: 'local'}}>
{() => (
<NotifViewLocal/>
)}
</Tab.Screen>
<Tab.Screen name="Remote" options={{title: 'distant'}}>
{()=> (
<NotifViewRemote/>
)}
</Tab.Screen>
</Tab.Navigator>
):(
<ScrollView contentContainerStyle={{flexDirection:"row",justifyContent:"center",height:"100%",padding:ps(30)}}>
<NotifViewLocal/>
<NotifViewRemote/>
</ScrollView>
)
}
</>
)
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: 5,
margin: ps(4),
}}>
{layout == 'compact' ? (
<Button
children={<></>}
icon="dots-vertical"
mode="contained"
style={{width: 'auto'}}
onPress={() => console.log('Pressed')}
/>
) : (
<></>
)}
<Searchbar
placeholder="Notifications"
onChangeText={setSearchQuery}
value={searchQuery}
style={{
flex: 1,
}}
/>
</View>
{layout == 'compact' ? (
<Tab.Navigator tabBarPosition="bottom">
<Tab.Screen name="Local" options={{title: 'local'}}>
{() => <NotifViewLocal />}
</Tab.Screen>
<Tab.Screen name="Remote" options={{title: 'distant'}}>
{() => <NotifViewRemote />}
</Tab.Screen>
</Tab.Navigator>
) : (
<ScrollView
contentContainerStyle={{
flexDirection: 'row',
justifyContent: 'center',
height: '100%',
padding: ps(30),
}}>
<NotifViewLocal />
<NotifViewRemote />
</ScrollView>
)}
</>
);
}

View File

@ -1,62 +1,67 @@
import React from 'react';
import {ScrollView, View, Text, useWindowDimensions} from 'react-native';
import { Button } from 'react-native-paper';
import {Button} from 'react-native-paper';
import NotifList from './NotifList';
import { useDispatch } from 'react-redux';
import { localClipAddToList, localNotifAddToList } from '../../redux/reducers';
import { useToast } from 'react-native-toast-notifications';
import {useDispatch} from 'react-redux';
import {localClipAddToList, localNotifAddToList} from '../../redux/reducers';
import {useToast} from 'react-native-toast-notifications';
import * as Clipboard from 'expo-clipboard';
import { ps } from '../../utils';
import { store } from '../../redux/store';
import {ps} from '../../utils';
import {store} from '../../redux/store';
export default function NotifViewLocal({}){
const [notifs, setNotifs] = React.useState(store.getState().localNotif.localNotif);
export default function NotifViewLocal({}) {
const [notifs, setNotifs] = React.useState(
store.getState().localNotif.localNotif,
);
const dispatch = useDispatch();
const toast = useToast();
const {height,width} = useWindowDimensions();
const {height, width} = useWindowDimensions();
function getSignOutBtn() {
return <Button mode="elevated" onPress={() => {}}>Sign out</Button>
return (
<Button mode="elevated" onPress={() => {}}>
Sign out
</Button>
);
}
async function addToLocal(dispatch) {
Clipboard.getStringAsync()
.then(value =>{
let newNotif = {"title":"placeholder title","content":"placeholder content"};
console.log(value);
dispatch(localNotifAddToList(newNotif));
setNotifs([...notifs,newNotif]);
toast.show('added "'+value+'" into history');
})
.catch((error)=>{
console.log(error);
toast.show("could not retreive last notification :(")
})
.then(value => {
let newNotif = {
title: 'placeholder title',
content: 'placeholder content',
};
console.log(value);
dispatch(localNotifAddToList(newNotif));
setNotifs([...notifs, newNotif]);
toast.show('added "' + value + '" into history');
})
.catch(error => {
console.log(error);
toast.show('could not retreive last notification :(');
});
}
return (
<View style={{
width:"100%",
height:"100%",
flex:1,
margin: width > 600 ? ps(10) : 0
}}>
<View
style={{
width: '100%',
height: '100%',
flex: 1,
margin: width > 600 ? ps(10) : 0,
}}>
<Button
mode="elevated"
onPress={() => {
console.log("TODO");
dispatch(addToLocal);
}}
>
importer la derniere notification
</Button>
mode="elevated"
onPress={() => {
console.log('TODO');
dispatch(addToLocal);
}}>
importer la derniere notification
</Button>
<ScrollView>
<NotifList
type={"local"}
notifs={notifs}
/>
<NotifList type={'local'} notifs={notifs} />
</ScrollView>
</View>
);
</View>
);
}

View File

@ -1,48 +1,56 @@
import React from 'react';
import axios from 'axios';
import { ScrollView,View, Text, useWindowDimensions } from 'react-native';
import {ScrollView, View, Text, useWindowDimensions} from 'react-native';
import NotifListfrom from './NotifList';
import { store } from '../../redux/store';
import { useToast } from 'react-native-toast-notifications';
import { Button } from 'react-native-paper';
import { ps } from '../../utils';
import {store} from '../../redux/store';
import {useToast} from 'react-native-toast-notifications';
import {Button} from 'react-native-paper';
import {ps} from '../../utils';
import NotifList from './NotifList';
import { useDispatch } from 'react-redux';
import { remoteNotifAddToList } from '../../redux/reducers';
import {useDispatch} from 'react-redux';
import {remoteNotifAddToList} from '../../redux/reducers';
export default function NotifViewRemote(){
const [clips,setClips] = React.useState(store.getState().remoteNotif.remoteNotif);
export default function NotifViewRemote() {
const [clips, setClips] = React.useState(
store.getState().remoteNotif.remoteNotif,
);
const toast = useToast();
const dispatch = useDispatch();
const {height,width} = useWindowDimensions();
const {height, width} = useWindowDimensions();
async function getNotif(dispatch) {
axios.get("http://notifysync.simailadjalim.fr/notification?token="+store.getState().user.token)
.then((response,status) => {
let remoteNotif = Object.values(response["data"]['notifications']);
axios
.get(
'http://notifysync.simailadjalim.fr/notification?token=' +
store.getState().user.token,
)
.then((response, status) => {
let remoteNotif = Object.values(response['data']['notifications']);
setClips(remoteNotif);
dispatch(remoteNotifAddToList(remoteNotif));
toast.show("fetched latest notifications from remote");
toast.show('fetched latest notifications from remote');
})
.catch(response =>{
.catch(response => {
console.log(response);
toast.show("failed to fetch latest notifications");
toast.show('failed to fetch latest notifications');
});
}
return <View style={{
width:"100%",
height:"100%",
flex:1,
margin: width > 600 ? ps(10) : 0
}}>
<Button mode="elevated" onPress={() => dispatch(getNotif)}>
Refresh
</Button>
<ScrollView>
<NotifList type="remote" notifs={clips} />
</ScrollView>
</View>;
return (
<View
style={{
width: '100%',
height: '100%',
flex: 1,
margin: width > 600 ? ps(10) : 0,
}}>
<Button mode="elevated" onPress={() => dispatch(getNotif)}>
Refresh
</Button>
<ScrollView>
<NotifList type="remote" notifs={clips} />
</ScrollView>
</View>
);
}

View File

@ -1,35 +1,42 @@
import { Platform, View, useWindowDimensions } from "react-native";
import SignIn from "../components/auth/SignIn";
import SignUp from "../components/auth/SignUp";
import {Platform, View, useWindowDimensions} from 'react-native';
import SignIn from '../components/auth/SignIn';
import SignUp from '../components/auth/SignUp';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { ps } from "../utils";
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
import {ps} from '../utils';
export default function AuthPage(){
export default function AuthPage() {
const {height, width} = useWindowDimensions();
const Tab = createMaterialTopTabNavigator();
if (width > 700){
if (width > 700) {
return (
<View style={{flexDirection:"row",justifyContent:"center",alignItems:"center",height:"100%",padding:ps(30)}}>
<SignIn/>
<SignUp/>
</View>
);}
else{
return(
<Tab.Navigator>
<Tab.Screen
children={() => <SignIn/>}
name="Login"
options={{title: 'Connexion'}}
/>
<Tab.Screen
children={() => <SignUp/>}
name="Register"
options={{title: 'Créer un compte'}}
/>
</Tab.Navigator>
);
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
padding: ps(30),
}}>
<SignIn />
<SignUp />
</View>
);
} else {
return (
<Tab.Navigator>
<Tab.Screen
children={() => <SignIn />}
name="Login"
options={{title: 'Connexion'}}
/>
<Tab.Screen
children={() => <SignUp />}
name="Register"
options={{title: 'Créer un compte'}}
/>
</Tab.Navigator>
);
}
}

View File

@ -1,19 +1,25 @@
import React from "react";
import { Drawer as DrawerLayout } from 'react-native-drawer-layout';
import { Button, Drawer} from 'react-native-paper';
import { Platform, View,StyleSheet, useWindowDimensions } from "react-native";
import { Modal, Text, Portal } from 'react-native-paper';
import { useDispatch } from 'react-redux';
import { disconnect, localClipClear, localNotifClear, remoteClipClear, remoteNotifClear } from "../redux/reducers";
import { ReactNavigationDracula as t } from "../themes";
import ClipView from "../components/clip/ClipView";
import Settings from "./Settings";
import NotifView from "../components/notif/NotifView";
import React from 'react';
import {Drawer as DrawerLayout} from 'react-native-drawer-layout';
import {Button, Drawer} from 'react-native-paper';
import {Platform, View, StyleSheet, useWindowDimensions} from 'react-native';
import {Modal, Text, Portal} from 'react-native-paper';
import {useDispatch} from 'react-redux';
import {
disconnect,
localClipClear,
localNotifClear,
remoteClipClear,
remoteNotifClear,
} from '../redux/reducers';
import {ReactNavigationDracula as t} from '../themes';
import ClipView from '../components/clip/ClipView';
import Settings from './Settings';
import NotifView from '../components/notif/NotifView';
const styles = StyleSheet.create({
modal: {
display:"flex",
flexDirection:"column",
display: 'flex',
flexDirection: 'column',
padding: 10,
gap: 10,
alignItems: 'center',
@ -21,168 +27,171 @@ const styles = StyleSheet.create({
},
});
export default function ClipPage(){
export default function ClipPage() {
const [open, setOpen] = React.useState(false);
const [visible, setVisible] = React.useState(false);
const [active, setActive] = React.useState('clips');
const dispatch = useDispatch()
const dispatch = useDispatch();
const hideModal = () => setVisible(false);
const containerStyle = {backgroundColor: 'white', padding: 20};
const {height, width} = useWindowDimensions();
function signout(){
dispatch(localClipClear())
dispatch(remoteClipClear())
dispatch(localNotifClear())
dispatch(remoteNotifClear())
dispatch(disconnect())
function signout() {
dispatch(localClipClear());
dispatch(remoteClipClear());
dispatch(localNotifClear());
dispatch(remoteNotifClear());
dispatch(disconnect());
}
let layout = ""
if (width < 600) layout = "compact";
else if (width < 1200 ) layout = "medium";
else layout = "expanded";
let layout = '';
if (width < 600) layout = 'compact';
else if (width < 1200) layout = 'medium';
else layout = 'expanded';
let style = {};
if (layout == "medium"){
if (layout == 'medium') {
style = StyleSheet.create({
drawer: {
backgroundColor: t.colors.background,
width : 100
}
})
width: 100,
},
});
} else {
style = StyleSheet.create({
drawer : {
backgroundColor: t.colors.background
}
})
drawer: {
backgroundColor: t.colors.background,
},
});
}
let page;
if (active == "clips") page = <ClipView/>;
if (active == "notif") page = <NotifView/>;
if (active == "settings") page = <Settings/>;
if (active == 'clips') page = <ClipView />;
if (active == 'notif') page = <NotifView />;
if (active == 'settings') page = <Settings />;
return (<View style={{
width:"100%",
height:"100%",
paddingTop: Platform.OS == "android" ? 30 : 0 }}>
<Portal>
<Modal
visible={visible}
onDismiss={hideModal}
contentContainerStyle={containerStyle}
style={styles.modal}
>
<Text>Do you really want to sign out?</Text>
<Button mode="contained" onPress={hideModal}>
no
</Button>
<Button mode="contained-tonal" onPress={()=> signout()}>
yes
</Button>
</Modal>
</Portal>
<DrawerLayout
swipeEdgeWidth={70}
drawerType={layout == "compact" ? "slide":"permanent"}
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
drawerStyle={style.drawer}
renderDrawerContent={() => {
if (layout != "medium"){
return <>
<Drawer.Section title=" ">
<Drawer.Item
icon="clipboard-arrow-down"
label="Clipboards"
active={active === 'clips'}
onPress={() => {
setActive('clips');
setOpen(false)
}}
/>
<Drawer.Item
icon="clipboard-arrow-down"
label="Notifications"
active={active === 'notif'}
onPress={() => {
setActive('notif');
setOpen(false)
}}
/>
<Drawer.Item
icon="cog"
label="Settings"
active={active === 'settings'}
onPress={() => {
setActive('settings');
setOpen(false)
}}
/>
</Drawer.Section>
<Drawer.Section>
<Drawer.Item
icon="door"
active={active === 'third'}
onPress={() => setVisible(true)}
label="Sign out"
/>
</Drawer.Section>
</>
}else{
return <View style={{alignItems:"center", height:"100%"}}>
<Drawer.Section title=" ">
<Drawer.CollapsedItem
focusedIcon="clipboard-arrow-down"
unfocusedIcon="clipboard-arrow-down-outline"
label="Clipboards"
active={active === 'clips'}
onPress={() => {
setActive('clips');
setOpen(false)
}}
/>
<Drawer.CollapsedItem
focusedIcon="clipboard-arrow-down"
unfocusedIcon="clipboard-arrow-down-outline"
label="Notifications"
active={active === 'notif'}
onPress={() => {
setActive('notif');
setOpen(false)
}}
/>
<Drawer.CollapsedItem
focusedIcon="cog"
unfocusedIcon="cog-outline"
label="Settings"
active={active === 'settings'}
onPress={() => {
setActive('settings');
setOpen(false)
}}
/>
</Drawer.Section>
<Drawer.Section>
<Drawer.CollapsedItem
focusedIcon="door-open"
unfocusedIcon="door"
label="Sign out"
onPress={() => setVisible(true)}
/>
</Drawer.Section>
</View>
}
}}
>
{page}
</DrawerLayout>
</View>
return (
<View
style={{
width: '100%',
height: '100%',
paddingTop: Platform.OS == 'android' ? 30 : 0,
}}>
<Portal>
<Modal
visible={visible}
onDismiss={hideModal}
contentContainerStyle={containerStyle}
style={styles.modal}>
<Text>Do you really want to sign out?</Text>
<Button mode="contained" onPress={hideModal}>
no
</Button>
<Button mode="contained-tonal" onPress={() => signout()}>
yes
</Button>
</Modal>
</Portal>
<DrawerLayout
swipeEdgeWidth={70}
drawerType={layout == 'compact' ? 'slide' : 'permanent'}
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
drawerStyle={style.drawer}
renderDrawerContent={() => {
if (layout != 'medium') {
return (
<>
<Drawer.Section title=" ">
<Drawer.Item
icon="clipboard-arrow-down"
label="Clipboards"
active={active === 'clips'}
onPress={() => {
setActive('clips');
setOpen(false);
}}
/>
<Drawer.Item
icon="clipboard-arrow-down"
label="Notifications"
active={active === 'notif'}
onPress={() => {
setActive('notif');
setOpen(false);
}}
/>
<Drawer.Item
icon="cog"
label="Settings"
active={active === 'settings'}
onPress={() => {
setActive('settings');
setOpen(false);
}}
/>
</Drawer.Section>
<Drawer.Section>
<Drawer.Item
icon="door"
active={active === 'third'}
onPress={() => setVisible(true)}
label="Sign out"
/>
</Drawer.Section>
</>
);
} else {
return (
<View style={{alignItems: 'center', height: '100%'}}>
<Drawer.Section title=" ">
<Drawer.CollapsedItem
focusedIcon="clipboard-arrow-down"
unfocusedIcon="clipboard-arrow-down-outline"
label="Clipboards"
active={active === 'clips'}
onPress={() => {
setActive('clips');
setOpen(false);
}}
/>
<Drawer.CollapsedItem
focusedIcon="clipboard-arrow-down"
unfocusedIcon="clipboard-arrow-down-outline"
label="Notifications"
active={active === 'notif'}
onPress={() => {
setActive('notif');
setOpen(false);
}}
/>
<Drawer.CollapsedItem
focusedIcon="cog"
unfocusedIcon="cog-outline"
label="Settings"
active={active === 'settings'}
onPress={() => {
setActive('settings');
setOpen(false);
}}
/>
</Drawer.Section>
<Drawer.Section>
<Drawer.CollapsedItem
focusedIcon="door-open"
unfocusedIcon="door"
label="Sign out"
onPress={() => setVisible(true)}
/>
</Drawer.Section>
</View>
);
}
}}>
{page}
</DrawerLayout>
</View>
);
}

View File

@ -1,23 +1,26 @@
import { View, Text } from "react-native";
import { Button } from 'react-native-paper';
import { ps } from "../utils";
import { ReactNavigationDracula as t } from "../themes";
import {View, Text} from 'react-native';
import {Button} from 'react-native-paper';
import {ps} from '../utils';
import {ReactNavigationDracula as t} from '../themes';
export default function IntroPage({navigation}){
return(
<View style={{
alignItems:"center",
justifyContent:"center",
gap:ps(6),
flex:1,
margin:ps(16),
flexDirection:'column'}}>
<Text style={{
fontSize:20,
textAlign:"center",
color: t.colors.text
export default function IntroPage({navigation}) {
return (
<View
style={{
alignItems: 'center',
justifyContent: 'center',
gap: ps(6),
flex: 1,
margin: ps(16),
flexDirection: 'column',
}}>
Salut, bienvenue dans ClipSync :) connecte toi pour commencer
<Text
style={{
fontSize: 20,
textAlign: 'center',
color: t.colors.text,
}}>
Salut, bienvenue dans ClipSync :) connecte toi pour commencer
</Text>
<Button mode="contained" onPress={() => navigation.navigate('SignIn')}>
Connecte moi le sang

View File

@ -1,26 +1,29 @@
import { ScrollView } from "react-native";
import { View, Text } from "react-native";
import { Button } from 'react-native-paper';
import { ps } from "../utils";
import { ReactNavigationDracula as t } from "../themes";
import {ScrollView} from 'react-native';
import {View, Text} from 'react-native';
import {Button} from 'react-native-paper';
import {ps} from '../utils';
import {ReactNavigationDracula as t} from '../themes';
export default function Settings(){
return(
<View style={{
width: "100%",
height: "100%",
alignItems:"center",
justifyContent:"center",
gap:ps(6),
flex:1,
flexDirection:'column'}}>
<Text style={{
fontSize:20,
textAlign:"center",
color: t.colors.text
export default function Settings() {
return (
<View
style={{
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
gap: ps(6),
flex: 1,
flexDirection: 'column',
}}>
Pas encore pret mais on y travaille .w.
<Text
style={{
fontSize: 20,
textAlign: 'center',
color: t.colors.text,
}}>
Pas encore pret mais on y travaille .w.
</Text>
</View>)
</View>
);
}

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { Button, Text } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
import {Button, Text} from 'react-native';
import {Drawer} from 'react-native-drawer-layout';
export default function DrawerExample() {
const [open, setOpen] = React.useState(false);
@ -12,10 +12,9 @@ export default function DrawerExample() {
onClose={() => setOpen(false)}
renderDrawerContent={() => {
return <Text>Drawer content</Text>;
}}
>
}}>
<Button
onPress={() => setOpen((prevOpen) => !prevOpen)}
onPress={() => setOpen(prevOpen => !prevOpen)}
title={`${open ? 'Close' : 'Open'} drawer`}
/>
</Drawer>

View File

@ -1 +0,0 @@

View File

@ -1,12 +1,12 @@
import { applyMiddleware,createSlice } from "@reduxjs/toolkit";
import {applyMiddleware, createSlice} from '@reduxjs/toolkit';
console.log(applyMiddleware);
export const userSlice = createSlice({
name: 'user',
initialState: {
token: "",
username:"",
token: '',
username: '',
},
reducers: {
login: (state, action) => {
@ -14,12 +14,11 @@ export const userSlice = createSlice({
state.username = action.payload.username;
},
disconnect: state => {
state.token = "";
state.username = "";
}
state.token = '';
state.username = '';
},
},
})
});
export const {login, disconnect} = userSlice.actions;
@ -31,22 +30,23 @@ export const {login, disconnect} = userSlice.actions;
export const localClipsSlice = createSlice({
name: 'localClips',
initialState: {
localClip:[],
localClip: [],
},
reducers: {
localClipAddToList: (state,action) => {
state.localClip = [...state.localClip,action.payload]
localClipAddToList: (state, action) => {
state.localClip = [...state.localClip, action.payload];
},
localClipRemoveFromList: (state,action) => {
state.localClip = state.localClip.filter(e => e !== action.payload)
localClipRemoveFromList: (state, action) => {
state.localClip = state.localClip.filter(e => e !== action.payload);
},
localClipClear : (state,action) =>{
state.localClip = []
}
}
})
localClipClear: (state, action) => {
state.localClip = [];
},
},
});
export const {localClipAddToList, localClipRemoveFromList, localClipClear} = localClipsSlice.actions;
export const {localClipAddToList, localClipRemoveFromList, localClipClear} =
localClipsSlice.actions;
// Remote clip structure
// [
@ -56,62 +56,66 @@ export const {localClipAddToList, localClipRemoveFromList, localClipClear} = loc
export const remoteClipsSlice = createSlice({
name: 'remoteClips',
initialState: {
remoteClip:[],
remoteClip: [],
},
reducers: {
remoteClipAddToList: (state,action) => {
remoteClipAddToList: (state, action) => {
console.log(action.payload);
state.remoteClip = action.payload
state.remoteClip = action.payload;
},
remoteClipRemoveFromList: (state,action) => {
state.remoteClip = state.remoteClip.filter(e => e !== action.payload);
remoteClipRemoveFromList: (state, action) => {
state.remoteClip = state.remoteClip.filter(e => e !== action.payload);
},
remoteClipClear : (state,action) =>{
state.remoteClip = []
remoteClipClear: (state, action) => {
state.remoteClip = [];
},
}
})
export const {remoteClipAddToList, remoteClipRemoveFromList, remoteClipClear} = remoteClipsSlice.actions;
},
});
export const {remoteClipAddToList, remoteClipRemoveFromList, remoteClipClear} =
remoteClipsSlice.actions;
export const localNotifsSlice = createSlice({
name: 'localNotifs',
initialState: {
localNotif:[],
localNotif: [],
},
reducers: {
localNotifAddToList: (state,action) => {
state.localNotif = [...state.localNotif,action.payload]
localNotifAddToList: (state, action) => {
state.localNotif = [...state.localNotif, action.payload];
},
localNotifRemoveFromList: (state,action) => {
state.localNotif = state.localNotif.filter(e => e !== action.payload)
localNotifRemoveFromList: (state, action) => {
state.localNotif = state.localNotif.filter(e => e !== action.payload);
},
localNotifClear : (state,action) =>{
state.localNotif = []
}
}
})
localNotifClear: (state, action) => {
state.localNotif = [];
},
},
});
export const {localNotifAddToList, localNotifRemoveFromList, localNotifClear} = localNotifsSlice.actions;
export const {localNotifAddToList, localNotifRemoveFromList, localNotifClear} =
localNotifsSlice.actions;
export const remoteNotifsSlice = createSlice({
name: 'remoteNotifs',
initialState: {
remoteNotif:[],
remoteNotif: [],
},
reducers: {
remoteNotifAddToList: (state,action) => {
state.remoteNotif = [...action.payload]
remoteNotifAddToList: (state, action) => {
state.remoteNotif = [...action.payload];
},
remoteNotifRemoveFromList: (state,action) => {
state.remoteNotif = state.remoteNotif.filter(e => e !== action.payload);
remoteNotifRemoveFromList: (state, action) => {
state.remoteNotif = state.remoteNotif.filter(e => e !== action.payload);
},
remoteNotifClear : (state,action) =>{
state.remoteNotif = []
}
}
})
remoteNotifClear: (state, action) => {
state.remoteNotif = [];
},
},
});
export const {remoteNotifAddToList, remoteNotifRemoveFromList, remoteNotifClear} = remoteNotifsSlice.actions;
export const {
remoteNotifAddToList,
remoteNotifRemoveFromList,
remoteNotifClear,
} = remoteNotifsSlice.actions;

View File

@ -1,29 +1,29 @@
import { applyMiddleware,configureStore } from '@reduxjs/toolkit'
import { combineReducers } from '@reduxjs/toolkit';
import { userSlice, localClipsSlice ,remoteClipsSlice } from './reducers';
import { localNotifsSlice,remoteNotifsSlice } from './reducers';
import { persistStore, persistReducer } from 'redux-persist'
import {applyMiddleware, configureStore} from '@reduxjs/toolkit';
import {combineReducers} from '@reduxjs/toolkit';
import {userSlice, localClipsSlice, remoteClipsSlice} from './reducers';
import {localNotifsSlice, remoteNotifsSlice} from './reducers';
import {persistStore, persistReducer} from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
const persistConfig = {
key: "root",
key: 'root',
storage: AsyncStorage,
};
const rootReducer = combineReducers({
user:userSlice.reducer,
localClip:localClipsSlice.reducer,
remoteClip:remoteClipsSlice.reducer,
localNotif:localNotifsSlice.reducer,
remoteNotif:remoteNotifsSlice.reducer
user: userSlice.reducer,
localClip: localClipsSlice.reducer,
remoteClip: remoteClipsSlice.reducer,
localNotif: localNotifsSlice.reducer,
remoteNotif: remoteNotifsSlice.reducer,
});
const persistedReducer = persistReducer(persistConfig, rootReducer)
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer
})
reducer: persistedReducer,
});
const persistor = persistStore(store)
const persistor = persistStore(store);
export {store, persistor};
export {store, persistor};

View File

@ -1,4 +1,4 @@
import { MD3DarkTheme, Surface } from 'react-native-paper';
import {MD3DarkTheme, Surface} from 'react-native-paper';
export const Material3Dracula = {
...MD3DarkTheme,
@ -10,8 +10,8 @@ export const Material3Dracula = {
surface: '#44475a',
elevation: {
...MD3DarkTheme.colors.elevation,
level1: "#44475A"
}
level1: '#44475A',
},
},
};

View File

@ -1,11 +1,12 @@
import { PixelRatio,StyleSheet } from "react-native";
import {PixelRatio, StyleSheet} from 'react-native';
export const ps = (lp:number) => PixelRatio.getPixelSizeForLayoutSize(PixelRatio.roundToNearestPixel(lp));
export const ps = (lp: number) =>
PixelRatio.getPixelSizeForLayoutSize(PixelRatio.roundToNearestPixel(lp));
export const style = StyleSheet.create({
default : {
default: {
margin: PixelRatio.getPixelSizeForLayoutSize(8),
marginTop : PixelRatio.getPixelSizeForLayoutSize(8),
marginLeft : PixelRatio.getPixelSizeForLayoutSize(8)
}
})
marginTop: PixelRatio.getPixelSizeForLayoutSize(8),
marginLeft: PixelRatio.getPixelSizeForLayoutSize(8),
},
});