From 0f7a30b8991c56a2ed2dcacfaee7aec82d589d73 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 16 Aug 2018 17:05:56 +0200 Subject: [PATCH] MOBILE-2546 ios: Fix split view animation when recording audio --- src/components/split-view/split-view.ts | 14 ++++- .../fileuploader/providers/fileuploader.ts | 54 ++++++++++++++++++- src/core/fileuploader/providers/helper.ts | 10 ++-- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/components/split-view/split-view.ts b/src/components/split-view/split-view.ts index 86eae75ce..ec7dbd4a4 100644 --- a/src/components/split-view/split-view.ts +++ b/src/components/split-view/split-view.ts @@ -16,6 +16,7 @@ import { Component, ViewChild, Input, ElementRef, OnInit, Optional, OnDestroy } from '@angular/core'; import { NavController, Nav, ViewController } from 'ionic-angular'; +import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { Subscription } from 'rxjs'; /** @@ -53,12 +54,18 @@ export class CoreSplitViewComponent implements OnInit, OnDestroy { protected detailsDidEnterSubscription: Subscription; protected masterCanLeaveOverridden = false; protected originalMasterCanLeave: Function; + protected ignoreSplitChanged = false; + protected audioCaptureSubscription: Subscription; // Empty placeholder for the 'detail' page. detailPage: any = null; - constructor(@Optional() private masterNav: NavController, element: ElementRef) { + constructor(@Optional() private masterNav: NavController, element: ElementRef, fileUploaderProvider: CoreFileUploaderProvider) { this.element = element.nativeElement; + + this.audioCaptureSubscription = fileUploaderProvider.onAudioCapture.subscribe((starting) => { + this.ignoreSplitChanged = starting; + }); } /** @@ -184,6 +191,10 @@ export class CoreSplitViewComponent implements OnInit, OnDestroy { * @param {Boolean} isOn If it fits both panels at the same time. */ onSplitPaneChanged(isOn: boolean): void { + if (this.ignoreSplitChanged) { + return; + } + this.isEnabled = isOn; if (this.masterNav && this.detailNav) { (isOn) ? this.activateSplitView() : this.deactivateSplitView(); @@ -228,5 +239,6 @@ export class CoreSplitViewComponent implements OnInit, OnDestroy { */ ngOnDestroy(): void { this.detailsDidEnterSubscription && this.detailsDidEnterSubscription.unsubscribe(); + this.audioCaptureSubscription.unsubscribe(); } } diff --git a/src/core/fileuploader/providers/fileuploader.ts b/src/core/fileuploader/providers/fileuploader.ts index 4effe967c..166982d34 100644 --- a/src/core/fileuploader/providers/fileuploader.ts +++ b/src/core/fileuploader/providers/fileuploader.ts @@ -14,7 +14,8 @@ import { Injectable } from '@angular/core'; import { Platform } from 'ionic-angular'; -import { MediaFile } from '@ionic-native/media-capture'; +import { Camera, CameraOptions } from '@ionic-native/camera'; +import { MediaCapture, MediaFile, CaptureError, CaptureAudioOptions, CaptureVideoOptions } from '@ionic-native/media-capture'; import { TranslateService } from '@ngx-translate/core'; import { CoreFileProvider } from '@providers/file'; import { CoreFilepoolProvider } from '@providers/filepool'; @@ -25,6 +26,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreWSFileUploadOptions } from '@providers/ws'; +import { Subject } from 'rxjs'; /** * File upload options. @@ -47,10 +49,16 @@ export class CoreFileUploaderProvider { protected logger; + // Observers to notify when a media file starts/stops being recorded/selected. + onGetPicture: Subject = new Subject(); + onAudioCapture: Subject = new Subject(); + onVideoCapture: Subject = new Subject(); + constructor(logger: CoreLoggerProvider, private fileProvider: CoreFileProvider, private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider, private sitesProvider: CoreSitesProvider, private timeUtils: CoreTimeUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider, private filepoolProvider: CoreFilepoolProvider, - private platform: Platform, private translate: TranslateService) { + private platform: Platform, private translate: TranslateService, private mediaCapture: MediaCapture, + private camera: Camera) { this.logger = logger.getInstance('CoreFileUploaderProvider'); } @@ -89,6 +97,34 @@ export class CoreFileUploaderProvider { return false; } + /** + * Start the audio recorder application and return information about captured audio clip files. + * + * @param {CaptureAudioOptions} options Options. + * @return {Promise} Promise resolved with the result. + */ + captureAudio(options: CaptureAudioOptions): Promise { + this.onAudioCapture.next(true); + + return this.mediaCapture.captureAudio(options).finally(() => { + this.onAudioCapture.next(false); + }); + } + + /** + * Start the video recorder application and return information about captured video clip files. + * + * @param {CaptureVideoOptions} options Options. + * @return {Promise} Promise resolved with the result. + */ + captureVideo(options: CaptureVideoOptions): Promise { + this.onVideoCapture.next(true); + + return this.mediaCapture.captureVideo(options).finally(() => { + this.onVideoCapture.next(false); + }); + } + /** * Clear temporary attachments to be uploaded. * Attachments already saved in an offline store will NOT be deleted. @@ -194,6 +230,20 @@ export class CoreFileUploaderProvider { return options; } + /** + * Take a picture or video, or load one from the library. + * + * @param {CameraOptions} options Options. + * @return {Promise} Promise resolved with the result. + */ + getPicture(options: CameraOptions): Promise { + this.onGetPicture.next(true); + + return this.camera.getPicture(options).finally(() => { + this.onGetPicture.next(false); + }); + } + /** * Get the files stored in a folder, marking them as offline. * diff --git a/src/core/fileuploader/providers/helper.ts b/src/core/fileuploader/providers/helper.ts index fc0c6abf8..df0d8fb21 100644 --- a/src/core/fileuploader/providers/helper.ts +++ b/src/core/fileuploader/providers/helper.ts @@ -14,7 +14,7 @@ import { Injectable } from '@angular/core'; import { ActionSheetController, ActionSheet, Platform } from 'ionic-angular'; -import { MediaCapture, MediaFile } from '@ionic-native/media-capture'; +import { MediaFile } from '@ionic-native/media-capture'; import { Camera, CameraOptions } from '@ionic-native/camera'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '@providers/app'; @@ -40,7 +40,7 @@ export class CoreFileUploaderHelperProvider { private fileUploaderProvider: CoreFileUploaderProvider, private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, private fileProvider: CoreFileProvider, private utils: CoreUtilsProvider, private actionSheetCtrl: ActionSheetController, private uploaderDelegate: CoreFileUploaderDelegate, - private mediaCapture: MediaCapture, private camera: Camera, private platform: Platform) { + private camera: Camera, private platform: Platform) { this.logger = logger.getInstance('CoreFileUploaderProvider'); } @@ -450,10 +450,10 @@ export class CoreFileUploaderHelperProvider { * @return {Promise} Promise resolved when done. */ uploadAudioOrVideo(isAudio: boolean, maxSize: number, upload?: boolean, mimetypes?: string[]): Promise { - this.logger.debug('Trying to record a video file'); + this.logger.debug('Trying to record a ' + (isAudio ? 'audio' : 'video') + ' file'); const options = { limit: 1, mimetypes: mimetypes }, - promise = isAudio ? this.mediaCapture.captureAudio(options) : this.mediaCapture.captureVideo(options); + promise = isAudio ? this.fileUploaderProvider.captureAudio(options) : this.fileUploaderProvider.captureVideo(options); // The mimetypes param is only for desktop apps, the Cordova plugin doesn't support it. return promise.then((medias) => { @@ -549,7 +549,7 @@ export class CoreFileUploaderHelperProvider { } } - return this.camera.getPicture(options).then((path) => { + return this.fileUploaderProvider.getPicture(options).then((path) => { const error = this.fileUploaderProvider.isInvalidMimetype(mimetypes, path); // Verify that the mimetype is supported. if (error) { return Promise.reject(error);