Этот урок покажет вам, как вы можете реализовать чат-продавец покупателей для онлайн-маршрутов, а также пользователя в чате пользователя, благодаря использованию TalkJS в любом приложении Angular 6. Мы покажем вам, как внедрить TalkJS в уже существующее приложение, чтобы дать больше контекста реализации. Мы будем подробнее поговорить об этом существующем приложении дальше на протяжении всего этого урока.
Это первая часть учебника из двух частей. В этой части мы посмотрим, как мы можем добавить всплывающее окно в чате в существующее приложение. В следующей части мы узнаем, как добавить в приложение в ящик чат и почтовый ящик.
Перво -на первый взгляд
Предварительные условия
Угловая версия Код в этом уроке был написан в Angular CLI версии 6.1.5. Обязательно следуйте этому учебному пособию с Angular CLI V6.1.5 или выше.
Nodejs версия Убедитесь, что вы работаете с Nodejs v8.11.4 или выше.
Рынок
Наш рынок – это приложение, которое реализует упрощенный случай использования рынка. На этом рынке пользователи могут войти в систему и просматривать списки продуктов:
Перед реализацией этого учебника:
После реализации этого учебника:
Нажмите на изображение, чтобы открыть пример приложения в прямом эфире.
Этот учебник предназначен для демонстрации того, как добавить функциональность чата в любое приложение Angular 6, с помощью TalkJS. Вы можете выполнить шаги в этом уроке на нашем примере рынка, но вы также должны быть в состоянии сразу же сделать их в своем собственном угловом приложении.
Исходный код для обоих рыночных приложений можно найти в нашем GitHub Repo Анкет
Функциональные возможности чата будут добавлены на следующие страницы на нашем рынке: профиль пользователя, страница продукта и входящая страница.
Запуск приложения Начните приложение, в которое вы собираетесь добавить функциональные возможности чата.
Если вы добавляете функции чата в наше приложение на рынке, вы можете клонировать проект из его GitHub Repository Анкет
Начните приложение:
npm install npm start
Если рынок начался успешно, перейдите к http://localhost: 4200/ в вашем браузере, чтобы увидеть приложение.
Давайте начнем
Установите Talkjs JavaScript SDK
Самое первое, что мы должны сделать, это установить TalkJS JavaScript SDK в наш проект:
npm install talkjs --save
Создайте обратный сервис
Чтобы поддерживать модульность в нашем приложении, вся логика TalkJS должна быть выполнена в отдельной службе.
Создайте файл в SRC/App/Core/Services
называется talk.service.ts
и заполните его следующим кодом:
import { Injectable } from "@angular/core"; import * as Talk from 'talkjs'; @Injectable({ providedIn: 'root' }) export class TalkService { }
Чтобы гарантировать, что наше выступление работает в качестве экземпляра Singleton на протяжении всего нашего приложения, мы предоставляем его в корне нашего приложения. Обязательно не добавляйте эту услугу в список поставщиков для любого модуля, так как это приведет к тому, что наш сервис больше не будет работать как один экземпляр Синглтона. Вы можете прочитать больше о Singleton Services здесь.
Активная сессия
Первое, что вы должны сделать для TalkJS, чтобы правильно работать в вашем приложении, – это запустить Сессия Для текущего зарегистрированного пользователя. Пока у вас работает активное занятие, ваш пользователь сможет получать уведомления настольных компьютеров. Поэтому мы убедимся, что сеанс работает на каждой странице нашего приложения, даже на тех, на которых наш пользователь не может читать или записывать сообщения. Вы можете прочитать больше о сессии TalkJS Здесь Анкет
Аутентификация
Всякий раз, когда пользователь входит в нашу приложение, мы должны убедиться, что мы создаем сеанс для этого пользователя.
Перейдите к LoginComponent: src/app/core/outentication/components/login/login.component.ts
После того, как наш пользователь успешно вошел в систему, мы должны начать сеанс. Нам придется позвонить в TalkService#CreateCurrentSession
Метод – который мы создадим всего за мгновение – в нашей функции входа в систему.
Чтобы мы могли быть в состоянии вызвать функцию в сфере службы, мы должны сначала ввести экземпляр Singleton TalkService в наш LoginComponent с использованием инъекции зависимостей.
Мы передаем его как параметр в конструктор нашего входа в систему:
constructor(..., private talkService: TalkService)
Обязательно импортируйте переговорную службу в вход в систему:
import { TalkService } from 'src/app/core/services/talk.service';
Позвоните в TalkService#CreateCurrentSession
Метод в методе входа в систему:
login(credentials) { this.authenticationService.login(credentials.username).then(response => { if (response) { this.toastrService.success('Successful login'); this.router.navigate(['home']); this.talkService.createCurrentSession(); } else { this.toastrService.error('Incorrect credentials'); } }); }
Методы общения
Приложение идентификатор Чтобы TalkJS работал в рамках вашего приложения, ваше приложение должно иметь идентификатор приложения, который вы можете найти на панели TalkJS.
Создайте учетную запись – бесплатно, находясь в тестовой среде – в Talkjs Анкет
Затем перейдите к Talkjs Dashboard И ищите свой идентификатор приложения.
Сохраните идентификатор приложения как частную константу в сфере службы:
private static APP_ID = 'YOUR_APP_ID';
Текущий пользователь Для того, чтобы выступление на сессии создала сеанс, он должен знать текущего пользователя приложения. Наша аутентификация содержит метод для извлечения текущего пользователя.
Введите аутентификацию в сфере службы:
constructor(private authenticationService: AuthenticationService)
Talkjs User Нам понадобится экземпляр класса пользователя TalkJS для создания сеанса. Создайте метод, который преобразует экземпляр класса пользователя нашего приложения в экземпляр класса пользователя TalkJS:
private currentTalkUser: Talk.User; async createTalkUser(applicationUser: User) : Promise { await Talk.ready; return new Talk.User({ id: applicationUser.id, name: applicationUser.username, photoUrl: applicationUser.profilePictureUrl }); }
SDK Talkjs загружен асинхронно. Работая и с асинхронными методами, мы следим за тем, чтобы весь код, связанный с TalkJS, не блокирует в нашем приложении и что мы следуем стандартам ввода/вывода (методы ввода/вывода асинхронны).
Сначала мы ждем загрузки SDK Talkjs, что мы делаем, позвонив:
await Talk.ready
Затем мы создаем новый экземпляр класса пользователя, заполняя его данными нашего текущего пользователя.
Создание сессии Добавьте следующий метод для создания фактического сеанса:
async createCurrentSession() { await Talk.ready; const currentUser = await this.authenticationService.getCurrentUser(); const currentTalkUser = await this.createTalkUser(currentUser); const session = new Talk.Session({ appId: TalkService.APP_ID, me: currentTalkUser }); this.currentTalkUser = currentTalkUser; this.currentSessionDeferred.resolve(session); }
Я объясню, что здесь происходит, шаг за шагом.
Как видите, этот метод также является асинхронным методом. Нам нужно подождать, пока мы будем готовы к тому, чтобы мы сможем создать сеанс.
Затем мы должны убедиться, что конвертируйте текущий экземпляр пользователя нашего приложения в экземпляр пользователя TalkJS, сначала извлеките текущего пользователя нашего приложения, а затем преобразовав его:
const currentUser = await this.authenticationService.getCurrentUser(); const currentTalkUser = await this.createTalkUser(currentUser);
После получения и преобразования нашего текущего пользователя мы создаем фактический сеанс:
const session = new Talk.Session({ appId: TalkService.APP_ID, me: currentTalkUser });
Поиск сессии Всякий раз, когда наш пользователь уже входит в нашу приложение и посещает компонент, который должен использовать наш сеанс, существует вероятность того, что наш сеанс все еще создается, в то время как компонент уже пытается использовать сеанс. Это может вызвать всевозможные проблемы, поэтому мы собираемся исправить это, убедившись, что приложение сможет ждать активного сеанса.
Чего мы хотим достичь, так это то, что мы можем вызвать код аналогичным:
await currentSession;
Без необходимости опросить на точке, пока она не станет активной. Это означает, что нам нужно создать обещание под названием тока
Это решается, когда сеанс загружен.
Общим способом создания обещания является использование отложенного, которое является небольшим объектом, который позволяет вам вернуть обещание и разрешить его позже. Пример кода включает в себя помощник класса для этого Анкет
Мы создадим его при строительстве:
private currentSessionDeferred = new Deferred();
Когда мы создадим сеанс, мы решим CurrentSessionDeferred
со значением сеанса:
this.currentSessionDeferred.resolve(session);
Затем мы можем дождаться текущего сеанса где -нибудь еще в Сервис
:
await this.currentSessionDeferred.promise;
Ок, отлично! Ваше разговорное обслуживание должно выглядеть как:
import { Injectable } from "@angular/core"; import * as Talk from 'talkjs'; import { User } from "src/app/shared/models/user.model"; import { AuthenticationService } from "src/app/core/services/authentication.service"; import { Deferred } from "src/app/shared/utils/deffered.util"; @Injectable({ providedIn: 'root' }) export class TalkService { private static APP_ID = 'YOUR_APP_ID'; private currentTalkUser: Talk.User; private currentSessionDeferred = new Deferred() constructor(private authenticationService: AuthenticationService) { } async createCurrentSession() { await Talk.ready; const currentUser = await this.authenticationService.getCurrentUser(); const currentTalkUser = await this.createTalkUser(currentUser); const session = new Talk.Session({ appId: TalkService.APP_ID, me: currentTalkUser }); this.currentTalkUser = currentTalkUser; this.currentSessionDeferred.resolve(session); } async createTalkUser(applicationUser: User) : Promise { await Talk.ready; return new Talk.User({ id: applicationUser.id, name: applicationUser.username, photoUrl: applicationUser.profilePictureUrl }); } }
Основной модуль Есть еще один шаг, который мы должны сделать, чтобы закончить этот раздел.
Coremodule – это сердце нашего применения. Это первый модуль, который загружается приложением после AppModule. Архитектура нашего приложения была разработана таким образом, что все другие модули, но Coremodule и Appmodule, лениво загружаются – они загружаются только в любом случае.
Нам также необходимо рассмотреть сценарий, в котором пользователь уже вошел в систему при загрузке приложения. На данный момент наше приложение запускает только сеанс, когда наш пользователь входит в систему. Это означает, что при вышеупомянутом сценарии наш пользователь вошел в систему, пока не работает активное сеанс. Как вы знаете, важно, чтобы всегда проводился активный сеанс, когда наш пользователь входит в систему. Поэтому мы должны убедиться, что сеанс будет создан для уже зарегистрированного пользователя в этом сценарии. Мы можем сделать это, убедившись, что если Coremodule начнется, сеанс также будет создан.
Перейдите в Coremodule в src/app/core/core.module.ts
и добавьте следующую выделенную линию:
constructor ( @Optional() @SkipSelf() parentModule: CoreModule, private productService: ProductService, private talkService: TalkService) { if (parentModule) { throw new Error('CoreModule is already loaded. Import only in AppModule'); } this.talkService.createCurrentSession(); }
Убедитесь, что также внедрите сервис в Coremodule.
Чат всплывающее окно
В этом разделе мы убедитесь, что наш пользователь сможет открыть чат с поставщиком продукта, используя всплывающее окно чата.
Вот как выглядит всплывающее окно в чате:
Предварительная загрузка
Перейдите на страницу продукта мотоцикла.
Первое, что мы должны сделать, это убедиться, что чат между нашим пользователем и поставщиком продукта был готов до того, как наш пользователь фактически попытается открыть этот чат.
Мы собираемся сделать это, предварительно загрузив чат всякий раз, когда загружается страница продукта.
Сервис Добавьте следующий метод в TalkService:
async createPopup(otherApplicationUser: User, keepOpen: boolean) : Promise { const session = await this.currentSessionDeferred.promise; const conversationBuilder = await this.getOrCreateConversation(session, otherApplicationUser); const popup = session.createPopup(conversationBuilder, { keepOpen: keepOpen }); return popup; }
Что делает этот метод, так это получение токи и создать Talkjs CongrangeBuilder экземпляр, позвонив в метод TalkService#getorCreateConversation, который мы собираемся добавить в мгновение ока.
У сеанса есть метод, который создает и возвращает всплывающий экземпляр Talkjs. Мы называем этот метод и возвращаем его созданный всплывающий экземпляр. Внутренняя всплывающая чиновник определяет, должно ли всплывающее окно оставаться открытым, если пользователь перейдет на другую страницу в вашем приложении. Вы можете прочитать больше об этом здесь.
Добавьте отсутствующее TalkService#getorCreateConversation
Метод:
private async getOrCreateConversation(session: Talk.Session, otherApplicationUser: User) { const otherTalkUser = await this.createTalkUser(otherApplicationUser); const conversationBuilder = session.getOrCreateConversation(Talk.oneOnOneId(this.currentTalkUser, otherTalkUser)); conversationBuilder.setParticipant(this.currentTalkUser); conversationBuilder.setParticipant(otherTalkUser); return conversationBuilder; }
Сессия#getorcreateConversation
Метод требует разговора. У TalkJs есть функция под названием Talk#Oneononeid
который генерирует идентификатор между двумя экземплярами пользователей TalkJS, который всегда будет одинаковым для двух данных пользователей, независимо от того, в каком порядке вы передаете пользователей в качестве его параметров. Вы можете прочитать больше о функции здесь.
Мы используем Talk#Oneononeid
Метод для создания необходимого разговора.
Компонент страницы продукта Перейдите к ProductPageComponent: src/app/products/components/product-page/product-page.component.ts
Сначала мы должны добавить локальную переменную для всплывающего окна, которую мы собираемся на предварительную нагрузку и отображение. Добавлять:
private chatPopup: Talk.Popup;
Обязательно импортируйте TalkJS SDK и введите нашу службу в этот компонент.
Добавьте метод предварительной загрузки:
private async preloadChatPopup(vendor: User) { this.chatPopup = await this.talkService.createPopup(vendor, false); this.chatPopup.mount({ show: false }); }
Этот метод асинхронно ждет создания всплывающего окна, чтобы затем назначить его локальной переменной и вызвать всплывающее окно#Маунт
Метод на созданном всплывающем окне. всплывающее окно#Маунт
Метод вызывается, поскольку свойство шоу является ложным, что означает, что всплывающее окно монтируется – это необходимо, чтобы иметь возможность показать всплывающее окно позже – но не показано впоследствии.
Вызовите метод предварительной загрузки в крючке жизни Ngoninit Lifecycle:
ngOnInit() { this.productService.getProduct(this.getProductId()).then(product => { this.product = product; this.preloadChatPopup(product.vendor); }); }
Отображение
Создайте кнопку, которая при нажатии вызывает метод ProductPageComponent#ShowChatPopup. Вы можете посмотреть, как мы добавили кнопку в конечном источнике приложения Marketplace.
Добавьте метод дисплея в наш ProductPageComponent:
showChatPopup() { this.chatPopup.show(); }
Теперь мы успешно добавили всплывающее окно TalkJS в нашу приложение.
Если вы успешно выполнили все шаги, ваш разговорной службу, шаблон ProductPageComponent и ProductPageComponent должен выглядеть как:
Сервис
import { Injectable } from "@angular/core"; import * as Talk from 'talkjs'; import { User } from "src/app/shared/models/user.model"; import { AuthenticationService } from "src/app/core/services/authentication.service"; import { Deferred } from "src/app/shared/utils/deffered.util"; @Injectable({ providedIn: 'root' }) export class TalkService { private static APP_ID = 'YOUR_APP_ID'; private currentTalkUser: Talk.User; private currentSessionDeferred = new Deferred() constructor(private authenticationService: AuthenticationService) { } async createCurrentSession() { await Talk.ready; const currentUser = await this.authenticationService.getCurrentUser(); const currentTalkUser = await this.createTalkUser(currentUser); const session = new Talk.Session({ appId: TalkService.APP_ID, me: currentTalkUser }); this.currentTalkUser = currentTalkUser; this.currentSessionDeferred.resolve(session); } async createTalkUser(applicationUser: User) : Promise { await Talk.ready; return new Talk.User({ id: applicationUser.id, name: applicationUser.username, photoUrl: applicationUser.profilePictureUrl }); } async createPopup(otherApplicationUser: User, keepOpen: boolean) : Promise { const session = await this.currentSessionDeferred.promise; const conversationBuilder = await this.getOrCreateConversation(session, otherApplicationUser); const popup = session.createPopup(conversationBuilder, { keepOpen: keepOpen }); return popup; } private async getOrCreateConversation(session: Talk.Session, otherApplicationUser: User) { const otherTalkUser = await this.createTalkUser(otherApplicationUser); const conversationBuilder = session.getOrCreateConversation(Talk.oneOnOneId(this.currentTalkUser, otherTalkUser)); conversationBuilder.setParticipant(this.currentTalkUser); conversationBuilder.setParticipant(otherTalkUser); return conversationBuilder; } }
ProductPageComponent:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import * as Talk from 'talkjs'; import { Product } from 'src/app/shared/models/product.model'; import { ProductService } from 'src/app/core/services/product.service'; import { User } from 'src/app/shared/models/user.model'; import { TalkService } from 'src/app/core/services/talk.service'; @Component({ selector: 'app-product-page', templateUrl: './product-page.component.html', styleUrls: ['./product-page.component.css'] }) export class ProductPageComponent implements OnInit { product: Product; private chatPopup: Talk.Popup; constructor( private productService: ProductService, private talkService: TalkService, private route: ActivatedRoute, private router: Router) { } ngOnInit() { this.productService.getProduct(this.getProductId()).then(product => { this.product = product; this.preloadChatPopup(product.vendor); }); } goToVendorPage(vendor: User) { this.router.navigate(['users/' + vendor.id]); } showChatPopup() { this.chatPopup.show(); } private async preloadChatPopup(vendor: User) { this.chatPopup = await this.talkService.createPopup(vendor, false); this.chatPopup.mount({ show: false }); } private getProductId() { return Number(this.route.snapshot.paramMap.get('id')); } }
До сих пор мы узнали, как мы можем добавить всплывающее окно в чате в приложение для углового рынка. В следующей части этого учебника мы узнаем, как добавить в приложение для чата и почтового ящика.
Оригинал: “https://dev.to/talkjs/add-buyer-seller-chat-into-a-marketplace-with-angular-6-part-1-4ij4”