Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { useStableCallback } from '@rocket.chat/fuselage-hooks';
|
|
import { usePermission, useSetting, useTranslation, useUser } from '@rocket.chat/ui-contexts';
|
|
import type { DragEvent, ReactNode } from 'react';
|
|
import { useMemo, useSyncExternalStore } from 'react';
|
|
|
|
import { useDropTarget } from './useDropTarget';
|
|
import { roomCoordinator } from '../../../../lib/rooms/roomCoordinator';
|
|
import { useIsRoomOverMacLimit } from '../../../omnichannel/hooks/useIsRoomOverMacLimit';
|
|
import { useChat } from '../../contexts/ChatContext';
|
|
import { useRoom, useRoomSubscription } from '../../contexts/RoomContext';
|
|
|
|
export const useFileUploadDropTarget = (): readonly [
|
|
fileUploadTriggerProps: {
|
|
onDragEnter: (event: DragEvent<Element>) => void;
|
|
},
|
|
fileUploadOverlayProps: {
|
|
visible: boolean;
|
|
onDismiss: () => void;
|
|
enabled: boolean;
|
|
reason?: ReactNode;
|
|
},
|
|
] => {
|
|
const room = useRoom();
|
|
const { triggerProps, overlayProps } = useDropTarget();
|
|
|
|
const isRoomOverMacLimit = useIsRoomOverMacLimit(room);
|
|
|
|
const t = useTranslation();
|
|
|
|
const fileUploadEnabled = useSetting('FileUpload_Enabled', true);
|
|
const user = useUser();
|
|
const postReadOnly = usePermission('post-readonly', room._id);
|
|
const fileUploadAllowedForUser = useMemo(
|
|
() => !roomCoordinator.readOnly(room, { username: user?.username }),
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
[room, user?.username, postReadOnly],
|
|
);
|
|
|
|
const chat = useChat();
|
|
const subscription = useRoomSubscription();
|
|
|
|
const isEditing = useSyncExternalStore(
|
|
chat?.composer?.editing.subscribe ?? (() => () => undefined),
|
|
chat?.composer?.editing.get ?? (() => false),
|
|
);
|
|
|
|
const onFileDrop = useStableCallback(async (files: File[]) => {
|
|
const { getMimeType } = await import('../../../../../app/utils/lib/mimeTypes');
|
|
const getUniqueFiles = () => {
|
|
const uniqueFiles: File[] = [];
|
|
const st: Set<string> = new Set();
|
|
files.forEach((file) => {
|
|
const key = `${file.name}-${file.size}-${file.lastModified}`;
|
|
if (!st.has(key)) {
|
|
uniqueFiles.push(file);
|
|
st.add(key);
|
|
}
|
|
});
|
|
return uniqueFiles;
|
|
};
|
|
const uniqueFiles = getUniqueFiles();
|
|
|
|
const uploads = Array.from(uniqueFiles).map((file) => {
|
|
Object.defineProperty(file, 'type', { value: getMimeType(file.type, file.name) });
|
|
return file;
|
|
});
|
|
|
|
chat?.flows.uploadFiles({ files: uploads });
|
|
});
|
|
|
|
const allOverlayProps = useMemo(() => {
|
|
if (!fileUploadEnabled || isRoomOverMacLimit) {
|
|
return {
|
|
enabled: false,
|
|
reason: t('FileUpload_Disabled'),
|
|
...overlayProps,
|
|
} as const;
|
|
}
|
|
|
|
if (!fileUploadAllowedForUser || !subscription || isEditing) {
|
|
return {
|
|
enabled: false,
|
|
reason: t('error-not-allowed'),
|
|
...overlayProps,
|
|
} as const;
|
|
}
|
|
|
|
return {
|
|
enabled: true,
|
|
onFileDrop,
|
|
...overlayProps,
|
|
} as const;
|
|
}, [isEditing, fileUploadAllowedForUser, fileUploadEnabled, isRoomOverMacLimit, onFileDrop, overlayProps, subscription, t]);
|
|
|
|
return [triggerProps, allOverlayProps] as const;
|
|
};
|