Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP-2191] I want only supported files to be uploaded #1393

Merged
merged 10 commits into from
Sep 25, 2023
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 @@ -876,7 +882,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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it suppose to be in polish? :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was synced with phrase, i guess that's some legacy data that still lingers there

}
}
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