Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/libs/fileDownload/FileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,25 @@ function base64ToFile(base64: string, filename: string): File {
return file;
}

/**
* Converts a File instance in to base64 encoded image.
*
* @param file - The File instance with image.
* @returns string with base64 encoding of image.
*/
function fileToBase64(file?: File) {
return new Promise<string>((resolve, reject) => {
if (!file) {
resolve('');
return;
}
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
}

function validateImageForCorruption(file: FileObject): Promise<{width: number; height: number} | void> {
if (!Str.isImage(file.name ?? '') || !file.uri) {
return Promise.resolve();
Expand Down Expand Up @@ -669,6 +688,7 @@ export {
appendTimeToFileName,
readFileAsync,
base64ToFile,
fileToBase64,
isLocalFile,
validateImageForCorruption,
isImage,
Expand Down
13 changes: 8 additions & 5 deletions src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useCallback, useState} from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
import AvatarWithImagePicker from '@components/AvatarWithImagePicker';
import FormProvider from '@components/Form/FormProvider';
Expand All @@ -17,6 +17,7 @@
import {generatePolicyID, setDuplicateWorkspaceData} from '@libs/actions/Policy/Policy';
import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types';
import {addErrorMessage} from '@libs/ErrorUtils';
import {fileToBase64} from '@libs/fileDownload/FileUtils';
import getFirstAlphaNumericCharacter from '@libs/getFirstAlphaNumericCharacter';
import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils';
import {isRequiredFulfilled} from '@libs/ValidationUtils';
Expand All @@ -36,6 +37,7 @@
const {inputCallbackRef} = useAutoFocusInput();
const policy = usePolicy(policyID);
const defaultWorkspaceName = `${policy?.name} (${translate('workspace.common.duplicateWorkspacePrefix')})`;
const newPolicyID = useMemo(generatePolicyID, []);

Check failure on line 40 in src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Expected the first argument to be an inline function expression

Check failure on line 40 in src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Expected the first argument to be an inline function expression

const validate = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_DUPLICATE_FORM>) => {
Expand All @@ -60,11 +62,12 @@
if (!policyID) {
return;
}
const newPolicyID = generatePolicyID();
setDuplicateWorkspaceData({policyID: newPolicyID, name, file: avatarFile});
fileToBase64(avatarFile as File | undefined).then((base64) => {
setDuplicateWorkspaceData({policyID: newPolicyID, name, file: base64});
});
Navigation.navigate(ROUTES.WORKSPACE_DUPLICATE_SELECT_FEATURES.getRoute(policyID, ROUTES.WORKSPACES_LIST.route));
},
[policyID],
[policyID, newPolicyID],
);

const [workspaceNameFirstCharacter, setWorkspaceNameFirstCharacter] = useState(defaultWorkspaceName ?? '');
Expand All @@ -79,7 +82,7 @@
const stashedLocalAvatarImage = workspaceAvatar?.avatarUri ?? undefined;

const DefaultAvatar = useWorkspaceConfirmationAvatar({
policyID,
policyID: newPolicyID,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing cannot be used if left side can be empty string
source: stashedLocalAvatarImage || getDefaultWorkspaceAvatar(workspaceNameFirstCharacter),
name: workspaceNameFirstCharacter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
import useThemeStyles from '@hooks/useThemeStyles';
import {base64ToFile} from '@libs/fileDownload/FileUtils';
import {getDistanceRateCustomUnit, getMemberAccountIDsForWorkspace, getPerDiemCustomUnit, isCollectPolicy} from '@libs/PolicyUtils';
import {getReportFieldsByPolicyID} from '@libs/ReportUtils';
import Navigation from '@navigation/Navigation';
Expand Down Expand Up @@ -239,7 +240,7 @@ function WorkspaceDuplicateSelectFeaturesForm({policyID}: WorkspaceDuplicateForm
invoices: selectedItems.includes('invoices'),
exportLayouts: selectedItems.includes('workflows'),
},
file: duplicateWorkspace?.file,
file: duplicateWorkspace?.file ? base64ToFile(duplicateWorkspace?.file, 'tmpfile') : undefined,
});
Navigation.closeRHPFlow();
}, [duplicateWorkspace?.file, duplicateWorkspace?.name, duplicateWorkspace?.policyID, policy, policyCategories, selectedItems, translate]);
Expand Down
3 changes: 1 addition & 2 deletions src/types/onyx/DuplicateWorkspace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types';
import type * as OnyxCommon from './OnyxCommon';

/** Model of plaid data */
Expand All @@ -10,7 +9,7 @@ type DuplicateWorkspace = {
name?: string;

/** Workspace avatar */
file?: File | CustomRNImageManipulatorResult;
file?: string;

/** Whether the data is being fetched from server */
isLoading?: boolean;
Expand Down
Loading