254 lines
10 KiB
JavaScript
254 lines
10 KiB
JavaScript
import { WebPlugin, CapacitorException } from '@capacitor/core';
|
|
import { CameraSource, CameraDirection } from './definitions';
|
|
export class CameraWeb extends WebPlugin {
|
|
async getPhoto(options) {
|
|
// eslint-disable-next-line no-async-promise-executor
|
|
return new Promise(async (resolve, reject) => {
|
|
if (options.webUseInput || options.source === CameraSource.Photos) {
|
|
this.fileInputExperience(options, resolve, reject);
|
|
}
|
|
else if (options.source === CameraSource.Prompt) {
|
|
let actionSheet = document.querySelector('pwa-action-sheet');
|
|
if (!actionSheet) {
|
|
actionSheet = document.createElement('pwa-action-sheet');
|
|
document.body.appendChild(actionSheet);
|
|
}
|
|
actionSheet.header = options.promptLabelHeader || 'Photo';
|
|
actionSheet.cancelable = false;
|
|
actionSheet.options = [
|
|
{ title: options.promptLabelPhoto || 'From Photos' },
|
|
{ title: options.promptLabelPicture || 'Take Picture' },
|
|
];
|
|
actionSheet.addEventListener('onSelection', async (e) => {
|
|
const selection = e.detail;
|
|
if (selection === 0) {
|
|
this.fileInputExperience(options, resolve, reject);
|
|
}
|
|
else {
|
|
this.cameraExperience(options, resolve, reject);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
this.cameraExperience(options, resolve, reject);
|
|
}
|
|
});
|
|
}
|
|
async pickImages(_options) {
|
|
// eslint-disable-next-line no-async-promise-executor
|
|
return new Promise(async (resolve, reject) => {
|
|
this.multipleFileInputExperience(resolve, reject);
|
|
});
|
|
}
|
|
async cameraExperience(options, resolve, reject) {
|
|
if (customElements.get('pwa-camera-modal')) {
|
|
const cameraModal = document.createElement('pwa-camera-modal');
|
|
cameraModal.facingMode =
|
|
options.direction === CameraDirection.Front ? 'user' : 'environment';
|
|
document.body.appendChild(cameraModal);
|
|
try {
|
|
await cameraModal.componentOnReady();
|
|
cameraModal.addEventListener('onPhoto', async (e) => {
|
|
const photo = e.detail;
|
|
if (photo === null) {
|
|
reject(new CapacitorException('User cancelled photos app'));
|
|
}
|
|
else if (photo instanceof Error) {
|
|
reject(photo);
|
|
}
|
|
else {
|
|
resolve(await this._getCameraPhoto(photo, options));
|
|
}
|
|
cameraModal.dismiss();
|
|
document.body.removeChild(cameraModal);
|
|
});
|
|
cameraModal.present();
|
|
}
|
|
catch (e) {
|
|
this.fileInputExperience(options, resolve, reject);
|
|
}
|
|
}
|
|
else {
|
|
console.error(`Unable to load PWA Element 'pwa-camera-modal'. See the docs: https://capacitorjs.com/docs/web/pwa-elements.`);
|
|
this.fileInputExperience(options, resolve, reject);
|
|
}
|
|
}
|
|
fileInputExperience(options, resolve, reject) {
|
|
let input = document.querySelector('#_capacitor-camera-input');
|
|
const cleanup = () => {
|
|
var _a;
|
|
(_a = input.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(input);
|
|
};
|
|
if (!input) {
|
|
input = document.createElement('input');
|
|
input.id = '_capacitor-camera-input';
|
|
input.type = 'file';
|
|
input.hidden = true;
|
|
document.body.appendChild(input);
|
|
input.addEventListener('change', (_e) => {
|
|
const file = input.files[0];
|
|
let format = 'jpeg';
|
|
if (file.type === 'image/png') {
|
|
format = 'png';
|
|
}
|
|
else if (file.type === 'image/gif') {
|
|
format = 'gif';
|
|
}
|
|
if (options.resultType === 'dataUrl' ||
|
|
options.resultType === 'base64') {
|
|
const reader = new FileReader();
|
|
reader.addEventListener('load', () => {
|
|
if (options.resultType === 'dataUrl') {
|
|
resolve({
|
|
dataUrl: reader.result,
|
|
format,
|
|
});
|
|
}
|
|
else if (options.resultType === 'base64') {
|
|
const b64 = reader.result.split(',')[1];
|
|
resolve({
|
|
base64String: b64,
|
|
format,
|
|
});
|
|
}
|
|
cleanup();
|
|
});
|
|
reader.readAsDataURL(file);
|
|
}
|
|
else {
|
|
resolve({
|
|
webPath: URL.createObjectURL(file),
|
|
format: format,
|
|
});
|
|
cleanup();
|
|
}
|
|
});
|
|
input.addEventListener('cancel', (_e) => {
|
|
reject(new CapacitorException('User cancelled photos app'));
|
|
cleanup();
|
|
});
|
|
}
|
|
input.accept = 'image/*';
|
|
input.capture = true;
|
|
if (options.source === CameraSource.Photos ||
|
|
options.source === CameraSource.Prompt) {
|
|
input.removeAttribute('capture');
|
|
}
|
|
else if (options.direction === CameraDirection.Front) {
|
|
input.capture = 'user';
|
|
}
|
|
else if (options.direction === CameraDirection.Rear) {
|
|
input.capture = 'environment';
|
|
}
|
|
input.click();
|
|
}
|
|
multipleFileInputExperience(resolve, reject) {
|
|
let input = document.querySelector('#_capacitor-camera-input-multiple');
|
|
const cleanup = () => {
|
|
var _a;
|
|
(_a = input.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(input);
|
|
};
|
|
if (!input) {
|
|
input = document.createElement('input');
|
|
input.id = '_capacitor-camera-input-multiple';
|
|
input.type = 'file';
|
|
input.hidden = true;
|
|
input.multiple = true;
|
|
document.body.appendChild(input);
|
|
input.addEventListener('change', (_e) => {
|
|
const photos = [];
|
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
for (let i = 0; i < input.files.length; i++) {
|
|
const file = input.files[i];
|
|
let format = 'jpeg';
|
|
if (file.type === 'image/png') {
|
|
format = 'png';
|
|
}
|
|
else if (file.type === 'image/gif') {
|
|
format = 'gif';
|
|
}
|
|
photos.push({
|
|
webPath: URL.createObjectURL(file),
|
|
format: format,
|
|
});
|
|
}
|
|
resolve({ photos });
|
|
cleanup();
|
|
});
|
|
input.addEventListener('cancel', (_e) => {
|
|
reject(new CapacitorException('User cancelled photos app'));
|
|
cleanup();
|
|
});
|
|
}
|
|
input.accept = 'image/*';
|
|
input.click();
|
|
}
|
|
_getCameraPhoto(photo, options) {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
const format = photo.type.split('/')[1];
|
|
if (options.resultType === 'uri') {
|
|
resolve({
|
|
webPath: URL.createObjectURL(photo),
|
|
format: format,
|
|
saved: false,
|
|
});
|
|
}
|
|
else {
|
|
reader.readAsDataURL(photo);
|
|
reader.onloadend = () => {
|
|
const r = reader.result;
|
|
if (options.resultType === 'dataUrl') {
|
|
resolve({
|
|
dataUrl: r,
|
|
format: format,
|
|
saved: false,
|
|
});
|
|
}
|
|
else {
|
|
resolve({
|
|
base64String: r.split(',')[1],
|
|
format: format,
|
|
saved: false,
|
|
});
|
|
}
|
|
};
|
|
reader.onerror = e => {
|
|
reject(e);
|
|
};
|
|
}
|
|
});
|
|
}
|
|
async checkPermissions() {
|
|
if (typeof navigator === 'undefined' || !navigator.permissions) {
|
|
throw this.unavailable('Permissions API not available in this browser');
|
|
}
|
|
try {
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/Permissions/query
|
|
// the specific permissions that are supported varies among browsers that implement the
|
|
// permissions API, so we need a try/catch in case 'camera' is invalid
|
|
const permission = await window.navigator.permissions.query({
|
|
name: 'camera',
|
|
});
|
|
return {
|
|
camera: permission.state,
|
|
photos: 'granted',
|
|
};
|
|
}
|
|
catch (_a) {
|
|
throw this.unavailable('Camera permissions are not available in this browser');
|
|
}
|
|
}
|
|
async requestPermissions() {
|
|
throw this.unimplemented('Not implemented on web.');
|
|
}
|
|
async pickLimitedLibraryPhotos() {
|
|
throw this.unavailable('Not implemented on web.');
|
|
}
|
|
async getLimitedLibraryPhotos() {
|
|
throw this.unavailable('Not implemented on web.');
|
|
}
|
|
}
|
|
const Camera = new CameraWeb();
|
|
export { Camera };
|
|
//# sourceMappingURL=web.js.map
|