Mobile changes (#1784)

* privacy link

* remove spacedrop screens, add browse

* icon

* changes and network screen

* bump react native
This commit is contained in:
Utku
2023-11-22 03:49:52 +03:00
committed by GitHub
parent 07b45fe824
commit c8dbf715fd
13 changed files with 95 additions and 201 deletions

View File

@@ -44,7 +44,7 @@
"phosphor-react-native": "^1.1.2",
"react": "^18.2.0",
"react-hook-form": "^7.47.0",
"react-native": "0.72.5",
"react-native": "0.72.6",
"react-native-document-picker": "^9.0.1",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.12.1",

View File

@@ -54,9 +54,6 @@ function AppNavigation() {
initPlausible({ platformType: 'mobile', buildInfo: buildInfo?.data });
// TODO: Make sure library has actually been loaded by this point - precache with useCachedLibraries?
// if (library === undefined) throw new Error("Tried to render AppNavigation before libraries fetched!")
const navRef = useNavigationContainerRef();
const routeNameRef = useRef<string>();

View File

@@ -0,0 +1,23 @@
import { getIcon, iconNames } from '@sd/assets/util';
import { Image, ImageProps } from 'react-native';
import { isDarkTheme } from '@sd/client';
export type IconName = keyof typeof iconNames;
interface IconProps extends Omit<ImageProps, 'source'> {
name: IconName;
size?: number;
theme?: 'dark' | 'light';
}
export const Icon = ({ name, size, theme, ...props }: IconProps) => {
const isDark = isDarkTheme();
return (
<Image
{...props}
style={{ width: size, height: size }}
source={getIcon(name, theme ? theme === 'dark' : isDark)}
/>
);
};

View File

@@ -1,12 +1,12 @@
import { BottomTabScreenProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
import { Broadcast, CirclesFour, Planet } from 'phosphor-react-native';
import { CirclesFour, FolderOpen, Planet } from 'phosphor-react-native';
import { tw } from '~/lib/tailwind';
import type { HomeDrawerScreenProps } from './DrawerNavigator';
import BrowseStack, { BrowseStackParamList } from './tabs/BrowseStack';
import NetworkStack, { NetworkStackParamList } from './tabs/NetworkStack';
import OverviewStack, { OverviewStackParamList } from './tabs/OverviewStack';
import SpacedropStack, { SpacedropStackParamList } from './tabs/SpacedropStack';
import SpacesStack, { SpacesStackParamList } from './tabs/SpacesStack';
const Tab = createBottomTabNavigator<TabParamList>();
@@ -41,8 +41,8 @@ export default function TabNavigator() {
}}
/>
<Tab.Screen
name="SpacesStack"
component={SpacesStack}
name="NetworkStack"
component={NetworkStack}
options={{
tabBarIcon: ({ focused }) => (
<CirclesFour
@@ -51,22 +51,22 @@ export default function TabNavigator() {
color={focused ? tw.color('accent') : tw.color('ink')}
/>
),
tabBarLabel: 'Spaces',
tabBarLabel: 'Network',
tabBarLabelStyle: tw`text-[10px] font-semibold`
}}
/>
<Tab.Screen
name="SpacedropStack"
component={SpacedropStack}
name="BrowseStack"
component={BrowseStack}
options={{
tabBarIcon: ({ focused }) => (
<Broadcast
<FolderOpen
size={22}
weight={focused ? 'bold' : 'regular'}
color={focused ? tw.color('accent') : tw.color('ink')}
/>
),
tabBarLabel: 'Spacedrop',
tabBarLabel: 'Browse',
tabBarLabelStyle: tw`text-[10px] font-semibold`
}}
/>
@@ -76,8 +76,8 @@ export default function TabNavigator() {
export type TabParamList = {
OverviewStack: NavigatorScreenParams<OverviewStackParamList>;
SpacedropStack: NavigatorScreenParams<SpacedropStackParamList>;
SpacesStack: NavigatorScreenParams<SpacesStackParamList>;
NetworkStack: NavigatorScreenParams<NetworkStackParamList>;
BrowseStack: NavigatorScreenParams<BrowseStackParamList>;
};
export type TabScreenProps<Screen extends keyof TabParamList> = CompositeScreenProps<

View File

@@ -2,17 +2,17 @@ import { CompositeScreenProps } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import Header from '~/components/header/Header';
import { tw } from '~/lib/tailwind';
import BrowseScreen from '~/screens/Browse';
import SpacesScreen from '../../screens/Spaces';
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
import { TabScreenProps } from '../TabNavigator';
const Stack = createStackNavigator<SpacesStackParamList>();
const Stack = createStackNavigator<BrowseStackParamList>();
export default function SpacesStack() {
export default function BrowseStack() {
return (
<Stack.Navigator
initialRouteName="Spaces"
initialRouteName="Browse"
screenOptions={{
headerStyle: { backgroundColor: tw.color('app-box') },
headerTintColor: tw.color('ink'),
@@ -20,18 +20,18 @@ export default function SpacesStack() {
headerBackTitleStyle: tw`text-base`
}}
>
<Stack.Screen name="Spaces" component={SpacesScreen} options={{ header: Header }} />
<Stack.Screen name="Browse" component={BrowseScreen} options={{ header: Header }} />
{SharedScreens(Stack as any)}
</Stack.Navigator>
);
}
export type SpacesStackParamList = {
Spaces: undefined;
export type BrowseStackParamList = {
Browse: undefined;
} & SharedScreensParamList;
export type SpacesStackScreenProps<Screen extends keyof SpacesStackParamList> =
export type BrowseStackScreenProps<Screen extends keyof BrowseStackParamList> =
CompositeScreenProps<
StackScreenProps<SpacesStackParamList, Screen>,
TabScreenProps<'SpacesStack'>
StackScreenProps<BrowseStackParamList, Screen>,
TabScreenProps<'BrowseStack'>
>;

View File

@@ -2,17 +2,17 @@ import { CompositeScreenProps } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import Header from '~/components/header/Header';
import { tw } from '~/lib/tailwind';
import SpacedropScreen from '~/screens/Spacedrop';
import NetworkScreen from '../../screens/Network';
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
import { TabScreenProps } from '../TabNavigator';
const Stack = createStackNavigator<SpacedropStackParamList>();
const Stack = createStackNavigator<NetworkStackParamList>();
export default function SpacedropStack() {
export default function NetworkStack() {
return (
<Stack.Navigator
initialRouteName="Spacedrop"
initialRouteName="Network"
screenOptions={{
headerStyle: { backgroundColor: tw.color('app-box') },
headerTintColor: tw.color('ink'),
@@ -20,22 +20,18 @@ export default function SpacedropStack() {
headerBackTitleStyle: tw`text-base`
}}
>
<Stack.Screen
name="Spacedrop"
component={SpacedropScreen}
options={{ header: Header }}
/>
<Stack.Screen name="Network" component={NetworkScreen} options={{ header: Header }} />
{SharedScreens(Stack as any)}
</Stack.Navigator>
);
}
export type SpacedropStackParamList = {
Spacedrop: undefined;
export type NetworkStackParamList = {
Network: undefined;
} & SharedScreensParamList;
export type SpacedropStackScreenProps<Screen extends keyof SpacedropStackParamList> =
export type NetworkStackScreenProps<Screen extends keyof NetworkStackParamList> =
CompositeScreenProps<
StackScreenProps<SpacedropStackParamList, Screen>,
TabScreenProps<'SpacedropStack'>
StackScreenProps<NetworkStackParamList, Screen>,
TabScreenProps<'NetworkStack'>
>;

View File

@@ -0,0 +1,6 @@
import { View } from 'react-native';
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
export default function BrowseScreen({ navigation, route }: BrowseStackScreenProps<'Browse'>) {
return <View></View>;
}

View File

@@ -0,0 +1,17 @@
import { Text, View } from 'react-native';
import { Icon } from '~/components/icons/Icon';
import { tw } from '~/lib/tailwind';
import { NetworkStackScreenProps } from '~/navigation/tabs/NetworkStack';
export default function NetworkScreen({ navigation }: NetworkStackScreenProps<'Network'>) {
return (
<View style={tw`flex-1 items-center justify-center`}>
<Icon name="Globe" size={128} />
<Text style={tw`mt-4 text-lg font-bold text-white`}>Your Local Network</Text>
<Text style={tw`mt-1 max-w-sm text-center text-sm text-ink-dull`}>
Other Spacedrive nodes on your LAN will appear here, along with your default OS
network mounts.
</Text>
</View>
);
}

View File

@@ -1,146 +0,0 @@
import { GoogleDrive, iCloud, Mega } from '@sd/assets/images';
import { DeviceMobile, Icon, Laptop, User } from 'phosphor-react-native';
import { Alert, Image, ImageSourcePropType, Pressable, ScrollView, Text, View } from 'react-native';
import { Polygon, Svg } from 'react-native-svg';
import { InfoPill } from '~/components/primitive/InfoPill';
import { tw, twStyle } from '~/lib/tailwind';
import { SpacedropStackScreenProps } from '~/navigation/tabs/SpacedropStack';
const testData = [
{
name: "Jamie's MacBook Pro",
receivingNodeOsType: 'macOS',
connectionType: 'lan',
icon: Laptop
},
{
name: "Jamie's MacBook Pro",
receivingNodeOsType: 'iOS',
connectionType: 'lan',
icon: DeviceMobile
},
{
name: 'Brendan Alan',
image: 'https://github.com/brendonovich.png',
connectionType: 'p2p'
},
{
name: 'Oscar Beaumont',
image: 'https://github.com/oscartbeaumont.png',
connectionType: 'usb'
},
{
name: 'maxichrome',
image: 'https://github.com/maxichrome.png',
connectionType: 'p2p'
},
{
name: 'Utku',
image: 'https://github.com/utkubakir.png',
connectionType: 'p2p'
},
{ name: "Jamie's Google Drive", brandIcon: 'google-drive', connectionType: 'cloud' },
{ name: 'iCloud', brandIcon: 'icloud', connectionType: 'cloud' },
{ name: 'Mega', brandIcon: 'mega', connectionType: 'cloud' }
] as DropItemProps[];
const Hexagon = () => {
const width = 180;
const height = width * 1.1547;
return (
<Svg width={width} height={height} viewBox="0 0 100 100">
<Polygon
points="0,25 0,75 50,100 100,75 100,25 50,0"
fill={tw.color('bg-app-box/30')}
/>
</Svg>
);
};
type OperatingSystem = 'browser' | 'linux' | 'macOS' | 'windows' | 'iOS' | 'android';
type DropItemProps = {
name: string;
connectionType: 'lan' | 'bluetooth' | 'usb' | 'p2p' | 'cloud';
receivingNodeOsType: OperatingSystem;
} & ({ image: string } | { icon: Icon } | { brandIcon: string });
function DropItem(props: DropItemProps) {
let icon;
if ('image' in props) {
icon = <Image style={tw`h-12 w-12 rounded-full`} source={{ uri: props.image }} />;
} else if ('brandIcon' in props) {
let brandIconSrc: ImageSourcePropType | undefined;
switch (props.brandIcon) {
case 'google-drive':
brandIconSrc = GoogleDrive;
break;
case 'icloud':
brandIconSrc = iCloud;
break;
case 'mega':
brandIconSrc = Mega;
break;
}
if (!brandIconSrc) throw new Error('Invalid brand icon url: ' + props.brandIcon);
icon = (
<View style={tw`flex items-center justify-center p-3`}>
{/* // Needs width and height */}
<Image source={brandIconSrc} style={tw`h-8 w-8 rounded-full`} />
</View>
);
} else {
// Use the custom icon or default to User icon.
const Icon = props.icon || User;
icon = <Icon size={30} color="white" style={twStyle(!props.name && 'opacity-20')} />;
}
return (
<View style={tw`relative`}>
<Hexagon />
<View style={tw`absolute h-full w-full items-center justify-center`}>
<Pressable
style={tw`w-full items-center justify-center`}
onPress={() => Alert.alert('TODO')}
>
<View
style={tw`h-12 w-12 items-center justify-center rounded-full bg-app-button`}
>
{icon}
</View>
{props.name && (
<Text numberOfLines={1} style={tw`mt-1 text-sm font-medium text-white`}>
{props.name}
</Text>
)}
<View style={tw`mt-1 flex flex-row gap-x-1`}>
{props.receivingNodeOsType && <InfoPill text={props.receivingNodeOsType} />}
{props.connectionType && (
<InfoPill
text={props.connectionType}
containerStyle={twStyle(
'px-1',
props.connectionType === 'lan' && 'bg-green-500',
props.connectionType === 'p2p' && 'bg-blue-500'
)}
textStyle={tw`uppercase text-white`}
/>
)}
</View>
</Pressable>
</View>
</View>
);
}
export default function SpacedropScreen({ navigation }: SpacedropStackScreenProps<'Spacedrop'>) {
return (
<View style={tw`flex-1 py-4`}>
<ScrollView contentContainerStyle={tw`flex flex-row flex-wrap justify-center gap-x-2`}>
{testData.map((item, i) => (
<DropItem key={i} {...item} />
))}
</ScrollView>
</View>
);
}

View File

@@ -1,11 +0,0 @@
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SpacesStackScreenProps } from '~/navigation/tabs/SpacesStack';
export default function SpacesScreen({ navigation }: SpacesStackScreenProps<'Spaces'>) {
return (
<View style={tw`flex-1 items-center justify-center`}>
<Text style={tw`text-xl font-bold text-ink`}>Spaces</Text>
</View>
);
}

View File

@@ -1,7 +1,7 @@
import { Database } from '@sd/assets/icons';
import { Controller } from 'react-hook-form';
import { Alert, Image, Text, View } from 'react-native';
import { Alert, Text, View } from 'react-native';
import { Input } from '~/components/form/Input';
import { Icon } from '~/components/icons/Icon';
import { Button } from '~/components/primitive/Button';
import { tw } from '~/lib/tailwind';
import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
@@ -20,7 +20,7 @@ const NewLibraryScreen = ({ navigation }: OnboardingStackScreenProps<'NewLibrary
return (
<OnboardingContainer>
<Image source={Database} style={tw`h-25 w-25`} />
<Icon name="Database" style={tw`h-25 w-25`} />
<OnboardingTitle style={tw`mt-4`}>Create a Library</OnboardingTitle>
<View style={tw`w-full px-4`}>
<OnboardingDescription style={tw`mt-4`}>

View File

@@ -1,6 +1,7 @@
import { ArrowRight } from 'phosphor-react-native';
import React from 'react';
import { Controller } from 'react-hook-form';
import { Pressable, Text, View, ViewStyle } from 'react-native';
import { Linking, Pressable, Text, View, ViewStyle } from 'react-native';
import { Button } from '~/components/primitive/Button';
import { tw, twStyle } from '~/lib/tailwind';
import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
@@ -83,6 +84,17 @@ const PrivacyScreen = () => {
<Button variant="accent" size="sm" onPress={form.handleSubmit(submit)} style={tw`mt-6`}>
<Text style={tw`text-center text-base font-medium text-ink`}>Continue</Text>
</Button>
<Pressable
onPress={() => {
Linking.openURL('https://www.spacedrive.com/docs/product/resources/privacy');
}}
style={tw`mt-6 flex flex-row items-center justify-center`}
>
<ArrowRight size={16} style={tw`mr-0.5`} color={tw.color('text-ink-faint')} />
<Text style={tw`text-center text-sm font-medium text-ink-faint underline`}>
Learn more about the data we collect
</Text>
</Pressable>
</OnboardingContainer>
);
};

BIN
pnpm-lock.yaml generated
View File

Binary file not shown.