У меня есть угловое приложение 5.2.9 PWA, которое хранит данные локально в IndexedDB через PouchDB для автономного использования.Это приложение хранит фотографии в виде BLOB-объектов внутри документа.Я не использую вложения.Это работает в браузерах Chrome & Edge и Andriod, но Blob не хранится и не загружается должным образом на iPad.IPad работает под управлением Safari 11.3.1.Когда фотографии сделаны, они отображаются в моей галерее просто отлично.После сохранения и получения через PouchDB я получаю BLOB-объект нулевого размера.Мне не хватает определенных настроек или настроек Safari / iPad?
import { Component, OnInit, Inject } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { MatDialog, MatDialogRef } from '@angular/material';
import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
import { ConfigurationService } from '../../service/configuration.service';
import PouchDB from 'pouchdb';
import { Inspection } from '../../model/inspection';
import { PhotoDialogComponent } from './../photo-dialog/photo-dialog.component';
import { InspectionPhoto } from '../../model/inspection-photo';
import { zip } from 'rxjs/observable/zip';
@Component({
selector: 'app-photo-gallery',
templateUrl: './photo-gallery.component.html',
styleUrls: ['./photo-gallery.component.css']
})
export class PhotoGalleryComponent implements OnInit {
photoDialogRef: MatDialogRef<PhotoDialogComponent>;
inspection: Inspection;
photoList: BehaviorSubject<Array<InspectionPhoto>>;
currentUrl: BehaviorSubject<SafeResourceUrl>;
currentIndex: number;
length: number;
rotate: string;
constructor(public config: ConfigurationService,
public dialogRef: MatDialogRef<PhotoDialogComponent>,
public dialog: MatDialog,
public domSanitiser: DomSanitizer) {
this.photoList = new BehaviorSubject<Array<InspectionPhoto>>(new Array<InspectionPhoto>());
this.currentUrl = new BehaviorSubject<string>('');
this.currentIndex = 0;
this.length = 0;
this.rotate = this.config.getRotateImages() ? "rotate90" : "";
}
ngOnInit() {
let db = new PouchDB('inspection-photo');
db.allDocs({include_docs: true})
.then(result => {
return Promise.all(result.rows.map(row => {
let item = new InspectionPhoto();
item = row.doc;
item._id = row.id;
item._rev = row.rev;
return item;
}));
}).then(list => {
this.length = list.length;
this.currentIndex = 0;
this.photoList.next(list);
if(list.length > 0) {
this.getImageUrl(list[0]);
}
})
.catch(err => {
console.log('ngOnInit db error' + err);
alert('ngOnInit db error' + err);
});
}
public getImageUrl(inspectionPhoto: InspectionPhoto): void {
if(inspectionPhoto == undefined
|| inspectionPhoto.Photo == undefined){
return; }
// alert('blob size: ' + inspectionPhoto.Photo.size);
let modified: Date = new Date();
let f:File = new File([inspectionPhoto.Photo],
"image" + this.currentIndex + ".jpg",
{type: "image/jpeg", lastModified: modified.getUTCMilliseconds()}
);
// alert('file: '
// + ' name: ' + f.name
// + ' type: ' + f.type
// + ' size: ' + f.size
// );
let url: string;
try {
url = URL.createObjectURL(f, {oneTimeOnly: true}); //.substring(5);
}
catch (e) {
alert('1:' + (<Error>e).message + (<Error>e).stack);
}
let sanitisedUrl: SafeResourceUrl;
try{
sanitisedUrl = this.domSanitiser.bypassSecurityTrustResourceUrl(url);
}
catch (e) {
alert('2:' + (<Error>e).message);
}
try{
this.currentUrl.next(sanitisedUrl);
}
catch (e) {
alert('3:' + (<Error>e).message);
}
}
public onNext() {
if (this.currentIndex >= this.length - 1) {
this.currentIndex = 0;
} else {
this.currentIndex += 1;
}
this.photoList.subscribe(list => {
// alert('image:' + this.currentIndex);
this.getImageUrl(list[this.currentIndex]);
});
}
public onPrevious() {
if (this.currentIndex <= 0) {
this.currentIndex = this.length - 1;
} else {
this.currentIndex -= 1;
}
this.photoList.subscribe(list => {
// alert('image:' + this.currentIndex);
this.getImageUrl(list[this.currentIndex]);
});
}
OnNewPhoto(): void {
this.photoDialogRef = this.dialog.open(PhotoDialogComponent, {
});
this.photoDialogRef.afterClosed().subscribe((result) => {
if (result) {
let inspectionPhoto = new InspectionPhoto();
inspectionPhoto.InspectionId = this.inspection._id;
inspectionPhoto.WorkOrderId = this.inspection.WorkOrderId;
inspectionPhoto.TaskId = this.inspection.TaskId;
inspectionPhoto.EquipmentId = this.inspection.EquipmentId;
let db = new PouchDB('inspection-photo');
let files: File[] = Array.from(this.photoDialogRef.componentInstance.files);
files.forEach(f => {
// alert('file: '
// + ' name: ' + f.name
// + ' type: ' + f.type
// + ' size: ' + f.size
// );
inspectionPhoto._id = this.config.uniqueID();
inspectionPhoto.Photo = new Blob([f], {type: 'image/jpeg'});
// alert('Blob size: ' + inspectionPhoto.Photo.size);
db.put(inspectionPhoto)
.then(result => {
inspectionPhoto._id = result.id;
inspectionPhoto._rev = result.rev;
// alert('**** saved photo blob size:' + inspectionPhoto.Photo.size);
this.photoList.subscribe(list => {
list.push(inspectionPhoto);
this.length = list.length;
this.currentIndex = this.length - 1;
});
this.getImageUrl(inspectionPhoto);
})
.catch(err => {
console.log('OnNewPhoto db error ' + err);
alert('OnNewPhoto db error ' + err);
});
});
}
this.photoDialogRef = null;
});
}
}