diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 87e5343c..3e7bfee0 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -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'}, ]; /** diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 24979cc4..4522e2f6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -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({ diff --git a/src/app/modules/data/detail/data-detail.component.ts b/src/app/modules/data/detail/data-detail.component.ts index 6905a0d0..79d728c6 100644 --- a/src/app/modules/data/detail/data-detail.component.ts +++ b/src/app/modules/data/detail/data-detail.component.ts @@ -42,7 +42,7 @@ export class DataDetailComponent { language: SCLanguageCode; /** - * + * * @param route TODO * @param dataProvider TODO * @param translateService TODO diff --git a/src/app/modules/data/elements/skeleton-list-item.component.ts b/src/app/modules/data/elements/skeleton-list-item.component.ts index 68f48e4b..cc65447d 100644 --- a/src/app/modules/data/elements/skeleton-list-item.component.ts +++ b/src/app/modules/data/elements/skeleton-list-item.component.ts @@ -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', diff --git a/src/app/modules/data/elements/skeleton-simple-card.component.ts b/src/app/modules/data/elements/skeleton-simple-card.component.ts index b653a595..71c0beb5 100644 --- a/src/app/modules/data/elements/skeleton-simple-card.component.ts +++ b/src/app/modules/data/elements/skeleton-simple-card.component.ts @@ -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', diff --git a/src/app/modules/news/news.module.ts b/src/app/modules/news/news.module.ts new file mode 100644 index 00000000..a24db78e --- /dev/null +++ b/src/app/modules/news/news.module.ts @@ -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 . + */ +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 {} diff --git a/src/app/modules/news/news.provider.ts b/src/app/modules/news/news.provider.ts new file mode 100644 index 00000000..1c4caa35 --- /dev/null +++ b/src/app/modules/news/news.provider.ts @@ -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 . + */ +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 { + 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; + } +} diff --git a/src/app/modules/news/page/news-item.component.ts b/src/app/modules/news/page/news-item.component.ts new file mode 100644 index 00000000..26087a66 --- /dev/null +++ b/src/app/modules/news/page/news-item.component.ts @@ -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 . + */ +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; + }); + } +} diff --git a/src/app/modules/news/page/news-item.html b/src/app/modules/news/page/news-item.html new file mode 100644 index 00000000..be046afc --- /dev/null +++ b/src/app/modules/news/page/news-item.html @@ -0,0 +1,22 @@ + + + + + + + + + + + {{item.datePublished | amLocale: language | amDateFormat:'Do MMMM YYYY, HH:mm'}} + Uhr + + + {{item.name}} + {{item.name}} + + + + {{item.messageBody}} + + diff --git a/src/app/modules/news/page/news-item.scss b/src/app/modules/news/page/news-item.scss new file mode 100644 index 00000000..4b6f7978 --- /dev/null +++ b/src/app/modules/news/page/news-item.scss @@ -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%; +} diff --git a/src/app/modules/news/page/news-page.component.ts b/src/app/modules/news/page/news-page.component.ts new file mode 100644 index 00000000..5aeca01b --- /dev/null +++ b/src/app/modules/news/page/news-page.component.ts @@ -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 . + */ +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); + } +} diff --git a/src/app/modules/news/page/news-page.html b/src/app/modules/news/page/news-page.html new file mode 100644 index 00000000..30585b05 --- /dev/null +++ b/src/app/modules/news/page/news-page.html @@ -0,0 +1,25 @@ + + + + + + + + {{'news.title' | translate}} + + + + + + + + + + + + + + + + + diff --git a/src/app/modules/news/page/skeleton-news-item.component.ts b/src/app/modules/news/page/skeleton-news-item.component.ts new file mode 100644 index 00000000..9e325cbb --- /dev/null +++ b/src/app/modules/news/page/skeleton-news-item.component.ts @@ -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 . + */ +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 { +} diff --git a/src/app/modules/news/page/skeleton-news-item.html b/src/app/modules/news/page/skeleton-news-item.html new file mode 100644 index 00000000..fa2ad103 --- /dev/null +++ b/src/app/modules/news/page/skeleton-news-item.html @@ -0,0 +1,12 @@ + + + + + + + +

+

+

+
+
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index f3940e22..27b3e221 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -15,6 +15,9 @@ } } }, + "news": { + "title": "Aktuelles" + }, "menu": { "context": { "title": "Kontext MenĂ¼", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 47cc1222..0f7a9619 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -15,6 +15,9 @@ } } }, + "news": { + "title": "News" + }, "menu": { "context": { "title": "context menu", diff --git a/src/assets/imgs/modules/news/placeholder.jpg b/src/assets/imgs/modules/news/placeholder.jpg new file mode 100644 index 00000000..94a31799 Binary files /dev/null and b/src/assets/imgs/modules/news/placeholder.jpg differ