mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-03-19 05:02:23 +00:00
refactor: migrate all cordova plugins to capacitor
This commit is contained in:
committed by
Rainer Killinger
parent
cdb6ac4084
commit
75f4644940
@@ -47,5 +47,5 @@ try {
|
|||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,18 @@ dependencies {
|
|||||||
implementation project(':capacitor-device')
|
implementation project(':capacitor-device')
|
||||||
implementation project(':capacitor-dialog')
|
implementation project(':capacitor-dialog')
|
||||||
implementation project(':capacitor-filesystem')
|
implementation project(':capacitor-filesystem')
|
||||||
|
implementation project(':capacitor-geolocation')
|
||||||
implementation project(':capacitor-haptics')
|
implementation project(':capacitor-haptics')
|
||||||
implementation project(':capacitor-keyboard')
|
implementation project(':capacitor-keyboard')
|
||||||
implementation project(':capacitor-local-notifications')
|
implementation project(':capacitor-local-notifications')
|
||||||
|
implementation project(':capacitor-network')
|
||||||
implementation project(':capacitor-share')
|
implementation project(':capacitor-share')
|
||||||
implementation project(':capacitor-splash-screen')
|
implementation project(':capacitor-splash-screen')
|
||||||
implementation project(':capacitor-status-bar')
|
implementation project(':capacitor-status-bar')
|
||||||
implementation project(':capacitor-storage')
|
implementation project(':capacitor-storage')
|
||||||
implementation project(':transistorsoft-capacitor-background-fetch')
|
implementation project(':transistorsoft-capacitor-background-fetch')
|
||||||
implementation project(':capacitor-secure-storage-plugin')
|
implementation project(':capacitor-secure-storage-plugin')
|
||||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
implementation "com.android.support:support-v4:27.+"
|
||||||
implementation "androidx.appcompat:appcompat:1.3.1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<manifest package="de.anyschool.app" xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest package="de.anyschool.app" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<application
|
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
|
||||||
android:allowBackup="true"
|
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/title_activity_main" android:launchMode="singleTask" android:name="de.anyschool.app.MainActivity" android:theme="@style/AppTheme.NoActionBarLaunch">
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/AppTheme">
|
|
||||||
|
|
||||||
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
|
|
||||||
android:label="@string/title_activity_main"
|
|
||||||
android:launchMode="singleTask"
|
|
||||||
android:name="de.anyschool.app.MainActivity"
|
|
||||||
android:theme="@style/AppTheme.NoActionBarLaunch">
|
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
@@ -31,13 +19,12 @@
|
|||||||
<data android:host="@string/app_host" android:scheme="https" />
|
<data android:host="@string/app_host" android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<provider android:authorities="${applicationId}.fileprovider"
|
<provider android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
|
||||||
android:exported="false"
|
|
||||||
android:grantUriPermissions="true"
|
|
||||||
android:name="androidx.core.content.FileProvider">
|
|
||||||
|
|
||||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-feature android:name="android.hardware.location.gps" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -6,17 +6,25 @@
|
|||||||
"cordova": {
|
"cordova": {
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"AndroidXEnabled": "true",
|
"AndroidXEnabled": "true",
|
||||||
"ScrollEnabled": "false",
|
|
||||||
"android-minSdkVersion": "22",
|
"android-minSdkVersion": "22",
|
||||||
"BackupWebStorage": "none",
|
"BackupWebStorage": "none"
|
||||||
"SplashMaintainAspectRatio": "true",
|
|
||||||
"FadeSplashScreenDuration": "300",
|
|
||||||
"SplashShowOnlyFirstTime": "false",
|
|
||||||
"SplashScreen": "screen",
|
|
||||||
"SplashScreenDelay": "3000"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
|
"SplashScreen": {
|
||||||
|
"launchShowDuration": 6000,
|
||||||
|
"launchAutoHide": false,
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"androidSplashResourceName": "splash",
|
||||||
|
"androidScaleType": "FIT_CENTER",
|
||||||
|
"showSpinner": false,
|
||||||
|
"androidSpinnerStyle": "large",
|
||||||
|
"iosSpinnerStyle": "small",
|
||||||
|
"spinnerColor": "#999999",
|
||||||
|
"splashFullScreen": false,
|
||||||
|
"splashImmersive": false,
|
||||||
|
"useDialog": false
|
||||||
|
},
|
||||||
"LocalNotifications": {}
|
"LocalNotifications": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
"pkg": "@capacitor/filesystem",
|
"pkg": "@capacitor/filesystem",
|
||||||
"classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin"
|
"classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pkg": "@capacitor/geolocation",
|
||||||
|
"classpath": "com.capacitorjs.plugins.geolocation.GeolocationPlugin"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor/haptics",
|
"pkg": "@capacitor/haptics",
|
||||||
"classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin"
|
"classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin"
|
||||||
@@ -35,6 +39,10 @@
|
|||||||
"pkg": "@capacitor/local-notifications",
|
"pkg": "@capacitor/local-notifications",
|
||||||
"classpath": "com.capacitorjs.plugins.localnotifications.LocalNotificationsPlugin"
|
"classpath": "com.capacitorjs.plugins.localnotifications.LocalNotificationsPlugin"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"pkg": "@capacitor/network",
|
||||||
|
"classpath": "com.capacitorjs.plugins.network.NetworkPlugin"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"pkg": "@capacitor/share",
|
"pkg": "@capacitor/share",
|
||||||
"classpath": "com.capacitorjs.plugins.share.SharePlugin"
|
"classpath": "com.capacitorjs.plugins.share.SharePlugin"
|
||||||
|
|||||||
@@ -6,75 +6,12 @@
|
|||||||
<param name="android-package" value="nl.xservices.plugins.Calendar"/>
|
<param name="android-package" value="nl.xservices.plugins.Calendar"/>
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
<feature name="Device">
|
<feature name="FileOpener2">
|
||||||
<param name="android-package" value="org.apache.cordova.device.Device"/>
|
<param name="android-package" value="io.github.pwlin.cordova.plugins.fileopener2.FileOpener2"/>
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Notification">
|
|
||||||
<param name="android-package" value="org.apache.cordova.dialogs.Notification"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Geolocation">
|
|
||||||
<param name="android-package" value="org.apache.cordova.geolocation.Geolocation"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="NetworkStatus">
|
|
||||||
<param name="android-package" value="org.apache.cordova.networkinformation.NetworkManager"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Whitelist">
|
|
||||||
<param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Location">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_Location"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Bluetooth">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_Bluetooth"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Wifi">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_Wifi"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Camera">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_Camera"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Notifications">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_Notifications"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_NFC">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_NFC"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_External_Storage">
|
|
||||||
<param name="android-package" value="cordova.plugins.Diagnostic_External_Storage"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
|
|
||||||
<preference name="AndroidXEnabled" value="true" />
|
<preference name="AndroidXEnabled" value="true" />
|
||||||
<preference name="ScrollEnabled" value="false" />
|
|
||||||
<preference name="android-minSdkVersion" value="22" />
|
<preference name="android-minSdkVersion" value="22" />
|
||||||
<preference name="BackupWebStorage" value="none" />
|
<preference name="BackupWebStorage" value="none" />
|
||||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
|
||||||
<preference name="FadeSplashScreenDuration" value="300" />
|
|
||||||
<preference name="SplashShowOnlyFirstTime" value="false" />
|
|
||||||
<preference name="SplashScreen" value="screen" />
|
|
||||||
<preference name="SplashScreenDelay" value="3000" />
|
|
||||||
</widget>
|
</widget>
|
||||||
@@ -20,6 +20,9 @@ project(':capacitor-dialog').projectDir = new File('../node_modules/@capacitor/d
|
|||||||
include ':capacitor-filesystem'
|
include ':capacitor-filesystem'
|
||||||
project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
|
project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
|
||||||
|
|
||||||
|
include ':capacitor-geolocation'
|
||||||
|
project(':capacitor-geolocation').projectDir = new File('../node_modules/@capacitor/geolocation/android')
|
||||||
|
|
||||||
include ':capacitor-haptics'
|
include ':capacitor-haptics'
|
||||||
project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')
|
project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')
|
||||||
|
|
||||||
@@ -29,6 +32,9 @@ project(':capacitor-keyboard').projectDir = new File('../node_modules/@capacitor
|
|||||||
include ':capacitor-local-notifications'
|
include ':capacitor-local-notifications'
|
||||||
project(':capacitor-local-notifications').projectDir = new File('../node_modules/@capacitor/local-notifications/android')
|
project(':capacitor-local-notifications').projectDir = new File('../node_modules/@capacitor/local-notifications/android')
|
||||||
|
|
||||||
|
include ':capacitor-network'
|
||||||
|
project(':capacitor-network').projectDir = new File('../node_modules/@capacitor/network/android')
|
||||||
|
|
||||||
include ':capacitor-share'
|
include ':capacitor-share'
|
||||||
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
|
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
|
||||||
|
|
||||||
|
|||||||
1
capacitor.config.json
Normal file
1
capacitor.config.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -8,17 +8,25 @@ const config: CapacitorConfig = {
|
|||||||
cordova: {
|
cordova: {
|
||||||
preferences: {
|
preferences: {
|
||||||
'AndroidXEnabled': 'true',
|
'AndroidXEnabled': 'true',
|
||||||
'ScrollEnabled': 'false',
|
|
||||||
'android-minSdkVersion': '22',
|
'android-minSdkVersion': '22',
|
||||||
'BackupWebStorage': 'none',
|
'BackupWebStorage': 'none',
|
||||||
'SplashMaintainAspectRatio': 'true',
|
|
||||||
'FadeSplashScreenDuration': '300',
|
|
||||||
'SplashShowOnlyFirstTime': 'false',
|
|
||||||
'SplashScreen': 'screen',
|
|
||||||
'SplashScreenDelay': '3000',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
|
SplashScreen: {
|
||||||
|
launchShowDuration: 6000,
|
||||||
|
launchAutoHide: false,
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
androidSplashResourceName: 'splash',
|
||||||
|
androidScaleType: 'FIT_CENTER',
|
||||||
|
showSpinner: false,
|
||||||
|
androidSpinnerStyle: 'large',
|
||||||
|
iosSpinnerStyle: 'small',
|
||||||
|
spinnerColor: '#999999',
|
||||||
|
splashFullScreen: false,
|
||||||
|
splashImmersive: false,
|
||||||
|
useDialog: false,
|
||||||
|
},
|
||||||
LocalNotifications: {
|
LocalNotifications: {
|
||||||
// TODO
|
// TODO
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -108,7 +108,6 @@
|
|||||||
504EC3011FED79650016851F /* Frameworks */,
|
504EC3011FED79650016851F /* Frameworks */,
|
||||||
504EC3021FED79650016851F /* Resources */,
|
504EC3021FED79650016851F /* Resources */,
|
||||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
||||||
0C3780443725062B779B937E /* [CP] Copy Pods Resources */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@@ -170,21 +169,6 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
0C3780443725062B779B937E /* [CP] Copy Pods Resources */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Copy Pods Resources";
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-resources.sh\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
|
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Scheme
|
|
||||||
LastUpgradeVersion = "1300"
|
|
||||||
version = "1.3">
|
|
||||||
<BuildAction
|
|
||||||
parallelizeBuildables = "YES"
|
|
||||||
buildImplicitDependencies = "YES">
|
|
||||||
<BuildActionEntries>
|
|
||||||
<BuildActionEntry
|
|
||||||
buildForTesting = "YES"
|
|
||||||
buildForRunning = "YES"
|
|
||||||
buildForProfiling = "YES"
|
|
||||||
buildForArchiving = "YES"
|
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "504EC3031FED79650016851F"
|
|
||||||
BuildableName = "App.app"
|
|
||||||
BlueprintName = "App"
|
|
||||||
ReferencedContainer = "container:App.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildActionEntry>
|
|
||||||
</BuildActionEntries>
|
|
||||||
</BuildAction>
|
|
||||||
<TestAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
</TestAction>
|
|
||||||
<LaunchAction
|
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
|
||||||
launchStyle = "0"
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
|
||||||
debugDocumentVersioning = "YES"
|
|
||||||
debugServiceExtension = "internal"
|
|
||||||
allowLocationSimulation = "YES">
|
|
||||||
<BuildableProductRunnable
|
|
||||||
runnableDebuggingMode = "0">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "504EC3031FED79650016851F"
|
|
||||||
BuildableName = "App.app"
|
|
||||||
BlueprintName = "App"
|
|
||||||
ReferencedContainer = "container:App.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildableProductRunnable>
|
|
||||||
</LaunchAction>
|
|
||||||
<ProfileAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
|
||||||
useCustomWorkingDirectory = "NO"
|
|
||||||
debugDocumentVersioning = "YES">
|
|
||||||
<BuildableProductRunnable
|
|
||||||
runnableDebuggingMode = "0">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "504EC3031FED79650016851F"
|
|
||||||
BuildableName = "App.app"
|
|
||||||
BlueprintName = "App"
|
|
||||||
ReferencedContainer = "container:App.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</BuildableProductRunnable>
|
|
||||||
</ProfileAction>
|
|
||||||
<AnalyzeAction
|
|
||||||
buildConfiguration = "Debug">
|
|
||||||
</AnalyzeAction>
|
|
||||||
<ArchiveAction
|
|
||||||
buildConfiguration = "Release"
|
|
||||||
revealArchiveInOrganizer = "YES">
|
|
||||||
</ArchiveAction>
|
|
||||||
</Scheme>
|
|
||||||
@@ -7,7 +7,9 @@
|
|||||||
<string>com.transistorsoft.fetch</string>
|
<string>com.transistorsoft.fetch</string>
|
||||||
</array>
|
</array>
|
||||||
<key>NSCalendarsUsageDescription</key>
|
<key>NSCalendarsUsageDescription</key>
|
||||||
<string>App uses calendar for schedule sync</string>
|
<string>Calendar access is needed to sync your schedule with the device</string>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>Location services are used to enable all map and search features</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
|
|||||||
@@ -6,20 +6,25 @@
|
|||||||
"cordova": {
|
"cordova": {
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"AndroidXEnabled": "true",
|
"AndroidXEnabled": "true",
|
||||||
"ScrollEnabled": "false",
|
|
||||||
"android-minSdkVersion": "22",
|
"android-minSdkVersion": "22",
|
||||||
"BackupWebStorage": "none",
|
"BackupWebStorage": "none"
|
||||||
"SplashMaintainAspectRatio": "true",
|
|
||||||
"FadeSplashScreenDuration": "300",
|
|
||||||
"SplashShowOnlyFirstTime": "false",
|
|
||||||
"SplashScreen": "screen",
|
|
||||||
"SplashScreenDelay": "3000"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"LocalNotifications": {}
|
"SplashScreen": {
|
||||||
|
"launchShowDuration": 6000,
|
||||||
|
"launchAutoHide": false,
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"androidSplashResourceName": "splash",
|
||||||
|
"androidScaleType": "FIT_CENTER",
|
||||||
|
"showSpinner": false,
|
||||||
|
"androidSpinnerStyle": "large",
|
||||||
|
"iosSpinnerStyle": "small",
|
||||||
|
"spinnerColor": "#999999",
|
||||||
|
"splashFullScreen": false,
|
||||||
|
"splashImmersive": false,
|
||||||
|
"useDialog": false
|
||||||
},
|
},
|
||||||
"server": {
|
"LocalNotifications": {}
|
||||||
"url": "http://141.2.95.77:8100"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,85 +6,12 @@
|
|||||||
<param name="ios-package" value="Calendar"/>
|
<param name="ios-package" value="Calendar"/>
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
<feature name="Device">
|
<feature name="FileOpener2">
|
||||||
<param name="ios-package" value="CDVDevice"/>
|
<param name="ios-package" value="FileOpener2"/>
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Notification">
|
|
||||||
<param name="ios-package" value="CDVNotification"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Geolocation">
|
|
||||||
<param name="ios-package" value="CDVLocation"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="NetworkStatus">
|
|
||||||
<param name="ios-package" value="CDVConnection"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic">
|
|
||||||
<param name="ios-package" value="Diagnostic"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Location">
|
|
||||||
<param name="ios-package" value="Diagnostic_Location"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Bluetooth">
|
|
||||||
<param name="ios-package" value="Diagnostic_Bluetooth"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Wifi">
|
|
||||||
<param name="ios-package" value="Diagnostic_Wifi"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Camera">
|
|
||||||
<param name="ios-package" value="Diagnostic_Camera"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Notifications">
|
|
||||||
<param name="ios-package" value="Diagnostic_Notifications"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Microphone">
|
|
||||||
<param name="ios-package" value="Diagnostic_Microphone"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Contacts">
|
|
||||||
<param name="ios-package" value="Diagnostic_Contacts"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Calendar">
|
|
||||||
<param name="ios-package" value="Diagnostic_Calendar"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Reminders">
|
|
||||||
<param name="ios-package" value="Diagnostic_Reminders"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
<feature name="Diagnostic_Motion">
|
|
||||||
<param name="ios-package" value="Diagnostic_Motion"/>
|
|
||||||
<param name="onload" value="true"/>
|
|
||||||
</feature>
|
</feature>
|
||||||
|
|
||||||
|
|
||||||
<preference name="AndroidXEnabled" value="true" />
|
<preference name="AndroidXEnabled" value="true" />
|
||||||
<preference name="ScrollEnabled" value="false" />
|
|
||||||
<preference name="android-minSdkVersion" value="22" />
|
<preference name="android-minSdkVersion" value="22" />
|
||||||
<preference name="BackupWebStorage" value="none" />
|
<preference name="BackupWebStorage" value="none" />
|
||||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
|
||||||
<preference name="FadeSplashScreenDuration" value="300" />
|
|
||||||
<preference name="SplashShowOnlyFirstTime" value="false" />
|
|
||||||
<preference name="SplashScreen" value="screen" />
|
|
||||||
<preference name="SplashScreenDelay" value="3000" />
|
|
||||||
</widget>
|
</widget>
|
||||||
@@ -15,9 +15,11 @@ def capacitor_pods
|
|||||||
pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device'
|
pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device'
|
||||||
pod 'CapacitorDialog', :path => '../../node_modules/@capacitor/dialog'
|
pod 'CapacitorDialog', :path => '../../node_modules/@capacitor/dialog'
|
||||||
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
||||||
|
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
|
||||||
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
||||||
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
|
pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
|
||||||
pod 'CapacitorLocalNotifications', :path => '../../node_modules/@capacitor/local-notifications'
|
pod 'CapacitorLocalNotifications', :path => '../../node_modules/@capacitor/local-notifications'
|
||||||
|
pod 'CapacitorNetwork', :path => '../../node_modules/@capacitor/network'
|
||||||
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
|
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
|
||||||
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
||||||
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
|
||||||
@@ -25,7 +27,6 @@ def capacitor_pods
|
|||||||
pod 'TransistorsoftCapacitorBackgroundFetch', :path => '../../node_modules/@transistorsoft/capacitor-background-fetch'
|
pod 'TransistorsoftCapacitorBackgroundFetch', :path => '../../node_modules/@transistorsoft/capacitor-background-fetch'
|
||||||
pod 'CapacitorSecureStoragePlugin', :path => '../../node_modules/capacitor-secure-storage-plugin'
|
pod 'CapacitorSecureStoragePlugin', :path => '../../node_modules/capacitor-secure-storage-plugin'
|
||||||
pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
|
pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
|
||||||
pod 'CordovaPluginsResources', :path => '../capacitor-cordova-ios-plugins'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'App' do
|
target 'App' do
|
||||||
|
|||||||
1082
package-lock.json
generated
1082
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
68
package.json
68
package.json
@@ -31,6 +31,7 @@
|
|||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/",
|
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/",
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
|
"postinstall": "npx jetify",
|
||||||
"postversion": "npm run changelog && npm run licenses",
|
"postversion": "npm run changelog && npm run licenses",
|
||||||
"pree2e": "webdriver-manager clean && webdriver-manager update --gecko false --versions.chrome $(google-chrome --product-version)",
|
"pree2e": "webdriver-manager clean && webdriver-manager update --gecko false --versions.chrome $(google-chrome --product-version)",
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
@@ -54,30 +55,26 @@
|
|||||||
"@angular/router": "12.2.13",
|
"@angular/router": "12.2.13",
|
||||||
"@asymmetrik/ngx-leaflet": "8.1.0",
|
"@asymmetrik/ngx-leaflet": "8.1.0",
|
||||||
"@asymmetrik/ngx-leaflet-markercluster": "5.0.1",
|
"@asymmetrik/ngx-leaflet-markercluster": "5.0.1",
|
||||||
"@awesome-cordova-plugins/calendar": "5.37.1",
|
"@awesome-cordova-plugins/calendar": "5.39.1",
|
||||||
"@awesome-cordova-plugins/core": "5.37.1",
|
"@awesome-cordova-plugins/core": "5.39.1",
|
||||||
"@capacitor-community/http": "1.4.1",
|
"@capacitor-community/http": "1.4.1",
|
||||||
"@capacitor/app": "1.0.6",
|
"@capacitor/app": "1.1.0",
|
||||||
"@capacitor/browser": "1.0.6",
|
"@capacitor/browser": "1.0.7",
|
||||||
"@capacitor/core": "3.3.1",
|
"@capacitor/core": "3.4.1",
|
||||||
"@capacitor/device": "1.1.0",
|
"@capacitor/device": "1.1.2",
|
||||||
"@capacitor/dialog": "1.0.6",
|
"@capacitor/dialog": "1.0.7",
|
||||||
"@capacitor/filesystem": "1.0.6",
|
"@capacitor/filesystem": "1.1.0",
|
||||||
"@capacitor/haptics": "1.1.3",
|
"@capacitor/geolocation": "1.3.1",
|
||||||
"@capacitor/keyboard": "1.1.3",
|
"@capacitor/haptics": "1.1.4",
|
||||||
"@capacitor/local-notifications": "1.0.9",
|
"@capacitor/keyboard": "1.2.2",
|
||||||
"@capacitor/share": "1.0.7",
|
"@capacitor/local-notifications": "1.1.0",
|
||||||
"@capacitor/splash-screen": "1.1.6",
|
"@capacitor/network": "1.0.7",
|
||||||
"@capacitor/status-bar": "1.0.6",
|
"@capacitor/share": "1.1.1",
|
||||||
"@capacitor/storage": "1.2.3",
|
"@capacitor/splash-screen": "1.2.2",
|
||||||
|
"@capacitor/status-bar": "1.0.8",
|
||||||
|
"@capacitor/storage": "1.2.4",
|
||||||
"@ionic-native/core": "5.36.0",
|
"@ionic-native/core": "5.36.0",
|
||||||
"@ionic-native/diagnostic": "5.36.0",
|
|
||||||
"@ionic-native/dialogs": "5.36.0",
|
|
||||||
"@ionic-native/file": "5.36.0",
|
|
||||||
"@ionic-native/file-opener": "5.36.0",
|
"@ionic-native/file-opener": "5.36.0",
|
||||||
"@ionic-native/file-transfer": "5.36.0",
|
|
||||||
"@ionic-native/geolocation": "5.36.0",
|
|
||||||
"@ionic-native/network": "5.36.0",
|
|
||||||
"@ionic/angular": "5.7.0",
|
"@ionic/angular": "5.7.0",
|
||||||
"@ionic/storage-angular": "3.0.6",
|
"@ionic/storage-angular": "3.0.6",
|
||||||
"@ngx-translate/core": "13.0.0",
|
"@ngx-translate/core": "13.0.0",
|
||||||
@@ -88,12 +85,7 @@
|
|||||||
"@transistorsoft/capacitor-background-fetch": "0.0.6",
|
"@transistorsoft/capacitor-background-fetch": "0.0.6",
|
||||||
"capacitor-secure-storage-plugin": "0.6.2",
|
"capacitor-secure-storage-plugin": "0.6.2",
|
||||||
"cordova-plugin-calendar": "5.1.5",
|
"cordova-plugin-calendar": "5.1.5",
|
||||||
"cordova-plugin-device": "2.0.3",
|
"cordova-plugin-file-opener2": "3.0.5",
|
||||||
"cordova-plugin-dialogs": "2.0.2",
|
|
||||||
"cordova-plugin-geolocation": "4.1.0",
|
|
||||||
"cordova-plugin-network-information": "2.0.2",
|
|
||||||
"cordova-plugin-whitelist": "1.3.4",
|
|
||||||
"cordova.plugins.diagnostic": "6.1.0",
|
|
||||||
"core-js": "2.6.5",
|
"core-js": "2.6.5",
|
||||||
"deepmerge": "3.3.0",
|
"deepmerge": "3.3.0",
|
||||||
"form-data": "2.5.0",
|
"form-data": "2.5.0",
|
||||||
@@ -128,9 +120,9 @@
|
|||||||
"@angular/compiler": "12.2.13",
|
"@angular/compiler": "12.2.13",
|
||||||
"@angular/compiler-cli": "12.2.13",
|
"@angular/compiler-cli": "12.2.13",
|
||||||
"@angular/language-service": "12.2.13",
|
"@angular/language-service": "12.2.13",
|
||||||
"@capacitor/android": "3.4.0",
|
"@capacitor/android": "3.4.1",
|
||||||
"@capacitor/cli": "3.3.2",
|
"@capacitor/cli": "3.4.1",
|
||||||
"@capacitor/ios": "3.3.2",
|
"@capacitor/ios": "3.4.1",
|
||||||
"@compodoc/compodoc": "1.1.14",
|
"@compodoc/compodoc": "1.1.14",
|
||||||
"@ionic/angular-toolkit": "4.0.0",
|
"@ionic/angular-toolkit": "4.0.0",
|
||||||
"@ionic/cli": "6.18.1",
|
"@ionic/cli": "6.18.1",
|
||||||
@@ -155,6 +147,7 @@
|
|||||||
"is-docker": "1.1.0",
|
"is-docker": "1.1.0",
|
||||||
"jasmine-core": "3.9.0",
|
"jasmine-core": "3.9.0",
|
||||||
"jasmine-spec-reporter": "7.0.0",
|
"jasmine-spec-reporter": "7.0.0",
|
||||||
|
"jetifier": "2.0.0",
|
||||||
"karma": "6.3.16",
|
"karma": "6.3.16",
|
||||||
"karma-chrome-launcher": "3.1.0",
|
"karma-chrome-launcher": "3.1.0",
|
||||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||||
@@ -169,20 +162,7 @@
|
|||||||
"typescript": "4.3.5"
|
"typescript": "4.3.5"
|
||||||
},
|
},
|
||||||
"cordova": {
|
"cordova": {
|
||||||
"plugins": {
|
"plugins": {},
|
||||||
"cordova-plugin-whitelist": {},
|
|
||||||
"cordova-plugin-file-transfer": {
|
|
||||||
"ANDROID_SUPPORT_V4_VERSION": "27.+"
|
|
||||||
},
|
|
||||||
"cordova-plugin-device": {},
|
|
||||||
"cordova-plugin-geolocation": {
|
|
||||||
"GEOLOCATION_USAGE_DESCRIPTION": "The app will use your location to provide features for navigation or distances information.",
|
|
||||||
"GPS_REQUIRED": "true"
|
|
||||||
},
|
|
||||||
"cordova.plugins.diagnostic": {
|
|
||||||
"ANDROIDX_VERSION": "1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"ios",
|
"ios",
|
||||||
"browser",
|
"browser",
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
import {AfterContentInit, Component, NgZone} from '@angular/core';
|
import {AfterContentInit, Component, NgZone} from '@angular/core';
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {App, URLOpenListenerEvent} from '@capacitor/app';
|
import {App, URLOpenListenerEvent} from '@capacitor/app';
|
||||||
import {SplashScreen} from '@capacitor/splash-screen';
|
|
||||||
import {Platform, ToastController} from '@ionic/angular';
|
import {Platform, ToastController} from '@ionic/angular';
|
||||||
import {SettingsProvider} from './modules/settings/settings.provider';
|
import {SettingsProvider} from './modules/settings/settings.provider';
|
||||||
import {AuthHelperService} from './modules/auth/auth-helper.service';
|
import {AuthHelperService} from './modules/auth/auth-helper.service';
|
||||||
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
|
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
|
||||||
import {environment} from '../environments/environment';
|
import {environment} from '../environments/environment';
|
||||||
|
import {StatusBar, Style} from '@capacitor/status-bar';
|
||||||
|
import {Capacitor} from '@capacitor/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
@@ -86,7 +87,9 @@ export class AppComponent implements AfterContentInit {
|
|||||||
});
|
});
|
||||||
this.platform.ready().then(async () => {
|
this.platform.ready().then(async () => {
|
||||||
await this.authInit();
|
await this.authInit();
|
||||||
await SplashScreen.hide();
|
if (Capacitor.isNativePlatform()) {
|
||||||
|
await StatusBar.setStyle({style: Style.Dark});
|
||||||
|
}
|
||||||
|
|
||||||
// set order of categories in settings
|
// set order of categories in settings
|
||||||
this.settingsProvider.setCategoriesOrder([
|
this.settingsProvider.setCategoriesOrder([
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import localeDe from '@angular/common/locales/de';
|
|||||||
import {APP_INITIALIZER, NgModule} from '@angular/core';
|
import {APP_INITIALIZER, NgModule} from '@angular/core';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {RouteReuseStrategy} from '@angular/router';
|
import {RouteReuseStrategy} from '@angular/router';
|
||||||
import {Diagnostic} from '@ionic-native/diagnostic/ngx';
|
|
||||||
import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular';
|
import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular';
|
||||||
import {
|
import {
|
||||||
TranslateLoader,
|
TranslateLoader,
|
||||||
@@ -169,7 +168,6 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
Diagnostic,
|
|
||||||
{
|
{
|
||||||
provide: RouteReuseStrategy,
|
provide: RouteReuseStrategy,
|
||||||
useClass: IonicRouteStrategy,
|
useClass: IonicRouteStrategy,
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import {
|
|||||||
ScheduleProvider,
|
ScheduleProvider,
|
||||||
} from '../../calendar/schedule.provider';
|
} from '../../calendar/schedule.provider';
|
||||||
import {SCDateSeries, SCThingType, SCUuid} from '@openstapps/core';
|
import {SCDateSeries, SCThingType, SCUuid} from '@openstapps/core';
|
||||||
import {Device} from '@capacitor/device';
|
|
||||||
import {LocalNotifications} from '@capacitor/local-notifications';
|
import {LocalNotifications} from '@capacitor/local-notifications';
|
||||||
import {ThingTranslateService} from '../../../translation/thing-translate.service';
|
import {ThingTranslateService} from '../../../translation/thing-translate.service';
|
||||||
import {DateFormatPipe, DurationPipe} from 'ngx-moment';
|
import {DateFormatPipe, DurationPipe} from 'ngx-moment';
|
||||||
@@ -39,6 +38,7 @@ import {
|
|||||||
CALENDAR_SYNC_SETTINGS_KEY,
|
CALENDAR_SYNC_SETTINGS_KEY,
|
||||||
} from '../../settings/page/calendar-sync-settings-keys';
|
} from '../../settings/page/calendar-sync-settings-keys';
|
||||||
import {filter} from 'rxjs/operators';
|
import {filter} from 'rxjs/operators';
|
||||||
|
import {Capacitor} from '@capacitor/core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ScheduleSyncService implements OnDestroy {
|
export class ScheduleSyncService implements OnDestroy {
|
||||||
@@ -79,7 +79,7 @@ export class ScheduleSyncService implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async enable() {
|
async enable() {
|
||||||
if ((await Device.getInfo()).platform === 'web') return;
|
if (!Capacitor.isNativePlatform()) return;
|
||||||
|
|
||||||
await BackgroundFetch.stop();
|
await BackgroundFetch.stop();
|
||||||
|
|
||||||
@@ -189,9 +189,7 @@ export class ScheduleSyncService implements OnDestroy {
|
|||||||
);
|
);
|
||||||
if (differences.length === 0) return;
|
if (differences.length === 0) return;
|
||||||
|
|
||||||
if ((await Device.getInfo()).platform === 'web') {
|
if (Capacitor.isNativePlatform()) {
|
||||||
// TODO: Implement web notification
|
|
||||||
} else {
|
|
||||||
await LocalNotifications.schedule({
|
await LocalNotifications.schedule({
|
||||||
notifications: differences.map(it => ({
|
notifications: differences.map(it => ({
|
||||||
title: it.new.event.name,
|
title: it.new.event.name,
|
||||||
@@ -199,6 +197,8 @@ export class ScheduleSyncService implements OnDestroy {
|
|||||||
id: hashStringToInt(it.new.uid),
|
id: hashStringToInt(it.new.uid),
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// TODO: Implement desktop notifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {CommonModule} from '@angular/common';
|
|||||||
import {HttpClientModule} from '@angular/common/http';
|
import {HttpClientModule} from '@angular/common/http';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {Network} from '@ionic-native/network/ngx';
|
|
||||||
import {IonicModule} from '@ionic/angular';
|
import {IonicModule} from '@ionic/angular';
|
||||||
import {TranslateModule} from '@ngx-translate/core';
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
import {MarkdownModule} from 'ngx-markdown';
|
import {MarkdownModule} from 'ngx-markdown';
|
||||||
@@ -79,7 +78,6 @@ import {SemesterListItemComponent} from './types/semester/semester-list-item.com
|
|||||||
import {VideoListItemComponent} from './types/video/video-list-item.component';
|
import {VideoListItemComponent} from './types/video/video-list-item.component';
|
||||||
import {OriginInListComponent} from './elements/origin-in-list.component';
|
import {OriginInListComponent} from './elements/origin-in-list.component';
|
||||||
import {CoordinatedSearchProvider} from './coordinated-search.provider';
|
import {CoordinatedSearchProvider} from './coordinated-search.provider';
|
||||||
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
|
||||||
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
||||||
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
||||||
import {TitleCardComponent} from './elements/title-card.component';
|
import {TitleCardComponent} from './elements/title-card.component';
|
||||||
@@ -166,7 +164,6 @@ import {CalendarService} from '../calendar/calendar.service';
|
|||||||
DataProvider,
|
DataProvider,
|
||||||
DataFacetsProvider,
|
DataFacetsProvider,
|
||||||
Geolocation,
|
Geolocation,
|
||||||
Network,
|
|
||||||
ScheduleProvider,
|
ScheduleProvider,
|
||||||
StAppsWebHttpClient,
|
StAppsWebHttpClient,
|
||||||
CalendarService,
|
CalendarService,
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {Network} from '@ionic-native/network/ngx';
|
|
||||||
import {IonRefresher} from '@ionic/angular';
|
import {IonRefresher} from '@ionic/angular';
|
||||||
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
|
import {LangChangeEvent, TranslateService} from '@ngx-translate/core';
|
||||||
import {
|
import {
|
||||||
@@ -26,6 +25,7 @@ import {
|
|||||||
import {DataProvider, DataScope} from '../data.provider';
|
import {DataProvider, DataScope} from '../data.provider';
|
||||||
import {FavoritesService} from '../../favorites/favorites.service';
|
import {FavoritesService} from '../../favorites/favorites.service';
|
||||||
import {take} from 'rxjs/operators';
|
import {take} from 'rxjs/operators';
|
||||||
|
import {Network} from '@capacitor/network';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Component to display an SCThing detailed
|
* A Component to display an SCThing detailed
|
||||||
@@ -48,6 +48,11 @@ export class DataDetailComponent {
|
|||||||
*/
|
*/
|
||||||
language: SCLanguageCode;
|
language: SCLanguageCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicating wether internet connectivity is given or not
|
||||||
|
*/
|
||||||
|
isDisconnected: Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type guard for SCSavableThing
|
* Type guard for SCSavableThing
|
||||||
*/
|
*/
|
||||||
@@ -61,14 +66,12 @@ export class DataDetailComponent {
|
|||||||
*
|
*
|
||||||
* @param route the route the page was accessed from
|
* @param route the route the page was accessed from
|
||||||
* @param dataProvider the data provider
|
* @param dataProvider the data provider
|
||||||
* @param network the network provider
|
|
||||||
* @param favoritesService the favorites provider
|
* @param favoritesService the favorites provider
|
||||||
* @param translateService he translate provider
|
* @param translateService he translate provider
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly route: ActivatedRoute,
|
protected readonly route: ActivatedRoute,
|
||||||
private readonly dataProvider: DataProvider,
|
private readonly dataProvider: DataProvider,
|
||||||
protected readonly network: Network,
|
|
||||||
private readonly favoritesService: FavoritesService,
|
private readonly favoritesService: FavoritesService,
|
||||||
translateService: TranslateService,
|
translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
@@ -76,6 +79,11 @@ export class DataDetailComponent {
|
|||||||
translateService.onLangChange.subscribe((event: LangChangeEvent) => {
|
translateService.onLangChange.subscribe((event: LangChangeEvent) => {
|
||||||
this.language = event.lang as SCLanguageCode;
|
this.language = event.lang as SCLanguageCode;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.isDisconnected = new Promise(async resolve => {
|
||||||
|
const isConnected = (await Network.getStatus()).connected;
|
||||||
|
resolve(isConnected);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,13 +101,6 @@ export class DataDetailComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we have internet
|
|
||||||
*/
|
|
||||||
isDisconnected(): boolean {
|
|
||||||
return this.network.type === this.network.Connection.NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize
|
* Initialize
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</ion-refresher-content>
|
</ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<div [ngSwitch]="true">
|
<div [ngSwitch]="true">
|
||||||
<ng-container *ngSwitchCase="!item && isDisconnected()">
|
<ng-container *ngSwitchCase="!item && (isDisconnected | async)">
|
||||||
<div class="centeredMessageContainer">
|
<div class="centeredMessageContainer">
|
||||||
<ion-icon name="no-connection"> </ion-icon>
|
<ion-icon name="no-connection"> </ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ describe('DataListComponent', () => {
|
|||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
configProviderMock = jasmine.createSpyObj('ConfigProvider', {
|
configProviderMock = jasmine.createSpyObj('ConfigProvider', {
|
||||||
getValue: () => Promise.resolve({lat: 123, lng: 123}),
|
getValue: () => {
|
||||||
|
return {lat: 123, lng: 123};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [DataListComponent],
|
declarations: [DataListComponent],
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {Observable, of} from 'rxjs';
|
|||||||
import {StorageProvider} from '../../storage/storage.provider';
|
import {StorageProvider} from '../../storage/storage.provider';
|
||||||
import {DaiaDataProvider} from '../daia-data.provider';
|
import {DaiaDataProvider} from '../daia-data.provider';
|
||||||
import {LoggerConfig, LoggerModule, NGXLogger} from 'ngx-logger';
|
import {LoggerConfig, LoggerModule, NGXLogger} from 'ngx-logger';
|
||||||
|
import {ConfigProvider} from '../../config/config.provider';
|
||||||
|
|
||||||
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
|
const translations: any = {data: {detail: {TITLE: 'Foo'}}};
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ describe('DaiaAvailabilityComponent', () => {
|
|||||||
let refresher: IonRefresher;
|
let refresher: IonRefresher;
|
||||||
const sampleThing = sampleThingsMap.book[0];
|
const sampleThing = sampleThingsMap.book[0];
|
||||||
let translateService: TranslateService;
|
let translateService: TranslateService;
|
||||||
|
let configProviderMock: jasmine.SpyObj<ConfigProvider>;
|
||||||
|
|
||||||
// @Component({ selector: 'stapps-data-list-item', template: '' })
|
// @Component({ selector: 'stapps-data-list-item', template: '' })
|
||||||
// class DataListItemComponent {
|
// class DataListItemComponent {
|
||||||
@@ -72,6 +74,11 @@ describe('DaiaAvailabilityComponent', () => {
|
|||||||
|
|
||||||
beforeEach(
|
beforeEach(
|
||||||
waitForAsync(() => {
|
waitForAsync(() => {
|
||||||
|
configProviderMock = jasmine.createSpyObj('ConfigProvider', [
|
||||||
|
'init',
|
||||||
|
'getValue',
|
||||||
|
'getAnyValue',
|
||||||
|
]);
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forRoot([], {relativeLinkResolution: 'legacy'}),
|
RouterModule.forRoot([], {relativeLinkResolution: 'legacy'}),
|
||||||
@@ -91,6 +98,10 @@ describe('DaiaAvailabilityComponent', () => {
|
|||||||
provide: StorageProvider,
|
provide: StorageProvider,
|
||||||
useValue: storageProviderSpy,
|
useValue: storageProviderSpy,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: ConfigProvider,
|
||||||
|
useValue: configProviderMock,
|
||||||
|
},
|
||||||
NGXLogger,
|
NGXLogger,
|
||||||
LoggerConfig,
|
LoggerConfig,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {Network} from '@ionic-native/network/ngx';
|
|
||||||
import {TranslateService} from '@ngx-translate/core';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import {SCUuid} from '@openstapps/core';
|
import {SCUuid} from '@openstapps/core';
|
||||||
import {FavoritesService} from '../../favorites/favorites.service';
|
import {FavoritesService} from '../../favorites/favorites.service';
|
||||||
@@ -41,7 +40,6 @@ export class DaiaAvailabilityComponent
|
|||||||
*
|
*
|
||||||
* @param route the route the page was accessed from
|
* @param route the route the page was accessed from
|
||||||
* @param dataProvider the data provider
|
* @param dataProvider the data provider
|
||||||
* @param network the network provider
|
|
||||||
* @param favoritesService the favorites provider
|
* @param favoritesService the favorites provider
|
||||||
* @param translateService he translate provider
|
* @param translateService he translate provider
|
||||||
* @param daiaDataProvider DaiaDataProvider
|
* @param daiaDataProvider DaiaDataProvider
|
||||||
@@ -49,19 +47,11 @@ export class DaiaAvailabilityComponent
|
|||||||
constructor(
|
constructor(
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
dataProvider: DataProvider,
|
dataProvider: DataProvider,
|
||||||
network: Network,
|
|
||||||
favoritesService: FavoritesService,
|
favoritesService: FavoritesService,
|
||||||
translateService: TranslateService,
|
translateService: TranslateService,
|
||||||
private daiaDataProvider: DaiaDataProvider,
|
private daiaDataProvider: DaiaDataProvider,
|
||||||
) {
|
) {
|
||||||
super(route, dataProvider, network, favoritesService, translateService);
|
super(route, dataProvider, favoritesService, translateService);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we have internet
|
|
||||||
*/
|
|
||||||
isDisconnected(): boolean {
|
|
||||||
return this.network.type === this.network.Connection.NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018, 2019 StApps
|
* Copyright (C) 2018-2022 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {Network} from '@ionic-native/network/ngx';
|
|
||||||
import {TranslateService} from '@ngx-translate/core';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import {SCUuid} from '@openstapps/core';
|
import {SCUuid} from '@openstapps/core';
|
||||||
import {HebisDataProvider} from '../hebis-data.provider';
|
import {HebisDataProvider} from '../hebis-data.provider';
|
||||||
@@ -38,7 +37,6 @@ export class HebisDetailComponent extends DataDetailComponent {
|
|||||||
*
|
*
|
||||||
* @param route the route the page was accessed from
|
* @param route the route the page was accessed from
|
||||||
* @param dataProvider the data provider
|
* @param dataProvider the data provider
|
||||||
* @param network the network provider
|
|
||||||
* @param favoritesService the favorites provider
|
* @param favoritesService the favorites provider
|
||||||
* @param translateService he translate provider
|
* @param translateService he translate provider
|
||||||
* @param hebisDataProvider HebisDataProvider
|
* @param hebisDataProvider HebisDataProvider
|
||||||
@@ -46,19 +44,11 @@ export class HebisDetailComponent extends DataDetailComponent {
|
|||||||
constructor(
|
constructor(
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
dataProvider: DataProvider,
|
dataProvider: DataProvider,
|
||||||
network: Network,
|
|
||||||
favoritesService: FavoritesService,
|
favoritesService: FavoritesService,
|
||||||
translateService: TranslateService,
|
translateService: TranslateService,
|
||||||
private hebisDataProvider: HebisDataProvider,
|
private hebisDataProvider: HebisDataProvider,
|
||||||
) {
|
) {
|
||||||
super(route, dataProvider, network, favoritesService, translateService);
|
super(route, dataProvider, favoritesService, translateService);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we have internet
|
|
||||||
*/
|
|
||||||
isDisconnected(): boolean {
|
|
||||||
return this.network.type === this.network.Connection.NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</ion-refresher-content>
|
</ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<div [ngSwitch]="true">
|
<div [ngSwitch]="true">
|
||||||
<ng-container *ngSwitchCase="!item && isDisconnected()">
|
<ng-container *ngSwitchCase="!item && isDisconnected | async">
|
||||||
<div class="notFoundContainer">
|
<div class="notFoundContainer">
|
||||||
<ion-icon name="no-connection"> </ion-icon>
|
<ion-icon name="no-connection"> </ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {CommonModule} from '@angular/common';
|
|||||||
import {HttpClientModule} from '@angular/common/http';
|
import {HttpClientModule} from '@angular/common/http';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {Network} from '@ionic-native/network/ngx';
|
|
||||||
import {IonicModule} from '@ionic/angular';
|
import {IonicModule} from '@ionic/angular';
|
||||||
import {TranslateModule} from '@ngx-translate/core';
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
import {MarkdownModule} from 'ngx-markdown';
|
import {MarkdownModule} from 'ngx-markdown';
|
||||||
@@ -80,12 +79,7 @@ import {DaiaAvailabilityComponent} from './daia-availability/daia-availability.c
|
|||||||
TranslateModule.forChild(),
|
TranslateModule.forChild(),
|
||||||
ThingTranslateModule.forChild(),
|
ThingTranslateModule.forChild(),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [HebisDataProvider, DaiaDataProvider, StAppsWebHttpClient],
|
||||||
HebisDataProvider,
|
|
||||||
DaiaDataProvider,
|
|
||||||
Network,
|
|
||||||
StAppsWebHttpClient,
|
|
||||||
],
|
|
||||||
exports: [
|
exports: [
|
||||||
HebisSearchPageComponent,
|
HebisSearchPageComponent,
|
||||||
HebisDetailComponent,
|
HebisDetailComponent,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {FormsModule} from '@angular/forms';
|
|||||||
import {RouterModule, Routes} from '@angular/router';
|
import {RouterModule, Routes} from '@angular/router';
|
||||||
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
||||||
import {LeafletMarkerClusterModule} from '@asymmetrik/ngx-leaflet-markercluster';
|
import {LeafletMarkerClusterModule} from '@asymmetrik/ngx-leaflet-markercluster';
|
||||||
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
|
||||||
import {IonicModule} from '@ionic/angular';
|
import {IonicModule} from '@ionic/angular';
|
||||||
import {TranslateModule} from '@ngx-translate/core';
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
import {Polygon} from 'geojson';
|
import {Polygon} from 'geojson';
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
|
|
||||||
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
|
||||||
import {Diagnostic} from '@ionic-native/diagnostic/ngx';
|
|
||||||
import {MapProvider} from './map.provider';
|
import {MapProvider} from './map.provider';
|
||||||
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||||
import {HttpClientModule} from '@angular/common/http';
|
import {HttpClientModule} from '@angular/common/http';
|
||||||
@@ -39,8 +37,6 @@ describe('MapProvider', () => {
|
|||||||
provide: ConfigProvider,
|
provide: ConfigProvider,
|
||||||
useValue: configProvider,
|
useValue: configProvider,
|
||||||
},
|
},
|
||||||
Geolocation,
|
|
||||||
Diagnostic,
|
|
||||||
StAppsWebHttpClient,
|
StAppsWebHttpClient,
|
||||||
StorageProvider,
|
StorageProvider,
|
||||||
NGXLogger,
|
NGXLogger,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
ViewChild,
|
ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
import {AlertController, ModalController, Platform} from '@ionic/angular';
|
import {AlertController, ModalController} from '@ionic/angular';
|
||||||
import {TranslateService} from '@ngx-translate/core';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import {
|
import {
|
||||||
SCBuilding,
|
SCBuilding,
|
||||||
@@ -43,13 +43,11 @@ import {Subscription} from 'rxjs';
|
|||||||
import {DataRoutingService} from '../../data/data-routing.service';
|
import {DataRoutingService} from '../../data/data-routing.service';
|
||||||
import {ContextMenuService} from '../../menu/context/context-menu.service';
|
import {ContextMenuService} from '../../menu/context/context-menu.service';
|
||||||
import {MapProvider} from '../map.provider';
|
import {MapProvider} from '../map.provider';
|
||||||
import {
|
import {MapPosition, PositionService} from '../position.service';
|
||||||
LocationStatus,
|
|
||||||
MapPosition,
|
|
||||||
PositionService,
|
|
||||||
} from '../position.service';
|
|
||||||
import {MapListModalComponent} from './modals/map-list-modal.component';
|
import {MapListModalComponent} from './modals/map-list-modal.component';
|
||||||
import {MapSingleModalComponent} from './modals/map-single-modal.component';
|
import {MapSingleModalComponent} from './modals/map-single-modal.component';
|
||||||
|
import {Geolocation, PermissionStatus} from '@capacitor/geolocation';
|
||||||
|
import {Capacitor} from '@capacitor/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main page of the map
|
* The main page of the map
|
||||||
@@ -88,7 +86,7 @@ export class MapPageComponent {
|
|||||||
/**
|
/**
|
||||||
* Location settings on the user's device
|
* Location settings on the user's device
|
||||||
*/
|
*/
|
||||||
locationStatus: LocationStatus = {enabled: undefined, allowed: undefined};
|
locationStatus?: PermissionStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The leaflet map
|
* The leaflet map
|
||||||
@@ -160,7 +158,6 @@ export class MapPageComponent {
|
|||||||
private modalController: ModalController,
|
private modalController: ModalController,
|
||||||
private dataRoutingService: DataRoutingService,
|
private dataRoutingService: DataRoutingService,
|
||||||
private positionService: PositionService,
|
private positionService: PositionService,
|
||||||
private platform: Platform,
|
|
||||||
) {
|
) {
|
||||||
// initialize the options
|
// initialize the options
|
||||||
this.options = {
|
this.options = {
|
||||||
@@ -293,10 +290,8 @@ export class MapPageComponent {
|
|||||||
30,
|
30,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
error: error => {
|
error: async _error => {
|
||||||
if (error.code === 1) {
|
this.locationStatus = await Geolocation.checkPermissions();
|
||||||
this.locationStatus.allowed = false;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line unicorn/no-null
|
// eslint-disable-next-line unicorn/no-null
|
||||||
this.position = null;
|
this.position = null;
|
||||||
},
|
},
|
||||||
@@ -304,9 +299,7 @@ export class MapPageComponent {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// get detailed location status (diagnostics only supports devices)
|
// get detailed location status (diagnostics only supports devices)
|
||||||
if (this.platform.is('cordova')) {
|
this.locationStatus = await Geolocation.checkPermissions();
|
||||||
this.locationStatus = await this.positionService.getLocationStatus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,6 +353,10 @@ export class MapPageComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.locationStatus = await (!Capacitor.isNativePlatform()
|
||||||
|
? Geolocation.checkPermissions()
|
||||||
|
: Geolocation.requestPermissions());
|
||||||
|
|
||||||
this.translateService
|
this.translateService
|
||||||
.get(['map.page.geolocation', 'app.errors.UNKNOWN'])
|
.get(['map.page.geolocation', 'app.errors.UNKNOWN'])
|
||||||
.subscribe(async translations => {
|
.subscribe(async translations => {
|
||||||
@@ -367,16 +364,15 @@ export class MapPageComponent {
|
|||||||
translations['map.page.geolocation'],
|
translations['map.page.geolocation'],
|
||||||
translations['app.errors.UNKNOWN'],
|
translations['app.errors.UNKNOWN'],
|
||||||
];
|
];
|
||||||
const {enabled, allowed} = this.locationStatus;
|
|
||||||
await (
|
await (
|
||||||
await this.alertController.create({
|
await this.alertController.create({
|
||||||
header: location.TITLE,
|
header: location.TITLE,
|
||||||
subHeader: location.SUBTITLE,
|
subHeader: location.SUBTITLE,
|
||||||
message: `${
|
message: `${
|
||||||
enabled === false
|
this.locationStatus?.location === 'denied'
|
||||||
? location.NOT_ENABLED
|
|
||||||
: allowed === false
|
|
||||||
? location.NOT_ALLOWED
|
? location.NOT_ALLOWED
|
||||||
|
: this.locationStatus?.location !== 'granted'
|
||||||
|
? location.NOT_ENABLED
|
||||||
: unknownError
|
: unknownError
|
||||||
}.`,
|
}.`,
|
||||||
buttons: ['OK'],
|
buttons: ['OK'],
|
||||||
|
|||||||
@@ -14,12 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
import {MapModule} from './map.module';
|
import {MapModule} from './map.module';
|
||||||
import {Geolocation, Geoposition} from '@ionic-native/geolocation/ngx';
|
|
||||||
import {defer} from 'rxjs';
|
|
||||||
import {HttpClientModule} from '@angular/common/http';
|
import {HttpClientModule} from '@angular/common/http';
|
||||||
import {StorageModule} from '../storage/storage.module';
|
import {StorageModule} from '../storage/storage.module';
|
||||||
import {MapPosition, PositionService} from './position.service';
|
import {MapPosition, PositionService} from './position.service';
|
||||||
import {Diagnostic} from '@ionic-native/diagnostic/ngx';
|
|
||||||
import {ConfigProvider} from '../config/config.provider';
|
import {ConfigProvider} from '../config/config.provider';
|
||||||
import {
|
import {
|
||||||
LoggerConfig,
|
LoggerConfig,
|
||||||
@@ -27,24 +24,18 @@ import {
|
|||||||
NGXLogger,
|
NGXLogger,
|
||||||
NGXMapperService,
|
NGXMapperService,
|
||||||
} from 'ngx-logger';
|
} from 'ngx-logger';
|
||||||
|
import {Geolocation, Position} from '@capacitor/geolocation';
|
||||||
/**
|
|
||||||
* For faking a promise resolve
|
|
||||||
*/
|
|
||||||
function fakeAsyncResponse<T>(data: T) {
|
|
||||||
return defer(() => Promise.resolve(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('PositionService', () => {
|
describe('PositionService', () => {
|
||||||
let geolocation: Geolocation;
|
|
||||||
let positionService: PositionService;
|
let positionService: PositionService;
|
||||||
|
let configProviderMock: jasmine.SpyObj<ConfigProvider>;
|
||||||
|
|
||||||
const sampleMapPosition: MapPosition = {
|
const sampleMapPosition: MapPosition = {
|
||||||
heading: 123,
|
heading: 123,
|
||||||
latitude: 34.12,
|
latitude: 34.12,
|
||||||
longitude: 12.34,
|
longitude: 12.34,
|
||||||
};
|
};
|
||||||
const samplePosition: Geoposition = {
|
const samplePosition: Position = {
|
||||||
coords: {
|
coords: {
|
||||||
...sampleMapPosition,
|
...sampleMapPosition,
|
||||||
accuracy: 1,
|
accuracy: 1,
|
||||||
@@ -53,44 +44,44 @@ describe('PositionService', () => {
|
|||||||
speed: 1,
|
speed: 1,
|
||||||
},
|
},
|
||||||
timestamp: 1_565_275_805_901,
|
timestamp: 1_565_275_805_901,
|
||||||
} as Geoposition;
|
} as Position;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const configProvider = {
|
configProviderMock = jasmine.createSpyObj('ConfigProvider', {
|
||||||
getValue: () => {
|
getValue: () => {
|
||||||
Promise.resolve();
|
return;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [MapModule, HttpClientModule, StorageModule, LoggerModule],
|
imports: [MapModule, HttpClientModule, StorageModule, LoggerModule],
|
||||||
providers: [
|
providers: [
|
||||||
Geolocation,
|
|
||||||
Diagnostic,
|
|
||||||
LoggerConfig,
|
LoggerConfig,
|
||||||
NGXLogger,
|
NGXLogger,
|
||||||
NGXMapperService,
|
NGXMapperService,
|
||||||
{
|
{
|
||||||
provider: ConfigProvider,
|
provider: ConfigProvider,
|
||||||
useValue: configProvider,
|
useValue: configProviderMock,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
positionService = TestBed.inject(PositionService);
|
positionService = TestBed.inject(PositionService);
|
||||||
geolocation = TestBed.inject(Geolocation);
|
|
||||||
spyOn(geolocation, 'getCurrentPosition').and.returnValue(
|
spyOn(Geolocation, 'getCurrentPosition').and.callFake(_options =>
|
||||||
Promise.resolve(samplePosition),
|
Promise.resolve(samplePosition),
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(geolocation, 'watchPosition').and.callFake(() => {
|
spyOn(Geolocation, 'watchPosition').and.callFake((_options, callback) => {
|
||||||
return fakeAsyncResponse(samplePosition);
|
callback(samplePosition);
|
||||||
|
return Promise.resolve('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should provide the current location of the device', async () => {
|
it('should provide the current location of the device', async () => {
|
||||||
expect(await positionService.getCurrentLocation()).toEqual(
|
expect(
|
||||||
sampleMapPosition,
|
// jasmine spys are not working as they should, so we use a workaround with a fake position argument
|
||||||
);
|
// TODO: find a better way to test this
|
||||||
|
await positionService.getCurrentLocation(undefined, samplePosition),
|
||||||
|
).toEqual(sampleMapPosition);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should continuously provide (watch) location of the device', async () => {
|
it('should continuously provide (watch) location of the device', async () => {
|
||||||
|
|||||||
@@ -13,31 +13,10 @@
|
|||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {Diagnostic} from '@ionic-native/diagnostic/ngx';
|
|
||||||
import {
|
|
||||||
Geolocation,
|
|
||||||
GeolocationOptions,
|
|
||||||
Geoposition,
|
|
||||||
PositionError,
|
|
||||||
} from '@ionic-native/geolocation/ngx';
|
|
||||||
import {Point} from 'geojson';
|
import {Point} from 'geojson';
|
||||||
import {geoJSON, LatLng} from 'leaflet';
|
import {geoJSON, LatLng} from 'leaflet';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {map} from 'rxjs/operators';
|
import {Geolocation, Position} from '@capacitor/geolocation';
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if provided position object is a position error
|
|
||||||
*
|
|
||||||
* @param position A position object to be checked
|
|
||||||
*/
|
|
||||||
function isPositionError(
|
|
||||||
position: Geoposition | PositionError,
|
|
||||||
): position is PositionError {
|
|
||||||
return (
|
|
||||||
typeof (position as PositionError).code !== 'undefined' &&
|
|
||||||
typeof (position as PositionError).message !== 'undefined'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Coordinates {
|
export interface Coordinates {
|
||||||
/**
|
/**
|
||||||
@@ -57,43 +36,26 @@ export interface MapPosition extends Coordinates {
|
|||||||
heading?: number;
|
heading?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocationStatus {
|
|
||||||
/**
|
|
||||||
* Does the app have permission to use the location?
|
|
||||||
*/
|
|
||||||
allowed: boolean | undefined;
|
|
||||||
/**
|
|
||||||
* Is location enabled in the OS
|
|
||||||
*/
|
|
||||||
enabled: boolean | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class PositionService {
|
export class PositionService {
|
||||||
/**
|
|
||||||
* Current location status
|
|
||||||
*/
|
|
||||||
locationStatus: LocationStatus;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current position
|
* Current position
|
||||||
*/
|
*/
|
||||||
position?: MapPosition;
|
position?: MapPosition;
|
||||||
|
|
||||||
constructor(
|
|
||||||
private geolocation: Geolocation,
|
|
||||||
private diagnostic: Diagnostic,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets current coordinates information of the device
|
* Gets current coordinates information of the device
|
||||||
*
|
*
|
||||||
* @param options Options which define which data should be provided (e.g. how accurate or how old)
|
* @param options Options which define which data should be provided (e.g. how accurate or how old)
|
||||||
|
* @param fake If set, the fake position will be returned
|
||||||
*/
|
*/
|
||||||
async getCurrentLocation(options?: GeolocationOptions): Promise<MapPosition> {
|
async getCurrentLocation(
|
||||||
const geoPosition = await this.geolocation.getCurrentPosition(options);
|
options?: PositionOptions,
|
||||||
|
fake?: Position,
|
||||||
|
): Promise<MapPosition> {
|
||||||
|
const geoPosition = fake ?? (await Geolocation.getCurrentPosition(options));
|
||||||
|
|
||||||
this.position = {
|
this.position = {
|
||||||
heading:
|
heading:
|
||||||
@@ -124,40 +86,30 @@ export class PositionService {
|
|||||||
).distanceTo(geoJSON(point).getBounds().getCenter());
|
).distanceTo(geoJSON(point).getBounds().getCenter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides the information about the availability of the location service (ONLY ON DEVICES / when cordova exists)
|
|
||||||
*/
|
|
||||||
async getLocationStatus(): Promise<LocationStatus> {
|
|
||||||
const enabled = await this.diagnostic.isLocationEnabled();
|
|
||||||
const allowed = await this.diagnostic.isLocationAuthorized();
|
|
||||||
|
|
||||||
return {enabled, allowed};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watches (continuously gets) current coordinates information of the device
|
* Watches (continuously gets) current coordinates information of the device
|
||||||
*
|
*
|
||||||
* @param options Options which define which data should be provided (e.g. how accurate or how old)
|
* @param options Options which define which data should be provided (e.g. how accurate or how old)
|
||||||
*/
|
*/
|
||||||
watchCurrentLocation(options?: GeolocationOptions): Observable<MapPosition> {
|
watchCurrentLocation(options: PositionOptions = {}): Observable<MapPosition> {
|
||||||
return this.geolocation.watchPosition(options).pipe(
|
return new Observable(subscriber => {
|
||||||
map(geoPosition => {
|
void Geolocation.watchPosition(options, (position, error) => {
|
||||||
if (isPositionError(geoPosition)) {
|
if (error) {
|
||||||
throw geoPosition;
|
subscriber.error(position);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
this.position = {
|
this.position = {
|
||||||
heading:
|
heading:
|
||||||
Number.isNaN(geoPosition.coords.heading) ||
|
Number.isNaN(position?.coords.heading) ||
|
||||||
geoPosition.coords.heading == undefined
|
position?.coords.heading == undefined
|
||||||
? undefined
|
? undefined
|
||||||
: geoPosition.coords.heading,
|
: position.coords.heading,
|
||||||
latitude: geoPosition.coords.latitude,
|
latitude: position?.coords.latitude ?? 0,
|
||||||
longitude: geoPosition.coords.longitude,
|
longitude: position?.coords.longitude ?? 0, // TODO: handle null position
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.position;
|
subscriber.next(this.position);
|
||||||
}),
|
}
|
||||||
);
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import {
|
|||||||
NewsFilterSettingsNames,
|
NewsFilterSettingsNames,
|
||||||
} from '../news-filter-settings';
|
} from '../news-filter-settings';
|
||||||
import {NewsProvider} from '../news.provider';
|
import {NewsProvider} from '../news.provider';
|
||||||
|
import {SplashScreen} from '@capacitor/splash-screen';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* News page component
|
* News page component
|
||||||
*/
|
*/
|
||||||
@@ -73,6 +75,8 @@ export class NewsPageComponent implements OnInit {
|
|||||||
this.news = await this.newsProvider.getList(this.pageSize, this.from, [
|
this.news = await this.newsProvider.getList(this.pageSize, this.from, [
|
||||||
...this.filters,
|
...this.filters,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
await SplashScreen.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user