socialnetworknews-web

A open-source Paper.li clone
git clone git://archive.git.mtrnord.blog/SocialNetworkNews/socialnetworknews-web.git
Log | Files | Refs | README | LICENSE

commit b50090e300dec354a69f217e71173e6bdfc78fda
parent 84d7de835e3fa065e392591e4c938fa5923661c0
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 25 Mar 2018 13:34:54 +0200

use angular-material grid for tweets and add author image to the cards

Diffstat:
Msrc/app/app.module.ts | 2++
Msrc/app/tweet-list/tweet-list.component.html | 60+++++++++++++++++++++++++++++++++---------------------------
Msrc/app/tweet-list/tweet-list.component.ts | 33++++++++++++++++++++++++++++++++-
3 files changed, 67 insertions(+), 28 deletions(-)

diff --git a/src/app/app.module.ts b/src/app/app.module.ts @@ -15,6 +15,7 @@ import { SpinnerComponent } from './spinner/spinner.component'; import {MatCardModule} from '@angular/material/card'; import {MatButtonModule} from '@angular/material/button'; +import {MatGridListModule} from '@angular/material/grid-list'; import { ApiService } from './api.service'; @@ -61,6 +62,7 @@ export class RavenErrorHandler implements ErrorHandler { ToastrModule.forRoot(), MatCardModule, MatButtonModule, + MatGridListModule, ], providers: [ ApiService, diff --git a/src/app/tweet-list/tweet-list.component.html b/src/app/tweet-list/tweet-list.component.html @@ -1,36 +1,42 @@ <spinner spinner="spinner"></spinner> -<div class="grid"> - <mat-card *ngFor="let item of data"> - <div class="ribbon ribbon-top-left" *ngIf="item.retweet" style="max-width: 22rem"> +<mat-grid-list cols="3"> + <mat-grid-tile-header> + {{paperData.name}} + </mat-grid-tile-header> + <mat-grid-tile> + <mat-card *ngFor="let item of data"> + <div class="ribbon ribbon-top-left" *ngIf="item.retweet" style="max-width: 22rem"> <span> <i class="fa fa-retweet"></i> </span> - </div> - <mat-card-header> - <mat-card-title>{{item.display_name}}</mat-card-title> - <mat-card-subtitle><i class="fa fa-clock-o">&nbsp;</i>{{item.created_at.toLocaleString()}}</mat-card-subtitle> - </mat-card-header> - <a (click)="show(lightboxItem)" > - <img mat-card-image *ngIf="item.image_urls && item.image_urls[0]" [src]="item.image_urls[0]"> - </a> - - <!-- lightbox container hidden with CSS --> - <a (click)="hide(lightboxItem)" class="lightbox" #lightboxItem> - <div class="img-wrapper"> - <img *ngIf="item.image_urls && item.image_urls[0]" [src]="item.image_urls[0]"> </div> - </a> - <mat-card-content> - {{item.text}} - <br> - <i class="fa fa-heart">&nbsp;</i>{{item.favorites.toLocaleString()}}&nbsp;<i class="fa fa-retweet">&nbsp;</i>{{item.retweets.toLocaleString()}} - </mat-card-content> - <mat-card-actions> - <a mat-button href="{{item.tweet_link}}">OPEN ON TWITTER</a> - </mat-card-actions> - </mat-card> + <mat-card-header> + <img src="https://twitter.com/{{item.user_id}}/profile_image" mat-card-avatar> + <mat-card-title>{{item.display_name}}</mat-card-title> + <mat-card-subtitle><i class="fa fa-clock-o">&nbsp;</i>{{item.created_at.toLocaleString()}}</mat-card-subtitle> + </mat-card-header> + <a (click)="show(lightboxItem)" > + <img mat-card-image *ngIf="item.image_urls && item.image_urls[0]" [src]="item.image_urls[0]"> + </a> + + <!-- lightbox container hidden with CSS --> + <a (click)="hide(lightboxItem)" class="lightbox" #lightboxItem> + <div class="img-wrapper"> + <img *ngIf="item.image_urls && item.image_urls[0]" [src]="item.image_urls[0]"> + </div> + </a> + <mat-card-content> + {{item.text}} + <br> + <i class="fa fa-heart">&nbsp;</i>{{item.favorites.toLocaleString()}}&nbsp;<i class="fa fa-retweet">&nbsp;</i>{{item.retweets.toLocaleString()}} + </mat-card-content> + <mat-card-actions> + <a mat-button href="{{item.tweet_link}}">OPEN ON TWITTER</a> + </mat-card-actions> + </mat-card> + </mat-grid-tile> <!--<ng-container *ngFor="let item of data"> <app-card *ngIf="item.image_urls" [title]="item.display_name" [image]="item.image_urls[0]" [text]="item.text" [retweet]="item.retweet" [retweets]="item.retweets" [created_at]="item.created_at" [favs]="item.favorites"></app-card> <app-card *ngIf="!item.image_urls" [title]="item.display_name" [text]="item.text" [retweet]="item.retweet" [retweets]="item.retweets" [created_at]="item.created_at" [favs]="item.favorites"></app-card> </ng-container>--> -</div> +</mat-grid-list> diff --git a/src/app/tweet-list/tweet-list.component.ts b/src/app/tweet-list/tweet-list.component.ts @@ -1,6 +1,6 @@ import {Component, Input, OnInit} from '@angular/core'; import * as Raven from 'raven-js'; -import {ApiService, TweetsEntity} from '../api.service'; +import {ApiService, Paper, TweetsEntity} from '../api.service'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/retryWhen'; @@ -19,6 +19,7 @@ import {ToastrService} from 'ngx-toastr'; export class TweetListComponent implements OnInit { @Input() uuid; data: (TweetsEntity)[]; + paperData: Paper; constructor(private apiService: ApiService, private toastr: ToastrService) { Raven.captureBreadcrumb({ @@ -40,6 +41,36 @@ export class TweetListComponent implements OnInit { ngOnInit() { this.getYesterday(); + this.getPaper(); + } + getPaper() { + this.apiService.getPaper(this.uuid) + // TODO: Better variable naming + .retryWhen(oerror => { + return oerror + .mergeMap((error: any) => { + if (String(error.status).startsWith('50')) { + return Observable.of(error.status).delay(1000); + } else if (error.status === 404) { + return Observable.throw({error: 'Sorry, there was an error. The Server just doesn\'t find the requested paper :('}); + } + return Observable.throw({error: 'Unknown error'}); + }) + .take(5) + // TODO: Allow to link to a Status Page + .concat(Observable.throw({error: 'Sorry, there was an error (after 5 retries). This probably means we can\'t reach our API Server :('})); + }) + .subscribe( + data => { this.paperData = data; }, + err => { + this.toastr.error(err['error'], 'Error connecting API', { + positionClass: 'toast-top-center', + disableTimeOut: true + }); + throw err; + }, + () => console.log('done loading Paper Data') + ); } getYesterday() {