Merge pull request #638 from NicolasConstant/topic_enhance-filters
Topic enhance filters
This commit is contained in:
commit
6a8d85f40c
|
@ -70,17 +70,29 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<app-status *ngIf="notification.status && notification.type === 'update'" class="stream__status"
|
<app-status *ngIf="notification.status && notification.type === 'update'" class="stream__status"
|
||||||
[statusWrapper]="notification.status" [notificationAccount]="notification.account"
|
[statusWrapper]="notification.status"
|
||||||
[notificationType]="notification.type" (browseAccountEvent)="browseAccount($event)"
|
[notificationAccount]="notification.account"
|
||||||
(browseHashtagEvent)="browseHashtag($event)" (browseThreadEvent)="browseThread($event)"></app-status>
|
[notificationType]="notification.type"
|
||||||
|
[context]="'notifications'"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
|
(browseThreadEvent)="browseThread($event)"></app-status>
|
||||||
|
|
||||||
<app-status *ngIf="notification.status && notification.type === 'mention'" class="stream__status"
|
<app-status *ngIf="notification.status && notification.type === 'mention'" class="stream__status"
|
||||||
[statusWrapper]="notification.status" (browseAccountEvent)="browseAccount($event)"
|
[statusWrapper]="notification.status"
|
||||||
(browseHashtagEvent)="browseHashtag($event)" (browseThreadEvent)="browseThread($event)"></app-status>
|
[context]="'notifications'"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
|
(browseThreadEvent)="browseThread($event)"></app-status>
|
||||||
|
|
||||||
<app-status *ngIf="notification.status && notification.type !== 'mention' && notification.type !== 'update'"
|
<app-status *ngIf="notification.status && notification.type !== 'mention' && notification.type !== 'update'"
|
||||||
class="stream__status" [statusWrapper]="notification.status" [notificationAccount]="notification.account"
|
class="stream__status"
|
||||||
[notificationType]="notification.type" (browseAccountEvent)="browseAccount($event)"
|
[statusWrapper]="notification.status"
|
||||||
(browseHashtagEvent)="browseHashtag($event)" (browseThreadEvent)="browseThread($event)"></app-status>
|
[notificationAccount]="notification.account"
|
||||||
|
[notificationType]="notification.type"
|
||||||
|
[context]="'notifications'"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
|
(browseThreadEvent)="browseThread($event)"></app-status>
|
||||||
|
|
||||||
</div>
|
</div>
|
|
@ -59,6 +59,8 @@ export class StatusComponent implements OnInit {
|
||||||
@Input() notificationType: 'mention' | 'reblog' | 'favourite' | 'poll' | 'update';
|
@Input() notificationType: 'mention' | 'reblog' | 'favourite' | 'poll' | 'update';
|
||||||
@Input() notificationAccount: Account;
|
@Input() notificationAccount: Account;
|
||||||
|
|
||||||
|
@Input() context: 'home' | 'notifications' | 'public' | 'thread' | 'account';
|
||||||
|
|
||||||
private _statusWrapper: StatusWrapper;
|
private _statusWrapper: StatusWrapper;
|
||||||
status: Status;
|
status: Status;
|
||||||
|
|
||||||
|
@ -98,6 +100,8 @@ export class StatusComponent implements OnInit {
|
||||||
// this.statusAccountName = this.emojiConverter.applyEmojis(this.displayedStatus.account.emojis, this.displayedStatus.account.display_name, EmojiTypeEnum.small);
|
// this.statusAccountName = this.emojiConverter.applyEmojis(this.displayedStatus.account.emojis, this.displayedStatus.account.display_name, EmojiTypeEnum.small);
|
||||||
let statusContent = this.emojiConverter.applyEmojis(this.displayedStatus.emojis, this.displayedStatus.content, EmojiTypeEnum.medium);
|
let statusContent = this.emojiConverter.applyEmojis(this.displayedStatus.emojis, this.displayedStatus.content, EmojiTypeEnum.medium);
|
||||||
this.statusContent = this.ensureMentionAreDisplayed(statusContent);
|
this.statusContent = this.ensureMentionAreDisplayed(statusContent);
|
||||||
|
|
||||||
|
this.validateFilteringStatus();
|
||||||
}
|
}
|
||||||
get statusWrapper(): StatusWrapper {
|
get statusWrapper(): StatusWrapper {
|
||||||
return this._statusWrapper;
|
return this._statusWrapper;
|
||||||
|
@ -123,6 +127,36 @@ export class StatusComponent implements OnInit {
|
||||||
if (this.statusesStateServiceSub) this.statusesStateServiceSub.unsubscribe();
|
if (this.statusesStateServiceSub) this.statusesStateServiceSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private validateFilteringStatus(){
|
||||||
|
const filterStatus = this.displayedStatus.filtered;
|
||||||
|
|
||||||
|
if(!filterStatus || filterStatus.length === 0) return;
|
||||||
|
|
||||||
|
// if(!this.context){
|
||||||
|
// console.warn('this.context not found');
|
||||||
|
// console.warn(this.context);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (let filter of filterStatus) {
|
||||||
|
if(this.context && filter.filter.context && filter.filter.context.length > 0){
|
||||||
|
if(!filter.filter.context.includes(this.context)) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filter.filter.filter_action === 'warn'){
|
||||||
|
this.isContentWarned = true;
|
||||||
|
|
||||||
|
let filterTxt = `FILTERED:`;
|
||||||
|
for(let w of filter.keyword_matches){
|
||||||
|
filterTxt += ` ${w}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contentWarningText = filterTxt;
|
||||||
|
} else if (filter.filter.filter_action === 'hide'){
|
||||||
|
this.hideStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getAvatar(acc: Account): string {
|
getAvatar(acc: Account): string {
|
||||||
if(this.freezeAvatarEnabled){
|
if(this.freezeAvatarEnabled){
|
||||||
return acc.avatar_static;
|
return acc.avatar_static;
|
||||||
|
|
|
@ -122,7 +122,7 @@ export class StreamNotificationsComponent extends BrowseBase {
|
||||||
loadNotifications(): any {
|
loadNotifications(): any {
|
||||||
this.account = this.toolsService.getAccountById(this.streamElement.accountId);
|
this.account = this.toolsService.getAccountById(this.streamElement.accountId);
|
||||||
|
|
||||||
this.mentionsSubscription = this.userNotificationService.userNotifications.subscribe((userNotifications: UserNotification[]) => {
|
this.mentionsSubscription = this.userNotificationService.userNotifications.subscribe((userNotifications: UserNotification[]) => {
|
||||||
this.loadMentions(userNotifications);
|
this.loadMentions(userNotifications);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,10 +130,13 @@ export class StreamNotificationsComponent extends BrowseBase {
|
||||||
.then((notifications: Notification[]) => {
|
.then((notifications: Notification[]) => {
|
||||||
this.isNotificationsLoading = false;
|
this.isNotificationsLoading = false;
|
||||||
|
|
||||||
this.notifications = notifications.map(x => {
|
let wrappedNotification= notifications.map(x => {
|
||||||
let cwPolicy = this.toolsService.checkContentWarning(x.status);
|
let cwPolicy = this.toolsService.checkContentWarning(x.status);
|
||||||
return new NotificationWrapper(x, this.account, cwPolicy.applyCw, cwPolicy.hide);
|
return new NotificationWrapper(x, this.account, cwPolicy.applyCw, cwPolicy.hide);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.notifications = wrappedNotification.filter(x => x.type !== 'mention' || (x.type === 'mention' && x.status.status !== null));
|
||||||
|
|
||||||
this.lastNotificationId = this.notifications[this.notifications.length - 1].notification.id;
|
this.lastNotificationId = this.notifications[this.notifications.length - 1].notification.id;
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
|
@ -17,8 +17,11 @@
|
||||||
|
|
||||||
<div class="stream-toots__status" *ngFor="let statusWrapper of statuses" #status>
|
<div class="stream-toots__status" *ngFor="let statusWrapper of statuses" #status>
|
||||||
<app-status
|
<app-status
|
||||||
[statusWrapper]="statusWrapper" [isThreadDisplay]="isThread"
|
[statusWrapper]="statusWrapper"
|
||||||
(browseAccountEvent)="browseAccount($event)" (browseHashtagEvent)="browseHashtag($event)"
|
[isThreadDisplay]="isThread"
|
||||||
|
[context]="context"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
(browseThreadEvent)="browseThread($event)"></app-status>
|
(browseThreadEvent)="browseThread($event)"></app-status>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { Store } from '@ngxs/store';
|
import { Store } from '@ngxs/store';
|
||||||
|
|
||||||
import { StreamElement } from '../../../states/streams.state';
|
import { StreamElement, StreamTypeEnum } from '../../../states/streams.state';
|
||||||
import { AccountInfo } from '../../../states/accounts.state';
|
import { AccountInfo } from '../../../states/accounts.state';
|
||||||
import { StreamingService, EventEnum, StatusUpdate } from '../../../services/streaming.service';
|
import { StreamingService, EventEnum, StatusUpdate } from '../../../services/streaming.service';
|
||||||
import { Status } from '../../../services/models/mastodon.interfaces';
|
import { Status } from '../../../services/models/mastodon.interfaces';
|
||||||
|
@ -20,9 +20,11 @@ import { SettingsService } from '../../../services/settings.service';
|
||||||
templateUrl: './stream-statuses.component.html',
|
templateUrl: './stream-statuses.component.html',
|
||||||
styleUrls: ['./stream-statuses.component.scss']
|
styleUrls: ['./stream-statuses.component.scss']
|
||||||
})
|
})
|
||||||
export class StreamStatusesComponent extends TimelineBase {
|
export class StreamStatusesComponent extends TimelineBase {
|
||||||
protected _streamElement: StreamElement;
|
protected _streamElement: StreamElement;
|
||||||
|
|
||||||
|
context: 'home' | 'notifications' | 'public' | 'thread' | 'account';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
set streamElement(streamElement: StreamElement) {
|
set streamElement(streamElement: StreamElement) {
|
||||||
this._streamElement = streamElement;
|
this._streamElement = streamElement;
|
||||||
|
@ -32,6 +34,8 @@ export class StreamStatusesComponent extends TimelineBase {
|
||||||
this.hideReplies = streamElement.hideReplies;
|
this.hideReplies = streamElement.hideReplies;
|
||||||
|
|
||||||
this.load(this._streamElement);
|
this.load(this._streamElement);
|
||||||
|
|
||||||
|
this.setContext(this._streamElement);
|
||||||
}
|
}
|
||||||
get streamElement(): StreamElement {
|
get streamElement(): StreamElement {
|
||||||
return this._streamElement;
|
return this._streamElement;
|
||||||
|
@ -112,6 +116,24 @@ export class StreamStatusesComponent extends TimelineBase {
|
||||||
if (this.deleteStatusSubscription) this.deleteStatusSubscription.unsubscribe();
|
if (this.deleteStatusSubscription) this.deleteStatusSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setContext(streamElement: StreamElement) {
|
||||||
|
switch(streamElement.type){
|
||||||
|
case StreamTypeEnum.global:
|
||||||
|
case StreamTypeEnum.local:
|
||||||
|
case StreamTypeEnum.tag:
|
||||||
|
this.context = 'public';
|
||||||
|
break;
|
||||||
|
case StreamTypeEnum.personnal:
|
||||||
|
case StreamTypeEnum.list:
|
||||||
|
this.context = 'home';
|
||||||
|
break;
|
||||||
|
case StreamTypeEnum.activity:
|
||||||
|
case StreamTypeEnum.directmessages:
|
||||||
|
this.context = 'notifications';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
refresh(): any {
|
refresh(): any {
|
||||||
this.load(this._streamElement);
|
this.load(this._streamElement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ export class ThreadComponent extends BrowseBase {
|
||||||
hasContentWarnings = false;
|
hasContentWarnings = false;
|
||||||
private remoteStatusFetchingDisabled = false;
|
private remoteStatusFetchingDisabled = false;
|
||||||
|
|
||||||
|
context = 'thread';
|
||||||
|
|
||||||
numNewItems: number; //html compatibility only
|
numNewItems: number; //html compatibility only
|
||||||
bufferStream: Status[] = []; //html compatibility only
|
bufferStream: Status[] = []; //html compatibility only
|
||||||
streamPositionnedAtTop: boolean = true; //html compatibility only
|
streamPositionnedAtTop: boolean = true; //html compatibility only
|
||||||
|
|
|
@ -196,16 +196,24 @@
|
||||||
|
|
||||||
<div *ngIf="statusSection === 'status' && !statusLoading">
|
<div *ngIf="statusSection === 'status' && !statusLoading">
|
||||||
<div *ngFor="let statusWrapper of pinnedStatuses">
|
<div *ngFor="let statusWrapper of pinnedStatuses">
|
||||||
<app-status [statusWrapper]="statusWrapper" (browseHashtagEvent)="browseHashtag($event)"
|
<app-status
|
||||||
(browseAccountEvent)="browseAccount($event)" (browseThreadEvent)="browseThread($event)">
|
[statusWrapper]="statusWrapper"
|
||||||
|
[context]="'account'"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseThreadEvent)="browseThread($event)">
|
||||||
</app-status>
|
</app-status>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let statusWrapper of statuses">
|
<div *ngFor="let statusWrapper of statuses">
|
||||||
<div *ngIf="statusSection !== 'media'">
|
<div *ngIf="statusSection !== 'media'">
|
||||||
<app-status [statusWrapper]="statusWrapper" (browseHashtagEvent)="browseHashtag($event)"
|
<app-status
|
||||||
(browseAccountEvent)="browseAccount($event)" (browseThreadEvent)="browseThread($event)">
|
[statusWrapper]="statusWrapper"
|
||||||
|
[context]="'account'"
|
||||||
|
(browseHashtagEvent)="browseHashtag($event)"
|
||||||
|
(browseAccountEvent)="browseAccount($event)"
|
||||||
|
(browseThreadEvent)="browseThread($event)">
|
||||||
</app-status>
|
</app-status>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="statusSection === 'media'" class="status-media">
|
<div *ngIf="statusSection === 'media'" class="status-media">
|
||||||
|
|
|
@ -194,6 +194,33 @@ export interface Results {
|
||||||
hashtags: string[];
|
hashtags: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FilterKeyword {
|
||||||
|
id: string;
|
||||||
|
keyword: string;
|
||||||
|
whole_word: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterStatus {
|
||||||
|
id: string;
|
||||||
|
status_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Filter {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
context: string[]; //home notifications public thread account
|
||||||
|
expires_at: string;
|
||||||
|
filter_action: string; //warn hide
|
||||||
|
keywords: FilterKeyword[];
|
||||||
|
statuses: FilterStatus[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterResult {
|
||||||
|
filter: Filter;
|
||||||
|
keyword_matches: string[];
|
||||||
|
status_matches: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Status {
|
export interface Status {
|
||||||
id: string;
|
id: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
|
@ -224,6 +251,7 @@ export interface Status {
|
||||||
bookmarked: boolean;
|
bookmarked: boolean;
|
||||||
card: Card;
|
card: Card;
|
||||||
poll: Poll;
|
poll: Poll;
|
||||||
|
filtered: FilterResult[];
|
||||||
|
|
||||||
pleroma: PleromaStatusInfo;
|
pleroma: PleromaStatusInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ export class UserNotificationService {
|
||||||
private startFetchingNotifications(account: AccountInfo) {
|
private startFetchingNotifications(account: AccountInfo) {
|
||||||
let getMentionsPromise = this.mastodonService.getNotifications(account, ['favourite', 'follow', 'reblog', 'poll', 'follow_request', 'move', 'update'], null, null, 10)
|
let getMentionsPromise = this.mastodonService.getNotifications(account, ['favourite', 'follow', 'reblog', 'poll', 'follow_request', 'move', 'update'], null, null, 10)
|
||||||
.then((notifications: Notification[]) => {
|
.then((notifications: Notification[]) => {
|
||||||
|
notifications = notifications.filter(x => x.status !== null);
|
||||||
|
|
||||||
this.processMentionsAndNotifications(account, notifications, NotificationTypeEnum.UserMention);
|
this.processMentionsAndNotifications(account, notifications, NotificationTypeEnum.UserMention);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
Loading…
Reference in New Issue