🎨 style(App.tsx, SignIn.tsx, SignUp.tsx, ClipElementLocal.tsx, ClipElementRemote.tsx, ClipList.tsx, ClipView.tsx, ClipViewLocal.tsx, ClipViewRemote.tsx, Auth.tsx, Clips.tsx, Intro.tsx, Settings.tsx): Improve UI/UX by adding responsive design and theme support
🔧 refactor(App.tsx, SignIn.tsx, SignUp.tsx, ClipElementLocal.tsx, ClipElementRemote.tsx, ClipList.tsx, ClipView.tsx, ClipViewLocal.tsx, ClipViewRemote.tsx, Auth.tsx, Clips.tsx, Intro.tsx, Settings.tsx): Refactor code for better readability and maintainability 🔥 remove(ClipElementLocal.tsx, ClipElementRemote.tsx, ClipList.tsx): Remove unused imports and props ✨ feat(App.tsx, SignIn.tsx, SignUp.tsx, ClipElementLocal.tsx, ClipElementRemote.tsx, ClipList.tsx, ClipView.tsx, ClipViewLocal.tsx, ClipViewRemote.tsx, Auth.tsx, Clips.tsx, Intro.tsx, Settings.tsx, themes.ts, utils.ts): Add new features such as theme support, responsive design, and utility functions
This commit is contained in:
parent
b969b4f36b
commit
ba5d2697c5
21
App.tsx
21
App.tsx
@ -1,7 +1,7 @@
|
|||||||
import 'react-native-gesture-handler';
|
import 'react-native-gesture-handler';
|
||||||
// ^ le bouge pas ca casse tout ^
|
// ^ le bouge pas ca casse tout ^
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';
|
||||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { store } from './src/redux/store';
|
import { store } from './src/redux/store';
|
||||||
@ -11,25 +11,33 @@ import AuthPage from './src/pages/Auth';
|
|||||||
import ClipPage from './src/pages/Clips';
|
import ClipPage from './src/pages/Clips';
|
||||||
import IntroPage from './src/pages/Intro';
|
import IntroPage from './src/pages/Intro';
|
||||||
import { StatusBar } from 'expo-status-bar';
|
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();
|
const Stack = createNativeStackNavigator();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function App(){
|
function App(){
|
||||||
const [token,setToken] = useState("");
|
const [token,setToken] = useState("");
|
||||||
const [username,setUsername] = useState("");
|
const [username,setUsername] = useState("");
|
||||||
|
|
||||||
|
const {height,width} = useWindowDimensions();
|
||||||
|
console.log(width);
|
||||||
|
console.log(PixelRatio.get())
|
||||||
|
|
||||||
store.subscribe(()=>{
|
store.subscribe(()=>{
|
||||||
console.log("state Changed .w.");
|
|
||||||
let newToken = store.getState().user.token;
|
let newToken = store.getState().user.token;
|
||||||
setToken(newToken);
|
setToken(newToken);
|
||||||
console.log(store.getState());
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PaperProvider theme={MD3LightTheme}>
|
<PaperProvider theme={Material3Dracula}>
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<StatusBar style="light"/>
|
<StatusBar style="light"/>
|
||||||
<NavigationContainer>
|
<SafeAreaProvider>
|
||||||
|
<NavigationContainer theme={ReactNavigationDracula}>
|
||||||
<Stack.Navigator>
|
<Stack.Navigator>
|
||||||
{
|
{
|
||||||
token !== "" ? (
|
token !== "" ? (
|
||||||
@ -45,6 +53,7 @@ function App(){
|
|||||||
}
|
}
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
|
</SafeAreaProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
</ToastProvider>
|
</ToastProvider>
|
||||||
</PaperProvider>
|
</PaperProvider>
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, Text } from 'react-native';
|
import { View, Text, Platform, useWindowDimensions } from 'react-native';
|
||||||
import { useToast } from "react-native-toast-notifications";
|
import { useToast } from "react-native-toast-notifications";
|
||||||
import { Button, TextInput } from 'react-native-paper';
|
import { Button, TextInput } from 'react-native-paper';
|
||||||
import { login } from '../../redux/reducers';
|
import { login } from '../../redux/reducers';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { ReactNavigationDracula as t } from '../../themes';
|
||||||
|
import { ps } from '../../utils';
|
||||||
|
|
||||||
export default function SignIn(){
|
export default function SignIn(){
|
||||||
const [username, setUsername] = React.useState("");
|
const [username, setUsername] = React.useState("");
|
||||||
@ -12,7 +14,8 @@ export default function SignIn(){
|
|||||||
const [token,setToken] = React.useState("");
|
const [token,setToken] = React.useState("");
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const {height, width} = useWindowDimensions();
|
||||||
|
|
||||||
|
|
||||||
async function signInFunction(dispatch) {
|
async function signInFunction(dispatch) {
|
||||||
axios.post("https://notifysync.simailadjalim.fr/user",{
|
axios.post("https://notifysync.simailadjalim.fr/user",{
|
||||||
@ -32,16 +35,22 @@ export default function SignIn(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return <View style={{
|
return <View style={[{
|
||||||
|
borderRadius:12,
|
||||||
|
height:"100%"
|
||||||
|
},{
|
||||||
flex:1,
|
flex:1,
|
||||||
margin:10,
|
margin:ps(8),
|
||||||
|
padding:ps(8),
|
||||||
|
paddingTop:ps(8),
|
||||||
gap:10,
|
gap:10,
|
||||||
flexDirection:'column',
|
flexDirection:'column',
|
||||||
justifyContent:"center",
|
justifyContent:"center",
|
||||||
alignItems:"center"
|
alignItems:"center",
|
||||||
}}>
|
backgroundColor: width > 600 ? t.colors.card : t.colors.background,
|
||||||
|
}]}>
|
||||||
|
|
||||||
<Text style={{ fontWeight: 'bold', fontSize: 30, color:"black" }}>
|
<Text style={{ fontWeight: 'bold', fontSize: 30, color:t.colors.text }}>
|
||||||
Connexion
|
Connexion
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -50,7 +59,7 @@ export default function SignIn(){
|
|||||||
value={username}
|
value={username}
|
||||||
onChangeText={setUsername}
|
onChangeText={setUsername}
|
||||||
style={{
|
style={{
|
||||||
width:"80%"
|
width: 300
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -59,7 +68,7 @@ export default function SignIn(){
|
|||||||
value={password}
|
value={password}
|
||||||
onChangeText={setPassword}
|
onChangeText={setPassword}
|
||||||
style={{
|
style={{
|
||||||
width:"80%"
|
width: 300
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {View, Text } from 'react-native';
|
import {View, Text, Platform, useWindowDimensions } from 'react-native';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useToast } from "react-native-toast-notifications";
|
import { useToast } from "react-native-toast-notifications";
|
||||||
import { Button, TextInput } from 'react-native-paper';
|
import { Button, TextInput } from 'react-native-paper';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { login } from '../../redux/reducers';
|
import { login } from '../../redux/reducers';
|
||||||
|
import { ReactNavigationDracula as t } from '../../themes';
|
||||||
|
import { ps } from '../../utils';
|
||||||
|
|
||||||
export default function SignUp(){
|
export default function SignUp(){
|
||||||
const [username, setUsername] = React.useState("");
|
const [username, setUsername] = React.useState("");
|
||||||
@ -12,9 +14,10 @@ export default function SignUp(){
|
|||||||
const [confirm, setConfirm] = React.useState("");
|
const [confirm, setConfirm] = React.useState("");
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const {height, width} = useWindowDimensions();
|
||||||
|
|
||||||
function signUpFunction(dispatch) {
|
function signUpFunction(dispatch) {
|
||||||
|
|
||||||
if (confirm != password){
|
if (confirm != password){
|
||||||
toast.show("The password and its confirmation are not the same",{
|
toast.show("The password and its confirmation are not the same",{
|
||||||
type:"warning"
|
type:"warning"
|
||||||
@ -50,14 +53,21 @@ export default function SignUp(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{flex:1,
|
<View style={[{
|
||||||
gap:10,
|
borderRadius:12,
|
||||||
margin:10,
|
height:"100%"
|
||||||
justifyContent:"center",
|
},{
|
||||||
alignItems:"center",
|
flex:1,
|
||||||
flexDirection:'column'
|
margin:ps(8),
|
||||||
}}>
|
padding:ps(8),
|
||||||
<Text style={{fontWeight: 'bold', fontSize: 30 ,color:"black"}}>
|
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
|
Créer un compte
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -66,7 +76,7 @@ export default function SignUp(){
|
|||||||
value={username}
|
value={username}
|
||||||
onChangeText={setUsername}
|
onChangeText={setUsername}
|
||||||
style={{
|
style={{
|
||||||
width:"80%"
|
width:300
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -75,7 +85,7 @@ export default function SignUp(){
|
|||||||
value={password}
|
value={password}
|
||||||
onChangeText={setPassword}
|
onChangeText={setPassword}
|
||||||
style={{
|
style={{
|
||||||
width:"80%"
|
width:300
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
@ -84,7 +94,7 @@ export default function SignUp(){
|
|||||||
value={confirm}
|
value={confirm}
|
||||||
onChangeText={setConfirm}
|
onChangeText={setConfirm}
|
||||||
style={{
|
style={{
|
||||||
width:"80%"
|
width:300
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button mode="contained" onPress={()=>{dispatch(signUpFunction)}}>
|
<Button mode="contained" onPress={()=>{dispatch(signUpFunction)}}>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import {View} from 'react-native';
|
import {View} from 'react-native';
|
||||||
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
||||||
import { Store } from 'redux';
|
|
||||||
import { useToast } from "react-native-toast-notifications";
|
import { useToast } from "react-native-toast-notifications";
|
||||||
import * as Clipboard from 'expo-clipboard';
|
import * as Clipboard from 'expo-clipboard';
|
||||||
import { Avatar, Card, Text } from 'react-native-paper';
|
import { Avatar, Card, Text } from 'react-native-paper';
|
||||||
@ -42,7 +41,7 @@ export default function ClipElementLocal({content}:{content: string}){
|
|||||||
}}>
|
}}>
|
||||||
<Card style={{width:"100%"}} onPress={onCopy}>
|
<Card style={{width:"100%"}} onPress={onCopy}>
|
||||||
<Card.Title title={content} right={() =>
|
<Card.Title title={content} right={() =>
|
||||||
<Button mode="elevated" onPress={() => sendToRemote()} >
|
<Button mode="contained" onPress={() => sendToRemote()} >
|
||||||
<IconVector name="paper-plane" size={20} color="black" />
|
<IconVector name="paper-plane" size={20} color="black" />
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
import IconVector from 'react-native-vector-icons/FontAwesome5';
|
||||||
import { Store } from 'redux';
|
|
||||||
import * as Clipboard from 'expo-clipboard';
|
import * as Clipboard from 'expo-clipboard';
|
||||||
import { useToast } from "react-native-toast-notifications";
|
import { useToast } from "react-native-toast-notifications";
|
||||||
import { Avatar, Card, Text } from 'react-native-paper';
|
import { Card, Text, Button } from 'react-native-paper';
|
||||||
|
|
||||||
export default function ClipElementRemote({content,timestamp,deviceName,store}:{content:string;timestamp:number,deviceName:string;store: Store}){
|
export default function ClipElementRemote({content,timestamp,deviceName}:{content:string;timestamp:number,deviceName:string}){
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
function onCopy() {
|
function onCopy() {
|
||||||
@ -18,19 +17,17 @@ export default function ClipElementRemote({content,timestamp,deviceName,store}:{
|
|||||||
const date= new Date(timestamp*1000);
|
const date= new Date(timestamp*1000);
|
||||||
return(
|
return(
|
||||||
<View style={{flex:1,
|
<View style={{flex:1,
|
||||||
margin:10,
|
padding:10,
|
||||||
|
width:"100%",
|
||||||
flexDirection:'row',
|
flexDirection:'row',
|
||||||
justifyContent:'center',
|
justifyContent:'center',
|
||||||
alignItems:'center'}}>
|
alignItems:'center'}}>
|
||||||
<Card>
|
<Card style={{width:"100%"}} onPress={onCopy} >
|
||||||
|
<Card.Title title={content}/>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<Text variant="titleLarge">{content.length >28 ?content.slice(0,24)+"...":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>
|
<Text variant="bodyMedium">{deviceName}</Text>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
<Card.Actions>
|
|
||||||
<IconVector name="clipboard" size={40} color="black" onPress={() => onCopy()} />
|
|
||||||
</Card.Actions>
|
|
||||||
</Card>
|
</Card>
|
||||||
</View>);
|
</View>);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export default class ClipList extends React.Component<any, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createClipElementLocal(content: string): JSX.Element {
|
createClipElementLocal(content: string): JSX.Element {
|
||||||
return <ClipElementLocal store={this.props.store} content={content} />;
|
return <ClipElementLocal content={content} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
createClipElementRemote(
|
createClipElementRemote(
|
||||||
@ -19,7 +19,6 @@ export default class ClipList extends React.Component<any, any> {
|
|||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<ClipElementRemote
|
<ClipElementRemote
|
||||||
store={this.props.store}
|
|
||||||
content={content}
|
content={content}
|
||||||
deviceName={deviceName}
|
deviceName={deviceName}
|
||||||
timestamp={timestamp}
|
timestamp={timestamp}
|
||||||
|
51
src/components/clip/ClipView.tsx
Normal file
51
src/components/clip/ClipView.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useWindowDimensions, ScrollView } from "react-native";
|
||||||
|
import { Searchbar } 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(){
|
||||||
|
|
||||||
|
const [searchQuery, setSearchQuery] = React.useState('');
|
||||||
|
const {height, width} = useWindowDimensions();
|
||||||
|
|
||||||
|
const Tab = createMaterialTopTabNavigator();
|
||||||
|
let layout = ""
|
||||||
|
|
||||||
|
if (width < 600) layout = "compact";
|
||||||
|
else if (width < 1200 ) layout = "medium";
|
||||||
|
else layout = "expanded";
|
||||||
|
return ( <>
|
||||||
|
|
||||||
|
<Searchbar
|
||||||
|
placeholder="Clipboards"
|
||||||
|
onChangeText={setSearchQuery}
|
||||||
|
value={searchQuery}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
@ -1,18 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {ScrollView, Text} from 'react-native';
|
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 ClipList from './ClipList';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { localAddToList } from '../../redux/reducers';
|
import { localAddToList } from '../../redux/reducers';
|
||||||
import { useToast } from 'react-native-toast-notifications';
|
import { useToast } from 'react-native-toast-notifications';
|
||||||
import * as Clipboard from 'expo-clipboard';
|
import * as Clipboard from 'expo-clipboard';
|
||||||
|
import { ps } from '../../utils';
|
||||||
|
|
||||||
|
|
||||||
export default function ClipViewLocal({}){
|
export default function ClipViewLocal({}){
|
||||||
const [clips, setClips] = React.useState([]);
|
const [clips, setClips] = React.useState([]);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
const {height,width} = useWindowDimensions();
|
||||||
|
|
||||||
|
|
||||||
let title = 'Local Clipboard';
|
let title = 'Local Clipboard';
|
||||||
@ -37,8 +37,13 @@ export default function ClipViewLocal({}){
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<View style={{
|
||||||
<Button
|
width:"100%",
|
||||||
|
height:"100%",
|
||||||
|
flex:1,
|
||||||
|
margin: width > 600 ? ps(10) : 0
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
mode="elevated"
|
mode="elevated"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
dispatch(addToLocal);
|
dispatch(addToLocal);
|
||||||
@ -46,11 +51,13 @@ export default function ClipViewLocal({}){
|
|||||||
>
|
>
|
||||||
Coller depuis le presse papier
|
Coller depuis le presse papier
|
||||||
</Button>
|
</Button>
|
||||||
|
<ScrollView>
|
||||||
<ClipList
|
<ClipList
|
||||||
type={"local"}
|
type={"local"}
|
||||||
clips={clips}
|
clips={clips}
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ScrollView, Text } from 'react-native';
|
import { ScrollView,View, Text, useWindowDimensions } from 'react-native';
|
||||||
import ClipList from './ClipList';
|
import ClipList from './ClipList';
|
||||||
import { store } from '../../redux/store';
|
import { store } from '../../redux/store';
|
||||||
import { useToast } from 'react-native-toast-notifications';
|
import { useToast } from 'react-native-toast-notifications';
|
||||||
import { Button } from 'react-native-paper';
|
import { Button } from 'react-native-paper';
|
||||||
|
import { ps } from '../../utils';
|
||||||
|
|
||||||
|
export default function ClipViewRemote(){
|
||||||
export default function ClipViewRemote({type} :{type:string} ){
|
|
||||||
const [clips,setClips] = React.useState([]);
|
const [clips,setClips] = React.useState([]);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
const {height,width} = useWindowDimensions();
|
||||||
|
|
||||||
function getClips() {
|
function getClips() {
|
||||||
axios.get("http://notifysync.simailadjalim.fr/clipboard?token="+store.getState().user.token)
|
axios.get("http://notifysync.simailadjalim.fr/clipboard?token="+store.getState().user.token)
|
||||||
.then((response,status) => {
|
.then((response,status) => {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
setClips(Object.values(response["data"]['clipboard']));
|
setClips(Object.values(response["data"]['clipboard']));
|
||||||
toast.show("fetched latest clips from remote");
|
toast.show("fetched latest clips from remote");
|
||||||
})
|
})
|
||||||
.catch(response =>{
|
.catch(response =>{
|
||||||
console.log(response);
|
console.log(response);
|
||||||
toast.show("failed to fetch latest clips");
|
toast.show("failed to fetch latest clips");
|
||||||
});
|
});
|
||||||
@ -29,13 +31,18 @@ export default function ClipViewRemote({type} :{type:string} ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
let title = "Remote Clipboard";
|
let title = "Remote Clipboard";
|
||||||
return <>
|
return <View style={{
|
||||||
<ScrollView>
|
width:"100%",
|
||||||
<Button mode="elevated" onPress={getClips}>
|
height:"100%",
|
||||||
Refresh
|
flex:1,
|
||||||
</Button>
|
margin: width > 600 ? ps(10) : 0
|
||||||
<ClipList type={type} clips={clips} />
|
}}>
|
||||||
|
<Button mode="elevated" onPress={getClips}>
|
||||||
|
Refresh
|
||||||
|
</Button>
|
||||||
|
<ScrollView>
|
||||||
|
<ClipList type="remote" clips={clips} />
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</>;
|
</View>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
|
import { Platform, View, useWindowDimensions } from "react-native";
|
||||||
import SignIn from "../components/auth/SignIn";
|
import SignIn from "../components/auth/SignIn";
|
||||||
import SignUp from "../components/auth/SignUp";
|
import SignUp from "../components/auth/SignUp";
|
||||||
|
|
||||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
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();
|
const Tab = createMaterialTopTabNavigator();
|
||||||
|
if (width > 700){
|
||||||
|
return (
|
||||||
|
<View style={{flexDirection:"row",justifyContent:"center",alignItems:"center",height:"100%",padding:ps(30)}}>
|
||||||
|
<SignIn/>
|
||||||
|
<SignUp/>
|
||||||
|
</View>
|
||||||
|
);}
|
||||||
|
else{
|
||||||
return(
|
return(
|
||||||
<Tab.Navigator>
|
<Tab.Navigator>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
@ -19,4 +31,5 @@ export default function AuthPage(){
|
|||||||
/>
|
/>
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ClipViewLocal from "../components/clip/ClipViewLocal";
|
|
||||||
import ClipViewRemote from "../components/clip/ClipViewRemote";
|
|
||||||
import { Drawer as DrawerLayout } from 'react-native-drawer-layout';
|
import { Drawer as DrawerLayout } from 'react-native-drawer-layout';
|
||||||
import { Button, Drawer } from 'react-native-paper';
|
import { Button, Drawer, Searchbar } from 'react-native-paper';
|
||||||
import { store } from "../redux/store";
|
import { Platform, View,StyleSheet, useWindowDimensions, ScrollView } from "react-native";
|
||||||
import { Platform, View,StyleSheet } from "react-native";
|
|
||||||
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
||||||
import { Appbar, Modal, Text, Portal } from 'react-native-paper';
|
import { Appbar, Modal, Text, Portal } from 'react-native-paper';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { disconnect } from "../redux/reducers";
|
import { disconnect } from "../redux/reducers";
|
||||||
|
import { ps } from "../utils";
|
||||||
|
import { ReactNavigationDracula as t } from "../themes";
|
||||||
|
import ClipView from "../components/clip/ClipView";
|
||||||
|
import Settings from "./Settings";
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
modal: {
|
modal: {
|
||||||
@ -24,90 +25,137 @@ const styles = StyleSheet.create({
|
|||||||
export default function ClipPage(){
|
export default function ClipPage(){
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [visible, setVisible] = React.useState(false);
|
||||||
const Tab = createMaterialTopTabNavigator();
|
|
||||||
const [active, setActive] = React.useState('clips');
|
const [active, setActive] = React.useState('clips');
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const showModal = () => setVisible(true);
|
|
||||||
const hideModal = () => setVisible(false);
|
const hideModal = () => setVisible(false);
|
||||||
const containerStyle = {backgroundColor: 'white', padding: 20};
|
const containerStyle = {backgroundColor: 'white', padding: 20};
|
||||||
function signout(){
|
const {height, width} = useWindowDimensions();
|
||||||
setVisible(true);
|
|
||||||
//dispatch(disconnect());
|
let layout = ""
|
||||||
|
|
||||||
|
if (width < 600) layout = "compact";
|
||||||
|
else if (width < 1200 ) layout = "medium";
|
||||||
|
else layout = "expanded";
|
||||||
|
|
||||||
|
|
||||||
|
let style = {};
|
||||||
|
if (layout == "medium"){
|
||||||
|
style = StyleSheet.create({
|
||||||
|
drawer: {
|
||||||
|
backgroundColor: t.colors.background,
|
||||||
|
width : 100
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
style = StyleSheet.create({
|
||||||
|
drawer : {
|
||||||
|
backgroundColor: t.colors.background
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (<>
|
let page;
|
||||||
|
if (active == "clips") page = <ClipView/>;
|
||||||
|
if (active == "notif") page = <ClipView/>;
|
||||||
|
if (active == "settings") page = <Settings/>;
|
||||||
|
|
||||||
|
return (<View style={{
|
||||||
|
width:"100%",
|
||||||
|
height:"100%",
|
||||||
|
paddingTop: Platform.OS == "android" ? 30 : 0 }}>
|
||||||
<Portal>
|
<Portal>
|
||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onDismiss={hideModal}
|
onDismiss={hideModal}
|
||||||
contentContainerStyle={containerStyle}
|
contentContainerStyle={containerStyle}
|
||||||
style={styles.modal}
|
style={styles.modal}
|
||||||
>
|
>
|
||||||
<Text>Do you really want to sign out?</Text>
|
<Text>Do you really want to sign out?</Text>
|
||||||
<Button mode="contained" onPress={hideModal}>
|
<Button mode="contained" onPress={hideModal}>
|
||||||
no
|
no
|
||||||
</Button>
|
</Button>
|
||||||
<Button mode="contained-tonal" onPress={()=> dispatch(disconnect())}>
|
<Button mode="contained-tonal" onPress={()=> dispatch(disconnect())}>
|
||||||
yes
|
yes
|
||||||
</Button>
|
</Button>
|
||||||
</Modal>
|
</Modal>
|
||||||
</Portal>
|
</Portal>
|
||||||
<DrawerLayout
|
<DrawerLayout
|
||||||
swipeEdgeWidth={70}
|
swipeEdgeWidth={70}
|
||||||
drawerType={(Platform.OS == "android" || Platform.OS == "ios") ? "slide":"permanent"}
|
drawerType={layout == "compact" ? "slide":"permanent"}
|
||||||
open={open}
|
open={open}
|
||||||
onOpen={() => setOpen(true)}
|
onOpen={() => setOpen(true)}
|
||||||
onClose={() => setOpen(false)}
|
onClose={() => setOpen(false)}
|
||||||
|
drawerStyle={style.drawer}
|
||||||
renderDrawerContent={() => {
|
renderDrawerContent={() => {
|
||||||
return <>
|
if (layout != "medium"){
|
||||||
<Drawer.Section title="Some title">
|
return <>
|
||||||
<Drawer.Item
|
<Drawer.Section title=" ">
|
||||||
label="Clipboards"
|
<Drawer.Item
|
||||||
active={active === 'clips'}
|
icon="clipboard-arrow-down"
|
||||||
onPress={() => setActive('clips')}
|
label="Clipboards"
|
||||||
/>
|
active={active === 'clips'}
|
||||||
<Drawer.Item
|
onPress={() => {
|
||||||
label="Settings"
|
setActive('clips');
|
||||||
active={active === 'second'}
|
setOpen(false)
|
||||||
onPress={() => setActive('second')}
|
}}
|
||||||
/>
|
/>
|
||||||
</Drawer.Section>
|
<Drawer.Item
|
||||||
<Drawer.Section>
|
icon="cog"
|
||||||
<Drawer.Item
|
label="Settings"
|
||||||
label="Sign out"
|
active={active === 'settings'}
|
||||||
icon="door"
|
onPress={() => {
|
||||||
active={active === 'third'}
|
setActive('settings');
|
||||||
onPress={() => signout()}
|
setOpen(false)
|
||||||
/>
|
}}
|
||||||
</Drawer.Section>
|
/>
|
||||||
</>
|
</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>
|
||||||
|
<Drawer.CollapsedItem
|
||||||
|
focusedIcon="clipboard-arrow-down"
|
||||||
|
unfocusedIcon="clipboard-arrow-down-outline"
|
||||||
|
label="Clipboards"
|
||||||
|
active={active === 'clips'}
|
||||||
|
onPress={() => {
|
||||||
|
setActive('clips');
|
||||||
|
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>
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Appbar.Header>
|
{page}
|
||||||
<Appbar.BackAction onPress={() => {setOpen(true)}} />
|
|
||||||
<Appbar.Content title="Clipboards" />
|
|
||||||
</Appbar.Header>
|
|
||||||
<Tab.Navigator>
|
|
||||||
<Tab.Screen name="Local" options={{title: 'local'}}>
|
|
||||||
{props => (
|
|
||||||
<ClipViewLocal
|
|
||||||
store={store}
|
|
||||||
navigation={props.navigation}
|
|
||||||
type={'local'}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Tab.Screen>
|
|
||||||
<Tab.Screen name="Remote" options={{title: 'distant'}}>
|
|
||||||
{props => (
|
|
||||||
<ClipViewRemote
|
|
||||||
store={store}
|
|
||||||
navigation={props.navigation}
|
|
||||||
type={'remote'}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Tab.Screen>
|
|
||||||
</Tab.Navigator>
|
|
||||||
</DrawerLayout>
|
</DrawerLayout>
|
||||||
</>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
import { View, Text } from "react-native";
|
import { View, Text } from "react-native";
|
||||||
import { Button } from 'react-native-paper';
|
import { Button } from 'react-native-paper';
|
||||||
|
import { ps } from "../utils";
|
||||||
|
import { ReactNavigationDracula as t } from "../themes";
|
||||||
|
|
||||||
export default function IntroPage({navigation}){
|
export default function IntroPage({navigation}){
|
||||||
return(
|
return(
|
||||||
<View style={{alignItems:"center",justifyContent:"center",flex:1,margin:10,flexDirection:'column'}}>
|
<View style={{
|
||||||
<Text style={{fontSize:20,color:"black"}}>
|
alignItems:"center",
|
||||||
Holla Benvenido in l'application du turfu
|
justifyContent:"center",
|
||||||
|
gap:ps(6),
|
||||||
|
flex:1,
|
||||||
|
margin:ps(16),
|
||||||
|
flexDirection:'column'}}>
|
||||||
|
<Text style={{
|
||||||
|
fontSize:20,
|
||||||
|
textAlign:"center",
|
||||||
|
color: t.colors.text
|
||||||
|
}}>
|
||||||
|
Salut, bienvenue dans ClipSync :) connecte toi pour commencer
|
||||||
</Text>
|
</Text>
|
||||||
<Button mode="contained" onPress={() => navigation.navigate('SignIn')}>
|
<Button mode="contained" onPress={() => navigation.navigate('SignIn')}>
|
||||||
Connecte moi le sang
|
Connecte moi le sang
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
}}>
|
||||||
|
Pas encore pret mais on y travaille .w.
|
||||||
|
</Text>
|
||||||
|
</View>)
|
||||||
|
}
|
28
src/themes.ts
Normal file
28
src/themes.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { MD3DarkTheme, Surface } from 'react-native-paper';
|
||||||
|
|
||||||
|
export const Material3Dracula = {
|
||||||
|
...MD3DarkTheme,
|
||||||
|
// Specify custom property
|
||||||
|
// Specify custom property in nested object
|
||||||
|
colors: {
|
||||||
|
...MD3DarkTheme.colors,
|
||||||
|
background: '#44475a',
|
||||||
|
surface: '#44475a',
|
||||||
|
elevation: {
|
||||||
|
...MD3DarkTheme.colors.elevation,
|
||||||
|
level1: "#44475A"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ReactNavigationDracula = {
|
||||||
|
dark: true,
|
||||||
|
colors: {
|
||||||
|
primary: '#bd93f9',
|
||||||
|
background: '#282a36',
|
||||||
|
card: '#44475a',
|
||||||
|
text: '#F8F8F2',
|
||||||
|
border: '#44475a',
|
||||||
|
notification: 'rgb(255, 69, 58)',
|
||||||
|
},
|
||||||
|
};
|
11
src/utils.ts
Normal file
11
src/utils.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { PixelRatio,StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
export const ps = (lp:number) => PixelRatio.getPixelSizeForLayoutSize(PixelRatio.roundToNearestPixel(lp));
|
||||||
|
|
||||||
|
export const style = StyleSheet.create({
|
||||||
|
default : {
|
||||||
|
margin: PixelRatio.getPixelSizeForLayoutSize(8),
|
||||||
|
marginTop : PixelRatio.getPixelSizeForLayoutSize(8),
|
||||||
|
marginLeft : PixelRatio.getPixelSizeForLayoutSize(8)
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user