Merge pull request #257 from NicolasConstant/fix_infinity-scroll-spam
Fix infinity scroll spam
This commit is contained in:
commit
9c53010ae8
|
@ -91,6 +91,10 @@ export class SearchComponent implements OnInit {
|
|||
this.accounts = results.accounts.slice(0, 5);
|
||||
this.hashtags = results.hashtags;
|
||||
|
||||
if(!this.hashtags.map(x => x.toLowerCase()).includes(data.toLowerCase())){
|
||||
this.hashtags.unshift(data);
|
||||
}
|
||||
|
||||
for (let status of results.statuses) {
|
||||
let cwPolicy = this.toolsService.checkContentWarning(status);
|
||||
const statusWrapper = new StatusWrapper(cwPolicy.status, this.lastAccountUsed, cwPolicy.applyCw, cwPolicy.hide);
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DatabindedTextComponent } from './databinded-text.component';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { isGeneratedFile } from '@angular/compiler/src/aot/util';
|
||||
import { tick } from '@angular/core/src/render3';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
|
||||
describe('DatabindedTextComponent', () => {
|
||||
let component: DatabindedTextComponent;
|
||||
|
@ -11,7 +9,8 @@ describe('DatabindedTextComponent', () => {
|
|||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DatabindedTextComponent]
|
||||
declarations: [DatabindedTextComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -42,6 +41,14 @@ describe('DatabindedTextComponent', () => {
|
|||
expect(component.processedText).toContain('bla2');
|
||||
});
|
||||
|
||||
it('should parse hashtag - Pleroma 2.0.2', () => {
|
||||
const sample = `Blabla <a class="hashtag" data-tag="covid19" href="https://url.com/tag/covid19">#covid19</a> Blibli`;
|
||||
component.text = sample;
|
||||
expect(component.processedText).toContain('<a href class="hashtag-covid19" title="#covid19">#covid19</a>');
|
||||
expect(component.processedText).toContain('Blabla');
|
||||
expect(component.processedText).toContain('Blibli');
|
||||
});
|
||||
|
||||
it('should parse mention', () => {
|
||||
const mention = 'sengi_app';
|
||||
const url = 'https://mastodon.social/@sengi_app';
|
||||
|
|
|
@ -28,11 +28,11 @@ export class DatabindedTextComponent implements OnInit {
|
|||
|
||||
@Input('text')
|
||||
set text(value: string) {
|
||||
//console.warn(value);
|
||||
|
||||
let parser = new DOMParser();
|
||||
var dom = parser.parseFromString(value, 'text/html')
|
||||
this.isCollapsed = [...dom.body.textContent].length > 500;
|
||||
//console.warn(this.isCollapsed);
|
||||
|
||||
this.processedText = '';
|
||||
|
||||
|
@ -52,7 +52,7 @@ export class DatabindedTextComponent implements OnInit {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (section.includes('class="mention hashtag"') || section.includes('target="_blank">#') || section.includes('rel="tag">')) {
|
||||
if (section.includes('class="mention hashtag"') || section.includes('class="hashtag"') || section.includes('target="_blank">#') || section.includes('rel="tag">')) {
|
||||
try {
|
||||
this.processHashtag(section);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { StatusWrapper } from '../../../models/common.model';
|
|||
})
|
||||
export class StreamStatusesComponent implements OnInit, OnDestroy {
|
||||
isLoading = true;
|
||||
private lastInfinityFetchReturnedNothing = false;
|
||||
isThread = false;
|
||||
displayError: string;
|
||||
hasContentWarnings = false;
|
||||
|
@ -255,7 +256,7 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
private scrolledToBottom() {
|
||||
if (this.isLoading) return;
|
||||
if (this.isLoading || this.lastInfinityFetchReturnedNothing) return;
|
||||
|
||||
this.isLoading = true;
|
||||
this.isProcessingInfiniteScroll = true;
|
||||
|
@ -272,6 +273,10 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
|
|||
const wrapper = new StatusWrapper(cwPolicy.status, this.account, cwPolicy.applyCw, cwPolicy.hide);
|
||||
this.statuses.push(wrapper);
|
||||
}
|
||||
|
||||
if(!status || status.length === 0){
|
||||
this.lastInfinityFetchReturnedNothing = true;
|
||||
}
|
||||
})
|
||||
.catch((err: HttpErrorResponse) => {
|
||||
this.notificationService.notifyHttpError(err, this.account);
|
||||
|
@ -318,6 +323,7 @@ export class StreamStatusesComponent implements OnInit, OnDestroy {
|
|||
private checkAndCleanUpStream(): void {
|
||||
if (this.streamPositionnedAtTop && this.statuses.length > 3 * this.streamingService.nbStatusPerIteration) {
|
||||
this.statuses.length = 2 * this.streamingService.nbStatusPerIteration;
|
||||
this.lastInfinityFetchReturnedNothing = false;
|
||||
}
|
||||
|
||||
if (this.bufferStream.length > 3 * this.streamingService.nbStatusPerIteration) {
|
||||
|
|
|
@ -133,10 +133,9 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
const sourceAccount = openThreadEvent.sourceAccount;
|
||||
|
||||
if (status.visibility === 'public' || status.visibility === 'unlisted') {
|
||||
var statusPromise: Promise<Status> = Promise.resolve(status);
|
||||
|
||||
if (!sourceAccount || sourceAccount.id !== currentAccount.id) {
|
||||
statusPromise = this.toolsService.getInstanceInfo(currentAccount)
|
||||
// var statusPromise: Promise<Status> = Promise.resolve(status);
|
||||
// if (!sourceAccount || sourceAccount.id !== currentAccount.id) {
|
||||
var statusPromise = this.toolsService.getInstanceInfo(currentAccount)
|
||||
.then(instance => {
|
||||
let version: 'v1' | 'v2' = 'v1';
|
||||
if (instance.major >= 3) version = 'v2';
|
||||
|
@ -149,7 +148,7 @@ export class ThreadComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
throw new Error('could not find status');
|
||||
});
|
||||
}
|
||||
// }
|
||||
|
||||
this.retrieveThread(currentAccount, statusPromise);
|
||||
|
||||
|
|
|
@ -215,9 +215,7 @@
|
|||
</div>
|
||||
<div *ngIf="statusSection === 'media'" class="status-media">
|
||||
<div *ngFor="let media of statusWrapper.status.media_attachments">
|
||||
<a href title="open" (click)="openAttachment(media)">
|
||||
<img class="status-media__image" src="{{media.preview_url}}" />
|
||||
</a>
|
||||
<app-attachement-image *ngIf="media.type === 'image' || media.type === 'gifv'" class="status-media__image" [attachment]="media" (openEvent)="openAttachment(media)"></app-attachement-image>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { faUser, faHourglassHalf, faUserCheck, faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faUser, faHourglassHalf, faUserCheck, faExclamationTriangle, faLink } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faUser as faUserRegular } from "@fortawesome/free-regular-svg-icons";
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Store } from '@ngxs/store';
|
||||
|
@ -27,6 +27,7 @@ export class UserProfileComponent implements OnInit {
|
|||
faHourglassHalf = faHourglassHalf;
|
||||
faUserCheck = faUserCheck;
|
||||
faExclamationTriangle = faExclamationTriangle;
|
||||
faLink = faLink;
|
||||
|
||||
displayedAccount: Account;
|
||||
hasNote: boolean;
|
||||
|
|
Loading…
Reference in New Issue