diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b4be9a76..6dcd04e99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## 0.61.2 - 2022-07-20
+
+### Fixed
+
+- Hide camera flash button for front camera
+- Android flash light on only on capture photo or record video
+
+## 0.61.1 - 2022-07-19
+
+### Added
+
+- Camera flash light
+
+### Fixed
+
+- Capture flow, confirm button work smoothly
+- Use high resolution as default camera settings
+
## 0.60.2 - 2022-07-07
### Changed
@@ -15,6 +33,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
diff --git a/README.md b/README.md
index 13341cbea..d9b000a4e 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 07c85a749..4e09291be 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -6,8 +6,8 @@ android {
applicationId "io.numbersprotocol.capturelite"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 422
- versionName "0.60.2"
+ versionCode 432
+ versionName "0.61.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
diff --git a/package-lock.json b/package-lock.json
index 5b2129103..f04aee225 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "capture-lite",
- "version": "0.60.2",
+ "version": "0.61.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "capture-lite",
- "version": "0.60.2",
+ "version": "0.61.2",
"dependencies": {
"@angular/animations": "^12.2.4",
"@angular/cdk": "^12.2.4",
@@ -48,7 +48,7 @@
"@ngx-formly/core": "^5.10.22",
"@ngx-formly/material": "^5.10.22",
"@ngx-formly/schematics": "^5.10.22",
- "@numbersprotocol/preview-camera": "github:numbersprotocol/preview-camera#release-0.0.2-auto-rotate-fix",
+ "@numbersprotocol/preview-camera": "github:numbersprotocol/preview-camera",
"@numbersprotocol/preview-video": "github:numbersprotocol/preview-video",
"@techiediaries/ngx-qrcode": "^9.1.0",
"async-mutex": "^0.3.2",
@@ -4157,8 +4157,8 @@
}
},
"node_modules/@numbersprotocol/preview-camera": {
- "version": "0.0.2",
- "resolved": "git+ssh://git@github.com/numbersprotocol/preview-camera.git#2ce3dc63f83780c4c8e7afe8291238b9c838eb5c",
+ "version": "0.0.5",
+ "resolved": "git+ssh://git@github.com/numbersprotocol/preview-camera.git#460cdc935ff16e14feca062c0d3cd6b35cf9996b",
"license": "MIT",
"peerDependencies": {
"@capacitor/core": "^3.0.0"
@@ -8111,18 +8111,18 @@
}
},
"node_modules/date-format": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
- "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.11.tgz",
+ "integrity": "sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw==",
"dev": true,
"engines": {
"node": ">=4.0"
}
},
"node_modules/debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@@ -10346,9 +10346,9 @@
}
},
"node_modules/flatted": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
- "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
+ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
},
"node_modules/flatten": {
@@ -13727,27 +13727,21 @@
}
},
"node_modules/log4js": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
- "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.6.0.tgz",
+ "integrity": "sha512-3v8R7fd45UB6THucSht6wN2/7AZEruQbXdjygPZcxt5TA/msO6si9CN5MefUuKXbYnJHTBnYcx4famwcyQd+sA==",
"dev": true,
"dependencies": {
- "date-format": "^3.0.0",
- "debug": "^4.1.1",
- "flatted": "^2.0.1",
- "rfdc": "^1.1.4",
- "streamroller": "^2.2.4"
+ "date-format": "^4.0.11",
+ "debug": "^4.3.4",
+ "flatted": "^3.2.5",
+ "rfdc": "^1.3.0",
+ "streamroller": "^3.1.1"
},
"engines": {
"node": ">=8.0"
}
},
- "node_modules/log4js/node_modules/flatted": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
- "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
- "dev": true
- },
"node_modules/loglevel": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
@@ -21610,40 +21604,52 @@
}
},
"node_modules/streamroller": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
- "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.1.tgz",
+ "integrity": "sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ==",
"dev": true,
"dependencies": {
- "date-format": "^2.1.0",
- "debug": "^4.1.1",
- "fs-extra": "^8.1.0"
+ "date-format": "^4.0.10",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.1.0"
},
"engines": {
"node": ">=8.0"
}
},
- "node_modules/streamroller/node_modules/date-format": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
- "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
+ "node_modules/streamroller/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
"engines": {
- "node": ">=4.0"
+ "node": ">=12"
}
},
- "node_modules/streamroller/node_modules/fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "node_modules/streamroller/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
+ "universalify": "^2.0.0"
},
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/streamroller/node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true,
"engines": {
- "node": ">=6 <7 || >=8"
+ "node": ">= 10.0.0"
}
},
"node_modules/strict-uri-encode": {
@@ -28525,8 +28531,8 @@
}
},
"@numbersprotocol/preview-camera": {
- "version": "git+ssh://git@github.com/numbersprotocol/preview-camera.git#2ce3dc63f83780c4c8e7afe8291238b9c838eb5c",
- "from": "@numbersprotocol/preview-camera@github:numbersprotocol/preview-camera#release-0.0.2-auto-rotate-fix",
+ "version": "git+ssh://git@github.com/numbersprotocol/preview-camera.git#460cdc935ff16e14feca062c0d3cd6b35cf9996b",
+ "from": "@numbersprotocol/preview-camera@github:numbersprotocol/preview-camera",
"requires": {}
},
"@numbersprotocol/preview-video": {
@@ -31611,15 +31617,15 @@
}
},
"date-format": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
- "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.11.tgz",
+ "integrity": "sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw==",
"dev": true
},
"debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -33455,9 +33461,9 @@
}
},
"flatted": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
- "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
+ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
},
"flatten": {
@@ -36020,24 +36026,16 @@
}
},
"log4js": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
- "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.6.0.tgz",
+ "integrity": "sha512-3v8R7fd45UB6THucSht6wN2/7AZEruQbXdjygPZcxt5TA/msO6si9CN5MefUuKXbYnJHTBnYcx4famwcyQd+sA==",
"dev": true,
"requires": {
- "date-format": "^3.0.0",
- "debug": "^4.1.1",
- "flatted": "^2.0.1",
- "rfdc": "^1.1.4",
- "streamroller": "^2.2.4"
- },
- "dependencies": {
- "flatted": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
- "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
- "dev": true
- }
+ "date-format": "^4.0.11",
+ "debug": "^4.3.4",
+ "flatted": "^3.2.5",
+ "rfdc": "^1.3.0",
+ "streamroller": "^3.1.1"
}
},
"loglevel": {
@@ -42024,32 +42022,42 @@
}
},
"streamroller": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
- "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.1.tgz",
+ "integrity": "sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ==",
"dev": true,
"requires": {
- "date-format": "^2.1.0",
- "debug": "^4.1.1",
- "fs-extra": "^8.1.0"
+ "date-format": "^4.0.10",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.1.0"
},
"dependencies": {
- "date-format": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
- "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
- "dev": true
- },
"fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
}
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true
}
}
},
diff --git a/package.json b/package.json
index 434af9dda..37fe08243 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "capture-lite",
- "version": "0.60.2",
+ "version": "0.61.2",
"author": "numbersprotocol",
"homepage": "https://numbersprotocol.io/",
"scripts": {
@@ -59,7 +59,7 @@
"@ngx-formly/core": "^5.10.22",
"@ngx-formly/material": "^5.10.22",
"@ngx-formly/schematics": "^5.10.22",
- "@numbersprotocol/preview-camera": "github:numbersprotocol/preview-camera#release-0.0.2-auto-rotate-fix",
+ "@numbersprotocol/preview-camera": "github:numbersprotocol/preview-camera",
"@numbersprotocol/preview-video": "github:numbersprotocol/preview-video",
"@techiediaries/ngx-qrcode": "^9.1.0",
"async-mutex": "^0.3.2",
diff --git a/src/app/features/home/custom-camera/custom-camera-routing.module.ts b/src/app/features/home/custom-camera/custom-camera-routing.module.ts
index 471a97ef7..fbba440f6 100644
--- a/src/app/features/home/custom-camera/custom-camera-routing.module.ts
+++ b/src/app/features/home/custom-camera/custom-camera-routing.module.ts
@@ -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';
diff --git a/src/app/features/home/custom-camera/custom-camera.module.ts b/src/app/features/home/custom-camera/custom-camera.module.ts
index c4b4c14b7..c5d485bb5 100644
--- a/src/app/features/home/custom-camera/custom-camera.module.ts
+++ b/src/app/features/home/custom-camera/custom-camera.module.ts
@@ -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: [
@@ -16,6 +17,6 @@ import { CustomCameraService } from './custom-camera.service';
JoyrideModule.forChild(),
],
providers: [CustomCameraService],
- declarations: [CustomCameraPage],
+ declarations: [CustomCameraPage, PrePublishModeComponent],
})
export class CustomCameraPageModule {}
diff --git a/src/app/features/home/custom-camera/custom-camera.page.html b/src/app/features/home/custom-camera/custom-camera.page.html
index 313f5fc19..21ff52413 100644
--- a/src/app/features/home/custom-camera/custom-camera.page.html
+++ b/src/app/features/home/custom-camera/custom-camera.page.html
@@ -3,61 +3,83 @@
[style.--background]="'transparent'"
*transloco="let t"
>
-
-
- GoPro
- featured_video
-
+
+
-
- close
-
-
-
+
+
+
+ video_collection
+
+
+
+
+
+ flip_camera_android
+
+
+
+
+
+
diff --git a/src/app/features/home/custom-camera/custom-camera.page.scss b/src/app/features/home/custom-camera/custom-camera.page.scss
index 9331afe28..e367e6529 100644
--- a/src/app/features/home/custom-camera/custom-camera.page.scss
+++ b/src/app/features/home/custom-camera/custom-camera.page.scss
@@ -13,6 +13,12 @@ mat-icon {
width: 36px;
}
+mat-icon.flash-camera-button {
+ position: absolute;
+ top: 16px;
+ left: 16px;
+}
+
mat-icon.close-camera-button {
position: absolute;
top: 16px;
diff --git a/src/app/features/home/custom-camera/custom-camera.page.ts b/src/app/features/home/custom-camera/custom-camera.page.ts
index d6a4b1585..41698a600 100644
--- a/src/app/features/home/custom-camera/custom-camera.page.ts
+++ b/src/app/features/home/custom-camera/custom-camera.page.ts
@@ -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';
@@ -33,6 +34,16 @@ 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;
+
+ isFlashOn = false;
+ isFlashAvailable = false;
+
readonly lastConnectedGoProDevice$ =
this.goProBluetoothService.lastConnectedDevice$;
@@ -59,6 +70,8 @@ export class CustomCameraPage implements OnInit, OnDestroy {
).then((listener: any) => (this.captureVideoFinishedListener = listener));
this.startPreviewCamera();
+
+ this.syncCameraState();
}
async ionViewDidEnter() {
@@ -85,12 +98,24 @@ 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();
}
}
- startPreviewCamera() {
- this.customCameraService.startPreviewCamera();
+ async startPreviewCamera() {
+ await this.customCameraService.startPreviewCamera();
+ await this.syncCameraState();
}
// eslint-disable-next-line class-methods-use-this
@@ -98,8 +123,14 @@ export class CustomCameraPage implements OnInit, OnDestroy {
this.customCameraService.stopPreviewCamera();
}
- flipCamera() {
- this.customCameraService.flipCamera();
+ async flipCamera() {
+ await this.customCameraService.flipCamera();
+ await this.syncCameraState();
+ }
+
+ async syncCameraState() {
+ this.isFlashOn = (await this.isTorchOn()).result;
+ this.isFlashAvailable = await this.customCameraService.isTorchAvailable();
}
onPress() {
@@ -131,6 +162,31 @@ export class CustomCameraPage implements OnInit, OnDestroy {
}
}
+ discardCurrentCapture() {
+ this.mode$.next('capture');
+ this.startPreviewCamera();
+ this.removeCurrentCapture();
+ }
+
+ async confirmCurrentCapture() {
+ if (this.curCaptureFilePath && this.curCaptureType) {
+ this.customCameraService.uploadToCapture(
+ this.curCaptureFilePath,
+ this.curCaptureType
+ );
+ this.leaveCustomCamera();
+ }
+ }
+
+ async isTorchOn() {
+ return this.customCameraService.isTorchOn();
+ }
+
+ async enableTorch() {
+ await this.customCameraService.enableTorch(!this.isFlashOn);
+ this.isFlashOn = (await this.customCameraService.isTorchOn()).result;
+ }
+
async leaveCustomCamera() {
return this.location.back();
}
@@ -142,6 +198,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
diff --git a/src/app/features/home/custom-camera/custom-camera.service.spec.ts b/src/app/features/home/custom-camera/custom-camera.service.spec.ts
index 288da8ca1..383e6e88c 100644
--- a/src/app/features/home/custom-camera/custom-camera.service.spec.ts
+++ b/src/app/features/home/custom-camera/custom-camera.service.spec.ts
@@ -1,14 +1,30 @@
-import { TestBed } from '@angular/core/testing';
+import { TestBed, waitForAsync } from '@angular/core/testing';
+import { Platform } from '@ionic/angular';
import { SharedTestingModule } from '../../../shared/shared-testing.module';
import { CustomCameraService } from './custom-camera.service';
describe('CustomCameraService', () => {
let service: CustomCameraService;
+ let platformReadySpy: Promise;
+ let platformIsSpy: boolean | undefined;
+ let platformSpy: Platform;
- beforeEach(() => {
- TestBed.configureTestingModule({ imports: [SharedTestingModule] });
- service = TestBed.inject(CustomCameraService);
- });
+ beforeEach(
+ waitForAsync(() => {
+ platformReadySpy = Promise.resolve();
+ platformIsSpy = false;
+ platformSpy = jasmine.createSpyObj('Platform', {
+ ready: platformReadySpy,
+ is: platformIsSpy,
+ });
+
+ TestBed.configureTestingModule({
+ imports: [SharedTestingModule],
+ providers: [{ provide: Platform, useValue: platformSpy }],
+ }).compileComponents();
+ service = TestBed.inject(CustomCameraService);
+ })
+ );
it('should be created', () => {
expect(service).toBeTruthy();
diff --git a/src/app/features/home/custom-camera/custom-camera.service.ts b/src/app/features/home/custom-camera/custom-camera.service.ts
index 30febf614..2e7143fbc 100644
--- a/src/app/features/home/custom-camera/custom-camera.service.ts
+++ b/src/app/features/home/custom-camera/custom-camera.service.ts
@@ -1,10 +1,13 @@
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 { Platform } from '@ionic/angular';
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';
@@ -27,7 +30,10 @@ 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 readonly platform: Platform
) {}
private mediaItemFromFilePath(
@@ -52,6 +58,7 @@ export class CustomCameraService {
const base64 = await blobToBase64(itemBlob);
const mimeType = itemToUpload.mimeType;
await this.captureService.capture({ base64, mimeType });
+ await this.removeFile(filePath);
} catch (error) {
const errMsg = this.translocoService.translate(`error.internetError`);
await this.errorService.toastError$(errMsg).toPromise();
@@ -89,6 +96,36 @@ export class CustomCameraService {
return PreviewCamera.stopRecord().catch(() => ({}));
}
+ async removeFile(filePath: string | undefined) {
+ if (!filePath) return;
+ await this.filesystemPlugin.deleteFile({ path: filePath });
+ }
+
+ async isTorchOn() {
+ if (this.isNativePlatform) {
+ return await PreviewCamera.isTorchOn();
+ }
+ return { result: false };
+ }
+
+ async enableTorch(enable: boolean): Promise {
+ if (this.isNativePlatform) {
+ return await PreviewCamera.enableTorch({ enable });
+ }
+ return Promise.resolve();
+ }
+
+ async isTorchAvailable(): Promise {
+ if (this.isNativePlatform) {
+ return (await PreviewCamera.isTorchAvailable()).result;
+ }
+ return false;
+ }
+
+ private get isNativePlatform() {
+ return this.platform.is('ios') || this.platform.is('android');
+ }
+
private changeGlobalCSSBackgroundToTransparent() {
document.querySelector('body')?.classList.add(this.globalCSSClass);
document.querySelector('ion-app')?.classList.add(this.globalCSSClass);
diff --git a/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.html b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.html
new file mode 100644
index 000000000..eadb07419
--- /dev/null
+++ b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.scss b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.scss
new file mode 100644
index 000000000..174d93691
--- /dev/null
+++ b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.scss
@@ -0,0 +1,54 @@
+.action-buttons {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ padding: calc(var(--ion-safe-area-top) + 4px) 16px;
+ background-color: black;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ z-index: 100;
+}
+
+.footer {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: calc(var(--ion-safe-area-bottom) + 4px) 16px;
+ background-color: black;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ z-index: 100;
+ height: 75px;
+}
+
+.back-button {
+ background: #ffffff40 !important; /* stylelint-disable-line declaration-no-important */
+ color: white !important; /* stylelint-disable-line declaration-no-important */
+ backdrop-filter: blur(4px);
+ box-shadow: none;
+}
+
+.confirm-button {
+ background: #486cd9 !important; /* stylelint-disable-line declaration-no-important */
+ color: white !important; /* stylelint-disable-line declaration-no-important */
+ border-radius: 37px;
+ height: 38px;
+}
+
+.preview {
+ height: 100%;
+ overflow: auto;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ app-media {
+ width: 100%;
+ object-fit: cover;
+ object-position: center;
+ }
+}
diff --git a/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.spec.ts b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.spec.ts
new file mode 100644
index 000000000..1aacbb205
--- /dev/null
+++ b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.spec.ts
@@ -0,0 +1,26 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { SharedTestingModule } from '../../../../shared/shared-testing.module';
+
+import { PrePublishModeComponent } from './pre-publish-mode.component';
+
+describe('PrePublishModeComponent', () => {
+ let component: PrePublishModeComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(
+ waitForAsync(() => {
+ TestBed.configureTestingModule({
+ declarations: [PrePublishModeComponent],
+ imports: [SharedTestingModule],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(PrePublishModeComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ })
+ );
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.ts b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.ts
new file mode 100644
index 000000000..1fea586aa
--- /dev/null
+++ b/src/app/features/home/custom-camera/pre-publish-mode/pre-publish-mode.component.ts
@@ -0,0 +1,29 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+ selector: 'app-pre-publish-mode',
+ templateUrl: './pre-publish-mode.component.html',
+ styleUrls: ['./pre-publish-mode.component.scss'],
+})
+export class PrePublishModeComponent {
+ @Input()
+ curCaptureFilePath?: string;
+
+ @Input()
+ curCaptureMimeType?: 'image/jpeg' | 'video/mp4';
+
+ @Input()
+ curCaptureSrc?: string;
+
+ @Output() discard: EventEmitter = new EventEmitter();
+
+ @Output() confirm: EventEmitter = new EventEmitter();
+
+ onDiscard() {
+ this.discard.emit(null);
+ }
+
+ onConfirm() {
+ this.confirm.emit(null);
+ }
+}
diff --git a/src/app/features/home/details/details.page.ts b/src/app/features/home/details/details.page.ts
index 7403f8762..e22a25305 100644
--- a/src/app/features/home/details/details.page.ts
+++ b/src/app/features/home/details/details.page.ts
@@ -22,6 +22,7 @@ import {
tap,
} from 'rxjs/operators';
import SwiperCore, { Swiper, Virtual } from 'swiper/core';
+import { ActionsService } from '../../../shared/actions/service/actions.service';
import { BlockingActionService } from '../../../shared/blocking-action/blocking-action.service';
import { ConfirmAlert } from '../../../shared/confirm-alert/confirm-alert.service';
import { ContactSelectionDialogComponent } from '../../../shared/contact-selection-dialog/contact-selection-dialog.component';
@@ -207,7 +208,8 @@ export class DetailsPage {
private readonly diaBackendWorkflowService: DiaBackendWorkflowService,
private readonly alertController: AlertController,
private readonly changeDetectorRef: ChangeDetectorRef,
- private readonly userGuideService: UserGuideService
+ private readonly userGuideService: UserGuideService,
+ private readonly actionsService: ActionsService
) {
this.initializeActiveDetailedCapture$
.pipe(untilDestroyed(this))
@@ -467,6 +469,11 @@ export class DetailsPage {
activeDetailedCapture => activeDetailedCapture.diaBackendAsset$
),
isNonNullable(),
+ tap(diaBackendAsset =>
+ this.actionsService
+ .generateSeoImageAndDescription$(diaBackendAsset)
+ .toPromise()
+ ),
concatMap(diaBackendAsset => this.shareService.share(diaBackendAsset)),
catchError((err: unknown) => this.errorService.toastError$(err)),
untilDestroyed(this)
diff --git a/src/app/shared/actions/service/actions.service.ts b/src/app/shared/actions/service/actions.service.ts
index 0ac2eeedc..8076937f3 100644
--- a/src/app/shared/actions/service/actions.service.ts
+++ b/src/app/shared/actions/service/actions.service.ts
@@ -2,6 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { defer, forkJoin, of } from 'rxjs';
import { map } from 'rxjs/operators';
+import { DiaBackendAsset } from '../../dia-backend/asset/dia-backend-asset-repository.service';
import { BUBBLE_DB_URL } from '../../dia-backend/secret';
@Injectable({
@@ -34,6 +35,16 @@ export class ActionsService {
send$(url: string, body: any) {
return this.httpClient.post(url, body);
}
+
+ generateSeoImageAndDescription$(diaBackendAsset: DiaBackendAsset) {
+ return this.httpClient.post(
+ `https://authmedia.net/api/1.1/obj/nftprofile`,
+ {
+ asset_url: diaBackendAsset.asset_file,
+ Description: diaBackendAsset.cid,
+ }
+ );
+ }
}
export interface Action {
diff --git a/src/assets/i18n/en-us.json b/src/assets/i18n/en-us.json
index 86caac067..314f771b7 100644
--- a/src/assets/i18n/en-us.json
+++ b/src/assets/i18n/en-us.json
@@ -268,6 +268,9 @@
"networkActionsAreUnavailable": "Network Actions are unavailable. Please try again later."
}
},
+ "customCamera": {
+ "confirmCapture": "Confirm"
+ },
"wallets": {
"wallets": "Wallets",
"pullToRefreshBalance": "Pull to refresh balance",
diff --git a/src/assets/i18n/zh-tw.json b/src/assets/i18n/zh-tw.json
index 0e7d43cf0..a7f060682 100644
--- a/src/assets/i18n/zh-tw.json
+++ b/src/assets/i18n/zh-tw.json
@@ -268,6 +268,9 @@
"networkActionsAreUnavailable": "暫時無法使用 Network Action,請稍後再試。"
}
},
+ "customCamera": {
+ "confirmCapture": "確認"
+ },
"wallets": {
"wallets": "錢包",
"pullToRefreshBalance": "下拉以刷新餘額",