metasocket-cordova/src/app/chat/chat.component.ts

163 lines
4.8 KiB
TypeScript

import {Plugins, AppState} from '@capacitor/core';
import {AfterViewChecked, AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ChatMessage} from '../chat.message';
import {Host} from '../host';
import {ApiService} from '../api.service';
import {WebsocketListener} from '../websocket.listener';
import {WebsocketService} from '../websocket.service';
import {LocalNotifications} from '@ionic-native/local-notifications/ngx';
import {BackgroundMode} from '@ionic-native/background-mode/ngx';
import {ForegroundService} from '@ionic-native/foreground-service/ngx';
const {App} = Plugins;
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss'],
})
export class ChatComponent implements OnInit, AfterViewInit, AfterViewChecked, WebsocketListener {
messages: ChatMessage[] = [];
userToken: string;
userId: number;
url: string;
@ViewChild('chatPostArea') chatPostArea: ElementRef;
chatText: string;
private oldScrollHeight = 0;
private messageOffset = 0;
private messageLimit = 10;
private hasBeenReloaded = false;
private hasFocus = true;
public constructor(
private apiService: ApiService,
private websocketService: WebsocketService,
private localNotifications: LocalNotifications,
private backgroundMode: BackgroundMode,
private foregroundService: ForegroundService
) {
this.userToken = this.apiService.getFromStorage('token');
this.userId = Number(this.apiService.getFromStorage('userId'));
this.url = Host.URL;
this.websocketService.setListener(this);
this.websocketService.initializeSocket(this.apiService.getFromStorage('chatToken'));
this.backgroundMode.disableBatteryOptimizations();
this.backgroundMode.disableWebViewOptimizations();
}
ngAfterViewInit(): void {
this.chatPostArea.nativeElement.scroll(0, this.chatPostArea.nativeElement.scrollHeight);
}
ngAfterViewChecked(): void {
if (this.oldScrollHeight !== this.chatPostArea.nativeElement.scrollHeight) {
const scrollTop = this.chatPostArea.nativeElement.scrollTop;
const clientHeight = this.chatPostArea.nativeElement.clientHeight;
if (this.hasBeenReloaded) {
this.chatPostArea.nativeElement.scroll(0, this.chatPostArea.nativeElement.scrollHeight - this.oldScrollHeight);
this.hasBeenReloaded = false;
} else if (scrollTop + clientHeight > this.oldScrollHeight - 10) {
this.chatPostArea.nativeElement.scroll(0, this.oldScrollHeight);
}
this.oldScrollHeight = this.chatPostArea.nativeElement.scrollHeight;
}
}
ngOnInit(): void {
if (this.userToken === null) {
return;
}
this.localNotifications.requestPermission();
this.foregroundService.start('METAsocket', 'The chat for WowApp', 'ic_stat_notification_icon_enabled');
this.apiService.getChatHistory(this.userToken, this.messageOffset, this.messageLimit).subscribe(
(response) => {
this.messages = response;
this.messageOffset += this.messageLimit;
}
);
App.addListener('appStateChange', (state: AppState) => {
this.hasFocus = state.isActive;
});
setInterval(
() => {
this.websocketService.sendKeepAliveMessage();
}, 1000 * 60 // every minute
);
}
onScroll(): void {
if (this.chatPostArea.nativeElement.scrollTop === 0) {
this.apiService.getChatHistory(this.userToken, this.messageOffset, this.messageLimit).subscribe(
(response) => {
this.messages = response.concat(this.messages);
this.messageOffset += this.messageLimit;
this.hasBeenReloaded = true;
}
);
}
}
onTextInput(event: Event): void {
if (!(event instanceof KeyboardEvent)) {
return;
}
switch (event.key) {
case 'Enter':
event.preventDefault();
if (this.chatText.trim() === '') {
return;
}
this.websocketService.sendChatMessage(this.chatText);
this.chatText = '';
return;
default:
return;
}
}
onChatMessage(message: ChatMessage): void {
this.messages.push(message);
this.messageOffset++;
if (message.userId === this.userId) {
return;
}
this.triggerNotification(message);
}
triggerNotification(message: ChatMessage): void
{
this.localNotifications.schedule(
{
title: message.username,
text: message.message,
id: 1,
priority: 2,
lockscreen: true,
autoClear: true,
icon: Host.URL + '/user/' + message.userId + '/avatar?token=' + this.userToken,
smallIcon: 'ic_stat_notification_icon_enabled',
led: {color: '#ff00ff', on: 500, off: 500},
trigger: { at: new Date(new Date().getTime() + 1000) },
sound: 'file://assets/audio/murloc.wav',
vibrate: true
}
);
}
}