Implemented persistent storage when using cordova

This commit is contained in:
Ferdinand Thiessen 2021-11-26 02:56:07 +01:00
parent c9df257bbf
commit 8ced3e6ce1
57 changed files with 458 additions and 604 deletions

View File

@ -1,28 +1,16 @@
import { LocalStorage, SessionStorage } from 'quasar'; import { SessionStorage } from 'quasar';
import { FG_Plugin } from '@flaschengeist/types'; import { FG_Plugin } from '@flaschengeist/types';
import { useSessionStore, useUserStore } from '.'; import { useSessionStore, useUserStore } from '.';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import { api } from '../internal'; import { api } from '../internal';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
function loadCurrentSession() {
const session = LocalStorage.getItem<FG.Session>('session');
if (session) session.expires = new Date(session.expires);
return session || undefined;
}
function loadUser() {
const user = SessionStorage.getItem<FG.User>('user');
if (user && user.birthday) user.birthday = new Date(user.birthday);
return user || undefined;
}
export const useMainStore = defineStore({ export const useMainStore = defineStore({
id: 'main', id: 'main',
state: () => ({ state: () => ({
session: loadCurrentSession(), session: undefined as FG.Session | undefined,
user: loadUser(), user: undefined as FG.User | undefined,
notifications: [] as Array<FG_Plugin.Notification>, notifications: [] as Array<FG_Plugin.Notification>,
shortcuts: [] as Array<FG_Plugin.MenuLink>, shortcuts: [] as Array<FG_Plugin.MenuLink>,
}), }),
@ -65,7 +53,6 @@ export const useMainStore = defineStore({
const { data } = await api.post<FG.Session>('/auth', { userid, password }); const { data } = await api.post<FG.Session>('/auth', { userid, password });
this.session = data; this.session = data;
this.session.expires = new Date(this.session.expires); this.session.expires = new Date(this.session.expires);
LocalStorage.set('session', this.session);
return true; return true;
} catch ({ response }) { } catch ({ response }) {
return (<AxiosResponse | undefined>response)?.status || false; return (<AxiosResponse | undefined>response)?.status || false;
@ -144,11 +131,11 @@ export const useMainStore = defineStore({
await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts); await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts);
}, },
handleLoggedOut() { handleLoggedOut() {
LocalStorage.clear();
this.$patch({ this.$patch({
session: undefined, session: undefined,
user: undefined, user: undefined,
notifications: [],
shortcuts: [],
}); });
SessionStorage.clear(); SessionStorage.clear();
}, },

View File

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<widget id="de.wu5.flaschengeist" version="2.0.0-alpha.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <widget id="de.wu5.flaschengeist" version="2.0.0-alpha.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Flaschengeist</name> <name>flaschengeist-frontend</name>
<description>Modular student club administration system</description> <description>Modular student club administration system</description>
<author email="dev@cordova.apache.org" href="http://cordova.io"> <author email="dev@cordova.apache.org" href="http://cordova.io">
Apache Cordova Team Apache Cordova Team
@ -15,62 +15,10 @@
<allow-intent href="geo:*" /> <allow-intent href="geo:*" />
<platform name="android"> <platform name="android">
<allow-intent href="market:*" /> <allow-intent href="market:*" />
<icon density="ldpi" src="res/android/ldpi.png" />
<icon density="mdpi" src="res/android/mdpi.png" />
<icon density="hdpi" src="res/android/hdpi.png" />
<icon density="xhdpi" src="res/android/xhdpi.png" />
<icon density="xxhdpi" src="res/android/xxhdpi.png" />
<icon density="xxxhdpi" src="res/android/xxxhdpi.png" />
<splash density="land-ldpi" src="res/screen/android/splash-land-ldpi.png" />
<splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
<splash density="land-mdpi" src="res/screen/android/splash-land-mdpi.png" />
<splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
<splash density="land-hdpi" src="res/screen/android/splash-land-hdpi.png" />
<splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />
<splash density="land-xhdpi" src="res/screen/android/splash-land-xhdpi.png" />
<splash density="port-xhdpi" src="res/screen/android/splash-port-xhdpi.png" />
<splash density="land-xxhdpi" src="res/screen/android/splash-land-xxhdpi.png" />
<splash density="port-xxhdpi" src="res/screen/android/splash-port-xxhdpi.png" />
<splash density="land-xxxhdpi" src="res/screen/android/splash-land-xxxhdpi.png" />
<splash density="port-xxxhdpi" src="res/screen/android/splash-port-xxxhdpi.png" />
</platform> </platform>
<platform name="ios"> <platform name="ios">
<allow-intent href="itms:*" /> <allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" /> <allow-intent href="itms-apps:*" />
<icon height="57" src="res/ios/icon.png" width="57" />
<icon height="114" src="res/ios/icon@2x.png" width="114" />
<icon height="40" src="res/ios/icon-20@2x.png" width="40" />
<icon height="60" src="res/ios/icon-20@3x.png" width="60" />
<icon height="29" src="res/ios/icon-29.png" width="29" />
<icon height="58" src="res/ios/icon-29@2x.png" width="58" />
<icon height="87" src="res/ios/icon-29@3x.png" width="87" />
<icon height="80" src="res/ios/icon-40@2x.png" width="80" />
<icon height="120" src="res/ios/icon-60@2x.png" width="120" />
<icon height="180" src="res/ios/icon-60@3x.png" width="180" />
<icon height="20" src="res/ios/icon-20.png" width="20" />
<icon height="40" src="res/ios/icon-40.png" width="40" />
<icon height="50" src="res/ios/icon-50.png" width="50" />
<icon height="100" src="res/ios/icon-50@2x.png" width="100" />
<icon height="72" src="res/ios/icon-72.png" width="72" />
<icon height="144" src="res/ios/icon-72@2x.png" width="144" />
<icon height="76" src="res/ios/icon-76.png" width="76" />
<icon height="152" src="res/ios/icon-76@2x.png" width="152" />
<icon height="167" src="res/ios/icon-83.5@2x.png" width="167" />
<icon height="1024" src="res/ios/icon-1024.png" width="1024" />
<icon height="48" src="res/ios/icon-24@2x.png" width="48" />
<icon height="55" src="res/ios/icon-27.5@2x.png" width="55" />
<icon height="88" src="res/ios/icon-44@2x.png" width="88" />
<icon height="172" src="res/ios/icon-86@2x.png" width="172" />
<icon height="196" src="res/ios/icon-98@2x.png" width="196" />
<splash src="res/screen/ios/Default@2x~iphone~anyany.png" />
<splash src="res/screen/ios/Default@2x~iphone~comany.png" />
<splash src="res/screen/ios/Default@2x~iphone~comcom.png" />
<splash src="res/screen/ios/Default@3x~iphone~anyany.png" />
<splash src="res/screen/ios/Default@3x~iphone~anycom.png" />
<splash src="res/screen/ios/Default@3x~iphone~comany.png" />
<splash src="res/screen/ios/Default@2x~ipad~anyany.png" />
<splash src="res/screen/ios/Default@2x~ipad~comany.png" />
</platform> </platform>
<allow-navigation href="about:*" /> <allow-navigation href="about:*" />
<preference name="SplashMaintainAspectRatio" value="true" />
</widget> </widget>

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "de.wu5.flaschengeist", "name": "dev.flaschengeist",
"displayName": "Flaschengeist", "displayName": "flaschengeist-frontend",
"version": "1.0.0", "version": "1.0.0",
"description": "A sample Apache Cordova application that responds to the deviceready event.", "description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js", "main": "index.js",
@ -13,18 +13,17 @@
"author": "Apache Cordova Team", "author": "Apache Cordova Team",
"license": "Apache-2.0", "license": "Apache-2.0",
"devDependencies": { "devDependencies": {
"cordova-android": "^9.0.0", "cordova-android": "^9.1.0",
"cordova-ios": "^6.1.1", "cordova-ios": "^6.1.1",
"cordova-plugin-splashscreen": "^6.0.0", "cordova-plugin-nativestorage": "^2.3.2",
"cordova-plugin-whitelist": "^1.3.4" "cordova-plugin-whitelist": "^1.3.4"
}, },
"cordova": { "cordova": {
"plugins": { "plugins": {
"cordova-plugin-whitelist": {}, "cordova-plugin-whitelist": {},
"cordova-plugin-splashscreen": {} "cordova-plugin-nativestorage": {}
}, },
"platforms": [ "platforms": [
"ios",
"android" "android"
] ]
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1022 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -1,9 +1,50 @@
import { useMainStore, pinia } from '@flaschengeist/api'; import { LocalStorage } from 'quasar';
import { boot } from 'quasar/wrappers'; import { boot } from 'quasar/wrappers';
import { useMainStore, pinia } from '@flaschengeist/api';
function isCordova() {
return window.hasOwnProperty('cordova');
}
function error() {
console.debug('NativeStorage Error');
}
export default boot(({ app }) => { export default boot(({ app }) => {
app.use(pinia); app.use(pinia);
const store = useMainStore(); document.addEventListener('deviceready', () => {
void store.init(); const store = useMainStore();
// Load main state from storage
if (isCordova()) {
// is cordova, so use Native Storage
window.NativeStorage.keys((keys) => {
// Check if key is set
if (keys.includes('main_store'))
window.NativeStorage.getItem<typeof store.$state>(
'main_store',
(v) => {
// Check is object, then patch it
if (typeof v === 'object') store.$patch(v);
},
error
);
}, error);
} else {
// is not cordova, so use LocalStorage
store.$patch(LocalStorage.getItem<typeof store.$state>('main_store') || {});
}
// Subscript to save changes of state to storage
store.$subscribe(
(mutation, state) => {
if (isCordova()) window.NativeStorage.setItem('main_store', state, () => undefined, error);
else LocalStorage.set('main_store', state);
},
{ deep: true }
);
void store.init();
});
}); });

67
src/cordova.d.ts vendored Normal file
View File

@ -0,0 +1,67 @@
/**
* @name Native Storage
* @premier nativestorage
* @description Native storage of variables in Android and iOS
*
* @usage
* ```typescript
* import { NativeStorage } from '@ionic-native/native-storage/ngx';
*
* constructor(private nativeStorage: NativeStorage) { }
*
* ...
*
* this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
* .then(
* () => console.log('Stored item!'),
* error => console.error('Error storing item', error)
* );
*
* this.nativeStorage.getItem('myitem')
* .then(
* data => console.log(data),
* error => console.error(error)
* );
* ```
*/
export {};
declare class NativeStorageOriginal {
/**
* Initialises shared storage with the suite name when using app groups in iOS
* @param reference {string}
*/
initWithSuiteName(reference: string, success: () => void, error: () => void): void;
/**
* Stores a value
* @param reference {string}
* @param value
*/
setItem(reference: string, value: unknown, success: () => void, error: () => void): void;
/**
* Gets a stored item
* @param reference {string}
*/
getItem<T = unknown>(reference: string, success: (obj: T) => void, error: () => void): void;
/**
* Retrieving all keys
*/
keys(success: (keys: string[]) => void, error: () => void): void;
/**
* Removes a single stored item
* @param reference {string}
*/
remove(reference: string, success: () => void, error: () => void): void;
/**
* Removes all stored values.
*/
clear(success: () => void, error: () => void): void;
}
declare const NativeStorage: NativeStorageOriginal;
declare global {
interface Window {
NativeStorage: NativeStorageOriginal;
}
}