Commit 44f93840 authored by Mark Harding's avatar Mark Harding

(feat): boost feed is back

parent 14a72a8a
No related merge requests found
Pipeline #76323542 canceled with stages
<div class="m-boost-rotator-tools">
<span
i1n="@@BOOST_ROTATOR__SHOWING_BOOSTS"
*ngIf="router.url == '/newsfeed/boost'"
>
Showing boosts
</span>
<div class="m-layout--spacer"></div>
<ul class="m-boost-rotator-tabs">
<li routerLink="/newsfeed/boost"
*ngIf="router.url !== '/newsfeed/boost'"
class="m-boostRotator__tab--boost-feed"
>
<a i18n="@@M__COMMON__BOOSTFEED">Boostfeed</a>
</li>
<ng-container *ngIf="boosts.length > 0; else noBoosts">
<li (click)="prev()">
<i class="material-icons mdl-color-text--blue-grey-400">chevron_left</i>
......@@ -14,7 +26,7 @@
<i style="height: 32px;display: block;"></i>
</li>
</ng-template>
<li>
<li class="m-boost-rotator-tabs--settings">
<m-newsfeed--dropdown [showBoost]="true"></m-newsfeed--dropdown>
</li>
</ul>
......
......@@ -102,6 +102,21 @@
display:flex;
z-index: 1;
.m-boostRotator__tab--boost-feed a {
text-transform: uppercase;
letter-spacing: 1.25px;
font-size: 11px;
line-height: 24px;
margin-top: -5px;
margin-right: 8px;
display: block;
cursor: pointer;
@include m-theme(){
color: themed($m-grey-400);
}
}
.m-boost-rotator-tabs-tab{
margin:0 2px;
padding:0;
......
<div class="minds-list">
<m-newsfeed--boost-rotator interval="12" *ngIf="showBoostRotator"></m-newsfeed--boost-rotator>
<minds-activity *ngFor="let activity of newsfeed; let i = index" [object]="activity" [boostToggle]="activity.boostToggle" [boost]="boostFeed" [showBoostMenuOptions]="boostFeed" (delete)="delete(activity)" [slot]="i + 1" class="mdl-card m-border item"></minds-activity>
<minds-newsfeed-poster></minds-newsfeed-poster>
<div class="m-feeds-sorted__query">
<span>Showing Boosts</span>
</div>
<ng-container *ngFor="let activity$ of (feedsService.feed | async); let i = index">
<minds-activity
*ngIf="(activity$ | async) as activity"
[object]="activity"
[boostToggle]="activity.boostToggle"
[boost]="boostFeed"
[showBoostMenuOptions]="boostFeed"
(delete)="delete(activity)"
[slot]="i + 1"
class="mdl-card m-border item"
>
</minds-activity>
</ng-container>
<infinite-scroll
distance="25%"
(load)="load()"
[moreData]="moreData"
[inProgress]="inProgress">
distance="25%"
(load)="loadNext()"
[moreData]="feedsService.hasMore | async"
[inProgress]="feedsService.inProgress | async"
>
</infinite-scroll>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { CommonModule } from '@angular/common';
import { MockComponent, MockDirective } from '../../../utils/mock';
import { By } from '@angular/platform-browser';
import { NewsfeedBoostComponent } from './boost.component';
import { Session } from '../../../services/session';
import { sessionMock } from '../../../../tests/session-mock.spec';
import { clientMock } from '../../../../tests/client-mock.spec';
import { Client } from '../../../services/api/client';
import { Navigation } from '../../../services/navigation';
import { navigationMock } from '../../../../tests/navigation-service-mock.spec';
import { MindsTitle } from '../../../services/ux/title';
import { mindsTitleMock } from '../../../mocks/services/ux/minds-title.service.mock.spec';
import { Upload } from '../../../services/api/upload';
import { uploadMock } from '../../../../tests/upload-mock.spec';
import { storageMock } from '../../../../tests/storage-mock.spec';
import { Storage } from '../../../services/storage';
import { ContextService } from '../../../services/context.service';
import { contextServiceMock } from '../../../../tests/context-service-mock.spec';
@Component({
selector: 'm-newsfeed--boost-rotator',
template: ''
})
class NewsfeedBoostRotatorComponentMock {
@Input() interval: any;
@Input() channel: any;
}
@Component({
selector: 'minds-activity',
template: ''
})
class MindsActivityMock {
@Input() object: any;
@Input() boostToggle;
@Input() boost;
@Input() showBoostMenuOptions: boolean;
@Output() delete: EventEmitter<any> = new EventEmitter<any>();
}
describe('NewsfeedBoostComponent', () => {
let comp: NewsfeedBoostComponent;
let fixture: ComponentFixture<NewsfeedBoostComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MockDirective({ selector: '[mdl]', inputs: ['mdl'] }),
MockComponent({ selector: 'm-newsfeed--boost-rotator', template: '', inputs: ['interval', 'channel'] }),
MindsActivityMock,
MockComponent({
selector: 'infinite-scroll',
inputs: ['inProgress', 'moreData', 'inProgress'],
}),
NewsfeedBoostComponent
],
imports: [RouterTestingModule, ReactiveFormsModule, CommonModule, FormsModule],
providers: [
{ provide: Session, useValue: sessionMock },
{ provide: Client, useValue: clientMock },
{ provide: MindsTitle, useValue: mindsTitleMock },
{ provide: Navigation, useValue: navigationMock },
{ provide: Upload, useValue: uploadMock },
{ provide: Storage, useValue: storageMock },
{ provide: ContextService, useValue: contextServiceMock },
]
})
.compileComponents();
}));
beforeEach((done) => {
jasmine.MAX_PRETTY_PRINT_DEPTH = 10;
jasmine.clock().install();
fixture = TestBed.createComponent(NewsfeedBoostComponent);
comp = fixture.componentInstance;
clientMock.response = {};
clientMock.response['api/v1/boost/fetch/newsfeed'] = {
status: 'success',
boosts: [
{
'guid': '1',
'type': 'activity',
'time_created': '1525457795',
'time_updated': '1525457795',
'title': '',
'message': 'test',
'boosted': true,
'boosted_guid': '1'
}, {
'guid': '2',
'type': 'activity',
'message': 'test2',
'boosted': true,
'boosted_guid': 2
}
],
'load-next': ''
};
fixture.detectChanges();
if (fixture.isStable()) {
done();
} else {
fixture.whenStable()
.then(() => {
fixture.detectChanges();
done()
});
}
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should have a boost rotator', () => {
expect(fixture.debugElement.query(By.css('m-newsfeed--boost-rotator'))).toBeTruthy();
});
it('should have an infinite-scroll', () => {
expect(fixture.debugElement.query(By.css('infinite-scroll'))).toBeTruthy();
});
it('should have a list of activities', () => {
expect(clientMock.get).toHaveBeenCalled();
const call = clientMock.get.calls.mostRecent();
expect(call.args[0]).toBe('api/v1/boost/fetch/newsfeed');
expect(call.args[1]).toEqual({ limit: 12, offset: '' });
expect(call.args[2]).toEqual({ cache: true });
const list = fixture.debugElement.query(By.css('.minds-list'));
expect(list.nativeElement.children.length).toBe(4); // 2 activities + boost rotator + infinite-scroll
});
});
......@@ -6,10 +6,11 @@ import { ActivatedRoute, Router } from '@angular/router';
import { Client, Upload } from '../../../services/api';
import { MindsTitle } from '../../../services/ux/title';
import { Navigation as NavigationService } from '../../../services/navigation';
import { Session } from '../../../services/session';
import { Storage } from '../../../services/storage';
import { ContextService } from '../../../services/context.service';
import { PosterComponent } from '../poster/poster.component';
import { FeaturesService } from "../../../services/features.service";
import { FeedsService } from "../../../common/services/feeds.service";
@Component({
selector: 'm-newsfeed--boost',
......@@ -21,6 +22,7 @@ export class NewsfeedBoostComponent {
newsfeed: Array<Object>;
prepended: Array<any> = [];
offset: string = '';
exclude: string[] = [];
showBoostRotator: boolean = true;
inProgress: boolean = false;
moreData: boolean = true;
......@@ -43,7 +45,8 @@ export class NewsfeedBoostComponent {
public title: MindsTitle,
private storage: Storage,
private context: ContextService,
private session: Session,
protected featuresService: FeaturesService,
protected feedsService: FeedsService,
) {
this.title.setTitle('Boost Newsfeed');
}
......@@ -70,39 +73,28 @@ export class NewsfeedBoostComponent {
this.paramsSubscription.unsubscribe();
}
load(refresh: boolean = false) {
async load(refresh: boolean = false) {
if (this.inProgress)
return false;
if (refresh) {
this.offset = '';
}
this.feedsService
.setEndpoint('api/v2/boost/feed')
.setParams({
boostfeed: true,
})
.setLimit(6)
.setOffset(0)
.fetch();
}
if (this.storage.get('boost:offset:boostfeed')) {
this.offset = this.storage.get('boost:offset:boostfeed');
loadNext() {
if (this.feedsService.canFetchMore
&& !this.feedsService.inProgress.getValue()
&& this.feedsService.offset.getValue()
) {
this.feedsService.fetch(); // load the next 150 in the background
}
this.inProgress = true;
this.client.get('api/v1/boost/fetch/newsfeed', { limit: 12, offset: this.offset }, { cache: true })
.then((data: any) => {
if (!data.boosts) {
this.moreData = false;
this.inProgress = false;
return false;
}
if (this.newsfeed && !refresh) {
this.newsfeed = this.newsfeed.concat(data.boosts);
} else {
this.newsfeed = data.boosts;
}
this.offset = data['load-next'];
this.storage.set('boost:offset:boostfeed', this.offset);
this.inProgress = false;
})
.catch((e) => {
this.inProgress = false;
});
this.feedsService.loadMore();
}
delete(activity) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment