#327413 Add image picker for editable images.
This commit is contained in:
Родитель
4f903f86f7
Коммит
9d494d4b12
|
@ -11,13 +11,15 @@ import {
|
||||||
EventsService,
|
EventsService,
|
||||||
EventRegistrationsService,
|
EventRegistrationsService,
|
||||||
AlertService,
|
AlertService,
|
||||||
GroupsService
|
GroupsService,
|
||||||
|
ImagePickerService,
|
||||||
|
FilesService
|
||||||
} from './services';
|
} from './services';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
templateUrl: 'app.component.html',
|
templateUrl: 'app.component.html',
|
||||||
providers: [EverliveProvider, UsersService, EventsService, EventRegistrationsService, AlertService, GroupsService]
|
providers: [EverliveProvider, UsersService, EventsService, EventRegistrationsService, AlertService, GroupsService, ImagePickerService, FilesService]
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
loggedIn: boolean = false;
|
loggedIn: boolean = false;
|
||||||
|
|
|
@ -3,7 +3,8 @@ import { RouterExtensions } from 'nativescript-angular/router';
|
||||||
|
|
||||||
import { EventCreationModalComponent } from '../event-creation-modal/event-creation-modal.component';
|
import { EventCreationModalComponent } from '../event-creation-modal/event-creation-modal.component';
|
||||||
import { Event, Group } from '../../shared/models';
|
import { Event, Group } from '../../shared/models';
|
||||||
import { EventsService, AlertService, UsersService, GroupsService } from '../../services';
|
import { EventsService, AlertService, UsersService, GroupsService, FilesService } from '../../services';
|
||||||
|
import { utilities } from '../../shared';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'add-event',
|
selector: 'add-event',
|
||||||
|
@ -16,6 +17,7 @@ export class AddEventComponent {
|
||||||
constructor(
|
constructor(
|
||||||
private _routerExtensions: RouterExtensions,
|
private _routerExtensions: RouterExtensions,
|
||||||
private _groupsService: GroupsService,
|
private _groupsService: GroupsService,
|
||||||
|
private _filesService: FilesService,
|
||||||
private _eventService: EventsService,
|
private _eventService: EventsService,
|
||||||
private _alertService: AlertService,
|
private _alertService: AlertService,
|
||||||
private _usersService: UsersService,
|
private _usersService: UsersService,
|
||||||
|
@ -35,6 +37,20 @@ export class AddEventComponent {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
// TODO: move to service
|
||||||
|
let prm = Promise.resolve<{ Id: string, Uri: string }>();
|
||||||
|
|
||||||
|
if (utilities.isLocalUrl(this.newEvent.ImageUrl)) {
|
||||||
|
// this has been turned into local uri by the picker component
|
||||||
|
prm = this._filesService.uploadFromUri(this.newEvent.ImageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prm;
|
||||||
|
})
|
||||||
|
.then((uploadResult) => {
|
||||||
|
if (uploadResult) {
|
||||||
|
this.newEvent.Image = uploadResult.Id;
|
||||||
|
}
|
||||||
let creationPromise = this._eventService.create(this.newEvent);
|
let creationPromise = this._eventService.create(this.newEvent);
|
||||||
let groupPromise = this._groupsService.getById(this.newEvent.GroupId);
|
let groupPromise = this._groupsService.getById(this.newEvent.GroupId);
|
||||||
return Promise.all<any>([groupPromise, creationPromise]);;
|
return Promise.all<any>([groupPromise, creationPromise]);;
|
||||||
|
|
|
@ -2,8 +2,9 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { RouterExtensions } from 'nativescript-angular/router';
|
import { RouterExtensions } from 'nativescript-angular/router';
|
||||||
|
|
||||||
import { EventsService, AlertService } from '../../services';
|
import { EventsService, AlertService, FilesService } from '../../services';
|
||||||
import { Event, User } from '../../shared/models';
|
import { Event, User } from '../../shared/models';
|
||||||
|
import { utilities } from '../../shared';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'edit-event',
|
selector: 'edit-event',
|
||||||
|
@ -17,8 +18,9 @@ export class EditEventComponent implements OnInit {
|
||||||
private _route: ActivatedRoute,
|
private _route: ActivatedRoute,
|
||||||
private _alertsService: AlertService,
|
private _alertsService: AlertService,
|
||||||
private _routerExtensions: RouterExtensions,
|
private _routerExtensions: RouterExtensions,
|
||||||
|
private _filesService: FilesService,
|
||||||
private _eventsService: EventsService
|
private _eventsService: EventsService
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this._route.params.subscribe(p => {
|
this._route.params.subscribe(p => {
|
||||||
|
@ -39,6 +41,20 @@ export class EditEventComponent implements OnInit {
|
||||||
|
|
||||||
this._alertsService.askConfirmation('Save all changes?')
|
this._alertsService.askConfirmation('Save all changes?')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
// TODO: move to service
|
||||||
|
let prm = Promise.resolve<{ Id: string, Uri: string }>();
|
||||||
|
|
||||||
|
if (utilities.isLocalUrl(this.event.ImageUrl)) {
|
||||||
|
// this has been turned into local uri by the picker component
|
||||||
|
prm = this._filesService.uploadFromUri(this.event.ImageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prm;
|
||||||
|
})
|
||||||
|
.then((uploadResult) => {
|
||||||
|
if (uploadResult) {
|
||||||
|
this.event.Image = uploadResult.Id;
|
||||||
|
}
|
||||||
return this._eventsService.update(this.event);
|
return this._eventsService.update(this.event);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -51,7 +67,7 @@ export class EditEventComponent implements OnInit {
|
||||||
if (err) {
|
if (err) {
|
||||||
this._alertsService.showError(err.message);
|
this._alertsService.showError(err.message);
|
||||||
}
|
}
|
||||||
});;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<StackLayout class="cntnr">
|
<StackLayout class="cntnr">
|
||||||
<photo-picker [url]="event.ImageUrl" [type]="'event'" [editable]="true"></photo-picker>
|
<photo-picker [(url)]="event.ImageUrl" [type]="'event'" [editable]="true"></photo-picker>
|
||||||
|
|
||||||
<StackLayout class="form info-cntnr">
|
<StackLayout class="form info-cntnr">
|
||||||
<StackLayout class="input-field">
|
<StackLayout class="input-field">
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
border-bottom-width: 1;
|
border-bottom-width: 1;
|
||||||
border-color: #ccc;
|
border-color: #ccc;
|
||||||
|
margin: 0 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
.event-name,
|
.event-name,
|
||||||
.event-date-wrp,
|
.event-date-wrp,
|
||||||
.event-description,
|
.event-description,
|
||||||
.event-organiser,
|
.event-organiser {
|
||||||
.event-list-separator {
|
|
||||||
margin: 10 20;
|
margin: 10 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ export class EventsComponent implements OnInit {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
onAdd() {
|
onAdd() {
|
||||||
this._routerExtensions.navigate(['/events/add']);
|
this._routerExtensions.navigateByUrl('/events/add');
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||||
import { RouterExtensions } from 'nativescript-angular/router';
|
import { RouterExtensions } from 'nativescript-angular/router';
|
||||||
|
|
||||||
import { GroupCreationModalComponent } from '../group-creation-modal/group-creation-modal.component';
|
import { GroupCreationModalComponent } from '../group-creation-modal/group-creation-modal.component';
|
||||||
import { GroupsService, AlertService } from '../../services';
|
import { GroupsService, AlertService, FilesService } from '../../services';
|
||||||
import { Group } from '../../shared/models';
|
import { Group } from '../../shared/models';
|
||||||
import { utilities } from '../../shared';
|
import { utilities } from '../../shared';
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ export class AddGroupComponent {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _routerExtensions: RouterExtensions,
|
private _routerExtensions: RouterExtensions,
|
||||||
|
private _filesService: FilesService,
|
||||||
private _groupsService: GroupsService,
|
private _groupsService: GroupsService,
|
||||||
private _alertService: AlertService,
|
private _alertService: AlertService,
|
||||||
private _vsRef: ViewContainerRef
|
private _vsRef: ViewContainerRef
|
||||||
|
@ -30,25 +31,35 @@ export class AddGroupComponent {
|
||||||
return this._alertService.showError(errMsg);
|
return this._alertService.showError(errMsg);
|
||||||
}
|
}
|
||||||
let createdId: string;
|
let createdId: string;
|
||||||
this._groupsService.create(this.group)
|
let promise: Promise<{ Id: string, Uri: string }> = Promise.resolve();
|
||||||
.then((result) => {
|
|
||||||
createdId = result.Id;
|
if (utilities.isLocalUrl(this.group.ImageUrl)) {
|
||||||
let ctx = { groupName: this.group.Name };
|
promise = this._filesService.uploadFromUri(this.group.ImageUrl);
|
||||||
return this._alertService.showModal(ctx, this._vsRef, GroupCreationModalComponent);
|
}
|
||||||
})
|
|
||||||
.then((doInviteMembers: boolean) => {
|
promise.then((uploadResult) => {
|
||||||
if (doInviteMembers) {
|
if (uploadResult) {
|
||||||
return this._alertService.showError('Not implemented, yet');
|
this.group.Image = uploadResult.Id;
|
||||||
}
|
}
|
||||||
|
return this._groupsService.create(this.group);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then((result) => {
|
||||||
this._routerExtensions.navigateByUrl(`/groups/${createdId}`);
|
createdId = result.Id;
|
||||||
})
|
let ctx = { groupName: this.group.Name };
|
||||||
.catch(err => {
|
return this._alertService.showModal(ctx, this._vsRef, GroupCreationModalComponent);
|
||||||
if (err) {
|
})
|
||||||
this._alertService.showError(err.message);
|
.then((doInviteMembers: boolean) => {
|
||||||
}
|
if (doInviteMembers) {
|
||||||
});
|
return this._alertService.showError('Not implemented, yet');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this._routerExtensions.navigateByUrl(`/groups/${createdId}`);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err) {
|
||||||
|
this._alertService.showError(err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { RouterExtensions } from 'nativescript-angular/router';
|
import { RouterExtensions } from 'nativescript-angular/router';
|
||||||
|
|
||||||
import { GroupsService, AlertService } from '../../services';
|
import { GroupsService, AlertService, FilesService } from '../../services';
|
||||||
import { Group } from '../../shared/models';
|
import { Group } from '../../shared/models';
|
||||||
import { utilities } from '../../shared';
|
import { utilities } from '../../shared';
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ export class EditGroupComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private _groupsService: GroupsService,
|
private _groupsService: GroupsService,
|
||||||
private _alertsService: AlertService,
|
private _alertsService: AlertService,
|
||||||
|
private _filesService: FilesService,
|
||||||
private _routerExtensions: RouterExtensions,
|
private _routerExtensions: RouterExtensions,
|
||||||
private _activatedRoute: ActivatedRoute
|
private _activatedRoute: ActivatedRoute
|
||||||
) { }
|
) { }
|
||||||
|
@ -40,6 +41,18 @@ export class EditGroupComponent implements OnInit {
|
||||||
|
|
||||||
this._alertsService.askConfirmation(`Update all fields of "${this.group.Name}"?`)
|
this._alertsService.askConfirmation(`Update all fields of "${this.group.Name}"?`)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
let prm = Promise.resolve<{ Id: string, Uri: string }>();
|
||||||
|
|
||||||
|
if (utilities.isLocalUrl(this.group.ImageUrl)) {
|
||||||
|
prm = this._filesService.uploadFromUri(this.group.ImageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prm;
|
||||||
|
})
|
||||||
|
.then((uploadResult) => {
|
||||||
|
if (uploadResult) {
|
||||||
|
this.group.Image = uploadResult.Id;
|
||||||
|
}
|
||||||
return this._groupsService.update(this.group);
|
return this._groupsService.update(this.group);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -17,7 +17,7 @@ TextView {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-image {
|
.user >>> Image {
|
||||||
width: 30;
|
width: 30;
|
||||||
height: 30;
|
height: 30;
|
||||||
margin-right: 10;
|
margin-right: 10;
|
||||||
|
|
|
@ -51,14 +51,6 @@ export class EditableGroupComponent implements OnInit {
|
||||||
}, err => err); // ignore rejection (when user clicks back and closes));
|
}, err => err); // ignore rejection (when user clicks back and closes));
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserResizedUrl(rawUrl: string) {
|
|
||||||
return this._getResizedImageUrl(rawUrl, { width: 60, height: 60 });
|
|
||||||
}
|
|
||||||
|
|
||||||
getGroupResizedUrl(rawUrl: string) {
|
|
||||||
return this._getResizedImageUrl(rawUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _openGroupTypeModal() {
|
private _openGroupTypeModal() {
|
||||||
let ctx = {
|
let ctx = {
|
||||||
items: this._groupTypeOptions,
|
items: this._groupTypeOptions,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<StackLayout class="cntnr">
|
<StackLayout class="cntnr">
|
||||||
<Image src="{{getGroupResizedUrl(group.ImageUrl)}}"></Image>
|
<photo-picker [(url)]="group.ImageUrl" [editable]="true" [type]="'group'"></photo-picker>
|
||||||
|
|
||||||
<StackLayout class="input-field">
|
<StackLayout class="input-field">
|
||||||
<Label class="label" text="Name"></Label>
|
<Label class="label" text="Name"></Label>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<StackLayout *ngIf="currentUser" class="input-field user">
|
<StackLayout *ngIf="currentUser" class="input-field user">
|
||||||
<Label class="label" text="Administrator"></Label>
|
<Label class="label" text="Administrator"></Label>
|
||||||
<StackLayout orientation="horizontal">
|
<StackLayout orientation="horizontal">
|
||||||
<Image class="user-image" src="{{getUserResizedUrl(currentUser.ImageUrl)}}"></Image>
|
<photo-picker [url]="currentUser.ImageUrl" [type]="'user'" [small]="true"></photo-picker>
|
||||||
<Label class="user-label" [text]="currentUser.DisplayName || currentUser.Username"></Label>
|
<Label class="user-label" [text]="currentUser.DisplayName || currentUser.Username"></Label>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { EverliveProvider } from './everlive-provider.service';
|
||||||
|
import { ImagePickerService } from './image-picker.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FilesService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _elProvider: EverliveProvider,
|
||||||
|
private _imagesService: ImagePickerService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
upload(base64File: string, filename?: string) {
|
||||||
|
let data = {
|
||||||
|
Filename: filename || `teamupimg${Date.now()}.png`,
|
||||||
|
ContentType: 'image/png',
|
||||||
|
base64: base64File
|
||||||
|
};
|
||||||
|
|
||||||
|
return this._elProvider.get.files.create(data)
|
||||||
|
.then((res: any) => {
|
||||||
|
let result = res.result;
|
||||||
|
return {
|
||||||
|
Id: result.Id,
|
||||||
|
Uri: result.Uri
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadFromUri(uri: string) {
|
||||||
|
let base64 = this._imagesService.getBase64FromUri(uri);
|
||||||
|
return this.upload(base64);
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ export class GroupsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
create(group: Group) {
|
create(group: Group) {
|
||||||
|
group = this._sanitizeGroup(group);
|
||||||
return this._groupsData.create(group).then(res => res.result);
|
return this._groupsData.create(group).then(res => res.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ export class GroupsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
update(group: Group) {
|
update(group: Group) {
|
||||||
delete (<any>group).ImageUrl; // sanitize expanded field
|
group = this._sanitizeGroup(group);
|
||||||
return this._groupsData.updateSingle(group).then(r => r.result);
|
return this._groupsData.updateSingle(group).then(r => r.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,4 +197,9 @@ export class GroupsService {
|
||||||
query.expand(this._imageExpandExp);
|
query.expand(this._imageExpandExp);
|
||||||
return this._groupsData.get(query).then(res => res.result);
|
return this._groupsData.get(query).then(res => res.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _sanitizeGroup(group: Group) {
|
||||||
|
delete group.ImageUrl;
|
||||||
|
return group;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import * as nsPermissions from 'nativescript-permissions';
|
||||||
|
import * as nsPicker from 'nativescript-imagepicker';
|
||||||
|
import * as nsImgSource from 'image-source';
|
||||||
|
import * as nsPlatform from 'platform';
|
||||||
|
import * as fs from 'file-system';
|
||||||
|
|
||||||
|
import { EverliveProvider } from './';
|
||||||
|
declare const android: any;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ImagePickerService {
|
||||||
|
private _imageItems: any[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _elProvider: EverliveProvider
|
||||||
|
) {}
|
||||||
|
|
||||||
|
pickImage() {
|
||||||
|
return this._pick('single')
|
||||||
|
.then(images => images[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pickImages() {
|
||||||
|
return this._pick('multiple');
|
||||||
|
}
|
||||||
|
|
||||||
|
getBase64FromUri(uri: string) {
|
||||||
|
let imgSrc = nsImgSource.fromFileOrResource(uri);
|
||||||
|
return imgSrc.toBase64String('png');
|
||||||
|
}
|
||||||
|
|
||||||
|
private _pick(mode: string): Promise<{ name: string, uri: string }[]> {
|
||||||
|
let ctx = nsPicker.create({ mode });
|
||||||
|
let authPromise = Promise.resolve<any>();
|
||||||
|
|
||||||
|
if (nsPlatform.device.os === 'Android' && (+nsPlatform.device.sdkVersion >= 23)) {
|
||||||
|
let text = 'We need these permissions to read from storage';
|
||||||
|
let permType = android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||||
|
authPromise = nsPermissions.requestPermission(permType, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authPromise.then(() => this._presentPicker(ctx))
|
||||||
|
.then((res) => {
|
||||||
|
return this._processImages(res);
|
||||||
|
}, (err) => {
|
||||||
|
console.log('user cancelled or refused to grant permissions');
|
||||||
|
return Promise.reject(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _presentPicker(context: any) {
|
||||||
|
return context.authorize()
|
||||||
|
.then(() => {
|
||||||
|
return context.present();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _processImages(selection: any[]): Promise<{ name: string, uri: string }[]> {
|
||||||
|
let processedImgs: Promise<any>[] = selection.map((selectedItem) => {
|
||||||
|
return selectedItem.getImage().then(imgSource => {
|
||||||
|
return this._processImage(imgSource);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.all(processedImgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _processImage(imageSource: any): Promise<{ name: string, uri: string }> {
|
||||||
|
let name = `teamupimg${Date.now()}.png`;
|
||||||
|
let folder = fs.knownFolders.documents();
|
||||||
|
let uri = fs.path.join(folder.path, name);
|
||||||
|
let saved = imageSource.saveToFile(uri, 'png');
|
||||||
|
let imgItem = null;
|
||||||
|
|
||||||
|
if (saved) {
|
||||||
|
imgItem = { name, uri };
|
||||||
|
} else {
|
||||||
|
console.log('didnt save!!!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return imgItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private _sendImage(name, uri) {
|
||||||
|
// let base64;
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// let imgSrc = nsImgSource.fromFileOrResource(uri);
|
||||||
|
// base64 = imgSrc.toBase64String('png');
|
||||||
|
// } catch (ex) {
|
||||||
|
// console.log('err parsing as base64: ' + JSON.stringify(ex.message));
|
||||||
|
// return Promise.reject({ message: 'Could not read image' });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return Promise.resolve();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private _sendImages(imgData: { name: any, uri: any }[]) {
|
||||||
|
// let sendPromises: Promise<any>[] = [];
|
||||||
|
|
||||||
|
// imgData.forEach(data => {
|
||||||
|
// if (data) {
|
||||||
|
// console.log(`id: ${JSON.stringify(data)}`);
|
||||||
|
// sendPromises.push(this._sendImage(data.name, data.uri));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return Promise.all(sendPromises);
|
||||||
|
// }
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
|
export * from './event-registrations.service';
|
||||||
|
export * from './event-registrations.service';
|
||||||
export * from './everlive-provider.service';
|
export * from './everlive-provider.service';
|
||||||
|
export * from './files.service';
|
||||||
export * from './users.service';
|
export * from './users.service';
|
||||||
export * from './events.service';
|
export * from './events.service';
|
||||||
export * from './event-registrations.service';
|
|
||||||
export * from './alert.service';
|
export * from './alert.service';
|
||||||
export * from './groups.service';
|
export * from './groups.service';
|
||||||
|
export * from './image-picker.service';
|
||||||
|
|
|
@ -82,6 +82,6 @@ export class UsersService {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new User(user.Id, user.Username, user.DisplayName, user.Email, user.ImageUrl, user.Phone);
|
return new User(user.Id, user.Username, user.DisplayName, user.Email, user.ImageUrl, user.Phone, user.Image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ import { ItemModel } from './item.model';
|
||||||
|
|
||||||
export class Group extends ItemModel {
|
export class Group extends ItemModel {
|
||||||
Name: string;
|
Name: string;
|
||||||
Image?: string;
|
Image: string;
|
||||||
|
ImageUrl: string;
|
||||||
RequiresApproval: boolean;
|
RequiresApproval: boolean;
|
||||||
IsPublic: boolean;
|
IsPublic: boolean;
|
||||||
Description: string;
|
Description: string;
|
||||||
|
|
|
@ -8,7 +8,8 @@ export class User extends ItemModel {
|
||||||
public DisplayName: string,
|
public DisplayName: string,
|
||||||
public Email: string,
|
public Email: string,
|
||||||
public ImageUrl: string,
|
public ImageUrl: string,
|
||||||
public Phone: string
|
public Phone: string,
|
||||||
|
public Image: string
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.container.large {
|
||||||
|
width: 100%;
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit, Output, EventEmitter, ViewChild } from '@angular/core';
|
||||||
|
import * as nsImgSource from 'image-source';
|
||||||
|
import * as nsImage from 'ui/image';
|
||||||
|
|
||||||
|
import { ImagePickerService } from '../../services';
|
||||||
import { utilities, constants } from '../';
|
import { utilities, constants } from '../';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -15,6 +18,12 @@ export class PhotoPickerComponent implements OnInit {
|
||||||
@Input('small') isSmall: boolean;
|
@Input('small') isSmall: boolean;
|
||||||
@Input() editable: boolean;
|
@Input() editable: boolean;
|
||||||
|
|
||||||
|
@Output('urlChange') onUpload = new EventEmitter<any>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _imgPickerService: ImagePickerService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (!this.rawUrl) {
|
if (!this.rawUrl) {
|
||||||
this.rawUrl = this._decidePlaceholder();
|
this.rawUrl = this._decidePlaceholder();
|
||||||
|
@ -25,7 +34,18 @@ export class PhotoPickerComponent implements OnInit {
|
||||||
|
|
||||||
onEdit(event) {
|
onEdit(event) {
|
||||||
if (this.editable) {
|
if (this.editable) {
|
||||||
console.log('picking...');
|
this._imgPickerService.pickImage()
|
||||||
|
.then(obj => {
|
||||||
|
console.log('picked:' + JSON.stringify(obj));
|
||||||
|
// this.onUpload.emit(obj);
|
||||||
|
|
||||||
|
// this.editableImg.imageSource = nsImgSource.fromFileOrResource(obj.uri);
|
||||||
|
this.resizedUrl = obj.uri;
|
||||||
|
this.onUpload.emit(obj.uri);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('pick err: ' + JSON.stringify(err));
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('editable is false...');
|
console.log('editable is false...');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<StackLayout *ngIf="resizedUrl">
|
<AbsoluteLayout *ngIf="resizedUrl">
|
||||||
<Image *ngIf="editable" [src]="resizedUrl" (tap)="onEdit()"></Image>
|
<StackLayout class="container" [ngClass]="{ 'large': !isSmall }">
|
||||||
<Image *ngIf="!editable" [src]="resizedUrl"></Image>
|
<Image class="image" *ngIf="editable" [src]="resizedUrl" (tap)="onEdit()"></Image>
|
||||||
</StackLayout>
|
<Image class="image" *ngIf="!editable" [src]="resizedUrl"></Image>
|
||||||
|
</StackLayout>
|
||||||
|
</AbsoluteLayout>
|
||||||
|
|
|
@ -33,3 +33,8 @@ export function findIndex<T> (arr: T[], predicate: (item: T) => any): number {
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function isLocalUrl (url: string) {
|
||||||
|
let regExp = new RegExp('^\/.*', 'i');
|
||||||
|
return url && regExp.test(url);
|
||||||
|
};
|
||||||
|
|
|
@ -36,4 +36,9 @@ export class EditUserComponent implements OnInit {
|
||||||
.then(() => this._routerExtensions.navigateByUrl('user'))
|
.then(() => this._routerExtensions.navigateByUrl('user'))
|
||||||
.catch(err => err && this._alertsService.showError(err));
|
.catch(err => err && this._alertsService.showError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onImageUpload(createdImage: { Uri: string, Id: string }) {
|
||||||
|
this.user.Image = createdImage.Id;
|
||||||
|
this._usersService.updateUser(this.user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<StackLayout *ngIf="user" class="user-info-cnt">
|
<StackLayout *ngIf="user" class="user-info-cnt">
|
||||||
<photo-picker [url]="user.ImageUrl" [type]="'user'" [editable]="true"></photo-picker>
|
<photo-picker [(url)]="user.ImageUrl" [type]="'user'" [editable]="true" (uplodad)="onImageUpload($event)"></photo-picker>
|
||||||
|
|
||||||
<StackLayout class="user-info-block">
|
<StackLayout class="user-info-block">
|
||||||
<Label class="user-label" text="Name"></Label>
|
<Label class="user-label" text="Name"></Label>
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
"tns-core-modules": "2.4.4",
|
"tns-core-modules": "2.4.4",
|
||||||
"rxjs": "5.0.0-beta.12",
|
"rxjs": "5.0.0-beta.12",
|
||||||
"everlive-sdk": "1.9.1",
|
"everlive-sdk": "1.9.1",
|
||||||
"nativescript-theme-core": "^0.1.3"
|
"nativescript-theme-core": "^0.1.3",
|
||||||
|
"nativescript-imagepicker": "^2.4.1",
|
||||||
|
"nativescript-permissions": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-traverse": "6.18.0",
|
"babel-traverse": "6.18.0",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче