diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index c53bc532..488af28e 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -10,6 +10,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { implementation project(':capacitor-app') + implementation project(':capacitor-browser') implementation project(':capacitor-haptics') implementation project(':capacitor-keyboard') implementation project(':capacitor-splash-screen') diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json index a07780d4..51bdacac 100644 --- a/android/app/src/main/assets/capacitor.plugins.json +++ b/android/app/src/main/assets/capacitor.plugins.json @@ -3,6 +3,10 @@ "pkg": "@capacitor/app", "classpath": "com.capacitorjs.plugins.app.AppPlugin" }, + { + "pkg": "@capacitor/browser", + "classpath": "com.capacitorjs.plugins.browser.BrowserPlugin" + }, { "pkg": "@capacitor/haptics", "classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin" diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index fd6199e9..a6873f0b 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -5,6 +5,9 @@ project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/ include ':capacitor-app' project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') +include ':capacitor-browser' +project(':capacitor-browser').projectDir = new File('../node_modules/@capacitor/browser/android') + include ':capacitor-haptics' project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android') diff --git a/package-lock.json b/package-lock.json index b78481fc..a8501571 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2078,6 +2078,11 @@ "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-1.0.6.tgz", "integrity": "sha512-NjHIs6f4WJQuhabnCkcE6YLyIIn+t4Al5etB/SJGZJwUYRe1yJYtZ4T/KobDIzwwZn9I9de7QbEA5947lGttBQ==" }, + "@capacitor/browser": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@capacitor/browser/-/browser-1.0.6.tgz", + "integrity": "sha512-ZDx+HNPRQZKHpWxbYEyDz34Ge4fwhiiGg2UEnA+ol+pmdvHyYxw/c8HafCEVRJutHrXcVdSNoBNAeEPkQeabrQ==" + }, "@capacitor/cli": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-3.3.2.tgz", diff --git a/package.json b/package.json index 6e62026b..5d69afa2 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@asymmetrik/ngx-leaflet": "8.1.0", "@asymmetrik/ngx-leaflet-markercluster": "5.0.1", "@capacitor/app": "1.0.6", + "@capacitor/browser": "1.0.6", "@capacitor/core": "3.3.1", "@capacitor/haptics": "1.1.3", "@capacitor/keyboard": "1.1.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f4f2120c..bae50456 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -24,7 +24,7 @@ import {APP_INITIALIZER, NgModule, Provider} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {RouteReuseStrategy} from '@angular/router'; import {Diagnostic} from '@ionic-native/diagnostic/ngx'; -import {IonicModule, IonicRouteStrategy} from '@ionic/angular'; +import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular'; import { TranslateLoader, TranslateModule, @@ -57,6 +57,8 @@ import {AboutModule} from './modules/about/about.module'; import {FavoritesModule} from './modules/favorites/favorites.module'; import {FeedbackModule} from './modules/feedback/feedback.module'; import {DebugDataCollectorService} from './modules/data/debug-data-collector.service'; +import {Browser} from './util/browser.factory'; +import {browserFactory} from './util/browser.factory'; registerLocaleData(localeDe); @@ -119,6 +121,11 @@ const providers: Provider[] = [ provide: LocationStrategy, useClass: PathLocationStrategy, }, + { + provide: Browser, + useFactory: browserFactory, + deps: [Platform], + }, { provide: APP_INITIALIZER, multi: true, diff --git a/src/app/modules/data/types/message/message-detail-content.component.ts b/src/app/modules/data/types/message/message-detail-content.component.ts index 3f559215..9b0bd999 100644 --- a/src/app/modules/data/types/message/message-detail-content.component.ts +++ b/src/app/modules/data/types/message/message-detail-content.component.ts @@ -14,6 +14,7 @@ */ import {Component, Input} from '@angular/core'; import {SCMessage} from '@openstapps/core'; +import {Browser} from '../../../../util/browser.factory'; /** * TODO @@ -21,10 +22,22 @@ import {SCMessage} from '@openstapps/core'; @Component({ selector: 'stapps-message-detail-content', templateUrl: 'message-detail-content.html', + styleUrls: ['message-detail-content.scss'], }) export class MessageDetailContentComponent { + constructor(private browser: Browser) {} + /** * TODO */ @Input() item: SCMessage; + + /** + * Open the external link when clicked + * + * @param url Web address to open + */ + onLinkClick(url: string) { + this.browser.open(url); + } } diff --git a/src/app/modules/data/types/message/message-detail-content.html b/src/app/modules/data/types/message/message-detail-content.html index aff45627..a8523057 100644 --- a/src/app/modules/data/types/message/message-detail-content.html +++ b/src/app/modules/data/types/message/message-detail-content.html @@ -1,23 +1,51 @@ - - - - - +
+ + + + + +
+ + + + + + + + + + {{ 'sameAs' | propertyNameTranslate: item | titlecase }} + + + {{ item.name }} + + + + diff --git a/src/app/modules/data/types/message/message-detail-content.scss b/src/app/modules/data/types/message/message-detail-content.scss new file mode 100644 index 00000000..aff5a181 --- /dev/null +++ b/src/app/modules/data/types/message/message-detail-content.scss @@ -0,0 +1,39 @@ +/* + * 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 . + */ + +:host { + ion-thumbnail { + width: 100%; + height: auto; + img { + display: block; + } + } + a { + cursor: pointer; + ion-icon { + vertical-align: text-top; + font-size: 80%; + padding-left: 2px; + } + } + // Show smaller image on a desktop + @media (min-width: 992px) { + ion-thumbnail { + width: 60%; + margin: 0 auto; + } + } +} diff --git a/src/app/modules/news/item/news-item.component.ts b/src/app/modules/news/item/news-item.component.ts index 90010b75..315db6b6 100644 --- a/src/app/modules/news/item/news-item.component.ts +++ b/src/app/modules/news/item/news-item.component.ts @@ -14,6 +14,7 @@ */ import {Component, Input} from '@angular/core'; import {SCMessage} from '@openstapps/core'; +import {Browser} from '../../../util/browser.factory'; /** * News page component */ @@ -23,8 +24,14 @@ import {SCMessage} from '@openstapps/core'; styleUrls: ['news-item.scss'], }) export class NewsItemComponent { + constructor(private browser: Browser) {} + /** * News (message) to show */ @Input() item: SCMessage; + + onLinkClick(url: string) { + this.browser.open(url); + } } diff --git a/src/app/modules/news/item/news-item.html b/src/app/modules/news/item/news-item.html index 5b5947ab..ae9d6ede 100644 --- a/src/app/modules/news/item/news-item.html +++ b/src/app/modules/news/item/news-item.html @@ -1,6 +1,6 @@ - - + + - - - - - - {{ item.datePublished | amCalendar | sentencecase }} - {{ item.name }} - {{ item.name }} + + {{ item.name }} - {{ item.messageBody }} + + {{ item.messageBody | slice: 0:120 }}... diff --git a/src/app/modules/news/item/news-item.scss b/src/app/modules/news/item/news-item.scss index 4bb9c5a5..c22251b4 100644 --- a/src/app/modules/news/item/news-item.scss +++ b/src/app/modules/news/item/news-item.scss @@ -1,11 +1,6 @@ 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 ion-thumbnail { diff --git a/src/app/util/browser.factory.ts b/src/app/util/browser.factory.ts new file mode 100644 index 00000000..79016dcd --- /dev/null +++ b/src/app/util/browser.factory.ts @@ -0,0 +1,36 @@ +/* + * 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 {Platform} from '@ionic/angular'; +import {Browser as BrowserPlugin} from '@capacitor/browser'; + +export abstract class Browser { + abstract open(url: string): Promise | void; +} + +class CapacitorBrowser { + open(url: string) { + return BrowserPlugin.open({url}); + } +} + +class WebBrowser { + open(url: string) { + window.open(url, '_blank'); + } +} + +export const browserFactory = (platform: Platform) => { + return platform.is('capacitor') ? new CapacitorBrowser() : new WebBrowser(); +};