feat: news module

This commit is contained in:
Jovan Krunić
2021-01-13 18:21:14 +01:00
parent 3c079cd189
commit 22cd0af1bf
17 changed files with 320 additions and 4 deletions

View File

@@ -16,7 +16,7 @@ import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{path: '', redirectTo: '/search', pathMatch: 'full'},
{path: '', redirectTo: '/news', pathMatch: 'full'},
];
/**

View File

@@ -30,6 +30,7 @@ import {AppComponent} from './app.component';
import {ConfigModule} from './modules/config/config.module';
import {DataModule} from './modules/data/data.module';
import {MenuModule} from './modules/menu/menu.module';
import {NewsModule} from './modules/news/news.module';
import {SettingsModule} from './modules/settings/settings.module';
import {StorageModule} from './modules/storage/storage.module';
import {fakeBackendProvider} from './_helpers/fake-backend.interceptor';
@@ -72,6 +73,7 @@ const providers : Provider[] = [
DataModule,
IonicModule.forRoot(),
MenuModule,
NewsModule,
SettingsModule,
StorageModule,
TranslateModule.forRoot({

View File

@@ -42,7 +42,7 @@ export class DataDetailComponent {
language: SCLanguageCode;
/**
*
*
* @param route TODO
* @param dataProvider TODO
* @param translateService TODO

View File

@@ -15,7 +15,7 @@
import {Component} from '@angular/core';
/**
* TODO
* A placeholder to show when a list item is being loaded
*/
@Component({
selector: 'stapps-skeleton-list-item',

View File

@@ -15,7 +15,7 @@
import {Component} from '@angular/core';
/**
* TODO
* A placeholder to show when a simple card is being loaded
*/
@Component({
selector: 'stapps-skeleton-simple-card',

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2020-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {TranslateModule} from '@ngx-translate/core';
import {MomentModule} from 'ngx-moment';
import {DataModule} from '../data/data.module';
import {SettingsProvider} from '../settings/settings.provider';
import {NewsPageComponent} from './page/news-page.component';
import {SkeletonNewsItem} from './page/skeleton-news-item.component';
import {NewsItemComponent} from './page/news-item.component';
const newsRoutes: Routes = [
{path: 'news', component: NewsPageComponent},
];
/**
* News Module
*/
@NgModule({
declarations: [
NewsPageComponent,
SkeletonNewsItem,
NewsItemComponent,
],
imports: [
IonicModule.forRoot(),
TranslateModule.forChild(),
RouterModule.forChild(newsRoutes),
CommonModule,
MomentModule,
DataModule,
],
providers: [
SettingsProvider,
],
})
export class NewsModule {}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2020-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Injectable} from '@angular/core';
import {SCMessage} from '@openstapps/core';
import {DataProvider} from '../data/data.provider';
/**
* Service for providing news messages
*/
@Injectable({
providedIn: 'root',
})
export class NewsProvider {
constructor(private dataProvider: DataProvider) {
}
/**
* Get news messages
* TODO: make dates sortable on the backend side and then adjust this method
* @param size How many messages/news to fetch
* @param sort If sort by date needs to be performed
*/
async getList(size: number, sort?: boolean): Promise<SCMessage[]> {
const result = await this.dataProvider.search({
filter: {
type: 'value',
arguments: {
field: 'type',
value: 'message',
},
},
size: size,
});
const news = result.data as SCMessage[];
if (sort) {
news.sort((a, b) => {
if (typeof a.datePublished !== 'undefined' && typeof b.datePublished !== 'undefined') {
return (a.datePublished > b.datePublished) ? -1 : ((a.datePublished < b.datePublished) ? 1 : 0);
}
return 0;
});
}
return news;
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input} from '@angular/core';
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
import {SCLanguageCode, SCMessage} from '@openstapps/core';
import {Subscription} from 'rxjs';
/**
* News page component
*/
@Component({
selector: 'stapps-news-item',
templateUrl: 'news-item.html',
styleUrls: ['news-item.scss'],
})
export class NewsItemComponent {
/**
* News (message) to show
*/
@Input() item: SCMessage;
/**
* Current language
*/
language: string;
/**
* Current language subscription
*/
languageSubscription: Subscription;
constructor(private translateService: TranslateService) {}
/**
* Remove language subscription on component destruction
*/
ngOnDestroy() {
this.languageSubscription?.unsubscribe();
}
/**
* Initialize the local variables on component initialization
*/
ngOnInit() {
this.language = this.translateService.currentLang as SCLanguageCode;
this.languageSubscription = this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
this.language = event.lang as SCLanguageCode;
});
}
}

View File

@@ -0,0 +1,22 @@
<ion-card>
<span *ngIf="item.url; else imageNoUrl">
<a href="{{item.url}}">
<img src="{{item.image}}" onError="this.src='../../assets/imgs/modules/news/placeholder.jpg';" />
</a>
</span>
<ng-template #imageNoUrl>
<img src="{{item.image}}" onError="this.src='../../assets/imgs/modules/news/placeholder.jpg';" />
</ng-template>
<ion-card-header>
<ion-card-subtitle *ngIf="item.datePublished">{{item.datePublished | amLocale: language | amDateFormat:'Do MMMM YYYY, HH:mm'}}
<span *ngIf="language === 'de'">Uhr</span>
</ion-card-subtitle>
<ion-card-title>
<span *ngIf="item.url; else titleNoUrl"><a href="{{item.url}}"><span class="text">{{item.name}}</span><span class="icon"><ion-icon name="open-outline"></ion-icon></span></a></span>
<ng-template #titleNoUrl>{{item.name}}</ng-template>
</ion-card-title>
</ion-card-header>
<ion-card-content>
{{item.messageBody}}
</ion-card-content>
</ion-card>

View File

@@ -0,0 +1,12 @@
ion-card-header a {
color: var(--ion-color-dark-tint);
text-decoration: none;
span.icon ion-icon {
vertical-align: text-top;
font-size: 60%;
padding-left: 4px;
}
}
ion-card img {
width: 100%;
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component} from '@angular/core';
import {SCMessage} from '@openstapps/core';
import {NewsProvider} from '../news.provider';
/**
* News page component
*/
@Component({
selector: 'stapps-news-page',
templateUrl: 'news-page.html',
})
export class NewsPageComponent {
/**
* News (messages) to show
*/
news: SCMessage[];
constructor(private newsProvider: NewsProvider) {
}
/**
* Initialize the local variables on component initialization
*/
async ngOnInit() {
/* tslint:disable:no-magic-numbers */
this.news = await this.newsProvider.getList(30, true);
}
}

View File

@@ -0,0 +1,25 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
<ion-menu-button></ion-menu-button>
</ion-buttons>
<!--TODO: read this from the config (menu item title)-->
<ion-title>{{'news.title' | translate}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content fullscreen>
<ion-grid>
<ion-row *ngIf="!news">
<ion-col size="12" size-md="6" *ngFor="let skeleton of [1, 2, 3, 4, 5]">
<stapps-skeleton-news-item></stapps-skeleton-news-item>
</ion-col>
</ion-row>
<ion-row *ngIf="news">
<ion-col size="12" size-md="6" *ngFor="let item of news">
<stapps-news-item [item]="item"></stapps-news-item>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2020-2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component} from '@angular/core';
/**
* A placeholder to show when a news item is being loaded
*/
@Component({
selector: 'stapps-skeleton-news-item',
templateUrl: 'skeleton-news-item.html',
})
export class SkeletonNewsItem {
}

View File

@@ -0,0 +1,12 @@
<ion-card>
<ion-card-header>
<ion-card-subtitle><ion-skeleton-text animated style="width: 20%"></ion-skeleton-text></ion-card-subtitle>
<ion-card-title><ion-skeleton-text animated style="width: 95%"></ion-skeleton-text></ion-card-title>
<ion-card-title><ion-skeleton-text animated style="width: 65%"></ion-skeleton-text></ion-card-title>
</ion-card-header>
<ion-card-content>
<p><ion-skeleton-text animated style="width: 95%;"></ion-skeleton-text></p>
<p><ion-skeleton-text animated style="width: 95%;"></ion-skeleton-text></p>
<p><ion-skeleton-text animated style="width: 55%;"></ion-skeleton-text></p>
</ion-card-content>
</ion-card>

View File

@@ -15,6 +15,9 @@
}
}
},
"news": {
"title": "Aktuelles"
},
"menu": {
"context": {
"title": "Kontext Menü",

View File

@@ -15,6 +15,9 @@
}
}
},
"news": {
"title": "News"
},
"menu": {
"context": {
"title": "context menu",

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB