[ENG-1116] Distinct job manager for library (#1363)

Done
This commit is contained in:
Ericson "Fogo" Soares
2023-09-21 08:10:56 -03:00
committed by GitHub
parent 394d90af68
commit 5f5cd60dd2
168 changed files with 276 additions and 364 deletions

View File

@@ -15,12 +15,12 @@ jobs:
if: ${{ runner.os == 'Linux' }}
uses: easimon/maximize-build-space@master
with:
remove-codeql: "true"
remove-dotnet: "true"
remove-haskell: "true"
remove-android: "true"
overprovision-lvm: "true"
remove-docker-images: "true"
remove-codeql: 'true'
remove-dotnet: 'true'
remove-haskell: 'true'
remove-android: 'true'
overprovision-lvm: 'true'
remove-docker-images: 'true'
- name: Checkout repository
uses: actions/checkout@v3
@@ -56,7 +56,7 @@ jobs:
tags: ${{ steps.image_info.outputs.tag }} ${{ github.event_name == 'release' && 'production' || 'staging' }}
archs: amd64
image: ${{ steps.image_info.outputs.name }}
layers: "false"
layers: 'false'
context: ./apps/server/docker
build-args: |
REPO=${{ steps.image_info.outputs.repo }}

View File

@@ -8,7 +8,7 @@
"start": "expo start --dev-client",
"android": "expo run:android",
"ios": "expo run:ios",
"prebuild": "expo prebuild",
"prebuild": "expo prebuild",
"xcode": "open ios/Spacedrive.xcworkspace",
"android-studio": "open -a '/Applications/Android Studio.app' ./android",
"lint": "eslint src --cache",

View File

@@ -1,7 +1,6 @@
import { MotiView } from 'moti';
import { memo } from 'react';
import { View } from 'react-native';
import { tw } from '~/lib/tailwind';
type ProgressBarProps = {

View File

@@ -7,7 +7,6 @@ import Animated, {
useSharedValue,
withTiming
} from 'react-native-reanimated';
import Layout from '~/constants/Layout';
type MotiViewProps = PropsWithChildren<ViewProps>;

View File

@@ -5,10 +5,10 @@ import { CheckCircle, Gear } from 'phosphor-react-native';
import { useRef } from 'react';
import { Image, Platform, Pressable, Text, View } from 'react-native';
import { JobManagerContextProvider, useLibraryQuery } from '@sd/client';
import Layout from '~/constants/Layout';
import { tw, twStyle } from '~/lib/tailwind';
import { getStackNameFromState } from '~/utils/nav';
import { PulseAnimation } from '../animation/lottie';
import { ModalRef } from '../layout/Modal';
import { JobManagerModal } from '../modal/job/JobManagerModal';

View File

@@ -5,9 +5,9 @@ import { CaretRight, Gear, Lock, Plus } from 'phosphor-react-native';
import { useEffect, useRef, useState } from 'react';
import { Alert, Pressable, Text, View } from 'react-native';
import { useClientContext } from '@sd/client';
import { tw, twStyle } from '~/lib/tailwind';
import { currentLibraryStore } from '~/utils/nav';
import { AnimatedHeight } from '../animation/layout';
import { ModalRef } from '../layout/Modal';
import CreateLibraryModal from '../modal/CreateLibraryModal';

View File

@@ -3,9 +3,9 @@ import { useNavigation } from '@react-navigation/native';
import { useRef } from 'react';
import { Pressable, Text, View } from 'react-native';
import { useLibraryQuery } from '@sd/client';
import { ModalRef } from '~/components/layout/Modal';
import { tw, twStyle } from '~/lib/tailwind';
import FolderIcon from '../icons/FolderIcon';
import CollapsibleView from '../layout/CollapsibleView';
import ImportModal from '../modal/ImportModal';

View File

@@ -3,9 +3,9 @@ import { useNavigation } from '@react-navigation/native';
import { useRef } from 'react';
import { ColorValue, Pressable, Text, View } from 'react-native';
import { useLibraryQuery } from '@sd/client';
import { ModalRef } from '~/components/layout/Modal';
import { tw, twStyle } from '~/lib/tailwind';
import CollapsibleView from '../layout/CollapsibleView';
import CreateTagModal from '../modal/tag/CreateTagModal';

View File

@@ -4,13 +4,13 @@ import { Rows, SquaresFour } from 'phosphor-react-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { isPath, type ExplorerItem } from '@sd/client';
import SortByMenu from '~/components/menu/SortByMenu';
import Layout from '~/constants/Layout';
import { tw } from '~/lib/tailwind';
import { type SharedScreenProps } from '~/navigation/SharedScreens';
import { getExplorerStore } from '~/stores/explorerStore';
import { useActionsModalStore } from '~/stores/modalStore';
import FileItem from './FileItem';
import FileRow from './FileRow';

View File

@@ -1,9 +1,9 @@
import { Text, View } from 'react-native';
import { ExplorerItem, getItemFilePath } from '@sd/client';
import Layout from '~/constants/Layout';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
import FileThumb from './FileThumb';
type FileItemProps = {

View File

@@ -1,9 +1,9 @@
import React from 'react';
import { Text, View } from 'react-native';
import { ExplorerItem, getItemFilePath } from '@sd/client';
import { tw, twStyle } from '~/lib/tailwind';
import { getExplorerStore } from '~/stores/explorerStore';
import FileThumb from './FileThumb';
type FileRowProps = {

View File

@@ -9,8 +9,8 @@ import {
isDarkTheme,
type ExplorerItem
} from '@sd/client';
import { flattenThumbnailKey, useExplorerStore } from '~/stores/explorerStore';
import { tw } from '../../lib/tailwind';
export const getThumbnailUrlByThumbKey = (thumbKey: string[]) =>

View File

@@ -8,7 +8,6 @@ import {
isPath,
useLibraryQuery
} from '@sd/client';
import { InfoPill, PlaceholderPill } from '~/components/primitive/InfoPill';
import { tw, twStyle } from '~/lib/tailwind';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import WheelColorPicker from 'react-native-wheel-color-picker';
import { tw } from '~/lib/tailwind';
type ColorPickerProps = {

View File

@@ -3,7 +3,6 @@ import { cva, VariantProps } from 'class-variance-authority';
import { Eye, EyeSlash } from 'phosphor-react-native';
import { useState } from 'react';
import { Pressable, TextInputProps as RNTextInputProps, TextInput, View } from 'react-native';
import { tw, twStyle } from '~/lib/tailwind';
const input = cva(['rounded-md border text-sm leading-tight shadow-sm'], {

View File

@@ -1,6 +1,5 @@
import { FC } from 'react';
import { Switch as RNSwitch, SwitchProps, Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
export const Switch: FC<SwitchProps> = ({ ...props }) => {

View File

@@ -5,7 +5,6 @@ import { MotiView } from 'moti';
import { List } from 'phosphor-react-native';
import { Pressable, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { tw, twStyle } from '~/lib/tailwind';
// Default header with search bar and button to open drawer

View File

@@ -11,8 +11,8 @@ import {
import { memo } from 'react';
import { View, ViewStyle } from 'react-native';
import { JobProgressEvent, JobReport, useJobInfo } from '@sd/client';
import { tw } from '~/lib/tailwind';
import { ProgressBar } from '../animation/ProgressBar';
import JobContainer from './JobContainer';

View File

@@ -2,7 +2,6 @@ import { Icon } from 'phosphor-react-native';
import { Fragment } from 'react';
import { Image, Text, View, ViewStyle } from 'react-native';
import { TextItems } from '@sd/client';
import { styled, tw, twStyle } from '~/lib/tailwind';
type JobContainerProps = {

View File

@@ -13,8 +13,8 @@ import {
useLibraryMutation,
useTotalElapsedTimeText
} from '@sd/client';
import { tw } from '~/lib/tailwind';
import { AnimatedHeight } from '../animation/layout';
import { ProgressBar } from '../animation/ProgressBar';
import { Button } from '../primitive/Button';

View File

@@ -1,6 +1,5 @@
import { Text, View, ViewStyle } from 'react-native';
import { getPasswordStrength } from '@sd/client';
import { tw, twStyle } from '~/lib/tailwind';
// NOTE: Lazy load this component.

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { View, ViewProps } from 'react-native';
import { twStyle } from '~/lib/tailwind';
type CardProps = {

View File

@@ -2,8 +2,8 @@ import { MotiView } from 'moti';
import { CaretRight } from 'phosphor-react-native';
import { PropsWithChildren, useReducer } from 'react';
import { Pressable, StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native';
import { tw } from '~/lib/tailwind';
import { AnimatedHeight } from '../animation/layout';
type CollapsibleViewProps = PropsWithChildren<{

View File

@@ -11,9 +11,9 @@ import {
import { X } from 'phosphor-react-native';
import { forwardRef, ReactNode } from 'react';
import { Pressable, Text, View } from 'react-native';
import useForwardedRef from '~/hooks/useForwardedRef';
import { tw } from '~/lib/tailwind';
import { Button } from '../primitive/Button';
const ModalBackdrop = (props: BottomSheetBackdropProps) => (

View File

@@ -1,7 +1,6 @@
import { ArrowDown, ArrowUp } from 'phosphor-react-native';
import { useState } from 'react';
import { Text, View } from 'react-native';
import { Menu, MenuItem } from '~/components/primitive/Menu';
import { tw } from '~/lib/tailwind';

View File

@@ -2,7 +2,6 @@ import { useQueryClient } from '@tanstack/react-query';
import { forwardRef, useState } from 'react';
import { Text, View } from 'react-native';
import { useBridgeMutation, usePlausibleEvent } from '@sd/client';
import { ModalInput } from '~/components/form/Input';
import { Modal, ModalRef } from '~/components/layout/Modal';
import { Button } from '~/components/primitive/Button';

View File

@@ -2,7 +2,6 @@ import { forwardRef, useCallback } from 'react';
import { Alert, Text, View } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import { useLibraryMutation } from '@sd/client';
import { Modal, ModalRef } from '~/components/layout/Modal';
import { Button } from '~/components/primitive/Button';
import useForwardedRef from '~/hooks/useForwardedRef';

View File

@@ -1,7 +1,6 @@
import { useQueryClient } from '@tanstack/react-query';
import { useRef } from 'react';
import { useBridgeMutation, usePlausibleEvent } from '@sd/client';
import { ConfirmModal, ModalRef } from '~/components/layout/Modal';
type Props = {

View File

@@ -1,6 +1,5 @@
import { useRef } from 'react';
import { useLibraryMutation, usePlausibleEvent } from '@sd/client';
import { ConfirmModal, ModalRef } from '~/components/layout/Modal';
type Props = {

View File

@@ -1,6 +1,5 @@
import { useRef } from 'react';
import { useLibraryMutation, usePlausibleEvent } from '@sd/client';
import { ConfirmModal, ModalRef } from '~/components/layout/Modal';
type Props = {

View File

@@ -13,13 +13,13 @@ import {
import { PropsWithChildren, useRef } from 'react';
import { Pressable, Text, View, ViewStyle } from 'react-native';
import { byteSize, getItemFilePath, getItemObject } from '@sd/client';
import FileThumb from '~/components/explorer/FileThumb';
import FavoriteButton from '~/components/explorer/sections/FavoriteButton';
import InfoTagPills from '~/components/explorer/sections/InfoTagPills';
import { Modal, ModalRef } from '~/components/layout/Modal';
import { tw, twStyle } from '~/lib/tailwind';
import { useActionsModalStore } from '~/stores/modalStore';
import FileInfoModal from './FileInfoModal';
type ActionsContainerProps = PropsWithChildren<{

View File

@@ -17,7 +17,6 @@ import {
useLibraryQuery,
type ExplorerItem
} from '@sd/client';
import FileThumb from '~/components/explorer/FileThumb';
import InfoTagPills from '~/components/explorer/sections/InfoTagPills';
import { Modal, ModalScrollView, type ModalRef } from '~/components/layout/Modal';

View File

@@ -1,7 +1,7 @@
import { forwardRef, useMemo } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { forwardRef } from 'react';
import { FlatList, Text, View } from 'react-native';
import { useBridgeQuery, useJobProgress } from '@sd/client';
import { useJobProgress, useLibraryQuery } from '@sd/client';
import JobGroup from '~/components/job/JobGroup';
import { Modal, ModalRef } from '~/components/layout/Modal';
import { tw } from '~/lib/tailwind';
@@ -11,18 +11,10 @@ import { tw } from '~/lib/tailwind';
// - Add clear all jobs button
export const JobManagerModal = forwardRef<ModalRef, unknown>((_, ref) => {
const jobGroupsById = useBridgeQuery(['jobs.reports']);
// TODO: Currently we're only clustering togheter all job reports from all libraries without any distinction.
// TODO: We should probably cluster them by library in the job manager UI
const jobGroups = useMemo(() => {
if (!jobGroupsById.data) return [];
return Object.values(jobGroupsById.data).flat();
}, [jobGroupsById.data]);
const progress = useJobProgress(jobGroups);
const queryClient = useQueryClient();
const jobGroups = useLibraryQuery(['jobs.reports']);
const progress = useJobProgress(jobGroups.data);
// const clearAllJobs = useLibraryMutation(['jobs.clearAll'], {
// onError: () => {
// // TODO: Show error toast
@@ -35,7 +27,7 @@ export const JobManagerModal = forwardRef<ModalRef, unknown>((_, ref) => {
return (
<Modal ref={ref} snapPoints={['60']} title="Recent Jobs" showCloseButton>
<FlatList
data={jobGroups}
data={jobGroups.data}
style={tw`flex-1`}
keyExtractor={(i) => i.id}
contentContainerStyle={tw`mt-4`}

View File

@@ -3,7 +3,6 @@ import { forwardRef, useEffect, useState } from 'react';
import { Pressable, Text, View } from 'react-native';
import ColorPicker from 'react-native-wheel-color-picker';
import { useLibraryMutation, usePlausibleEvent } from '@sd/client';
import { FadeInAnimation } from '~/components/animation/layout';
import { ModalInput } from '~/components/form/Input';
import { Modal, ModalRef } from '~/components/layout/Modal';

View File

@@ -2,7 +2,6 @@ import { useQueryClient } from '@tanstack/react-query';
import { forwardRef, useEffect, useState } from 'react';
import { Pressable, Text, View } from 'react-native';
import { Tag, useLibraryMutation } from '@sd/client';
import { FadeInAnimation } from '~/components/animation/layout';
import ColorPicker from '~/components/form/ColorPicker';
import { Input } from '~/components/form/Input';

View File

@@ -2,7 +2,6 @@ import { FC, useEffect, useState } from 'react';
import { ScrollView, Text, View } from 'react-native';
import RNFS from 'react-native-fs';
import { byteSize, Statistics, useLibraryQuery } from '@sd/client';
import useCounter from '~/hooks/useCounter';
import { tw, twStyle } from '~/lib/tailwind';

View File

@@ -2,7 +2,6 @@ import { cva, VariantProps } from 'class-variance-authority';
import { MotiPressable, MotiPressableProps } from 'moti/interactions';
import { FC, useMemo } from 'react';
import { Pressable, PressableProps, View, ViewProps } from 'react-native';
import { twStyle } from '~/lib/tailwind';
const button = cva(['items-center justify-center rounded-md border shadow-sm'], {

View File

@@ -1,5 +1,4 @@
import { View } from 'react-native';
import { styled } from '~/lib/tailwind';
export const Divider = styled(View, 'bg-app-line my-1 h-[1px] w-full');

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, TextStyle, View, ViewStyle } from 'react-native';
import { twStyle } from '~/lib/tailwind';
type Props = {

View File

@@ -8,7 +8,6 @@ import {
Menu as PMenu,
renderers
} from 'react-native-popup-menu';
import { tw } from '~/lib/tailwind';
type MenuProps = {

View File

@@ -1,6 +1,5 @@
import { PropsWithChildren } from 'react';
import { Text, View } from 'react-native';
import { styled, tw } from '~/lib/tailwind';
type SettingsContainerProps = PropsWithChildren<{

View File

@@ -1,6 +1,5 @@
import { CaretRight, Icon } from 'phosphor-react-native';
import { Pressable, Text, View, ViewStyle } from 'react-native';
import { tw, twStyle } from '~/lib/tailwind';
type SettingsItemProps = {

View File

@@ -3,7 +3,6 @@ import { Appearance, NativeEventSubscription } from 'react-native';
import { useDeviceContext } from 'twrnc';
import { subscribe } from 'valtio';
import { getThemeStore } from '@sd/client';
import { changeTwTheme, tw } from '~/lib/tailwind';
export function useTheme() {

View File

@@ -1,9 +1,9 @@
import { createDrawerNavigator, DrawerScreenProps } from '@react-navigation/drawer';
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
import { StackScreenProps } from '@react-navigation/stack';
import DrawerContent from '~/components/drawer/DrawerContent';
import { tw } from '~/lib/tailwind';
import type { RootStackParamList } from '.';
import type { TabParamList } from './TabNavigator';
import TabNavigator from './TabNavigator';

View File

@@ -1,5 +1,4 @@
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import { OnboardingContext, useContextValue } from '~/screens/onboarding/context';
import CreatingLibraryScreen from '~/screens/onboarding/CreatingLibrary';
import GetStartedScreen from '~/screens/onboarding/GetStarted';

View File

@@ -1,5 +1,4 @@
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import { tw } from '~/lib/tailwind';
import AppearanceSettingsScreen from '~/screens/settings/client/AppearanceSettings';
import ExtensionsSettingsScreen from '~/screens/settings/client/ExtensionsSettings';

View File

@@ -4,7 +4,6 @@ import {
StackNavigationOptions,
StackScreenProps
} from '@react-navigation/stack';
import LocationScreen from '~/screens/Location';
import TagScreen from '~/screens/Tag';

View File

@@ -1,8 +1,8 @@
import { BottomTabScreenProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
import { Broadcast, CirclesFour, Planet } from 'phosphor-react-native';
import { tw } from '~/lib/tailwind';
import type { HomeDrawerScreenProps } from './DrawerNavigator';
import OverviewStack, { OverviewStackParamList } from './tabs/OverviewStack';
import SpacedropStack, { SpacedropStackParamList } from './tabs/SpacedropStack';

View File

@@ -1,9 +1,9 @@
import { NavigatorScreenParams } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import { tw } from '~/lib/tailwind';
import NotFoundScreen from '~/screens/NotFound';
import SearchScreen from '~/screens/Search';
import type { DrawerNavParamList } from './DrawerNavigator';
import DrawerNavigator from './DrawerNavigator';
import SettingsNavigator, { SettingsStackParamList } from './SettingsNavigator';

View File

@@ -1,8 +1,8 @@
import { CompositeScreenProps } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import Header from '~/components/header/Header';
import { tw } from '~/lib/tailwind';
import OverviewScreen from '../../screens/Overview';
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
import { TabScreenProps } from '../TabNavigator';

View File

@@ -1,9 +1,9 @@
import { CompositeScreenProps } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import Header from '~/components/header/Header';
import { tw } from '~/lib/tailwind';
import SpacedropScreen from '~/screens/Spacedrop';
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
import { TabScreenProps } from '../TabNavigator';

View File

@@ -1,8 +1,8 @@
import { CompositeScreenProps } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';
import Header from '~/components/header/Header';
import { tw } from '~/lib/tailwind';
import SpacesScreen from '../../screens/Spaces';
import { SharedScreens, SharedScreensParamList } from '../SharedScreens';
import { TabScreenProps } from '../TabNavigator';

View File

@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { useLibraryQuery } from '@sd/client';
import Explorer from '~/components/explorer/Explorer';
import { SharedScreenProps } from '~/navigation/SharedScreens';
import { getExplorerStore } from '~/stores/explorerStore';

View File

@@ -1,5 +1,4 @@
import { Text, TouchableOpacity, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { RootStackScreenProps } from '~/navigation';

View File

@@ -1,5 +1,4 @@
import { View } from 'react-native';
import VirtualizedListWrapper from '~/components/layout/VirtualizedListWrapper';
import OverviewStats from '~/components/overview/OverviewStats';
import { tw } from '~/lib/tailwind';

View File

@@ -3,7 +3,6 @@ import { Suspense, useDeferredValue, useMemo, useState } from 'react';
import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { getExplorerItemData, useLibraryQuery } from '@sd/client';
import Explorer from '~/components/explorer/Explorer';
import { tw, twStyle } from '~/lib/tailwind';
import { RootStackScreenProps } from '~/navigation';

View File

@@ -2,7 +2,6 @@ import { GoogleDrive, iCloud, Mega } from '@sd/assets/images';
import { DeviceMobile, Icon, Laptop, User } from 'phosphor-react-native';
import { Alert, Image, ImageSourcePropType, Pressable, ScrollView, Text, View } from 'react-native';
import { Polygon, Svg } from 'react-native-svg';
import { InfoPill } from '~/components/primitive/InfoPill';
import { tw, twStyle } from '~/lib/tailwind';
import { SpacedropStackScreenProps } from '~/navigation/tabs/SpacedropStack';

View File

@@ -1,5 +1,4 @@
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SpacesStackScreenProps } from '~/navigation/tabs/SpacesStack';

View File

@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { useLibraryQuery } from '@sd/client';
import Explorer from '~/components/explorer/Explorer';
import { SharedScreenProps } from '~/navigation/SharedScreens';

View File

@@ -1,8 +1,8 @@
import React from 'react';
import { Text } from 'react-native';
import { PulseAnimation } from '~/components/animation/lottie';
import { tw } from '~/lib/tailwind';
import { OnboardingContainer, OnboardingDescription, OnboardingTitle } from './GetStarted';
const CreatingLibraryScreen = () => {

View File

@@ -5,7 +5,6 @@ import { CaretLeft } from 'phosphor-react-native';
import { Image, KeyboardAvoidingView, Platform, Pressable, Text, View } from 'react-native';
import Animated from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { FadeInUpAnimation, LogoAnimation } from '~/components/animation/layout';
import { AnimatedButton } from '~/components/primitive/Button';
import { styled, tw, twStyle } from '~/lib/tailwind';

View File

@@ -1,11 +1,11 @@
import { Database } from '@sd/assets/icons';
import { Controller } from 'react-hook-form';
import { Alert, Image, Text, View } from 'react-native';
import { Input } from '~/components/form/Input';
import { Button } from '~/components/primitive/Button';
import { tw } from '~/lib/tailwind';
import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
import { useOnboardingContext } from './context';
import { OnboardingContainer, OnboardingDescription, OnboardingTitle } from './GetStarted';

View File

@@ -1,10 +1,10 @@
import React from 'react';
import { Controller } from 'react-hook-form';
import { Pressable, Text, View, ViewStyle } from 'react-native';
import { Button } from '~/components/primitive/Button';
import { tw, twStyle } from '~/lib/tailwind';
import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
import { useOnboardingContext } from './context';
import { OnboardingContainer, OnboardingDescription, OnboardingTitle } from './GetStarted';

View File

@@ -15,7 +15,6 @@ import {
import React from 'react';
import { SectionList, Text, TouchableWithoutFeedback, View } from 'react-native';
import { DebugState, useDebugState, useDebugStateEnabler } from '@sd/client';
import { SettingsItem, SettingsItemDivider } from '~/components/settings/SettingsItem';
import { tw, twStyle } from '~/lib/tailwind';
import { SettingsStackParamList, SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -2,7 +2,6 @@ import { CheckCircle } from 'phosphor-react-native';
import React, { useState } from 'react';
import { ColorValue, Pressable, ScrollView, Text, View, ViewStyle } from 'react-native';
import { Themes, useThemeStore } from '@sd/client';
import { SettingsTitle } from '~/components/settings/SettingsContainer';
import Colors from '~/constants/style/Colors';
import { tw, twStyle } from '~/lib/tailwind';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -1,6 +1,5 @@
import { Text, View } from 'react-native';
import { useBridgeQuery, useDebugState } from '@sd/client';
import { Input } from '~/components/form/Input';
import Card from '~/components/layout/Card';
import { Divider } from '~/components/primitive/Divider';

View File

@@ -3,7 +3,6 @@ import React, { useEffect, useRef } from 'react';
import { Animated, FlatList, Text, View } from 'react-native';
import { Swipeable } from 'react-native-gesture-handler';
import { LibraryConfigWrapped, useBridgeQuery } from '@sd/client';
import { ModalRef } from '~/components/layout/Modal';
import DeleteLibraryModal from '~/components/modal/confirmModals/DeleteLibraryModal';
import { AnimatedButton, FakeButton } from '~/components/primitive/Button';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { Text, View } from 'react-native';
import { getDebugState, toggleFeatureFlag, useDebugState, useFeatureFlags } from '@sd/client';
import Card from '~/components/layout/Card';
import { Button } from '~/components/primitive/Button';
import { tw } from '~/lib/tailwind';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -5,7 +5,6 @@ import { Controller } from 'react-hook-form';
import { Alert, ScrollView, Text, View } from 'react-native';
import { z } from 'zod';
import { useLibraryMutation, useLibraryQuery, useZodForm } from '@sd/client';
import { Input } from '~/components/form/Input';
import { Switch } from '~/components/form/Switch';
import DeleteLocationModal from '~/components/modal/confirmModals/DeleteLocationModal';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { Text, View } from 'react-native';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -4,7 +4,6 @@ import { Controller } from 'react-hook-form';
import { Alert, View } from 'react-native';
import { z } from 'zod';
import { useBridgeMutation, useLibraryContext, useZodForm } from '@sd/client';
import { Input } from '~/components/form/Input';
import { Switch } from '~/components/form/Switch';
import DeleteLibraryModal from '~/components/modal/confirmModals/DeleteLibraryModal';

View File

@@ -9,7 +9,6 @@ import {
useLibraryQuery,
useOnlineLocations
} from '@sd/client';
import FolderIcon from '~/components/icons/FolderIcon';
import { ModalRef } from '~/components/layout/Modal';
import DeleteLocationModal from '~/components/modal/confirmModals/DeleteLocationModal';

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { Text, View } from 'react-native';
import { isEnabled, useBridgeMutation, useDiscoveredPeers } from '@sd/client';
import { Button } from '~/components/primitive/Button';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';

View File

@@ -3,7 +3,6 @@ import { useEffect, useRef } from 'react';
import { Animated, FlatList, Text, View } from 'react-native';
import { Swipeable } from 'react-native-gesture-handler';
import { Tag, useLibraryQuery } from '@sd/client';
import { ModalRef } from '~/components/layout/Modal';
import DeleteTagModal from '~/components/modal/confirmModals/DeleteTagModal';
import CreateTagModal from '~/components/modal/tag/CreateTagModal';

View File

@@ -1,7 +1,6 @@
import { createRef } from 'react';
import { proxy, ref, useSnapshot } from 'valtio';
import { ExplorerItem } from '@sd/client';
import { ModalRef } from '~/components/layout/Modal';
export const actionsModalStore = proxy({

View File

@@ -1,7 +1,6 @@
use crate::{
invalidate_query,
job::{job_without_data, Job, JobReport, JobStatus, Jobs},
library::Library,
location::{find_location, LocationError},
object::{
file_identifier::file_identifier_job::FileIdentifierJobInit, media::MediaProcessorJobInit,
@@ -17,7 +16,6 @@ use std::{
};
use chrono::{DateTime, Utc};
use futures::future::try_join_all;
use prisma_client_rust::or;
use rspc::alpha::AlphaRouter;
use serde::{Deserialize, Serialize};
@@ -80,113 +78,90 @@ pub(crate) fn mount() -> AlphaRouter<Ctx> {
jobs: VecDeque<JobReport>,
}
async fn group_jobs_by_library(
library: &Library,
active_job_reports_by_id: &HashMap<Uuid, JobReport>,
) -> Result<Vec<JobGroup>, rspc::Error> {
let mut groups: HashMap<String, JobGroup> = HashMap::new();
R.with2(library())
.query(|(node, library), _: ()| async move {
let mut groups: HashMap<String, JobGroup> = HashMap::new();
let job_reports: Vec<JobReport> = library
.db
.job()
.find_many(vec![])
.order_by(job::date_created::order(SortOrder::Desc))
.take(100)
.select(job_without_data::select())
.exec()
.await?
.into_iter()
.flat_map(JobReport::try_from)
.collect();
let job_reports: Vec<JobReport> = library
.db
.job()
.find_many(vec![])
.order_by(job::date_created::order(SortOrder::Desc))
.take(100)
.select(job_without_data::select())
.exec()
.await?
.into_iter()
.flat_map(JobReport::try_from)
.collect();
for job in job_reports {
// action name and group key are computed from the job data
let (action_name, group_key) = job.get_meta();
let active_reports_by_id = node.jobs.get_active_reports_with_id().await;
trace!(
"job {:#?}, action_name {}, group_key {:?}",
job,
action_name,
group_key
);
for job in job_reports {
// action name and group key are computed from the job data
let (action_name, group_key) = job.get_meta();
// if the job is running, use the in-memory report
let report = active_job_reports_by_id.get(&job.id).unwrap_or(&job);
trace!(
"job {:#?}, action_name {}, group_key {:?}",
job,
action_name,
group_key
);
// if we have a group key, handle grouping
if let Some(group_key) = group_key {
match groups.entry(group_key) {
// Create new job group with metadata
Entry::Vacant(entry) => {
entry.insert(JobGroup {
id: job.parent_id.unwrap_or(job.id),
action: Some(action_name.clone()),
// if the job is running, use the in-memory report
let report = active_reports_by_id.get(&job.id).unwrap_or(&job);
// if we have a group key, handle grouping
if let Some(group_key) = group_key {
match groups.entry(group_key) {
// Create new job group with metadata
Entry::Vacant(entry) => {
entry.insert(JobGroup {
id: job.parent_id.unwrap_or(job.id),
action: Some(action_name.clone()),
status: job.status,
jobs: [report.clone()].into_iter().collect(),
created_at: job.created_at.unwrap_or(Utc::now()),
});
}
// Add to existing job group
Entry::Occupied(mut entry) => {
let group = entry.get_mut();
// protect paused status from being overwritten
if report.status != JobStatus::Paused {
group.status = report.status;
}
group.jobs.push_front(report.clone());
}
}
} else {
// insert individual job as group
groups.insert(
job.id.to_string(),
JobGroup {
id: job.id,
action: None,
status: job.status,
jobs: [report.clone()].into_iter().collect(),
created_at: job.created_at.unwrap_or(Utc::now()),
});
}
// Add to existing job group
Entry::Occupied(mut entry) => {
let group = entry.get_mut();
// protect paused status from being overwritten
if report.status != JobStatus::Paused {
group.status = report.status;
}
// if group.status.is_finished() && !report.status.is_finished() {
// }
group.jobs.push_front(report.clone());
}
},
);
}
} else {
// insert individual job as group
groups.insert(
job.id.to_string(),
JobGroup {
id: job.id,
action: None,
status: job.status,
jobs: [report.clone()].into_iter().collect(),
created_at: job.created_at.unwrap_or(Utc::now()),
},
);
}
}
let mut groups_vec = groups.into_values().collect::<Vec<_>>();
groups_vec.sort_by(|a, b| b.created_at.cmp(&a.created_at));
let mut groups_vec = groups.into_values().collect::<Vec<_>>();
groups_vec.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(groups_vec)
}
R.query(|node, _: ()| async move {
// WARN: We really need the borrow in this line, this way each async move in the map below
// received a copy of the reference to the active job reports,
// I feel like I'm conquering the borrow checker
let active_job_reports_by_id = &node.jobs.get_active_reports_with_id().await;
try_join_all(
node.libraries
.get_all()
.await
.into_iter()
.map(|library| async move {
group_jobs_by_library(&library, active_job_reports_by_id)
.await
.map(|groups| (library.id, groups))
}),
)
.await
.map(|groups_by_library_id| {
groups_by_library_id.into_iter().collect::<HashMap<_, _>>()
Ok(groups_vec)
})
})
})
.procedure("isActive", {
R.with2(library())
.query(|(node, _), _: ()| async move { Ok(node.jobs.has_active_workers().await) })
.query(|(node, library), _: ()| async move {
Ok(node.jobs.has_active_workers(library.id).await)
})
})
.procedure("clear", {
R.with2(library())

View File

@@ -347,9 +347,9 @@ impl Jobs {
}
/// Check if the manager currently has some active workers.
pub async fn has_active_workers(&self) -> bool {
pub async fn has_active_workers(&self, library_id: Uuid) -> bool {
for worker in self.running_workers.read().await.values() {
if !worker.is_paused() {
if worker.library_id == library_id && !worker.is_paused() {
return true;
}
}

View File

@@ -28,6 +28,7 @@ use super::{
#[derive(Debug, Clone, Serialize, Type)]
pub struct JobProgressEvent {
pub id: Uuid,
pub library_id: Uuid,
pub task_count: i32,
pub completed_task_count: i32,
pub message: String,
@@ -90,6 +91,7 @@ impl WorkerContext {
// a worker is a dedicated thread that runs a single job
// once the job is complete the worker will exit
pub struct Worker {
pub(super) library_id: Uuid,
commands_tx: mpsc::Sender<WorkerCommand>,
report_watch_tx: Arc<watch::Sender<JobReport>>,
report_watch_rx: watch::Receiver<JobReport>,
@@ -130,6 +132,7 @@ impl Worker {
let (report_watch_tx, report_watch_rx) = watch::channel(report.clone());
let report_watch_tx = Arc::new(report_watch_tx);
let library_id = library.id;
// spawn task to handle running the job
tokio::spawn(Self::do_work(
@@ -148,6 +151,7 @@ impl Worker {
));
Ok(Self {
library_id,
commands_tx,
report_watch_tx,
report_watch_rx,
@@ -279,6 +283,7 @@ impl Worker {
// emit a CoreEvent
library.emit(CoreEvent::JobProgress(JobProgressEvent {
id: report.id,
library_id: library.id,
task_count: report.task_count,
completed_task_count: report.completed_task_count,
estimated_completion: report.estimated_completion,

View File

@@ -25,7 +25,7 @@ use tokio::{fs, io};
use tracing::{error, warn};
use super::{
file_path_helper::{path_is_hidden, FilePathMetadata, MetadataExt},
file_path_helper::{path_is_hidden, MetadataExt},
generate_thumbnail,
indexer::rules::{
seed::{no_hidden, no_os_protected},
@@ -188,7 +188,7 @@ pub async fn walk(
has_local_thumbnail: thumbnail_key.is_some(),
thumbnail_key,
item: NonIndexedPathItem {
hidden: path_is_hidden(&Path::new(&entry_path), &metadata),
hidden: path_is_hidden(Path::new(&entry_path), &metadata),
path: entry_path,
name,
extension,
@@ -234,7 +234,7 @@ pub async fn walk(
has_local_thumbnail: false,
thumbnail_key: None,
item: NonIndexedPathItem {
hidden: path_is_hidden(&Path::new(&directory), &metadata),
hidden: path_is_hidden(Path::new(&directory), &metadata),
path: directory,
name,
extension: "".to_string(),

View File

@@ -1,9 +1,9 @@
import { Copy, Scissors } from '@phosphor-icons/react';
import { useLibraryMutation } from '@sd/client';
import { ContextMenu, ModifierKeys, toast } from '@sd/ui';
import { useKeybindFactory } from '~/hooks/useKeybindFactory';
import { isNonEmpty } from '~/util';
import { useExplorerContext } from '../../Context';
import { getExplorerStore } from '../../store';
import { useExplorerSearchParams } from '../../util';

View File

@@ -1,11 +1,11 @@
import { Image, Package, Trash, TrashSimple } from '@phosphor-icons/react';
import { libraryClient, useLibraryContext, useLibraryMutation } from '@sd/client';
import { ContextMenu, dialogManager, ModifierKeys, toast } from '@sd/ui';
import { Menu } from '~/components/Menu';
import { useKeybindFactory } from '~/hooks/useKeybindFactory';
import { isNonEmpty } from '~/util';
import { usePlatform } from '~/util/Platform';
import { useExplorerContext } from '../../Context';
import { CopyAsPathBase } from '../../CopyAsPath';
import DeleteDialog from '../../FilePath/DeleteDialog';

View File

@@ -2,9 +2,9 @@ import { useQuery } from '@tanstack/react-query';
import { Suspense } from 'react';
import { useLibraryContext } from '@sd/client';
import { toast } from '@sd/ui';
import { Menu } from '~/components/Menu';
import { Platform, usePlatform } from '~/util/Platform';
import { ConditionalItem } from '../ConditionalItem';
import { useContextMenuContext } from '../context';

View File

@@ -2,10 +2,10 @@ import { ArrowBendUpRight, TagSimple } from '@phosphor-icons/react';
import { useMemo } from 'react';
import { ObjectKind, useLibraryMutation, type ObjectKindEnum } from '@sd/client';
import { ContextMenu, toast } from '@sd/ui';
import AssignTagMenuItems from '~/components/AssignTagMenuItems';
import { Menu } from '~/components/Menu';
import { isNonEmpty } from '~/util';
import { ConditionalItem } from '../ConditionalItem';
import { useContextMenuContext } from '../context';

View File

@@ -1,11 +1,11 @@
import { FileX, Share as ShareIcon } from '@phosphor-icons/react';
import { useMemo } from 'react';
import { ContextMenu, ModifierKeys } from '@sd/ui';
import { Menu } from '~/components/Menu';
import { useKeybindFactory } from '~/hooks/useKeybindFactory';
import { isNonEmpty } from '~/util';
import { type Platform } from '~/util/Platform';
import { useExplorerContext } from '../Context';
import { getQuickPreviewStore } from '../QuickPreview/store';
import { RevealInNativeExplorerBase } from '../RevealInNativeExplorer';

View File

@@ -1,6 +1,5 @@
import { createContext, PropsWithChildren, useContext } from 'react';
import { ExplorerItem, FilePath, Object, useItemsAsFilePaths, useItemsAsObjects } from '@sd/client';
import { NonEmptyArray } from '~/util';
const ContextMenuContext = createContext<{

View File

@@ -2,8 +2,8 @@ import { Plus } from '@phosphor-icons/react';
import { useMemo, type PropsWithChildren } from 'react';
import { ExplorerItem } from '@sd/client';
import { ContextMenu } from '@sd/ui';
import { isNonEmpty } from '~/util';
import { useExplorerContext } from '../Context';
import { Conditional, type ConditionalGroupProps } from './ConditionalItem';
import { ContextMenuContextProvider } from './context';

View File

@@ -1,6 +1,5 @@
import { ClipboardText } from '@phosphor-icons/react';
import { toast } from '@sd/ui';
import { Menu } from '~/components/Menu';
export const CopyAsPathBase = (

View File

@@ -8,10 +8,10 @@ import {
} from '@sd/assets/icons';
import { ReactNode } from 'react';
import { ExplorerLayout } from '@sd/client';
import DismissibleNotice from '~/components/DismissibleNotice';
import { useIsDark } from '~/hooks';
import { dismissibleNoticeStore } from '~/hooks/useDismissibleNoticeStore';
import { useExplorerContext } from './Context';
import { useExplorerStore } from './store';

View File

@@ -13,11 +13,11 @@ import {
type VideoHTMLAttributes
} from 'react';
import { getItemFilePath, useLibraryContext, type ExplorerItem } from '@sd/client';
import { PDFViewer, TextViewer } from '~/components';
import { useCallbackToWatchResize, useIsDark } from '~/hooks';
import { pdfViewerEnabled } from '~/util/pdfViewer';
import { usePlatform } from '~/util/Platform';
import { useExplorerContext } from '../Context';
import { getExplorerStore } from '../store';
import { useExplorerItemData } from '../util';

View File

@@ -1,6 +1,6 @@
import { RadixCheckbox, Select, SelectOption, Slider, tw, z } from '@sd/ui';
import { SortOrderSchema } from '~/app/route-schemas';
import { useExplorerContext } from './Context';
import {
createOrdering,

View File

@@ -2,9 +2,9 @@ import { Clipboard, FileX, Image, Plus, Repeat, Share, ShieldCheck } from '@phos
import { PropsWithChildren } from 'react';
import { useLibraryMutation } from '@sd/client';
import { ContextMenu as CM, ModifierKeys, toast } from '@sd/ui';
import { useOperatingSystem } from '~/hooks';
import { keybindForOs } from '~/util/keybinds';
import { useExplorerContext } from './Context';
import { CopyAsPathBase } from './CopyAsPath';
import { RevealInNativeExplorerBase } from './RevealInNativeExplorer';

View File

@@ -1,6 +1,5 @@
import { useLibraryContext } from '@sd/client';
import { ModifierKeys } from '@sd/ui';
import { Menu } from '~/components/Menu';
import { useOperatingSystem } from '~/hooks';
import { useKeybindFactory } from '~/hooks/useKeybindFactory';

View File

@@ -84,7 +84,7 @@ const GridListItem = (props: {
return (
<div
className="w-full h-full"
className="h-full w-full"
data-selectable=""
data-selectable-index={props.index}
data-selectable-id={itemId}

View File

@@ -59,7 +59,7 @@ interface ListViewItemProps {
const ListViewItem = memo((props: ListViewItemProps) => {
return (
<ViewItem data={props.row.original} className="w-full">
<div role="row" className="flex items-center h-full">
<div role="row" className="flex h-full items-center">
{props.row.getVisibleCells().map((cell) => (
<div
role="cell"
@@ -1028,7 +1028,7 @@ export default () => {
useLayoutEffect(() => setListOffset(tableRef.current?.offsetTop ?? 0), []);
return (
<div className="flex flex-col w-full" ref={tableRef}>
<div className="flex w-full flex-col" ref={tableRef}>
{sized && (
<ScrollSync>
<>
@@ -1050,7 +1050,7 @@ export default () => {
<div
ref={tableHeaderRef}
key={headerGroup.id}
className="flex border-b grow border-app-line/50"
className="flex grow border-b border-app-line/50"
onMouseDown={(e) => e.stopPropagation()}
>
{headerGroup.headers.map((header, i) => {
@@ -1073,7 +1073,7 @@ export default () => {
return (
<div
key={header.id}
className="relative px-4 py-2 text-xs shrink-0 first:pl-24"
className="relative shrink-0 px-4 py-2 text-xs first:pl-24"
style={{
width:
i === 0
@@ -1190,7 +1190,7 @@ export default () => {
</ScrollSyncPane>
<ScrollSyncPane>
<div className="overflow-x-auto no-scrollbar overscroll-x-none">
<div className="no-scrollbar overflow-x-auto overscroll-x-none">
<div
ref={tableBodyRef}
className="relative"
@@ -1218,7 +1218,7 @@ export default () => {
return (
<div
key={row.id}
className="absolute top-0 left-0 flex w-full"
className="absolute left-0 top-0 flex w-full"
style={{
height: virtualRow.size,
transform: `translateY(${
@@ -1251,7 +1251,7 @@ export default () => {
)}
>
{selectedPrior && (
<div className="absolute top-0 h-px inset-x-3 bg-accent/10" />
<div className="absolute inset-x-3 top-0 h-px bg-accent/10" />
)}
<ListViewItem

View File

@@ -1,5 +1,5 @@
import clsx from 'clsx';
import { ArrowsOutSimple } from '@phosphor-icons/react';
import clsx from 'clsx';
import { memo } from 'react';
import { ExplorerItem } from '@sd/client';
import { Button } from '@sd/ui';

View File

@@ -1,8 +1,8 @@
import { useMemo } from 'react';
import { getExplorerItemData, type ExplorerItem } from '@sd/client';
import { ExplorerParamsSchema } from '~/app/route-schemas';
import { useZodSearchParams } from '~/hooks';
import { flattenThumbnailKey, useExplorerStore } from './store';
export function useExplorerSearchParams() {

Some files were not shown because too many files have changed in this diff Show More