#327413 Add image picker for editable images.
This commit is contained in:
Родитель
4f903f86f7
Коммит
9d494d4b12
|
@ -11,13 +11,15 @@ import {
|
|||
EventsService,
|
||||
EventRegistrationsService,
|
||||
AlertService,
|
||||
GroupsService
|
||||
GroupsService,
|
||||
ImagePickerService,
|
||||
FilesService
|
||||
} from './services';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
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 {
|
||||
loggedIn: boolean = false;
|
||||
|
|
|
@ -3,7 +3,8 @@ import { RouterExtensions } from 'nativescript-angular/router';
|
|||
|
||||
import { EventCreationModalComponent } from '../event-creation-modal/event-creation-modal.component';
|
||||
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({
|
||||
selector: 'add-event',
|
||||
|
@ -16,6 +17,7 @@ export class AddEventComponent {
|
|||
constructor(
|
||||
private _routerExtensions: RouterExtensions,
|
||||
private _groupsService: GroupsService,
|
||||
private _filesService: FilesService,
|
||||
private _eventService: EventsService,
|
||||
private _alertService: AlertService,
|
||||
private _usersService: UsersService,
|
||||
|
@ -35,6 +37,20 @@ export class AddEventComponent {
|
|||
}
|
||||
})
|
||||
.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 groupPromise = this._groupsService.getById(this.newEvent.GroupId);
|
||||
return Promise.all<any>([groupPromise, creationPromise]);;
|
||||
|
|
|
@ -2,8 +2,9 @@ import { Component, OnInit } from '@angular/core';
|
|||
import { ActivatedRoute } from '@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 { utilities } from '../../shared';
|
||||
|
||||
@Component({
|
||||
selector: 'edit-event',
|
||||
|
@ -17,8 +18,9 @@ export class EditEventComponent implements OnInit {
|
|||
private _route: ActivatedRoute,
|
||||
private _alertsService: AlertService,
|
||||
private _routerExtensions: RouterExtensions,
|
||||
private _filesService: FilesService,
|
||||
private _eventsService: EventsService
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._route.params.subscribe(p => {
|
||||
|
@ -39,6 +41,20 @@ export class EditEventComponent implements OnInit {
|
|||
|
||||
this._alertsService.askConfirmation('Save all changes?')
|
||||
.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);
|
||||
})
|
||||
.then(() => {
|
||||
|
@ -51,7 +67,7 @@ export class EditEventComponent implements OnInit {
|
|||
if (err) {
|
||||
this._alertsService.showError(err.message);
|
||||
}
|
||||
});;
|
||||
});
|
||||
}
|
||||
|
||||
delete() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<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="input-field">
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
border-width: 0;
|
||||
border-bottom-width: 1;
|
||||
border-color: #ccc;
|
||||
margin: 0 20;
|
||||
}
|
||||
|
||||
.event-name,
|
||||
.event-date-wrp,
|
||||
.event-description,
|
||||
.event-organiser,
|
||||
.event-list-separator {
|
||||
.event-organiser {
|
||||
margin: 10 20;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ export class EventsComponent implements OnInit {
|
|||
) { }
|
||||
|
||||
onAdd() {
|
||||
this._routerExtensions.navigate(['/events/add']);
|
||||
this._routerExtensions.navigateByUrl('/events/add');
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router';
|
|||
import { RouterExtensions } from 'nativescript-angular/router';
|
||||
|
||||
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 { utilities } from '../../shared';
|
||||
|
||||
|
@ -17,6 +17,7 @@ export class AddGroupComponent {
|
|||
|
||||
constructor(
|
||||
private _routerExtensions: RouterExtensions,
|
||||
private _filesService: FilesService,
|
||||
private _groupsService: GroupsService,
|
||||
private _alertService: AlertService,
|
||||
private _vsRef: ViewContainerRef
|
||||
|
@ -30,25 +31,35 @@ export class AddGroupComponent {
|
|||
return this._alertService.showError(errMsg);
|
||||
}
|
||||
let createdId: string;
|
||||
this._groupsService.create(this.group)
|
||||
.then((result) => {
|
||||
createdId = result.Id;
|
||||
let ctx = { groupName: this.group.Name };
|
||||
return this._alertService.showModal(ctx, this._vsRef, GroupCreationModalComponent);
|
||||
})
|
||||
.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);
|
||||
}
|
||||
});
|
||||
let promise: Promise<{ Id: string, Uri: string }> = Promise.resolve();
|
||||
|
||||
if (utilities.isLocalUrl(this.group.ImageUrl)) {
|
||||
promise = this._filesService.uploadFromUri(this.group.ImageUrl);
|
||||
}
|
||||
|
||||
promise.then((uploadResult) => {
|
||||
if (uploadResult) {
|
||||
this.group.Image = uploadResult.Id;
|
||||
}
|
||||
return this._groupsService.create(this.group);
|
||||
})
|
||||
.then((result) => {
|
||||
createdId = result.Id;
|
||||
let ctx = { groupName: this.group.Name };
|
||||
return this._alertService.showModal(ctx, this._vsRef, GroupCreationModalComponent);
|
||||
})
|
||||
.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 { RouterExtensions } from 'nativescript-angular/router';
|
||||
|
||||
import { GroupsService, AlertService } from '../../services';
|
||||
import { GroupsService, AlertService, FilesService } from '../../services';
|
||||
import { Group } from '../../shared/models';
|
||||
import { utilities } from '../../shared';
|
||||
|
||||
|
@ -17,6 +17,7 @@ export class EditGroupComponent implements OnInit {
|
|||
constructor(
|
||||
private _groupsService: GroupsService,
|
||||
private _alertsService: AlertService,
|
||||
private _filesService: FilesService,
|
||||
private _routerExtensions: RouterExtensions,
|
||||
private _activatedRoute: ActivatedRoute
|
||||
) { }
|
||||
|
@ -40,6 +41,18 @@ export class EditGroupComponent implements OnInit {
|
|||
|
||||
this._alertsService.askConfirmation(`Update all fields of "${this.group.Name}"?`)
|
||||
.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);
|
||||
})
|
||||
.then(() => {
|
||||
|
|
|
@ -17,7 +17,7 @@ TextView {
|
|||
color: #888;
|
||||
}
|
||||
|
||||
.user-image {
|
||||
.user >>> Image {
|
||||
width: 30;
|
||||
height: 30;
|
||||
margin-right: 10;
|
||||
|
|
|
@ -51,14 +51,6 @@ export class EditableGroupComponent implements OnInit {
|
|||
}, 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() {
|
||||
let ctx = {
|
||||
items: this._groupTypeOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<StackLayout class="cntnr">
|
||||
<Image src="{{getGroupResizedUrl(group.ImageUrl)}}"></Image>
|
||||
<photo-picker [(url)]="group.ImageUrl" [editable]="true" [type]="'group'"></photo-picker>
|
||||
|
||||
<StackLayout class="input-field">
|
||||
<Label class="label" text="Name"></Label>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<StackLayout *ngIf="currentUser" class="input-field user">
|
||||
<Label class="label" text="Administrator"></Label>
|
||||
<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>
|
||||
</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) {
|
||||
group = this._sanitizeGroup(group);
|
||||
return this._groupsData.create(group).then(res => res.result);
|
||||
}
|
||||
|
||||
|
@ -138,7 +139,7 @@ export class GroupsService {
|
|||
}
|
||||
|
||||
update(group: Group) {
|
||||
delete (<any>group).ImageUrl; // sanitize expanded field
|
||||
group = this._sanitizeGroup(group);
|
||||
return this._groupsData.updateSingle(group).then(r => r.result);
|
||||
}
|
||||
|
||||
|
@ -196,4 +197,9 @@ export class GroupsService {
|
|||
query.expand(this._imageExpandExp);
|
||||
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 './files.service';
|
||||
export * from './users.service';
|
||||
export * from './events.service';
|
||||
export * from './event-registrations.service';
|
||||
export * from './alert.service';
|
||||
export * from './groups.service';
|
||||
export * from './image-picker.service';
|
||||
|
|
|
@ -82,6 +82,6 @@ export class UsersService {
|
|||
if (!user) {
|
||||
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 {
|
||||
Name: string;
|
||||
Image?: string;
|
||||
Image: string;
|
||||
ImageUrl: string;
|
||||
RequiresApproval: boolean;
|
||||
IsPublic: boolean;
|
||||
Description: string;
|
||||
|
|
|
@ -8,7 +8,8 @@ export class User extends ItemModel {
|
|||
public DisplayName: string,
|
||||
public Email: string,
|
||||
public ImageUrl: string,
|
||||
public Phone: string
|
||||
public Phone: string,
|
||||
public Image: string
|
||||
) {
|
||||
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 '../';
|
||||
|
||||
@Component({
|
||||
|
@ -15,6 +18,12 @@ export class PhotoPickerComponent implements OnInit {
|
|||
@Input('small') isSmall: boolean;
|
||||
@Input() editable: boolean;
|
||||
|
||||
@Output('urlChange') onUpload = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private _imgPickerService: ImagePickerService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.rawUrl) {
|
||||
this.rawUrl = this._decidePlaceholder();
|
||||
|
@ -25,7 +34,18 @@ export class PhotoPickerComponent implements OnInit {
|
|||
|
||||
onEdit(event) {
|
||||
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 {
|
||||
console.log('editable is false...');
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<StackLayout *ngIf="resizedUrl">
|
||||
<Image *ngIf="editable" [src]="resizedUrl" (tap)="onEdit()"></Image>
|
||||
<Image *ngIf="!editable" [src]="resizedUrl"></Image>
|
||||
</StackLayout>
|
||||
<AbsoluteLayout *ngIf="resizedUrl">
|
||||
<StackLayout class="container" [ngClass]="{ 'large': !isSmall }">
|
||||
<Image class="image" *ngIf="editable" [src]="resizedUrl" (tap)="onEdit()"></Image>
|
||||
<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;
|
||||
};
|
||||
|
||||
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'))
|
||||
.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>
|
||||
<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">
|
||||
<Label class="user-label" text="Name"></Label>
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
"tns-core-modules": "2.4.4",
|
||||
"rxjs": "5.0.0-beta.12",
|
||||
"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": {
|
||||
"babel-traverse": "6.18.0",
|
||||
|
|
Загрузка…
Ссылка в новой задаче