Save image

This commit is contained in:
Willem Dantuma 2021-03-01 22:03:18 +01:00
parent 47f3238edd
commit 2f1c5210ea
7 changed files with 86 additions and 15 deletions

View File

@ -16,6 +16,7 @@ import { ItemService } from './services/item.service';
import { EventService } from './services/event.service'; import { EventService } from './services/event.service';
import { TypeaheadService } from './services/typeahead.service'; import { TypeaheadService } from './services/typeahead.service';
import { UserService } from './services/user.service'; import { UserService } from './services/user.service';
import { ImageService } from './services/image.service';
import { WeatherService} from './services/weather.service'; import { WeatherService} from './services/weather.service';
import { AppConfig } from './shared/app.config'; import { AppConfig } from './shared/app.config';
import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor"; import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor";
@ -42,6 +43,7 @@ export {
EventService, EventService,
TypeaheadService, TypeaheadService,
UserService, UserService,
ImageService,
WeatherService, WeatherService,
AppConfig, AppConfig,
AccessTokenInterceptor, AccessTokenInterceptor,

View File

@ -16,18 +16,19 @@
[maintainAspectRatio]="true" [maintainAspectRatio]="true"
format="jpeg" format="jpeg"
[aspectRatio]="aspectRatio" [aspectRatio]="aspectRatio"
[autoCrop]="false" [autoCrop]="true"
(imageCropped)="imageCropped($event)" (imageCropped)="imageCropped($event)"
(imageLoaded)="imageLoaded($event)" (imageLoaded)="imageLoaded($event)"
(cropperReady)="cropperReady()" (cropperReady)="cropperReady()"
(loadImageFailed)="loadImageFailed()" (loadImageFailed)="loadImageFailed()"
[imageURL]="imageUrl"
></image-cropper> ></image-cropper>
</div> </div>
<input #fileInput type="file" (change)="fileChangeEvent($event)" style="display:none" accept="image/*"/> <input #fileInput type="file" (change)="fileChangeEvent($event)" style="display:none" accept="image/*"/>
<span class="btn btn-primary" (click)="fileInput.click()" i18n>Select image</span> <span class="btn btn-primary" (click)="fileInput.click()" i18n>Select image</span>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary" i18n [disabled]="!isImageLoaded">Apply</button> <button type="submit" class="btn btn-primary" i18n [disabled]="!isImageLoaded" (click)="save()">Apply</button>
<button type="button" autofocus class="btn btn-secondary" (click)="modal.close('Save click')" i18n="@@buttonCancel">Cancel</button> <button type="button" autofocus class="btn btn-secondary" (click)="modal.close('Save click')" i18n="@@buttonCancel">Cancel</button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,6 +1,8 @@
import { Component, OnInit,ViewChild,ElementRef } from '@angular/core'; import { Component, OnInit,ViewChild,ElementRef,EventEmitter, Output } from '@angular/core';
import { HttpClient, HttpParams,HttpHeaders } from "@angular/common/http";
import {NgbModal} from "@ng-bootstrap/ng-bootstrap" import {NgbModal} from "@ng-bootstrap/ng-bootstrap"
import { ImageCroppedEvent,LoadedImage } from 'ngx-image-cropper'; import { ImageCroppedEvent,LoadedImage } from 'ngx-image-cropper';
import {ImageService } from '../../services/image.service';
@Component({ @Component({
selector: 'fm-edit-image-modal', selector: 'fm-edit-image-modal',
@ -9,23 +11,28 @@ import { ImageCroppedEvent,LoadedImage } from 'ngx-image-cropper';
}) })
export class EditImageModalComponent implements OnInit { export class EditImageModalComponent implements OnInit {
@Output() changed = new EventEmitter();
@ViewChild('upload_modal') modal:ElementRef; @ViewChild('upload_modal') modal:ElementRef;
constructor(private modalService: NgbModal) { } constructor(private modalService: NgbModal,public imageService:ImageService) { }
isImageLoaded:boolean = false;
aspectRatio:number = 4/3;
imageChangedEvent: any = '';
croppedImage: string = '';
endpointUrl:string = null;
imageUrl:string = null;
ngOnInit(): void { ngOnInit(): void {
} }
open(endpoint:string,aspectRatio:number) { open(endpoint:string,aspectRatio:number) {
this.endpointUrl = endpoint;
this.imageUrl = endpoint;
this.aspectRatio= aspectRatio; this.aspectRatio= aspectRatio;
this.modalService.open(this.modal,{ size: 'lg' }); this.modalService.open(this.modal,{ size: 'lg' });
} }
isImageLoaded:boolean = false;
aspectRatio:number = 4/3;
imageChangedEvent: any = '';
croppedImage: any = '';
fileChangeEvent(event: any): void { fileChangeEvent(event: any): void {
this.imageChangedEvent = event; this.imageChangedEvent = event;
} }
@ -41,4 +48,15 @@ export class EditImageModalComponent implements OnInit {
loadImageFailed() { loadImageFailed() {
// show message // show message
} }
save() {
if(this.croppedImage) {
var body = this.croppedImage.substr(23);
this.imageService.putImage(this.endpointUrl,this.imageService.b64toBlob(body,"image/jpeg")).subscribe(() => {
this.changed.emit({});
});
(this.modal as any).close('Save click');
}
}
} }

View File

@ -6,4 +6,4 @@
</div> </div>
</div> </div>
<fm-edit-image-modal #modal></fm-edit-image-modal> <fm-edit-image-modal #modal (changed)="onChanged()"></fm-edit-image-modal>

View File

@ -4,6 +4,7 @@ import { Store } from '@ngrx/store';
import { IListItem } from '../../models/list.item'; import { IListItem } from '../../models/list.item';
import { commonReducers,ItemTypeService } from '../../../public-api' import { commonReducers,ItemTypeService } from '../../../public-api'
import { EditImageModalComponent} from '../edit-image-modal/edit-image-modal.component'; import { EditImageModalComponent} from '../edit-image-modal/edit-image-modal.component';
import { AppConfig } from "../../shared/app.config";
@Component({ @Component({
selector: 'fm-thumbnail', selector: 'fm-thumbnail',
@ -18,11 +19,11 @@ import { EditImageModalComponent} from '../edit-image-modal/edit-image-modal.com
@ViewChild('thumbnail') el:ElementRef; @ViewChild('thumbnail') el:ElementRef;
@ViewChild('modal') modal:EditImageModalComponent; @ViewChild('modal') modal:EditImageModalComponent;
constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService) { constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService,public appConfig: AppConfig,) {
} }
getThumbnailUrl(item:IListItem):string { getThumbnailUrl(item:IListItem):string {
return item.url+'/thumbnail?v=' + Date.parse(item.updated); return this.appConfig.getConfig("apiEndPoint")+item.url+'/thumbnail?v=' + Date.parse(item.updated);
} }
getFontSize():string { getFontSize():string {
@ -47,6 +48,11 @@ import { EditImageModalComponent} from '../edit-image-modal/edit-image-modal.com
} }
onEditClick() { onEditClick() {
this.modal.open(this.item.url+"/thumbnail",4/3); var endpoint = `${this.appConfig.getConfig("apiEndPoint")}/api/v1/items/${this.item.code}/thumbnail`;
this.modal.open(endpoint,4/3);
}
onChanged() {
console.log("changed");
} }
} }

View File

@ -0,0 +1,44 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { IUser } from '../models/user';
import { HttpClient,HttpHeaders } from "@angular/common/http";
import { AppConfig } from "../shared/app.config";
@Injectable({
providedIn: 'root',
})
export class ImageService {
constructor(public httpClient: HttpClient, public appConfig: AppConfig) {
}
ApiEndpoint() {
return this.appConfig.getConfig("apiEndPoint");
}
putImage(endpoint:string,blob:Blob) {
const formData = new FormData();
formData.append('file', blob,blob.type);
return this.httpClient.put<any>(endpoint,formData);
}
b64toBlob(b64Data:string, contentType?:string):Blob {
const sliceSize = 512;
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
}

View File

@ -1,9 +1,9 @@
{ {
"issuer": "https://accounts.test.farmmaps.eu", "issuer": "https://accounts.test.farmmaps.eu",
"clientId": "farmmapsdev", "clientId": "farmmapsdev",
"audience": "https://test.farmmaps.eu", "audience": "http://localhost:8082",
"requireHttps": true, "requireHttps": true,
"apiEndPoint": "https://test.farmmaps.eu", "apiEndPoint": "http://localhost:8082",
"grantType":"code" "grantType":"code"
} }