Skip to content

Commit

Permalink
[CP-2191] I want only supported files to be uploaded (#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
OskarMichalkiewicz authored and dkarski committed Sep 27, 2023
1 parent d0ded80 commit 0bcabc6
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 29 deletions.
25 changes: 15 additions & 10 deletions packages/app/src/__deprecated__/renderer/locales/default/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"component.contactModalSuccessBody": "We will contact you as soon as the problem is resolved",
"component.contactModalSuccessBodyWithoutEmail": "We will check the issue as soon as possible.",
"component.contactModalSuccessTitle": "Message sent",
"component.contactModalTitle": "Mudita Center Support",
"component.contactSupportModalActionButton": "Send",
"component.contactSupportModalActionButtonProgress": "Sending",
"component.contactSupportModalDescription": "Contact Mudita support team and we will do our best to help you resolve your issues.",
Expand Down Expand Up @@ -153,6 +154,7 @@
"component.supportModalSuccessBody": "We will contact you as soon as the problem is resolved",
"component.supportModalSuccessBodyWithoutEmail": "We will check the issue as soon as possible.",
"component.supportModalSuccessTitle": "Message sent",
"component.supportModalTitle": "Mudita Center Support",
"component.table.close": "Close",
"component.textEditorCancelButton": "Reject changes",
"component.textEditorSaveButton": "Save to phone",
Expand All @@ -178,7 +180,7 @@
"component.updateDownloadedModalDescription": "Do you want to update app now or during next launch?",
"component.updateDownloadedModalMessage": "Update is ready to install",
"component.updateDownloadedModalWarning": "Note that update process will require app {osxPlatform, select, false {restart} true {quit}}.\nMake sure you saved all data you're currently working on.",
"component.updateErrorModalDescription": "Please download the latest Mudita Center version from {link}",
"component.updateErrorModalDescription": "Please restart the app or update it manually.",
"component.updateErrorModalMessage": "Error",
"component.updateForcedModalButton": "Download",
"component.updateForcedModalCurrentVersion": "Your current version: v.{version}",
Expand Down Expand Up @@ -418,12 +420,16 @@
"module.filesManager.duplicatedFilesUploadModalPendingFilesTextInfo": "Of the {uploadFilesCount} files you selected, {duplicatedFilesCount} {duplicatedFilesCount, plural, one {file} other {files}} with that name\nalready exist on your device. Change the name and try again.",
"module.filesManager.duplicatedFilesUploadModalTextInfo": "The file with this name already exists on the device. Change the name and try again.",
"module.filesManager.duplicatedFilesUploadModalTitle": "Upload files",
"module.filesManager.invalidFiledModalFilesInfo": "We found some files which wouldn't work on your device. To avoid problems we only uploaded the files that will work.",
"module.filesManager.invalidFiledModalHelpInfo": "To find out more about which files work on your device, visit our {link}.",
"module.filesManager.invalidFiledModalTitle": "File upload complete",
"module.filesManager.invalidFiledModalUploadInfo": "To avoid problems we only uploaded the files that will work.",
"module.filesManager.panelSearchPlaceholder": "Search music files",
"module.filesManager.pendingUploadModalAbortButtonText": "Abort",
"module.filesManager.pendingUploadModalActionButton": "Ok",
"module.filesManager.pendingUploadModalHeader": "Files uploading",
"module.filesManager.pendingUploadModalTextDetailsInfo": "The first {count, plural, one {file} other {# files}} will be uploaded to the device.",
"module.filesManager.pendingUploadModalTextInfo": "Mudita Center cannot load all files.\nThe number of selected files exceeds the limit.",
"module.filesManager.pendingUploadModalAbortButtonText": "Abort",
"module.filesManager.pendingUploadModalTextInfo": "Mudita Center cannot load all files.\\nThe number of selected files exceeds the limit.",
"module.filesManager.pendingUploadModalTitle": "Upload files",
"module.filesManager.selectionNumber": "{num, plural, =-1 {All Files} one {# File} other {# Files}} selected",
"module.filesManager.tooManyFilesTooltipDescription": "The maximum number of files has been reached ({filesSlotsHarmonyMaxLimit} files)",
Expand Down Expand Up @@ -789,11 +795,6 @@
"module.settings.aboutLicense": "License",
"module.settings.aboutPrivacyPolicy": "Privacy Policy",
"module.settings.aboutTermsOfService": "Terms of service",
"module.settings.checkForFailedAppUpdateTitle": "Mudita Center",
"module.settings.checkForFailedAppUpdateSubtitle": "Checking failed",
"module.settings.checkForFailedAppUpdateBody": "Opps, something went wrong. \nPlease check your internet connection",
"module.settings.loadingTitle": "Mudita Center",
"module.settings.loadingSubtitle": "Checking for update",
"module.settings.audioConversion": "Audio Conversion",
"module.settings.audioConversionAlwaysAskLabel": "Always ask",
"module.settings.audioConversionConversionFormat": "Conversion format:",
Expand All @@ -810,11 +811,15 @@
"module.settings.backupDescription": " ",
"module.settings.backupLabel": "Backup Location",
"module.settings.backupTetheringLabel": "Start tethering",
"module.settings.systemUpdateCheckFailed": "Checking for update failed",
"module.settings.checkForFailedAppUpdateBody": "Opps, something went wrong. \nPlease check your internet connection",
"module.settings.checkForFailedAppUpdateSubtitle": "Checking failed",
"module.settings.checkForFailedAppUpdateTitle": "Mudita Center",
"module.settings.collectingData": "Send Mudita Center logs to Mudita",
"module.settings.collectingDataTooltip": "Sending logs is completely voluntary. Mudita doesn’t collect nor store any sensitive data - find out more in Mudita Center Privacy Policy (https://mudita.com/legal/privacy-policy/mudita-center/)",
"module.settings.connection": "General",
"module.settings.description": " ",
"module.settings.loadingSubtitle": "Checking for update",
"module.settings.loadingTitle": "Mudita Center",
"module.settings.notifications": "Notifications",
"module.settings.notificationsDescription": "Select which notifications you want to receive while using Mudita Center:",
"module.settings.notificationsIncomingCallsNotificationsLabel": "Incoming calls notifications",
Expand All @@ -828,6 +833,7 @@
"module.settings.privacyPolicyModalHeader": "Read and accept the Privacy policy",
"module.settings.privacyPolicyModalLink": "Read the Privacy Policy",
"module.settings.privacyPolicyModalTitle": "Privacy Policy",
"module.settings.systemUpdateCheckFailed": "Checking for update failed",
"module.settings.tetheringLabel": "Start tethering",
"module.template.dropdownDelete": "Delete Template",
"module.templates": "Templates",
Expand Down Expand Up @@ -875,7 +881,6 @@
"module.templates.temporary": "New template",
"module.templates.text": "Template...",
"module.templates.tooLong": "The template is too long",
"module.templates.newLine": "The template contains new line character",
"module.templates.unsavedTemplate": "unsaved",
"module.templates.updatingModalErrorSubtitle": "Updating failed",
"module.templates.updatingModalErrorTitle": "Updating Template",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"component.collectingDataModalBody": "I agree on sending anonymized data to Mudita"
}
}
4 changes: 4 additions & 0 deletions packages/app/src/files-manager/actions/base.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ export const setDuplicatedFiles = createAction<string[]>(
FilesManagerEvent.SetDuplicatedFiles
)
export const resetFiles = createAction(FilesManagerEvent.ResetFiles)

export const setInvalidFiles = createAction<string[]>(
FilesManagerEvent.SetInvalidFiles
)
20 changes: 12 additions & 8 deletions packages/app/src/files-manager/actions/upload-file.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { uploadFilesRequest } from "App/files-manager/requests"
import { getFiles } from "App/files-manager/actions/get-files.action"
import {
setDuplicatedFiles,
setInvalidFiles,
setPendingFilesToUpload,
setUploadBlocked,
setUploadingFileCount,
Expand Down Expand Up @@ -52,9 +53,9 @@ export const uploadFile = createAsyncThunk<
return rejectWithValue("no files to upload")
}

const allFilesSupported = checkFilesExtensions(filePaths)
const { validFiles, invalidFiles } = checkFilesExtensions(filePaths)

if (!allFilesSupported) {
if (!validFiles.length && invalidFiles.length) {
dispatch(setUploadBlocked(false))
return rejectWithValue(
new AppError(
Expand All @@ -66,11 +67,11 @@ export const uploadFile = createAsyncThunk<

const duplicatedFiles = getDuplicatedFiles(
state.filesManager.files,
filePaths
validFiles
)

if (duplicatedFiles.length > 0) {
const uniqueFiles = getUniqueFiles(state.filesManager.files, filePaths)
const uniqueFiles = getUniqueFiles(state.filesManager.files, validFiles)
dispatch(setPendingFilesToUpload(uniqueFiles))
dispatch(setDuplicatedFiles(duplicatedFiles))
dispatch(setUploadBlocked(false))
Expand All @@ -96,17 +97,17 @@ export const uploadFile = createAsyncThunk<

if (
state.device.deviceType === DeviceType.MuditaHarmony &&
harmonyFreeFilesSlotsCount < filePaths.length
harmonyFreeFilesSlotsCount < validFiles.length
) {
dispatch(
setPendingFilesToUpload(filePaths.slice(0, harmonyFreeFilesSlotsCount))
setPendingFilesToUpload(validFiles.slice(0, harmonyFreeFilesSlotsCount))
)
dispatch(setUploadingState(State.Pending))
dispatch(setUploadBlocked(false))
return
}

dispatch(setUploadingFileCount(filePaths.length))
dispatch(setUploadingFileCount(validFiles.length))
dispatch(setUploadingState(State.Loading))

const directory =
Expand All @@ -116,7 +117,7 @@ export const uploadFile = createAsyncThunk<

const result = await uploadFilesRequest({
directory,
filePaths,
filePaths: validFiles,
})

void dispatch(getFiles(directory))
Expand All @@ -128,6 +129,9 @@ export const uploadFile = createAsyncThunk<
void dispatch(loadStorageInfoAction())
dispatch(setUploadingState(State.Loaded))
dispatch(setUploadBlocked(false))
if (invalidFiles.length) {
dispatch(setInvalidFiles(invalidFiles))
}

return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const FilesManager: FunctionComponent<FilesManagerProps> = ({
Array.from(fileInputRef.current?.files).map((file) => file.path)
)
)
fileInputRef.current.value = ""
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import { defineMessages } from "react-intl"
import { FunctionComponent } from "App/__deprecated__/renderer/types/function-component.interface"
import { useDispatch, useSelector } from "react-redux"
import { getInvalidFiles } from "App/files-manager/selectors/get-invalid-files.selector"
import {
ModalContent,
ModalDialog,
RoundIconWrapper,
} from "App/ui/components/modal-dialog"
import React from "react"
import { ModalSize } from "App/__deprecated__/renderer/components/core/modal/modal.interface"
import { intl } from "App/__deprecated__/renderer/utils/intl"
import Icon from "App/__deprecated__/renderer/components/core/icon/icon.component"
import { IconType } from "App/__deprecated__/renderer/components/core/icon/icon-type"
import Text, {
TextDisplayStyle,
} from "App/__deprecated__/renderer/components/core/text/text.component"
import { resetUploadingState } from "App/files-manager/actions"
import styled from "styled-components"
import {
fontWeight,
textColor,
} from "App/__deprecated__/renderer/styles/theming/theme-getters"
import { ipcRenderer } from "electron-better-ipc"
import { HelpActions } from "App/__deprecated__/common/enums/help-actions.enum"

const messages = defineMessages({
title: {
id: "module.filesManager.invalidFiledModalTitle",
},
filesInfo: {
id: "module.filesManager.invalidFiledModalFilesInfo",
},
helpInfo: {
id: "module.filesManager.invalidFiledModalHelpInfo",
},
})

const StyledLink = styled.a`
text-decoration: underline;
cursor: pointer;
font-size: 1.4rem;
font-weight: ${fontWeight("default")};
color: ${textColor("action")};
`
const StyledModalContent = styled(ModalContent)`
p {
text-align: left;
}
`

export const InvalidFilesModal: FunctionComponent = ({ ...props }) => {
const invalidFiles = useSelector(getInvalidFiles)
const openHelpWindow = () => ipcRenderer.callMain(HelpActions.OpenWindow)

const dispatch = useDispatch()
return (
<ModalDialog
size={ModalSize.Small}
title={intl.formatMessage(messages.title)}
open={!!invalidFiles.length}
closeButton
onCloseButton={() => {
dispatch(resetUploadingState())
}}
{...props}
>
<StyledModalContent>
<RoundIconWrapper>
<Icon type={IconType.Info} width={3.2} />
</RoundIconWrapper>
<Text
displayStyle={TextDisplayStyle.Paragraph4}
color="secondary"
message={messages.filesInfo}
/>
<Text
displayStyle={TextDisplayStyle.Paragraph4}
color="secondary"
message={{
...messages.helpInfo,
values: {
link: (
<StyledLink onClick={openHelpWindow}>help pages</StyledLink>
),
},
}}
/>
</StyledModalContent>
</ModalDialog>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import PendingUploadModal from "App/files-manager/components/pending-upload-moda
import DuplicatedFilesModal from "App/files-manager/components/duplicated-files-modal/duplicated-files-modal.component"
import UnsupportedFileFormatModal from "App/files-manager/components/unsupported-file-format-modal/unsupported-file-format-modal.component"
import UnsupportedFileSizeModal from "App/files-manager/components/unsupported-file-size-modal/unsupported-file-size-modal.component"
import { InvalidFilesModal } from "../invalid-files-modal/invalid-files-modal.component"

const messages = defineMessages({
uploadingModalInfo: { id: "module.filesManager.uploadingModalInfo" },
Expand Down Expand Up @@ -100,6 +101,7 @@ export const UploadFilesModals: FunctionComponent<UploadFilesModalProps> = ({
<DuplicatedFilesModal />
<UnsupportedFileFormatModal />
<UnsupportedFileSizeModal />
<InvalidFilesModal />
</>
)
}
1 change: 1 addition & 0 deletions packages/app/src/files-manager/constants/event.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export enum FilesManagerEvent {
AbortPendingUpload = "FILES_MANAGER_ABORT_PENDING_UPLOAD",
ContinuePendingUpload = "FILES_MANAGER_CONTINUE_PENDING_UPLOAD",
SetDuplicatedFiles = "FILES_MANAGER_SET_DUPLICATED_FILES",
SetInvalidFiles = "FILES_MANAGER_SET_INVALID_FILES",
ResetFiles = "FILES_MANAGER_RESET_FILES",
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ const supportedFiles = eligibleFormat.map((extension) => `file.${extension}`)

describe("`checkFilesExtensions` helper", () => {
test("all correct extensions", () => {
expect(checkFilesExtensions(supportedFiles)).toBeTruthy()
expect(checkFilesExtensions(supportedFiles)).toEqual({
validFiles: supportedFiles,
invalidFiles: [],
})
})

test("empty files array", () => {
expect(checkFilesExtensions([])).toBeTruthy()
expect(checkFilesExtensions([])).toEqual({
validFiles: [],
invalidFiles: [],
})
})

test("at least one unsupported extension", () => {
const unsupportedFiles = [...supportedFiles, "file.unsupported"]
expect(checkFilesExtensions(unsupportedFiles)).toBeFalsy()
const unsupportedFiles = ["file.unsupported"]
const allFiles = [...supportedFiles, ...unsupportedFiles]
expect(checkFilesExtensions(allFiles)).toEqual({
validFiles: supportedFiles,
invalidFiles: unsupportedFiles,
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@

import { eligibleFormat } from "App/files-manager/constants/eligible-format.constant"

export const checkFilesExtensions = (filesPaths: string[]): boolean => {
return filesPaths.every((filePath) => {
return eligibleFormat.includes(
(filePath.split(".").pop() ?? "").toLocaleLowerCase()
)
})
export const checkFilesExtensions = (
filesPaths: string[]
): { validFiles: string[]; invalidFiles: string[] } => {
const isPathEligible = (path: string) =>
eligibleFormat.includes((path.split(".").pop() ?? "").toLocaleLowerCase())
const validFiles = filesPaths.filter((filePath) => isPathEligible(filePath))
const invalidFiles = filesPaths.filter(
(filePath) => !isPathEligible(filePath)
)

return { validFiles, invalidFiles }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export interface FilesManagerState {
uploadBlocked: boolean
uploadPendingFiles: string[]
duplicatedFiles: string[]
invalidFiles: string[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
setDuplicatedFiles,
resetUploadingStateAfterSuccess,
resetFiles,
setInvalidFiles,
} from "App/files-manager/actions"
import { changeLocation } from "App/core/actions"
import { FilesManagerState } from "App/files-manager/reducers/files-manager.interface"
Expand All @@ -42,6 +43,7 @@ export const initialState: FilesManagerState = {
error: null,
uploadPendingFiles: [],
duplicatedFiles: [],
invalidFiles: [],
}

export const filesManagerReducer = createReducer<FilesManagerState>(
Expand Down Expand Up @@ -173,6 +175,7 @@ export const filesManagerReducer = createReducer<FilesManagerState>(
uploadingFileCount: 0,
uploadBlocked: false,
duplicatedFiles: [],
invalidFiles: [],
}
})
.addCase(resetUploadingStateAfterSuccess, (state) => {
Expand Down Expand Up @@ -203,6 +206,9 @@ export const filesManagerReducer = createReducer<FilesManagerState>(
.addCase(setDuplicatedFiles, (state, action) => {
state.duplicatedFiles = action.payload
})
.addCase(setInvalidFiles, (state, action) => {
state.invalidFiles = action.payload
})
.addCase(resetFiles, (state, _) => {
state.files = null
})
Expand Down
Loading

0 comments on commit 0bcabc6

Please sign in to comment.