Skip to content

Commit

Permalink
fix import ui states
Browse files Browse the repository at this point in the history
  • Loading branch information
jomapp committed Jan 9, 2025
1 parent c636d43 commit 67d6abf
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 62 deletions.
20 changes: 17 additions & 3 deletions packages/node-mimimi/src/importer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ pub enum ImportParams {
/// keep in sync with TutanotaConstants.ts
#[cfg_attr(feature = "javascript", napi_derive::napi)]
#[cfg_attr(not(feature = "javascript"), derive(Clone))]
#[derive(PartialEq, Default)]
#[cfg_attr(test, derive(Debug))]
#[derive(PartialEq, Default, Debug)]
#[repr(u8)]
pub enum ImportStatus {
#[default]
Expand All @@ -158,6 +157,7 @@ pub enum ImportStatus {
Canceled = 2,
Finished = 3,
Error = 4,
ServiceUnavailable = 5,
}

/// A running import can be stopped or paused
Expand Down Expand Up @@ -614,7 +614,8 @@ impl Importer {
local_state.current_status == ImportStatus::Finished
|| local_state.current_status == ImportStatus::Canceled
|| local_state.current_status == ImportStatus::Paused,
"only cancel and finished should be final state"
"only cancel and finished should be final state {:?}",
local_state.current_status
);

// we reached final state before making first call, was either empty mails or was cancelled before making first post call
Expand Down Expand Up @@ -741,6 +742,19 @@ impl Importer {
}
}

if import_progress_action == ImportProgressAction::Pause {
self.update_state(|mut state| state.change_status(ImportStatus::Paused))
.await;
} else if import_progress_action == ImportProgressAction::Stop {
self.update_state(|mut state| state.change_status(ImportStatus::Canceled))
.await;
Self::delete_import_dir(&self.import_directory)?;
}

let current_state = self.get_state(|state| state.clone()).await;
Importer::mark_remote_final_state(&self.essentials.logged_in_sdk, &current_state)
.await?;

Ok(())
}

Expand Down
49 changes: 20 additions & 29 deletions packages/node-mimimi/src/importer_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,17 @@ impl ImporterApi {
Ok(_) => {},
Err(e) => {
log::error!("Importer task failed: {:?}", e);
inner
.update_state(|mut state| state.change_status(ImportStatus::Error))
.await;
if let ImportError::NoImportFeature = e {
inner
.update_state(|mut state| {
state.change_status(ImportStatus::ServiceUnavailable)
})
.await;
} else {
inner
.update_state(|mut state| state.change_status(ImportStatus::Error))
.await;
};
},
};
});
Expand Down Expand Up @@ -234,32 +242,15 @@ impl ImporterApi {
let mut local_import_state = local_import_state.lock().await;
local_import_state.import_progress_action = import_progress_action;

match import_progress_action {
ImportProgressAction::Continue => Ok(()),

ImportProgressAction::Pause => {
local_import_state.current_status = ImportStatus::Paused;
let logged_in_sdk = ImporterApi::create_sdk(tuta_credentials).await?;
Importer::mark_remote_final_state(&logged_in_sdk, &local_import_state)
.await?;

Ok(())
},

ImportProgressAction::Stop => {
let previous_status = local_import_state.current_status;
local_import_state.current_status = ImportStatus::Canceled;
let logged_in_sdk = ImporterApi::create_sdk(tuta_credentials).await?;
Importer::mark_remote_final_state(&logged_in_sdk, &local_import_state)
.await?;

if previous_status != ImportStatus::Running {
Importer::delete_import_dir(&import_directory_path)?;
}

Ok(())
},
}
if local_import_state.current_status != ImportStatus::Running
&& import_progress_action == ImportProgressAction::Stop
{
local_import_state.current_status = ImportStatus::Canceled;
Importer::delete_import_dir(&import_directory_path)?;
let logged_in_sdk = ImporterApi::create_sdk(tuta_credentials).await?;
Importer::mark_remote_final_state(&logged_in_sdk, &local_import_state).await?;
};
Ok(())
},

None => {
Expand Down
82 changes: 53 additions & 29 deletions src/mail-app/mail/import/MailImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export class MailImporter {
if (isEmpty(filePaths)) return
if (!this.shouldShowStartButton()) throw new ProgrammingError("can't change state to starting")

this.resetStatus()

const apiUrl = getApiBaseUrl(this.domainConfigProvider.getCurrentDomainConfig())
const ownerGroup = assertNotNull(targetFolder._ownerGroup)
const userId = this.loginController.getUserController().userId
Expand All @@ -146,24 +148,26 @@ export class MailImporter {
this.isLastRunFailed = false
this.startProgressEstimation()
m.redraw()
await importFacade.startFileImport((await this.getMailbox())._id, apiUrl, unencryptedCredentials, ownerGroup, targetFolder._id, filePaths)

try {
await importFacade.startFileImport((await this.getMailbox())._id, apiUrl, unencryptedCredentials, ownerGroup, targetFolder._id, filePaths)
} catch (e) {
this.uiStatus = UiImportStatus.Error
console.log("could not start file import", e)
m.redraw()
}
}

async onPauseBtnClick() {
if (this.uiStatus !== UiImportStatus.Running) {
throw new ProgrammingError("can't change state to pausing")
}

this.stopProgressEstimation()
this.uiStatus = UiImportStatus.Pausing
this.stopProgressEstimation()
m.redraw()

const importFacade = assertNotNull(this.nativeMailImportFacade)
const apiUrl = getApiBaseUrl(this.domainConfigProvider.getCurrentDomainConfig())
const userId = this.loginController.getUserController().userId

const unencryptedCredentials = assertNotNull(await this.credentialsProvider?.getDecryptedCredentialsByUserId(userId))
await importFacade.setProgressAction((await this.getMailbox())._id, apiUrl, unencryptedCredentials, ImportProgressAction.Pause)
await this.setProgressAction(ImportProgressAction.Pause)
}

async onResumeBtnClick() {
Expand All @@ -181,27 +185,27 @@ export class MailImporter {
const unencryptedCredentials = assertNotNull(await this.credentialsProvider?.getDecryptedCredentialsByUserId(userId))
const resumableStateId = assertNotNull(this.activeImport?.remoteStateId)

await importFacade.resumeFileImport((await this.getMailbox())._id, apiUrl, unencryptedCredentials, resumableStateId)
try {
await importFacade.resumeFileImport((await this.getMailbox())._id, apiUrl, unencryptedCredentials, resumableStateId)
} catch (e) {
this.uiStatus = UiImportStatus.Error
console.log("could not resume file import", e)
m.redraw()
}
}

async onCancelBtnClick() {
if (!this.shouldShowCancelButton()) throw new ProgrammingError("can't change state to cancelling")
const importFacade = assertNotNull(this.nativeMailImportFacade)

this.stopProgressEstimation()

this.uiStatus = UiImportStatus.Cancelling
this.stopProgressEstimation()
m.redraw()

const apiUrl = getApiBaseUrl(this.domainConfigProvider.getCurrentDomainConfig())
const userId = this.loginController.getUserController().userId

const unencryptedCredentials = assertNotNull(await this.credentialsProvider?.getDecryptedCredentialsByUserId(userId))
await importFacade.setProgressAction((await this.getMailbox())._id, apiUrl, unencryptedCredentials, ImportProgressAction.Stop)
await this.setProgressAction(ImportProgressAction.Stop)
}

shouldShowStartButton() {
return this.wsConnectionOnline && this.uiStatus === UiImportStatus.Idle
return this.wsConnectionOnline && (this.uiStatus === UiImportStatus.Idle || this.uiStatus === UiImportStatus.Error)
}

shouldShowImportStatus(): boolean {
Expand All @@ -215,19 +219,22 @@ export class MailImporter {
}

shouldShowPauseButton(): boolean {
return this.wsConnectionOnline && (this.uiStatus === UiImportStatus.Running || this.uiStatus === UiImportStatus.Pausing)
return (
this.wsConnectionOnline &&
(this.uiStatus === UiImportStatus.Running || this.uiStatus === UiImportStatus.Starting || this.uiStatus === UiImportStatus.Pausing)
)
}

shouldDisablePauseButton(): boolean {
return this.wsConnectionOnline && this.uiStatus === UiImportStatus.Pausing
return (this.wsConnectionOnline && this.uiStatus === UiImportStatus.Pausing) || this.uiStatus === UiImportStatus.Starting
}

shouldShowResumeButton(): boolean {
return this.wsConnectionOnline && (this.uiStatus === UiImportStatus.Paused || this.uiStatus === UiImportStatus.Resuming)
}

shouldDisableResumeButton(): boolean {
return !this.wsConnectionOnline || this.uiStatus === UiImportStatus.Resuming
return !this.wsConnectionOnline || this.uiStatus === UiImportStatus.Resuming || this.uiStatus === UiImportStatus.Starting
}

shouldShowCancelButton(): boolean {
Expand All @@ -241,7 +248,12 @@ export class MailImporter {
}

shouldDisableCancelButton(): boolean {
return !this.wsConnectionOnline || this.uiStatus === UiImportStatus.Cancelling || this.uiStatus === UiImportStatus.Pausing
return (
!this.wsConnectionOnline ||
this.uiStatus === UiImportStatus.Cancelling ||
this.uiStatus === UiImportStatus.Pausing ||
this.uiStatus === UiImportStatus.Starting
)
}

shouldShowProcessedMails(): boolean {
Expand Down Expand Up @@ -324,7 +336,7 @@ export class MailImporter {
*/
async onNewLocalImportMailState(localImportMailState: LocalImportMailState): Promise<void> {
const previousState = this.activeImport
if (localImportMailState.status == ImportStatus.Error) {
if (localImportMailState.status == ImportStatus.ServiceUnavailable) {
this.resetStatus()
if (!this.isLastRunFailed) {
this.isLastRunFailed = true
Expand Down Expand Up @@ -396,12 +408,7 @@ export class MailImporter {
this.stopProgressEstimation()
this.uiStatus = UiImportStatus.Paused
m.redraw()
const importFacade = assertNotNull(this.nativeMailImportFacade)
const apiUrl = getApiBaseUrl(this.domainConfigProvider.getCurrentDomainConfig())
const userId = this.loginController.getUserController().userId

const unencryptedCredentials = assertNotNull(await this.credentialsProvider?.getDecryptedCredentialsByUserId(userId))
await importFacade.setProgressAction((await this.getMailbox())._id, apiUrl, unencryptedCredentials, ImportProgressAction.Pause)
await this.setProgressAction(ImportProgressAction.Pause)
}
})
}
Expand All @@ -418,6 +425,20 @@ export class MailImporter {
}
}

async setProgressAction(progressAction: ImportProgressAction): Promise<void> {
const importFacade = assertNotNull(this.nativeMailImportFacade)

const apiUrl = getApiBaseUrl(this.domainConfigProvider.getCurrentDomainConfig())
const userId = this.loginController.getUserController().userId
const unencryptedCredentials = assertNotNull(await this.credentialsProvider?.getDecryptedCredentialsByUserId(userId))

try {
await importFacade.setProgressAction((await this.getMailbox())._id, apiUrl, unencryptedCredentials, progressAction)
} catch (e) {
console.log(`could execute progress action ${progressAction} for file import`, e)
}
}

async entityEventsReceived(updates: ReadonlyArray<EntityUpdateData>): Promise<void> {
for (const update of updates) {
if (isUpdateForTypeRef(ImportMailStateTypeRef, update)) {
Expand Down Expand Up @@ -463,6 +484,8 @@ function importStatusToUiImportStatus(importStatus: ImportStatus) {
return UiImportStatus.Running
case ImportStatus.Error:
return UiImportStatus.Error
case ImportStatus.ServiceUnavailable:
return UiImportStatus.Error
}
}

Expand All @@ -472,6 +495,7 @@ export const enum ImportStatus {
Canceled = 2,
Finished = 3,
Error = 4,
ServiceUnavailable = 5,
}

export function isFinalisedImport(remoteImportStatus: ImportStatus): boolean {
Expand Down
4 changes: 3 additions & 1 deletion src/mail-app/settings/MailImportSettingsViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { formatDate } from "../../common/misc/Formatter.js"
export class MailImportSettingsViewer implements UpdatableSettingsViewer {
private foldersForMailbox: FolderSystem | undefined
private selectedTargetFolder: MailFolder | null = null
private isImportHistoryExpanded: boolean = false
private isImportHistoryExpanded: boolean = true

private mailImporter: MailImporter
private fileApp: NativeFileApp | null
Expand Down Expand Up @@ -353,5 +353,7 @@ export function getImportStatusTranslationKey(importStatus: ImportStatus): Trans
return "mailImportStatusFinished_label"
case ImportStatus.Error:
return "mailImportStatusError_label"
case ImportStatus.ServiceUnavailable:
return "mailImportStatusError_label"
}
}

0 comments on commit 67d6abf

Please sign in to comment.