From b855ae22ebbd5835193ec36015e8668599ad5fde Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Tue, 30 Aug 2022 18:21:32 +0300 Subject: [PATCH 01/15] Dialog & fixed relative imports --- apps/mobile/babel.config.js | 23 ++++- apps/mobile/ios/Podfile.lock | 8 +- apps/mobile/package.json | 1 + apps/mobile/pnpm-lock.yaml | Bin 326993 -> 327018 bytes .../src/components/animation/layout.tsx | 5 +- .../components/browse/BrowseLocationItem.tsx | 2 +- .../src/components/browse/BrowseTagItem.tsx | 3 +- apps/mobile/src/components/device/Device.tsx | 4 +- .../src/components/drawer/DrawerContent.tsx | 4 +- .../components/drawer/DrawerLocationItem.tsx | 2 +- .../src/components/drawer/DrawerLogo.tsx | 4 +- .../src/components/drawer/DrawerTagItem.tsx | 3 +- apps/mobile/src/components/header/Header.tsx | 3 +- .../src/components/layout/CollapsibleView.tsx | 2 +- apps/mobile/src/components/layout/Dialog.tsx | 89 ++++++++++++++++++ .../src/components/modals/FileModal.tsx | 2 +- .../components/{base => primitive}/Button.tsx | 8 +- .../{base => primitive}/Divider.tsx | 3 +- .../mobile/src/components/primitive/Input.tsx | 0 .../mobile/src/navigation/DrawerNavigator.tsx | 2 +- .../src/navigation/OnboardingNavigator.tsx | 3 +- apps/mobile/src/navigation/SharedScreens.tsx | 5 +- apps/mobile/src/navigation/TabNavigator.tsx | 2 +- apps/mobile/src/navigation/index.tsx | 6 +- .../src/navigation/tabs/BrowseStack.tsx | 10 +- apps/mobile/src/screens/Browse.tsx | 11 +-- apps/mobile/src/screens/Location.tsx | 5 +- apps/mobile/src/screens/NotFound.tsx | 5 +- apps/mobile/src/screens/Overview.tsx | 26 +++-- apps/mobile/src/screens/Photos.tsx | 5 +- apps/mobile/src/screens/Spaces.tsx | 5 +- apps/mobile/src/screens/Tag.tsx | 5 +- apps/mobile/src/screens/modals/Search.tsx | 7 +- .../src/screens/modals/settings/Settings.tsx | 5 +- .../src/screens/onboarding/Onboarding.tsx | 13 ++- apps/mobile/tsconfig.json | 7 +- 36 files changed, 203 insertions(+), 85 deletions(-) create mode 100644 apps/mobile/src/components/layout/Dialog.tsx rename apps/mobile/src/components/{base => primitive}/Button.tsx (89%) rename apps/mobile/src/components/{base => primitive}/Divider.tsx (88%) create mode 100644 apps/mobile/src/components/primitive/Input.tsx diff --git a/apps/mobile/babel.config.js b/apps/mobile/babel.config.js index 224bce79e..1575c5239 100644 --- a/apps/mobile/babel.config.js +++ b/apps/mobile/babel.config.js @@ -2,6 +2,27 @@ module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], - plugins: ['react-native-reanimated/plugin'] + plugins: [ + 'react-native-reanimated/plugin', + [ + 'module-resolver', + { + extensions: [ + '.js', + '.jsx', + '.ts', + '.tsx', + '.android.js', + '.android.tsx', + '.ios.js', + '.ios.tsx' + ], + root: ['src'], + alias: { + '@app': './src' + } + } + ] + ] }; }; diff --git a/apps/mobile/ios/Podfile.lock b/apps/mobile/ios/Podfile.lock index 00b80fd0f..eb04e2bc1 100644 --- a/apps/mobile/ios/Podfile.lock +++ b/apps/mobile/ios/Podfile.lock @@ -3,7 +3,7 @@ PODS: - DoubleConversion (1.1.6) - EXApplication (4.2.2): - ExpoModulesCore - - EXConstants (13.2.3): + - EXConstants (13.2.4): - ExpoModulesCore - EXFileSystem (14.1.0): - ExpoModulesCore @@ -373,7 +373,7 @@ DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - "EXApplication (from `../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.9/node_modules/expo-application/ios`)" - - "EXConstants (from `../node_modules/.pnpm/expo-constants@13.2.3_expo@46.0.9/node_modules/expo-constants/ios`)" + - "EXConstants (from `../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.9/node_modules/expo-constants/ios`)" - "EXFileSystem (from `../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.9/node_modules/expo-file-system/ios`)" - "EXFont (from `../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.9/node_modules/expo-font/ios`)" - "Expo (from `../node_modules/.pnpm/expo@46.0.9_@babel+core@7.18.10/node_modules/expo`)" @@ -435,7 +435,7 @@ EXTERNAL SOURCES: EXApplication: :path: "../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.9/node_modules/expo-application/ios" EXConstants: - :path: "../node_modules/.pnpm/expo-constants@13.2.3_expo@46.0.9/node_modules/expo-constants/ios" + :path: "../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.9/node_modules/expo-constants/ios" EXFileSystem: :path: "../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.9/node_modules/expo-file-system/ios" EXFont: @@ -531,7 +531,7 @@ SPEC CHECKSUMS: boost: a7c83b31436843459a1961bfd74b96033dc77234 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 EXApplication: e418d737a036e788510f2c4ad6c10a7d54d18586 - EXConstants: 75c40827af38bd6bfcf69f880a5b45037eeff9c9 + EXConstants: 7c44785d41d8e959d527d23d29444277a4d1ee73 EXFileSystem: 927e0a8885aa9c49e50fc38eaba2c2389f2f1019 EXFont: a5d80bd9b3452b2d5abbce2487da89b0150e6487 Expo: 73412414e62f5cbc6e713def821de70b92cd3ad6 diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 711926bd7..f915311a1 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -53,6 +53,7 @@ "@types/react-native": "~0.69.1", "@typescript-eslint/eslint-plugin": "^5.30.7", "@typescript-eslint/parser": "^5.30.7", + "babel-plugin-module-resolver": "^4.1.0", "eslint": "^8.21.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-react": "^7.30.1", diff --git a/apps/mobile/pnpm-lock.yaml b/apps/mobile/pnpm-lock.yaml index 75295d7a7edc621dca97cf736398368a1f2d7935..5fce41495b89a2a9fac6c79745341866bd445de2 100644 GIT binary patch delta 91 zcmV-h0HpuX`V;E<6R=1Fm$2ml9R^-BE-@}Jvp@sP3zx6u0V ( diff --git a/apps/mobile/src/components/browse/BrowseLocationItem.tsx b/apps/mobile/src/components/browse/BrowseLocationItem.tsx index 2298925c9..2fb4fa2da 100644 --- a/apps/mobile/src/components/browse/BrowseLocationItem.tsx +++ b/apps/mobile/src/components/browse/BrowseLocationItem.tsx @@ -1,7 +1,7 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { Pressable, Text, View } from 'react-native'; -import tw from '../../lib/tailwind'; import FolderIcon from '../icons/FolderIcon'; interface BrowseLocationItemProps { diff --git a/apps/mobile/src/components/browse/BrowseTagItem.tsx b/apps/mobile/src/components/browse/BrowseTagItem.tsx index 2f8508008..0337d214c 100644 --- a/apps/mobile/src/components/browse/BrowseTagItem.tsx +++ b/apps/mobile/src/components/browse/BrowseTagItem.tsx @@ -1,8 +1,7 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { ColorValue, Pressable, Text, View } from 'react-native'; -import tw from '../../lib/tailwind'; - type BrowseTagItemProps = { tagName: string; tagColor: ColorValue; diff --git a/apps/mobile/src/components/device/Device.tsx b/apps/mobile/src/components/device/Device.tsx index d8a24afad..04a71d37b 100644 --- a/apps/mobile/src/components/device/Device.tsx +++ b/apps/mobile/src/components/device/Device.tsx @@ -1,10 +1,10 @@ +import tw from '@app/lib/tailwind'; +import { FilePath } from '@app/types/bindings'; import { Cloud, Desktop, DeviceMobileCamera, Laptop } from 'phosphor-react-native'; import React from 'react'; import { FlatList, Text, View } from 'react-native'; import { LockClosedIcon } from 'react-native-heroicons/solid'; -import tw from '../../lib/tailwind'; -import { FilePath } from '../../types/bindings'; import FileItem from '../file/FileItem'; const placeholderFileItems: FilePath[] = [ diff --git a/apps/mobile/src/components/drawer/DrawerContent.tsx b/apps/mobile/src/components/drawer/DrawerContent.tsx index 0a727600b..a856af731 100644 --- a/apps/mobile/src/components/drawer/DrawerContent.tsx +++ b/apps/mobile/src/components/drawer/DrawerContent.tsx @@ -1,3 +1,5 @@ +import Layout from '@app/constants/Layout'; +import tw from '@app/lib/tailwind'; import { DrawerContentScrollView } from '@react-navigation/drawer'; import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typescript/src/types'; import { getFocusedRouteNameFromRoute } from '@react-navigation/native'; @@ -5,8 +7,6 @@ import React from 'react'; import { ColorValue, Platform, Pressable, Text, View } from 'react-native'; import { CogIcon } from 'react-native-heroicons/solid'; -import Layout from '../../constants/Layout'; -import tw from '../../lib/tailwind'; import CollapsibleView from '../layout/CollapsibleView'; import DrawerLocationItem from './DrawerLocationItem'; import DrawerLogo from './DrawerLogo'; diff --git a/apps/mobile/src/components/drawer/DrawerLocationItem.tsx b/apps/mobile/src/components/drawer/DrawerLocationItem.tsx index a9f74ae74..a838a9013 100644 --- a/apps/mobile/src/components/drawer/DrawerLocationItem.tsx +++ b/apps/mobile/src/components/drawer/DrawerLocationItem.tsx @@ -1,7 +1,7 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { Pressable, Text, View } from 'react-native'; -import tw from '../../lib/tailwind'; import FolderIcon from '../icons/FolderIcon'; interface DrawerLocationItemProps { diff --git a/apps/mobile/src/components/drawer/DrawerLogo.tsx b/apps/mobile/src/components/drawer/DrawerLogo.tsx index afe1ce54c..f0c2f6af6 100644 --- a/apps/mobile/src/components/drawer/DrawerLogo.tsx +++ b/apps/mobile/src/components/drawer/DrawerLogo.tsx @@ -1,8 +1,8 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { Image, Text, View } from 'react-native'; -import tw from '../../lib/tailwind'; -import Divider from '../base/Divider'; +import Divider from '../primitive/Divider'; const DrawerLogo = () => { return ( diff --git a/apps/mobile/src/components/drawer/DrawerTagItem.tsx b/apps/mobile/src/components/drawer/DrawerTagItem.tsx index 210b04876..a37e3f65e 100644 --- a/apps/mobile/src/components/drawer/DrawerTagItem.tsx +++ b/apps/mobile/src/components/drawer/DrawerTagItem.tsx @@ -1,8 +1,7 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { ColorValue, Pressable, Text, View } from 'react-native'; -import tw from '../../lib/tailwind'; - type DrawerTagItemProps = { tagName: string; tagColor: ColorValue; diff --git a/apps/mobile/src/components/header/Header.tsx b/apps/mobile/src/components/header/Header.tsx index 8838ade88..f35478e13 100644 --- a/apps/mobile/src/components/header/Header.tsx +++ b/apps/mobile/src/components/header/Header.tsx @@ -1,3 +1,4 @@ +import tw from '@app/lib/tailwind'; import { useDrawerStatus } from '@react-navigation/drawer'; import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types'; import { useNavigation } from '@react-navigation/native'; @@ -7,8 +8,6 @@ import React from 'react'; import { Pressable, Text, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import tw from '../../lib/tailwind'; - const Header = () => { const navigation = useNavigation(); diff --git a/apps/mobile/src/components/layout/CollapsibleView.tsx b/apps/mobile/src/components/layout/CollapsibleView.tsx index abdf28a68..dbaa25942 100644 --- a/apps/mobile/src/components/layout/CollapsibleView.tsx +++ b/apps/mobile/src/components/layout/CollapsibleView.tsx @@ -1,9 +1,9 @@ +import tw from '@app/lib/tailwind'; import { Ionicons } from '@expo/vector-icons'; import { MotiView } from 'moti'; import React, { useReducer } from 'react'; import { Pressable, StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native'; -import tw from '../../lib/tailwind'; import { AnimatedHeight } from '../animation/layout'; type CollapsibleViewProps = { diff --git a/apps/mobile/src/components/layout/Dialog.tsx b/apps/mobile/src/components/layout/Dialog.tsx new file mode 100644 index 000000000..283e49dd9 --- /dev/null +++ b/apps/mobile/src/components/layout/Dialog.tsx @@ -0,0 +1,89 @@ +import tw from '@app/lib/tailwind'; +import { MotiView } from 'moti'; +import React, { useState } from 'react'; +import { KeyboardAvoidingView, Modal, Platform, Pressable, Text, View } from 'react-native'; + +import { Button } from '../primitive/Button'; + +type DialogProps = { + title: string; + description?: string; + trigger?: React.ReactNode; + /** + * if `true`, dialog will be visible when mounted + * Can be used when trigger is not provided and/or you need to open the dialog programmatically + */ + isVisible?: boolean; + children?: React.ReactNode; + ctaAction?: () => void; + ctaLabel?: string; + ctaDanger?: boolean; + /** + * Disables backdrop press to close the modal. + */ + disableBackdropClose?: boolean; +}; + +const Dialog = (props: DialogProps) => { + const [visible, setVisible] = useState(props.isVisible ?? false); + + return ( + + {props.trigger && setVisible(true)}>{props.trigger}} + + {/* Backdrop */} + setVisible(false)} + disabled={props.disableBackdropClose} + /> + {/* Content */} + + {/* TODO: Animations are not invoking everytime probably reanimated bug we have on File Modal */} + + + + {/* Title */} + {props.title} + {/* Description */} + {props.description && ( + + {props.description} + + )} + {/* Children */} + {props.children} + + {/* Actions */} + + + {props.ctaAction && ( + + )} + + + + + + + ); +}; + +export default Dialog; diff --git a/apps/mobile/src/components/modals/FileModal.tsx b/apps/mobile/src/components/modals/FileModal.tsx index e5658ee1d..c63ff95ba 100644 --- a/apps/mobile/src/components/modals/FileModal.tsx +++ b/apps/mobile/src/components/modals/FileModal.tsx @@ -6,8 +6,8 @@ import { ChevronLeftIcon } from 'react-native-heroicons/outline'; import tw from '../../lib/tailwind'; import { useFileModalStore } from '../../stores/useModalStore'; -import Divider from '../base/Divider'; import FileIcon from '../file/FileIcon'; +import Divider from '../primitive/Divider'; import ModalBackdrop from './layout/ModalBackdrop'; import ModalHandle from './layout/ModalHandle'; diff --git a/apps/mobile/src/components/base/Button.tsx b/apps/mobile/src/components/primitive/Button.tsx similarity index 89% rename from apps/mobile/src/components/base/Button.tsx rename to apps/mobile/src/components/primitive/Button.tsx index 3cc76eda4..e78d07790 100644 --- a/apps/mobile/src/components/base/Button.tsx +++ b/apps/mobile/src/components/primitive/Button.tsx @@ -1,20 +1,22 @@ +import tw from '@app/lib/tailwind'; import { VariantProps, cva } from 'class-variance-authority'; import { MotiPressable, MotiPressableProps } from 'moti/interactions'; import React, { useMemo } from 'react'; import { Pressable, PressableProps } from 'react-native'; -import tw from '../../lib/tailwind'; - const button = cva(['border rounded-md items-center shadow-sm'], { variants: { variant: { default: 'bg-gray-50 border-gray-100', primary: ['bg-primary-600'], - gray: ['bg-gray-100 border-gray-200'] + danger: ['bg-red-600'], + gray: ['bg-gray-100 border-gray-200'], + dark_gray: ['bg-gray-500 border-gray-600'] }, size: { default: ['py-1', 'px-3'], sm: ['py-1', 'px-2'], + md: ['py-1.5', 'px-3'], lg: ['py-2', 'px-4'] } }, diff --git a/apps/mobile/src/components/base/Divider.tsx b/apps/mobile/src/components/primitive/Divider.tsx similarity index 88% rename from apps/mobile/src/components/base/Divider.tsx rename to apps/mobile/src/components/primitive/Divider.tsx index f936c2884..722eeddf8 100644 --- a/apps/mobile/src/components/base/Divider.tsx +++ b/apps/mobile/src/components/primitive/Divider.tsx @@ -1,8 +1,7 @@ +import tw from '@app/lib/tailwind'; import React from 'react'; import { StyleProp, Text, View, ViewStyle } from 'react-native'; -import tw from '../../lib/tailwind'; - type DividerProps = { style?: StyleProp; }; diff --git a/apps/mobile/src/components/primitive/Input.tsx b/apps/mobile/src/components/primitive/Input.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/apps/mobile/src/navigation/DrawerNavigator.tsx b/apps/mobile/src/navigation/DrawerNavigator.tsx index e321a6f25..30e298b36 100644 --- a/apps/mobile/src/navigation/DrawerNavigator.tsx +++ b/apps/mobile/src/navigation/DrawerNavigator.tsx @@ -1,9 +1,9 @@ +import DrawerContent from '@app/components/drawer/DrawerContent'; import { DrawerScreenProps, createDrawerNavigator } from '@react-navigation/drawer'; import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native'; import { StackScreenProps } from '@react-navigation/stack'; import type { RootStackParamList } from '.'; -import DrawerContent from '../components/drawer/DrawerContent'; import type { TabParamList } from './TabNavigator'; import TabNavigator from './TabNavigator'; diff --git a/apps/mobile/src/navigation/OnboardingNavigator.tsx b/apps/mobile/src/navigation/OnboardingNavigator.tsx index 354dbe271..0a2b07924 100644 --- a/apps/mobile/src/navigation/OnboardingNavigator.tsx +++ b/apps/mobile/src/navigation/OnboardingNavigator.tsx @@ -1,7 +1,6 @@ +import OnboardingScreen from '@app/screens/onboarding/Onboarding'; import { StackScreenProps, createStackNavigator } from '@react-navigation/stack'; -import OnboardingScreen from '../screens/onboarding/Onboarding'; - const OnboardingStack = createStackNavigator(); export default function OnboardingNavigator() { diff --git a/apps/mobile/src/navigation/SharedScreens.tsx b/apps/mobile/src/navigation/SharedScreens.tsx index 307887180..2e986eae6 100644 --- a/apps/mobile/src/navigation/SharedScreens.tsx +++ b/apps/mobile/src/navigation/SharedScreens.tsx @@ -1,3 +1,5 @@ +import LocationScreen from '@app/screens/Location'; +import TagScreen from '@app/screens/Tag'; import { ParamListBase, StackNavigationState, TypedNavigator } from '@react-navigation/native'; import { StackNavigationEventMap, @@ -5,9 +7,6 @@ import { StackScreenProps } from '@react-navigation/stack'; -import LocationScreen from '../screens/Location'; -import TagScreen from '../screens/Tag'; - export function SharedScreens( Stack: TypedNavigator< SharedScreensParamList, diff --git a/apps/mobile/src/navigation/TabNavigator.tsx b/apps/mobile/src/navigation/TabNavigator.tsx index 63a211f45..cfc6f4c9c 100644 --- a/apps/mobile/src/navigation/TabNavigator.tsx +++ b/apps/mobile/src/navigation/TabNavigator.tsx @@ -1,9 +1,9 @@ +import tw from '@app/lib/tailwind'; import { BottomTabScreenProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native'; import { CirclesFour, Folder, Planet } from 'phosphor-react-native'; import { PhotographIcon } from 'react-native-heroicons/outline'; -import tw from '../lib/tailwind'; import type { HomeDrawerScreenProps } from './DrawerNavigator'; import BrowseStack, { BrowseStackParamList } from './tabs/BrowseStack'; import OverviewStack, { OverviewStackParamList } from './tabs/OverviewStack'; diff --git a/apps/mobile/src/navigation/index.tsx b/apps/mobile/src/navigation/index.tsx index 857c9d362..2dabc5711 100644 --- a/apps/mobile/src/navigation/index.tsx +++ b/apps/mobile/src/navigation/index.tsx @@ -1,9 +1,9 @@ +import NotFoundScreen from '@app/screens/NotFound'; +import SearchScreen from '@app/screens/modals/Search'; +import SettingsScreen from '@app/screens/modals/settings/Settings'; import { NavigatorScreenParams } from '@react-navigation/native'; import { StackScreenProps, createStackNavigator } from '@react-navigation/stack'; -import NotFoundScreen from '../screens/NotFound'; -import SearchScreen from '../screens/modals/Search'; -import SettingsScreen from '../screens/modals/settings/Settings'; import type { DrawerNavParamList } from './DrawerNavigator'; import DrawerNavigator from './DrawerNavigator'; diff --git a/apps/mobile/src/navigation/tabs/BrowseStack.tsx b/apps/mobile/src/navigation/tabs/BrowseStack.tsx index d2363c9fa..64374ab9b 100644 --- a/apps/mobile/src/navigation/tabs/BrowseStack.tsx +++ b/apps/mobile/src/navigation/tabs/BrowseStack.tsx @@ -1,8 +1,12 @@ +import BrowseScreen from '@app/screens/Browse'; import { CompositeScreenProps } from '@react-navigation/native'; -import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack'; +import { + Header, + StackScreenProps, + TransitionPresets, + createStackNavigator +} from '@react-navigation/stack'; -import Header from '../../components/header/Header'; -import BrowseScreen from '../../screens/Browse'; import { SharedScreens, SharedScreensParamList } from '../SharedScreens'; import { TabScreenProps } from '../TabNavigator'; diff --git a/apps/mobile/src/screens/Browse.tsx b/apps/mobile/src/screens/Browse.tsx index 205533bb2..8217b9225 100644 --- a/apps/mobile/src/screens/Browse.tsx +++ b/apps/mobile/src/screens/Browse.tsx @@ -1,12 +1,11 @@ +import BrowseLocationItem from '@app/components/browse/BrowseLocationItem'; +import BrowseTagItem from '@app/components/browse/BrowseTagItem'; +import CollapsibleView from '@app/components/layout/CollapsibleView'; +import tw from '@app/lib/tailwind'; +import { BrowseStackScreenProps } from '@app/navigation/tabs/BrowseStack'; import React from 'react'; import { ColorValue, Text, View } from 'react-native'; -import BrowseLocationItem from '../components/browse/BrowseLocationItem'; -import BrowseTagItem from '../components/browse/BrowseTagItem'; -import CollapsibleView from '../components/layout/CollapsibleView'; -import tw from '../lib/tailwind'; -import { BrowseStackScreenProps } from '../navigation/tabs/BrowseStack'; - const placeholderLocationData = [ { id: 1, diff --git a/apps/mobile/src/screens/Location.tsx b/apps/mobile/src/screens/Location.tsx index 7cf2343a8..26424a10e 100644 --- a/apps/mobile/src/screens/Location.tsx +++ b/apps/mobile/src/screens/Location.tsx @@ -1,9 +1,8 @@ +import tw from '@app/lib/tailwind'; +import { SharedScreenProps } from '@app/navigation/SharedScreens'; import React from 'react'; import { Text, View } from 'react-native'; -import tw from '../lib/tailwind'; -import { SharedScreenProps } from '../navigation/SharedScreens'; - export default function LocationScreen({ navigation, route }: SharedScreenProps<'Location'>) { const { id } = route.params; return ( diff --git a/apps/mobile/src/screens/NotFound.tsx b/apps/mobile/src/screens/NotFound.tsx index 0f04aec50..1cba3b178 100644 --- a/apps/mobile/src/screens/NotFound.tsx +++ b/apps/mobile/src/screens/NotFound.tsx @@ -1,8 +1,7 @@ +import tw from '@app/lib/tailwind'; +import { RootStackScreenProps } from '@app/navigation'; import { Text, TouchableOpacity, View } from 'react-native'; -import tw from '../lib/tailwind'; -import type { RootStackScreenProps } from '../navigation'; - export default function NotFoundScreen({ navigation }: RootStackScreenProps<'NotFound'>) { return ( diff --git a/apps/mobile/src/screens/Overview.tsx b/apps/mobile/src/screens/Overview.tsx index 778486ebb..f9f7f2747 100644 --- a/apps/mobile/src/screens/Overview.tsx +++ b/apps/mobile/src/screens/Overview.tsx @@ -1,11 +1,11 @@ +import Device from '@app/components/device/Device'; +import Dialog from '@app/components/layout/Dialog'; +import VirtualizedListWrapper from '@app/components/layout/VirtualizedListWrapper'; +import OverviewStats from '@app/containers/OverviewStats'; +import tw from '@app/lib/tailwind'; +import { OverviewStackScreenProps } from '@app/navigation/tabs/OverviewStack'; import React from 'react'; -import { FlatList, View } from 'react-native'; - -import Device from '../components/device/Device'; -import VirtualizedListWrapper from '../components/layout/VirtualizedListWrapper'; -import OverviewStats from '../containers/OverviewStats'; -import tw from '../lib/tailwind'; -import { OverviewStackScreenProps } from '../navigation/tabs/OverviewStack'; +import { FlatList, Text, View } from 'react-native'; const placeholderOverviewStats = { id: 1, @@ -50,6 +50,18 @@ export default function OverviewScreen({ navigation }: OverviewStackScreenProps< return ( + console.log('wat')} + trigger={ + + Dialog + + } + /> {/* Stats */} {/* Spacing */} diff --git a/apps/mobile/src/screens/Photos.tsx b/apps/mobile/src/screens/Photos.tsx index 5742265ea..3065bf244 100644 --- a/apps/mobile/src/screens/Photos.tsx +++ b/apps/mobile/src/screens/Photos.tsx @@ -1,9 +1,8 @@ +import tw from '@app/lib/tailwind'; +import { PhotosStackScreenProps } from '@app/navigation/tabs/PhotosStack'; import React from 'react'; import { Text, View } from 'react-native'; -import tw from '../lib/tailwind'; -import { PhotosStackScreenProps } from '../navigation/tabs/PhotosStack'; - export default function PhotosScreen({ navigation }: PhotosStackScreenProps<'Photos'>) { return ( diff --git a/apps/mobile/src/screens/Spaces.tsx b/apps/mobile/src/screens/Spaces.tsx index 219041ddc..8ea16ed34 100644 --- a/apps/mobile/src/screens/Spaces.tsx +++ b/apps/mobile/src/screens/Spaces.tsx @@ -1,9 +1,8 @@ +import tw from '@app/lib/tailwind'; +import { SpacesStackScreenProps } from '@app/navigation/tabs/SpacesStack'; import React from 'react'; 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 ( diff --git a/apps/mobile/src/screens/Tag.tsx b/apps/mobile/src/screens/Tag.tsx index 7401157cc..1b4d9e645 100644 --- a/apps/mobile/src/screens/Tag.tsx +++ b/apps/mobile/src/screens/Tag.tsx @@ -1,9 +1,8 @@ +import tw from '@app/lib/tailwind'; +import { SharedScreenProps } from '@app/navigation/SharedScreens'; import React from 'react'; import { Text, View } from 'react-native'; -import tw from '../lib/tailwind'; -import { SharedScreenProps } from '../navigation/SharedScreens'; - export default function TagScreen({ navigation, route }: SharedScreenProps<'Tag'>) { const { id } = route.params; return ( diff --git a/apps/mobile/src/screens/modals/Search.tsx b/apps/mobile/src/screens/modals/Search.tsx index 2654cf46b..14a8ab730 100644 --- a/apps/mobile/src/screens/modals/Search.tsx +++ b/apps/mobile/src/screens/modals/Search.tsx @@ -1,12 +1,11 @@ +import { Button } from '@app/components/primitive/Button'; +import tw from '@app/lib/tailwind'; +import { RootStackScreenProps } from '@app/navigation'; import { MagnifyingGlass } from 'phosphor-react-native'; import React, { useState } from 'react'; import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { Button } from '../../components/base/Button'; -import tw from '../../lib/tailwind'; -import { RootStackScreenProps } from '../../navigation'; - const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => { const { top } = useSafeAreaInsets(); diff --git a/apps/mobile/src/screens/modals/settings/Settings.tsx b/apps/mobile/src/screens/modals/settings/Settings.tsx index 73fd7d643..0e586d1bf 100644 --- a/apps/mobile/src/screens/modals/settings/Settings.tsx +++ b/apps/mobile/src/screens/modals/settings/Settings.tsx @@ -1,9 +1,8 @@ +import tw from '@app/lib/tailwind'; +import { RootStackScreenProps } from '@app/navigation'; import React from 'react'; import { Text, View } from 'react-native'; -import tw from '../../../lib/tailwind'; -import { RootStackScreenProps } from '../../../navigation'; - export default function SettingsScreen({ navigation }: RootStackScreenProps<'Settings'>) { return ( diff --git a/apps/mobile/src/screens/onboarding/Onboarding.tsx b/apps/mobile/src/screens/onboarding/Onboarding.tsx index a56eed859..f8ca2f43b 100644 --- a/apps/mobile/src/screens/onboarding/Onboarding.tsx +++ b/apps/mobile/src/screens/onboarding/Onboarding.tsx @@ -1,13 +1,12 @@ +import { FadeInUpAnimation, LogoAnimation } from '@app/components/animation/layout'; +import { AnimatedButton } from '@app/components/primitive/Button'; +import { setItemToStorage } from '@app/lib/storage'; +import tw from '@app/lib/tailwind'; +import { OnboardingStackScreenProps } from '@app/navigation/OnboardingNavigator'; +import { useOnboardingStore } from '@app/stores/useOnboardingStore'; import React from 'react'; import { Image, Text, View } from 'react-native'; -import { FadeInUpAnimation, LogoAnimation } from '../../components/animation/layout'; -import { AnimatedButton } from '../../components/base/Button'; -import { setItemToStorage } from '../../lib/storage'; -import tw from '../../lib/tailwind'; -import type { OnboardingStackScreenProps } from '../../navigation/OnboardingNavigator'; -import { useOnboardingStore } from '../../stores/useOnboardingStore'; - const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding'>) => { const { hideOnboarding } = useOnboardingStore(); diff --git a/apps/mobile/tsconfig.json b/apps/mobile/tsconfig.json index 3e08e07e7..99a8a6c70 100644 --- a/apps/mobile/tsconfig.json +++ b/apps/mobile/tsconfig.json @@ -1,4 +1,9 @@ { "extends": "expo/tsconfig.base", - "compilerOptions": {} + "compilerOptions": { + "baseUrl": "src", + "paths": { + "@app/*": ["*"] + } + } } From 07ca9d220bc188f0e2d4093ce8b3bd287b4ceeb9 Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Tue, 30 Aug 2022 18:30:49 +0300 Subject: [PATCH 02/15] Fix package.json for interface --- packages/interface/package.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/interface/package.json b/packages/interface/package.json index 96d47df02..8bbff29ec 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -44,8 +44,6 @@ "pretty-bytes": "^6.0.0", "react": "^18.2.0", "react-colorful": "^5.5.1", - "react-dom": "^18.1.0", - "react-dropzone": "^14.2.1", "react-countup": "^6.3.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.2", @@ -65,12 +63,8 @@ "react-virtuoso": "^2.16.5", "rooks": "^5.14.0", "styled-components": "^5.3.5", - "tailwindcss": "^3.0.24", - "use-count-up": "^3.0.1", - "use-debounce": "^8.0.1", - "zustand": "4.0.0-rc.1", "tailwindcss": "^3.1.6", - "use-count-up": "^3.0.1", + "use-count-up": "^3.0.1", "use-debounce": "^8.0.3", "zustand": "4.0.0" }, From 297b9ccb7c09458dcb4e0b2328c1a23efb034f8c Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Wed, 31 Aug 2022 18:42:06 +0800 Subject: [PATCH 03/15] new invalidate_query + add IOS sim to setup script --- .github/scripts/setup-system.sh | 3 ++- core/src/api/files.rs | 13 +----------- core/src/api/utils/invalidate.rs | 35 +++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/.github/scripts/setup-system.sh b/.github/scripts/setup-system.sh index 433f73112..2c8ace653 100755 --- a/.github/scripts/setup-system.sh +++ b/.github/scripts/setup-system.sh @@ -38,7 +38,8 @@ if [ "$1" == "mobile" ]; then exit 1 fi - rustup target add aarch64-apple-ios + rustup target add aarch64-apple-ios + rustup target add aarch64-apple-ios-sim fi # Android requires python diff --git a/core/src/api/files.rs b/core/src/api/files.rs index e8329c6ac..9b08c27fc 100644 --- a/core/src/api/files.rs +++ b/core/src/api/files.rs @@ -30,18 +30,7 @@ pub(crate) fn mount() -> RouterBuilder { .exec() .await?; - invalidate_query!( - library, - "locations.getExplorerDir": LibraryArgs, - LibraryArgs { - library_id: library.id, - arg: GetExplorerDirArgs { - location_id: 0, // TODO: This should be the correct location_id - path: "".into(), - limit: 0, - } - } - ); + invalidate_query!(library, "locations.getExplorerDir"); Ok(()) }) diff --git a/core/src/api/utils/invalidate.rs b/core/src/api/utils/invalidate.rs index df397577d..9eff8d147 100644 --- a/core/src/api/utils/invalidate.rs +++ b/core/src/api/utils/invalidate.rs @@ -34,7 +34,7 @@ impl InvalidateOperationEvent { #[allow(dead_code)] pub(crate) struct InvalidationRequest { pub key: &'static str, - pub arg_ty: DataType, + pub arg_ty: Option, pub macro_src: &'static str, } @@ -58,11 +58,13 @@ impl InvalidRequests { let queries = r.queries(); for req in &invalidate_requests.queries { if let Some(query_ty) = queries.get(req.key) { - if query_ty.ty.arg_ty != req.arg_ty { - panic!( + if let Some(arg) = &req.arg_ty { + if &query_ty.ty.arg_ty != arg { + panic!( "Error at '{}': Attempted to invalid query '{}' but the argument type does not match the type defined on the router.", req.macro_src, req.key ); + } } } else { panic!( @@ -87,6 +89,29 @@ impl InvalidRequests { #[macro_export] #[allow(clippy::crate_in_macro_def)] macro_rules! invalidate_query { + ($ctx:expr, $key:literal) => {{ + let _: &crate::library::LibraryContext = &$ctx; // Assert the context is the correct type + + #[cfg(debug_assertions)] + { + #[ctor::ctor] + fn invalidate() { + crate::api::utils::INVALIDATION_REQUESTS + .get_or_init(|| Default::default()) + .lock() + .unwrap() + .queries + .push(crate::api::utils::InvalidationRequest { + key: $key, + arg_ty: None, + macro_src: concat!(file!(), ":", line!()), + }) + } + } + + // The error are ignored here because they aren't mission critical. If they fail the UI might be outdated for a bit. + crate::api::utils::InvalidateOperationEvent::dangerously_create($key, serde_json::Value::Null) + }}; ($ctx:expr, $key:literal: $arg_ty:ty, $arg:expr) => {{ let _: $arg_ty = $arg; // Assert the type the user provided is correct let ctx: &crate::library::LibraryContext = &$ctx; // Assert the context is the correct type @@ -102,10 +127,10 @@ macro_rules! invalidate_query { .queries .push(crate::api::utils::InvalidationRequest { key: $key, - arg_ty: <$arg_ty as rspc::internal::specta::Type>::reference(rspc::internal::specta::DefOpts { + arg_ty: Some(<$arg_ty as rspc::internal::specta::Type>::reference(rspc::internal::specta::DefOpts { parent_inline: false, type_map: &mut rspc::internal::specta::TypeDefs::new(), - }, &[]), + }, &[])), macro_src: concat!(file!(), ":", line!()), }) } From 83781be27a614a30004e4bb30da28d7b2a9bcf60 Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Thu, 1 Sep 2022 13:45:25 +0300 Subject: [PATCH 04/15] Init libraries with rspc + fix feedback stuff --- apps/mobile/package.json | 1 + apps/mobile/pnpm-lock.yaml | Bin 327018 -> 327263 bytes apps/mobile/src/App.tsx | 79 ++++++++++++------ .../src/components/drawer/DrawerContent.tsx | 22 +++-- .../mobile/src/components/primitive/Input.tsx | 32 +++++++ .../mobile/src/navigation/DrawerNavigator.tsx | 22 ++--- .../src/navigation/OnboardingNavigator.tsx | 3 + apps/mobile/src/navigation/index.tsx | 6 +- .../src/navigation/tabs/BrowseStack.tsx | 11 +-- .../src/navigation/tabs/OverviewStack.tsx | 3 +- .../src/navigation/tabs/PhotosStack.tsx | 3 +- .../src/navigation/tabs/SpacesStack.tsx | 3 +- apps/mobile/src/screens/Overview.tsx | 8 +- apps/mobile/src/screens/modals/Search.tsx | 4 +- .../src/screens/onboarding/CreateLibrary.tsx | 31 +++++++ .../src/screens/onboarding/Onboarding.tsx | 14 +--- apps/mobile/src/stores/useLibraryStore.ts | 72 ++++++++++++++-- 17 files changed, 233 insertions(+), 81 deletions(-) create mode 100644 apps/mobile/src/screens/onboarding/CreateLibrary.tsx diff --git a/apps/mobile/package.json b/apps/mobile/package.json index f915311a1..9b431525d 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -29,6 +29,7 @@ "expo-linking": "~3.2.2", "expo-splash-screen": "~0.16.2", "expo-status-bar": "~1.4.0", + "immer": "^9.0.15", "intl": "^1.2.5", "moti": "^0.18.0", "phosphor-react-native": "^1.1.2", diff --git a/apps/mobile/pnpm-lock.yaml b/apps/mobile/pnpm-lock.yaml index 5fce41495b89a2a9fac6c79745341866bd445de2..f13f916a483a21ba8ce3e146e98dfedde6432108 100644 GIT binary patch delta 236 zcmaF$OZfgD;SG$eyt%olMOF%NmU;$yhNhc;vixD?fe1lG-f}Hu;>`pJIY30ToBMd% z`*<0*_wh2hyyFB)=z}Gu7g{r^g&L(g=@%E5=N4N!x`qa4`{$YjCxw|tnuq0<=qGsx zl{;0Ym>OlJ`DBNi`1?erCWZtUySiq2Sth0zh8p{1fW>6R-gVvla#P1+yLtnF52v4Tr=H0k^~r0z~eIru+i8ru+j(|CjPG V0Wr5L`~)=tmyjR?6qkto1lM~@8)*Ol diff --git a/apps/mobile/src/App.tsx b/apps/mobile/src/App.tsx index 14794ffd7..04e70cb9f 100644 --- a/apps/mobile/src/App.tsx +++ b/apps/mobile/src/App.tsx @@ -8,12 +8,19 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'; import { useDeviceContext } from 'twrnc'; import { GlobalModals } from './components/modals/GlobalModals'; -import { ReactNativeTransport, queryClient, rspc, useInvalidateQuery } from './hooks/rspc'; +import { + ReactNativeTransport, + queryClient, + rspc, + useBridgeQuery, + useInvalidateQuery +} from './hooks/rspc'; import useCachedResources from './hooks/useCachedResources'; import { getItemFromStorage } from './lib/storage'; import tw from './lib/tailwind'; import RootNavigator from './navigation'; import OnboardingNavigator from './navigation/OnboardingNavigator'; +import { useLibraryStore } from './stores/useLibraryStore'; import { useOnboardingStore } from './stores/useOnboardingStore'; import type { Operations } from './types/bindings'; @@ -29,7 +36,7 @@ const NavigatorTheme: Theme = { } }; -export default function App() { +function AppContainer() { // Enables dark mode, and screen size breakpoints, etc. for tailwind useDeviceContext(tw, { withDeviceColorScheme: false }); @@ -37,38 +44,62 @@ export default function App() { const { showOnboarding, hideOnboarding } = useOnboardingStore(); + const { data: libraries } = useBridgeQuery(['library.get']); + + const { switchLibrary, _hasHydrated } = useLibraryStore(); + // Runs when the app is launched useEffect(() => { - getItemFromStorage('@onboarding').then((value) => { - value && hideOnboarding(); - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + async function appLaunch() { + // Check if the user went through onboarding + const didOnboarding = await getItemFromStorage('@onboarding'); + // If user did do onboarding, that means they've already have a library - if (!isLoadingComplete) { + // Temporarly set the first library to be the current library + if (libraries && libraries.length > 0) { + switchLibrary(libraries[0].uuid); + } + + if (didOnboarding) { + hideOnboarding(); + } + } + + appLaunch(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [libraries]); + + // Might need to move _hasHydrated to useCacheResources hook. + if (!isLoadingComplete && !_hasHydrated) { return null; } else { return ( - - <> - - - - - - - {showOnboarding ? : } - - - - - - - + + + + + + {showOnboarding ? : } + + + + + ); } } +export default function App() { + return ( + + <> + + + + + ); +} + function InvalidateQuery() { useInvalidateQuery(); return null; diff --git a/apps/mobile/src/components/drawer/DrawerContent.tsx b/apps/mobile/src/components/drawer/DrawerContent.tsx index 5b7ac971f..f60f0cc64 100644 --- a/apps/mobile/src/components/drawer/DrawerContent.tsx +++ b/apps/mobile/src/components/drawer/DrawerContent.tsx @@ -1,14 +1,14 @@ import Layout from '@app/constants/Layout'; import tw from '@app/lib/tailwind'; +import { useCurrentLibrary, useLibraryStore } from '@app/stores/useLibraryStore'; import { DrawerContentScrollView } from '@react-navigation/drawer'; import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typescript/src/types'; import { getFocusedRouteNameFromRoute } from '@react-navigation/native'; -import React from 'react'; +import React, { useEffect } from 'react'; import { ColorValue, Platform, Pressable, Text, View } from 'react-native'; import { CogIcon } from 'react-native-heroicons/solid'; import CollapsibleView from '../layout/CollapsibleView'; -import { Tooltip } from '../tooltip/Tooltip'; import DrawerLocationItem from './DrawerLocationItem'; import DrawerLogo from './DrawerLogo'; import DrawerTagItem from './DrawerTagItem'; @@ -57,12 +57,22 @@ const getActiveRouteState = function (state: any) { const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => { const stackName = getFocusedRouteNameFromRoute(getActiveRouteState(state)) ?? 'OverviewStack'; + // initialize libraries + const { init: initLibraries, switchLibrary } = useLibraryStore(); + const { currentLibrary, libraries, currentLibraryUuid } = useCurrentLibrary(); + + useEffect(() => { + if (libraries && !currentLibraryUuid) initLibraries(libraries); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [libraries, currentLibraryUuid]); + return ( TODO: Library Selection + {libraries[0].config.name} {/* Locations */} { {/* Settings */} - - navigation.navigate('Settings')}> - - - + navigation.navigate('Settings')}> + + ); diff --git a/apps/mobile/src/components/primitive/Input.tsx b/apps/mobile/src/components/primitive/Input.tsx index e69de29bb..4b92cb74e 100644 --- a/apps/mobile/src/components/primitive/Input.tsx +++ b/apps/mobile/src/components/primitive/Input.tsx @@ -0,0 +1,32 @@ +import tw from '@app/lib/tailwind'; +import { VariantProps, cva } from 'class-variance-authority'; +import React from 'react'; +import { TextInput as RNTextInput, TextInputProps as RNTextInputProps } from 'react-native'; + +const input = cva(['text-sm rounded-md border shadow-sm'], { + variants: { + variant: { + default: 'bg-gray-550 border-gray-500 text-white' + }, + size: { + default: ['py-2', 'px-3'] + } + }, + defaultVariants: { + variant: 'default', + size: 'default' + } +}); + +type InputProps = VariantProps & RNTextInputProps; + +export const TextInput: React.FC = ({ variant, ...props }) => { + const { style, ...otherProps } = props; + return ( + + ); +}; diff --git a/apps/mobile/src/navigation/DrawerNavigator.tsx b/apps/mobile/src/navigation/DrawerNavigator.tsx index 30e298b36..621a75222 100644 --- a/apps/mobile/src/navigation/DrawerNavigator.tsx +++ b/apps/mobile/src/navigation/DrawerNavigator.tsx @@ -13,19 +13,15 @@ export default function DrawerNavigator() { return ( { - return { - headerShown: false, - drawerStyle: { - backgroundColor: '#08090D', - width: '75%' - }, - overlayColor: 'transparent', - drawerType: 'slide' - // swipeEnabled: false - // drawerHideStatusBarOnOpen: true, - // drawerStatusBarAnimation: 'slide' - }; + screenOptions={{ + headerShown: false, + drawerStyle: { + backgroundColor: '#08090D', + width: '75%' + }, + overlayColor: 'transparent', + drawerType: 'slide', + swipeEdgeWidth: 50 }} drawerContent={(props) => } > diff --git a/apps/mobile/src/navigation/OnboardingNavigator.tsx b/apps/mobile/src/navigation/OnboardingNavigator.tsx index 0a2b07924..96b7f1a04 100644 --- a/apps/mobile/src/navigation/OnboardingNavigator.tsx +++ b/apps/mobile/src/navigation/OnboardingNavigator.tsx @@ -1,3 +1,4 @@ +import CreateLibraryScreen from '@app/screens/onboarding/CreateLibrary'; import OnboardingScreen from '@app/screens/onboarding/Onboarding'; import { StackScreenProps, createStackNavigator } from '@react-navigation/stack'; @@ -7,12 +8,14 @@ export default function OnboardingNavigator() { return ( + ); } export type OnboardingStackParamList = { Onboarding: undefined; + CreateLibrary: undefined; }; export type OnboardingStackScreenProps = diff --git a/apps/mobile/src/navigation/index.tsx b/apps/mobile/src/navigation/index.tsx index 2dabc5711..f36c514eb 100644 --- a/apps/mobile/src/navigation/index.tsx +++ b/apps/mobile/src/navigation/index.tsx @@ -15,7 +15,11 @@ export default function RootNavigator() { - + {/* Modals */} diff --git a/apps/mobile/src/navigation/tabs/OverviewStack.tsx b/apps/mobile/src/navigation/tabs/OverviewStack.tsx index 2245402eb..e1ed17a9d 100644 --- a/apps/mobile/src/navigation/tabs/OverviewStack.tsx +++ b/apps/mobile/src/navigation/tabs/OverviewStack.tsx @@ -14,8 +14,7 @@ export default function OverviewStack() { initialRouteName="Overview" screenOptions={{ headerStyle: { backgroundColor: '#08090D' }, - headerTintColor: '#fff', - ...TransitionPresets.ModalFadeTransition + headerTintColor: '#fff' }} > diff --git a/apps/mobile/src/navigation/tabs/PhotosStack.tsx b/apps/mobile/src/navigation/tabs/PhotosStack.tsx index f97e49889..c417dfc45 100644 --- a/apps/mobile/src/navigation/tabs/PhotosStack.tsx +++ b/apps/mobile/src/navigation/tabs/PhotosStack.tsx @@ -14,8 +14,7 @@ export default function PhotosStack() { initialRouteName="Photos" screenOptions={{ headerStyle: { backgroundColor: '#08090D' }, - headerTintColor: '#fff', - ...TransitionPresets.ModalFadeTransition + headerTintColor: '#fff' }} > diff --git a/apps/mobile/src/navigation/tabs/SpacesStack.tsx b/apps/mobile/src/navigation/tabs/SpacesStack.tsx index ff9fe6f03..1eb9c9f13 100644 --- a/apps/mobile/src/navigation/tabs/SpacesStack.tsx +++ b/apps/mobile/src/navigation/tabs/SpacesStack.tsx @@ -14,8 +14,7 @@ export default function SpacesStack() { initialRouteName="Spaces" screenOptions={{ headerStyle: { backgroundColor: '#08090D' }, - headerTintColor: '#fff', - ...TransitionPresets.ModalFadeTransition + headerTintColor: '#fff' }} > diff --git a/apps/mobile/src/screens/Overview.tsx b/apps/mobile/src/screens/Overview.tsx index f9f7f2747..9ef10e968 100644 --- a/apps/mobile/src/screens/Overview.tsx +++ b/apps/mobile/src/screens/Overview.tsx @@ -1,7 +1,9 @@ import Device from '@app/components/device/Device'; import Dialog from '@app/components/layout/Dialog'; import VirtualizedListWrapper from '@app/components/layout/VirtualizedListWrapper'; +import { TextInput } from '@app/components/primitive/Input'; import OverviewStats from '@app/containers/OverviewStats'; +import { useLibraryQuery } from '@app/hooks/rspc'; import tw from '@app/lib/tailwind'; import { OverviewStackScreenProps } from '@app/navigation/tabs/OverviewStack'; import React from 'react'; @@ -61,11 +63,11 @@ export default function OverviewScreen({ navigation }: OverviewStackScreenProps< Dialog } - /> + > + + {/* Stats */} - {/* Spacing */} - {/* Devices */} ) => { const [loading, setLoading] = useState(false); + // TODO: Animations! + return ( {/* Header */} {/* Search Input */} - + {loading ? ( diff --git a/apps/mobile/src/screens/onboarding/CreateLibrary.tsx b/apps/mobile/src/screens/onboarding/CreateLibrary.tsx new file mode 100644 index 000000000..00fb93cd7 --- /dev/null +++ b/apps/mobile/src/screens/onboarding/CreateLibrary.tsx @@ -0,0 +1,31 @@ +import { AnimatedButton } from '@app/components/primitive/Button'; +import { setItemToStorage } from '@app/lib/storage'; +import tw from '@app/lib/tailwind'; +import { OnboardingStackScreenProps } from '@app/navigation/OnboardingNavigator'; +import { useOnboardingStore } from '@app/stores/useOnboardingStore'; +import React from 'react'; +import { Text, View } from 'react-native'; + +const CreateLibraryScreen = ({ navigation }: OnboardingStackScreenProps<'CreateLibrary'>) => { + const { hideOnboarding } = useOnboardingStore(); + + function onButtonPress() { + setItemToStorage('@onboarding', '1'); + // TODO: Add a loading indicator to button as this takes a second or so. + hideOnboarding(); + } + return ( + + + Onboarding screen for users to create their first library + + + + Create Library + + + + ); +}; + +export default CreateLibraryScreen; diff --git a/apps/mobile/src/screens/onboarding/Onboarding.tsx b/apps/mobile/src/screens/onboarding/Onboarding.tsx index f8ca2f43b..dba1dd8fb 100644 --- a/apps/mobile/src/screens/onboarding/Onboarding.tsx +++ b/apps/mobile/src/screens/onboarding/Onboarding.tsx @@ -1,21 +1,11 @@ import { FadeInUpAnimation, LogoAnimation } from '@app/components/animation/layout'; import { AnimatedButton } from '@app/components/primitive/Button'; -import { setItemToStorage } from '@app/lib/storage'; import tw from '@app/lib/tailwind'; import { OnboardingStackScreenProps } from '@app/navigation/OnboardingNavigator'; -import { useOnboardingStore } from '@app/stores/useOnboardingStore'; import React from 'react'; import { Image, Text, View } from 'react-native'; const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding'>) => { - const { hideOnboarding } = useOnboardingStore(); - - function onButtonPress() { - setItemToStorage('@onboarding', '1'); - // TODO: Add a loading indicator to button as this takes a second or so. - hideOnboarding(); - } - return ( {/* Logo */} @@ -25,7 +15,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding {/* Text */} - + A file explorer from the future. @@ -40,7 +30,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding {/* Get Started Button */} - + navigation.navigate('CreateLibrary')}> Get Started diff --git a/apps/mobile/src/stores/useLibraryStore.ts b/apps/mobile/src/stores/useLibraryStore.ts index 77294c4cc..e5be837af 100644 --- a/apps/mobile/src/stores/useLibraryStore.ts +++ b/apps/mobile/src/stores/useLibraryStore.ts @@ -1,13 +1,73 @@ +import { useBridgeQuery } from '@app/hooks/rspc'; +import { LibraryConfigWrapped } from '@app/types/bindings'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import produce from 'immer'; +import { useMemo } from 'react'; import create from 'zustand'; +import { persist } from 'zustand/middleware'; interface LibraryStore { + _hasHydrated: boolean; + setHasHydrated: (hasHydrated: boolean) => void; currentLibraryUuid: string | null; switchLibrary: (id: string) => void; + init: (libraries: LibraryConfigWrapped[]) => Promise; } -export const useLibraryStore = create()((set) => ({ - currentLibraryUuid: null, - switchLibrary: (uuid) => { - set((state) => ({ currentLibraryUuid: uuid })); - } -})); +export const useLibraryStore = create()( + persist( + (set) => ({ + _hasHydrated: false, + setHasHydrated: (state) => { + set({ _hasHydrated: state }); + }, + currentLibraryUuid: null, + switchLibrary: (uuid) => { + set((state) => + produce(state, (draft) => { + draft.currentLibraryUuid = uuid; + }) + ); + // reset other stores + }, + init: async (libraries) => { + set((state) => + produce(state, (draft) => { + // use first library default if none set + if (!state.currentLibraryUuid) { + draft.currentLibraryUuid = libraries[0].uuid; + } + }) + ); + } + }), + { + name: 'sd-library-store', + getStorage: () => AsyncStorage, + // Since storage is async, app needs to stay in loading state until hydrated! + onRehydrateStorage: () => (state) => { + state.setHasHydrated(true); + } + } + ) +); + +// this must be used at least once in the app to correct the initial state +// is memorized and can be used safely in any component +export const useCurrentLibrary = () => { + const { currentLibraryUuid, switchLibrary } = useLibraryStore(); + const { data: libraries } = useBridgeQuery(['library.get']); + + // memorize library to avoid re-running find function + const currentLibrary = useMemo(() => { + const current = libraries?.find((l) => l.uuid === currentLibraryUuid); + // switch to first library if none set + if (Array.isArray(libraries) && !current && libraries[0]?.uuid) { + switchLibrary(libraries[0]?.uuid); + } + return current; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [libraries, currentLibraryUuid]); + + return { currentLibrary, libraries, currentLibraryUuid }; +}; From 61f9d0a944bf6aaaf1cbdfc1e018e2e38110277d Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:21:12 +0300 Subject: [PATCH 05/15] Align color with desktop & start library selector --- apps/mobile/src/App.tsx | 4 +- .../src/components/drawer/DrawerContent.tsx | 87 ++++++++++--------- .../drawer/DrawerLibraryManager.tsx | 34 ++++++++ .../components/drawer/DrawerLocationItem.tsx | 2 +- .../src/components/drawer/DrawerLogo.tsx | 19 ---- .../src/components/drawer/DrawerTagItem.tsx | 2 +- apps/mobile/src/components/header/Header.tsx | 8 +- .../src/components/layout/CollapsibleView.tsx | 10 +-- apps/mobile/src/navigation/TabNavigator.tsx | 6 +- apps/mobile/src/navigation/index.tsx | 9 +- .../src/navigation/tabs/BrowseStack.tsx | 7 +- .../src/navigation/tabs/OverviewStack.tsx | 7 +- .../src/navigation/tabs/PhotosStack.tsx | 7 +- .../src/navigation/tabs/SpacesStack.tsx | 7 +- apps/mobile/src/screens/modals/Search.tsx | 4 +- .../src/screens/onboarding/CreateLibrary.tsx | 2 +- .../src/screens/onboarding/Onboarding.tsx | 2 +- 17 files changed, 124 insertions(+), 93 deletions(-) create mode 100644 apps/mobile/src/components/drawer/DrawerLibraryManager.tsx delete mode 100644 apps/mobile/src/components/drawer/DrawerLogo.tsx diff --git a/apps/mobile/src/App.tsx b/apps/mobile/src/App.tsx index 04e70cb9f..acde9ab58 100644 --- a/apps/mobile/src/App.tsx +++ b/apps/mobile/src/App.tsx @@ -32,7 +32,7 @@ const NavigatorTheme: Theme = { ...DefaultTheme, colors: { ...DefaultTheme.colors, - background: '#08090D' + background: tw.color('gray-650') } }; @@ -74,7 +74,7 @@ function AppContainer() { return null; } else { return ( - + diff --git a/apps/mobile/src/components/drawer/DrawerContent.tsx b/apps/mobile/src/components/drawer/DrawerContent.tsx index f60f0cc64..81680edad 100644 --- a/apps/mobile/src/components/drawer/DrawerContent.tsx +++ b/apps/mobile/src/components/drawer/DrawerContent.tsx @@ -1,16 +1,16 @@ import Layout from '@app/constants/Layout'; import tw from '@app/lib/tailwind'; -import { useCurrentLibrary, useLibraryStore } from '@app/stores/useLibraryStore'; import { DrawerContentScrollView } from '@react-navigation/drawer'; import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typescript/src/types'; import { getFocusedRouteNameFromRoute } from '@react-navigation/native'; -import React, { useEffect } from 'react'; -import { ColorValue, Platform, Pressable, Text, View } from 'react-native'; +import React from 'react'; +import { ColorValue, Image, Platform, Pressable, Text, View } from 'react-native'; import { CogIcon } from 'react-native-heroicons/solid'; import CollapsibleView from '../layout/CollapsibleView'; +import Divider from '../primitive/Divider'; +import DrawerLibraryManager from './DrawerLibraryManager'; import DrawerLocationItem from './DrawerLocationItem'; -import DrawerLogo from './DrawerLogo'; import DrawerTagItem from './DrawerTagItem'; const placeholderLocationData = [ @@ -57,39 +57,37 @@ const getActiveRouteState = function (state: any) { const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => { const stackName = getFocusedRouteNameFromRoute(getActiveRouteState(state)) ?? 'OverviewStack'; - // initialize libraries - const { init: initLibraries, switchLibrary } = useLibraryStore(); - const { currentLibrary, libraries, currentLibraryUuid } = useCurrentLibrary(); - - useEffect(() => { - if (libraries && !currentLibraryUuid) initLibraries(libraries); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [libraries, currentLibraryUuid]); - return ( - - TODO: Library Selection - {libraries[0].config.name} + + + Spacedrive + + + {/* Library Manager */} + {/* Locations */} - {placeholderLocationData.map((location) => ( - - navigation.navigate(stackName, { - screen: 'Location', - params: { id: location.id } - }) - } - /> - ))} + + {placeholderLocationData.map((location) => ( + + navigation.navigate(stackName, { + screen: 'Location', + params: { id: location.id } + }) + } + /> + ))} + {/* Add Location */} @@ -100,21 +98,24 @@ const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => { {/* Tags */} - {placeholderTagsData.map((tag) => ( - - navigation.navigate(stackName, { - screen: 'Tag', - params: { id: tag.id } - }) - } - tagColor={tag.color as ColorValue} - /> - ))} + + {placeholderTagsData.map((tag) => ( + + navigation.navigate(stackName, { + screen: 'Tag', + params: { id: tag.id } + }) + } + tagColor={tag.color as ColorValue} + /> + ))} + {/* Settings */} diff --git a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx new file mode 100644 index 000000000..441ed5226 --- /dev/null +++ b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx @@ -0,0 +1,34 @@ +import tw from '@app/lib/tailwind'; +import { useCurrentLibrary, useLibraryStore } from '@app/stores/useLibraryStore'; +import React, { useEffect } from 'react'; +import { Text, View } from 'react-native'; +import { ChevronDownIcon } from 'react-native-heroicons/solid'; + +import { AnimatedHeight } from '../animation/layout'; + +const DrawerLibraryManager = () => { + // init libraries + const { init: initLibraries, switchLibrary } = useLibraryStore(); + const { currentLibrary, libraries, currentLibraryUuid } = useCurrentLibrary(); + + useEffect(() => { + if (libraries && !currentLibraryUuid) initLibraries(libraries); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [libraries, currentLibraryUuid]); + + return ( + + + {currentLibrary.config.name} + + + + Helo + + + ); +}; + +export default DrawerLibraryManager; diff --git a/apps/mobile/src/components/drawer/DrawerLocationItem.tsx b/apps/mobile/src/components/drawer/DrawerLocationItem.tsx index a838a9013..03bf368e8 100644 --- a/apps/mobile/src/components/drawer/DrawerLocationItem.tsx +++ b/apps/mobile/src/components/drawer/DrawerLocationItem.tsx @@ -13,7 +13,7 @@ const DrawerLocationItem: React.FC = (props) => { const { folderName, onPress } = props; return ( - + {folderName} diff --git a/apps/mobile/src/components/drawer/DrawerLogo.tsx b/apps/mobile/src/components/drawer/DrawerLogo.tsx deleted file mode 100644 index f0c2f6af6..000000000 --- a/apps/mobile/src/components/drawer/DrawerLogo.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import tw from '@app/lib/tailwind'; -import React from 'react'; -import { Image, Text, View } from 'react-native'; - -import Divider from '../primitive/Divider'; - -const DrawerLogo = () => { - return ( - <> - - - Spacedrive - - - - ); -}; - -export default DrawerLogo; diff --git a/apps/mobile/src/components/drawer/DrawerTagItem.tsx b/apps/mobile/src/components/drawer/DrawerTagItem.tsx index a37e3f65e..51c3ffc4f 100644 --- a/apps/mobile/src/components/drawer/DrawerTagItem.tsx +++ b/apps/mobile/src/components/drawer/DrawerTagItem.tsx @@ -12,7 +12,7 @@ const DrawerTagItem: React.FC = (props) => { const { tagName, tagColor, onPress } = props; return ( - + {tagName} diff --git a/apps/mobile/src/components/header/Header.tsx b/apps/mobile/src/components/header/Header.tsx index f35478e13..f48ec8afe 100644 --- a/apps/mobile/src/components/header/Header.tsx +++ b/apps/mobile/src/components/header/Header.tsx @@ -16,7 +16,11 @@ const Header = () => { const isDrawerOpen = useDrawerStatus() === 'open'; return ( - + navigation.openDrawer()}> { style={tw`flex-1 h-full justify-center`} onPress={() => navigation.navigate('Search')} > - Search + Search diff --git a/apps/mobile/src/components/layout/CollapsibleView.tsx b/apps/mobile/src/components/layout/CollapsibleView.tsx index dbaa25942..f8712e96c 100644 --- a/apps/mobile/src/components/layout/CollapsibleView.tsx +++ b/apps/mobile/src/components/layout/CollapsibleView.tsx @@ -3,6 +3,7 @@ import { Ionicons } from '@expo/vector-icons'; import { MotiView } from 'moti'; import React, { useReducer } from 'react'; import { Pressable, StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native'; +import { ChevronRightIcon } from 'react-native-heroicons/solid'; import { AnimatedHeight } from '../animation/layout'; @@ -18,7 +19,7 @@ const CollapsibleView = ({ title, titleStyle, containerStyle, children }: Collap return ( - + {title} @@ -30,12 +31,7 @@ const CollapsibleView = ({ title, titleStyle, containerStyle, children }: Collap }} transition={{ type: 'spring' }} > - + {children} diff --git a/apps/mobile/src/navigation/TabNavigator.tsx b/apps/mobile/src/navigation/TabNavigator.tsx index cfc6f4c9c..6fbd54ed5 100644 --- a/apps/mobile/src/navigation/TabNavigator.tsx +++ b/apps/mobile/src/navigation/TabNavigator.tsx @@ -18,11 +18,11 @@ export default function TabNavigator() { initialRouteName="OverviewStack" screenOptions={{ headerShown: false, - tabBarActiveTintColor: tw.color('bg-primary'), + tabBarActiveTintColor: tw.color('primary'), tabBarInactiveTintColor: 'white', tabBarStyle: { - backgroundColor: '#08090D', - borderTopColor: 'transparent' + backgroundColor: tw.color('gray-650'), + borderTopColor: tw.color('gray-600') } }} > diff --git a/apps/mobile/src/navigation/index.tsx b/apps/mobile/src/navigation/index.tsx index f36c514eb..6000e4aa8 100644 --- a/apps/mobile/src/navigation/index.tsx +++ b/apps/mobile/src/navigation/index.tsx @@ -1,3 +1,4 @@ +import tw from '@app/lib/tailwind'; import NotFoundScreen from '@app/screens/NotFound'; import SearchScreen from '@app/screens/modals/Search'; import SettingsScreen from '@app/screens/modals/settings/Settings'; @@ -25,9 +26,11 @@ export default function RootNavigator() { screenOptions={{ presentation: 'modal', headerBackTitleVisible: false, - headerStyle: { backgroundColor: '#08090D' }, - // headerShadowVisible: false, - headerTintColor: '#fff' + headerStyle: tw`bg-gray-650`, + headerTintColor: tw.color('gray-200'), + headerTitleStyle: tw`text-base`, + headerBackTitleStyle: tw`text-base` + // headerShadowVisible: false // will disable the white line under }} > diff --git a/apps/mobile/src/navigation/tabs/BrowseStack.tsx b/apps/mobile/src/navigation/tabs/BrowseStack.tsx index 5015b4013..236e5faa2 100644 --- a/apps/mobile/src/navigation/tabs/BrowseStack.tsx +++ b/apps/mobile/src/navigation/tabs/BrowseStack.tsx @@ -1,4 +1,5 @@ import Header from '@app/components/header/Header'; +import tw from '@app/lib/tailwind'; import BrowseScreen from '@app/screens/Browse'; import { CompositeScreenProps } from '@react-navigation/native'; import { StackScreenProps, createStackNavigator } from '@react-navigation/stack'; @@ -13,8 +14,10 @@ export default function BrowseStack() { diff --git a/apps/mobile/src/navigation/tabs/OverviewStack.tsx b/apps/mobile/src/navigation/tabs/OverviewStack.tsx index e1ed17a9d..b71125555 100644 --- a/apps/mobile/src/navigation/tabs/OverviewStack.tsx +++ b/apps/mobile/src/navigation/tabs/OverviewStack.tsx @@ -1,3 +1,4 @@ +import tw from '@app/lib/tailwind'; import { CompositeScreenProps } from '@react-navigation/native'; import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack'; @@ -13,8 +14,10 @@ export default function OverviewStack() { diff --git a/apps/mobile/src/navigation/tabs/PhotosStack.tsx b/apps/mobile/src/navigation/tabs/PhotosStack.tsx index c417dfc45..29e74e97c 100644 --- a/apps/mobile/src/navigation/tabs/PhotosStack.tsx +++ b/apps/mobile/src/navigation/tabs/PhotosStack.tsx @@ -1,3 +1,4 @@ +import tw from '@app/lib/tailwind'; import { CompositeScreenProps } from '@react-navigation/native'; import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack'; @@ -13,8 +14,10 @@ export default function PhotosStack() { diff --git a/apps/mobile/src/navigation/tabs/SpacesStack.tsx b/apps/mobile/src/navigation/tabs/SpacesStack.tsx index 1eb9c9f13..8239f6f01 100644 --- a/apps/mobile/src/navigation/tabs/SpacesStack.tsx +++ b/apps/mobile/src/navigation/tabs/SpacesStack.tsx @@ -1,3 +1,4 @@ +import tw from '@app/lib/tailwind'; import { CompositeScreenProps } from '@react-navigation/native'; import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack'; @@ -13,8 +14,10 @@ export default function SpacesStack() { diff --git a/apps/mobile/src/screens/modals/Search.tsx b/apps/mobile/src/screens/modals/Search.tsx index 0b2373332..3eb28a830 100644 --- a/apps/mobile/src/screens/modals/Search.tsx +++ b/apps/mobile/src/screens/modals/Search.tsx @@ -18,7 +18,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => { {/* Header */} {/* Search Input */} - + {loading ? ( @@ -32,7 +32,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => { clearButtonMode="never" // can't change the color?? underlineColorAndroid="transparent" placeholderTextColor={tw.color('gray-300')} - style={tw`text-white flex-1 text-sm`} + style={tw`flex-1 text-gray-300 font-medium text-sm`} textContentType={'none'} autoFocus autoCapitalize="none" diff --git a/apps/mobile/src/screens/onboarding/CreateLibrary.tsx b/apps/mobile/src/screens/onboarding/CreateLibrary.tsx index 00fb93cd7..31e2ceded 100644 --- a/apps/mobile/src/screens/onboarding/CreateLibrary.tsx +++ b/apps/mobile/src/screens/onboarding/CreateLibrary.tsx @@ -15,7 +15,7 @@ const CreateLibraryScreen = ({ navigation }: OnboardingStackScreenProps<'CreateL hideOnboarding(); } return ( - + Onboarding screen for users to create their first library diff --git a/apps/mobile/src/screens/onboarding/Onboarding.tsx b/apps/mobile/src/screens/onboarding/Onboarding.tsx index dba1dd8fb..cab0aa776 100644 --- a/apps/mobile/src/screens/onboarding/Onboarding.tsx +++ b/apps/mobile/src/screens/onboarding/Onboarding.tsx @@ -7,7 +7,7 @@ import { Image, Text, View } from 'react-native'; const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding'>) => { return ( - + {/* Logo */} From 674b95f5cdad25405b4bdaa334a40633cd0050ae Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Sun, 4 Sep 2022 15:14:28 +0300 Subject: [PATCH 06/15] Library menu & create library modal --- apps/mobile/ios/Spacedrive/Info.plist | 8 +- apps/mobile/package.json | 3 +- apps/mobile/pnpm-lock.yaml | Bin 327263 -> 328299 bytes apps/mobile/src/App.tsx | 9 +- .../src/components/drawer/DrawerContent.tsx | 2 +- .../drawer/DrawerLibraryManager.tsx | 108 ++++++++++++++++-- apps/mobile/src/components/header/Header.tsx | 2 +- .../src/components/layout/CollapsibleView.tsx | 3 +- apps/mobile/src/components/layout/Dialog.tsx | 9 +- apps/mobile/src/hooks/useCachedResources.ts | 5 - .../mobile/src/navigation/DrawerNavigator.tsx | 2 +- apps/mobile/src/screens/Overview.tsx | 19 +-- apps/mobile/src/screens/modals/Search.tsx | 4 +- 13 files changed, 124 insertions(+), 50 deletions(-) diff --git a/apps/mobile/ios/Spacedrive/Info.plist b/apps/mobile/ios/Spacedrive/Info.plist index d9d78a1b6..544e7b24b 100644 --- a/apps/mobile/ios/Spacedrive/Info.plist +++ b/apps/mobile/ios/Spacedrive/Info.plist @@ -2,10 +2,6 @@ - UIBackgroundModes - - remote-notification - CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -51,6 +47,10 @@ + UIBackgroundModes + + remote-notification + UILaunchStoryboardName SplashScreen UIRequiredDeviceCapabilities diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 9b431525d..6b86af1a9 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -10,7 +10,6 @@ "lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit" }, "dependencies": { - "@expo/vector-icons": "^13.0.0", "@gorhom/bottom-sheet": "^4.4.3", "@react-native-async-storage/async-storage": "~1.17.3", "@react-native-masked-view/masked-view": "0.2.7", @@ -25,12 +24,12 @@ "class-variance-authority": "^0.2.3", "date-fns": "^2.29.2", "expo": "~46.0.9", - "expo-font": "~10.2.0", "expo-linking": "~3.2.2", "expo-splash-screen": "~0.16.2", "expo-status-bar": "~1.4.0", "immer": "^9.0.15", "intl": "^1.2.5", + "lottie-react-native": "^5.1.4", "moti": "^0.18.0", "phosphor-react-native": "^1.1.2", "react": "18.0.0", diff --git a/apps/mobile/pnpm-lock.yaml b/apps/mobile/pnpm-lock.yaml index f13f916a483a21ba8ce3e146e98dfedde6432108..0055d8d8c91d23495dc0116cb226324640fe2a33 100644 GIT binary patch delta 637 zcmZvZO>EL&7{~KMN293IK%5ziGNYm)w3P2I*&-hT0_Ags(!)$kOINkM&c1C0g{CJ+vOl z(o}Mgj|$o9ffi1Lc(NSg!eeimt_g*HqL60>M6l{q8hn1A;BwJ!OCqa9Qi8w+)(#z6 z!_1L2ezV;8*9Sk}?;)Mh0_{?Q^i*n1r_MZL0#dz!lQp^5Qx4o}s=)Rn#$D3d37x?e zR`XGOI)^KnaCe*(#-1`+)_M)1gHxIMXVx{NL}Sa=5r_~Vsv4KhtoflnG> z{CJJ4i>@Vsp93TvqerUjW1V3sg|ma4pAL4t zS}96Lno20O8%pT$R#eO}O_HYsr?1!ODlwg^cI&)6V$xD36r!BTVVlO&kBMqL8;}MC wb{tu#-h-XtB7eXg`n^~2hiD@Tgb`hKL(D`Q~&?~ delta 122 zcmaFeB69za@PwMl3%;;UU%rBgpFPgdSkFMuV6p(a{KiSQnR(Ol^Gd7~>I@C^jDVtv zEM1d>1w=P1v3_Tq%>NgxM`p7)yDIbaZ7Z2nCg-wnPIl$$Xy)W@=j3MG&dJU6%c*^# ZAJg`Qe#}pVx1UO3Zr!_mo-)hXdjN~GECT=l diff --git a/apps/mobile/src/App.tsx b/apps/mobile/src/App.tsx index acde9ab58..120841ab5 100644 --- a/apps/mobile/src/App.tsx +++ b/apps/mobile/src/App.tsx @@ -44,7 +44,13 @@ function AppContainer() { const { showOnboarding, hideOnboarding } = useOnboardingStore(); - const { data: libraries } = useBridgeQuery(['library.get']); + const { data: libraries } = useBridgeQuery(['library.get'], { + onError(err) { + console.error(err); + } + }); + + console.log(libraries); const { switchLibrary, _hasHydrated } = useLibraryStore(); @@ -56,6 +62,7 @@ function AppContainer() { // If user did do onboarding, that means they've already have a library // Temporarly set the first library to be the current library + if (libraries && libraries.length > 0) { switchLibrary(libraries[0].uuid); } diff --git a/apps/mobile/src/components/drawer/DrawerContent.tsx b/apps/mobile/src/components/drawer/DrawerContent.tsx index 81680edad..bddbc61d3 100644 --- a/apps/mobile/src/components/drawer/DrawerContent.tsx +++ b/apps/mobile/src/components/drawer/DrawerContent.tsx @@ -62,7 +62,7 @@ const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => { - + Spacedrive diff --git a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx index 441ed5226..9d126267d 100644 --- a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx +++ b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx @@ -1,13 +1,21 @@ +import { useBridgeMutation } from '@app/hooks/rspc'; import tw from '@app/lib/tailwind'; import { useCurrentLibrary, useLibraryStore } from '@app/stores/useLibraryStore'; -import React, { useEffect } from 'react'; -import { Text, View } from 'react-native'; -import { ChevronDownIcon } from 'react-native-heroicons/solid'; +import { MotiView } from 'moti'; +import React, { useEffect, useState } from 'react'; +import { Pressable, Text, View } from 'react-native'; +import { LockClosedIcon } from 'react-native-heroicons/outline'; +import { ChevronRightIcon, CogIcon, PlusIcon } from 'react-native-heroicons/solid'; import { AnimatedHeight } from '../animation/layout'; +import Dialog from '../layout/Dialog'; +import Divider from '../primitive/Divider'; +import { TextInput } from '../primitive/Input'; const DrawerLibraryManager = () => { - // init libraries + const [hide, setHide] = useState(true); + + // Init Libraries const { init: initLibraries, switchLibrary } = useLibraryStore(); const { currentLibrary, libraries, currentLibraryUuid } = useCurrentLibrary(); @@ -16,16 +24,92 @@ const DrawerLibraryManager = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [libraries, currentLibraryUuid]); + // Create Library + const [libName, setLibName] = useState(''); + + const { mutate: createLibrary, isLoading: createLibLoading } = useBridgeMutation( + 'library.create', + { + onSuccess: () => { + setHide(true); + }, + onError: (err) => { + // TODO: Show toast? + console.log(err); + } + } + ); + return ( - - {currentLibrary.config.name} - - - - Helo + setHide((v) => !v)}> + + {currentLibrary?.config.name} + + + + + + + + {/* Libraries */} + {libraries?.map((library) => ( + + + {library.config.name} + + + ))} + + {/* Menu */} + console.log('settings')}> + + + Library Settings + + + createLibrary(libName)} + trigger={ + + + Add Library + + } + > + setLibName(text)} + placeholder="My Cool Library" + /> + + console.log('lock')}> + + + Lock + + + ); diff --git a/apps/mobile/src/components/header/Header.tsx b/apps/mobile/src/components/header/Header.tsx index f48ec8afe..f64764079 100644 --- a/apps/mobile/src/components/header/Header.tsx +++ b/apps/mobile/src/components/header/Header.tsx @@ -17,7 +17,7 @@ const Header = () => { return ( diff --git a/apps/mobile/src/components/layout/CollapsibleView.tsx b/apps/mobile/src/components/layout/CollapsibleView.tsx index f8712e96c..bf0a78392 100644 --- a/apps/mobile/src/components/layout/CollapsibleView.tsx +++ b/apps/mobile/src/components/layout/CollapsibleView.tsx @@ -1,5 +1,4 @@ import tw from '@app/lib/tailwind'; -import { Ionicons } from '@expo/vector-icons'; import { MotiView } from 'moti'; import React, { useReducer } from 'react'; import { Pressable, StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native'; @@ -29,7 +28,7 @@ const CollapsibleView = ({ title, titleStyle, containerStyle, children }: Collap translateX: hide ? 0 : 5, translateY: hide ? 0 : 5 }} - transition={{ type: 'spring' }} + transition={{ type: 'timing' }} > diff --git a/apps/mobile/src/components/layout/Dialog.tsx b/apps/mobile/src/components/layout/Dialog.tsx index 283e49dd9..e04784c3b 100644 --- a/apps/mobile/src/components/layout/Dialog.tsx +++ b/apps/mobile/src/components/layout/Dialog.tsx @@ -63,7 +63,7 @@ const Dialog = (props: DialogProps) => { )} {/* Children */} - {props.children} + {props.children} {/* Actions */} { Close {props.ctaAction && ( - )} diff --git a/apps/mobile/src/hooks/useCachedResources.ts b/apps/mobile/src/hooks/useCachedResources.ts index 50770266b..1d99fb5f5 100644 --- a/apps/mobile/src/hooks/useCachedResources.ts +++ b/apps/mobile/src/hooks/useCachedResources.ts @@ -1,5 +1,3 @@ -import { FontAwesome } from '@expo/vector-icons'; -import * as Font from 'expo-font'; import * as SplashScreen from 'expo-splash-screen'; import { useEffect, useState } from 'react'; import { Platform } from 'react-native'; @@ -28,9 +26,6 @@ export default function useCachedResources() { SplashScreen.preventAutoHideAsync(); // Load fonts, icons etc. - await Font.loadAsync({ - ...FontAwesome.font - }); } catch (e) { // We might want to provide this error information to an error reporting service console.warn(e); diff --git a/apps/mobile/src/navigation/DrawerNavigator.tsx b/apps/mobile/src/navigation/DrawerNavigator.tsx index 621a75222..77c9efff8 100644 --- a/apps/mobile/src/navigation/DrawerNavigator.tsx +++ b/apps/mobile/src/navigation/DrawerNavigator.tsx @@ -16,7 +16,7 @@ export default function DrawerNavigator() { screenOptions={{ headerShown: false, drawerStyle: { - backgroundColor: '#08090D', + backgroundColor: 'rgb(10,10,12)', width: '75%' }, overlayColor: 'transparent', diff --git a/apps/mobile/src/screens/Overview.tsx b/apps/mobile/src/screens/Overview.tsx index 9ef10e968..6231e4b1e 100644 --- a/apps/mobile/src/screens/Overview.tsx +++ b/apps/mobile/src/screens/Overview.tsx @@ -1,13 +1,10 @@ import Device from '@app/components/device/Device'; -import Dialog from '@app/components/layout/Dialog'; import VirtualizedListWrapper from '@app/components/layout/VirtualizedListWrapper'; -import { TextInput } from '@app/components/primitive/Input'; import OverviewStats from '@app/containers/OverviewStats'; -import { useLibraryQuery } from '@app/hooks/rspc'; import tw from '@app/lib/tailwind'; import { OverviewStackScreenProps } from '@app/navigation/tabs/OverviewStack'; import React from 'react'; -import { FlatList, Text, View } from 'react-native'; +import { FlatList, View } from 'react-native'; const placeholderOverviewStats = { id: 1, @@ -52,20 +49,6 @@ export default function OverviewScreen({ navigation }: OverviewStackScreenProps< return ( - console.log('wat')} - trigger={ - - Dialog - - } - > - - {/* Stats */} {/* Devices */} diff --git a/apps/mobile/src/screens/modals/Search.tsx b/apps/mobile/src/screens/modals/Search.tsx index 3eb28a830..56a167d21 100644 --- a/apps/mobile/src/screens/modals/Search.tsx +++ b/apps/mobile/src/screens/modals/Search.tsx @@ -18,7 +18,9 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => { {/* Header */} {/* Search Input */} - + {loading ? ( From 358874533b99dea6629b1999177472d4ec6982bb Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Sun, 4 Sep 2022 15:28:20 +0300 Subject: [PATCH 07/15] Update bindings =_= --- apps/mobile/src/types/bindings.ts | 206 +++++++++++++++--------------- core/index.ts | 206 +++++++++++++++--------------- 2 files changed, 206 insertions(+), 206 deletions(-) diff --git a/apps/mobile/src/types/bindings.ts b/apps/mobile/src/types/bindings.ts index 8a1c958b3..328caa721 100644 --- a/apps/mobile/src/types/bindings.ts +++ b/apps/mobile/src/types/bindings.ts @@ -2,130 +2,130 @@ export type Operations = { queries: - { key: ["version"], result: string } | - { key: ["jobs.getHistory", LibraryArgs], result: Array } | + { key: ["locations.indexer_rulesget", LibraryArgs], result: IndexerRule } | + { key: ["volumes.get"], result: Array } | + { key: ["locations.getById", LibraryArgs], result: Location | null } | { key: ["locations.indexer_ruleslist", LibraryArgs], result: Array } | - { key: ["files.readMetadata", LibraryArgs], result: null } | - { key: ["tags.getFilesForTag", LibraryArgs], result: Tag | null } | + { key: ["version"], result: string } | { key: ["library.getStatistics", LibraryArgs], result: Statistics } | { key: ["locations.get", LibraryArgs], result: Array } | - { key: ["library.get"], result: Array } | - { key: ["locations.indexer_rulesget", LibraryArgs], result: IndexerRule } | - { key: ["locations.getById", LibraryArgs], result: Location | null } | - { key: ["jobs.getRunning", LibraryArgs], result: Array } | - { key: ["volumes.get"], result: Array } | - { key: ["locations.getExplorerDir", LibraryArgs], result: DirectoryWithContents } | { key: ["tags.get", LibraryArgs], result: Array } | - { key: ["getNode"], result: NodeState }, + { key: ["jobs.getRunning", LibraryArgs], result: Array } | + { key: ["tags.getFilesForTag", LibraryArgs], result: Tag | null } | + { key: ["library.get"], result: Array } | + { key: ["locations.getExplorerDir", LibraryArgs], result: DirectoryWithContents } | + { key: ["jobs.getHistory", LibraryArgs], result: Array } | + { key: ["getNode"], result: NodeState } | + { key: ["files.readMetadata", LibraryArgs], result: null }, mutations: - { key: ["locations.indexer_rulesdelete", LibraryArgs], result: null } | + { key: ["tags.create", LibraryArgs], result: Tag } | + { key: ["tags.update", LibraryArgs], result: null } | + { key: ["locations.fullRescan", LibraryArgs], result: null } | + { key: ["locations.quickRescan", LibraryArgs], result: null } | + { key: ["locations.delete", LibraryArgs], result: null } | + { key: ["files.delete", LibraryArgs], result: null } | { key: ["jobs.identifyUniqueFiles", LibraryArgs], result: null } | { key: ["library.delete", string], result: null } | { key: ["library.create", string], result: null } | - { key: ["library.edit", EditLibraryArgs], result: null } | - { key: ["jobs.generateThumbsForLocation", LibraryArgs], result: null } | - { key: ["files.delete", LibraryArgs], result: null } | - { key: ["locations.update", LibraryArgs], result: null } | - { key: ["tags.create", LibraryArgs], result: Tag } | - { key: ["locations.delete", LibraryArgs], result: null } | - { key: ["locations.create", LibraryArgs], result: Location } | - { key: ["files.setNote", LibraryArgs], result: null } | - { key: ["tags.update", LibraryArgs], result: null } | + { key: ["locations.indexer_rulesdelete", LibraryArgs], result: null } | + { key: ["files.setFavorite", LibraryArgs], result: null } | { key: ["tags.assign", LibraryArgs], result: null } | { key: ["locations.indexer_rulescreate", LibraryArgs], result: IndexerRule } | - { key: ["locations.fullRescan", LibraryArgs], result: null } | + { key: ["jobs.generateThumbsForLocation", LibraryArgs], result: null } | + { key: ["locations.update", LibraryArgs], result: null } | + { key: ["library.edit", EditLibraryArgs], result: null } | { key: ["tags.delete", LibraryArgs], result: null } | - { key: ["locations.quickRescan", LibraryArgs], result: null } | - { key: ["files.setFavorite", LibraryArgs], result: null }, + { key: ["files.setNote", LibraryArgs], result: null } | + { key: ["locations.create", LibraryArgs], result: Location }, subscriptions: - { key: ["invalidateQuery"], result: InvalidateOperationEvent } | - { key: ["jobs.newThumbnail", LibraryArgs], result: string } + { key: ["jobs.newThumbnail", LibraryArgs], result: string } | + { key: ["invalidateQuery"], result: InvalidateOperationEvent } }; -export interface Album { id: number, pub_id: Array, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array | null } - -export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array } - -export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean } - -export interface SetFavoriteArgs { id: number, favorite: boolean } - -export interface IdentifyUniqueFilesArgs { id: number, path: string } - -export interface GenerateThumbsForLocationArgs { id: number, path: string } - -export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused" - -export interface ConfigMetadata { version: string | null } - -export interface File { id: number, cas_id: string, integrity_checksum: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, tags: Array | null, labels: Array | null, albums: Array | null, spaces: Array | null, paths: Array | null, comments: Array | null, media_data: MediaData | null | null, key: Key | null | null } - -export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent" - -export interface Label { id: number, pub_id: Array, name: string | null, date_created: string, date_modified: string, label_files: Array | null } - -export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, file_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, file: File | null | null, location: Location | null | null, key: Key | null | null } - -export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array } - -export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array, kind: number, column: string | null, value: string, node: Node | null } - -export interface Statistics { id: number, date_captured: string, total_file_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string } - -export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null } - -export interface DirectoryWithContents { directory: FilePath, contents: Array } - -export interface SetNoteArgs { id: number, note: string | null } - -export interface IndexerRulesInLocation { date_created: string, location_id: number, location: Location | null, indexer_rule_id: number, indexer_rule: IndexerRule | null } - -export interface JobReport { id: string, name: string, data: Array | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number } - -export interface TagUpdateArgs { id: number, name: string | null, color: string | null } - -export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null } - -export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null } - -export interface LibraryArgs { library_id: string, arg: T } - -export interface Location { id: number, pub_id: Array, node_id: number | null, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, date_created: string, node: Node | null | null, file_paths: Array | null, indexer_rules: Array | null } - -export interface Node { id: number, pub_id: Array, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array | null, jobs: Array | null, Location: Array | null } - -export interface LocationCreateArgs { path: string, indexer_rules_ids: Array } - -export interface InvalidateOperationEvent { key: string, arg: any } - -export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig } - -export interface Tag { id: number, pub_id: Array, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array | null } - -export interface Job { id: Array, name: string, node_id: number, action: number, status: number, data: Array | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: Node | null } - -export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null } - -export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array | null, file_paths: Array | null } - -export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null } - -export interface EditLibraryArgs { id: string, name: string | null, description: string | null } - -export interface TagCreateArgs { name: string, color: string } - -export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string } - -export interface Comment { id: number, pub_id: Array, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null } +export interface MediaData { id: number, pixel_width: number | null, pixel_height: number | null, longitude: number | null, latitude: number | null, fps: number | null, capture_device_make: string | null, capture_device_model: string | null, capture_device_software: string | null, duration_seconds: number | null, codecs: string | null, streams: number | null, files: File | null | null } export interface IndexerRule { id: number, kind: number, name: string, parameters: Array, date_created: string, date_modified: string, locations: Array | null } -export interface TagAssignArgs { file_id: number, tag_id: number } +export interface Label { id: number, pub_id: Array, name: string | null, date_created: string, date_modified: string, label_files: Array | null } + +export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null } + +export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null } + +export interface InvalidateOperationEvent { key: string, arg: any } + +export interface JobReport { id: string, name: string, data: Array | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number } + +export interface File { id: number, cas_id: string, integrity_checksum: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, tags: Array | null, labels: Array | null, albums: Array | null, spaces: Array | null, paths: Array | null, comments: Array | null, media_data: MediaData | null | null, key: Key | null | null } + +export interface ConfigMetadata { version: string | null } + +export interface Location { id: number, pub_id: Array, node_id: number | null, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, date_created: string, node: Node | null | null, file_paths: Array | null, indexer_rules: Array | null } export interface GetExplorerDirArgs { location_id: number, path: string, limit: number } +export interface IndexerRulesInLocation { date_created: string, location_id: number, location: Location | null, indexer_rule_id: number, indexer_rule: IndexerRule | null } + +export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string } + +export interface LocationCreateArgs { path: string, indexer_rules_ids: Array } + +export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean } + +export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null } + +export interface Comment { id: number, pub_id: Array, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null } + +export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array | null, file_paths: Array | null } + +export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, file_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, file: File | null | null, location: Location | null | null, key: Key | null | null } + +export interface SetFavoriteArgs { id: number, favorite: boolean } + +export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null } + +export interface LibraryArgs { library_id: string, arg: T } + +export interface GenerateThumbsForLocationArgs { id: number, path: string } + +export interface EditLibraryArgs { id: string, name: string | null, description: string | null } + +export interface Album { id: number, pub_id: Array, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array | null } + +export interface Job { id: Array, name: string, node_id: number, action: number, status: number, data: Array | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: Node | null } + +export interface TagAssignArgs { file_id: number, tag_id: number } + +export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array, kind: number, column: string | null, value: string, node: Node | null } + +export interface Node { id: number, pub_id: Array, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array | null, jobs: Array | null, Location: Array | null } + +export interface SetNoteArgs { id: number, note: string | null } + +export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig } + +export interface DirectoryWithContents { directory: FilePath, contents: Array } + +export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent" + +export interface TagCreateArgs { name: string, color: string } + +export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array } + +export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array } + +export interface Statistics { id: number, date_captured: string, total_file_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string } + export interface LibraryConfig { version: string | null, name: string, description: string } +export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null } + +export interface TagUpdateArgs { id: number, name: string | null, color: string | null } + export interface Space { id: number, pub_id: Array, name: string | null, description: string | null, date_created: string, date_modified: string, files: Array | null } -export interface MediaData { id: number, pixel_width: number | null, pixel_height: number | null, longitude: number | null, latitude: number | null, fps: number | null, capture_device_make: string | null, capture_device_model: string | null, capture_device_software: string | null, duration_seconds: number | null, codecs: string | null, streams: number | null, files: File | null | null } +export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused" + +export interface Tag { id: number, pub_id: Array, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array | null } + +export interface IdentifyUniqueFilesArgs { id: number, path: string } diff --git a/core/index.ts b/core/index.ts index 8a1c958b3..328caa721 100644 --- a/core/index.ts +++ b/core/index.ts @@ -2,130 +2,130 @@ export type Operations = { queries: - { key: ["version"], result: string } | - { key: ["jobs.getHistory", LibraryArgs], result: Array } | + { key: ["locations.indexer_rulesget", LibraryArgs], result: IndexerRule } | + { key: ["volumes.get"], result: Array } | + { key: ["locations.getById", LibraryArgs], result: Location | null } | { key: ["locations.indexer_ruleslist", LibraryArgs], result: Array } | - { key: ["files.readMetadata", LibraryArgs], result: null } | - { key: ["tags.getFilesForTag", LibraryArgs], result: Tag | null } | + { key: ["version"], result: string } | { key: ["library.getStatistics", LibraryArgs], result: Statistics } | { key: ["locations.get", LibraryArgs], result: Array } | - { key: ["library.get"], result: Array } | - { key: ["locations.indexer_rulesget", LibraryArgs], result: IndexerRule } | - { key: ["locations.getById", LibraryArgs], result: Location | null } | - { key: ["jobs.getRunning", LibraryArgs], result: Array } | - { key: ["volumes.get"], result: Array } | - { key: ["locations.getExplorerDir", LibraryArgs], result: DirectoryWithContents } | { key: ["tags.get", LibraryArgs], result: Array } | - { key: ["getNode"], result: NodeState }, + { key: ["jobs.getRunning", LibraryArgs], result: Array } | + { key: ["tags.getFilesForTag", LibraryArgs], result: Tag | null } | + { key: ["library.get"], result: Array } | + { key: ["locations.getExplorerDir", LibraryArgs], result: DirectoryWithContents } | + { key: ["jobs.getHistory", LibraryArgs], result: Array } | + { key: ["getNode"], result: NodeState } | + { key: ["files.readMetadata", LibraryArgs], result: null }, mutations: - { key: ["locations.indexer_rulesdelete", LibraryArgs], result: null } | + { key: ["tags.create", LibraryArgs], result: Tag } | + { key: ["tags.update", LibraryArgs], result: null } | + { key: ["locations.fullRescan", LibraryArgs], result: null } | + { key: ["locations.quickRescan", LibraryArgs], result: null } | + { key: ["locations.delete", LibraryArgs], result: null } | + { key: ["files.delete", LibraryArgs], result: null } | { key: ["jobs.identifyUniqueFiles", LibraryArgs], result: null } | { key: ["library.delete", string], result: null } | { key: ["library.create", string], result: null } | - { key: ["library.edit", EditLibraryArgs], result: null } | - { key: ["jobs.generateThumbsForLocation", LibraryArgs], result: null } | - { key: ["files.delete", LibraryArgs], result: null } | - { key: ["locations.update", LibraryArgs], result: null } | - { key: ["tags.create", LibraryArgs], result: Tag } | - { key: ["locations.delete", LibraryArgs], result: null } | - { key: ["locations.create", LibraryArgs], result: Location } | - { key: ["files.setNote", LibraryArgs], result: null } | - { key: ["tags.update", LibraryArgs], result: null } | + { key: ["locations.indexer_rulesdelete", LibraryArgs], result: null } | + { key: ["files.setFavorite", LibraryArgs], result: null } | { key: ["tags.assign", LibraryArgs], result: null } | { key: ["locations.indexer_rulescreate", LibraryArgs], result: IndexerRule } | - { key: ["locations.fullRescan", LibraryArgs], result: null } | + { key: ["jobs.generateThumbsForLocation", LibraryArgs], result: null } | + { key: ["locations.update", LibraryArgs], result: null } | + { key: ["library.edit", EditLibraryArgs], result: null } | { key: ["tags.delete", LibraryArgs], result: null } | - { key: ["locations.quickRescan", LibraryArgs], result: null } | - { key: ["files.setFavorite", LibraryArgs], result: null }, + { key: ["files.setNote", LibraryArgs], result: null } | + { key: ["locations.create", LibraryArgs], result: Location }, subscriptions: - { key: ["invalidateQuery"], result: InvalidateOperationEvent } | - { key: ["jobs.newThumbnail", LibraryArgs], result: string } + { key: ["jobs.newThumbnail", LibraryArgs], result: string } | + { key: ["invalidateQuery"], result: InvalidateOperationEvent } }; -export interface Album { id: number, pub_id: Array, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array | null } - -export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array } - -export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean } - -export interface SetFavoriteArgs { id: number, favorite: boolean } - -export interface IdentifyUniqueFilesArgs { id: number, path: string } - -export interface GenerateThumbsForLocationArgs { id: number, path: string } - -export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused" - -export interface ConfigMetadata { version: string | null } - -export interface File { id: number, cas_id: string, integrity_checksum: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, tags: Array | null, labels: Array | null, albums: Array | null, spaces: Array | null, paths: Array | null, comments: Array | null, media_data: MediaData | null | null, key: Key | null | null } - -export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent" - -export interface Label { id: number, pub_id: Array, name: string | null, date_created: string, date_modified: string, label_files: Array | null } - -export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, file_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, file: File | null | null, location: Location | null | null, key: Key | null | null } - -export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array } - -export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array, kind: number, column: string | null, value: string, node: Node | null } - -export interface Statistics { id: number, date_captured: string, total_file_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string } - -export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null } - -export interface DirectoryWithContents { directory: FilePath, contents: Array } - -export interface SetNoteArgs { id: number, note: string | null } - -export interface IndexerRulesInLocation { date_created: string, location_id: number, location: Location | null, indexer_rule_id: number, indexer_rule: IndexerRule | null } - -export interface JobReport { id: string, name: string, data: Array | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number } - -export interface TagUpdateArgs { id: number, name: string | null, color: string | null } - -export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null } - -export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null } - -export interface LibraryArgs { library_id: string, arg: T } - -export interface Location { id: number, pub_id: Array, node_id: number | null, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, date_created: string, node: Node | null | null, file_paths: Array | null, indexer_rules: Array | null } - -export interface Node { id: number, pub_id: Array, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array | null, jobs: Array | null, Location: Array | null } - -export interface LocationCreateArgs { path: string, indexer_rules_ids: Array } - -export interface InvalidateOperationEvent { key: string, arg: any } - -export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig } - -export interface Tag { id: number, pub_id: Array, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array | null } - -export interface Job { id: Array, name: string, node_id: number, action: number, status: number, data: Array | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: Node | null } - -export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null } - -export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array | null, file_paths: Array | null } - -export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null } - -export interface EditLibraryArgs { id: string, name: string | null, description: string | null } - -export interface TagCreateArgs { name: string, color: string } - -export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string } - -export interface Comment { id: number, pub_id: Array, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null } +export interface MediaData { id: number, pixel_width: number | null, pixel_height: number | null, longitude: number | null, latitude: number | null, fps: number | null, capture_device_make: string | null, capture_device_model: string | null, capture_device_software: string | null, duration_seconds: number | null, codecs: string | null, streams: number | null, files: File | null | null } export interface IndexerRule { id: number, kind: number, name: string, parameters: Array, date_created: string, date_modified: string, locations: Array | null } -export interface TagAssignArgs { file_id: number, tag_id: number } +export interface Label { id: number, pub_id: Array, name: string | null, date_created: string, date_modified: string, label_files: Array | null } + +export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null } + +export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null } + +export interface InvalidateOperationEvent { key: string, arg: any } + +export interface JobReport { id: string, name: string, data: Array | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number } + +export interface File { id: number, cas_id: string, integrity_checksum: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, tags: Array | null, labels: Array | null, albums: Array | null, spaces: Array | null, paths: Array | null, comments: Array | null, media_data: MediaData | null | null, key: Key | null | null } + +export interface ConfigMetadata { version: string | null } + +export interface Location { id: number, pub_id: Array, node_id: number | null, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, date_created: string, node: Node | null | null, file_paths: Array | null, indexer_rules: Array | null } export interface GetExplorerDirArgs { location_id: number, path: string, limit: number } +export interface IndexerRulesInLocation { date_created: string, location_id: number, location: Location | null, indexer_rule_id: number, indexer_rule: IndexerRule | null } + +export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string } + +export interface LocationCreateArgs { path: string, indexer_rules_ids: Array } + +export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean } + +export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null } + +export interface Comment { id: number, pub_id: Array, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null } + +export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array | null, file_paths: Array | null } + +export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, file_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, file: File | null | null, location: Location | null | null, key: Key | null | null } + +export interface SetFavoriteArgs { id: number, favorite: boolean } + +export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null } + +export interface LibraryArgs { library_id: string, arg: T } + +export interface GenerateThumbsForLocationArgs { id: number, path: string } + +export interface EditLibraryArgs { id: string, name: string | null, description: string | null } + +export interface Album { id: number, pub_id: Array, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array | null } + +export interface Job { id: Array, name: string, node_id: number, action: number, status: number, data: Array | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: Node | null } + +export interface TagAssignArgs { file_id: number, tag_id: number } + +export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array, kind: number, column: string | null, value: string, node: Node | null } + +export interface Node { id: number, pub_id: Array, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array | null, jobs: Array | null, Location: Array | null } + +export interface SetNoteArgs { id: number, note: string | null } + +export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig } + +export interface DirectoryWithContents { directory: FilePath, contents: Array } + +export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent" + +export interface TagCreateArgs { name: string, color: string } + +export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array } + +export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array } + +export interface Statistics { id: number, date_captured: string, total_file_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string } + export interface LibraryConfig { version: string | null, name: string, description: string } +export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null } + +export interface TagUpdateArgs { id: number, name: string | null, color: string | null } + export interface Space { id: number, pub_id: Array, name: string | null, description: string | null, date_created: string, date_modified: string, files: Array | null } -export interface MediaData { id: number, pixel_width: number | null, pixel_height: number | null, longitude: number | null, latitude: number | null, fps: number | null, capture_device_make: string | null, capture_device_model: string | null, capture_device_software: string | null, duration_seconds: number | null, codecs: string | null, streams: number | null, files: File | null | null } +export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused" + +export interface Tag { id: number, pub_id: Array, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array | null } + +export interface IdentifyUniqueFilesArgs { id: number, path: string } From 107f30276b8f57c85af6421f32018f84a8ddb97f Mon Sep 17 00:00:00 2001 From: Utku Bakir <74243531+utkubakir@users.noreply.github.com> Date: Sun, 4 Sep 2022 16:26:20 +0300 Subject: [PATCH 08/15] Fix Reanimated bug & Finalize Create Lib --- apps/mobile/ios/Podfile.lock | 54 +++++++++++------- apps/mobile/package.json | 6 +- apps/mobile/pnpm-lock.yaml | Bin 328299 -> 329461 bytes .../drawer/DrawerLibraryManager.tsx | 27 +++++---- apps/mobile/src/components/layout/Dialog.tsx | 30 +++++++--- .../src/components/modals/FileModal.tsx | 14 ----- 6 files changed, 75 insertions(+), 56 deletions(-) diff --git a/apps/mobile/ios/Podfile.lock b/apps/mobile/ios/Podfile.lock index eb04e2bc1..5825a73f1 100644 --- a/apps/mobile/ios/Podfile.lock +++ b/apps/mobile/ios/Podfile.lock @@ -9,11 +9,11 @@ PODS: - ExpoModulesCore - EXFont (10.2.0): - ExpoModulesCore - - Expo (46.0.9): + - Expo (46.0.10): - ExpoModulesCore - ExpoKeepAwake (10.2.0): - ExpoModulesCore - - ExpoModulesCore (0.11.4): + - ExpoModulesCore (0.11.5): - React-Core - ReactCommon/turbomodule/core - EXSplashScreen (0.16.2): @@ -31,6 +31,10 @@ PODS: - glog (0.3.5) - hermes-engine (0.69.4) - libevent (2.1.12) + - lottie-ios (3.4.2) + - lottie-react-native (5.1.4): + - lottie-ios (~> 3.4.0) + - React-Core - RCT-Folly (2021.06.28.00-v2): - boost - DoubleConversion @@ -335,7 +339,7 @@ PODS: - React-Core - RNGestureHandler (2.5.0): - React-Core - - RNReanimated (2.9.1): + - RNReanimated (2.10.0): - DoubleConversion - FBLazyVector - FBReactNativeSpec @@ -372,19 +376,20 @@ PODS: DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - "EXApplication (from `../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.9/node_modules/expo-application/ios`)" - - "EXConstants (from `../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.9/node_modules/expo-constants/ios`)" - - "EXFileSystem (from `../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.9/node_modules/expo-file-system/ios`)" - - "EXFont (from `../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.9/node_modules/expo-font/ios`)" - - "Expo (from `../node_modules/.pnpm/expo@46.0.9_@babel+core@7.18.10/node_modules/expo`)" - - "ExpoKeepAwake (from `../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.9/node_modules/expo-keep-awake/ios`)" - - "ExpoModulesCore (from `../node_modules/.pnpm/expo-modules-core@0.11.4/node_modules/expo-modules-core/ios`)" - - "EXSplashScreen (from `../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.9/node_modules/expo-splash-screen/ios`)" + - "EXApplication (from `../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.10/node_modules/expo-application/ios`)" + - "EXConstants (from `../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.10/node_modules/expo-constants/ios`)" + - "EXFileSystem (from `../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.10/node_modules/expo-file-system/ios`)" + - "EXFont (from `../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.10/node_modules/expo-font/ios`)" + - "Expo (from `../node_modules/.pnpm/expo@46.0.10_@babel+core@7.18.10/node_modules/expo`)" + - "ExpoKeepAwake (from `../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.10/node_modules/expo-keep-awake/ios`)" + - "ExpoModulesCore (from `../node_modules/.pnpm/expo-modules-core@0.11.5/node_modules/expo-modules-core/ios`)" + - "EXSplashScreen (from `../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.10/node_modules/expo-splash-screen/ios`)" - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`) - libevent (~> 2.1.12) + - lottie-react-native (from `../node_modules/lottie-react-native`) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) @@ -426,6 +431,7 @@ SPEC REPOS: trunk: - fmt - libevent + - lottie-ios EXTERNAL SOURCES: boost: @@ -433,21 +439,21 @@ EXTERNAL SOURCES: DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" EXApplication: - :path: "../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.9/node_modules/expo-application/ios" + :path: "../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.10/node_modules/expo-application/ios" EXConstants: - :path: "../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.9/node_modules/expo-constants/ios" + :path: "../node_modules/.pnpm/expo-constants@13.2.4_expo@46.0.10/node_modules/expo-constants/ios" EXFileSystem: - :path: "../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.9/node_modules/expo-file-system/ios" + :path: "../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.10/node_modules/expo-file-system/ios" EXFont: - :path: "../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.9/node_modules/expo-font/ios" + :path: "../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.10/node_modules/expo-font/ios" Expo: - :path: "../node_modules/.pnpm/expo@46.0.9_@babel+core@7.18.10/node_modules/expo" + :path: "../node_modules/.pnpm/expo@46.0.10_@babel+core@7.18.10/node_modules/expo" ExpoKeepAwake: - :path: "../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.9/node_modules/expo-keep-awake/ios" + :path: "../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.10/node_modules/expo-keep-awake/ios" ExpoModulesCore: - :path: "../node_modules/.pnpm/expo-modules-core@0.11.4/node_modules/expo-modules-core/ios" + :path: "../node_modules/.pnpm/expo-modules-core@0.11.5/node_modules/expo-modules-core/ios" EXSplashScreen: - :path: "../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.9/node_modules/expo-splash-screen/ios" + :path: "../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.10/node_modules/expo-splash-screen/ios" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" FBReactNativeSpec: @@ -456,6 +462,8 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes/hermes-engine.podspec" + lottie-react-native: + :path: "../node_modules/lottie-react-native" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -534,9 +542,9 @@ SPEC CHECKSUMS: EXConstants: 7c44785d41d8e959d527d23d29444277a4d1ee73 EXFileSystem: 927e0a8885aa9c49e50fc38eaba2c2389f2f1019 EXFont: a5d80bd9b3452b2d5abbce2487da89b0150e6487 - Expo: 73412414e62f5cbc6e713def821de70b92cd3ad6 + Expo: fcdb32274e2ca9c7638d3b21b30fb665c6869219 ExpoKeepAwake: 0e8f18142e71bbf2c7f6aa66ebed249ba1420320 - ExpoModulesCore: e281bb7b78ea47e227dd5af94d04b24d8b2e1255 + ExpoModulesCore: 5a973701f4400d70254bc836305228731c829010 EXSplashScreen: 799bece80089219b2c989c1082d70f3b00995cda FBLazyVector: c71b8c429a8af2aff1013934a7152e9d9d0c937d FBReactNativeSpec: 3cc5cff7d792e74a875be91e56d6242335016f50 @@ -544,6 +552,8 @@ SPEC CHECKSUMS: glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a hermes-engine: 761a544537e62df2a37189389b9d2654dc1f75af libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + lottie-ios: 6bbc53eef6957e4744a50321507015fba72d8ca6 + lottie-react-native: b702fab740cdb952a8e2354713d3beda63ff97b0 RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a RCTRequired: bd9d2ab0fda10171fcbcf9ba61a7df4dc15a28f4 RCTTypeSafety: e44e139bf6ec8042db396201834fc2372f6a21cd @@ -575,7 +585,7 @@ SPEC CHECKSUMS: RNCAsyncStorage: d81ee5c3db1060afd49ea7045ad460eff82d2b7d RNCMaskedView: cb9670ea9239998340eaab21df13fa12a1f9de15 RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50 - RNReanimated: 2cf7451318bb9cc430abeec8d67693f9cf4e039c + RNReanimated: 7faa787e8d4493fbc95fab2ad331fa7625828cfa RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 RNSVG: 42a0c731b11179ebbd27a3eeeafa7201ebb476ff Yoga: ff994563b2fd98c982ca58e8cd9db2cdaf4dda74 diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 6b86af1a9..f2be5a2bf 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -23,7 +23,7 @@ "byte-size": "^8.1.0", "class-variance-authority": "^0.2.3", "date-fns": "^2.29.2", - "expo": "~46.0.9", + "expo": "~46.0.10", "expo-linking": "~3.2.2", "expo-splash-screen": "~0.16.2", "expo-status-bar": "~1.4.0", @@ -36,7 +36,7 @@ "react-native": "0.69.4", "react-native-gesture-handler": "~2.5.0", "react-native-heroicons": "^2.2.0", - "react-native-reanimated": "~2.9.1", + "react-native-reanimated": "~2.10.0", "react-native-safe-area-context": "4.3.1", "react-native-screens": "~3.15.0", "react-native-svg": "13.0.0", @@ -47,7 +47,7 @@ "devDependencies": { "@babel/core": "^7.18.6", "@babel/runtime": "^7.18.9", - "@rnx-kit/metro-config": "^1.2.36", + "@rnx-kit/metro-config": "^1.2.37", "@rnx-kit/metro-resolver-symlinks": "^0.1.21", "@types/react": "~18.0.0", "@types/react-native": "~0.69.1", diff --git a/apps/mobile/pnpm-lock.yaml b/apps/mobile/pnpm-lock.yaml index 0055d8d8c91d23495dc0116cb226324640fe2a33..91564b5d306b5d981e7e61a4c5e9a59f3fc82c95 100644 GIT binary patch delta 1715 zcmaJ?Yiv_x7|!>tGGJ^VjIs*@hHefEYtQLfFHzY}+jVEXtf$wtGl)Iy>1lgc^BO=$DIuhzYC%wE z3K=pMB9n=%#F6oGzKVeZ$hV(Zg`RJ`*ikKK`ACdRiX}cAk43p^xRU3ooTePZw}QZm ze-DCXGhfdi2I$>uohTw(f`%6^sW(N>$U2v)`Uy=xxtXtI(nFM{zkXGrNm<*>o`vrL z8KLS|q3)KocvT3zh)-++El8ZV5P#PpTZ72vn?O6$-C}N9An++Z7c8W6=#?8AJVucf zbXB*TEi#?}YYC*aqb}MO&Q{}gJ!9kwN_Ej;7&dcKb;QSN>?s{rHnRp*+^^B=NQ-aG zkO)Y2B9&srNWAEGJJ^Dg$7f!Wb)lhEi(Z$@(a)Mzbo$bK)Yneovlrn~^lNX+Osc)L z7rnf35kfb5Jz>Eg8jaYCPL(J~HUr7&3$BU0*5fgogClm5<_a_wu?SvopeRZs3{@Yg zTN{;}%Qy3o5@=mjS?=uG3QANDy39H+4Uy0?*|H~ z5$KYm%iT{Q%Tzxa>{nrjT(-ClALv_+w*1zPZv4n#Hd|l6{`v*wee{H~PxRDmouCc= zYv;{)XBSv}zdSI#ymp}rEH||OuL^PZI$3Y6?`iPWKgDZxK^<(Wd!W0e6JJV!9xo>q z7>mgfoiHY8L%t~Kjn#zYAswEIzbsXvp7CPI9U+Y=Ar~;R8Xr#%#C^#~RT<6bIImNe zNsW{VmZGXmK<^?F#YkX4nbDvtm2SK(-!Q-STpHXGQFhXRQok&yeQ*)v8_^pbyVSQ~stbpW99MsLgmij@ zDjGROTA`ID{Jg@zvQ(UA^8+>;FA>89HRW)Is_}HD;>}oeIZDlpCQJChUeJZVI0Pee zt;Y|;+jZuH_~sB;fG@X#`Do1_#yiux`ZhdXkJY8$+2gZ&O*T);5O6qxoMcXu4DIpQ z{V_U_c2X%~blhN9GYLmB@AReZ2CE~lF^48h*#fUjl&w0IRg5yDnH=F%Yb_?7DNC3| ziqrFSZS@hj6wGddJPIGG&*0oHxbEI!X3yz5JbRu$dI#@s1^u{p8n%G}JU9)n;VrwN z0;f|zzBP0V)uBV`XKviX2$%KFT~VKpy}VPXWt o7<%o=h3LeQ=Gys{vK{yRQ6B68y|t-TGVr%c*VH~+BRhQMFJdrTHvj+t delta 1287 zcmah}T}&KR6wbXn6bfmP3gy3S3#^n)U}tA{c88>~`^y6R{|CEGw9D+@% zF(&n;Y1(M_D>^b6m7lY^v+9}BoNgX%4}kMkG7o;`5Pn@kp>i3Vsh0LYt{!D8n9Qg06%+ah z6=bIEwn$E!oRVkUNh*^dlfi;#ijEbunn1zKCw&wjG6g1_I3J18ZknCdsd=5B3Hb>+ zPddE|$-LJe)#l@&d^}2`?H$ljUHl2$gg}e%EEuYeJqEY8g{(@3e!Bzj9k#nmxbJL6 z(sfve9=-|BioV7r_yADo!zDOeGy69reL~@nHq^Nc*G2!2%kUF%RM6}9;1$$+7xsxb zeHVW8Ps}DE{iGdTS%DWs*Xj!V{MnO?2uW9u81$gMRcI9<&)R=T^@?zK9o|18a;~a) z8-4}QcRxd!PaCe4!oX?bJ_a9mmelcSUK`dIg2r)LuJZDlk}>X?h)?O#DK#4yRnO^F zdQKi?ohgzcnCT>$P80GOy~V3_GurGVF|H|E@HyoA1?xq(-+@sv^$YL9r$>^u>;ve} zlb{79HsF&(s7;XS2YtSrp5+yKtEMP-ESO1dA? { - const [hide, setHide] = useState(true); + const [dropdownClosed, setDropdownClosed] = useState(true); // Init Libraries const { init: initLibraries, switchLibrary } = useLibraryStore(); @@ -27,32 +28,35 @@ const DrawerLibraryManager = () => { // Create Library const [libName, setLibName] = useState(''); + const [createLibOpen, setCreateLibOpen] = useState(false); + const { mutate: createLibrary, isLoading: createLibLoading } = useBridgeMutation( 'library.create', { onSuccess: () => { - setHide(true); + // Reset form + setLibName(''); }, - onError: (err) => { - // TODO: Show toast? - console.log(err); + onSettled: () => { + // Close create lib dialog + setCreateLibOpen(false); } } ); return ( - setHide((v) => !v)}> + setDropdownClosed((v) => !v)}> {currentLibrary?.config.name} @@ -60,13 +64,13 @@ const DrawerLibraryManager = () => { - + {/* Libraries */} {libraries?.map((library) => ( - + switchLibrary(library.uuid)}> { Library Settings + {/* Create Library */} void; children?: React.ReactNode; ctaAction?: () => void; ctaLabel?: string; @@ -29,12 +34,18 @@ const Dialog = (props: DialogProps) => { return ( - {props.trigger && setVisible(true)}>{props.trigger}} - + {props.trigger && ( + (props.setIsVisible ? props.setIsVisible(true) : setVisible(true))} + > + {props.trigger} + + )} + {/* Backdrop */} setVisible(false)} + onPress={() => (props.setIsVisible ? props.setIsVisible(false) : setVisible(false))} disabled={props.disableBackdropClose} /> {/* Content */} @@ -44,7 +55,6 @@ const Dialog = (props: DialogProps) => { keyboardVerticalOffset={Platform.OS === 'ios' ? 40 : undefined} style={tw`flex-1 items-center justify-center`} > - {/* TODO: Animations are not invoking everytime probably reanimated bug we have on File Modal */} { - {props.ctaAction && ( diff --git a/apps/mobile/src/components/modals/FileModal.tsx b/apps/mobile/src/components/modals/FileModal.tsx index c63ff95ba..c672fd6f7 100644 --- a/apps/mobile/src/components/modals/FileModal.tsx +++ b/apps/mobile/src/components/modals/FileModal.tsx @@ -11,15 +11,6 @@ import Divider from '../primitive/Divider'; import ModalBackdrop from './layout/ModalBackdrop'; import ModalHandle from './layout/ModalHandle'; -/* -https://github.com/software-mansion/react-native-reanimated/issues/3296 -https://github.com/gorhom/react-native-bottom-sheet/issues/925 -https://github.com/gorhom/react-native-bottom-sheet/issues/1036 - -Reanimated has a bug where it sometimes doesn't animate on mount (IOS only?), doing a console.log() seems to do a re-render and fix the issue. -We can't do this for production obvs but until then they might fix it so, let's not try weird hacks for now and live with the logs. -*/ - interface MetaItemProps { title: string; value: string; @@ -46,8 +37,6 @@ export const FileModal = () => { snapPoints={['60%', '90%']} backdropComponent={ModalBackdrop} handleComponent={ModalHandle} - // Do not remove! - onAnimate={(from, to) => console.log(from, to)} > {data && ( @@ -72,7 +61,6 @@ export const FileModal = () => { {/* Divider */} {/* Buttons */} -