Автоматическая установка фото профиля в приложении NativeScript Angular

Разработка /
Как превратить просто хорошее мобильное приложение в отличное мобильное приложение? К примеру, что вы выберете: экран входа в приложение с запросом только логина и пароля или лучше добавить туда фото пользователя?
С помощью сервиса Gravatar вы можете получить аватарку по email адресу пользователя, если он загрузил её туда.
Мы увидим как автоматически установить аватарку в приложении на базе NativeScript Angular с помощью API сервиса Gravatar.

Наша цель — сделать приложение более запоминающимся для пользователя.

Создаём новый проект NativeScript Angular

Для лучшего понимания создадим проект приложения NativeScript с нуля для платформ и , в котором будем использовать Angular и TypeScript.
В командной строке (в Windows) или в окне терминала (в Linux и Mac) выполните следующие команды (перед этим убедитесь, что у вас установлен NativeScript):
tns create GravatarProject --ng
cd GravatarProject
tns platform add ios
tns platform add android

Для разработки приложений под iOS обязательно нужно иметь Mac с установленным Xcode!
Gravatar API требует хеширования email адреса алгоритмом MD5 перед отправкой их на сервис с помощью HTTP запроса. В JavaScript нет встроенной функции для этого, поэтому установим необходимую библиотеку.
Для этого выполним следующую команду:
npm install blueimp-md5 --save

Этот код установит библиотеку blueimp MD5.

Создание логики на TypeScript для использования Gravatar

Цель нашего алгоритма — захешировать email и отправить его в Gravatar в надежде получить от него картинку. Мы не будем делать запросы Angular HTTP из-за формата API.
Пример файла app/app.component.ts:
import { Component } from "@angular/core";
var MD5 = require("blueimp-md5");
 
@Component({
    selector: "my-app",
    templateUrl: "app.component.html"
})
export class AppComponent {
 
    public picture: string;
    public email: string;
 
    public constructor() {
        this.email = "";
        this.picture = "https://www.gravatar.com/avatar/00000000000000000000000000000000?s=150";
    }
 
    public getProfilePicture(email: any) {
        if(this.validateEmail(email)) {
            this.picture = "https://www.gravatar.com/avatar/" + MD5(email) + "?s=150";
        }
    }
 
    // Taken from http://stackoverflow.com/a/46181/498479
    private validateEmail(email: any) {
        let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }
 
}

Здесь не так много кода, но мы всё равно рассмотрим его более подробно.

После импорта компонентов Angular и MD5, мы создаём класс AppComponent. В этом классе есть две public переменных, одна из которых будет содержать ссылку на изображение из Gravatar, будь это реальная картинка или картинка по-умолчанию, а в другой будем хранить текущий email адрес.
В методе constructor мы инициализируем эти переменные. В переменной picture сначала будет ссылка на шаблон изображения Gravatar.
Обратите внимание на метод validateEmail. Я взял его на Stack Overflow. Он проверяет валидность email адреса с помощью регулярного выражения. С помощью этого метода мы уменьшим трафик и будем посылать в Gravatar только корректные адреса почты.
public getProfilePicture(email: any) {
    if(this.validateEmail(email)) {
        this.picture = "https://www.gravatar.com/avatar/" + MD5(email) + "?s=150";
    }
}

В методе getProfilePicture мы передаём валидный email, хешированный алгоритмом MD5 в Gravatar. Если такого адреса в базе не существует, мы получим обратно картинку по-умолчанию, в противном случае нам вернётся реальная аватарка.
В этом проекте мы используем форму ввода для email адреса, но по-умолчанию к ней нет привязок в Angular. Нам необходимо подключить модуль форм, чтобы сделать привязку.
Откроем файл проекта app/app.module.ts и вставим в него следующий код:
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/platform";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
 
import { AppComponent } from "./app.component";
 
@NgModule({
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    imports: [NativeScriptModule, NativeScriptFormsModule],
    schemas: [NO_ERRORS_SCHEMA]
})
export class AppModule { }

В нём мы импортируем модуль NativeScriptFormsModule и добавляем в массив imports в блоке @NgModule.
Код не очень простой, зато хорошо работает. Ещё бы добавить немного анимации.

Включение анимационных переходов и состояний Angular

Есть несколько способов добавить анимацию в приложение NativeScript, но для лучшего контроля мы будем использовать анимации Angular. Эти анимации пропишем в нашем коде на TypeScript.
Откроем файл проекта app/app.component.ts и добавим следующий код в блок @Component:
@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
    animations: [
        trigger("state", [
            transition("void => *", [
                animate(200, style({
                    transform: 'scale(2, 2)'
                })),
            ]),
            transition("* => *", [
                animate(500, keyframes([
                    style({ transform: 'scale(2, 2)' }),
                    style({ transform: 'scale(0, 0)' }),
                    style({ transform: 'scale(2, 2)' }),
                ]))
            ]),
        ])
    ]
})

В нём мы прописываем набор анимаций, называем его state хотя состояний в нём нет, только инструкции анимационных переходов.
Если компонент — void, или, другими словами, не отображается на экране, а состояние компонента меняется, то он будет увеличен на 200% в течение 200 миллисекунд. Если состояние изменится на что-то другое, нежели void, мы увидим keyframe-анимацию. В ней элемент масштабируется с 200% до 0% и обратно до 200% в течение 500 миллимекунд. Анимация будет выглядеть как пульсация.
Чтобы изменить первоначальные состояния, нам нужно создать булеву или любую другую переменную для представления текущего состояния:
public currentState: boolean;

С помощью метода constructor мы можем инициализировать и установить эту переменную в false. А когда будет введён корректный email, мы изменим состояние и тип анимации.
Файл app/app.component.ts полностью будет таким:
import { Component, trigger, state, transition, animate, style, keyframes } from "@angular/core";
var MD5 = require("blueimp-md5");
 
@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
    animations: [
        trigger("state", [
            transition("void => *", [
                animate(200, style({
                    transform: 'scale(2, 2)'
                })),
            ]),
            transition("* => *", [
                animate(500, keyframes([
                    style({ transform: 'scale(2, 2)' }),
                    style({ transform: 'scale(0, 0)' }),
                    style({ transform: 'scale(2, 2)' }),
                ]))
            ]),
        ])
    ]
})
export class AppComponent {
 
    public picture: any;
    public email: string;
    public currentState: boolean;
 
    public constructor() {
        this.email = "";
        this.picture = "https://www.gravatar.com/avatar/00000000000000000000000000000000?s=150";
        this.currentState = false;
    }
 
    public getProfilePicture(email: any) {
        if(this.validateEmail(email)) {
            this.currentState = !this.currentState;
            this.picture = "https://www.gravatar.com/avatar/" + MD5(email) + "?s=150";
        }
    }
 
    // Taken from http://stackoverflow.com/a/46181/498479
    private validateEmail(email: any) {
        let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }
 
}

Нам остаётся создать представление на XML и CSS.

Создание приятного интерфейса в NativeScript

Основным интерфейсом будет экран с двумя секциями по вертикали. В верхней секции будет аватарка, а в нижней — форма ввода адреса.
Откроем файл app/app.component.html и вставим в него такую разметку XML:
<ActionBar title="{N} Gravatar"></ActionBar>
<GridLayout rows="*, *" columns="*">
    <Image [src]="picture" [@state]="currentState ? 'active' : 'inactive'" height="75" width="75" class="img-rounded" row="0" col="0"></Image>
    <StackLayout class="form" row="1" col="0">
        <StackLayout class="input-field">
            <Label class="label" text="Email:"></Label>
            <TextField class="input input-border" [(ngModel)]="email" (ngModelChange)="getProfilePicture($event)" autocapitalizationType="none"></TextField>
        </StackLayout>
        <StackLayout class="input-field">
            <Label class="label" text="Password:"></Label>
            <TextField class="input input-border" secure="true"></TextField>
        </StackLayout>
    </StackLayout>
</GridLayout>


GridLayout позволяет нам разделить экран на две одинаковые секции.
В первом ряду будет наше изображение в переменной picture на языке TypeScript. Чанк [@state] это состояние state анимации и содержит текущее её состояние. Как только это состояние меняется, переклчается и анимация.
Во втором ряду расположена форма с несколькими полями ввода. Первое поле привязано к нашей переменной email и как только меняется её содержимое, данные передаются в метод getProfilePicture.
Зададим свои стили для полей ввода в файле app/app.css:
.form .input-field .input {
    padding: 5;
    background-color: #F0F0F0;
}
 
@import 'nativescript-theme-core/css/core.light.css';

В этом CSS добавлен отступ и фон для всех полей ввода текста.

Готово! Мы сделали простое приложение с автоматической подгрузкой аватарки пользователя и её анимацией.

*Оригинал взят у Nic Raboy
0 комментариев
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.