Skip to content

Commit

Permalink
Merge pull request #1818 from numbersprotocol/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
bafu committed Jul 14, 2022
2 parents 031b130 + 016d104 commit 6961ad8
Show file tree
Hide file tree
Showing 18 changed files with 297 additions and 69 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Expand Up @@ -15,6 +15,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fix withdraw page the text color

## 0.61.0 - 2022-07-14

### Added

- Show discard/confirm capture before upload
- Send generate SEO img & description on share asset

### Fixed

- Remove capture after discard/confirm

## 0.60.1 - 2022-07-06

### Fixed
Expand Down
8 changes: 3 additions & 5 deletions README.md
Expand Up @@ -77,12 +77,10 @@ cordova-res android --skip-config --copy

#### Android

If your operating system is Linux, set the `linuxAndroidStudioPath` in `capacitor.config.json`. For example,
If your operating system is Linux, set the environment variable `CAPACITOR_ANDROID_STUDIO_PATH` for your Android Studio. The default value is `/usr/local/android-studio/bin/studio.sh`.

```json
{
"linuxAndroidStudioPath": "/home/username/android-studio/bin/studio.sh"
}
```sh
export CAPACITOR_ANDROID_STUDIO_PATH="/home/username/android-studio/bin/studio.sh"
```

Before running the app with Android Studio, build and sync the dependencies and web assets.
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Expand Up @@ -6,8 +6,8 @@ android {
applicationId "io.numbersprotocol.capturelite"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 422
versionName "0.60.2"
versionCode 430
versionName "0.61.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "capture-lite",
"version": "0.60.2",
"version": "0.61.0",
"author": "numbersprotocol",
"homepage": "https://numbersprotocol.io/",
"scripts": {
Expand Down
@@ -1,5 +1,5 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RouterModule, Routes } from '@angular/router';

import { CustomCameraPage } from './custom-camera.page';

Expand Down
3 changes: 2 additions & 1 deletion src/app/features/home/custom-camera/custom-camera.module.ts
Expand Up @@ -6,6 +6,7 @@ import { SharedModule } from '../../../shared/shared.module';
import { CustomCameraPageRoutingModule } from './custom-camera-routing.module';
import { CustomCameraPage } from './custom-camera.page';
import { CustomCameraService } from './custom-camera.service';
import { PrePublishModeComponent } from './pre-publish-mode/pre-publish-mode.component';

@NgModule({
imports: [
Expand All @@ -16,6 +17,6 @@ import { CustomCameraService } from './custom-camera.service';
JoyrideModule.forChild(),
],
providers: [CustomCameraService],
declarations: [CustomCameraPage],
declarations: [CustomCameraPage, PrePublishModeComponent],
})
export class CustomCameraPageModule {}
117 changes: 65 additions & 52 deletions src/app/features/home/custom-camera/custom-camera.page.html
Expand Up @@ -3,61 +3,74 @@
[style.--background]="'transparent'"
*transloco="let t"
>
<div id="camera-flash-placeholder"></div>
<div
class="select-from-go-pro-camera-button"
*ngIf="lastConnectedGoProDevice$ | ngrxPush"
(click)="captureFromGoPro()"
>
GoPro
<mat-icon> featured_video </mat-icon>
</div>

<mat-icon
class="close-camera-button"
(click)="leaveCustomCamera()"
joyrideStep="highlightCustomCameraCloseButton"
[title]="t('userGuide.cameraUsageGuide')"
[text]="t('userGuide.afterTakingPhotosOrRecordingVideosCloseAndGoBackHome')"
>
close
</mat-icon>

<div class="camera-buttons-container">
<mat-icon class="temporarily-hidden" id="gallery-icon">
video_collection
</mat-icon>

<circle-progress
(click)="onPress()"
[maxTime]="maxRecordTimeInMilliseconds"
ngxLongPress2
(onLongPress)="onLongPress()"
(onLongPressing)="onLongPressing($event)"
(onReleasePressing)="onReleasePressing()"
[percent]="curRecordTimeInPercent"
[radius]="38"
[outerStrokeWidth]="6"
[innerStrokeWidth]="4"
[outerStrokeColor]="'#78C000'"
[innerStrokeColor]="'#F2F2F2'"
[showTitle]="false"
[showUnits]="false"
[showSubtitle]="false"
[animation]="false"
[animationDuration]="0"
joyrideStep="highlightCustomCameraCaptureButton"
[title]="t('userGuide.cameraUsageGuide')"
[text]="t('userGuide.tapToTakeAPhotoAndLongPressToRecordVideo')"
></circle-progress>
<ng-container *ngIf="(mode$ | ngrxPush) === 'capture'">
<div id="camera-flash-placeholder"></div>
<div
class="select-from-go-pro-camera-button"
*ngIf="lastConnectedGoProDevice$ | ngrxPush"
(click)="captureFromGoPro()"
>
GoPro
<mat-icon> featured_video </mat-icon>
</div>

<mat-icon
(click)="flipCamera()"
joyrideStep="highlightCustomCameraFlipButton"
class="close-camera-button"
(click)="leaveCustomCamera()"
joyrideStep="highlightCustomCameraCloseButton"
[title]="t('userGuide.cameraUsageGuide')"
[text]="t('userGuide.flipTheCameraToSwitchBetweenFrontAndBackCameras')"
[text]="
t('userGuide.afterTakingPhotosOrRecordingVideosCloseAndGoBackHome')
"
>
flip_camera_android
close
</mat-icon>
</div>

<div class="camera-buttons-container">
<mat-icon class="temporarily-hidden" id="gallery-icon">
video_collection
</mat-icon>

<circle-progress
(click)="onPress()"
[maxTime]="maxRecordTimeInMilliseconds"
ngxLongPress2
(onLongPress)="onLongPress()"
(onLongPressing)="onLongPressing($event)"
(onReleasePressing)="onReleasePressing()"
[percent]="curRecordTimeInPercent"
[radius]="38"
[outerStrokeWidth]="6"
[innerStrokeWidth]="4"
[outerStrokeColor]="'#78C000'"
[innerStrokeColor]="'#F2F2F2'"
[showTitle]="false"
[showUnits]="false"
[showSubtitle]="false"
[animation]="false"
[animationDuration]="0"
joyrideStep="highlightCustomCameraCaptureButton"
[title]="t('userGuide.cameraUsageGuide')"
[text]="t('userGuide.tapToTakeAPhotoAndLongPressToRecordVideo')"
></circle-progress>

<mat-icon
(click)="flipCamera()"
joyrideStep="highlightCustomCameraFlipButton"
[title]="t('userGuide.cameraUsageGuide')"
[text]="t('userGuide.flipTheCameraToSwitchBetweenFrontAndBackCameras')"
>
flip_camera_android
</mat-icon>
</div>
</ng-container>
<ng-container *ngIf="(mode$ | ngrxPush) === 'pre-publish'">
<app-pre-publish-mode
[curCaptureFilePath]="curCaptureFilePath"
[curCaptureMimeType]="curCaptureMimeType"
[curCaptureSrc]="curCaptureSrc"
(confirm)="confirmCurrentCapture()"
(discard)="discardCurrentCapture()"
></app-pre-publish-mode>
</ng-container>
</ion-content>
47 changes: 45 additions & 2 deletions src/app/features/home/custom-camera/custom-camera.page.ts
Expand Up @@ -2,9 +2,10 @@
import { Location } from '@angular/common';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { PluginListenerHandle } from '@capacitor/core';
import { Capacitor, PluginListenerHandle } from '@capacitor/core';
import { UntilDestroy } from '@ngneat/until-destroy';
import { CaptureResult, PreviewCamera } from '@numbersprotocol/preview-camera';
import { BehaviorSubject } from 'rxjs';
import { ErrorService } from '../../../shared/error/error.service';
import { UserGuideService } from '../../../shared/user-guide/user-guide.service';
import { GoProBluetoothService } from '../../settings/go-pro/services/go-pro-bluetooth.service';
Expand Down Expand Up @@ -33,6 +34,13 @@ export class CustomCameraPage implements OnInit, OnDestroy {

curSessionCaptureMediaItems: CustomCameraMediaItem[] = [];

mode$ = new BehaviorSubject<'capture' | 'pre-publish'>('capture');

curCaptureFilePath?: string;
curCaptureMimeType?: 'image/jpeg' | 'video/mp4';
curCaptureType?: 'image' | 'video' = 'image';
curCaptureSrc?: string;

readonly lastConnectedGoProDevice$ =
this.goProBluetoothService.lastConnectedDevice$;

Expand Down Expand Up @@ -85,7 +93,18 @@ export class CustomCameraPage implements OnInit, OnDestroy {
if (data.errorMessage) {
await this.errorService.toastError$(data.errorMessage).toPromise();
} else if (data.filePath) {
this.customCameraService.uploadToCapture(data.filePath, type);
const filePath = data.filePath;

let mimeType: 'image/jpeg' | 'video/mp4' = 'image/jpeg';
if (type === 'video') mimeType = 'video/mp4';

this.curCaptureFilePath = filePath;
this.curCaptureMimeType = mimeType;
this.curCaptureType = type;
this.curCaptureSrc = Capacitor.convertFileSrc(filePath);
this.mode$.next('pre-publish');

this.stopPreviewCamera();
}
}

Expand Down Expand Up @@ -131,6 +150,23 @@ export class CustomCameraPage implements OnInit, OnDestroy {
}
}

discardCurrentCapture() {
this.mode$.next('capture');
this.startPreviewCamera();
this.removeCurrentCapture();
}

async confirmCurrentCapture() {
if (this.curCaptureFilePath && this.curCaptureType) {
await this.customCameraService.uploadToCapture(
this.curCaptureFilePath,
this.curCaptureType
);
this.removeCurrentCapture();
}
this.leaveCustomCamera();
}

async leaveCustomCamera() {
return this.location.back();
}
Expand All @@ -142,6 +178,13 @@ export class CustomCameraPage implements OnInit, OnDestroy {
});
}

private removeCurrentCapture() {
this.customCameraService.removeFile(this.curCaptureFilePath);
this.curCaptureFilePath = undefined;
this.curCaptureMimeType = undefined;
this.curCaptureSrc = undefined;
}

// eslint-disable-next-line class-methods-use-this
private debugOnlyPreventContextMenuFromLongPressContextMenu() {
// Prevent showing context menu on long press
Expand Down
13 changes: 11 additions & 2 deletions src/app/features/home/custom-camera/custom-camera.service.ts
@@ -1,10 +1,12 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { Capacitor } from '@capacitor/core';
import { FilesystemPlugin } from '@capacitor/filesystem';
import { TranslocoService } from '@ngneat/transloco';
import { PreviewCamera } from '@numbersprotocol/preview-camera';
import { BehaviorSubject } from 'rxjs';
import { FILESYSTEM_PLUGIN } from '../../../shared/capacitor-plugins/capacitor-plugins.module';
import { CaptureService } from '../../../shared/capture/capture.service';
import { ErrorService } from '../../../shared/error/error.service';
import { blobToBase64 } from '../../../utils/encoding/encoding';
Expand All @@ -27,7 +29,9 @@ export class CustomCameraService {
private readonly httpClient: HttpClient,
private readonly captureService: CaptureService,
private readonly errorService: ErrorService,
private readonly translocoService: TranslocoService
private readonly translocoService: TranslocoService,
@Inject(FILESYSTEM_PLUGIN)
private readonly filesystemPlugin: FilesystemPlugin
) {}

private mediaItemFromFilePath(
Expand Down Expand Up @@ -89,6 +93,11 @@ export class CustomCameraService {
return PreviewCamera.stopRecord().catch(() => ({}));
}

async removeFile(filePath: string | undefined) {
if (!filePath) return;
await this.filesystemPlugin.deleteFile({ path: filePath });
}

private changeGlobalCSSBackgroundToTransparent() {
document.querySelector('body')?.classList.add(this.globalCSSClass);
document.querySelector('ion-app')?.classList.add(this.globalCSSClass);
Expand Down
@@ -0,0 +1,20 @@
<div class="action-buttons">
<button (click)="onDiscard()" class="back-button" mat-mini-fab>
<mat-icon>arrow_back</mat-icon>
</button>

<button
(click)="onConfirm()"
class="confirm-button"
mat-flat-button
*transloco="let t"
>
{{ t('customCamera.confirmCapture') | uppercase }}
</button>
</div>

<div class="preview" *ngIf="curCaptureFilePath && curCaptureMimeType">
<app-media [src]="curCaptureSrc" [mimeType]="curCaptureMimeType"></app-media>
</div>

<div class="footer"></div>

0 comments on commit 6961ad8

Please sign in to comment.