Rustify mobile (#361)
* Refactor navigation flow & types * Remove drawer screen wrapper * Remove DrawerItem + cleanup * Switch to JS Stack Nav & header animations * [WIP] Spacedrive core on Android & IOS * Update Podfile and cleanup Contributing guide. * Remove @sd/core from mobile * File Modal * Prettify File Modal & Add date-fns * IOS subscriptions * Update package versions * Custom header for stack screens * android subscriptions * Animate Drawer button & template for Search screen * Search header * Fix Search icon being weird * Merge branch 'main' into rustify-mobile * fix rspc dep + setup script for mobile * Less margin on header * Move shared assets & drawer logo for mobile * support for IOS simulator * add type safe rspc hooks to mobile * Cleanup PR & Update packages * Updated bindings from main * Update lefthook.yml * Remove `tag` folder from core The `tag` folder came back from the dead. Maybe it got confused in merge conflict? * update pnpm lockfile + fix tsc errors * fix asset import Co-authored-by: Utku Bakir <74243531+utkubakir@users.noreply.github.com>
|
@ -37,39 +37,43 @@ This project uses [Cargo](https://doc.rust-lang.org/cargo/getting-started/instal
|
||||||
|
|
||||||
> Note: MacOS M1 users should choose the customize option in the rustup init script and enter `x86_64-apple-darwin` as the default host triple instead of the default `aarch64-apple-darwin`
|
> Note: MacOS M1 users should choose the customize option in the rustup init script and enter `x86_64-apple-darwin` as the default host triple instead of the default `aarch64-apple-darwin`
|
||||||
|
|
||||||
- `$ git clone https://github.com/spacedriveapp/spacedrive`
|
- `git clone https://github.com/spacedriveapp/spacedrive`
|
||||||
- `$ cd spacedrive`
|
- `cd spacedrive`
|
||||||
- For Linux or MacOS users run: `./.github/scripts/setup-system.sh`
|
- For Linux or MacOS users run: `./.github/scripts/setup-system.sh`
|
||||||
- This will install FFMPEG and any other required dependencies for Spacedrive to build.
|
- This will install FFMPEG and any other required dependencies for Spacedrive to build.
|
||||||
- For Windows users run using PowerShell: `.\.github\scripts\setup-system.ps1`
|
- For Windows users run using PowerShell: `.\.github\scripts\setup-system.ps1`
|
||||||
- This will install pnpm, LLVM, FFMPEG and any other required dependencies for Spacedrive to build.
|
- This will install pnpm, LLVM, FFMPEG and any other required dependencies for Spacedrive to build.
|
||||||
- Ensure you run it like documented above as it expects it is executed from the root of the repository.
|
- Ensure you run it like documented above as it expects it is executed from the root of the repository.
|
||||||
- `$ pnpm i`
|
- `pnpm i`
|
||||||
- `$ pnpm prep` - Runs all necessary codegen & builds required dependencies.
|
- `pnpm prep` - Runs all necessary codegen & builds required dependencies.
|
||||||
|
|
||||||
To quickly run only the desktop app after `prep` you can use:
|
To quickly run only the desktop app after `prep` you can use:
|
||||||
|
|
||||||
- `$ pnpm desktop dev`
|
- `pnpm desktop dev`
|
||||||
|
|
||||||
To run the landing page
|
To run the landing page
|
||||||
|
|
||||||
- `$ pnpm web dev` - runs the web app for the embed
|
- `pnpm web dev` - runs the web app for the embed
|
||||||
- `$ pnpm landing dev`
|
- `pnpm landing dev`
|
||||||
|
|
||||||
To run mobile app
|
|
||||||
|
|
||||||
- `$ cd apps/mobile && pnpm i` - As this is a seperated workspace, you need to do this!
|
|
||||||
- `$ pnpm android` - runs on Android Emulator
|
|
||||||
- `$ pnpm ios` - runs on iOS Emulator
|
|
||||||
- `$ pnpm dev` - For already bundled app
|
|
||||||
|
|
||||||
You also need `expo-cli` installed globally.
|
|
||||||
|
|
||||||
If you are having issues ensure you are using the following versions of Rust and Node:
|
If you are having issues ensure you are using the following versions of Rust and Node:
|
||||||
|
|
||||||
- Rust version: **1.62.0**
|
- Rust version: **1.63.0**
|
||||||
- Node version: **17**
|
- Node version: **17**
|
||||||
|
|
||||||
|
##### Mobile app
|
||||||
|
|
||||||
|
To run mobile app
|
||||||
|
|
||||||
|
- Install [Android Studio](https://developer.android.com/studio) for Android and [Xcode](https://apps.apple.com/au/app/xcode/id497799835) for IOS development
|
||||||
|
- `./.github/scripts/setup-system.sh mobile`
|
||||||
|
- The should setup most of the dependencies for the mobile app to build.
|
||||||
|
- You must also ensure [you must have NDK 24.0.8215888 and CMake](https://developer.android.com/studio/projects/install-ndk#default-version) in Android Studio
|
||||||
|
- `cd apps/mobile && pnpm i` - This is a separate workspace, you need to do this!
|
||||||
|
- `pnpm android` - runs on Android Emulator
|
||||||
|
- `pnpm ios` - runs on iOS Emulator
|
||||||
|
- `pnpm dev` - For already bundled app - This is only temporarily supported. The final app will require the Spacedrive Rust code which isn't included in Expo Go.
|
||||||
|
|
||||||
### Pull Request
|
### Pull Request
|
||||||
|
|
||||||
When you're finished with the changes, create a pull request, also known as a PR.
|
When you're finished with the changes, create a pull request, also known as a PR.
|
||||||
|
|
430
Cargo.lock
generated
18
Cargo.toml
|
@ -1,9 +1,13 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
|
||||||
"apps/desktop/src-tauri",
|
|
||||||
"core",
|
|
||||||
"core/prisma",
|
|
||||||
"core/derive",
|
|
||||||
"apps/server",
|
|
||||||
]
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"apps/desktop/src-tauri",
|
||||||
|
"apps/mobile/rust",
|
||||||
|
"core",
|
||||||
|
"core/prisma",
|
||||||
|
"apps/server"
|
||||||
|
]
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
# We use this patch so we can compile for the IOS simulator on M1
|
||||||
|
openssl-sys = { git = "https://github.com/spacedriveapp/rust-openssl" }
|
|
@ -11,6 +11,7 @@ build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "1.0.4", features = ["api-all", "macos-private-api"] }
|
tauri = { version = "1.0.4", features = ["api-all", "macos-private-api"] }
|
||||||
|
rspc = { version = "0.0.4", features = ["tauri"] }
|
||||||
sdcore = { path = "../../../core" }
|
sdcore = { path = "../../../core" }
|
||||||
tokio = { version = "1.17.0", features = ["sync"] }
|
tokio = { version = "1.17.0", features = ["sync"] }
|
||||||
window-shadows = "0.1.2"
|
window-shadows = "0.1.2"
|
||||||
|
|
|
@ -23,7 +23,7 @@ async fn main() {
|
||||||
let (node, router) = Node::new(data_dir).await;
|
let (node, router) = Node::new(data_dir).await;
|
||||||
|
|
||||||
let app = tauri::Builder::default()
|
let app = tauri::Builder::default()
|
||||||
.plugin(sdcore::rspc::integrations::tauri::plugin(router, {
|
.plugin(rspc::integrations::tauri::plugin(router, {
|
||||||
let node = node.clone();
|
let node = node.clone();
|
||||||
move || node.get_request_context()
|
move || node.get_request_context()
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"@icons-pack/react-simple-icons": "^5.2.0",
|
"@icons-pack/react-simple-icons": "^5.2.0",
|
||||||
"@sd/interface": "link:../../packages/interface",
|
"@sd/interface": "link:../../packages/interface",
|
||||||
"@sd/ui": "link:../../packages/ui",
|
"@sd/ui": "link:../../packages/ui",
|
||||||
|
"@sd/assets": "link:../../packages/assets",
|
||||||
"@tryghost/content-api": "^1.11.0",
|
"@tryghost/content-api": "^1.11.0",
|
||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
|
|
@ -6,10 +6,9 @@ import {
|
||||||
Twitch,
|
Twitch,
|
||||||
Twitter
|
Twitter
|
||||||
} from '@icons-pack/react-simple-icons';
|
} from '@icons-pack/react-simple-icons';
|
||||||
|
import AppLogo from '@sd/assets/images/logo.png';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import AppLogo from '../assets/images/logo.png';
|
|
||||||
|
|
||||||
function FooterLink(props: { children: string | JSX.Element; link: string; blank?: boolean }) {
|
function FooterLink(props: { children: string | JSX.Element; link: string; blank?: boolean }) {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { BookOpenIcon, MapIcon, QuestionMarkCircleIcon, UsersIcon } from '@heroicons/react/solid';
|
import { BookOpenIcon, MapIcon, QuestionMarkCircleIcon, UsersIcon } from '@heroicons/react/solid';
|
||||||
import { Discord, Github } from '@icons-pack/react-simple-icons';
|
import { Discord, Github } from '@icons-pack/react-simple-icons';
|
||||||
|
import AppLogo from '@sd/assets/images/logo.png';
|
||||||
import { Dropdown, DropdownItem } from '@sd/ui';
|
import { Dropdown, DropdownItem } from '@sd/ui';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List } from 'phosphor-react';
|
import { List } from 'phosphor-react';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import AppLogo from '../assets/images/logo.png';
|
|
||||||
import { positions } from '../pages/careers.page';
|
import { positions } from '../pages/careers.page';
|
||||||
import { getWindow } from '../utils';
|
import { getWindow } from '../utils';
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
Make sure to run `pnpm i` in this folder after making changes to the `packages`.
|
Make sure to run `pnpm i` in this folder after making changes to the `packages`.
|
||||||
|
|
||||||
|
- Note: If you add/remove something from `packages/assets` folder, you need to delete node_modules and run `pnpm i` again to link it.
|
||||||
|
|
|
@ -3,6 +3,24 @@ apply plugin: "com.android.application"
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
|
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||||
|
|
||||||
|
cargo {
|
||||||
|
module = "../../rust"
|
||||||
|
libname = "sdcore"
|
||||||
|
// profile = 'release',
|
||||||
|
pythonCommand = 'python3'
|
||||||
|
targets = ["arm", "arm64", "x86", "x86_64"]
|
||||||
|
targetDirectory = "../.././../../target" // Monorepo moment
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.whenTaskAdded { task ->
|
||||||
|
if ((task.name == 'javaPreCompileDebug' || task.name == 'javaPreCompileRelease')) {
|
||||||
|
task.dependsOn 'cargoBuild'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||||
* and bundleReleaseJsAndAssets).
|
* and bundleReleaseJsAndAssets).
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
// packages.add(new MyReactNativePackage());
|
packages.add(new com.spacedrive.app.SpacedrivePackage());
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.spacedrive.app;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.Promise;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.ReactContext;
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class SDCore extends ReactContextBaseJavaModule {
|
||||||
|
SDCore(ReactApplicationContext context) { super(context); }
|
||||||
|
|
||||||
|
private boolean registeredWithRust = false;
|
||||||
|
private int listeners = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "SDCore";
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("sdcore");
|
||||||
|
}
|
||||||
|
|
||||||
|
// is exposed by Rust and is used to register the subscription
|
||||||
|
private native void registerCoreEventListener();
|
||||||
|
|
||||||
|
private native void handleCoreMsg(String query, Promise promise);
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void sd_core_msg(String query, Promise promise)
|
||||||
|
{
|
||||||
|
this.handleCoreMsg(query, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDataDirectory()
|
||||||
|
{
|
||||||
|
return getCurrentActivity().getFilesDir().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void addListener(String eventName)
|
||||||
|
{
|
||||||
|
if (!registeredWithRust)
|
||||||
|
{
|
||||||
|
this.registerCoreEventListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listeners++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void removeListeners(Integer count)
|
||||||
|
{
|
||||||
|
this.listeners--;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendCoreEvent(String body)
|
||||||
|
{
|
||||||
|
if (this.listeners > 0)
|
||||||
|
{
|
||||||
|
this.getReactApplicationContext()
|
||||||
|
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||||
|
.emit("SDCoreEvent", body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.spacedrive.app;
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.bridge.NativeModule;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SpacedrivePackage implements ReactPackage {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NativeModule> createNativeModules(
|
||||||
|
ReactApplicationContext reactContext) {
|
||||||
|
List<NativeModule> modules = new ArrayList<>();
|
||||||
|
|
||||||
|
modules.add(new SDCore(reactContext));
|
||||||
|
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,11 +24,15 @@ buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
url "https://plugins.gradle.org/m2/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath('com.android.tools.build:gradle:7.1.1')
|
classpath('com.android.tools.build:gradle:7.1.1')
|
||||||
classpath('com.facebook.react:react-native-gradle-plugin')
|
classpath('com.facebook.react:react-native-gradle-plugin')
|
||||||
classpath('de.undercouch:gradle-download-task:5.0.1')
|
classpath('de.undercouch:gradle-download-task:5.0.1')
|
||||||
|
classpath('org.mozilla.rust-android-gradle:plugin:0.9.3')
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,27 @@ PODS:
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- EXFont (10.2.0):
|
- EXFont (10.2.0):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- Expo (46.0.2):
|
- Expo (46.0.9):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoKeepAwake (10.2.0):
|
- ExpoKeepAwake (10.2.0):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- ExpoModulesCore (0.11.3):
|
- ExpoModulesCore (0.11.4):
|
||||||
- React-Core
|
- React-Core
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- EXSplashScreen (0.16.1):
|
- EXSplashScreen (0.16.2):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- React-Core
|
- React-Core
|
||||||
- FBLazyVector (0.69.3)
|
- FBLazyVector (0.69.4)
|
||||||
- FBReactNativeSpec (0.69.3):
|
- FBReactNativeSpec (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTRequired (= 0.69.3)
|
- RCTRequired (= 0.69.4)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Core (= 0.69.3)
|
- React-Core (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- fmt (6.2.1)
|
- fmt (6.2.1)
|
||||||
- glog (0.3.5)
|
- glog (0.3.5)
|
||||||
- hermes-engine (0.69.3)
|
- hermes-engine (0.69.4)
|
||||||
- libevent (2.1.12)
|
- libevent (2.1.12)
|
||||||
- RCT-Folly (2021.06.28.00-v2):
|
- RCT-Folly (2021.06.28.00-v2):
|
||||||
- boost
|
- boost
|
||||||
|
@ -48,214 +48,214 @@ PODS:
|
||||||
- fmt (~> 6.2.1)
|
- fmt (~> 6.2.1)
|
||||||
- glog
|
- glog
|
||||||
- libevent
|
- libevent
|
||||||
- RCTRequired (0.69.3)
|
- RCTRequired (0.69.4)
|
||||||
- RCTTypeSafety (0.69.3):
|
- RCTTypeSafety (0.69.4):
|
||||||
- FBLazyVector (= 0.69.3)
|
- FBLazyVector (= 0.69.4)
|
||||||
- RCTRequired (= 0.69.3)
|
- RCTRequired (= 0.69.4)
|
||||||
- React-Core (= 0.69.3)
|
- React-Core (= 0.69.4)
|
||||||
- React (0.69.3):
|
- React (0.69.4):
|
||||||
- React-Core (= 0.69.3)
|
- React-Core (= 0.69.4)
|
||||||
- React-Core/DevSupport (= 0.69.3)
|
- React-Core/DevSupport (= 0.69.4)
|
||||||
- React-Core/RCTWebSocket (= 0.69.3)
|
- React-Core/RCTWebSocket (= 0.69.4)
|
||||||
- React-RCTActionSheet (= 0.69.3)
|
- React-RCTActionSheet (= 0.69.4)
|
||||||
- React-RCTAnimation (= 0.69.3)
|
- React-RCTAnimation (= 0.69.4)
|
||||||
- React-RCTBlob (= 0.69.3)
|
- React-RCTBlob (= 0.69.4)
|
||||||
- React-RCTImage (= 0.69.3)
|
- React-RCTImage (= 0.69.4)
|
||||||
- React-RCTLinking (= 0.69.3)
|
- React-RCTLinking (= 0.69.4)
|
||||||
- React-RCTNetwork (= 0.69.3)
|
- React-RCTNetwork (= 0.69.4)
|
||||||
- React-RCTSettings (= 0.69.3)
|
- React-RCTSettings (= 0.69.4)
|
||||||
- React-RCTText (= 0.69.3)
|
- React-RCTText (= 0.69.4)
|
||||||
- React-RCTVibration (= 0.69.3)
|
- React-RCTVibration (= 0.69.4)
|
||||||
- React-bridging (0.69.3):
|
- React-bridging (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-callinvoker (0.69.3)
|
- React-callinvoker (0.69.4)
|
||||||
- React-Codegen (0.69.3):
|
- React-Codegen (0.69.4):
|
||||||
- FBReactNativeSpec (= 0.69.3)
|
- FBReactNativeSpec (= 0.69.4)
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTRequired (= 0.69.3)
|
- RCTRequired (= 0.69.4)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Core (= 0.69.3)
|
- React-Core (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-Core (0.69.3):
|
- React-Core (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default (= 0.69.3)
|
- React-Core/Default (= 0.69.4)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/CoreModulesHeaders (0.69.3):
|
- React-Core/CoreModulesHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/Default (0.69.3):
|
- React-Core/Default (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/DevSupport (0.69.3):
|
- React-Core/DevSupport (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default (= 0.69.3)
|
- React-Core/Default (= 0.69.4)
|
||||||
- React-Core/RCTWebSocket (= 0.69.3)
|
- React-Core/RCTWebSocket (= 0.69.4)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-jsinspector (= 0.69.3)
|
- React-jsinspector (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTActionSheetHeaders (0.69.3):
|
- React-Core/RCTActionSheetHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTAnimationHeaders (0.69.3):
|
- React-Core/RCTAnimationHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTBlobHeaders (0.69.3):
|
- React-Core/RCTBlobHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTImageHeaders (0.69.3):
|
- React-Core/RCTImageHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTLinkingHeaders (0.69.3):
|
- React-Core/RCTLinkingHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTNetworkHeaders (0.69.3):
|
- React-Core/RCTNetworkHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTSettingsHeaders (0.69.3):
|
- React-Core/RCTSettingsHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTTextHeaders (0.69.3):
|
- React-Core/RCTTextHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTVibrationHeaders (0.69.3):
|
- React-Core/RCTVibrationHeaders (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default
|
- React-Core/Default
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-Core/RCTWebSocket (0.69.3):
|
- React-Core/RCTWebSocket (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Core/Default (= 0.69.3)
|
- React-Core/Default (= 0.69.4)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- Yoga
|
- Yoga
|
||||||
- React-CoreModules (0.69.3):
|
- React-CoreModules (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/CoreModulesHeaders (= 0.69.3)
|
- React-Core/CoreModulesHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-RCTImage (= 0.69.3)
|
- React-RCTImage (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-cxxreact (0.69.3):
|
- React-cxxreact (0.69.4):
|
||||||
- boost (= 1.76.0)
|
- boost (= 1.76.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-callinvoker (= 0.69.3)
|
- React-callinvoker (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsinspector (= 0.69.3)
|
- React-jsinspector (= 0.69.4)
|
||||||
- React-logger (= 0.69.3)
|
- React-logger (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- React-runtimeexecutor (= 0.69.3)
|
- React-runtimeexecutor (= 0.69.4)
|
||||||
- React-hermes (0.69.3):
|
- React-hermes (0.69.4):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- hermes-engine
|
- hermes-engine
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCT-Folly/Futures (= 2021.06.28.00-v2)
|
- RCT-Folly/Futures (= 2021.06.28.00-v2)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-jsiexecutor (= 0.69.3)
|
- React-jsiexecutor (= 0.69.4)
|
||||||
- React-jsinspector (= 0.69.3)
|
- React-jsinspector (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- React-jsi (0.69.3):
|
- React-jsi (0.69.4):
|
||||||
- boost (= 1.76.0)
|
- boost (= 1.76.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-jsi/Default (= 0.69.3)
|
- React-jsi/Default (= 0.69.4)
|
||||||
- React-jsi/Default (0.69.3):
|
- React-jsi/Default (0.69.4):
|
||||||
- boost (= 1.76.0)
|
- boost (= 1.76.0)
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-jsiexecutor (0.69.3):
|
- React-jsiexecutor (0.69.4):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- React-jsinspector (0.69.3)
|
- React-jsinspector (0.69.4)
|
||||||
- React-logger (0.69.3):
|
- React-logger (0.69.4):
|
||||||
- glog
|
- glog
|
||||||
- react-native-safe-area-context (4.3.1):
|
- react-native-safe-area-context (4.3.1):
|
||||||
- RCT-Folly
|
- RCT-Folly
|
||||||
|
@ -263,74 +263,76 @@ PODS:
|
||||||
- RCTTypeSafety
|
- RCTTypeSafety
|
||||||
- React
|
- React
|
||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- React-perflogger (0.69.3)
|
- React-perflogger (0.69.4)
|
||||||
- React-RCTActionSheet (0.69.3):
|
- React-RCTActionSheet (0.69.4):
|
||||||
- React-Core/RCTActionSheetHeaders (= 0.69.3)
|
- React-Core/RCTActionSheetHeaders (= 0.69.4)
|
||||||
- React-RCTAnimation (0.69.3):
|
- React-RCTAnimation (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTAnimationHeaders (= 0.69.3)
|
- React-Core/RCTAnimationHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTBlob (0.69.3):
|
- React-RCTBlob (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTBlobHeaders (= 0.69.3)
|
- React-Core/RCTBlobHeaders (= 0.69.4)
|
||||||
- React-Core/RCTWebSocket (= 0.69.3)
|
- React-Core/RCTWebSocket (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-RCTNetwork (= 0.69.3)
|
- React-RCTNetwork (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTImage (0.69.3):
|
- React-RCTImage (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTImageHeaders (= 0.69.3)
|
- React-Core/RCTImageHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-RCTNetwork (= 0.69.3)
|
- React-RCTNetwork (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTLinking (0.69.3):
|
- React-RCTLinking (0.69.4):
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTLinkingHeaders (= 0.69.3)
|
- React-Core/RCTLinkingHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTNetwork (0.69.3):
|
- React-RCTNetwork (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTNetworkHeaders (= 0.69.3)
|
- React-Core/RCTNetworkHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTSettings (0.69.3):
|
- React-RCTSettings (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- RCTTypeSafety (= 0.69.3)
|
- RCTTypeSafety (= 0.69.4)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTSettingsHeaders (= 0.69.3)
|
- React-Core/RCTSettingsHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-RCTText (0.69.3):
|
- React-RCTText (0.69.4):
|
||||||
- React-Core/RCTTextHeaders (= 0.69.3)
|
- React-Core/RCTTextHeaders (= 0.69.4)
|
||||||
- React-RCTVibration (0.69.3):
|
- React-RCTVibration (0.69.4):
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-Codegen (= 0.69.3)
|
- React-Codegen (= 0.69.4)
|
||||||
- React-Core/RCTVibrationHeaders (= 0.69.3)
|
- React-Core/RCTVibrationHeaders (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (= 0.69.3)
|
- ReactCommon/turbomodule/core (= 0.69.4)
|
||||||
- React-runtimeexecutor (0.69.3):
|
- React-runtimeexecutor (0.69.4):
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- ReactCommon/turbomodule/core (0.69.3):
|
- ReactCommon/turbomodule/core (0.69.4):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- RCT-Folly (= 2021.06.28.00-v2)
|
- RCT-Folly (= 2021.06.28.00-v2)
|
||||||
- React-bridging (= 0.69.3)
|
- React-bridging (= 0.69.4)
|
||||||
- React-callinvoker (= 0.69.3)
|
- React-callinvoker (= 0.69.4)
|
||||||
- React-Core (= 0.69.3)
|
- React-Core (= 0.69.4)
|
||||||
- React-cxxreact (= 0.69.3)
|
- React-cxxreact (= 0.69.4)
|
||||||
- React-jsi (= 0.69.3)
|
- React-jsi (= 0.69.4)
|
||||||
- React-logger (= 0.69.3)
|
- React-logger (= 0.69.4)
|
||||||
- React-perflogger (= 0.69.3)
|
- React-perflogger (= 0.69.4)
|
||||||
- RNCAsyncStorage (1.17.7):
|
- RNCAsyncStorage (1.17.7):
|
||||||
- React-Core
|
- React-Core
|
||||||
|
- RNCMaskedView (0.2.7):
|
||||||
|
- React-Core
|
||||||
- RNGestureHandler (2.5.0):
|
- RNGestureHandler (2.5.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNReanimated (2.9.1):
|
- RNReanimated (2.9.1):
|
||||||
|
@ -363,21 +365,21 @@ PODS:
|
||||||
- RNScreens (3.15.0):
|
- RNScreens (3.15.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- React-RCTImage
|
- React-RCTImage
|
||||||
- RNSVG (12.4.3):
|
- RNSVG (13.0.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- Yoga (1.14.0)
|
- Yoga (1.14.0)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.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.2/node_modules/expo-application/ios`)"
|
- "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.2/node_modules/expo-constants/ios`)"
|
- "EXConstants (from `../node_modules/.pnpm/expo-constants@13.2.3_expo@46.0.9/node_modules/expo-constants/ios`)"
|
||||||
- "EXFileSystem (from `../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.2/node_modules/expo-file-system/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.2/node_modules/expo-font/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.2_@babel+core@7.18.10/node_modules/expo`)"
|
- "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.2/node_modules/expo-keep-awake/ios`)"
|
- "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.3/node_modules/expo-modules-core/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.1_expo@46.0.2/node_modules/expo-splash-screen/ios`)"
|
- "EXSplashScreen (from `../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.9/node_modules/expo-splash-screen/ios`)"
|
||||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||||
|
@ -413,6 +415,7 @@ DEPENDENCIES:
|
||||||
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
||||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||||
|
- "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)"
|
||||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||||
- RNScreens (from `../node_modules/react-native-screens`)
|
- RNScreens (from `../node_modules/react-native-screens`)
|
||||||
|
@ -430,21 +433,21 @@ EXTERNAL SOURCES:
|
||||||
DoubleConversion:
|
DoubleConversion:
|
||||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||||
EXApplication:
|
EXApplication:
|
||||||
:path: "../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.2/node_modules/expo-application/ios"
|
:path: "../node_modules/.pnpm/expo-application@4.2.2_expo@46.0.9/node_modules/expo-application/ios"
|
||||||
EXConstants:
|
EXConstants:
|
||||||
:path: "../node_modules/.pnpm/expo-constants@13.2.3_expo@46.0.2/node_modules/expo-constants/ios"
|
:path: "../node_modules/.pnpm/expo-constants@13.2.3_expo@46.0.9/node_modules/expo-constants/ios"
|
||||||
EXFileSystem:
|
EXFileSystem:
|
||||||
:path: "../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.2/node_modules/expo-file-system/ios"
|
:path: "../node_modules/.pnpm/expo-file-system@14.1.0_expo@46.0.9/node_modules/expo-file-system/ios"
|
||||||
EXFont:
|
EXFont:
|
||||||
:path: "../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.2/node_modules/expo-font/ios"
|
:path: "../node_modules/.pnpm/expo-font@10.2.0_expo@46.0.9/node_modules/expo-font/ios"
|
||||||
Expo:
|
Expo:
|
||||||
:path: "../node_modules/.pnpm/expo@46.0.2_@babel+core@7.18.10/node_modules/expo"
|
:path: "../node_modules/.pnpm/expo@46.0.9_@babel+core@7.18.10/node_modules/expo"
|
||||||
ExpoKeepAwake:
|
ExpoKeepAwake:
|
||||||
:path: "../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.2/node_modules/expo-keep-awake/ios"
|
:path: "../node_modules/.pnpm/expo-keep-awake@10.2.0_expo@46.0.9/node_modules/expo-keep-awake/ios"
|
||||||
ExpoModulesCore:
|
ExpoModulesCore:
|
||||||
:path: "../node_modules/.pnpm/expo-modules-core@0.11.3/node_modules/expo-modules-core/ios"
|
:path: "../node_modules/.pnpm/expo-modules-core@0.11.4/node_modules/expo-modules-core/ios"
|
||||||
EXSplashScreen:
|
EXSplashScreen:
|
||||||
:path: "../node_modules/.pnpm/expo-splash-screen@0.16.1_expo@46.0.2/node_modules/expo-splash-screen/ios"
|
:path: "../node_modules/.pnpm/expo-splash-screen@0.16.2_expo@46.0.9/node_modules/expo-splash-screen/ios"
|
||||||
FBLazyVector:
|
FBLazyVector:
|
||||||
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
||||||
FBReactNativeSpec:
|
FBReactNativeSpec:
|
||||||
|
@ -511,6 +514,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/ReactCommon"
|
:path: "../node_modules/react-native/ReactCommon"
|
||||||
RNCAsyncStorage:
|
RNCAsyncStorage:
|
||||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||||
|
RNCMaskedView:
|
||||||
|
:path: "../node_modules/@react-native-masked-view/masked-view"
|
||||||
RNGestureHandler:
|
RNGestureHandler:
|
||||||
:path: "../node_modules/react-native-gesture-handler"
|
:path: "../node_modules/react-native-gesture-handler"
|
||||||
RNReanimated:
|
RNReanimated:
|
||||||
|
@ -529,50 +534,51 @@ SPEC CHECKSUMS:
|
||||||
EXConstants: 75c40827af38bd6bfcf69f880a5b45037eeff9c9
|
EXConstants: 75c40827af38bd6bfcf69f880a5b45037eeff9c9
|
||||||
EXFileSystem: 927e0a8885aa9c49e50fc38eaba2c2389f2f1019
|
EXFileSystem: 927e0a8885aa9c49e50fc38eaba2c2389f2f1019
|
||||||
EXFont: a5d80bd9b3452b2d5abbce2487da89b0150e6487
|
EXFont: a5d80bd9b3452b2d5abbce2487da89b0150e6487
|
||||||
Expo: a2d9d4d17b9c97beab797c54220b305708f60e87
|
Expo: 73412414e62f5cbc6e713def821de70b92cd3ad6
|
||||||
ExpoKeepAwake: 0e8f18142e71bbf2c7f6aa66ebed249ba1420320
|
ExpoKeepAwake: 0e8f18142e71bbf2c7f6aa66ebed249ba1420320
|
||||||
ExpoModulesCore: 8303cc952788be09fc6eab62815d257016ae6dec
|
ExpoModulesCore: e281bb7b78ea47e227dd5af94d04b24d8b2e1255
|
||||||
EXSplashScreen: 31ab6df6d23e97e074d1330224741979943f1d82
|
EXSplashScreen: 799bece80089219b2c989c1082d70f3b00995cda
|
||||||
FBLazyVector: 1d83d91816fa605d16227a83f1b2e71c8df09d22
|
FBLazyVector: c71b8c429a8af2aff1013934a7152e9d9d0c937d
|
||||||
FBReactNativeSpec: 06454fe46192886c1bc472593057015292ba37ee
|
FBReactNativeSpec: 3cc5cff7d792e74a875be91e56d6242335016f50
|
||||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||||
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
|
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
|
||||||
hermes-engine: ff1ba576165861a94a0d101b0a351a8ca2149f36
|
hermes-engine: 761a544537e62df2a37189389b9d2654dc1f75af
|
||||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||||
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
|
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
|
||||||
RCTRequired: 66822c147facf02f7774af99825e0a31e39df42e
|
RCTRequired: bd9d2ab0fda10171fcbcf9ba61a7df4dc15a28f4
|
||||||
RCTTypeSafety: 309306c4e711b14a83c55c2816a6cc490ec19827
|
RCTTypeSafety: e44e139bf6ec8042db396201834fc2372f6a21cd
|
||||||
React: a779632422a918b26db4f1b57225a41c14d20525
|
React: 482cd1ba23c471be1aed3800180be2427418d7be
|
||||||
React-bridging: 96055aa45f0417898d7833e251f4ae79d28acef7
|
React-bridging: c2ea4fed6fe4ed27c12fd71e88b5d5d3da107fde
|
||||||
React-callinvoker: 02df4d620df286381ff3f99180fb24feceaf01cc
|
React-callinvoker: d4d1f98163fb5e35545e910415ef6c04796bb188
|
||||||
React-Codegen: 06613a5e753c3af2dca0d6e7dd02944a3d77c3f6
|
React-Codegen: ff35fb9c7f6ec2ed34fb6de2e1099d88dfb25f2f
|
||||||
React-Core: 638d54d64048aa635e7c583fb0d8425206f446b4
|
React-Core: 4d3443a45b67c71d74d7243ddde9569d1e4f4fad
|
||||||
React-CoreModules: f706ec2a1939387517cadc6ce0d2ef0f20fccb53
|
React-CoreModules: 70be25399366b5632ab18ecf6fe444a8165a7bea
|
||||||
React-cxxreact: ec183b7f6fec01e7167f38c1c64a03f68dca7fb2
|
React-cxxreact: 822d3794fc0bf206f4691592f90e086dd4f92228
|
||||||
React-hermes: a97962948f74aaefffd4fe00bdafafbc245b08af
|
React-hermes: 7f67b8363288258c3b0cd4aef5975cb7f0b9549a
|
||||||
React-jsi: ed7dc77f5193dca9c73cec90bfec409e7ddfe401
|
React-jsi: ffa51cbc9a78cc156cf61f79ed52ecb76dc6013b
|
||||||
React-jsiexecutor: 1842ca163b160aeb224d2c65b2a60c393b273c67
|
React-jsiexecutor: a27badbbdbc0ff781813370736a2d1c7261181d4
|
||||||
React-jsinspector: bb2605f98aada5d81f3494690da3ef3b4ff3b716
|
React-jsinspector: 8a3d3f5dcd23a91e8c80b1bf0e96902cd1dca999
|
||||||
React-logger: 23a50ef4c18bf9adbb51e2c979318e6b3a2e44a1
|
React-logger: 1088859f145b8f6dd0d3ed051a647ef0e3e80fad
|
||||||
react-native-safe-area-context: 6c12e3859b6f27b25de4fee8201cfb858432d8de
|
react-native-safe-area-context: 6c12e3859b6f27b25de4fee8201cfb858432d8de
|
||||||
React-perflogger: 39d2ba8cbcac54d1bb1d9a980dab348e96aef467
|
React-perflogger: cb386fd44c97ec7f8199c04c12b22066b0f2e1e0
|
||||||
React-RCTActionSheet: b1ad907a2c8f8e4d037148ca507b7f2d6ab1c66d
|
React-RCTActionSheet: f803a85e46cf5b4066c2ac5e122447f918e9c6e5
|
||||||
React-RCTAnimation: 914a9ba46fb6e7376f7709c7ce825d53b47ca2ee
|
React-RCTAnimation: 19c80fa950ccce7f4db76a2a7f2cf79baae07fc7
|
||||||
React-RCTBlob: de62fd5edc5c36951f0b113bf252eb43b7131f79
|
React-RCTBlob: f36ab97e2d515c36df14a1571e50056be80413d5
|
||||||
React-RCTImage: aa0749a8d748b34942c7e71ac5d9f42be8b70cf3
|
React-RCTImage: 2c8f0a329a116248e82f8972ffe806e47c6d1cfa
|
||||||
React-RCTLinking: 595a9f8fbf4d6634bff28d1175b3523b61466612
|
React-RCTLinking: 670f0223075aff33be3b89714f1da4f5343fc4af
|
||||||
React-RCTNetwork: 0559fd0fccb01f89c638baa43c8d185dc8008626
|
React-RCTNetwork: 09385b73f4ff1f46bd5d749540fb33f69a7e5908
|
||||||
React-RCTSettings: 8e492a25a62f1ef6323f82ce652ae87fa59c82ca
|
React-RCTSettings: 33b12d3ac7a1f2eba069ec7bd1b84345263b3bbe
|
||||||
React-RCTText: 17457cde6ef8832ba43c886baebb6627c5d7ed18
|
React-RCTText: a1a3ea902403bd9ae4cf6f7960551dc1d25711b5
|
||||||
React-RCTVibration: dd8099eb46e9cee4692934bc8cbe5e9a4f5e8d31
|
React-RCTVibration: 9adb4a3cbb598d1bbd46a05256f445e4b8c70603
|
||||||
React-runtimeexecutor: 607eb048e22a16388c908ee1f6644200e8d1e19b
|
React-runtimeexecutor: 61ee22a8cdf8b6bb2a7fb7b4ba2cc763e5285196
|
||||||
ReactCommon: af7636436b382db7cde4583bbd642f0978e6e3ed
|
ReactCommon: 8f67bd7e0a6afade0f20718f859dc8c2275f2e83
|
||||||
RNCAsyncStorage: d81ee5c3db1060afd49ea7045ad460eff82d2b7d
|
RNCAsyncStorage: d81ee5c3db1060afd49ea7045ad460eff82d2b7d
|
||||||
|
RNCMaskedView: cb9670ea9239998340eaab21df13fa12a1f9de15
|
||||||
RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50
|
RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50
|
||||||
RNReanimated: 2cf7451318bb9cc430abeec8d67693f9cf4e039c
|
RNReanimated: 2cf7451318bb9cc430abeec8d67693f9cf4e039c
|
||||||
RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7
|
RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7
|
||||||
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
|
RNSVG: 42a0c731b11179ebbd27a3eeeafa7201ebb476ff
|
||||||
Yoga: 44c64131616253fa83366295acdbce3d14926041
|
Yoga: ff994563b2fd98c982ca58e8cd9db2cdaf4dda74
|
||||||
|
|
||||||
PODFILE CHECKSUM: b77befb1871220c1a94408eeae0857d78b685698
|
PODFILE CHECKSUM: b77befb1871220c1a94408eeae0857d78b685698
|
||||||
|
|
||||||
|
|
|
@ -3,36 +3,38 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 46;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
08C620EC6F30A0663310BBC1 /* libPods-Spacedrive.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 080FB394AD883D9705C115A6 /* libPods-Spacedrive.a */; };
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||||
519D1250147D911454D7DB76 /* libPods-Spacedrive.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F276D840CDBF9D0D9D548D /* libPods-Spacedrive.a */; };
|
5574975428A2496C00851D5A /* SDCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 5574975328A2496C00851D5A /* SDCore.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||||
C95AE27BB525EFF3F02CEC11 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56E71A6EFA9EA8F4C11F42FA /* ExpoModulesProvider.swift */; };
|
C95AE27BB525EFF3F02CEC11 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56E71A6EFA9EA8F4C11F42FA /* ExpoModulesProvider.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||||
|
080FB394AD883D9705C115A6 /* libPods-Spacedrive.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Spacedrive.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07F961A680F5B00A75B9A /* Spacedrive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Spacedrive.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
13B07F961A680F5B00A75B9A /* Spacedrive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Spacedrive.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = "<group>"; };
|
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = "<group>"; };
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
|
5574975328A2496C00851D5A /* SDCore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDCore.m; sourceTree = "<group>"; };
|
||||||
|
5574975528A2498000851D5A /* SDCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDCore.h; sourceTree = "<group>"; };
|
||||||
|
5574975628A24E0D00851D5A /* sdcore-universal-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "sdcore-universal-ios.a"; path = "../../../target/sdcore-universal-ios.a"; sourceTree = "<group>"; };
|
||||||
56E71A6EFA9EA8F4C11F42FA /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Spacedrive/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
56E71A6EFA9EA8F4C11F42FA /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Spacedrive/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
|
||||||
6C2E3173556A471DD304B334 /* Pods-mobilenew.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobilenew.debug.xcconfig"; path = "Target Support Files/Pods-mobilenew/Pods-mobilenew.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
78E58D73F5113B1BD543EE4D /* Pods-Spacedrive.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Spacedrive.debug.xcconfig"; path = "Target Support Files/Pods-Spacedrive/Pods-Spacedrive.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
7A4D352CD337FB3A3BF06240 /* Pods-mobilenew.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mobilenew.release.xcconfig"; path = "Target Support Files/Pods-mobilenew/Pods-mobilenew.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SplashScreen.storyboard; sourceTree = "<group>"; };
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||||
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Expo.plist; path = Supporting/Expo.plist; sourceTree = "<group>"; };
|
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Expo.plist; path = Supporting/Expo.plist; sourceTree = "<group>"; };
|
||||||
D8F0094C07EEE7528760BD08 /* Pods-Spacedrive.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Spacedrive.release.xcconfig"; path = "Target Support Files/Pods-Spacedrive/Pods-Spacedrive.release.xcconfig"; sourceTree = "<group>"; };
|
CD5534017C1F13AB6E57EC53 /* Pods-Spacedrive.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Spacedrive.debug.xcconfig"; path = "Target Support Files/Pods-Spacedrive/Pods-Spacedrive.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
E661E5E8069E06E621509713 /* Pods-Spacedrive.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Spacedrive.release.xcconfig"; path = "Target Support Files/Pods-Spacedrive/Pods-Spacedrive.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
F3F276D840CDBF9D0D9D548D /* libPods-Spacedrive.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Spacedrive.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -40,7 +42,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
519D1250147D911454D7DB76 /* libPods-Spacedrive.a in Frameworks */,
|
08C620EC6F30A0663310BBC1 /* libPods-Spacedrive.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +60,8 @@
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
13B07FB71A68108700A75B9A /* main.m */,
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
|
||||||
|
5574975328A2496C00851D5A /* SDCore.m */,
|
||||||
|
5574975528A2498000851D5A /* SDCore.h */,
|
||||||
);
|
);
|
||||||
path = Spacedrive;
|
path = Spacedrive;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -73,8 +77,9 @@
|
||||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
5574975628A24E0D00851D5A /* sdcore-universal-ios.a */,
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
F3F276D840CDBF9D0D9D548D /* libPods-Spacedrive.a */,
|
080FB394AD883D9705C115A6 /* libPods-Spacedrive.a */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -120,10 +125,8 @@
|
||||||
D65327D7A22EEC0BE12398D9 /* Pods */ = {
|
D65327D7A22EEC0BE12398D9 /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
6C2E3173556A471DD304B334 /* Pods-mobilenew.debug.xcconfig */,
|
CD5534017C1F13AB6E57EC53 /* Pods-Spacedrive.debug.xcconfig */,
|
||||||
7A4D352CD337FB3A3BF06240 /* Pods-mobilenew.release.xcconfig */,
|
E661E5E8069E06E621509713 /* Pods-Spacedrive.release.xcconfig */,
|
||||||
78E58D73F5113B1BD543EE4D /* Pods-Spacedrive.debug.xcconfig */,
|
|
||||||
D8F0094C07EEE7528760BD08 /* Pods-Spacedrive.release.xcconfig */,
|
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -143,14 +146,15 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Spacedrive" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Spacedrive" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
|
9F553C6F8AA059AB72DAA720 /* [CP] Check Pods Manifest.lock */,
|
||||||
FD10A7F022414F080027D42C /* Start Packager */,
|
FD10A7F022414F080027D42C /* Start Packager */,
|
||||||
|
55B1130D28AB3061006C377F /* Build Spacedrive Core */,
|
||||||
13B07F871A680F5B00A75B9A /* Sources */,
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
|
C93832A891603A9ED877B5D2 /* [CP] Embed Pods Frameworks */,
|
||||||
0D580678BEFB3E7EF09A2CFE /* [CP] Embed Pods Frameworks */,
|
20C3591E751EF7109AA55859 /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -221,7 +225,50 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "export NODE_BINARY=node\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\n`node --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n";
|
shellScript = "export NODE_BINARY=node\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\n`node --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n";
|
||||||
};
|
};
|
||||||
08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = {
|
20C3591E751EF7109AA55859 /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-resources.sh",
|
||||||
|
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
||||||
|
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputPaths = (
|
||||||
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
||||||
|
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
55B1130D28AB3061006C377F /* Build Spacedrive Core */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
alwaysOutOfDate = 1;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"../../../core/src/*.rs",
|
||||||
|
"../rust/src/*.rs",
|
||||||
|
"../../../core/src/*/*.rs",
|
||||||
|
);
|
||||||
|
name = "Build Spacedrive Core";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"../../../target/sdcore-universal-ios.a",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/zsh;
|
||||||
|
shellScript = "set -e\n\nif [[ -n \"${DEVELOPER_SDK_DIR:-}\" ]]; then\n # Assume we're in Xcode, which means we're probably cross-compiling.\n # In this case, we need to add an extra library search path for build scripts and proc-macros,\n # which run on the host instead of the target.\n # (macOS Big Sur does not have linkable libraries in /usr/lib/.)\n export LIBRARY_PATH=\"${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}\"\nfi\n\nCARGO_FLAGS=\nif [[ \"$BUILDVARIANT\" != \"debug\" ]]; then\n CARGO_FLAGS=--release\nfi\n\nTARGET_DIRECTORY=../../../target\nif [[ $PLATFORM_NAME = \"iphonesimulator\" ]]\nthen\n cargo build -p sdcore-lib $CARGO_FLAGS --lib --target aarch64-apple-ios-sim\n lipo -create -output $TARGET_DIRECTORY/libsdcore-iossim.a $TARGET_DIRECTORY/aarch64-apple-ios-sim/release/libsdcore.a\nelse\n cargo build -p sdcore-lib $CARGO_FLAGS --lib --target aarch64-apple-ios\n lipo -create -output $TARGET_DIRECTORY/libsdcore-ios.a $TARGET_DIRECTORY/aarch64-apple-ios/release/libsdcore.a\nfi\n";
|
||||||
|
};
|
||||||
|
9F553C6F8AA059AB72DAA720 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -243,7 +290,7 @@
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
0D580678BEFB3E7EF09A2CFE /* [CP] Embed Pods Frameworks */ = {
|
C93832A891603A9ED877B5D2 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -261,26 +308,6 @@
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-frameworks.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-resources.sh",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
|
||||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
|
||||||
);
|
|
||||||
name = "[CP] Copy Pods Resources";
|
|
||||||
outputPaths = (
|
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
|
||||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Spacedrive/Pods-Spacedrive-resources.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -310,6 +337,7 @@
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||||
C95AE27BB525EFF3F02CEC11 /* ExpoModulesProvider.swift in Sources */,
|
C95AE27BB525EFF3F02CEC11 /* ExpoModulesProvider.swift in Sources */,
|
||||||
|
5574975428A2496C00851D5A /* SDCore.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -318,7 +346,7 @@
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 78E58D73F5113B1BD543EE4D /* Pods-Spacedrive.debug.xcconfig */;
|
baseConfigurationReference = CD5534017C1F13AB6E57EC53 /* Pods-Spacedrive.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
@ -333,12 +361,73 @@
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Spacedrive/Info.plist;
|
INFOPLIST_FILE = Spacedrive/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"\"${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXFont\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/Expo\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoKeepAwake\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNCMaskedView\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNScreens\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Codegen\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Core\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-bridging\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsi\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-logger\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-perflogger\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/Yoga\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/fmt\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/glog\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/libevent\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-safe-area-context\"",
|
||||||
|
/usr/lib/swift,
|
||||||
|
../../../target,
|
||||||
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-ObjC",
|
||||||
|
"-lc++",
|
||||||
|
"-lsdcore-ios",
|
||||||
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-ObjC",
|
||||||
|
"-lc++",
|
||||||
|
"-lsdcore-iossim",
|
||||||
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.spacedrive.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.spacedrive.app;
|
||||||
PRODUCT_NAME = Spacedrive;
|
PRODUCT_NAME = Spacedrive;
|
||||||
|
@ -351,7 +440,7 @@
|
||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = D8F0094C07EEE7528760BD08 /* Pods-Spacedrive.release.xcconfig */;
|
baseConfigurationReference = E661E5E8069E06E621509713 /* Pods-Spacedrive.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
@ -361,12 +450,73 @@
|
||||||
DEVELOPMENT_TEAM = 72SE38W7T9;
|
DEVELOPMENT_TEAM = 72SE38W7T9;
|
||||||
INFOPLIST_FILE = Spacedrive/Info.plist;
|
INFOPLIST_FILE = Spacedrive/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"\"${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/EXFont\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/Expo\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoKeepAwake\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RCTTypeSafety\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNCMaskedView\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNGestureHandler\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNReanimated\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/RNScreens\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Codegen\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Core\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-CoreModules\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTAnimation\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTBlob\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTImage\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTLinking\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTNetwork\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTSettings\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTText\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTVibration\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-bridging\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsi\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsiexecutor\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-jsinspector\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-logger\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-perflogger\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/Yoga\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/fmt\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/glog\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/libevent\"",
|
||||||
|
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-safe-area-context\"",
|
||||||
|
/usr/lib/swift,
|
||||||
|
../../../target,
|
||||||
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-ObjC",
|
||||||
|
"-lc++",
|
||||||
|
"-lsdcore-ios",
|
||||||
|
);
|
||||||
|
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||||
|
"$(inherited)",
|
||||||
|
"-ObjC",
|
||||||
|
"-lc++",
|
||||||
|
"-lsdcore-iossim",
|
||||||
|
);
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.spacedrive.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.spacedrive.app;
|
||||||
PRODUCT_NAME = Spacedrive;
|
PRODUCT_NAME = Spacedrive;
|
||||||
|
@ -425,7 +575,10 @@
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
/usr/lib/swift,
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
@ -476,7 +629,10 @@
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
/usr/lib/swift,
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
LIBRARY_SEARCH_PATHS = "\"$(inherited)\"";
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||||
|
|
|
@ -1,77 +1,81 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>UIBackgroundModes</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<array>
|
||||||
<key>CFBundleDisplayName</key>
|
<string>remote-notification</string>
|
||||||
<string>Spacedrive</string>
|
</array>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
<string>Spacedrive</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>6.0</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>$(PRODUCT_NAME)</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleName</key>
|
||||||
<string>0.0.1</string>
|
<string>$(PRODUCT_NAME)</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>????</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<array>
|
<string>0.0.1</string>
|
||||||
<dict>
|
<key>CFBundleSignature</key>
|
||||||
<key>CFBundleURLSchemes</key>
|
<string>????</string>
|
||||||
<array>
|
<key>CFBundleURLTypes</key>
|
||||||
<string>spacedrive</string>
|
<array>
|
||||||
<string>com.spacedrive.app</string>
|
<dict>
|
||||||
</array>
|
<key>CFBundleURLSchemes</key>
|
||||||
</dict>
|
<array>
|
||||||
</array>
|
<string>spacedrive</string>
|
||||||
<key>CFBundleVersion</key>
|
<string>com.spacedrive.app</string>
|
||||||
<string>1</string>
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
</dict>
|
||||||
<true/>
|
</array>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>CFBundleVersion</key>
|
||||||
<dict>
|
<string>1</string>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSExceptionDomains</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>localhost</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<dict>
|
<true/>
|
||||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
<key>NSExceptionDomains</key>
|
||||||
<true/>
|
<dict>
|
||||||
</dict>
|
<key>localhost</key>
|
||||||
</dict>
|
<dict>
|
||||||
</dict>
|
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||||
<key>UILaunchStoryboardName</key>
|
<true/>
|
||||||
<string>SplashScreen</string>
|
</dict>
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
</dict>
|
||||||
<array>
|
</dict>
|
||||||
<string>armv7</string>
|
<key>UILaunchStoryboardName</key>
|
||||||
</array>
|
<string>SplashScreen</string>
|
||||||
<key>UIRequiresFullScreen</key>
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
<false/>
|
<array>
|
||||||
<key>UIStatusBarStyle</key>
|
<string>armv7</string>
|
||||||
<string>UIStatusBarStyleDefault</string>
|
</array>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UIRequiresFullScreen</key>
|
||||||
<array>
|
<false/>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<key>UIStatusBarStyle</key>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
<string>UIStatusBarStyleDefault</string>
|
||||||
</array>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<array>
|
||||||
<array>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
</array>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<array>
|
||||||
</array>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<key>UIUserInterfaceStyle</key>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
<string>Automatic</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<false/>
|
</array>
|
||||||
</dict>
|
<key>UIUserInterfaceStyle</key>
|
||||||
</plist>
|
<string>Automatic</string>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
|
17
apps/mobile/ios/Spacedrive/SDCore.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//
|
||||||
|
// SDCore.h
|
||||||
|
// Spacedrive
|
||||||
|
//
|
||||||
|
// Created by Oscar Beaumont on 9/8/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
#import <React/RCTEventEmitter.h>
|
||||||
|
|
||||||
|
#ifndef SDCore_h
|
||||||
|
#define SDCore_h
|
||||||
|
|
||||||
|
@interface SDCore : RCTEventEmitter <RCTBridgeModule>
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* SDCore_h */
|
81
apps/mobile/ios/Spacedrive/SDCore.m
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
//
|
||||||
|
// SDCore.m
|
||||||
|
// Spacedrive
|
||||||
|
//
|
||||||
|
// This file will not work unless ARC is disabled. Do this by setting the compiler flag '-fno-objc-arc' on this file in Settings > Build Phases > Compile Sources.
|
||||||
|
// This file also expects the Spacedrive Rust library to be linked in Settings > Build Phases > Link Binary with Libraries. This is the crude way, you should link the core with custom linker flags so that you can do it conditonally based on target OS.
|
||||||
|
// This file also expects a Build Phase to be setup which compiles the Rust prior to linking the sdcore library to the IOS build.
|
||||||
|
// This file also expects you to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist
|
||||||
|
//
|
||||||
|
// Created by Oscar Beaumont on 9/8/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "SDCore.h"
|
||||||
|
#import <React/RCTLog.h>
|
||||||
|
|
||||||
|
// is a function defined in Rust which starts a listener for Rust events.
|
||||||
|
void register_core_event_listener(id objc_class);
|
||||||
|
|
||||||
|
// is a function defined in Rust which is responsible for handling messages from the frontend.
|
||||||
|
void sd_core_msg(const char* query, void* resolve);
|
||||||
|
|
||||||
|
// is called by Rust to determine the base directory to store data in. This is only done when initialising the Node.
|
||||||
|
const char* get_data_directory(void)
|
||||||
|
{
|
||||||
|
NSArray *dirPaths = dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
|
||||||
|
NSUserDomainMask, YES);
|
||||||
|
const char *docDir = [ [dirPaths objectAtIndex:0] UTF8String];
|
||||||
|
return docDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is called by Rust with a void* to the resolve function (of type RCTPromiseResolveBlock) to call it.
|
||||||
|
// Due to 'RCTPromiseResolveBlock' being an Objective-C block it is hard to call from Rust.
|
||||||
|
void call_resolve(void *resolvePtr, const char* resultRaw)
|
||||||
|
{
|
||||||
|
RCTPromiseResolveBlock resolve = (__bridge RCTPromiseResolveBlock) resolvePtr;
|
||||||
|
NSString *result = [NSString stringWithUTF8String:resultRaw];
|
||||||
|
resolve(result);
|
||||||
|
[result release];
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation SDCore
|
||||||
|
{
|
||||||
|
bool registeredWithRust;
|
||||||
|
bool hasListeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)startObserving {
|
||||||
|
if (!registeredWithRust)
|
||||||
|
{
|
||||||
|
register_core_event_listener(self);
|
||||||
|
registeredWithRust = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasListeners = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)stopObserving {
|
||||||
|
hasListeners = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendCoreEvent: (NSString*)query {
|
||||||
|
if (hasListeners) {
|
||||||
|
[self sendEventWithName:@"SDCoreEvent" body:query];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<NSString *> *)supportedEvents {
|
||||||
|
return @[@"SDCoreEvent"];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE();
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(sd_core_msg: (NSString *)queryRaw
|
||||||
|
resolver:(RCTPromiseResolveBlock)resolve
|
||||||
|
rejecter:(RCTPromiseRejectBlock)reject)
|
||||||
|
{
|
||||||
|
const char *query = [queryRaw UTF8String];
|
||||||
|
sd_core_msg(query, (__bridge void*) [resolve retain]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -3,7 +3,6 @@ const MetroSymlinksResolver = require('@rnx-kit/metro-resolver-symlinks');
|
||||||
|
|
||||||
// Might not need these anymore.
|
// Might not need these anymore.
|
||||||
const [SDAssetsPath, SDAssetsPathExclude] = resolveUniqueModule('@sd/assets', '.');
|
const [SDAssetsPath, SDAssetsPathExclude] = resolveUniqueModule('@sd/assets', '.');
|
||||||
const [SDCorePath, SDCorePathExclude] = resolveUniqueModule('@sd/core', '.');
|
|
||||||
const [babelRuntimePath, babelRuntimeExclude] = resolveUniqueModule('@babel/runtime');
|
const [babelRuntimePath, babelRuntimeExclude] = resolveUniqueModule('@babel/runtime');
|
||||||
const [reactPath, reactExclude] = resolveUniqueModule('react');
|
const [reactPath, reactExclude] = resolveUniqueModule('react');
|
||||||
|
|
||||||
|
@ -21,7 +20,6 @@ const metroConfig = makeMetroConfig({
|
||||||
extraNodeModules: {
|
extraNodeModules: {
|
||||||
'@babel/runtime': babelRuntimePath,
|
'@babel/runtime': babelRuntimePath,
|
||||||
'@sd/assets': SDAssetsPath,
|
'@sd/assets': SDAssetsPath,
|
||||||
'@sd/core': SDCorePath,
|
|
||||||
'react': reactPath,
|
'react': reactPath,
|
||||||
'react-native-svg': reactSVGPath
|
'react-native-svg': reactSVGPath
|
||||||
},
|
},
|
||||||
|
@ -29,7 +27,6 @@ const metroConfig = makeMetroConfig({
|
||||||
blockList: exclusionList([
|
blockList: exclusionList([
|
||||||
babelRuntimeExclude,
|
babelRuntimeExclude,
|
||||||
SDAssetsPathExclude,
|
SDAssetsPathExclude,
|
||||||
SDCorePathExclude,
|
|
||||||
reactExclude,
|
reactExclude,
|
||||||
reactSVGExclude
|
reactSVGExclude
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "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",
|
||||||
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit"
|
"lint": "eslint src/**/*.{ts,tsx} && tsc --noEmit"
|
||||||
|
@ -12,42 +12,45 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^13.0.0",
|
"@expo/vector-icons": "^13.0.0",
|
||||||
"@gorhom/bottom-sheet": "^4.4.3",
|
"@gorhom/bottom-sheet": "^4.4.3",
|
||||||
"@react-native-async-storage/async-storage": "^1.17.7",
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
||||||
"@react-navigation/bottom-tabs": "^6.3.2",
|
"@react-native-masked-view/masked-view": "0.2.7",
|
||||||
"@react-navigation/drawer": "^6.4.3",
|
"@react-navigation/bottom-tabs": "^6.3.3",
|
||||||
"@react-navigation/native": "^6.0.11",
|
"@react-navigation/drawer": "^6.4.4",
|
||||||
"@react-navigation/native-stack": "^6.7.0",
|
"@react-navigation/native": "^6.0.12",
|
||||||
|
"@react-navigation/stack": "^6.2.3",
|
||||||
|
"@rspc/client": "^0.0.5",
|
||||||
"@sd/assets": "file:../../packages/assets",
|
"@sd/assets": "file:../../packages/assets",
|
||||||
"@sd/core": "file:../../core",
|
"@tanstack/react-query": "^4.2.3",
|
||||||
"byte-size": "^8.1.0",
|
"byte-size": "^8.1.0",
|
||||||
"class-variance-authority": "^0.2.3",
|
"class-variance-authority": "^0.2.3",
|
||||||
"expo": "~46.0.2",
|
"date-fns": "^2.29.2",
|
||||||
"expo-font": "^10.2.0",
|
"expo": "~46.0.9",
|
||||||
"expo-linking": "^3.2.2",
|
"expo-font": "~10.2.0",
|
||||||
"expo-splash-screen": "~0.16.1",
|
"expo-linking": "~3.2.2",
|
||||||
|
"expo-splash-screen": "~0.16.2",
|
||||||
"expo-status-bar": "~1.4.0",
|
"expo-status-bar": "~1.4.0",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"moti": "^0.18.0",
|
"moti": "^0.18.0",
|
||||||
"phosphor-react-native": "^1.1.2",
|
"phosphor-react-native": "^1.1.2",
|
||||||
"react": "18.2.0",
|
"react": "18.0.0",
|
||||||
"react-native": "0.69.3",
|
"react-native": "0.69.4",
|
||||||
"react-native-gesture-handler": "^2.5.0",
|
"react-native-gesture-handler": "~2.5.0",
|
||||||
"react-native-heroicons": "^2.2.0",
|
"react-native-heroicons": "^2.2.0",
|
||||||
"react-native-reanimated": "^2.9.1",
|
"react-native-reanimated": "~2.9.1",
|
||||||
"react-native-safe-area-context": "^4.3.1",
|
"react-native-safe-area-context": "4.3.1",
|
||||||
"react-native-screens": "^3.15.0",
|
"react-native-screens": "~3.15.0",
|
||||||
"react-native-svg": "^12.3.0",
|
"react-native-svg": "13.0.0",
|
||||||
"twrnc": "^3.4.0",
|
"twrnc": "^3.4.0",
|
||||||
"use-count-up": "^3.0.1",
|
"use-count-up": "^3.0.1",
|
||||||
"zustand": "^4.0.0"
|
"zustand": "^4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.9",
|
"@babel/core": "^7.18.6",
|
||||||
"@babel/runtime": "^7.18.9",
|
"@babel/runtime": "^7.18.9",
|
||||||
"@rnx-kit/metro-config": "^1.2.36",
|
"@rnx-kit/metro-config": "^1.2.36",
|
||||||
"@rnx-kit/metro-resolver-symlinks": "^0.1.21",
|
"@rnx-kit/metro-resolver-symlinks": "^0.1.21",
|
||||||
"@types/react": "~18.0.15",
|
"@types/react": "~18.0.0",
|
||||||
"@types/react-native": "~0.69.5",
|
"@types/react-native": "~0.69.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
||||||
"@typescript-eslint/parser": "^5.30.7",
|
"@typescript-eslint/parser": "^5.30.7",
|
||||||
"eslint": "^8.21.0",
|
"eslint": "^8.21.0",
|
||||||
|
@ -55,8 +58,7 @@
|
||||||
"eslint-plugin-react": "^7.30.1",
|
"eslint-plugin-react": "^7.30.1",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-react-native": "^4.0.0",
|
"eslint-plugin-react-native": "^4.0.0",
|
||||||
"metro-minify-terser": "^0.72.0",
|
"metro-minify-terser": "^0.72.1",
|
||||||
"react-native-svg": "^12.4.3",
|
|
||||||
"react-native-svg-transformer": "^1.0.0",
|
"react-native-svg-transformer": "^1.0.0",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
},
|
},
|
||||||
|
|
27
apps/mobile/rust/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
[package]
|
||||||
|
name = "sdcore-lib"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.63.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "sdcore"
|
||||||
|
crate-type = ["staticlib", "cdylib"] # staticlib for IOS and cdylib for Android
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
once_cell = "1.13.0"
|
||||||
|
sdcore = { path = "../../../core", features = ["mobile", "p2p"], default-features = false }
|
||||||
|
rspc = { version = "0.0.4", features = [] }
|
||||||
|
serde_json = "1.0.83"
|
||||||
|
tokio = "1.20.1"
|
||||||
|
openssl = { version = "0.10.41", features = ["vendored"] } # Override features of transitive dependencies
|
||||||
|
openssl-sys = { version = "0.9.75", features = ["vendored"] } # Override features of transitive dependencies to support IOS Simulator on M1
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "ios")'.dependencies]
|
||||||
|
objc = "0.2.7"
|
||||||
|
objc_id = "0.1.1"
|
||||||
|
objc-foundation = "0.1.1"
|
||||||
|
|
||||||
|
# This is `not(ios)` instead of `android` because of https://github.com/mozilla/rust-android-gradle/issues/93
|
||||||
|
[target.'cfg(not(target_os = "ios"))'.dependencies]
|
||||||
|
jni = "0.19.0"
|
111
apps/mobile/rust/src/android.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
use crate::{CLIENT_CONTEXT, EVENT_SENDER, NODE, RUNTIME};
|
||||||
|
use jni::objects::{JClass, JObject, JString};
|
||||||
|
use jni::JNIEnv;
|
||||||
|
use rspc::Request;
|
||||||
|
use sdcore::Node;
|
||||||
|
use tokio::sync::mpsc::unbounded_channel;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_com_spacedrive_app_SDCore_registerCoreEventListener(
|
||||||
|
env: JNIEnv,
|
||||||
|
class: JClass,
|
||||||
|
) {
|
||||||
|
let jvm = env.get_java_vm().unwrap();
|
||||||
|
let class = env.new_global_ref(class).unwrap();
|
||||||
|
let (tx, mut rx) = unbounded_channel();
|
||||||
|
let _ = EVENT_SENDER.set(tx);
|
||||||
|
|
||||||
|
RUNTIME.spawn(async move {
|
||||||
|
while let Some(event) = rx.recv().await {
|
||||||
|
let data = match serde_json::to_string(&event) {
|
||||||
|
Ok(json) => json,
|
||||||
|
Err(err) => {
|
||||||
|
println!("Failed to serialize event: {}", err);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let env = jvm.attach_current_thread().unwrap();
|
||||||
|
env.call_method(
|
||||||
|
&class,
|
||||||
|
"sendCoreEvent",
|
||||||
|
"(Ljava/lang/String;)V",
|
||||||
|
&[env
|
||||||
|
.new_string(data)
|
||||||
|
.expect("Couldn't create java string!")
|
||||||
|
.into()],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "system" fn Java_com_spacedrive_app_SDCore_handleCoreMsg(
|
||||||
|
env: JNIEnv,
|
||||||
|
class: JClass,
|
||||||
|
query: JString,
|
||||||
|
callback: JObject,
|
||||||
|
) {
|
||||||
|
let jvm = env.get_java_vm().unwrap();
|
||||||
|
let query: String = env
|
||||||
|
.get_string(query)
|
||||||
|
.expect("Couldn't get java string!")
|
||||||
|
.into();
|
||||||
|
let class = env.new_global_ref(class).unwrap();
|
||||||
|
let callback = env.new_global_ref(callback).unwrap();
|
||||||
|
|
||||||
|
RUNTIME.spawn(async move {
|
||||||
|
let request: Request = serde_json::from_str(&query).unwrap();
|
||||||
|
|
||||||
|
let node = &mut *NODE.lock().await;
|
||||||
|
let (node, router) = match node {
|
||||||
|
Some(node) => node.clone(),
|
||||||
|
None => {
|
||||||
|
let data_dir: String = {
|
||||||
|
let env = jvm.attach_current_thread().unwrap();
|
||||||
|
let data_dir = env
|
||||||
|
.call_method(
|
||||||
|
&class,
|
||||||
|
"getDataDirectory",
|
||||||
|
"()Ljava/lang/String;",
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.l()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
env.get_string(data_dir.into()).unwrap().into()
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_node = Node::new(data_dir).await;
|
||||||
|
node.replace(new_node.clone());
|
||||||
|
new_node
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let resp = serde_json::to_string(
|
||||||
|
&request
|
||||||
|
.handle(
|
||||||
|
node.get_request_context(),
|
||||||
|
&router,
|
||||||
|
&CLIENT_CONTEXT,
|
||||||
|
EVENT_SENDER.get(),
|
||||||
|
)
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let env = jvm.attach_current_thread().unwrap();
|
||||||
|
env.call_method(
|
||||||
|
&callback,
|
||||||
|
"resolve",
|
||||||
|
"(Ljava/lang/Object;)V",
|
||||||
|
&[env
|
||||||
|
.new_string(resp)
|
||||||
|
.expect("Couldn't create java string!")
|
||||||
|
.into()],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
96
apps/mobile/rust/src/ios.rs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
use crate::{CLIENT_CONTEXT, EVENT_SENDER, NODE, RUNTIME};
|
||||||
|
use std::{
|
||||||
|
ffi::{CStr, CString},
|
||||||
|
os::raw::{c_char, c_void},
|
||||||
|
};
|
||||||
|
use tokio::sync::mpsc::unbounded_channel;
|
||||||
|
|
||||||
|
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
||||||
|
use objc_foundation::{INSString, NSString};
|
||||||
|
use objc_id::Id;
|
||||||
|
use rspc::Request;
|
||||||
|
use sdcore::Node;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn get_data_directory() -> *const c_char;
|
||||||
|
fn call_resolve(resolve: *const c_void, result: *const c_char);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This struct wraps the function pointer which represent a Javascript Promise. We wrap the
|
||||||
|
// function pointers in a struct so we can unsafely assert to Rust that they are `Send`.
|
||||||
|
// We know they are send as we have ensured Objective-C won't deallocate the function pointer
|
||||||
|
// until `call_resolve` is called.
|
||||||
|
struct RNPromise(*const c_void);
|
||||||
|
|
||||||
|
unsafe impl Send for RNPromise {}
|
||||||
|
|
||||||
|
impl RNPromise {
|
||||||
|
// resolve the promise
|
||||||
|
unsafe fn resolve(self, result: CString) {
|
||||||
|
call_resolve(self.0, result.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn register_core_event_listener(id: *mut Object) {
|
||||||
|
let id = Id::<Object>::from_ptr(id);
|
||||||
|
|
||||||
|
let (tx, mut rx) = unbounded_channel();
|
||||||
|
let _ = EVENT_SENDER.set(tx);
|
||||||
|
|
||||||
|
RUNTIME.spawn(async move {
|
||||||
|
while let Some(event) = rx.recv().await {
|
||||||
|
let data = match serde_json::to_string(&event) {
|
||||||
|
Ok(json) => json,
|
||||||
|
Err(err) => {
|
||||||
|
println!("Failed to serialize event: {}", err);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let data = NSString::from_str(&data);
|
||||||
|
let _: () = msg_send![id, sendCoreEvent: data];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn sd_core_msg(query: *const c_char, resolve: *const c_void) {
|
||||||
|
// This string is cloned to the Rust heap. This is important as Objective-C may remove the query once this function completions but prior to the async block finishing.
|
||||||
|
let query = CStr::from_ptr(query).to_str().unwrap().to_string();
|
||||||
|
|
||||||
|
let resolve = RNPromise(resolve);
|
||||||
|
RUNTIME.spawn(async move {
|
||||||
|
let request: Request = serde_json::from_str(&query).unwrap();
|
||||||
|
|
||||||
|
let node = &mut *NODE.lock().await;
|
||||||
|
let (node, router) = match node {
|
||||||
|
Some(node) => node.clone(),
|
||||||
|
None => {
|
||||||
|
let doc_dir = CStr::from_ptr(get_data_directory())
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
let new_node = Node::new(doc_dir).await;
|
||||||
|
node.replace(new_node.clone());
|
||||||
|
new_node
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
resolve.resolve(
|
||||||
|
CString::new(
|
||||||
|
serde_json::to_vec(
|
||||||
|
&request
|
||||||
|
.handle(
|
||||||
|
node.get_request_context(),
|
||||||
|
&router,
|
||||||
|
&CLIENT_CONTEXT,
|
||||||
|
EVENT_SENDER.get(),
|
||||||
|
)
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
31
apps/mobile/rust/src/lib.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use once_cell::sync::{Lazy, OnceCell};
|
||||||
|
use rspc::{ClientContext, Response};
|
||||||
|
use sdcore::{api::Router, Node};
|
||||||
|
use tokio::{
|
||||||
|
runtime::Runtime,
|
||||||
|
sync::{mpsc::UnboundedSender, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) static RUNTIME: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) static NODE: Lazy<Mutex<Option<(Arc<Node>, Arc<Router>)>>> =
|
||||||
|
Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) static CLIENT_CONTEXT: Lazy<ClientContext> = Lazy::new(|| ClientContext {
|
||||||
|
subscriptions: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) static EVENT_SENDER: OnceCell<UnboundedSender<Response>> = OnceCell::new();
|
||||||
|
|
||||||
|
#[cfg(target_os = "ios")]
|
||||||
|
mod ios;
|
||||||
|
|
||||||
|
/// This is `not(ios)` instead of `android` because of https://github.com/mozilla/rust-android-gradle/issues/93
|
||||||
|
#[cfg(not(target_os = "ios"))]
|
||||||
|
mod android;
|
|
@ -1,18 +1,26 @@
|
||||||
|
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
|
||||||
import { DefaultTheme, NavigationContainer, Theme } from '@react-navigation/native';
|
import { DefaultTheme, NavigationContainer, Theme } from '@react-navigation/native';
|
||||||
|
import { createClient } from '@rspc/client';
|
||||||
import { StatusBar } from 'expo-status-bar';
|
import { StatusBar } from 'expo-status-bar';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||||
import { useDeviceContext } from 'twrnc';
|
import { useDeviceContext } from 'twrnc';
|
||||||
|
|
||||||
|
import { GlobalModals } from './components/modals/GlobalModals';
|
||||||
|
import { ReactNativeTransport, queryClient, rspc, useInvalidateQuery } from './hooks/rspc';
|
||||||
import useCachedResources from './hooks/useCachedResources';
|
import useCachedResources from './hooks/useCachedResources';
|
||||||
import { getItemFromStorage } from './lib/storage';
|
import { getItemFromStorage } from './lib/storage';
|
||||||
import tw from './lib/tailwind';
|
import tw from './lib/tailwind';
|
||||||
import RootNavigator from './navigation';
|
import RootNavigator from './navigation';
|
||||||
import OnboardingNavigator from './navigation/OnboardingNavigator';
|
import OnboardingNavigator from './navigation/OnboardingNavigator';
|
||||||
import { useOnboardingStore } from './stores/useOnboardingStore';
|
import { useOnboardingStore } from './stores/useOnboardingStore';
|
||||||
|
import type { Operations } from './types/bindings';
|
||||||
|
|
||||||
|
const client = createClient<Operations>({
|
||||||
|
transport: new ReactNativeTransport()
|
||||||
|
});
|
||||||
|
|
||||||
//
|
|
||||||
const NavigatorTheme: Theme = {
|
const NavigatorTheme: Theme = {
|
||||||
...DefaultTheme,
|
...DefaultTheme,
|
||||||
colors: {
|
colors: {
|
||||||
|
@ -41,14 +49,27 @@ export default function App() {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider style={tw`flex-1 bg-black`}>
|
<rspc.Provider client={client} queryClient={queryClient}>
|
||||||
<GestureHandlerRootView style={tw`flex-1`}>
|
<>
|
||||||
<NavigationContainer theme={NavigatorTheme}>
|
<InvalidateQuery />
|
||||||
{showOnboarding ? <OnboardingNavigator /> : <RootNavigator />}
|
<SafeAreaProvider style={tw`flex-1 bg-black`}>
|
||||||
</NavigationContainer>
|
<GestureHandlerRootView style={tw`flex-1`}>
|
||||||
<StatusBar style="light" />
|
<BottomSheetModalProvider>
|
||||||
</GestureHandlerRootView>
|
<StatusBar style="light" />
|
||||||
</SafeAreaProvider>
|
<NavigationContainer theme={NavigatorTheme}>
|
||||||
|
{showOnboarding ? <OnboardingNavigator /> : <RootNavigator />}
|
||||||
|
</NavigationContainer>
|
||||||
|
<GlobalModals />
|
||||||
|
</BottomSheetModalProvider>
|
||||||
|
</GestureHandlerRootView>
|
||||||
|
</SafeAreaProvider>
|
||||||
|
</>
|
||||||
|
</rspc.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function InvalidateQuery() {
|
||||||
|
useInvalidateQuery();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_0_3)"/>
|
|
||||||
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_0_3)"/>
|
|
||||||
<path d="M0.582787 99.2818L140.005 100" stroke="white" stroke-opacity="0.03" stroke-width="2"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_0_3" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#E7E6E6"/>
|
|
||||||
<stop offset="1" stop-color="white"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear_0_3" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="white"/>
|
|
||||||
<stop offset="1" stop-color="#EAEAEA"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,16 +0,0 @@
|
||||||
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395V3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_13_627)"/>
|
|
||||||
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_13_627)"/>
|
|
||||||
<line x1="0.424076" y1="97.8758" x2="139.002" y2="98.1576" stroke="black" stroke-opacity="0.13" stroke-width="1.68485"/>
|
|
||||||
<line x1="0.582788" y1="99.2818" x2="140.005" y2="100" stroke="white" stroke-opacity="0.03" stroke-width="2"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_13_627" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#2D82E7"/>
|
|
||||||
<stop offset="1" stop-color="#083258"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear_13_627" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#319DCB"/>
|
|
||||||
<stop offset="1" stop-color="#264BA8"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 126 KiB |
14
apps/mobile/src/components/base/Divider.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { StyleProp, Text, View, ViewStyle } from 'react-native';
|
||||||
|
|
||||||
|
import tw from '../../lib/tailwind';
|
||||||
|
|
||||||
|
type DividerProps = {
|
||||||
|
style?: StyleProp<ViewStyle>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Divider = ({ style }: DividerProps) => {
|
||||||
|
return <View style={[tw`w-full my-1 h-[1px] bg-gray-550`, style]} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Divider;
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import { Pressable, Text, View } from 'react-native';
|
import { Pressable, Text, View } from 'react-native';
|
||||||
|
|
||||||
import tw from '../../lib/tailwind';
|
import tw from '../../lib/tailwind';
|
||||||
import FolderIcon from '../icons/Folder';
|
import FolderIcon from '../icons/FolderIcon';
|
||||||
|
|
||||||
interface BrowseLocationItemProps {
|
interface BrowseLocationItemProps {
|
||||||
folderName: string;
|
folderName: string;
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
import { FilePath } from '@sd/core';
|
|
||||||
import { Cloud, Desktop, DeviceMobileCamera, Laptop } from 'phosphor-react-native';
|
import { Cloud, Desktop, DeviceMobileCamera, Laptop } from 'phosphor-react-native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlatList, Text, View } from 'react-native';
|
import { FlatList, Text, View } from 'react-native';
|
||||||
import { LockClosedIcon } from 'react-native-heroicons/solid';
|
import { LockClosedIcon } from 'react-native-heroicons/solid';
|
||||||
|
|
||||||
import tw from '../../lib/tailwind';
|
import tw from '../../lib/tailwind';
|
||||||
|
import { FilePath } from '../../types/bindings';
|
||||||
import FileItem from '../file/FileItem';
|
import FileItem from '../file/FileItem';
|
||||||
|
|
||||||
export interface DeviceProps {
|
|
||||||
name: string;
|
|
||||||
size: string;
|
|
||||||
type: 'laptop' | 'desktop' | 'phone' | 'server';
|
|
||||||
locations: Array<{ name: string; folder?: boolean; format?: string; icon?: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const placeholderFileItems: FilePath[] = [
|
const placeholderFileItems: FilePath[] = [
|
||||||
{
|
{
|
||||||
is_dir: true,
|
is_dir: true,
|
||||||
|
@ -272,10 +265,18 @@ const placeholderFileItems: FilePath[] = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export interface DeviceProps {
|
||||||
|
name: string;
|
||||||
|
size: string;
|
||||||
|
type: 'laptop' | 'desktop' | 'phone' | 'server';
|
||||||
|
locations: { name: string; folder?: boolean; format?: string; icon?: string }[];
|
||||||
|
runningJob?: { amount: number; task: string };
|
||||||
|
}
|
||||||
|
|
||||||
const Device = ({ name, locations, size, type }: DeviceProps) => {
|
const Device = ({ name, locations, size, type }: DeviceProps) => {
|
||||||
return (
|
return (
|
||||||
<View style={tw`bg-gray-600 border rounded-md border-gray-550 my-2`}>
|
<View style={tw`bg-gray-600 border rounded-md border-gray-550 my-2`}>
|
||||||
<View style={tw`flex flex-row items-center px-4 pt-3 pb-2`}>
|
<View style={tw`flex flex-row items-center px-3.5 pt-3 pb-2`}>
|
||||||
<View style={tw`flex flex-row items-center`}>
|
<View style={tw`flex flex-row items-center`}>
|
||||||
{type === 'phone' && (
|
{type === 'phone' && (
|
||||||
<DeviceMobileCamera color="white" weight="fill" size={18} style={tw`mr-2`} />
|
<DeviceMobileCamera color="white" weight="fill" size={18} style={tw`mr-2`} />
|
||||||
|
@ -299,7 +300,7 @@ const Device = ({ name, locations, size, type }: DeviceProps) => {
|
||||||
renderItem={({ item }) => <FileItem file={item} />}
|
renderItem={({ item }) => <FileItem file={item} />}
|
||||||
keyExtractor={(item) => item.id.toString()}
|
keyExtractor={(item) => item.id.toString()}
|
||||||
horizontal
|
horizontal
|
||||||
contentContainerStyle={tw`mt-4 ml-2`}
|
contentContainerStyle={tw`mt-3 mb-5`}
|
||||||
showsHorizontalScrollIndicator={false}
|
showsHorizontalScrollIndicator={false}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -1,56 +1,110 @@
|
||||||
import { DrawerContentScrollView } from '@react-navigation/drawer';
|
import { DrawerContentScrollView } from '@react-navigation/drawer';
|
||||||
import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typescript/src/types';
|
import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typescript/src/types';
|
||||||
import { House } from 'phosphor-react-native';
|
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Pressable, Text, View } from 'react-native';
|
import { ColorValue, Platform, Pressable, Text, View } from 'react-native';
|
||||||
import { CogIcon } from 'react-native-heroicons/solid';
|
import { CogIcon } from 'react-native-heroicons/solid';
|
||||||
|
|
||||||
import Layout from '../../constants/Layout';
|
import Layout from '../../constants/Layout';
|
||||||
import tw from '../../lib/tailwind';
|
import tw from '../../lib/tailwind';
|
||||||
import type { DrawerNavParamList } from '../../navigation/DrawerNavigator';
|
import CollapsibleView from '../layout/CollapsibleView';
|
||||||
import { valueof } from '../../types/helper';
|
import DrawerLocationItem from './DrawerLocationItem';
|
||||||
import DrawerItem from './DrawerItem';
|
import DrawerLogo from './DrawerLogo';
|
||||||
|
import DrawerTagItem from './DrawerTagItem';
|
||||||
|
|
||||||
const drawerHeight = Layout.window.height * 0.85;
|
const placeholderLocationData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Spacedrive'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Content'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const placeholderTagsData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Funny',
|
||||||
|
color: tw.color('blue-500')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Twitch',
|
||||||
|
color: tw.color('purple-500')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'BlackMagic',
|
||||||
|
color: tw.color('red-500')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
// This is a hacky way to get the active route name and params but it works and it's typed...
|
const drawerHeight = Platform.select({
|
||||||
|
ios: Layout.window.height * 0.85,
|
||||||
|
android: Layout.window.height * 0.9
|
||||||
|
});
|
||||||
|
|
||||||
interface ActiveRoute {
|
const getActiveRouteState = function (state: any) {
|
||||||
key: string;
|
|
||||||
name: keyof DrawerNavParamList;
|
|
||||||
params: valueof<Omit<DrawerNavParamList, 'Home'>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getActiveRouteState = function (state: any): ActiveRoute {
|
|
||||||
if (!state.routes || state.routes.length === 0 || state.index >= state.routes.length) {
|
if (!state.routes || state.routes.length === 0 || state.index >= state.routes.length) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const childActiveRoute = state.routes[state.index];
|
const childActiveRoute = state.routes[state.index];
|
||||||
return getActiveRouteState(childActiveRoute);
|
return getActiveRouteState(childActiveRoute);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Overriding the default to add typing for our params.
|
const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => {
|
||||||
// interface DrawerContentComponentProps {
|
const stackName = getFocusedRouteNameFromRoute(getActiveRouteState(state)) ?? 'OverviewStack';
|
||||||
// state: DrawerNavigationState<DrawerNavParamList>;
|
|
||||||
// navigation: NavigationHelpers<DrawerNavParamList, DrawerNavigationEventMap> &
|
|
||||||
// DrawerActionHelpers<DrawerNavParamList>;
|
|
||||||
// // descriptors type is generic
|
|
||||||
// descriptors: DrawerDescriptorMap;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const DrawerContent = ({ descriptors, navigation, state }: DrawerContentComponentProps) => {
|
|
||||||
return (
|
return (
|
||||||
<DrawerContentScrollView style={tw`flex-1 p-4`} scrollEnabled={false}>
|
<DrawerContentScrollView style={tw`flex-1 px-4 py-2`} scrollEnabled={false}>
|
||||||
<View style={tw.style('justify-between', { height: drawerHeight })}>
|
<View style={tw.style('justify-between', { height: drawerHeight })}>
|
||||||
<View>
|
<View>
|
||||||
<Text style={tw`my-4 text-white`}>TODO: Library Selection</Text>
|
<DrawerLogo />
|
||||||
<DrawerItem
|
<Text style={tw`my-4 text-white text-xs`}>TODO: Library Selection</Text>
|
||||||
label={'Home'}
|
{/* Locations */}
|
||||||
icon={<House size={20} color={'white'} weight="bold" />}
|
<CollapsibleView
|
||||||
onPress={() => navigation.jumpTo('Home')}
|
title="Locations"
|
||||||
isSelected={getActiveRouteState(state).name === 'Home'}
|
titleStyle={tw`mt-4 mb-3 ml-1 text-sm font-semibold text-gray-300`}
|
||||||
/>
|
>
|
||||||
|
{placeholderLocationData.map((location) => (
|
||||||
|
<DrawerLocationItem
|
||||||
|
key={location.id}
|
||||||
|
folderName={location.name}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate(stackName, {
|
||||||
|
screen: 'Location',
|
||||||
|
params: { id: location.id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{/* Add Location */}
|
||||||
|
<View style={tw`border border-dashed rounded border-gray-450 border-opacity-60 mt-1`}>
|
||||||
|
<Text style={tw`text-xs font-bold text-center text-gray-400 px-2 py-2`}>
|
||||||
|
Add Location
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</CollapsibleView>
|
||||||
|
{/* Tags */}
|
||||||
|
<CollapsibleView
|
||||||
|
title="Tags"
|
||||||
|
titleStyle={tw`mt-6 mb-3 ml-1 text-sm font-semibold text-gray-300`}
|
||||||
|
>
|
||||||
|
{placeholderTagsData.map((tag) => (
|
||||||
|
<DrawerTagItem
|
||||||
|
key={tag.id}
|
||||||
|
tagName={tag.name}
|
||||||
|
onPress={() =>
|
||||||
|
navigation.navigate(stackName, {
|
||||||
|
screen: 'Tag',
|
||||||
|
params: { id: tag.id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
tagColor={tag.color as ColorValue}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</CollapsibleView>
|
||||||
</View>
|
</View>
|
||||||
{/* Settings */}
|
{/* Settings */}
|
||||||
<Pressable onPress={() => navigation.navigate('Settings')}>
|
<Pressable onPress={() => navigation.navigate('Settings')}>
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Pressable, Text, View } from 'react-native';
|
|
||||||
|
|
||||||
import tw from '../../lib/tailwind';
|
|
||||||
|
|
||||||
interface DrawerProps {
|
|
||||||
label: string;
|
|
||||||
onPress: () => void;
|
|
||||||
icon: JSX.Element;
|
|
||||||
isSelected: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DrawerItem: React.FC<DrawerProps> = (props) => {
|
|
||||||
const { label, icon, onPress, isSelected } = props;
|
|
||||||
return (
|
|
||||||
<Pressable onPress={onPress} style={tw``}>
|
|
||||||
<View
|
|
||||||
style={tw.style(
|
|
||||||
'flex mb-[4px] flex-row items-center py-2 px-2 rounded',
|
|
||||||
isSelected && 'bg-primary'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{icon}
|
|
||||||
<Text
|
|
||||||
style={tw.style('text-gray-300 text-sm font-medium ml-2', isSelected && 'text-white')}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</Pressable>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DrawerItem;
|
|
26
apps/mobile/src/components/drawer/DrawerLocationItem.tsx
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Pressable, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import tw from '../../lib/tailwind';
|
||||||
|
import FolderIcon from '../icons/FolderIcon';
|
||||||
|
|
||||||
|
interface DrawerLocationItemProps {
|
||||||
|
folderName: string;
|
||||||
|
onPress: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DrawerLocationItem: React.FC<DrawerLocationItemProps> = (props) => {
|
||||||
|
const { folderName, onPress } = props;
|
||||||
|
return (
|
||||||
|
<Pressable onPress={onPress}>
|
||||||
|
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-2 rounded')}>
|
||||||
|
<FolderIcon size={18} />
|
||||||
|
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
|
||||||
|
{folderName}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DrawerLocationItem;
|
19
apps/mobile/src/components/drawer/DrawerLogo.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Image, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import tw from '../../lib/tailwind';
|
||||||
|
import Divider from '../base/Divider';
|
||||||
|
|
||||||
|
const DrawerLogo = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View style={tw`flex flex-row items-center`}>
|
||||||
|
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-9 h-9`} />
|
||||||
|
<Text style={tw`text-base font-bold text-white ml-2`}>Spacedrive</Text>
|
||||||
|
</View>
|
||||||
|
<Divider style={tw`mt-4`} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DrawerLogo;
|
|
@ -1,31 +0,0 @@
|
||||||
import { useDrawerProgress } from '@react-navigation/drawer';
|
|
||||||
import React from 'react';
|
|
||||||
import Animated, { Extrapolate, interpolate, useAnimatedStyle } from 'react-native-reanimated';
|
|
||||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
||||||
|
|
||||||
import tw from '../../lib/tailwind';
|
|
||||||
|
|
||||||
// NOTE: Only wrap screens that need the drawer to be open. (Only Overview Screen for now.)
|
|
||||||
const DrawerScreenWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
||||||
const progress: any = useDrawerProgress();
|
|
||||||
|
|
||||||
const style = useAnimatedStyle(() => {
|
|
||||||
// TODO: Fix this, it looks weird. Especially on Android. translateX/Y might be the cause.
|
|
||||||
const scale = interpolate(progress.value, [0, 1], [1, 0.88], Extrapolate.CLAMP);
|
|
||||||
const translateX = interpolate(progress.value, [0, 1], [0, -12], Extrapolate.CLAMP);
|
|
||||||
const translateY = interpolate(progress.value, [0, 1], [0, 12], Extrapolate.CLAMP);
|
|
||||||
const borderRadius = interpolate(progress.value, [0, 1], [0, 16], Extrapolate.CLAMP);
|
|
||||||
return {
|
|
||||||
transform: [{ scale }, { translateX }, { translateY }],
|
|
||||||
borderRadius
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Animated.View style={[tw.style('flex-1 bg-[#121219]'), style]}>
|
|
||||||
<SafeAreaView edges={['top']}>{children}</SafeAreaView>
|
|
||||||
</Animated.View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DrawerScreenWrapper;
|
|
26
apps/mobile/src/components/drawer/DrawerTagItem.tsx
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ColorValue, Pressable, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import tw from '../../lib/tailwind';
|
||||||
|
|
||||||
|
type DrawerTagItemProps = {
|
||||||
|
tagName: string;
|
||||||
|
tagColor: ColorValue;
|
||||||
|
onPress: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DrawerTagItem: React.FC<DrawerTagItemProps> = (props) => {
|
||||||
|
const { tagName, tagColor, onPress } = props;
|
||||||
|
return (
|
||||||
|
<Pressable onPress={onPress}>
|
||||||
|
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-2 rounded')}>
|
||||||
|
<View style={tw.style('w-3 h-3 rounded-full', { backgroundColor: tagColor })} />
|
||||||
|
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
|
||||||
|
{tagName}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DrawerTagItem;
|
73
apps/mobile/src/components/file/FileIcon.tsx
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, View } from 'react-native';
|
||||||
|
import Svg, { Path } from 'react-native-svg';
|
||||||
|
|
||||||
|
import icons from '../../assets/icons/file';
|
||||||
|
import tw from '../../lib/tailwind';
|
||||||
|
import { FilePath } from '../../types/bindings';
|
||||||
|
import FolderIcon from '../icons/FolderIcon';
|
||||||
|
|
||||||
|
type FileIconProps = {
|
||||||
|
file?: FilePath | null;
|
||||||
|
/**
|
||||||
|
* This is multiplier for calculating icon size
|
||||||
|
* default: `1`
|
||||||
|
*/
|
||||||
|
size?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FileIcon = ({ file, size = 1 }: FileIconProps) => {
|
||||||
|
return (
|
||||||
|
<View style={[tw`justify-center`, { width: 60 * size, height: 60 * size }]}>
|
||||||
|
{file?.is_dir ? (
|
||||||
|
<View style={tw`items-center`}>
|
||||||
|
<FolderIcon size={50 * size} />
|
||||||
|
</View>
|
||||||
|
) : file?.file?.has_thumbnail ? (
|
||||||
|
<>{/* TODO */}</>
|
||||||
|
) : (
|
||||||
|
<View style={[tw`m-auto relative`, { width: 45 * size, height: 60 * size }]}>
|
||||||
|
<Svg
|
||||||
|
style={tw`absolute top-0 left-0`}
|
||||||
|
fill={tw.color('gray-550')}
|
||||||
|
width={45 * size}
|
||||||
|
height={60 * size}
|
||||||
|
viewBox="0 0 65 81"
|
||||||
|
>
|
||||||
|
<Path d="M0 8a8 8 0 0 1 8-8h31.686a8 8 0 0 1 5.657 2.343L53.5 10.5l9.157 9.157A8 8 0 0 1 65 25.314V73a8 8 0 0 1-8 8H8a8 8 0 0 1-8-8V8Z" />
|
||||||
|
</Svg>
|
||||||
|
<Svg
|
||||||
|
style={tw`absolute top-[2px] -right-[0.6px]`}
|
||||||
|
fill={tw.color('gray-500')}
|
||||||
|
width={15 * size}
|
||||||
|
height={15 * size}
|
||||||
|
viewBox="0 0 41 41"
|
||||||
|
>
|
||||||
|
<Path d="M41.412 40.558H11.234C5.03 40.558 0 35.528 0 29.324V0l41.412 40.558Z" />
|
||||||
|
</Svg>
|
||||||
|
{/* File Icon & Extension */}
|
||||||
|
<View style={tw`absolute w-full h-full items-center justify-center`}>
|
||||||
|
{file?.extension &&
|
||||||
|
icons[file.extension] &&
|
||||||
|
(() => {
|
||||||
|
const Icon = icons[file.extension];
|
||||||
|
return <Icon width={18 * size} height={18 * size} style={tw`mt-2`} />;
|
||||||
|
})()}
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
tw`mt-1 font-bold text-center uppercase text-gray-450`,
|
||||||
|
{
|
||||||
|
fontSize: 10 * (size * 0.8)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{file?.extension}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileIcon;
|
|
@ -1,76 +1,48 @@
|
||||||
import { FilePath } from '@sd/core';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Pressable, Text, View } from 'react-native';
|
||||||
import Svg, { Path } from 'react-native-svg';
|
|
||||||
|
|
||||||
import icons from '../../assets/icons/file';
|
|
||||||
import tw from '../../lib/tailwind';
|
import tw from '../../lib/tailwind';
|
||||||
import FolderIcon from '../icons/Folder';
|
import { SharedScreenProps } from '../../navigation/SharedScreens';
|
||||||
|
import { useFileModalStore } from '../../stores/useModalStore';
|
||||||
|
import { FilePath } from '../../types/bindings';
|
||||||
|
import FileIcon from './FileIcon';
|
||||||
|
|
||||||
type FileItemProps = {
|
type FileItemProps = {
|
||||||
file?: FilePath | null;
|
file?: FilePath | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Menu for file actions (File details, Share etc.)
|
// TODO: Menu for file actions (File details, Share etc.)
|
||||||
// TODO: Sheet Modal for file details
|
|
||||||
|
|
||||||
const FileItem = ({ file }: FileItemProps) => {
|
const FileItem = ({ file }: FileItemProps) => {
|
||||||
|
const fileRef = useFileModalStore((state) => state.fileRef);
|
||||||
|
const setData = useFileModalStore((state) => state.setData);
|
||||||
|
|
||||||
|
const navigation = useNavigation<SharedScreenProps<'Location'>['navigation']>();
|
||||||
|
|
||||||
|
function handlePress() {
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
if (file.is_dir) {
|
||||||
|
navigation.navigate('Location', { id: file.location_id });
|
||||||
|
} else {
|
||||||
|
setData(file);
|
||||||
|
fileRef.current.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={tw`w-[90px] h-[100px]`}>
|
<Pressable onPress={handlePress}>
|
||||||
<View style={tw`items-center`}>
|
<View style={tw`w-[90px] h-[80px] items-center`}>
|
||||||
{/* Folder Icons/Thumbnail etc. */}
|
{/* Folder Icons/Thumbnail etc. */}
|
||||||
<View style={tw`w-[60px] h-[60px] justify-center`}>
|
<FileIcon file={file} />
|
||||||
{file?.is_dir ? (
|
|
||||||
<View style={tw`items-center`}>
|
|
||||||
<FolderIcon size={54} />
|
|
||||||
</View>
|
|
||||||
) : file?.file?.has_thumbnail ? (
|
|
||||||
<>{/* TODO */}</>
|
|
||||||
) : (
|
|
||||||
<View style={tw`w-[45px] h-[60px] m-auto relative`}>
|
|
||||||
<Svg
|
|
||||||
style={tw`absolute top-0 left-0`}
|
|
||||||
fill={tw.color('gray-550')}
|
|
||||||
width={45}
|
|
||||||
height={60}
|
|
||||||
viewBox="0 0 65 81"
|
|
||||||
>
|
|
||||||
<Path d="M0 8a8 8 0 0 1 8-8h31.686a8 8 0 0 1 5.657 2.343L53.5 10.5l9.157 9.157A8 8 0 0 1 65 25.314V73a8 8 0 0 1-8 8H8a8 8 0 0 1-8-8V8Z" />
|
|
||||||
</Svg>
|
|
||||||
<Svg
|
|
||||||
style={tw`absolute top-[2px] -right-[0.6px]`}
|
|
||||||
fill={tw.color('gray-500')}
|
|
||||||
width={15}
|
|
||||||
height={15}
|
|
||||||
viewBox="0 0 41 41"
|
|
||||||
>
|
|
||||||
<Path d="M41.412 40.558H11.234C5.03 40.558 0 35.528 0 29.324V0l41.412 40.558Z" />
|
|
||||||
</Svg>
|
|
||||||
{/* File Icon & Extension */}
|
|
||||||
<View style={tw`absolute w-full h-full items-center justify-center`}>
|
|
||||||
{file?.extension && icons[file.extension] ? (
|
|
||||||
(() => {
|
|
||||||
const Icon = icons[file.extension];
|
|
||||||
return <Icon width={18} height={18} style={tw`mt-2`} />;
|
|
||||||
})()
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
<Text style={tw`mt-1 text-[10px] font-bold text-center uppercase text-gray-450`}>
|
|
||||||
{file?.extension}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
{/* Name */}
|
|
||||||
<View style={tw`px-1.5 py-[1px] mt-1`}>
|
<View style={tw`px-1.5 py-[1px] mt-1`}>
|
||||||
<Text numberOfLines={1} style={tw`text-gray-300 text-center text-xs font-medium`}>
|
<Text numberOfLines={1} style={tw`text-gray-300 text-center text-xs font-medium`}>
|
||||||
{file?.name}
|
{file?.name}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</Pressable>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
41
apps/mobile/src/components/header/Header.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { useDrawerStatus } from '@react-navigation/drawer';
|
||||||
|
import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
import { MotiView } from 'moti';
|
||||||
|
import { List } from 'phosphor-react-native';
|
||||||
|
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<DrawerNavigationHelpers>();
|
||||||
|
|
||||||
|
const { top } = useSafeAreaInsets();
|
||||||
|
|
||||||
|
const isDrawerOpen = useDrawerStatus() === 'open';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={tw.style('mx-4 bg-gray-550 rounded-md', { marginTop: top + 10 })}>
|
||||||
|
<View style={tw`flex flex-row items-center h-10`}>
|
||||||
|
<Pressable style={tw`px-3 h-full justify-center`} onPress={() => navigation.openDrawer()}>
|
||||||
|
<MotiView
|
||||||
|
animate={{ rotate: isDrawerOpen ? '90deg' : '0deg' }}
|
||||||
|
transition={{ type: 'timing' }}
|
||||||
|
>
|
||||||
|
<List size={20} color={tw.color('gray-300')} weight="fill" />
|
||||||
|
</MotiView>
|
||||||
|
</Pressable>
|
||||||
|
<Pressable
|
||||||
|
style={tw`flex-1 h-full justify-center`}
|
||||||
|
onPress={() => navigation.navigate('Search')}
|
||||||
|
>
|
||||||
|
<Text style={tw`text-gray-300 font-semibold text-sm`}>Search</Text>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
|
@ -1,9 +1,8 @@
|
||||||
|
import FolderWhite from '@sd/assets/svgs/folder-white.svg';
|
||||||
|
import Folder from '@sd/assets/svgs/folder.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SvgProps } from 'react-native-svg';
|
import { SvgProps } from 'react-native-svg';
|
||||||
|
|
||||||
import FolderWhite from '../../assets/temp/folder-white.svg';
|
|
||||||
import Folder from '../../assets/temp/folder.svg';
|
|
||||||
|
|
||||||
type FolderProps = {
|
type FolderProps = {
|
||||||
/**
|
/**
|
||||||
* Render a white folder icon
|
* Render a white folder icon
|
|
@ -1 +0,0 @@
|
||||||
// Only mount this modal if `FileItem` gets used in screen.
|
|
128
apps/mobile/src/components/modals/FileModal.tsx
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import { BottomSheetModal, BottomSheetScrollView } from '@gorhom/bottom-sheet';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { Button, Pressable, Text, View } from 'react-native';
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MetaItem({ title, value }: MetaItemProps) {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text style={tw`text-sm font-bold text-white`}>{title}</Text>
|
||||||
|
<Text style={tw`text-sm text-gray-400 mt-1`}>{value}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FileModal = () => {
|
||||||
|
const { fileRef, data } = useFileModalStore();
|
||||||
|
|
||||||
|
const fileDetailsRef = useRef<BottomSheetModal>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<BottomSheetModal
|
||||||
|
ref={fileRef}
|
||||||
|
snapPoints={['60%', '90%']}
|
||||||
|
backdropComponent={ModalBackdrop}
|
||||||
|
handleComponent={ModalHandle}
|
||||||
|
// Do not remove!
|
||||||
|
onAnimate={(from, to) => console.log(from, to)}
|
||||||
|
>
|
||||||
|
{data && (
|
||||||
|
<View style={tw`flex-1 p-4 bg-gray-600`}>
|
||||||
|
{/* File Icon / Name */}
|
||||||
|
<View style={tw`flex flex-row items-center`}>
|
||||||
|
<FileIcon file={data} size={1.6} />
|
||||||
|
{/* File Name, Details etc. */}
|
||||||
|
<View style={tw`ml-2`}>
|
||||||
|
<Text style={tw`text-base font-bold text-gray-200`}>{data?.name}</Text>
|
||||||
|
<View style={tw`flex flex-row mt-2`}>
|
||||||
|
<Text style={tw`text-xs text-gray-400`}>5 MB,</Text>
|
||||||
|
<Text style={tw`ml-1 text-xs text-gray-400`}>
|
||||||
|
{data?.extension.toUpperCase()},
|
||||||
|
</Text>
|
||||||
|
<Text style={tw`ml-1 text-xs text-gray-400`}>15 Aug</Text>
|
||||||
|
</View>
|
||||||
|
<Pressable style={tw`mt-2`} onPress={() => fileDetailsRef.current.present()}>
|
||||||
|
<Text style={tw`text-sm text-primary-500`}>More</Text>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{/* Divider */}
|
||||||
|
<Divider style={tw`my-6`} />
|
||||||
|
{/* Buttons */}
|
||||||
|
|
||||||
|
<Button onPress={() => fileRef.current.close()} title="Copy" color="white" />
|
||||||
|
<Button onPress={() => fileRef.current.close()} title="Move" color="white" />
|
||||||
|
<Button onPress={() => fileRef.current.close()} title="Share" color="white" />
|
||||||
|
<Button onPress={() => fileRef.current.close()} title="Delete" color="white" />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</BottomSheetModal>
|
||||||
|
{/* Details Modal */}
|
||||||
|
<BottomSheetModal
|
||||||
|
ref={fileDetailsRef}
|
||||||
|
enableContentPanningGesture={false}
|
||||||
|
enablePanDownToClose={false}
|
||||||
|
snapPoints={['70%']}
|
||||||
|
backdropComponent={ModalBackdrop}
|
||||||
|
handleComponent={ModalHandle}
|
||||||
|
// Do not remove!
|
||||||
|
onAnimate={(from, to) => console.log(from, to)}
|
||||||
|
>
|
||||||
|
{data && (
|
||||||
|
<BottomSheetScrollView style={tw`flex-1 p-4 bg-gray-600`}>
|
||||||
|
{/* Back Button */}
|
||||||
|
<Pressable style={tw`w-full ml-4`} onPress={() => fileDetailsRef.current.close()}>
|
||||||
|
<ChevronLeftIcon color={tw.color('primary-500')} width={20} height={20} />
|
||||||
|
</Pressable>
|
||||||
|
{/* File Icon / Name */}
|
||||||
|
<View style={tw`items-center`}>
|
||||||
|
<FileIcon file={data} size={1.8} />
|
||||||
|
<Text style={tw`text-base font-bold text-gray-200 mt-3`}>{data.name}</Text>
|
||||||
|
</View>
|
||||||
|
{/* Details */}
|
||||||
|
<Divider style={tw`mt-6 mb-4`} />
|
||||||
|
<>
|
||||||
|
{data?.file?.cas_id && (
|
||||||
|
<MetaItem title="Unique Content ID" value={data.file.cas_id as string} />
|
||||||
|
)}
|
||||||
|
<MetaItem title="URI" value={`/Users/utku/Somewhere/vite.config.js`} />
|
||||||
|
<Divider style={tw`my-4`} />
|
||||||
|
<MetaItem
|
||||||
|
title="Date Created"
|
||||||
|
value={format(new Date(data.date_created), 'MMMM Do yyyy, h:mm:ss aaa')}
|
||||||
|
/>
|
||||||
|
<Divider style={tw`my-4`} />
|
||||||
|
<MetaItem
|
||||||
|
title="Date Indexed"
|
||||||
|
value={format(new Date(data.date_indexed), 'MMMM Do yyyy, h:mm:ss aaa')}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
</BottomSheetScrollView>
|
||||||
|
)}
|
||||||
|
</BottomSheetModal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
13
apps/mobile/src/components/modals/GlobalModals.tsx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { FileModal } from './FileModal';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global Modals
|
||||||
|
* which are mounted when the app starts.
|
||||||
|
*/
|
||||||
|
export function GlobalModals() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FileModal />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
10
apps/mobile/src/components/modals/layout/ModalBackdrop.tsx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { BottomSheetBackdrop, BottomSheetBackdropProps } from '@gorhom/bottom-sheet';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const ModalBackdrop = (props: BottomSheetBackdropProps) => {
|
||||||
|
return (
|
||||||
|
<BottomSheetBackdrop {...props} appearsOnIndex={0} disappearsOnIndex={-1} opacity={0.75} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalBackdrop;
|
16
apps/mobile/src/components/modals/layout/ModalHandle.tsx
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { BottomSheetHandle, BottomSheetHandleProps } from '@gorhom/bottom-sheet';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import tw from '../../../lib/tailwind';
|
||||||
|
|
||||||
|
const ModalHandle = (props: BottomSheetHandleProps) => {
|
||||||
|
return (
|
||||||
|
<BottomSheetHandle
|
||||||
|
{...props}
|
||||||
|
style={tw`bg-gray-600 rounded-t-xl`}
|
||||||
|
indicatorStyle={tw`bg-gray-550`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalHandle;
|
|
@ -1,4 +1,3 @@
|
||||||
import { Statistics } from '@sd/core';
|
|
||||||
import byteSize from 'byte-size';
|
import byteSize from 'byte-size';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ScrollView, Text, View } from 'react-native';
|
import { ScrollView, Text, View } from 'react-native';
|
||||||
|
@ -6,6 +5,18 @@ import { ScrollView, Text, View } from 'react-native';
|
||||||
import useCounter from '../hooks/useCounter';
|
import useCounter from '../hooks/useCounter';
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
const StatItemNames: Partial<Record<keyof Statistics, string>> = {
|
const StatItemNames: Partial<Record<keyof Statistics, string>> = {
|
||||||
total_bytes_capacity: 'Total capacity',
|
total_bytes_capacity: 'Total capacity',
|
||||||
preview_media_bytes: 'Preview media',
|
preview_media_bytes: 'Preview media',
|
||||||
|
|
152
apps/mobile/src/hooks/rspc.ts
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
import {
|
||||||
|
ClientTransformer,
|
||||||
|
OperationKey,
|
||||||
|
OperationType,
|
||||||
|
RSPCError,
|
||||||
|
Transport,
|
||||||
|
createReactQueryHooks
|
||||||
|
} from '@rspc/client';
|
||||||
|
import {
|
||||||
|
QueryClient,
|
||||||
|
UseMutationOptions,
|
||||||
|
UseMutationResult,
|
||||||
|
UseQueryOptions,
|
||||||
|
UseQueryResult,
|
||||||
|
useMutation as _useMutation
|
||||||
|
} from '@tanstack/react-query';
|
||||||
|
import { NativeEventEmitter, NativeModules } from 'react-native';
|
||||||
|
|
||||||
|
import { useLibraryStore } from '../stores/useLibraryStore';
|
||||||
|
import type { LibraryArgs, Operations } from '../types/bindings';
|
||||||
|
|
||||||
|
export const queryClient = new QueryClient();
|
||||||
|
export const rspc = createReactQueryHooks<Operations>();
|
||||||
|
|
||||||
|
const { SDCore } = NativeModules;
|
||||||
|
const eventEmitter = new NativeEventEmitter(NativeModules.SDCore);
|
||||||
|
|
||||||
|
// TODO(@Oscar): Replace this with a better abstraction when it's released in rspc. This relies on internal details of rspc which will change without warning.
|
||||||
|
export class ReactNativeTransport implements Transport {
|
||||||
|
transformer?: ClientTransformer;
|
||||||
|
clientSubscriptionCallback?: (id: string, key: string, value: any) => void;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const subscriptionEventListener = eventEmitter.addListener('SDCoreEvent', (event) => {
|
||||||
|
const body = JSON.parse(event);
|
||||||
|
if (body.type === 'event') {
|
||||||
|
const { id, key, result } = body;
|
||||||
|
this.clientSubscriptionCallback(id, key, result);
|
||||||
|
} else if (body.type === 'response' || body.type === 'error') {
|
||||||
|
throw new Error(
|
||||||
|
`Recieved event of type '${body.type}'. This should be impossible with the React Native transport!`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error(`Received event of unknown method '${body.type}'`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async doRequest(operation: OperationType, key: OperationKey): Promise<any> {
|
||||||
|
const body = JSON.parse(
|
||||||
|
await SDCore.sd_core_msg(
|
||||||
|
JSON.stringify({
|
||||||
|
operation,
|
||||||
|
key: this.transformer?.serialize(operation, key) || key
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (body.type === 'error') {
|
||||||
|
const { status_code, message } = body;
|
||||||
|
throw new RSPCError(status_code, message);
|
||||||
|
} else if (body.type === 'response') {
|
||||||
|
return this.transformer?.deserialize(operation, key, body.result) || body.result;
|
||||||
|
} else if (body.type !== 'none') {
|
||||||
|
throw new Error(`RSPC ReactNative doRequest received invalid body type '${body?.type}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type NonLibraryQueries = Exclude<Operations['queries'], { key: [any, LibraryArgs<any>] }> &
|
||||||
|
Extract<Operations['queries'], { key: [any] }>;
|
||||||
|
type NonLibraryQuery<K extends string> = Extract<NonLibraryQueries, { key: [K] | [K, any] }>;
|
||||||
|
type NonLibraryQueryKey = NonLibraryQueries['key'][0];
|
||||||
|
type NonLibraryQueryResult<K extends NonLibraryQueryKey> = NonLibraryQuery<K>['result'];
|
||||||
|
|
||||||
|
export function useBridgeQuery<K extends NonLibraryQueries['key']>(
|
||||||
|
key: K,
|
||||||
|
options?: UseQueryOptions<NonLibraryQueryResult<K[0]>, RSPCError>
|
||||||
|
): UseQueryResult<NonLibraryQueryResult<K[0]>, RSPCError> {
|
||||||
|
// @ts-ignore
|
||||||
|
return rspc.useQuery(key, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
type LibraryQueries = Extract<Operations['queries'], { key: [string, LibraryArgs<any>] }>;
|
||||||
|
type LibraryQuery<K extends string> = Extract<LibraryQueries, { key: [K, any] }>;
|
||||||
|
type LibraryQueryKey = LibraryQueries['key'][0];
|
||||||
|
type LibraryQueryArgs<K extends string> = LibraryQuery<K>['key'][1] extends LibraryArgs<infer A>
|
||||||
|
? A
|
||||||
|
: never;
|
||||||
|
type LibraryQueryResult<K extends string> = LibraryQuery<K>['result'];
|
||||||
|
|
||||||
|
export function useLibraryQuery<K extends LibraryQueryKey>(
|
||||||
|
key: LibraryQueryArgs<K> extends null | undefined ? [K] : [K, LibraryQueryArgs<K>],
|
||||||
|
options?: UseQueryOptions<LibraryQueryResult<K>, RSPCError>
|
||||||
|
): UseQueryResult<LibraryQueryResult<K>, RSPCError> {
|
||||||
|
const library_id = useLibraryStore((state) => state.currentLibraryUuid);
|
||||||
|
if (!library_id) throw new Error(`Attempted to do library query with no library set!`);
|
||||||
|
// @ts-ignore
|
||||||
|
return rspc.useQuery([key[0], { library_id: library_id || '', arg: key[1] || null }], options);
|
||||||
|
}
|
||||||
|
|
||||||
|
type LibraryMutations = Extract<Operations['mutations'], { key: [string, LibraryArgs<any>] }>;
|
||||||
|
type LibraryMutation<K extends LibraryMutationKey> = Extract<LibraryMutations, { key: [K, any] }>;
|
||||||
|
type LibraryMutationKey = LibraryMutations['key'][0];
|
||||||
|
type LibraryMutationArgs<K extends LibraryMutationKey> =
|
||||||
|
LibraryMutation<K>['key'][1] extends LibraryArgs<infer A> ? A : never;
|
||||||
|
type LibraryMutationResult<K extends LibraryMutationKey> = LibraryMutation<K>['result'];
|
||||||
|
export function useLibraryMutation<K extends LibraryMutationKey>(
|
||||||
|
key: K,
|
||||||
|
options?: UseMutationOptions<LibraryMutationResult<K>, RSPCError>
|
||||||
|
) {
|
||||||
|
const ctx = rspc.useContext();
|
||||||
|
const library_id = useLibraryStore((state) => state.currentLibraryUuid);
|
||||||
|
if (!library_id) throw new Error(`Attempted to do library query with no library set!`);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return _useMutation<LibraryMutationResult<K>, RSPCError, LibraryMutationArgs<K>>(
|
||||||
|
async (data) => ctx.client.mutation([key, { library_id: library_id || '', arg: data || null }]),
|
||||||
|
{
|
||||||
|
...options,
|
||||||
|
context: rspc.ReactQueryContext
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type NonLibraryMutations = Exclude<Operations['mutations'], { key: [any, LibraryArgs<any>] }>;
|
||||||
|
type NonLibraryMutation<K extends NonLibraryMutationKey> = Extract<
|
||||||
|
NonLibraryMutations,
|
||||||
|
{ key: [K] | [K, any] }
|
||||||
|
>;
|
||||||
|
type NonLibraryMutationKey = NonLibraryMutations['key'][0];
|
||||||
|
type NonLibraryMutationArgs<K extends NonLibraryMutationKey> = NonLibraryMutation<K>['key'][1];
|
||||||
|
type NonLibraryMutationResult<K extends NonLibraryMutationKey> = NonLibraryMutation<K>['result'];
|
||||||
|
export function useBridgeMutation<K extends NonLibraryMutationKey>(
|
||||||
|
key: K,
|
||||||
|
options?: UseMutationOptions<NonLibraryMutationResult<K>, RSPCError>
|
||||||
|
): UseMutationResult<NonLibraryMutationResult<K>, RSPCError, NonLibraryMutationArgs<K>> {
|
||||||
|
// @ts-ignore
|
||||||
|
return rspc.useMutation(key, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useInvalidateQuery() {
|
||||||
|
const context = rspc.useContext();
|
||||||
|
rspc.useSubscription(['invalidateQuery'], {
|
||||||
|
onNext: (invalidateOperation) => {
|
||||||
|
const key = [invalidateOperation.key];
|
||||||
|
if (invalidateOperation.arg !== null) {
|
||||||
|
key.concat(invalidateOperation.arg);
|
||||||
|
}
|
||||||
|
context.queryClient.invalidateQueries(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,10 +1,6 @@
|
||||||
import { DrawerScreenProps, createDrawerNavigator } from '@react-navigation/drawer';
|
import { DrawerScreenProps, createDrawerNavigator } from '@react-navigation/drawer';
|
||||||
import {
|
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
|
||||||
CompositeScreenProps,
|
import { StackScreenProps } from '@react-navigation/stack';
|
||||||
NavigatorScreenParams,
|
|
||||||
getFocusedRouteNameFromRoute
|
|
||||||
} from '@react-navigation/native';
|
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
|
||||||
|
|
||||||
import type { RootStackParamList } from '.';
|
import type { RootStackParamList } from '.';
|
||||||
import DrawerContent from '../components/drawer/DrawerContent';
|
import DrawerContent from '../components/drawer/DrawerContent';
|
||||||
|
@ -25,8 +21,8 @@ export default function DrawerNavigator() {
|
||||||
width: '75%'
|
width: '75%'
|
||||||
},
|
},
|
||||||
overlayColor: 'transparent',
|
overlayColor: 'transparent',
|
||||||
// Can only swipe on Overview screen! (for opening drawer)
|
drawerType: 'slide'
|
||||||
swipeEnabled: getFocusedRouteNameFromRoute(route) === 'Overview'
|
// swipeEnabled: false
|
||||||
// drawerHideStatusBarOnOpen: true,
|
// drawerHideStatusBarOnOpen: true,
|
||||||
// drawerStatusBarAnimation: 'slide'
|
// drawerStatusBarAnimation: 'slide'
|
||||||
};
|
};
|
||||||
|
@ -39,10 +35,10 @@ export default function DrawerNavigator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DrawerNavParamList = {
|
export type DrawerNavParamList = {
|
||||||
Home: NavigatorScreenParams<TabParamList> | undefined;
|
Home: NavigatorScreenParams<TabParamList>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HomeDrawerScreenProps<Screen extends keyof DrawerNavParamList> = CompositeScreenProps<
|
export type HomeDrawerScreenProps<Screen extends keyof DrawerNavParamList> = CompositeScreenProps<
|
||||||
DrawerScreenProps<DrawerNavParamList, Screen>,
|
DrawerScreenProps<DrawerNavParamList, Screen>,
|
||||||
NativeStackScreenProps<RootStackParamList, 'Root'>
|
StackScreenProps<RootStackParamList, 'Root'>
|
||||||
>;
|
>;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { NativeStackScreenProps, createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { StackScreenProps, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
import OnboardingScreen from '../screens/onboarding/Onboarding';
|
import OnboardingScreen from '../screens/onboarding/Onboarding';
|
||||||
|
|
||||||
const OnboardingStack = createNativeStackNavigator<OnboardingStackParamList>();
|
const OnboardingStack = createStackNavigator<OnboardingStackParamList>();
|
||||||
|
|
||||||
export default function OnboardingNavigator() {
|
export default function OnboardingNavigator() {
|
||||||
return (
|
return (
|
||||||
|
@ -17,4 +17,4 @@ export type OnboardingStackParamList = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnboardingStackScreenProps<Screen extends keyof OnboardingStackParamList> =
|
export type OnboardingStackScreenProps<Screen extends keyof OnboardingStackParamList> =
|
||||||
NativeStackScreenProps<OnboardingStackParamList, Screen>;
|
StackScreenProps<OnboardingStackParamList, Screen>;
|
||||||
|
|
36
apps/mobile/src/navigation/SharedScreens.tsx
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import { ParamListBase, StackNavigationState, TypedNavigator } from '@react-navigation/native';
|
||||||
|
import {
|
||||||
|
StackNavigationEventMap,
|
||||||
|
StackNavigationOptions,
|
||||||
|
StackScreenProps
|
||||||
|
} from '@react-navigation/stack';
|
||||||
|
|
||||||
|
import LocationScreen from '../screens/Location';
|
||||||
|
import TagScreen from '../screens/Tag';
|
||||||
|
|
||||||
|
export function SharedScreens(
|
||||||
|
Stack: TypedNavigator<
|
||||||
|
SharedScreensParamList,
|
||||||
|
StackNavigationState<ParamListBase>,
|
||||||
|
StackNavigationOptions,
|
||||||
|
StackNavigationEventMap,
|
||||||
|
any
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack.Screen name="Location" component={LocationScreen} />
|
||||||
|
<Stack.Screen name="Tag" component={TagScreen} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SharedScreensParamList = {
|
||||||
|
Location: { id: number };
|
||||||
|
Tag: { id: number };
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SharedScreenProps<Screen extends keyof SharedScreensParamList> = StackScreenProps<
|
||||||
|
SharedScreensParamList,
|
||||||
|
Screen
|
||||||
|
>;
|
|
@ -1,21 +1,21 @@
|
||||||
import { BottomTabScreenProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
import { BottomTabScreenProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||||
import { CompositeScreenProps } from '@react-navigation/native';
|
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
|
||||||
import { CirclesFour, Folder, Planet } from 'phosphor-react-native';
|
import { CirclesFour, Folder, Planet } from 'phosphor-react-native';
|
||||||
import { PhotographIcon } from 'react-native-heroicons/outline';
|
import { PhotographIcon } from 'react-native-heroicons/outline';
|
||||||
|
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
import OverviewScreen from '../screens/Overview';
|
|
||||||
import PhotosScreen from '../screens/Photos';
|
|
||||||
import SpacesScreen from '../screens/Spaces';
|
|
||||||
import type { HomeDrawerScreenProps } from './DrawerNavigator';
|
import type { HomeDrawerScreenProps } from './DrawerNavigator';
|
||||||
import BrowseStack from './tabs/BrowseStack';
|
import BrowseStack, { BrowseStackParamList } from './tabs/BrowseStack';
|
||||||
|
import OverviewStack, { OverviewStackParamList } from './tabs/OverviewStack';
|
||||||
|
import PhotosStack, { PhotosStackParamList } from './tabs/PhotosStack';
|
||||||
|
import SpacesStack, { SpacesStackParamList } from './tabs/SpacesStack';
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator<TabParamList>();
|
const Tab = createBottomTabNavigator<TabParamList>();
|
||||||
|
|
||||||
export default function TabNavigator() {
|
export default function TabNavigator() {
|
||||||
return (
|
return (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
initialRouteName="Overview"
|
initialRouteName="OverviewStack"
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
tabBarActiveTintColor: tw.color('bg-primary'),
|
tabBarActiveTintColor: tw.color('bg-primary'),
|
||||||
|
@ -27,12 +27,13 @@ export default function TabNavigator() {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Overview"
|
name="OverviewStack"
|
||||||
component={OverviewScreen}
|
component={OverviewStack}
|
||||||
options={{
|
options={{
|
||||||
tabBarIcon: ({ focused }) => (
|
tabBarIcon: ({ focused }) => (
|
||||||
<Planet size={22} weight="bold" color={focused ? tw.color('bg-primary') : 'white'} />
|
<Planet size={22} weight="bold" color={focused ? tw.color('bg-primary') : 'white'} />
|
||||||
)
|
),
|
||||||
|
tabBarLabel: 'Overview'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
|
@ -46,8 +47,8 @@ export default function TabNavigator() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Spaces"
|
name="SpacesStack"
|
||||||
component={SpacesScreen}
|
component={SpacesStack}
|
||||||
options={{
|
options={{
|
||||||
tabBarIcon: ({ focused }) => (
|
tabBarIcon: ({ focused }) => (
|
||||||
<CirclesFour
|
<CirclesFour
|
||||||
|
@ -55,16 +56,18 @@ export default function TabNavigator() {
|
||||||
weight="bold"
|
weight="bold"
|
||||||
color={focused ? tw.color('bg-primary') : 'white'}
|
color={focused ? tw.color('bg-primary') : 'white'}
|
||||||
/>
|
/>
|
||||||
)
|
),
|
||||||
|
tabBarLabel: 'Spaces'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Photos"
|
name="PhotosStack"
|
||||||
component={PhotosScreen}
|
component={PhotosStack}
|
||||||
options={{
|
options={{
|
||||||
tabBarIcon: ({ focused }) => (
|
tabBarIcon: ({ focused }) => (
|
||||||
<PhotographIcon size={22} color={focused ? tw.color('bg-primary') : 'white'} />
|
<PhotographIcon size={22} color={focused ? tw.color('bg-primary') : 'white'} />
|
||||||
)
|
),
|
||||||
|
tabBarLabel: 'Photos'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
|
@ -72,10 +75,10 @@ export default function TabNavigator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TabParamList = {
|
export type TabParamList = {
|
||||||
Overview: undefined;
|
OverviewStack: NavigatorScreenParams<OverviewStackParamList>;
|
||||||
BrowseStack: undefined;
|
BrowseStack: NavigatorScreenParams<BrowseStackParamList>;
|
||||||
Spaces: undefined;
|
SpacesStack: NavigatorScreenParams<SpacesStackParamList>;
|
||||||
Photos: undefined;
|
PhotosStack: NavigatorScreenParams<PhotosStackParamList>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TabScreenProps<Screen extends keyof TabParamList> = CompositeScreenProps<
|
export type TabScreenProps<Screen extends keyof TabParamList> = CompositeScreenProps<
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { NavigatorScreenParams } from '@react-navigation/native';
|
import { NavigatorScreenParams } from '@react-navigation/native';
|
||||||
import { NativeStackScreenProps, createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { StackScreenProps, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
import NotFoundScreen from '../screens/NotFound';
|
import NotFoundScreen from '../screens/NotFound';
|
||||||
|
import SearchScreen from '../screens/modals/Search';
|
||||||
import SettingsScreen from '../screens/modals/settings/Settings';
|
import SettingsScreen from '../screens/modals/settings/Settings';
|
||||||
import DrawerNavigator from './DrawerNavigator';
|
|
||||||
import type { DrawerNavParamList } from './DrawerNavigator';
|
import type { DrawerNavParamList } from './DrawerNavigator';
|
||||||
|
import DrawerNavigator from './DrawerNavigator';
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator<RootStackParamList>();
|
const Stack = createStackNavigator<RootStackParamList>();
|
||||||
|
|
||||||
// This is the main navigator we nest everything under.
|
// This is the main navigator we nest everything under.
|
||||||
export default function RootNavigator() {
|
export default function RootNavigator() {
|
||||||
|
@ -14,7 +15,17 @@ export default function RootNavigator() {
|
||||||
<Stack.Navigator initialRouteName="Root">
|
<Stack.Navigator initialRouteName="Root">
|
||||||
<Stack.Screen name="Root" component={DrawerNavigator} options={{ headerShown: false }} />
|
<Stack.Screen name="Root" component={DrawerNavigator} options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />
|
<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />
|
||||||
<Stack.Group screenOptions={{ presentation: 'modal' }}>
|
<Stack.Screen name="Search" component={SearchScreen} options={{ headerShown: false }} />
|
||||||
|
{/* Modals */}
|
||||||
|
<Stack.Group
|
||||||
|
screenOptions={{
|
||||||
|
presentation: 'modal',
|
||||||
|
headerBackTitleVisible: false,
|
||||||
|
headerStyle: { backgroundColor: '#08090D' },
|
||||||
|
// headerShadowVisible: false,
|
||||||
|
headerTintColor: '#fff'
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Stack.Screen name="Settings" component={SettingsScreen} />
|
<Stack.Screen name="Settings" component={SettingsScreen} />
|
||||||
</Stack.Group>
|
</Stack.Group>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
|
@ -22,13 +33,23 @@ export default function RootNavigator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RootStackParamList = {
|
export type RootStackParamList = {
|
||||||
Root: NavigatorScreenParams<DrawerNavParamList> | undefined;
|
Root: NavigatorScreenParams<DrawerNavParamList>;
|
||||||
NotFound: undefined;
|
NotFound: undefined;
|
||||||
// Modals
|
// Modals
|
||||||
|
Search: undefined;
|
||||||
Settings: undefined;
|
Settings: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RootStackScreenProps<Screen extends keyof RootStackParamList> = NativeStackScreenProps<
|
export type RootStackScreenProps<Screen extends keyof RootStackParamList> = StackScreenProps<
|
||||||
RootStackParamList,
|
RootStackParamList,
|
||||||
Screen
|
Screen
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
// This declaration is used by useNavigation, Link, ref etc.
|
||||||
|
declare global {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||||
|
namespace ReactNavigation {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
|
interface RootParamList extends RootStackParamList {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,30 +1,35 @@
|
||||||
import { CompositeScreenProps } from '@react-navigation/native';
|
import { CompositeScreenProps } from '@react-navigation/native';
|
||||||
import { NativeStackScreenProps, createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
|
import Header from '../../components/header/Header';
|
||||||
import BrowseScreen from '../../screens/Browse';
|
import BrowseScreen from '../../screens/Browse';
|
||||||
import LocationScreen from '../../screens/Location';
|
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
|
||||||
import TagScreen from '../../screens/Tag';
|
|
||||||
import { TabScreenProps } from '../TabNavigator';
|
import { TabScreenProps } from '../TabNavigator';
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator<BrowseStackParamList>();
|
const Stack = createStackNavigator<BrowseStackParamList>();
|
||||||
|
|
||||||
export default function BrowseStack() {
|
export default function BrowseStack() {
|
||||||
return (
|
return (
|
||||||
<Stack.Navigator initialRouteName="Browse">
|
<Stack.Navigator
|
||||||
<Stack.Screen name="Browse" component={BrowseScreen} />
|
initialRouteName="Browse"
|
||||||
<Stack.Screen name="Location" component={LocationScreen} />
|
screenOptions={{
|
||||||
<Stack.Screen name="Tag" component={TagScreen} />
|
headerStyle: { backgroundColor: '#08090D' },
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
...TransitionPresets.ModalFadeTransition
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack.Screen name="Browse" component={BrowseScreen} options={{ header: Header }} />
|
||||||
|
{SharedScreens(Stack as any)}
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BrowseStackParamList = {
|
export type BrowseStackParamList = {
|
||||||
Browse: undefined;
|
Browse: undefined;
|
||||||
Location: { id: number };
|
} & SharedScreensParamList;
|
||||||
Tag: { id: number };
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BrowseScreenProps<Screen extends keyof BrowseStackParamList> = CompositeScreenProps<
|
export type BrowseStackScreenProps<Screen extends keyof BrowseStackParamList> =
|
||||||
NativeStackScreenProps<BrowseStackParamList, Screen>,
|
CompositeScreenProps<
|
||||||
TabScreenProps<'BrowseStack'>
|
StackScreenProps<BrowseStackParamList, Screen>,
|
||||||
>;
|
TabScreenProps<'BrowseStack'>
|
||||||
|
>;
|
||||||
|
|
35
apps/mobile/src/navigation/tabs/OverviewStack.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { CompositeScreenProps } from '@react-navigation/native';
|
||||||
|
import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
|
import Header from '../../components/header/Header';
|
||||||
|
import OverviewScreen from '../../screens/Overview';
|
||||||
|
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
|
||||||
|
import { TabScreenProps } from '../TabNavigator';
|
||||||
|
|
||||||
|
const Stack = createStackNavigator<OverviewStackParamList>();
|
||||||
|
|
||||||
|
export default function OverviewStack() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator
|
||||||
|
initialRouteName="Overview"
|
||||||
|
screenOptions={{
|
||||||
|
headerStyle: { backgroundColor: '#08090D' },
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
...TransitionPresets.ModalFadeTransition
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack.Screen name="Overview" component={OverviewScreen} options={{ header: Header }} />
|
||||||
|
{SharedScreens(Stack as any)}
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OverviewStackParamList = {
|
||||||
|
Overview: undefined;
|
||||||
|
} & SharedScreensParamList;
|
||||||
|
|
||||||
|
export type OverviewStackScreenProps<Screen extends keyof OverviewStackParamList> =
|
||||||
|
CompositeScreenProps<
|
||||||
|
StackScreenProps<OverviewStackParamList, Screen>,
|
||||||
|
TabScreenProps<'OverviewStack'>
|
||||||
|
>;
|
35
apps/mobile/src/navigation/tabs/PhotosStack.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { CompositeScreenProps } from '@react-navigation/native';
|
||||||
|
import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
|
import Header from '../../components/header/Header';
|
||||||
|
import PhotosScreen from '../../screens/Photos';
|
||||||
|
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
|
||||||
|
import { TabScreenProps } from '../TabNavigator';
|
||||||
|
|
||||||
|
const Stack = createStackNavigator<PhotosStackParamList>();
|
||||||
|
|
||||||
|
export default function PhotosStack() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator
|
||||||
|
initialRouteName="Photos"
|
||||||
|
screenOptions={{
|
||||||
|
headerStyle: { backgroundColor: '#08090D' },
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
...TransitionPresets.ModalFadeTransition
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack.Screen name="Photos" component={PhotosScreen} options={{ header: Header }} />
|
||||||
|
{SharedScreens(Stack as any)}
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PhotosStackParamList = {
|
||||||
|
Photos: undefined;
|
||||||
|
} & SharedScreensParamList;
|
||||||
|
|
||||||
|
export type PhotosStackScreenProps<Screen extends keyof PhotosStackParamList> =
|
||||||
|
CompositeScreenProps<
|
||||||
|
StackScreenProps<PhotosStackParamList, Screen>,
|
||||||
|
TabScreenProps<'PhotosStack'>
|
||||||
|
>;
|
35
apps/mobile/src/navigation/tabs/SpacesStack.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { CompositeScreenProps } from '@react-navigation/native';
|
||||||
|
import { StackScreenProps, TransitionPresets, createStackNavigator } from '@react-navigation/stack';
|
||||||
|
|
||||||
|
import Header from '../../components/header/Header';
|
||||||
|
import SpacesScreen from '../../screens/Spaces';
|
||||||
|
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
|
||||||
|
import { TabScreenProps } from '../TabNavigator';
|
||||||
|
|
||||||
|
const Stack = createStackNavigator<SpacesStackParamList>();
|
||||||
|
|
||||||
|
export default function SpacesStack() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator
|
||||||
|
initialRouteName="Spaces"
|
||||||
|
screenOptions={{
|
||||||
|
headerStyle: { backgroundColor: '#08090D' },
|
||||||
|
headerTintColor: '#fff',
|
||||||
|
...TransitionPresets.ModalFadeTransition
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack.Screen name="Spaces" component={SpacesScreen} options={{ header: Header }} />
|
||||||
|
{SharedScreens(Stack as any)}
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SpacesStackParamList = {
|
||||||
|
Spaces: undefined;
|
||||||
|
} & SharedScreensParamList;
|
||||||
|
|
||||||
|
export type SpacesStackScreenProps<Screen extends keyof SpacesStackParamList> =
|
||||||
|
CompositeScreenProps<
|
||||||
|
StackScreenProps<SpacesStackParamList, Screen>,
|
||||||
|
TabScreenProps<'SpacesStack'>
|
||||||
|
>;
|
|
@ -5,7 +5,7 @@ import BrowseLocationItem from '../components/browse/BrowseLocationItem';
|
||||||
import BrowseTagItem from '../components/browse/BrowseTagItem';
|
import BrowseTagItem from '../components/browse/BrowseTagItem';
|
||||||
import CollapsibleView from '../components/layout/CollapsibleView';
|
import CollapsibleView from '../components/layout/CollapsibleView';
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
import { BrowseScreenProps } from '../navigation/tabs/BrowseStack';
|
import { BrowseStackScreenProps } from '../navigation/tabs/BrowseStack';
|
||||||
|
|
||||||
const placeholderLocationData = [
|
const placeholderLocationData = [
|
||||||
{
|
{
|
||||||
|
@ -35,7 +35,7 @@ const placeholderTagsData = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const BrowseScreen = ({ navigation }: BrowseScreenProps<'Browse'>) => {
|
const BrowseScreen = ({ navigation }: BrowseStackScreenProps<'Browse'>) => {
|
||||||
return (
|
return (
|
||||||
<View style={tw`flex-1 p-4`}>
|
<View style={tw`flex-1 p-4`}>
|
||||||
<CollapsibleView
|
<CollapsibleView
|
||||||
|
|
|
@ -2,8 +2,9 @@ import React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
|
import { SharedScreenProps } from '../navigation/SharedScreens';
|
||||||
|
|
||||||
export default function LocationScreen({ navigation, route }: any) {
|
export default function LocationScreen({ navigation, route }: SharedScreenProps<'Location'>) {
|
||||||
const { id } = route.params;
|
const { id } = route.params;
|
||||||
return (
|
return (
|
||||||
<View style={tw`flex-1 items-center justify-center`}>
|
<View style={tw`flex-1 items-center justify-center`}>
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlatList, Text, View } from 'react-native';
|
import { FlatList, View } from 'react-native';
|
||||||
|
|
||||||
import { Button } from '../components/base/Button';
|
|
||||||
import Device from '../components/device/Device';
|
import Device from '../components/device/Device';
|
||||||
import DrawerScreenWrapper from '../components/drawer/DrawerScreenWrapper';
|
|
||||||
import VirtualizedListWrapper from '../components/layout/VirtualizedListWrapper';
|
import VirtualizedListWrapper from '../components/layout/VirtualizedListWrapper';
|
||||||
import OverviewStats from '../containers/OverviewStats';
|
import OverviewStats from '../containers/OverviewStats';
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
import type { TabScreenProps } from '../navigation/TabNavigator';
|
import { OverviewStackScreenProps } from '../navigation/tabs/OverviewStack';
|
||||||
|
|
||||||
const placeholderOverviewStats = {
|
const placeholderOverviewStats = {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
@ -48,31 +46,23 @@ const placeholderDevices: any = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function OverviewScreen({ navigation }: TabScreenProps<'Overview'>) {
|
export default function OverviewScreen({ navigation }: OverviewStackScreenProps<'Overview'>) {
|
||||||
return (
|
return (
|
||||||
<DrawerScreenWrapper>
|
<VirtualizedListWrapper>
|
||||||
<VirtualizedListWrapper>
|
<View style={tw`px-4 mt-4`}>
|
||||||
<View style={tw`px-4`}>
|
{/* Stats */}
|
||||||
{/* Header */}
|
<OverviewStats stats={placeholderOverviewStats} />
|
||||||
<View style={tw`flex-row my-6 justify-center items-center`}>
|
{/* Spacing */}
|
||||||
{/* TODO: Header with a button to open drawer! */}
|
<View style={tw`mt-4`} />
|
||||||
<Button variant="primary" size="lg" onPress={() => navigation.openDrawer()}>
|
{/* Devices */}
|
||||||
<Text style={tw`font-bold text-white`}>Open Drawer</Text>
|
<FlatList
|
||||||
</Button>
|
data={placeholderDevices}
|
||||||
</View>
|
keyExtractor={(item, index) => index.toString()}
|
||||||
{/* Stats */}
|
renderItem={({ item }) => (
|
||||||
<OverviewStats stats={placeholderOverviewStats} />
|
<Device locations={[]} name={item.name} size={item.size} type={item.type} />
|
||||||
<View style={tw`mt-4`} />
|
)}
|
||||||
{/* Devices */}
|
/>
|
||||||
<FlatList
|
</View>
|
||||||
data={placeholderDevices}
|
</VirtualizedListWrapper>
|
||||||
keyExtractor={(item, index) => index.toString()}
|
|
||||||
renderItem={({ item }) => (
|
|
||||||
<Device locations={[]} name={item.name} size={item.size} type={item.type} />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</VirtualizedListWrapper>
|
|
||||||
</DrawerScreenWrapper>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
import type { TabScreenProps } from '../navigation/TabNavigator';
|
import { PhotosStackScreenProps } from '../navigation/tabs/PhotosStack';
|
||||||
|
|
||||||
export default function PhotosScreen({ navigation }: TabScreenProps<'Photos'>) {
|
export default function PhotosScreen({ navigation }: PhotosStackScreenProps<'Photos'>) {
|
||||||
return (
|
return (
|
||||||
<View style={tw`flex-1 items-center justify-center`}>
|
<View style={tw`flex-1 items-center justify-center`}>
|
||||||
<Text style={tw`font-bold text-xl text-white`}>Photos</Text>
|
<Text style={tw`font-bold text-xl text-white`}>Photos</Text>
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
||||||
|
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
import type { TabScreenProps } from '../navigation/TabNavigator';
|
import { SpacesStackScreenProps } from '../navigation/tabs/SpacesStack';
|
||||||
|
|
||||||
export default function SpacesScreen({ navigation }: TabScreenProps<'Spaces'>) {
|
export default function SpacesScreen({ navigation }: SpacesStackScreenProps<'Spaces'>) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={tw`flex-1 items-center justify-center`}>
|
<View style={tw`flex-1 items-center justify-center`}>
|
||||||
<Text style={tw`font-bold text-xl text-white`}>Spaces</Text>
|
<Text style={tw`font-bold text-xl text-white`}>Spaces</Text>
|
||||||
</SafeAreaView>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ import React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import tw from '../lib/tailwind';
|
import tw from '../lib/tailwind';
|
||||||
|
import { SharedScreenProps } from '../navigation/SharedScreens';
|
||||||
|
|
||||||
export default function TagScreen({ navigation, route }: any) {
|
export default function TagScreen({ navigation, route }: SharedScreenProps<'Tag'>) {
|
||||||
const { id } = route.params;
|
const { id } = route.params;
|
||||||
return (
|
return (
|
||||||
<View style={tw`flex-1 items-center justify-center`}>
|
<View style={tw`flex-1 items-center justify-center`}>
|
||||||
|
|
57
apps/mobile/src/screens/modals/Search.tsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
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();
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={tw.style('flex-1', { marginTop: top + 10 })}>
|
||||||
|
{/* Header */}
|
||||||
|
<View style={tw`flex flex-row items-center mx-4`}>
|
||||||
|
{/* Search Input */}
|
||||||
|
<View style={tw`flex-1 bg-gray-550 rounded-md h-9 mr-3`}>
|
||||||
|
<View style={tw`flex flex-row h-full items-center px-3`}>
|
||||||
|
<View style={tw`mr-3`}>
|
||||||
|
{loading ? (
|
||||||
|
<ActivityIndicator size={'small'} color={'white'} />
|
||||||
|
) : (
|
||||||
|
<MagnifyingGlass size={20} weight="light" color={tw.color('gray-300')} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<TextInput
|
||||||
|
placeholder={'Search'}
|
||||||
|
clearButtonMode="never" // can't change the color??
|
||||||
|
underlineColorAndroid="transparent"
|
||||||
|
placeholderTextColor={tw.color('gray-300')}
|
||||||
|
style={tw`text-white flex-1 text-sm`}
|
||||||
|
textContentType={'none'}
|
||||||
|
autoFocus
|
||||||
|
autoCapitalize="none"
|
||||||
|
autoCorrect={false}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{/* Cancel Button */}
|
||||||
|
<Pressable onPress={() => navigation.goBack()}>
|
||||||
|
<Text style={tw`text-primary-500`}>Cancel</Text>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
{/* Content */}
|
||||||
|
<View style={tw`flex-1 items-center mt-8`}>
|
||||||
|
<Button variant="primary" onPress={() => setLoading((v) => !v)}>
|
||||||
|
<Text>Toggle loading</Text>
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SearchScreen;
|
|
@ -6,7 +6,7 @@ import { RootStackScreenProps } from '../../../navigation';
|
||||||
|
|
||||||
export default function SettingsScreen({ navigation }: RootStackScreenProps<'Settings'>) {
|
export default function SettingsScreen({ navigation }: RootStackScreenProps<'Settings'>) {
|
||||||
return (
|
return (
|
||||||
<View style={tw`flex-1`}>
|
<View style={tw`flex-1 items-center justify-center`}>
|
||||||
<Text style={tw`font-bold text-xl text-white`}>Settings</Text>
|
<Text style={tw`font-bold text-xl text-white`}>Settings</Text>
|
||||||
<View style={tw`my-8 h-1 w-4/5`} />
|
<View style={tw`my-8 h-1 w-4/5`} />
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -12,10 +12,6 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
|
||||||
const { hideOnboarding } = useOnboardingStore();
|
const { hideOnboarding } = useOnboardingStore();
|
||||||
|
|
||||||
function onButtonPress() {
|
function onButtonPress() {
|
||||||
// Persist onboarding state only when app in production for now.
|
|
||||||
// if (process.env.NODE_ENV === 'production') {
|
|
||||||
// setItemToStorage('@onboarding', '1');
|
|
||||||
// }
|
|
||||||
setItemToStorage('@onboarding', '1');
|
setItemToStorage('@onboarding', '1');
|
||||||
// TODO: Add a loading indicator to button as this takes a second or so.
|
// TODO: Add a loading indicator to button as this takes a second or so.
|
||||||
hideOnboarding();
|
hideOnboarding();
|
||||||
|
@ -26,8 +22,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<LogoAnimation>
|
<LogoAnimation>
|
||||||
<View style={tw`items-center mt-2`}>
|
<View style={tw`items-center mt-2`}>
|
||||||
{/* TODO: Change this to @sd/assets. */}
|
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-24 h-24`} />
|
||||||
<Image source={require('../../assets/temp/logo.png')} style={tw`w-24 h-24`} />
|
|
||||||
</View>
|
</View>
|
||||||
</LogoAnimation>
|
</LogoAnimation>
|
||||||
{/* Text */}
|
{/* Text */}
|
||||||
|
|
13
apps/mobile/src/stores/useLibraryStore.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import create from 'zustand';
|
||||||
|
|
||||||
|
interface LibraryStore {
|
||||||
|
currentLibraryUuid: string | null;
|
||||||
|
switchLibrary: (id: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useLibraryStore = create<LibraryStore>()((set) => ({
|
||||||
|
currentLibraryUuid: null,
|
||||||
|
switchLibrary: (uuid) => {
|
||||||
|
set((state) => ({ currentLibraryUuid: uuid }));
|
||||||
|
}
|
||||||
|
}));
|
19
apps/mobile/src/stores/useModalStore.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { BottomSheetModal } from '@gorhom/bottom-sheet';
|
||||||
|
import React from 'react';
|
||||||
|
import create from 'zustand';
|
||||||
|
|
||||||
|
import { FilePath } from '../types/bindings';
|
||||||
|
|
||||||
|
interface FileModalState {
|
||||||
|
fileRef: React.RefObject<BottomSheetModal>;
|
||||||
|
data: FilePath | null;
|
||||||
|
setData: (data: FilePath) => void;
|
||||||
|
clearData: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFileModalStore = create<FileModalState>((set) => ({
|
||||||
|
fileRef: React.createRef<BottomSheetModal>(),
|
||||||
|
data: null,
|
||||||
|
setData: (data: FilePath) => set((_) => ({ data })),
|
||||||
|
clearData: () => set((_) => ({ data: null }))
|
||||||
|
}));
|
117
apps/mobile/src/types/bindings.ts
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
// This file was generated by [rspc](https://github.com/oscartbeaumont/rspc). Do not edit this file manually.
|
||||||
|
|
||||||
|
export type Operations = {
|
||||||
|
queries:
|
||||||
|
{ key: ["files.readMetadata", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["jobs.getHistory", LibraryArgs<null>], result: Array<JobReport> } |
|
||||||
|
{ key: ["jobs.getRunning", LibraryArgs<null>], result: Array<JobReport> } |
|
||||||
|
{ key: ["library.get"], result: Array<LibraryConfigWrapped> } |
|
||||||
|
{ key: ["locations.getExplorerDir", LibraryArgs<GetExplorerDirArgs>], result: DirectoryWithContents } |
|
||||||
|
{ key: ["locations.getById", LibraryArgs<number>], result: Location | null } |
|
||||||
|
{ key: ["getNode"], result: NodeState } |
|
||||||
|
{ key: ["version"], result: string } |
|
||||||
|
{ key: ["volumes.get"], result: Array<Volume> } |
|
||||||
|
{ key: ["tags.getFilesForTag", LibraryArgs<number>], result: Tag | null } |
|
||||||
|
{ key: ["tags.get", LibraryArgs<null>], result: Array<Tag> } |
|
||||||
|
{ key: ["library.getStatistics", LibraryArgs<null>], result: Statistics } |
|
||||||
|
{ key: ["locations.get", LibraryArgs<null>], result: Array<Location> },
|
||||||
|
mutations:
|
||||||
|
{ key: ["jobs.generateThumbsForLocation", LibraryArgs<GenerateThumbsForLocationArgs>], result: null } |
|
||||||
|
{ key: ["files.setNote", LibraryArgs<SetNoteArgs>], result: null } |
|
||||||
|
{ key: ["library.create", string], result: null } |
|
||||||
|
{ key: ["library.delete", string], result: null } |
|
||||||
|
{ key: ["files.setFavorite", LibraryArgs<SetFavoriteArgs>], result: null } |
|
||||||
|
{ key: ["locations.update", LibraryArgs<LocationUpdateArgs>], result: null } |
|
||||||
|
{ key: ["tags.update", LibraryArgs<TagUpdateArgs>], result: null } |
|
||||||
|
{ key: ["tags.assign", LibraryArgs<TagAssignArgs>], result: null } |
|
||||||
|
{ key: ["tags.delete", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["library.edit", EditLibraryArgs], result: null } |
|
||||||
|
{ key: ["jobs.identifyUniqueFiles", LibraryArgs<IdentifyUniqueFilesArgs>], result: null } |
|
||||||
|
{ key: ["locations.create", LibraryArgs<string>], result: Location } |
|
||||||
|
{ key: ["locations.quickRescan", LibraryArgs<null>], result: null } |
|
||||||
|
{ key: ["files.delete", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["locations.delete", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["locations.fullRescan", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["tags.create", LibraryArgs<TagCreateArgs>], result: Tag },
|
||||||
|
subscriptions:
|
||||||
|
{ key: ["jobs.newThumbnail", LibraryArgs<null>], result: string } |
|
||||||
|
{ key: ["invalidateQuery"], result: InvalidateOperationEvent }
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface GenerateThumbsForLocationArgs { id: number, path: string }
|
||||||
|
|
||||||
|
export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array<number>, kind: number, column: string | null, value: string, node: Node | null }
|
||||||
|
|
||||||
|
export interface Location { id: number, pub_id: Array<number>, 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<FilePath> | null }
|
||||||
|
|
||||||
|
export interface TagAssignArgs { file_id: number, tag_id: number }
|
||||||
|
|
||||||
|
export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array<File> | null, file_paths: Array<FilePath> | null }
|
||||||
|
|
||||||
|
export interface DirectoryWithContents { directory: FilePath, contents: Array<FilePath> }
|
||||||
|
|
||||||
|
export interface ConfigMetadata { version: string | null }
|
||||||
|
|
||||||
|
export interface TagUpdateArgs { id: number, name: string | null, color: string | null }
|
||||||
|
|
||||||
|
export interface LibraryConfig { version: string | null, name: string, description: string }
|
||||||
|
|
||||||
|
export interface IdentifyUniqueFilesArgs { id: number, path: string }
|
||||||
|
|
||||||
|
export interface FilePath { id: number, is_dir: boolean, location_id: number | null, 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 Album { id: number, pub_id: Array<number>, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array<FileInAlbum> | null }
|
||||||
|
|
||||||
|
export interface SetFavoriteArgs { id: number, favorite: boolean }
|
||||||
|
|
||||||
|
export interface LocationUpdateArgs { id: number, name: string | null }
|
||||||
|
|
||||||
|
export interface Job { id: Array<number>, name: string, node_id: number, action: number, status: number, data: Array<number> | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: 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 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 NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null }
|
||||||
|
|
||||||
|
export interface TagCreateArgs { name: string, color: string }
|
||||||
|
|
||||||
|
export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface Label { id: number, pub_id: Array<number>, name: string | null, date_created: string, date_modified: string, label_files: Array<LabelOnFile> | null }
|
||||||
|
|
||||||
|
export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface EditLibraryArgs { id: string, name: string | null, description: string | null }
|
||||||
|
|
||||||
|
export interface Space { id: number, pub_id: Array<number>, name: string | null, description: string | null, date_created: string, date_modified: string, files: Array<FileInSpace> | null }
|
||||||
|
|
||||||
|
export interface Comment { id: number, pub_id: Array<number>, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null }
|
||||||
|
|
||||||
|
export interface GetExplorerDirArgs { location_id: number, path: string, limit: number }
|
||||||
|
|
||||||
|
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused"
|
||||||
|
|
||||||
|
export interface JobReport { id: string, name: string, data: Array<number> | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number }
|
||||||
|
|
||||||
|
export interface Tag { id: number, pub_id: Array<number>, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array<TagOnFile> | null }
|
||||||
|
|
||||||
|
export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig }
|
||||||
|
|
||||||
|
export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface InvalidateOperationEvent { key: string, arg: any }
|
||||||
|
|
||||||
|
export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string }
|
||||||
|
|
||||||
|
export interface LibraryArgs<T> { library_id: string, arg: T }
|
||||||
|
|
||||||
|
export interface Node { id: number, pub_id: Array<number>, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array<SyncEvent> | null, jobs: Array<Job> | null, Location: Array<Location> | 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<TagOnFile> | null, labels: Array<LabelOnFile> | null, albums: Array<FileInAlbum> | null, spaces: Array<FileInSpace> | null, paths: Array<FilePath> | null, comments: Array<Comment> | null, media_data: MediaData | null | null, key: Key | null | null }
|
||||||
|
|
||||||
|
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 SetNoteArgs { id: number, note: string | null }
|
8
apps/mobile/src/types/declarations.d.ts
vendored
|
@ -4,11 +4,3 @@ declare module '*.svg' {
|
||||||
const content: React.FC<SvgProps>;
|
const content: React.FC<SvgProps>;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This declaration is used by useNavigation, Link, ref etc.
|
|
||||||
declare global {
|
|
||||||
namespace ReactNavigation {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
||||||
interface RootParamList extends RootStackParamList {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sdcore = { path = "../../core", features = [] }
|
sdcore = { path = "../../core", features = [] }
|
||||||
|
rspc = { version = "0.0.4", features = ["axum"] }
|
||||||
axum = "0.5.13"
|
axum = "0.5.13"
|
||||||
tokio = { version = "1.17.0", features = ["sync", "rt-multi-thread", "signal"] }
|
tokio = { version = "1.17.0", features = ["sync", "rt-multi-thread", "signal"] }
|
||||||
tracing = "0.1.35"
|
tracing = "0.1.35"
|
||||||
|
|
|
@ -6,10 +6,13 @@ authors = ["Spacedrive Technology Inc."]
|
||||||
license = "GNU GENERAL PUBLIC LICENSE"
|
license = "GNU GENERAL PUBLIC LICENSE"
|
||||||
repository = "https://github.com/spacedriveapp/spacedrive"
|
repository = "https://github.com/spacedriveapp/spacedrive"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
rust-version = "1.63.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
p2p = [
|
default = ["p2p"]
|
||||||
] # This feature controlls whether the Spacedrive Core contains the Peer to Peer syncing engine (It isn't required for the hosted core so we can disable it).
|
p2p = [] # This feature controlls whether the Spacedrive Core contains the Peer to Peer syncing engine (It isn't required for the hosted core so we can disable it).
|
||||||
|
mobile = [] # This feature allows features to be disabled when the Core is running on mobile.
|
||||||
|
ffmpeg = ["dep:ffmpeg-next"] # This feature controls whether the Spacedrive Core contains functionality which requires FFmpeg.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hostname = "0.3.1"
|
hostname = "0.3.1"
|
||||||
|
@ -32,8 +35,6 @@ prisma-client-rust = { git = "https://github.com/Brendonovich/prisma-client-rust
|
||||||
"sqlite-create-many",
|
"sqlite-create-many",
|
||||||
] }
|
] }
|
||||||
rspc = { version = "0.0.4", features = [
|
rspc = { version = "0.0.4", features = [
|
||||||
"axum",
|
|
||||||
"tauri",
|
|
||||||
"uuid",
|
"uuid",
|
||||||
"chrono",
|
"chrono",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -42,14 +43,13 @@ walkdir = "^2.3.2"
|
||||||
uuid = { version = "1.1.2", features = ["v4", "serde"] }
|
uuid = { version = "1.1.2", features = ["v4", "serde"] }
|
||||||
sysinfo = "0.23.9"
|
sysinfo = "0.23.9"
|
||||||
thiserror = "1.0.30"
|
thiserror = "1.0.30"
|
||||||
core-derive = { path = "./derive" }
|
|
||||||
|
|
||||||
tokio = { version = "1.17.0", features = ["sync", "rt-multi-thread"] }
|
tokio = { version = "1.17.0", features = ["sync", "rt-multi-thread"] }
|
||||||
include_dir = { version = "0.7.2", features = ["glob"] }
|
include_dir = { version = "0.7.2", features = ["glob"] }
|
||||||
async-trait = "^0.1.52"
|
async-trait = "^0.1.52"
|
||||||
image = "0.24.1"
|
image = "0.24.1"
|
||||||
webp = "0.2.2"
|
webp = "0.2.2"
|
||||||
ffmpeg-next = "5.0.3"
|
ffmpeg-next = { version = "5.0.3", optional = true, features = [] }
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
tracing = "0.1.35"
|
tracing = "0.1.35"
|
||||||
tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "core-derive"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
quote = "1.0.18"
|
|
||||||
syn = "1.0.91"
|
|
|
@ -1,42 +0,0 @@
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use quote::quote;
|
|
||||||
use syn::{parse_macro_input, Data, DeriveInput};
|
|
||||||
|
|
||||||
/// This macro must be executed in a file with `PropertyOperationCtx` defined and in the same package as the SyncContext is defined.
|
|
||||||
/// The creates:
|
|
||||||
/// ```rust
|
|
||||||
/// impl PropertyOperation {
|
|
||||||
/// fn apply(operation: PropertyOperationCtx, ctx: SyncContext) {
|
|
||||||
/// match operation.resource {
|
|
||||||
/// PropertyOperation::Tag(method) => method.apply(ctx),
|
|
||||||
/// };
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[proc_macro_derive(PropertyOperationApply)]
|
|
||||||
pub fn property_operation_apply(input: TokenStream) -> TokenStream {
|
|
||||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
|
||||||
|
|
||||||
if let Data::Enum(data) = data {
|
|
||||||
let impls = data.variants.iter().map(|variant| {
|
|
||||||
let variant_ident = &variant.ident;
|
|
||||||
quote! {
|
|
||||||
#ident::#variant_ident(method) => method.apply(ctx),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let expanded = quote! {
|
|
||||||
impl #ident {
|
|
||||||
fn apply(operation: CrdtCtx<PropertyOperation>, ctx: self::engine::SyncContext) {
|
|
||||||
match operation.resource {
|
|
||||||
#(#impls)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TokenStream::from(expanded)
|
|
||||||
} else {
|
|
||||||
panic!("The 'PropertyOperationApply' macro can only be used on enums!");
|
|
||||||
}
|
|
||||||
}
|
|
135
core/index.ts
|
@ -1,118 +1,117 @@
|
||||||
/* eslint-disable */
|
|
||||||
// This file was generated by [rspc](https://github.com/oscartbeaumont/rspc). Do not edit this file manually.
|
// This file was generated by [rspc](https://github.com/oscartbeaumont/rspc). Do not edit this file manually.
|
||||||
|
|
||||||
export type Operations = {
|
export type Operations = {
|
||||||
queries:
|
queries:
|
||||||
{ key: ["getNode"], result: NodeState } |
|
|
||||||
{ key: ["version"], result: string } |
|
|
||||||
{ key: ["tags.getFilesForTag", LibraryArgs<number>], result: Tag | null } |
|
|
||||||
{ key: ["locations.getById", LibraryArgs<number>], result: Location | null } |
|
|
||||||
{ key: ["files.readMetadata", LibraryArgs<number>], result: null } |
|
{ key: ["files.readMetadata", LibraryArgs<number>], result: null } |
|
||||||
{ key: ["locations.get", LibraryArgs<null>], result: Array<Location> } |
|
{ key: ["jobs.getHistory", LibraryArgs<null>], result: Array<JobReport> } |
|
||||||
{ key: ["jobs.getRunning", LibraryArgs<null>], result: Array<JobReport> } |
|
{ key: ["jobs.getRunning", LibraryArgs<null>], result: Array<JobReport> } |
|
||||||
{ key: ["library.get"], result: Array<LibraryConfigWrapped> } |
|
{ key: ["library.get"], result: Array<LibraryConfigWrapped> } |
|
||||||
{ key: ["locations.getExplorerDir", LibraryArgs<GetExplorerDirArgs>], result: DirectoryWithContents } |
|
{ key: ["locations.getExplorerDir", LibraryArgs<GetExplorerDirArgs>], result: DirectoryWithContents } |
|
||||||
|
{ key: ["locations.getById", LibraryArgs<number>], result: Location | null } |
|
||||||
|
{ key: ["getNode"], result: NodeState } |
|
||||||
|
{ key: ["version"], result: string } |
|
||||||
|
{ key: ["volumes.get"], result: Array<Volume> } |
|
||||||
|
{ key: ["tags.getFilesForTag", LibraryArgs<number>], result: Tag | null } |
|
||||||
{ key: ["tags.get", LibraryArgs<null>], result: Array<Tag> } |
|
{ key: ["tags.get", LibraryArgs<null>], result: Array<Tag> } |
|
||||||
{ key: ["jobs.getHistory", LibraryArgs<null>], result: Array<JobReport> } |
|
|
||||||
{ key: ["library.getStatistics", LibraryArgs<null>], result: Statistics } |
|
{ key: ["library.getStatistics", LibraryArgs<null>], result: Statistics } |
|
||||||
{ key: ["volumes.get"], result: Array<Volume> },
|
{ key: ["locations.get", LibraryArgs<null>], result: Array<Location> },
|
||||||
mutations:
|
mutations:
|
||||||
|
{ key: ["jobs.generateThumbsForLocation", LibraryArgs<GenerateThumbsForLocationArgs>], result: null } |
|
||||||
|
{ key: ["files.setNote", LibraryArgs<SetNoteArgs>], result: null } |
|
||||||
|
{ key: ["library.create", string], result: null } |
|
||||||
|
{ key: ["library.delete", string], result: null } |
|
||||||
{ key: ["files.setFavorite", LibraryArgs<SetFavoriteArgs>], result: null } |
|
{ key: ["files.setFavorite", LibraryArgs<SetFavoriteArgs>], result: null } |
|
||||||
{ key: ["tags.assign", LibraryArgs<TagAssignArgs>], result: null } |
|
|
||||||
{ key: ["locations.update", LibraryArgs<LocationUpdateArgs>], result: null } |
|
{ key: ["locations.update", LibraryArgs<LocationUpdateArgs>], result: null } |
|
||||||
|
{ key: ["tags.update", LibraryArgs<TagUpdateArgs>], result: null } |
|
||||||
|
{ key: ["tags.assign", LibraryArgs<TagAssignArgs>], result: null } |
|
||||||
|
{ key: ["tags.delete", LibraryArgs<number>], result: null } |
|
||||||
|
{ key: ["library.edit", EditLibraryArgs], result: null } |
|
||||||
|
{ key: ["jobs.identifyUniqueFiles", LibraryArgs<IdentifyUniqueFilesArgs>], result: null } |
|
||||||
|
{ key: ["locations.create", LibraryArgs<string>], result: Location } |
|
||||||
|
{ key: ["locations.quickRescan", LibraryArgs<null>], result: null } |
|
||||||
|
{ key: ["files.delete", LibraryArgs<number>], result: null } |
|
||||||
{ key: ["locations.delete", LibraryArgs<number>], result: null } |
|
{ key: ["locations.delete", LibraryArgs<number>], result: null } |
|
||||||
{ key: ["locations.fullRescan", LibraryArgs<number>], result: null } |
|
{ key: ["locations.fullRescan", LibraryArgs<number>], result: null } |
|
||||||
{ key: ["tags.delete", LibraryArgs<number>], result: null } |
|
{ key: ["tags.create", LibraryArgs<TagCreateArgs>], result: Tag },
|
||||||
{ key: ["jobs.identifyUniqueFiles", LibraryArgs<IdentifyUniqueFilesArgs>], result: null } |
|
|
||||||
{ key: ["library.delete", string], result: null } |
|
|
||||||
{ key: ["files.delete", LibraryArgs<number>], result: null } |
|
|
||||||
{ key: ["locations.quickRescan", LibraryArgs<null>], result: null } |
|
|
||||||
{ key: ["locations.create", LibraryArgs<string>], result: Location } |
|
|
||||||
{ key: ["files.setNote", LibraryArgs<SetNoteArgs>], result: null } |
|
|
||||||
{ key: ["library.edit", EditLibraryArgs], result: null } |
|
|
||||||
{ key: ["tags.create", LibraryArgs<TagCreateArgs>], result: Tag } |
|
|
||||||
{ key: ["library.create", string], result: null } |
|
|
||||||
{ key: ["jobs.generateThumbsForLocation", LibraryArgs<GenerateThumbsForLocationArgs>], result: null } |
|
|
||||||
{ key: ["tags.update", LibraryArgs<TagUpdateArgs>], result: null },
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
{ key: ["jobs.newThumbnail", LibraryArgs<null>], result: string } |
|
{ key: ["jobs.newThumbnail", LibraryArgs<null>], result: string } |
|
||||||
{ key: ["invalidateQuery"], result: InvalidateOperationEvent }
|
{ key: ["invalidateQuery"], result: InvalidateOperationEvent }
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Tag { id: number, pub_id: Array<number>, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array<TagOnFile> | null }
|
export interface GenerateThumbsForLocationArgs { id: number, path: string }
|
||||||
|
|
||||||
export interface SetFavoriteArgs { id: number, favorite: boolean }
|
export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array<number>, kind: number, column: string | null, value: string, node: Node | null }
|
||||||
|
|
||||||
export interface LibraryConfig { version: string | null, name: string, description: string }
|
|
||||||
|
|
||||||
export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | 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 GetExplorerDirArgs { location_id: number, path: string, limit: number }
|
|
||||||
|
|
||||||
export interface JobReport { id: string, name: string, data: Array<number> | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number }
|
|
||||||
|
|
||||||
export interface Album { id: number, pub_id: Array<number>, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array<FileInAlbum> | null }
|
|
||||||
|
|
||||||
export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null }
|
|
||||||
|
|
||||||
export interface Location { id: number, pub_id: Array<number>, 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<FilePath> | null }
|
export interface Location { id: number, pub_id: Array<number>, 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<FilePath> | null }
|
||||||
|
|
||||||
export interface Label { id: number, pub_id: Array<number>, name: string | null, date_created: string, date_modified: string, label_files: Array<LabelOnFile> | null }
|
export interface TagAssignArgs { file_id: number, tag_id: number }
|
||||||
|
|
||||||
export interface InvalidateOperationEvent { key: string, arg: any }
|
export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array<File> | null, file_paths: Array<FilePath> | null }
|
||||||
|
|
||||||
export interface LibraryArgs<T> { library_id: string, arg: T }
|
|
||||||
|
|
||||||
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 GenerateThumbsForLocationArgs { id: number, path: string }
|
|
||||||
|
|
||||||
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 DirectoryWithContents { directory: FilePath, contents: Array<FilePath> }
|
export interface DirectoryWithContents { directory: FilePath, contents: Array<FilePath> }
|
||||||
|
|
||||||
export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null }
|
export interface ConfigMetadata { version: string | null }
|
||||||
|
|
||||||
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 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<TagOnFile> | null, labels: Array<LabelOnFile> | null, albums: Array<FileInAlbum> | null, spaces: Array<FileInSpace> | null, paths: Array<FilePath> | null, comments: Array<Comment> | null, media_data: MediaData | null | null, key: Key | null | null }
|
export interface LibraryConfig { version: string | null, name: string, description: string }
|
||||||
|
|
||||||
export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string }
|
|
||||||
|
|
||||||
export interface SetNoteArgs { id: number, note: string | null }
|
|
||||||
|
|
||||||
export interface IdentifyUniqueFilesArgs { id: number, path: string }
|
export interface IdentifyUniqueFilesArgs { id: number, path: string }
|
||||||
|
|
||||||
export interface Space { id: number, pub_id: Array<number>, name: string | null, description: string | null, date_created: string, date_modified: string, files: Array<FileInSpace> | null }
|
export interface FilePath { id: number, is_dir: boolean, location_id: number | null, 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 Album { id: number, pub_id: Array<number>, name: string, is_hidden: boolean, date_created: string, date_modified: string, files: Array<FileInAlbum> | null }
|
||||||
|
|
||||||
|
export interface SetFavoriteArgs { id: number, favorite: boolean }
|
||||||
|
|
||||||
export interface LocationUpdateArgs { id: number, name: string | null }
|
export interface LocationUpdateArgs { id: number, name: string | null }
|
||||||
|
|
||||||
export interface Job { id: Array<number>, name: string, node_id: number, action: number, status: number, data: Array<number> | null, task_count: number, completed_task_count: number, date_created: string, date_modified: string, seconds_elapsed: number, nodes: Node | null }
|
export interface Job { id: Array<number>, name: string, node_id: number, action: number, status: number, data: Array<number> | 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 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 FilePath { id: number, is_dir: boolean, location_id: number | null, 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 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 TagCreateArgs { name: string, color: string }
|
|
||||||
|
|
||||||
export interface EditLibraryArgs { id: string, name: string | null, description: string | null }
|
|
||||||
|
|
||||||
export interface TagUpdateArgs { id: number, name: string | null, color: string | null }
|
|
||||||
|
|
||||||
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused"
|
|
||||||
|
|
||||||
export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null }
|
export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null }
|
||||||
|
|
||||||
|
export interface TagCreateArgs { name: string, color: string }
|
||||||
|
|
||||||
|
export interface FileInAlbum { date_created: string, album_id: number, album: Album | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface Label { id: number, pub_id: Array<number>, name: string | null, date_created: string, date_modified: string, label_files: Array<LabelOnFile> | null }
|
||||||
|
|
||||||
|
export interface LabelOnFile { date_created: string, label_id: number, label: Label | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface EditLibraryArgs { id: string, name: string | null, description: string | null }
|
||||||
|
|
||||||
|
export interface Space { id: number, pub_id: Array<number>, name: string | null, description: string | null, date_created: string, date_modified: string, files: Array<FileInSpace> | null }
|
||||||
|
|
||||||
export interface Comment { id: number, pub_id: Array<number>, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null }
|
export interface Comment { id: number, pub_id: Array<number>, content: string, date_created: string, date_modified: string, file_id: number | null, file: File | null | null }
|
||||||
|
|
||||||
|
export interface GetExplorerDirArgs { location_id: number, path: string, limit: number }
|
||||||
|
|
||||||
|
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused"
|
||||||
|
|
||||||
|
export interface JobReport { id: string, name: string, data: Array<number> | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number }
|
||||||
|
|
||||||
|
export interface Tag { id: number, pub_id: Array<number>, name: string | null, color: string | null, total_files: number | null, redundancy_goal: number | null, date_created: string, date_modified: string, tag_files: Array<TagOnFile> | null }
|
||||||
|
|
||||||
export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig }
|
export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig }
|
||||||
|
|
||||||
export interface SyncEvent { id: number, node_id: number, timestamp: string, record_id: Array<number>, kind: number, column: string | null, value: string, node: Node | null }
|
export interface FileInSpace { date_created: string, space_id: number, space: Space | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
export interface ConfigMetadata { version: string | null }
|
export interface InvalidateOperationEvent { key: string, arg: any }
|
||||||
|
|
||||||
|
export interface TagOnFile { date_created: string, tag_id: number, tag: Tag | null, file_id: number, file: File | null }
|
||||||
|
|
||||||
|
export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string }
|
||||||
|
|
||||||
|
export interface LibraryArgs<T> { library_id: string, arg: T }
|
||||||
|
|
||||||
export interface Node { id: number, pub_id: Array<number>, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array<SyncEvent> | null, jobs: Array<Job> | null, Location: Array<Location> | null }
|
export interface Node { id: number, pub_id: Array<number>, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string, sync_events: Array<SyncEvent> | null, jobs: Array<Job> | null, Location: Array<Location> | null }
|
||||||
|
|
||||||
export interface Key { id: number, checksum: string, name: string | null, date_created: string | null, algorithm: number | null, files: Array<File> | null, file_paths: Array<FilePath> | 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<TagOnFile> | null, labels: Array<LabelOnFile> | null, albums: Array<FileInAlbum> | null, spaces: Array<FileInSpace> | null, paths: Array<FilePath> | null, comments: Array<Comment> | null, media_data: MediaData | null | null, key: Key | null | null }
|
||||||
|
|
||||||
|
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 SetNoteArgs { id: number, note: string | null }
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
|
|
||||||
use utils::{InvalidRequests, InvalidateOperationEvent};
|
use utils::{InvalidRequests, InvalidateOperationEvent};
|
||||||
|
|
||||||
pub(crate) type Router = rspc::Router<Ctx>;
|
pub type Router = rspc::Router<Ctx>;
|
||||||
pub(crate) type RouterBuilder = rspc::RouterBuilder<Ctx>;
|
pub(crate) type RouterBuilder = rspc::RouterBuilder<Ctx>;
|
||||||
|
|
||||||
/// Represents an internal core event, these are exposed to client via a rspc subscription.
|
/// Represents an internal core event, these are exposed to client via a rspc subscription.
|
||||||
|
@ -133,5 +133,9 @@ mod tests {
|
||||||
let r = super::mount();
|
let r = super::mount();
|
||||||
r.export_ts(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("./index.ts"))
|
r.export_ts(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("./index.ts"))
|
||||||
.expect("Error exporting rspc Typescript bindings!");
|
.expect("Error exporting rspc Typescript bindings!");
|
||||||
|
r.export_ts(
|
||||||
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../apps/mobile/src/types/bindings.ts"),
|
||||||
|
)
|
||||||
|
.expect("Error exporting rspc Typescript bindings!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use rspc::{internal::specta::DataType, Type};
|
use rspc::{internal::specta::DataType, Type};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -27,6 +31,7 @@ impl InvalidateOperationEvent {
|
||||||
|
|
||||||
/// a request to invalidate a specific resource
|
/// a request to invalidate a specific resource
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) struct InvalidationRequest {
|
pub(crate) struct InvalidationRequest {
|
||||||
pub key: &'static str,
|
pub key: &'static str,
|
||||||
pub arg_ty: DataType,
|
pub arg_ty: DataType,
|
||||||
|
@ -35,6 +40,7 @@ pub(crate) struct InvalidationRequest {
|
||||||
|
|
||||||
/// invalidation request for a specific resource
|
/// invalidation request for a specific resource
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) struct InvalidRequests {
|
pub(crate) struct InvalidRequests {
|
||||||
pub queries: Vec<InvalidationRequest>,
|
pub queries: Vec<InvalidationRequest>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#[cfg(feature = "ffmpeg")]
|
||||||
use ffmpeg_next::format;
|
use ffmpeg_next::format;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
@ -21,9 +22,10 @@ pub struct Stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)] // TODO: Remove this when we start using ffmpeg
|
||||||
pub enum StreamKind {
|
pub enum StreamKind {
|
||||||
// Video(VideoStream),
|
Video(VideoStream),
|
||||||
// Audio(AudioStream),
|
Audio(AudioStream),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -31,6 +33,7 @@ pub struct VideoStream {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
pub aspect_ratio: String,
|
pub aspect_ratio: String,
|
||||||
|
#[cfg(feature = "ffmpeg")]
|
||||||
pub format: format::Pixel,
|
pub format: format::Pixel,
|
||||||
pub bitrate: usize,
|
pub bitrate: usize,
|
||||||
}
|
}
|
||||||
|
@ -38,6 +41,7 @@ pub struct VideoStream {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AudioStream {
|
pub struct AudioStream {
|
||||||
pub channels: u16,
|
pub channels: u16,
|
||||||
|
#[cfg(feature = "ffmpeg")]
|
||||||
pub format: format::Sample,
|
pub format: format::Sample,
|
||||||
pub bitrate: usize,
|
pub bitrate: usize,
|
||||||
pub rate: u32,
|
pub rate: u32,
|
||||||
|
|
|
@ -9,9 +9,7 @@ use tracing_subscriber::{filter::LevelFilter, fmt, prelude::*, EnvFilter};
|
||||||
|
|
||||||
use tokio::{fs, sync::broadcast};
|
use tokio::{fs, sync::broadcast};
|
||||||
|
|
||||||
pub use rspc; // We expose rspc so we can access it in the Desktop app
|
pub mod api;
|
||||||
|
|
||||||
pub(crate) mod api;
|
|
||||||
pub(crate) mod encode;
|
pub(crate) mod encode;
|
||||||
pub(crate) mod file;
|
pub(crate) mod file;
|
||||||
pub(crate) mod job;
|
pub(crate) mod job;
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
use crate::{
|
|
||||||
file::File,
|
|
||||||
library::LibraryContext,
|
|
||||||
prisma::{self, file, tag, tag_on_file},
|
|
||||||
ClientQuery, CoreError, CoreEvent, CoreResponse, LibraryQuery,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use thiserror::Error;
|
|
||||||
use ts_rs::TS;
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
||||||
#[ts(export)]
|
|
||||||
pub struct Tag {
|
|
||||||
pub id: i32,
|
|
||||||
pub pub_id: Uuid,
|
|
||||||
pub name: Option<String>,
|
|
||||||
pub color: Option<String>,
|
|
||||||
|
|
||||||
pub total_files: Option<i32>,
|
|
||||||
pub redundancy_goal: Option<i32>,
|
|
||||||
|
|
||||||
pub date_created: chrono::DateTime<chrono::Utc>,
|
|
||||||
pub date_modified: chrono::DateTime<chrono::Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
||||||
#[ts(export)]
|
|
||||||
pub struct TagOnFile {
|
|
||||||
pub tag_id: i32,
|
|
||||||
pub tag: Option<Tag>,
|
|
||||||
|
|
||||||
pub file_id: i32,
|
|
||||||
pub file: Option<File>,
|
|
||||||
|
|
||||||
pub date_created: chrono::DateTime<chrono::Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<tag::Data> for Tag {
|
|
||||||
fn from(data: tag::Data) -> Self {
|
|
||||||
Self {
|
|
||||||
id: data.id,
|
|
||||||
pub_id: Uuid::from_slice(&data.pub_id).unwrap(),
|
|
||||||
name: data.name,
|
|
||||||
color: data.color,
|
|
||||||
total_files: data.total_files,
|
|
||||||
redundancy_goal: data.redundancy_goal,
|
|
||||||
date_created: data.date_created.into(),
|
|
||||||
date_modified: data.date_modified.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<tag_on_file::Data> for TagOnFile {
|
|
||||||
fn from(data: tag_on_file::Data) -> Self {
|
|
||||||
Self {
|
|
||||||
tag_id: data.tag_id,
|
|
||||||
tag: data.tag.map(|t| (*t).into()),
|
|
||||||
file_id: data.file_id,
|
|
||||||
file: data.file.map(|f| (*f).into()),
|
|
||||||
date_created: data.date_created.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, TS, Debug)]
|
|
||||||
#[ts(export)]
|
|
||||||
pub struct TagWithFiles {
|
|
||||||
pub tag: Tag,
|
|
||||||
pub files_with_tag: Vec<TagOnFile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum TagError {
|
|
||||||
// #[error("Tag not found")]
|
|
||||||
// TagNotFound(i32),
|
|
||||||
#[error("Database error")]
|
|
||||||
DatabaseError(#[from] prisma::QueryError),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn create_tag(
|
|
||||||
ctx: LibraryContext,
|
|
||||||
name: String,
|
|
||||||
color: String,
|
|
||||||
) -> Result<CoreResponse, CoreError> {
|
|
||||||
let created_tag = ctx
|
|
||||||
.db
|
|
||||||
.tag()
|
|
||||||
.create(
|
|
||||||
tag::pub_id::set(Uuid::new_v4().as_bytes().to_vec()),
|
|
||||||
vec![tag::name::set(Some(name)), tag::color::set(Some(color))],
|
|
||||||
)
|
|
||||||
.exec()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::LibraryQuery {
|
|
||||||
library_id: ctx.id,
|
|
||||||
query: LibraryQuery::GetTags,
|
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(CoreResponse::TagCreateResponse(created_tag.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_tag(
|
|
||||||
ctx: LibraryContext,
|
|
||||||
id: i32,
|
|
||||||
name: Option<String>,
|
|
||||||
color: Option<String>,
|
|
||||||
) -> Result<CoreResponse, CoreError> {
|
|
||||||
ctx.db
|
|
||||||
.tag()
|
|
||||||
.find_unique(tag::id::equals(id))
|
|
||||||
.update(vec![tag::name::set(name), tag::color::set(color)])
|
|
||||||
.exec()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::LibraryQuery {
|
|
||||||
library_id: ctx.id,
|
|
||||||
query: LibraryQuery::GetTags,
|
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(CoreResponse::Success(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn tag_assign(
|
|
||||||
ctx: LibraryContext,
|
|
||||||
file_id: i32,
|
|
||||||
tag_id: i32,
|
|
||||||
) -> Result<CoreResponse, CoreError> {
|
|
||||||
ctx.db.tag_on_file().create(
|
|
||||||
tag_on_file::tag::link(tag::UniqueWhereParam::IdEquals(tag_id)),
|
|
||||||
tag_on_file::file::link(file::UniqueWhereParam::IdEquals(file_id)),
|
|
||||||
vec![],
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(CoreResponse::Success(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn tag_delete(ctx: LibraryContext, id: i32) -> Result<CoreResponse, CoreError> {
|
|
||||||
ctx.db
|
|
||||||
.tag()
|
|
||||||
.find_unique(tag::id::equals(id))
|
|
||||||
.delete()
|
|
||||||
.exec()
|
|
||||||
.await?
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::LibraryQuery {
|
|
||||||
library_id: ctx.id,
|
|
||||||
query: LibraryQuery::GetTags,
|
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(CoreResponse::Success(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_files_for_tag(ctx: LibraryContext, id: i32) -> Result<CoreResponse, CoreError> {
|
|
||||||
let tag: Option<Tag> = ctx
|
|
||||||
.db
|
|
||||||
.tag()
|
|
||||||
.find_unique(tag::id::equals(id))
|
|
||||||
.exec()
|
|
||||||
.await?
|
|
||||||
.map(Into::into);
|
|
||||||
|
|
||||||
Ok(CoreResponse::GetTag(tag))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_all_tags(ctx: LibraryContext) -> Result<CoreResponse, CoreError> {
|
|
||||||
let tags: Vec<Tag> = ctx
|
|
||||||
.db
|
|
||||||
.tag()
|
|
||||||
.find_many(vec![])
|
|
||||||
.exec()
|
|
||||||
.await?
|
|
||||||
.into_iter()
|
|
||||||
.map(Into::into)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(CoreResponse::GetTags(tags))
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ pre-push:
|
||||||
parallel: true
|
parallel: true
|
||||||
commands:
|
commands:
|
||||||
type-check:
|
type-check:
|
||||||
glob: "*.{ts,tsx}"
|
glob: '*.{ts,tsx}'
|
||||||
run: pnpm typecheck
|
run: pnpm typecheck
|
||||||
lint:
|
lint:
|
||||||
glob: '*.{ts,tsx}'
|
glob: '*.{ts,tsx}'
|
||||||
|
@ -22,7 +22,5 @@ pre-push:
|
||||||
run: cargo clippy --package spacedrive -- -D warnings
|
run: cargo clippy --package spacedrive -- -D warnings
|
||||||
rust-lint-core:
|
rust-lint-core:
|
||||||
run: cargo clippy --package sdcore --lib -- -D warnings
|
run: cargo clippy --package sdcore --lib -- -D warnings
|
||||||
rust-lint-core-derive:
|
|
||||||
run: cargo clippy --package core-derive --lib -- -D warnings
|
|
||||||
rust-lint-server:
|
rust-lint-server:
|
||||||
run: cargo clippy --package server -- -D warnings
|
run: cargo clippy --package server -- -D warnings
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prep": "pnpm db:gen",
|
"prep": "pnpm db:gen && pnpm core codegen",
|
||||||
|
"build": "turbo run build",
|
||||||
|
"landing-web": "turbo run dev --parallel --filter=@sd/landing --filter=@sd/web",
|
||||||
"db:migrate": "pnpm core prisma migrate dev",
|
"db:migrate": "pnpm core prisma migrate dev",
|
||||||
"db:gen": "pnpm core prisma generate",
|
"db:gen": "pnpm core prisma generate",
|
||||||
"format": "prettier --config .prettierrc.cli.js --write \"**/*.{ts,tsx,html,scss,json,yml,md}\"",
|
"format": "prettier --config .prettierrc.cli.js --write \"**/*.{ts,tsx,html,scss,json,yml,md}\"",
|
||||||
|
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
15
packages/assets/svgs/folder-white.svg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_0_3)" />
|
||||||
|
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_0_3)" />
|
||||||
|
<path d="M0.582787 99.2818L140.005 100" stroke="white" stroke-opacity="0.03" stroke-width="2" />
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_0_3" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#E7E6E6" />
|
||||||
|
<stop offset="1" stop-color="white" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_0_3" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white" />
|
||||||
|
<stop offset="1" stop-color="#EAEAEA" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
16
packages/assets/svgs/folder.svg
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395V3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_13_627)" />
|
||||||
|
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_13_627)" />
|
||||||
|
<line x1="0.424076" y1="97.8758" x2="139.002" y2="98.1576" stroke="black" stroke-opacity="0.13" stroke-width="1.68485" />
|
||||||
|
<line x1="0.582788" y1="99.2818" x2="140.005" y2="100" stroke="white" stroke-opacity="0.03" stroke-width="2" />
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_13_627" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#2D82E7" />
|
||||||
|
<stop offset="1" stop-color="#083258" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_13_627" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#319DCB" />
|
||||||
|
<stop offset="1" stop-color="#264BA8" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -18,8 +18,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rspc/client": "^0.0.5",
|
"@rspc/client": "^0.0.5",
|
||||||
"@sd/config": "workspace:*",
|
|
||||||
"@sd/core": "workspace:*",
|
"@sd/core": "workspace:*",
|
||||||
|
"@sd/config": "workspace:*",
|
||||||
"@sd/interface": "workspace:*",
|
"@sd/interface": "workspace:*",
|
||||||
"@tanstack/react-query": "^4.0.10",
|
"@tanstack/react-query": "^4.0.10",
|
||||||
"eventemitter3": "^4.0.7",
|
"eventemitter3": "^4.0.7",
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_0_3)"/>
|
|
||||||
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_0_3)"/>
|
|
||||||
<path d="M0.582787 99.2818L140.005 100" stroke="white" stroke-opacity="0.03" stroke-width="2"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_0_3" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#E7E6E6"/>
|
|
||||||
<stop offset="1" stop-color="white"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear_0_3" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="white"/>
|
|
||||||
<stop offset="1" stop-color="#EAEAEA"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,16 +0,0 @@
|
||||||
<svg style="width: 100%; height: auto;" viewBox="0 0 141 110" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 15.5273C0 7.15264 6.78899 0.363647 15.1636 0.363647H35.9094C39.3671 0.363647 42.7035 1.63836 45.2803 3.94395V3.94395C47.8571 6.24955 51.1935 7.52425 54.6512 7.52425H123.836C132.211 7.52425 139 14.3132 139 22.6879V23.9515C139 32.3262 132.211 39.1152 123.836 39.1152H15.1636C6.78899 39.1152 0 32.3262 0 23.9515V15.5273Z" fill="url(#paint0_linear_13_627)"/>
|
|
||||||
<path d="M0 29.8485C0 23.8001 4.90316 18.897 10.9515 18.897H128.048C134.097 18.897 139 23.8001 139 29.8485V94.7152C139 103.09 132.211 109.879 123.836 109.879H15.1636C6.78899 109.879 0 103.09 0 94.7152V29.8485Z" fill="url(#paint1_linear_13_627)"/>
|
|
||||||
<line x1="0.424076" y1="97.8758" x2="139.002" y2="98.1576" stroke="black" stroke-opacity="0.13" stroke-width="1.68485"/>
|
|
||||||
<line x1="0.582788" y1="99.2818" x2="140.005" y2="100" stroke="white" stroke-opacity="0.03" stroke-width="2"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_13_627" x1="69.5" y1="0.363647" x2="69.5" y2="39.1152" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#2D82E7"/>
|
|
||||||
<stop offset="1" stop-color="#083258"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="paint1_linear_13_627" x1="69.5" y1="18.897" x2="69.5" y2="109.879" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#319DCB"/>
|
|
||||||
<stop offset="1" stop-color="#264BA8"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.4 KiB |
|
@ -1,10 +1,10 @@
|
||||||
|
import { ReactComponent as Folder } from '@sd/assets/svgs/folder.svg';
|
||||||
import { LocationContext } from '@sd/client';
|
import { LocationContext } from '@sd/client';
|
||||||
import { FilePath } from '@sd/core';
|
import { FilePath } from '@sd/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
|
||||||
import icons from '../../assets/icons';
|
import icons from '../../assets/icons';
|
||||||
import { ReactComponent as Folder } from '../../assets/svg/folder.svg';
|
|
||||||
import FileThumb from './FileThumb';
|
import FileThumb from './FileThumb';
|
||||||
|
|
||||||
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
import folderWhiteSvg from '@sd/assets/svgs/folder-white.svg';
|
||||||
|
import folderSvg from '@sd/assets/svgs/folder.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import folderWhiteSvg from '../../assets/svg/folder-white.svg';
|
|
||||||
import folderSvg from '../../assets/svg/folder.svg';
|
|
||||||
|
|
||||||
interface FolderProps {
|
interface FolderProps {
|
||||||
/**
|
/**
|
||||||
* Append additional classes to the underlying SVG
|
* Append additional classes to the underlying SVG
|
||||||
|
|
|
@ -83,6 +83,7 @@ importers:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@heroicons/react': ^1.0.6
|
'@heroicons/react': ^1.0.6
|
||||||
'@icons-pack/react-simple-icons': ^5.2.0
|
'@icons-pack/react-simple-icons': ^5.2.0
|
||||||
|
'@sd/assets': link:../../packages/assets
|
||||||
'@sd/config': link:../../packages/config
|
'@sd/config': link:../../packages/config
|
||||||
'@sd/interface': link:../../packages/interface
|
'@sd/interface': link:../../packages/interface
|
||||||
'@sd/ui': link:../../packages/ui
|
'@sd/ui': link:../../packages/ui
|
||||||
|
@ -123,6 +124,7 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@heroicons/react': 1.0.6_react@18.2.0
|
'@heroicons/react': 1.0.6_react@18.2.0
|
||||||
'@icons-pack/react-simple-icons': 5.2.0_react@18.2.0
|
'@icons-pack/react-simple-icons': 5.2.0_react@18.2.0
|
||||||
|
'@sd/assets': link:../../packages/assets
|
||||||
'@sd/interface': link:../../packages/interface
|
'@sd/interface': link:../../packages/interface
|
||||||
'@sd/ui': link:../../packages/ui
|
'@sd/ui': link:../../packages/ui
|
||||||
'@tryghost/content-api': 1.11.0
|
'@tryghost/content-api': 1.11.0
|
||||||
|
@ -2113,8 +2115,8 @@ packages:
|
||||||
'@cspell/dict-docker': 1.1.1
|
'@cspell/dict-docker': 1.1.1
|
||||||
'@cspell/dict-dotnet': 2.0.1
|
'@cspell/dict-dotnet': 2.0.1
|
||||||
'@cspell/dict-elixir': 2.0.1
|
'@cspell/dict-elixir': 2.0.1
|
||||||
'@cspell/dict-en-gb': 1.1.33
|
|
||||||
'@cspell/dict-en_us': 2.3.0
|
'@cspell/dict-en_us': 2.3.0
|
||||||
|
'@cspell/dict-en-gb': 1.1.33
|
||||||
'@cspell/dict-filetypes': 2.1.1
|
'@cspell/dict-filetypes': 2.1.1
|
||||||
'@cspell/dict-fonts': 2.0.1
|
'@cspell/dict-fonts': 2.0.1
|
||||||
'@cspell/dict-fullstack': 2.0.6
|
'@cspell/dict-fullstack': 2.0.6
|
||||||
|
@ -6052,7 +6054,7 @@ packages:
|
||||||
'@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.18.9
|
'@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.18.9
|
||||||
magic-string: 0.26.2
|
magic-string: 0.26.2
|
||||||
react-refresh: 0.14.0
|
react-refresh: 0.14.0
|
||||||
vite: 3.0.3_sass@1.54.0
|
vite: 3.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
@ -17606,6 +17608,7 @@ packages:
|
||||||
/unified/9.2.0:
|
/unified/9.2.0:
|
||||||
resolution: {integrity: sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==}
|
resolution: {integrity: sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@types/unist': 2.0.6
|
||||||
bail: 1.0.5
|
bail: 1.0.5
|
||||||
extend: 3.0.2
|
extend: 3.0.2
|
||||||
is-buffer: 2.0.5
|
is-buffer: 2.0.5
|
||||||
|
@ -18095,7 +18098,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 4.2.1
|
'@rollup/pluginutils': 4.2.1
|
||||||
'@svgr/core': 6.3.1
|
'@svgr/core': 6.3.1
|
||||||
vite: 3.0.3_sass@1.54.0
|
vite: 3.0.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -18160,7 +18163,6 @@ packages:
|
||||||
rollup: 2.77.1
|
rollup: 2.77.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vite/3.0.3_sass@1.54.0:
|
/vite/3.0.3_sass@1.54.0:
|
||||||
resolution: {integrity: sha512-sDIpIcl3mv1NUaSzZwiXGEy1ZoWwwC2vkxUHY6yiDacR6zf//ZFuBJrozO62gedpE43pmxnLATNR5IYUdAEkMQ==}
|
resolution: {integrity: sha512-sDIpIcl3mv1NUaSzZwiXGEy1ZoWwwC2vkxUHY6yiDacR6zf//ZFuBJrozO62gedpE43pmxnLATNR5IYUdAEkMQ==}
|
||||||
|
@ -18188,6 +18190,7 @@ packages:
|
||||||
sass: 1.54.0
|
sass: 1.54.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/vm-browserify/1.1.2:
|
/vm-browserify/1.1.2:
|
||||||
resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
|
resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
|
||||||
|
|