Sengi-Windows-MacOS-Linux/src/app/components/floating-column/manage-account/notifications/notifications.component.ts

172 lines
6.5 KiB
TypeScript
Raw Normal View History

2020-06-14 09:07:44 +02:00
import { Component, Input, ViewChild, ElementRef } from '@angular/core';
import { Subscription } from 'rxjs';
2019-03-25 05:52:30 +01:00
import { AccountWrapper } from '../../../../models/account.models';
import { UserNotificationService, UserNotification } from '../../../../services/user-notification.service';
import { StatusWrapper } from '../../../../models/common.model';
import { Notification, Account } from '../../../../services/models/mastodon.interfaces';
import { MastodonWrapperService } from '../../../../services/mastodon-wrapper.service';
import { NotificationService } from '../../../../services/notification.service';
import { AccountInfo } from '../../../../states/accounts.state';
2020-06-14 09:07:44 +02:00
import { ToolsService } from '../../../../services/tools.service';
import { BrowseBase } from '../../../../components/common/browse-base';
@Component({
2019-03-25 05:52:30 +01:00
selector: 'app-notifications',
templateUrl: './notifications.component.html',
styleUrls: ['./notifications.component.scss']
})
2020-06-14 09:07:44 +02:00
export class NotificationsComponent extends BrowseBase {
notifications: NotificationWrapper[] = [];
2020-05-29 09:38:38 +02:00
private isProcessingInfiniteScroll: boolean;
isLoading = false;
2019-03-25 05:52:30 +01:00
@Input('account')
set account(acc: AccountWrapper) {
this._account = acc;
this.loadNotifications();
2019-03-25 05:52:30 +01:00
}
get account(): AccountWrapper {
return this._account;
}
@ViewChild('statusstream') public statustream: ElementRef;
2019-03-25 05:52:30 +01:00
private maxReached = false;
2019-03-25 05:52:30 +01:00
private _account: AccountWrapper;
private userNotificationServiceSub: Subscription;
private lastId: string;
2019-03-25 05:52:30 +01:00
constructor(
2020-04-01 08:29:51 +02:00
private readonly toolsService: ToolsService,
private readonly notificationService: NotificationService,
private readonly userNotificationService: UserNotificationService,
2020-06-14 09:07:44 +02:00
private readonly mastodonService: MastodonWrapperService) {
super();
}
2019-03-25 05:52:30 +01:00
ngOnInit() {
}
ngOnDestroy(): void {
if (this.userNotificationServiceSub) {
this.userNotificationServiceSub.unsubscribe();
}
}
private loadNotifications() {
if (this.userNotificationServiceSub) {
this.userNotificationServiceSub.unsubscribe();
}
this.notifications.length = 0;
this.userNotificationService.markNotificationAsRead(this.account.info);
this.userNotificationServiceSub = this.userNotificationService.userNotifications.subscribe((userNotifications: UserNotification[]) => {
this.processNewNotifications(userNotifications);
if (this.notifications.length < 20) this.scrolledToBottom();
});
}
private processNewNotifications(userNotifications: UserNotification[]) {
const userNotification = userNotifications.find(x => x.account.id === this.account.info.id);
if (userNotification && userNotification.notifications) {
let orderedNotifications = [...userNotification.notifications].reverse();
for (let n of orderedNotifications) {
2020-04-01 08:29:51 +02:00
let cwPolicy = this.toolsService.checkContentWarning(n.status);
const notificationWrapper = new NotificationWrapper(n, this.account.info, cwPolicy.applyCw, cwPolicy.hide);
if (!this.notifications.find(x => x.wrapperId === notificationWrapper.wrapperId)) {
this.notifications.unshift(notificationWrapper);
}
}
}
this.lastId = userNotification.lastNotificationsId;
this.userNotificationService.markNotificationAsRead(this.account.info);
}
2019-03-28 04:34:29 +01:00
onScroll() {
var element = this.statustream.nativeElement as HTMLElement;
const atBottom = element.scrollHeight <= element.clientHeight + element.scrollTop + 1000;
2020-05-29 09:38:38 +02:00
if (atBottom && !this.isProcessingInfiniteScroll) {
2019-03-28 04:34:29 +01:00
this.scrolledToBottom();
}
}
2020-06-14 09:48:30 +02:00
private scrolledErrorOccured = false;
2019-03-28 04:34:29 +01:00
private scrolledToBottom() {
2020-06-14 09:48:30 +02:00
if (this.isLoading || this.maxReached || this.notifications.length === 0 || this.scrolledErrorOccured) return;
2019-03-28 04:34:29 +01:00
this.isLoading = true;
2020-05-29 09:38:38 +02:00
this.isProcessingInfiniteScroll = true;
2019-03-28 04:34:29 +01:00
this.mastodonService.getNotifications(this.account.info, ['mention', 'update'], this.lastId)
2019-03-28 04:34:29 +01:00
.then((notifications: Notification[]) => {
if (notifications.length === 0) {
this.maxReached = true;
return;
}
2019-03-28 04:34:29 +01:00
for (const s of notifications) {
2020-04-01 08:29:51 +02:00
let cwPolicy = this.toolsService.checkContentWarning(s.status);
const wrapper = new NotificationWrapper(s, this.account.info, cwPolicy.applyCw, cwPolicy.hide);
if (!this.notifications.find(x => x.wrapperId === wrapper.wrapperId)) {
this.notifications.push(wrapper);
}
2019-03-28 04:34:29 +01:00
}
this.lastId = notifications[notifications.length - 1].id;
})
.catch(err => {
2020-06-14 09:48:30 +02:00
this.scrolledErrorOccured = true;
setTimeout(() => {
this.scrolledErrorOccured = false;
}, 5000);
2019-09-07 23:52:07 +02:00
this.notificationService.notifyHttpError(err, this.account.info);
2019-03-28 04:34:29 +01:00
})
.then(() => {
this.isLoading = false;
2020-05-29 09:38:38 +02:00
this.isProcessingInfiniteScroll = false;
2019-03-28 04:34:29 +01:00
});
}
2019-07-06 07:28:30 +02:00
2020-04-30 08:12:01 +02:00
applyGoToTop(): boolean {
const stream = this.statustream.nativeElement as HTMLElement;
setTimeout(() => {
stream.scrollTo({
top: 0,
behavior: 'smooth'
});
}, 0);
return false;
}
}
2019-11-19 05:54:11 +01:00
export class NotificationWrapper {
constructor(notification: Notification, provider: AccountInfo, applyCw: boolean, hideStatus: boolean) {
this.type = notification.type;
switch (this.type) {
case 'mention':
case 'reblog':
case 'favourite':
case 'poll':
this.status = new StatusWrapper(notification.status, provider, applyCw, hideStatus);
break;
}
this.account = notification.account;
2020-12-22 05:12:47 +01:00
this.target = notification.target;
this.wrapperId = `${this.type}-${notification.id}`;
2019-11-21 04:40:23 +01:00
this.notification = notification;
2020-10-03 06:40:43 +02:00
this.provider = provider;
}
2020-10-03 06:40:43 +02:00
provider: AccountInfo;
2019-11-21 04:40:23 +01:00
notification: Notification;
wrapperId: string;
account: Account;
2020-12-22 05:12:47 +01:00
target: Account;
status: StatusWrapper;
type: 'mention' | 'reblog' | 'favourite' | 'follow' | 'poll' | 'follow_request' | 'move' | 'update';
}