[MOB-37, MOB-38, MOB-39] Preview for PDF, Text and Media files (#2098)

* version & microphonePermission text & eslint

* remove polyfill as hermes supports intl now

* why do we have solid on mobile?

* cleanup

* add solid back =_=

* pnpm lock

* we hate relative paths here

* android config

* open file logic

* visual tweaks

---------

Co-authored-by: ameer2468 <33054370+ameer2468@users.noreply.github.com>
This commit is contained in:
Utku 2024-02-21 08:26:05 -05:00 committed by GitHub
parent c533d12df0
commit b638fc2177
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 241 additions and 193 deletions

View file

@ -3,7 +3,7 @@
"name": "Spacedrive", "name": "Spacedrive",
"slug": "spacedrive", "slug": "spacedrive",
"owner": "spacedrive", "owner": "spacedrive",
"version": "0.0.1", "version": "0.1.0",
"orientation": "portrait", "orientation": "portrait",
"jsEngine": "hermes", "jsEngine": "hermes",
"scheme": "spacedrive", "scheme": "spacedrive",
@ -58,7 +58,14 @@
} }
} }
], ],
["./withRiveAssets.js"] [
"expo-av",
{
"microphonePermission": "Allow Spacedrive to access your microphone."
}
],
["./scripts/withRiveAssets.js"],
["./scripts/withAndroidIntent.js"]
] ]
} }
} }

View file

@ -4,7 +4,7 @@ apply plugin: 'maven-publish'
group = 'com.spacedrive.core' group = 'com.spacedrive.core'
version = '0.0.1' version = '0.1.0'
buildscript { buildscript {
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle") def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@ -72,7 +72,7 @@ android {
minSdkVersion safeExtGet("minSdkVersion", 28) minSdkVersion safeExtGet("minSdkVersion", 28)
targetSdkVersion safeExtGet("targetSdkVersion", 34) targetSdkVersion safeExtGet("targetSdkVersion", 34)
versionCode 1 versionCode 1
versionName "0.2.0" versionName "0.1.0"
} }
lintOptions { lintOptions {
abortOnError false abortOnError false

View file

@ -1,83 +1,84 @@
{ {
"name": "@sd/mobile", "name": "@sd/mobile",
"version": "1.0.0", "version": "1.0.0",
"main": "index.js", "main": "index.js",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "expo start --dev-client", "start": "expo start --dev-client",
"android": "expo run:android", "android": "expo run:android",
"ios": "expo run:ios", "ios": "expo run:ios",
"prebuild": "expo prebuild", "prebuild": "expo prebuild",
"xcode": "open ios/Spacedrive.xcworkspace", "xcode": "open ios/Spacedrive.xcworkspace",
"android-studio": "open -a '/Applications/Android Studio.app' ./android", "android-studio": "open -a '/Applications/Android Studio.app' ./android",
"lint": "eslint src --cache", "lint": "eslint src --cache",
"test": "cd ../.. && ./apps/mobile/scripts/run-maestro-tests ios", "test": "cd ../.. && ./apps/mobile/scripts/run-maestro-tests ios",
"export": "expo export", "export": "expo export",
"typecheck": "tsc -b" "typecheck": "tsc -b",
}, "format": "prettier --write ."
"dependencies": { },
"@gorhom/bottom-sheet": "^4.4.7", "dependencies": {
"@hookform/resolvers": "^3.1.0", "@gorhom/bottom-sheet": "^4.4.7",
"@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2", "@hookform/resolvers": "^3.1.0",
"@oscartbeaumont-sd/rspc-react": "=0.0.0-main-dc31e5b2", "@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2",
"@react-native-async-storage/async-storage": "~1.21.0", "@oscartbeaumont-sd/rspc-react": "=0.0.0-main-dc31e5b2",
"@react-native-masked-view/masked-view": "^0.3.0", "@react-native-async-storage/async-storage": "~1.21.0",
"@react-navigation/bottom-tabs": "^6.5.8", "@react-native-masked-view/masked-view": "^0.3.0",
"@react-navigation/drawer": "^6.6.3", "@react-navigation/bottom-tabs": "^6.5.8",
"@react-navigation/native": "^6.1.7", "@react-navigation/drawer": "^6.6.3",
"@react-navigation/stack": "^6.3.17", "@react-navigation/native": "^6.1.7",
"@sd/assets": "workspace:*", "@react-navigation/stack": "^6.3.17",
"@sd/client": "workspace:*", "@sd/assets": "workspace:*",
"@shopify/flash-list": "1.6.3", "@sd/client": "workspace:*",
"@tanstack/react-query": "^4.36.1", "@shopify/flash-list": "1.6.3",
"babel-preset-solid": "^1.8.9", "@tanstack/react-query": "^4.36.1",
"class-variance-authority": "^0.7.0", "babel-preset-solid": "^1.8.9",
"dayjs": "^1.11.10", "class-variance-authority": "^0.7.0",
"event-target-polyfill": "^0.0.3", "dayjs": "^1.11.10",
"expo": "~50.0.6", "event-target-polyfill": "^0.0.3",
"expo-av": "^13.10.5", "expo": "~50.0.6",
"expo-blur": "^12.9.1", "expo-av": "^13.10.5",
"expo-build-properties": "~0.11.1", "expo-blur": "^12.9.1",
"expo-linking": "~6.2.2", "expo-build-properties": "~0.11.1",
"expo-media-library": "~15.9.1", "expo-linking": "~6.2.2",
"expo-splash-screen": "~0.26.4", "expo-media-library": "~15.9.1",
"expo-status-bar": "~1.11.1", "expo-splash-screen": "~0.26.4",
"intl": "^1.2.5", "expo-status-bar": "~1.11.1",
"lottie-react-native": "6.5.1", "lottie-react-native": "6.5.1",
"metro-react-native-babel-transformer": "^0.77.0", "metro-react-native-babel-transformer": "^0.77.0",
"moti": "^0.26.0", "moti": "^0.26.0",
"phosphor-react-native": "^2.0.0", "phosphor-react-native": "^2.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-hook-form": "^7.47.0", "react-hook-form": "^7.47.0",
"react-native": "0.73.4", "react-native": "0.73.4",
"react-native-circular-progress": "^1.3.9", "react-native-circular-progress": "^1.3.9",
"react-native-document-picker": "^9.0.1", "react-native-document-picker": "^9.0.1",
"react-native-fs": "^2.20.0", "react-native-file-viewer": "^2.1.5",
"react-native-gesture-handler": "~2.14.1", "react-native-fs": "^2.20.0",
"react-native-linear-gradient": "^2.8.3", "react-native-gesture-handler": "~2.14.1",
"react-native-popup-menu": "^0.16.1", "react-native-linear-gradient": "^2.8.3",
"react-native-reanimated": "~3.6.2", "react-native-popup-menu": "^0.16.1",
"react-native-safe-area-context": "4.8.2", "react-native-reanimated": "~3.6.2",
"react-native-screens": "~3.29.0", "react-native-safe-area-context": "4.8.2",
"react-native-svg": "14.1.0", "react-native-screens": "~3.29.0",
"react-native-wheel-color-picker": "^1.2.0", "react-native-svg": "14.1.0",
"rive-react-native": "^6.2.3", "react-native-wheel-color-picker": "^1.2.0",
"solid-js": "^1.8.8", "rive-react-native": "^6.2.3",
"twrnc": "^3.6.4", "solid-js": "^1.8.8",
"use-count-up": "^3.0.1", "twrnc": "^3.6.4",
"use-debounce": "^9.0.4", "use-count-up": "^3.0.1",
"valtio": "^1.11.2", "use-debounce": "^9.0.4",
"zod": "~3.22.4" "valtio": "^1.11.2",
}, "zod": "~3.22.4"
"devDependencies": { },
"@babel/core": "^7.23.2", "devDependencies": {
"@rnx-kit/metro-config": "^1.3.12", "@babel/core": "^7.23.2",
"@sd/config": "workspace:*", "@rnx-kit/metro-config": "^1.3.12",
"@types/react": "^18.2.52", "@sd/config": "workspace:*",
"babel-plugin-module-resolver": "^5.0.0", "@types/react": "^18.2.52",
"eslint-plugin-react-native": "^4.1.0", "babel-plugin-module-resolver": "^5.0.0",
"react-native-svg-transformer": "^1.1.0", "eslint-plugin-react-native": "^4.1.0",
"typescript": "^5.3.3" "react-native-svg-transformer": "^1.1.0",
} "typescript": "^5.3.3"
}
} }

View file

@ -0,0 +1,26 @@
const { withAndroidManifest } = require('@expo/config-plugins');
// NOTE: Can be extended if needed (https://forums.expo.dev/t/how-to-edit-android-manifest-was-build/65663/4)
function modifyAndroidManifest(androidManifest) {
const { manifest } = androidManifest;
const intent = manifest['queries'][0]['intent'][0];
if (intent) {
// Adds <data android:mimeType="*/*" /> to the intents
intent['data'].push({
$: {
'android:mimeType': '*/*'
}
});
}
return androidManifest;
}
module.exports = function withAndroidIntent(config) {
return withAndroidManifest(config, (config) => {
config.modResults = modifyAndroidManifest(config.modResults);
return config;
});
};

View file

@ -68,11 +68,7 @@ function AppNavigation() {
useEffect(() => { useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
plausibleEvent({ plausibleEvent({ event: { type: 'ping' } });
event: {
type: 'ping'
}
});
}, 270 * 1000); }, 270 * 1000);
return () => clearInterval(interval); return () => clearInterval(interval);

View file

@ -13,6 +13,7 @@ import { useActionsModalStore } from '~/stores/modalStore';
import FileItem from './FileItem'; import FileItem from './FileItem';
import FileRow from './FileRow'; import FileRow from './FileRow';
import ScreenContainer from '../layout/ScreenContainer';
type ExplorerProps = { type ExplorerProps = {
items?: ExplorerItem[]; items?: ExplorerItem[];
@ -44,7 +45,7 @@ const Explorer = ({ items }: ExplorerProps) => {
} }
return ( return (
<View style={tw`flex-1 bg-mobile-screen`}> <ScreenContainer style={'gap-0 py-0'} scrollview={false}>
{/* Header */} {/* Header */}
<View style={tw`flex flex-row items-center justify-between`}> <View style={tw`flex flex-row items-center justify-between`}>
{/* Sort By */} {/* Sort By */}
@ -99,6 +100,7 @@ const Explorer = ({ items }: ExplorerProps) => {
)} )}
</Pressable> </Pressable>
)} )}
contentContainerStyle={tw`p-2`}
extraData={layoutMode} extraData={layoutMode}
estimatedItemSize={ estimatedItemSize={
layoutMode === 'grid' layoutMode === 'grid'
@ -107,7 +109,7 @@ const Explorer = ({ items }: ExplorerProps) => {
} }
/> />
)} )}
</View> </ScreenContainer>
); );
}; };

View file

@ -2,7 +2,8 @@ import { useNavigation } from '@react-navigation/native';
import { StackHeaderProps } from '@react-navigation/stack'; import { StackHeaderProps } from '@react-navigation/stack';
import { ArrowLeft, DotsThreeOutline, MagnifyingGlass } from 'phosphor-react-native'; import { ArrowLeft, DotsThreeOutline, MagnifyingGlass } from 'phosphor-react-native';
import { lazy } from 'react'; import { lazy } from 'react';
import { Platform, Pressable, Text, View } from 'react-native'; import { Pressable, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { tw, twStyle } from '~/lib/tailwind'; import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore'; import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore';
@ -44,16 +45,18 @@ export default function Header({
const explorerStore = useExplorerStore(); const explorerStore = useExplorerStore();
const routeParams = route?.route.params as any; const routeParams = route?.route.params as any;
const headerHeight = useSafeAreaInsets().top;
return ( return (
<View <View
style={twStyle( style={twStyle(
'relative h-auto w-full border-b border-app-line/50 bg-mobile-header', 'relative h-auto w-full border-b border-app-line/50 bg-mobile-header',
Platform.OS === 'android' ? 'pt-5' : 'pt-10' { paddingTop: headerHeight }
)} )}
> >
<View style={tw`mx-auto mt-5 h-auto w-full justify-center px-7 pb-5`}> <View style={tw`mx-auto h-auto w-full justify-center px-7 pb-5`}>
<View style={tw`w-full flex-row items-center justify-between`}> <View style={tw`w-full flex-row items-center justify-between`}>
<View style={tw`flex-row items-center gap-5`}> <View style={tw`flex-row items-center gap-3`}>
{navBack && ( {navBack && (
<Pressable <Pressable
onPress={() => { onPress={() => {
@ -67,7 +70,7 @@ export default function Header({
<HeaderIconKind headerKind={headerKind} routeParams={routeParams} /> <HeaderIconKind headerKind={headerKind} routeParams={routeParams} />
<Text <Text
numberOfLines={1} numberOfLines={1}
style={tw`max-w-[190px] text-[22px] font-bold text-white`} style={tw`max-w-[200px] text-xl font-bold text-white`}
> >
{title || (routeTitle && route?.options.title)} {title || (routeTitle && route?.options.title)}
</Text> </Text>
@ -128,11 +131,11 @@ interface HeaderIconKindProps {
const HeaderIconKind = ({ headerKind, routeParams }: HeaderIconKindProps) => { const HeaderIconKind = ({ headerKind, routeParams }: HeaderIconKindProps) => {
switch (headerKind) { switch (headerKind) {
case 'location': case 'location':
return <Icon size={32} name="Folder" />; return <Icon size={30} name="Folder" />;
case 'tag': case 'tag':
return ( return (
<View <View
style={twStyle('h-6 w-6 rounded-full', { style={twStyle('h-[30px] w-[30px] rounded-full', {
backgroundColor: routeParams.color backgroundColor: routeParams.color
})} })}
/> />

View file

@ -12,7 +12,14 @@ import {
} from 'phosphor-react-native'; } from 'phosphor-react-native';
import { PropsWithChildren, useRef } from 'react'; import { PropsWithChildren, useRef } from 'react';
import { Pressable, Text, View, ViewStyle } from 'react-native'; import { Pressable, Text, View, ViewStyle } from 'react-native';
import { byteSize, getItemFilePath, getItemObject } from '@sd/client'; import FileViewer from 'react-native-file-viewer';
import {
byteSize,
getIndexedItemFilePath,
getItemObject,
useLibraryMutation,
useLibraryQuery
} from '@sd/client';
import FileThumb from '~/components/explorer/FileThumb'; import FileThumb from '~/components/explorer/FileThumb';
import FavoriteButton from '~/components/explorer/sections/FavoriteButton'; import FavoriteButton from '~/components/explorer/sections/FavoriteButton';
import InfoTagPills from '~/components/explorer/sections/InfoTagPills'; import InfoTagPills from '~/components/explorer/sections/InfoTagPills';
@ -32,7 +39,7 @@ const ActionsContainer = ({ children, style }: ActionsContainerProps) => (
type ActionsItemProps = { type ActionsItemProps = {
title: string; title: string;
icon: Icon; icon?: Icon;
onPress?: () => void; onPress?: () => void;
isDanger?: boolean; isDanger?: boolean;
}; };
@ -49,7 +56,7 @@ const ActionsItem = ({ icon, onPress, title, isDanger = false }: ActionsItemProp
> >
{title} {title}
</Text> </Text>
<Icon color={isDanger ? 'red' : 'white'} size={22} /> {Icon && <Icon color={isDanger ? 'red' : 'white'} size={22} />}
</Pressable> </Pressable>
); );
}; };
@ -62,7 +69,31 @@ export const ActionsModal = () => {
const { modalRef, data } = useActionsModalStore(); const { modalRef, data } = useActionsModalStore();
const objectData = data && getItemObject(data); const objectData = data && getItemObject(data);
const filePath = data && getItemFilePath(data); const filePath = data && getIndexedItemFilePath(data);
// Open
const updateAccessTime = useLibraryMutation('files.updateAccessTime');
const queriedFullPath = useLibraryQuery(['files.getPath', filePath?.id ?? -1], {
enabled: filePath != null
});
async function handleOpen() {
const absolutePath = queriedFullPath.data;
if (!absolutePath) return;
try {
await FileViewer.open(absolutePath, {
// Android only
showAppsSuggestions: false, // If there is not an installed app that can open the file, open the Play Store with suggested apps
showOpenWithDialog: true // if there is more than one app that can open the file, show an Open With dialogue box
});
filePath &&
filePath.object_id &&
updateAccessTime.mutateAsync([filePath.object_id]).catch(console.error);
} catch (error) {
// TODO: Handle Error & toast message
}
}
return ( return (
<> <>
@ -99,6 +130,8 @@ export const ActionsModal = () => {
<View style={tw`my-3`} /> <View style={tw`my-3`} />
{/* Actions */} {/* Actions */}
<ActionsContainer> <ActionsContainer>
<ActionsItem title="Open" onPress={handleOpen} />
<ActionDivider />
<ActionsItem <ActionsItem
icon={Info} icon={Info}
title="Show Info" title="Show Info"

View file

@ -7,26 +7,19 @@ import OverviewSection from './OverviewSection';
const Cloud = () => { const Cloud = () => {
return ( return (
<View> <OverviewSection title="Cloud Drives" count={0}>
<OverviewSection title="Cloud Drives" count={0}> <View style={tw`px-7`}>
<View style={tw`px-7`}> <NewCard
<NewCard icons={['DriveAmazonS3', 'DriveDropbox', 'DriveGoogleDrive', 'DriveOneDrive']}
icons={[ text="Connect your cloud accounts to Spacedrive."
'DriveAmazonS3', button={() => (
'DriveDropbox', <Button variant="transparent">
'DriveGoogleDrive', <Text style={tw`font-bold text-ink-dull`}>Coming soon</Text>
'DriveOneDrive' </Button>
]} )}
text="Connect your cloud accounts to Spacedrive." />
button={() => ( </View>
<Button variant="transparent"> </OverviewSection>
<Text style={tw`font-bold text-ink-dull`}>Coming soon</Text>
</Button>
)}
/>
</View>
</OverviewSection>
</View>
); );
}; };

View file

@ -23,7 +23,7 @@ const Locations = ({ locations }: Props) => {
const modalRef = useRef<ModalRef>(null); const modalRef = useRef<ModalRef>(null);
return ( return (
<View> <>
<OverviewSection title="Locations" count={locations?.length}> <OverviewSection title="Locations" count={locations?.length}>
<View style={tw`flex-row items-center`}> <View style={tw`flex-row items-center`}>
<Fade height={'100%'} width={30} color="mobile-screen"> <Fade height={'100%'} width={30} color="mobile-screen">
@ -80,7 +80,7 @@ const Locations = ({ locations }: Props) => {
</View> </View>
</OverviewSection> </OverviewSection>
<ImportModal ref={modalRef} /> <ImportModal ref={modalRef} />
</View> </>
); );
}; };

View file

@ -94,20 +94,6 @@ window.screen = {
height height
}; };
/*
https://github.com/facebook/hermes/issues/23
We are using "Hermes" on Android & IOS, which for the current version (0.11),
IOS does not support the Intl fully so we need polyfill it.
NOTE: We can be picky about what we "polyfill" to optimize but for now this works.
*/
if (Platform.OS === 'ios') {
require('intl'); // import intl object
require('intl/locale-data/jsonp/en');
}
// This is insane. We load all data from `AsyncStorage` into the `_localStorage` global and then once complete we import the app. // This is insane. We load all data from `AsyncStorage` into the `_localStorage` global and then once complete we import the app.
// This way the polyfilled `localStorage` implementation has its data populated before the global stores within `@sd/client` are initialized (as they are initialized on import). // This way the polyfilled `localStorage` implementation has its data populated before the global stores within `@sd/client` are initialized (as they are initialized on import).
const App = lazy(async () => { const App = lazy(async () => {

View file

@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import { useCache, useLibraryQuery, useNodes } from '@sd/client'; import { useCache, useLibraryQuery, useNodes } from '@sd/client';
import Explorer from '~/components/explorer/Explorer'; import Explorer from '~/components/explorer/Explorer';
import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack'; import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack';
@ -11,21 +11,23 @@ export default function LocationScreen({ navigation, route }: BrowseStackScreenP
useNodes(location.data?.nodes); useNodes(location.data?.nodes);
const locationData = useCache(location.data?.item); const locationData = useCache(location.data?.item);
const { data } = useLibraryQuery([ const paths = useLibraryQuery([
'search.paths', 'search.paths',
{ {
filters: [ filters: [
{ {
filePath: { filePath: {
locations: { in: [id] }, locations: { in: [id] }
path: { path: path ?? '', location_id: id, include_descendants: false } // path: {location_id: id, path: path ?? '', include_descendants: true} // FIXME: This is the correct query, but it doesn't work and then provides a deserialization error.
} }
} }
], ],
take: 100 take: 100
} }
]); ]);
const pathsItemsReferences = useMemo(() => data?.items ?? [], [data]);
const pathsItemsReferences = useMemo(() => paths.data?.items ?? [], [paths.data]);
useNodes(paths.data?.nodes);
const pathsItems = useCache(pathsItemsReferences); const pathsItems = useCache(pathsItemsReferences);
useEffect(() => { useEffect(() => {

View file

@ -2,10 +2,13 @@ import { proxy, useSnapshot } from 'valtio';
import { proxySet } from 'valtio/utils'; import { proxySet } from 'valtio/utils';
import { resetStore } from '@sd/client'; import { resetStore } from '@sd/client';
// TODO: Add "media"
export type ExplorerLayoutMode = 'list' | 'grid' | 'media'; export type ExplorerLayoutMode = 'list' | 'grid' | 'media';
export type ExplorerKind = 'Location' | 'Tag' | 'Space'; export enum ExplorerKind {
Location,
Tag,
Space
}
const state = { const state = {
locationId: null as number | null, locationId: null as number | null,

View file

@ -251,9 +251,7 @@ function Options({
<Tooltip label={t('pause')}> <Tooltip label={t('pause')}>
<Button <Button
className="cursor-pointer" className="cursor-pointer"
onClick={() => { onClick={() => pauseJob.mutate(group.id)}
pauseJob.mutate(group.id);
}}
size="icon" size="icon"
variant="outline" variant="outline"
> >

View file

@ -1,7 +1,7 @@
import { byteSize } from '.';
import { getItemFilePath, getItemLocation, getItemObject, type ObjectKindKey } from '..';
import type { ExplorerItem } from '../core'; import type { ExplorerItem } from '../core';
import { ObjectKind } from './objectKind'; import { getItemFilePath, getItemLocation, getItemObject } from '../utils';
import { byteSize } from './byte-size';
import { ObjectKind, ObjectKindKey } from './objectKind';
// ItemData is a single data structure understood by the Explorer, we map all ExplorerItems to this structure in this file // ItemData is a single data structure understood by the Explorer, we map all ExplorerItems to this structure in this file
// we use `null` instead of `?` optional values intentionally // we use `null` instead of `?` optional values intentionally

View file

@ -397,9 +397,6 @@ importers:
expo-status-bar: expo-status-bar:
specifier: ~1.11.1 specifier: ~1.11.1
version: 1.11.1 version: 1.11.1
intl:
specifier: ^1.2.5
version: 1.2.5
lottie-react-native: lottie-react-native:
specifier: 6.5.1 specifier: 6.5.1
version: 6.5.1(react-native@0.73.4)(react@18.2.0) version: 6.5.1(react-native@0.73.4)(react@18.2.0)
@ -427,6 +424,9 @@ importers:
react-native-document-picker: react-native-document-picker:
specifier: ^9.0.1 specifier: ^9.0.1
version: 9.0.1(react-native@0.73.4)(react@18.2.0) version: 9.0.1(react-native@0.73.4)(react@18.2.0)
react-native-file-viewer:
specifier: ^2.1.5
version: 2.1.5(react-native@0.73.4)
react-native-fs: react-native-fs:
specifier: ^2.20.0 specifier: ^2.20.0
version: 2.20.0(react-native@0.73.4) version: 2.20.0(react-native@0.73.4)
@ -6565,7 +6565,7 @@ packages:
magic-string: 0.27.0 magic-string: 0.27.0
react-docgen-typescript: 2.2.2(typescript@5.3.3) react-docgen-typescript: 2.2.2(typescript@5.3.3)
typescript: 5.3.3 typescript: 5.3.3
vite: 5.0.10(less@4.2.0) vite: 5.0.10(@types/node@18.17.19)
/@jridgewell/gen-mapping@0.3.3: /@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
@ -10043,7 +10043,7 @@ packages:
magic-string: 0.30.5 magic-string: 0.30.5
rollup: 3.29.4 rollup: 3.29.4
typescript: 5.3.3 typescript: 5.3.3
vite: 5.0.10(less@4.2.0) vite: 5.0.10(@types/node@18.17.19)
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
- supports-color - supports-color
@ -10396,7 +10396,7 @@ packages:
react: 18.2.0 react: 18.2.0
react-docgen: 6.0.4 react-docgen: 6.0.4
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
vite: 5.0.10(less@4.2.0) vite: 5.0.10(@types/node@18.17.19)
transitivePeerDependencies: transitivePeerDependencies:
- '@preact/preset-vite' - '@preact/preset-vite'
- encoding - encoding
@ -10636,7 +10636,7 @@ packages:
dependencies: dependencies:
'@babel/core': 7.23.2 '@babel/core': 7.23.2
'@svgr/babel-preset': 8.1.0(@babel/core@7.23.2) '@svgr/babel-preset': 8.1.0(@babel/core@7.23.2)
'@svgr/core': 8.1.0(typescript@5.2.2) '@svgr/core': 8.1.0(typescript@5.3.3)
'@svgr/hast-util-to-babel-ast': 8.0.0 '@svgr/hast-util-to-babel-ast': 8.0.0
svg-parser: 2.0.4 svg-parser: 2.0.4
transitivePeerDependencies: transitivePeerDependencies:
@ -11841,7 +11841,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.7) '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.7)
magic-string: 0.27.0 magic-string: 0.27.0
react-refresh: 0.14.0 react-refresh: 0.14.0
vite: 5.0.10(less@4.2.0) vite: 5.0.10(@types/node@18.17.19)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -12489,21 +12489,8 @@ packages:
- supports-color - supports-color
dev: false dev: false
/babel-plugin-jsx-dom-expressions@0.37.11(@babel/core@7.23.7): /babel-plugin-jsx-dom-expressions@0.37.17(@babel/core@7.23.2):
resolution: {integrity: sha512-0NaWy4sFsE0AWlucvL/myEiZ851BgjeLwhtctOFmyVCK6fPXqQHQUBB5SrrrmvOiw/BZCmMe8dOy7JL3FSyTtQ==} resolution: {integrity: sha512-1bv8rOTzs6TR3DVyVZ7ElxyPEhnS556FMWRIsB3gBPfkn/cSKaLvXLGk+X1lvI+SzcUo4G+UcmJrn3vr1ig8mQ==}
peerDependencies:
'@babel/core': ^7.20.12
dependencies:
'@babel/core': 7.23.7
'@babel/helper-module-imports': 7.18.6
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7)
'@babel/types': 7.23.6
html-entities: 2.3.3
validate-html-nesting: 1.2.2
dev: true
/babel-plugin-jsx-dom-expressions@0.37.13(@babel/core@7.23.2):
resolution: {integrity: sha512-oAEMMIgU0h1DmHn4ZDaBBFc08nsVJciLq9pF7g0ZdpeIDKfY4zXjXr8+/oBjKhXG8nyomhnTodPjeG+/ZXcWXQ==}
peerDependencies: peerDependencies:
'@babel/core': ^7.20.12 '@babel/core': ^7.20.12
dependencies: dependencies:
@ -12515,6 +12502,19 @@ packages:
validate-html-nesting: 1.2.2 validate-html-nesting: 1.2.2
dev: false dev: false
/babel-plugin-jsx-dom-expressions@0.37.17(@babel/core@7.23.7):
resolution: {integrity: sha512-1bv8rOTzs6TR3DVyVZ7ElxyPEhnS556FMWRIsB3gBPfkn/cSKaLvXLGk+X1lvI+SzcUo4G+UcmJrn3vr1ig8mQ==}
peerDependencies:
'@babel/core': ^7.20.12
dependencies:
'@babel/core': 7.23.7
'@babel/helper-module-imports': 7.18.6
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7)
'@babel/types': 7.23.6
html-entities: 2.3.3
validate-html-nesting: 1.2.2
dev: true
/babel-plugin-module-resolver@5.0.0: /babel-plugin-module-resolver@5.0.0:
resolution: {integrity: sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==} resolution: {integrity: sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
@ -12730,13 +12730,13 @@ packages:
babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0 babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0
dev: false dev: false
/babel-preset-solid@1.8.8(@babel/core@7.23.7): /babel-preset-solid@1.8.15(@babel/core@7.23.7):
resolution: {integrity: sha512-m+sFxzriUgMiyUPz/oWxU+N6PwY2bVsZVlc4Jxx+5XhDt5lGE/meg+ZL/kLgSAZ75YuU9AJZr444Un1bO0vhJQ==} resolution: {integrity: sha512-P2yOQbB7Hn/m4YvpXV6ExHIMcgNWXWXcvY4kJzG3yqAB3hKS58OZRsvJ7RObsZWqXRvZTITBIwnpK0BMGu+ZIQ==}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0 '@babel/core': ^7.0.0
dependencies: dependencies:
'@babel/core': 7.23.7 '@babel/core': 7.23.7
babel-plugin-jsx-dom-expressions: 0.37.11(@babel/core@7.23.7) babel-plugin-jsx-dom-expressions: 0.37.17(@babel/core@7.23.7)
dev: true dev: true
/babel-preset-solid@1.8.9(@babel/core@7.23.2): /babel-preset-solid@1.8.9(@babel/core@7.23.2):
@ -12745,7 +12745,7 @@ packages:
'@babel/core': ^7.0.0 '@babel/core': ^7.0.0
dependencies: dependencies:
'@babel/core': 7.23.2 '@babel/core': 7.23.2
babel-plugin-jsx-dom-expressions: 0.37.13(@babel/core@7.23.2) babel-plugin-jsx-dom-expressions: 0.37.17(@babel/core@7.23.2)
dev: false dev: false
/bail@2.0.2: /bail@2.0.2:
@ -16953,10 +16953,6 @@ packages:
hasown: 2.0.0 hasown: 2.0.0
side-channel: 1.0.4 side-channel: 1.0.4
/intl@1.2.5:
resolution: {integrity: sha512-rK0KcPHeBFBcqsErKSpvZnrOmWOj+EmDkyJ57e90YWaQNqbcivcqmKDlHEeNprDWOsKzPsh1BfSpPQdDvclHVw==}
dev: false
/invariant@2.2.4: /invariant@2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
dependencies: dependencies:
@ -21190,6 +21186,14 @@ packages:
resolution: {integrity: sha512-BWIKcEYtzjRV6GpkX0Km5/w2E7fgIcywiQOT7JZTc5NSbv/YI9kpFinB9lRFsOoRVGmiqq/O3VfP/oH2clIiBA==} resolution: {integrity: sha512-BWIKcEYtzjRV6GpkX0Km5/w2E7fgIcywiQOT7JZTc5NSbv/YI9kpFinB9lRFsOoRVGmiqq/O3VfP/oH2clIiBA==}
dev: false dev: false
/react-native-file-viewer@2.1.5(react-native@0.73.4):
resolution: {integrity: sha512-MGC6sx9jsqHdefhVQ6o0akdsPGpkXgiIbpygb2Sg4g4bh7v6K1cardLV1NwGB9A6u1yICOSDT/MOC//9Ez6EUg==}
peerDependencies:
react-native: '>=0.47'
dependencies:
react-native: 0.73.4(@babel/core@7.23.2)(@babel/preset-env@7.23.8)(react@18.2.0)
dev: false
/react-native-fs@2.20.0(react-native@0.73.4): /react-native-fs@2.20.0(react-native@0.73.4):
resolution: {integrity: sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==} resolution: {integrity: sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==}
peerDependencies: peerDependencies:
@ -22371,15 +22375,9 @@ packages:
seroval: 1.0.4 seroval: 1.0.4
dev: true dev: true
/seroval@1.0.3:
resolution: {integrity: sha512-v5Psun3O2OdehTS/BpTC9EezHxyQRM4lqtvOdbngEq8qOZUECqG5XaoFNZgBQrJKXZFgcyZtMH6Dv7G96pKSSQ==}
engines: {node: '>=10'}
dev: false
/seroval@1.0.4: /seroval@1.0.4:
resolution: {integrity: sha512-qQs/N+KfJu83rmszFQaTxcoJoPn6KNUruX4KmnmyD0oZkUoiNvJ1rpdYKDf4YHM05k+HOgCxa3yvf15QbVijGg==} resolution: {integrity: sha512-qQs/N+KfJu83rmszFQaTxcoJoPn6KNUruX4KmnmyD0oZkUoiNvJ1rpdYKDf4YHM05k+HOgCxa3yvf15QbVijGg==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true
/serve-static@1.15.0: /serve-static@1.15.0:
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
@ -22582,8 +22580,8 @@ packages:
/solid-js@1.8.8: /solid-js@1.8.8:
resolution: {integrity: sha512-9CtL5xWTYX1WWjQKqht3Tl0AJzgz4YWVQk8hoscO9TzRCgzlpAauEOexXa6bPG30W+fWLnFVE7XUiAzQFNeUKw==} resolution: {integrity: sha512-9CtL5xWTYX1WWjQKqht3Tl0AJzgz4YWVQk8hoscO9TzRCgzlpAauEOexXa6bPG30W+fWLnFVE7XUiAzQFNeUKw==}
dependencies: dependencies:
csstype: 3.1.2 csstype: 3.1.3
seroval: 1.0.3 seroval: 1.0.4
dev: false dev: false
/solid-refresh@0.5.3(solid-js@1.8.11): /solid-refresh@0.5.3(solid-js@1.8.11):
@ -24701,7 +24699,7 @@ packages:
'@babel/core': 7.23.7 '@babel/core': 7.23.7
'@babel/preset-typescript': 7.23.3(@babel/core@7.23.7) '@babel/preset-typescript': 7.23.3(@babel/core@7.23.7)
'@types/babel__core': 7.20.5 '@types/babel__core': 7.20.5
babel-preset-solid: 1.8.8(@babel/core@7.23.7) babel-preset-solid: 1.8.15(@babel/core@7.23.7)
merge-anything: 5.1.7 merge-anything: 5.1.7
solid-js: 1.8.11 solid-js: 1.8.11
solid-refresh: 0.5.3(solid-js@1.8.11) solid-refresh: 0.5.3(solid-js@1.8.11)
@ -24827,7 +24825,6 @@ packages:
rollup: 4.9.2 rollup: 4.9.2
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
dev: true
/vite@5.0.10(less@4.2.0): /vite@5.0.10(less@4.2.0):
resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==}
@ -24863,6 +24860,7 @@ packages:
rollup: 4.9.2 rollup: 4.9.2
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
dev: true
/vite@5.0.10(sass@1.69.5): /vite@5.0.10(sass@1.69.5):
resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==}