Skip to content

Commit

Permalink
Added pagination service
Browse files Browse the repository at this point in the history
  • Loading branch information
robbdimitrov committed Nov 7, 2019
1 parent 2727d3c commit de3f485
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 51 deletions.
1 change: 0 additions & 1 deletion frontend/browserslist
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
4 changes: 2 additions & 2 deletions frontend/src/app/screens/feed/feed.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="container full-width">
<pg-image
*ngFor="let image of images"
*ngFor="let image of images()"
[image]="image"
[user]="image.owner | user | async"
(like)="onLike($event)"
Expand All @@ -12,7 +12,7 @@

<button
id="next"
*ngIf="images.length > 5"
*ngIf="count() > 5"
class="button outline-button round-corners"
(click)="onNextClick()"
>
Expand Down
48 changes: 23 additions & 25 deletions frontend/src/app/screens/feed/feed.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ import { Location } from '@angular/common';
import { Subscription } from 'rxjs';

import {
APIClient, APIPageCountLimit, UserDidLogoutNotification
APIClient, UserDidLogoutNotification
} from '../../services/api-client.service';
import { Image } from '../../models/image.model';
import { UserCache } from '../../services/user-cache.service';
import { PaginationService } from '../../services/pagination.service';
import { Session } from '../../services/session.service';

@Component({
templateUrl: './feed.component.html',
styleUrls: ['feed.component.scss']
styleUrls: ['feed.component.scss'],
providers: [PaginationService]
})
export class FeedComponent implements AfterViewInit, OnDestroy {
images: Image[] = [];
page = 0;
isSingleImageMode = false;
userId?: string;
loginSubscription: Subscription;

constructor(private apiClient: APIClient, private router: Router,
private userCache: UserCache, private session: Session,
private route: ActivatedRoute, private location: Location) {
private pagination: PaginationService<Image>,
private session: Session, private route: ActivatedRoute,
private location: Location) {

this.subscribeToLogout();

Expand All @@ -44,8 +44,7 @@ export class FeedComponent implements AfterViewInit, OnDestroy {
this.loginSubscription = this.apiClient.loginSubject.subscribe(
(value) => {
if (value === UserDidLogoutNotification) {
this.page = 0;
this.images = [];
this.pagination.reset();
this.router.navigate(['/login']);
}
}
Expand All @@ -68,31 +67,34 @@ export class FeedComponent implements AfterViewInit, OnDestroy {

loadNextPage() {
const req = (this.userId ?
this.apiClient.getUsersLikedImages(this.userId, this.page) :
this.apiClient.getAllImages(this.page));
this.apiClient.getUsersLikedImages(this.userId, this.pagination.page) :
this.apiClient.getAllImages(this.pagination.page));

req.subscribe((data) => {
const images = data.filter((image) => {
return !(this.images.some((value) => image.id === value.id));
return !(this.pagination.data.some((value) => image.id === value.id));
});

this.images.push(...images);

if (data.length === APIPageCountLimit) {
this.page += 1;
}
this.pagination.update(images);
},
(error) => console.error('Error loading images.')
);
}

loadImage(imageId: string) {
this.apiClient.getImage(imageId).subscribe(
(data) => this.images.push(data),
(data) => this.pagination.update([data]),
(error) => console.error(`Loading user failed: ${error}`)
);
}

images() {
return this.pagination.data;
}

count() {
return this.pagination.count();
}

// Actions

onLike(imageId: string) {
Expand All @@ -112,15 +114,11 @@ export class FeedComponent implements AfterViewInit, OnDestroy {
}

onDeleteAction(image: Image) {
const index = this.images.indexOf(image);

if (index > -1) {
this.images.splice(index, 1);
}
this.pagination.remove(image);

this.apiClient.deleteImage(image.id).subscribe(
(data) => {
if (this.isSingleImageMode && this.images.length === 0) {
if (this.isSingleImageMode && this.pagination.count() === 0) {
this.location.back();
}
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/screens/profile/profile.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<div class="image-container">
<pg-thumbnail
*ngFor="let image of images"
*ngFor="let image of images()"
[image]="image"
(openImage)="onOpenImage($event)"
>
Expand All @@ -18,7 +18,7 @@

<button
id="next"
*ngIf="images.length > 5"
*ngIf="count() > 5"
class="button outline-button round-corners"
(click)="onNextClick()"
>
Expand Down
36 changes: 17 additions & 19 deletions frontend/src/app/screens/profile/profile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,29 @@ import { Router, ActivatedRoute } from '@angular/router';

import { Image } from '../../models/image.model';
import {
APIClient, APIPageCountLimit, UserDidLogoutNotification
APIClient, UserDidLogoutNotification
} from '../../services/api-client.service';
import { Session } from '../../services/session.service';
import { UserCache } from '../../services/user-cache.service';
import { PaginationService } from '../../services/pagination.service';
import { User } from '../../models/user.model';

@Component({
selector: 'pg-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss']
styleUrls: ['./profile.component.scss'],
providers: [PaginationService]
})
export class ProfileComponent implements OnDestroy {
images: Image[] = [];
page = 0;
loginSubscription: Subscription;
user: User;

constructor(private apiClient: APIClient, private router: Router,
private userCache: UserCache, private session: Session,
private pagination: PaginationService<Image>,
private route: ActivatedRoute) {
this.subscribeToLogout();

this.route.params.subscribe(params => {
const id = params.id;
if (!this.user || id !== this.user.id) {
this.page = 0;
this.images = [];
this.loadUser(id);
}
});
Expand All @@ -42,8 +38,7 @@ export class ProfileComponent implements OnDestroy {
this.loginSubscription = this.apiClient.loginSubject.subscribe(
(value) => {
if (value === UserDidLogoutNotification) {
this.page = 0;
this.images = [];
this.pagination.reset();
this.router.navigate(['/login']);
}
}
Expand All @@ -69,22 +64,25 @@ export class ProfileComponent implements OnDestroy {
}

loadNextPage() {
this.apiClient.getUsersImages(this.user.id, this.page).subscribe(
this.apiClient.getUsersImages(this.user.id, this.pagination.page).subscribe(
(data) => {
const images = data.filter((image) => {
return !(this.images.some((value) => image.id === value.id));
return !(this.pagination.data.some((value) => image.id === value.id));
});

this.images.push(...images);

if (data.length === APIPageCountLimit) {
this.page += 1;
}
this.pagination.update(images);
},
(error) => console.error(`Error loading images: ${error}`)
);
}

images() {
return this.pagination.data;
}

count() {
return this.pagination.count();
}

// Actions

onOpenSettings() {
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/app/services/api-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import { environment } from '../../environments/environment';
export const UserDidLogoutNotification = 'UserDidLogoutNotification';
export const UserDidLoginNotification = 'UserDidLoginNotification';

export const APIPageCountLimit = 10;

@Injectable()
export class APIClient {
private apiRoot = environment.apiRoot;
Expand Down
34 changes: 34 additions & 0 deletions frontend/src/app/services/pagination.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Injectable } from '@angular/core';

@Injectable()
export class PaginationService<T> {
data: Array<T> = [];
perPage = 10;
page = 0;

update(data: Array<T>) {
this.data.push(...data);
this.updatePage();
}

remove(item: T) {
const index = this.data.indexOf(item);
if (index > -1) {
this.data.splice(index, 1);
}
this.updatePage();
}

reset() {
this.page = 0;
this.data = [];
}

count() {
return this.data.length;
}

private updatePage() {
this.page = Math.floor(this.data.length / this.perPage);
}
}

0 comments on commit de3f485

Please sign in to comment.