mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 03:20:46 +02:00
Chore/v2/improve uploads (#5351)
Co-authored-by: James Brunton <[email protected]>
This commit is contained in:
co-authored by
James Brunton
parent
d9caa3482c
commit
c158664d2c
@@ -43,7 +43,7 @@ const FileEditor = ({
|
||||
const { clearAllFileErrors } = fileContextActions;
|
||||
|
||||
// Extract needed values from state (memoized to prevent infinite loops)
|
||||
const activeStirlingFileStubs = useMemo(() => selectors.getStirlingFileStubs(), [selectors.getFilesSignature()]);
|
||||
const activeStirlingFileStubs = useMemo(() => selectors.getStirlingFileStubs(), [state.files.byId, state.files.ids]);
|
||||
const selectedFileIds = state.ui.selectedFileIds;
|
||||
const totalItems = state.files.ids.length;
|
||||
const selectedCount = selectedFileIds.length;
|
||||
@@ -365,7 +365,7 @@ const FileEditor = ({
|
||||
activateOnDrag={true}
|
||||
>
|
||||
<Box pos="relative" style={{ overflow: 'auto' }}>
|
||||
<LoadingOverlay visible={false} />
|
||||
<LoadingOverlay visible={state.ui.isProcessing} />
|
||||
|
||||
<Box p="md">
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useCallback, useRef, useMemo } from 'react';
|
||||
import { Text, ActionIcon, CheckboxIndicator, Tooltip, Modal, Button, Group, Stack } from '@mantine/core';
|
||||
import { Text, ActionIcon, CheckboxIndicator, Tooltip, Modal, Button, Group, Stack, Loader } from '@mantine/core';
|
||||
import { useIsMobile } from '@app/hooks/useIsMobile';
|
||||
import { alert } from '@app/components/toast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -389,7 +389,7 @@ const FileEditorThumbnail = ({
|
||||
style={isSupported || hasError ? undefined : { filter: 'grayscale(80%)', opacity: 0.6 }}
|
||||
>
|
||||
<div className={styles.previewPaper}>
|
||||
{file.thumbnailUrl && (
|
||||
{file.thumbnailUrl ? (
|
||||
<PrivateContent>
|
||||
<img
|
||||
src={file.thumbnailUrl}
|
||||
@@ -416,7 +416,12 @@ const FileEditorThumbnail = ({
|
||||
}}
|
||||
/>
|
||||
</PrivateContent>
|
||||
)}
|
||||
) : file.type?.startsWith('application/pdf') ? (
|
||||
<Stack align="center" justify="center" gap="xs" style={{ height: '100%' }}>
|
||||
<Loader size="sm" />
|
||||
<Text size="xs" c="dimmed">Loading thumbnail...</Text>
|
||||
</Stack>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Drag handle (span wrapper so we can attach a ref reliably) */}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { Card, Stack, Text, Group, Badge, Button, Box, Image, ThemeIcon, ActionIcon, Tooltip } from "@mantine/core";
|
||||
import { Card, Stack, Text, Group, Badge, Button, Box, Image, ThemeIcon, ActionIcon, Tooltip, Loader } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
|
||||
import StorageIcon from "@mui/icons-material/Storage";
|
||||
@@ -29,6 +29,10 @@ const FileCard = ({ file, fileStub, onRemove, onDoubleClick, onView, onEdit, isS
|
||||
const thumb = fileStub?.thumbnailUrl || indexedDBThumb;
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
// Show loading state during hydration: PDF file without thumbnail yet
|
||||
const isPdf = file.type === 'application/pdf';
|
||||
const isHydrating = isPdf && !thumb && !isGenerating;
|
||||
|
||||
return (
|
||||
<Card
|
||||
shadow="xs"
|
||||
@@ -125,24 +129,11 @@ const FileCard = ({ file, fileStub, onRemove, onDoubleClick, onView, onEdit, isS
|
||||
fit="contain"
|
||||
radius="sm"
|
||||
/>
|
||||
) : isGenerating ? (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<div style={{
|
||||
width: 20,
|
||||
height: 20,
|
||||
border: '2px solid #ddd',
|
||||
borderTop: '2px solid #666',
|
||||
borderRadius: '50%',
|
||||
animation: 'spin 1s linear infinite',
|
||||
marginBottom: 8
|
||||
}} />
|
||||
<Text size="xs" c="dimmed">Generating...</Text>
|
||||
</div>
|
||||
) : (isGenerating || isHydrating) ? (
|
||||
<Stack align="center" justify="center" gap="xs">
|
||||
<Loader size="sm" />
|
||||
<Text size="xs" c="dimmed">Loading...</Text>
|
||||
</Stack>
|
||||
) : (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button, Text, Stack, Group, Card, Progress } from "@mantine/core";
|
||||
import { Button, Text, Stack, Group, Card, Progress, Loader } from "@mantine/core";
|
||||
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
||||
import CheckIcon from "@mui/icons-material/Check";
|
||||
import { useFileSelection } from "@app/contexts/FileContext";
|
||||
import { useToolRegistry } from "@app/contexts/ToolRegistryContext";
|
||||
import { AutomationConfig, ExecutionStep } from "@app/types/automation";
|
||||
import { AUTOMATION_CONSTANTS, EXECUTION_STATUS } from "@app/constants/automation";
|
||||
import { EXECUTION_STATUS } from "@app/constants/automation";
|
||||
import { useResourceCleanup } from "@app/utils/resourceManager";
|
||||
|
||||
interface AutomationRunProps {
|
||||
@@ -119,14 +119,7 @@ export default function AutomationRun({ automation, onComplete, automateOperatio
|
||||
case EXECUTION_STATUS.ERROR:
|
||||
return <span style={{ fontSize: 16, color: 'red' }}>✕</span>;
|
||||
case EXECUTION_STATUS.RUNNING:
|
||||
return <div style={{
|
||||
width: 16,
|
||||
height: 16,
|
||||
border: '2px solid #ccc',
|
||||
borderTop: '2px solid #007bff',
|
||||
borderRadius: '50%',
|
||||
animation: `spin ${AUTOMATION_CONSTANTS.SPINNER_ANIMATION_DURATION} linear infinite`
|
||||
}} />;
|
||||
return <Loader size={16} />;
|
||||
default:
|
||||
return <div style={{
|
||||
width: 16,
|
||||
|
||||
Reference in New Issue
Block a user