tweet-list.component.ts (4650B)
1 2 import {throwError as observableThrowError, of} from 'rxjs'; 3 import {Component, Input, OnInit} from '@angular/core'; 4 import * as Raven from 'raven-js'; 5 import {ApiService, Paper, TweetsEntity} from '../api.service'; 6 import {ToastrService} from 'ngx-toastr'; 7 import {Meta, Title} from '@angular/platform-browser'; 8 import {Lightbox} from '../utils/lightbox'; 9 import {concat, delay, mergeMap, retryWhen, take} from 'rxjs/operators'; 10 11 12 13 @Component({ 14 selector: 'app-tweet-list', 15 templateUrl: './tweet-list.component.html', 16 styleUrls: ['./tweet-list.component.scss'] 17 }) 18 export class TweetListComponent implements OnInit { 19 @Input() uuid; 20 data: (TweetsEntity)[]; 21 paperData: Paper; 22 23 constructor(private apiService: ApiService, private toastr: ToastrService, private lightbox: Lightbox, private metaService: Meta, private titleService: Title) { 24 Raven.captureBreadcrumb({ 25 message: 'Showing Paper', 26 category: 'paper', 27 data: { 28 uuid: this.uuid 29 } 30 }); 31 } 32 33 ngOnInit() { 34 // Get API 35 this.getYesterday(); 36 this.getPaper(); 37 } 38 getPaper() { 39 this.apiService.getPaper(this.uuid) 40 // TODO: Better variable naming 41 .pipe( 42 retryWhen(oerror => { 43 return oerror 44 .pipe( 45 mergeMap((error: any) => { 46 if (String(error.status).startsWith('50')) { 47 return of(error.status) 48 .pipe( 49 delay(1000) 50 ); 51 } else if (error.status === 404) { 52 return observableThrowError({error: 'Sorry, there was an error. The Server just doesn\'t find the requested paper :('}); 53 } 54 return observableThrowError({error: 'Unknown error'}); 55 }), 56 take(5), 57 // TODO: Allow to link to a Status Page 58 concat(observableThrowError({error: 'Sorry, there was an error (after 5 retries). This probably means we can\'t reach our API Server :('})) 59 ); 60 }) 61 ) 62 .subscribe( 63 data => { 64 this.paperData = data; 65 // Set Meta Tags 66 this.metaService.addTags([ 67 { name: 'og:title', content: this.paperData.name }, 68 { name: 'og:description', content: this.paperData.description }, 69 { name: 'og:image', content: this.paperData.paper_image }, 70 { name: 'description', content: this.paperData.description }, 71 // TODO Disabled until Author API Implemented 72 // { name: 'author', content: this.paperData.author.username }, 73 ]); 74 this.titleService.setTitle( this.paperData.name ); 75 }, 76 err => { 77 this.toastr.error(err['error'], 'Error connecting API', { 78 positionClass: 'toast-top-center', 79 disableTimeOut: true 80 }); 81 throw err; 82 }, 83 () => console.log('done loading Paper Data') 84 ); 85 } 86 87 getYesterday() { 88 this.apiService.getYesterday(this.uuid) 89 // TODO: Better variable naming 90 .pipe( 91 retryWhen(oerror => { 92 return oerror 93 .pipe( 94 mergeMap((error: any) => { 95 if (String(error.status).startsWith('50')) { 96 return of(error.status) 97 .pipe(delay(1000)); 98 } else if (error.status === 404) { 99 return observableThrowError({error: 'Sorry, there was an error. The Server just doesn\'t find any data for the requested time :('}); 100 } 101 return observableThrowError({error: 'Unknown error'}); 102 }), 103 take(5), 104 // TODO: Allow to link to a Status Page 105 concat(observableThrowError({error: 'Sorry, there was an error (after 5 retries). This probably means we can\'t reach our API Server :('})) 106 ); 107 }) 108 ) 109 .subscribe( 110 data => { this.data = this.sort(data.tweets); }, 111 err => { 112 this.toastr.error(err['error'], 'Error connecting API', { 113 positionClass: 'toast-top-center', 114 disableTimeOut: true 115 }); 116 throw err; 117 }, 118 () => console.log('done loading Yesterday') 119 ); 120 } 121 122 private sort(arr: (TweetsEntity)[]): (TweetsEntity)[] { 123 const compare = (a, b): number => { 124 if ((a.image_urls && a.image_urls[0]) && !(b.image_urls && b.image_urls[0])) { 125 return -1; 126 } 127 if (!(a.image_urls && a.image_urls[0]) && (b.image_urls && b.image_urls[0])) { 128 return 1; 129 } 130 return 0; 131 }; 132 133 arr.sort(compare); 134 return arr; 135 } 136 }