Begins implementation of persistent inappbrowser logic. #20.
This commit is contained in:
parent
fb5f77f4ea
commit
eab2bd60ed
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"appId": "io.ionic.starter",
|
||||
"appName": "tainacan-mobile",
|
||||
"appId": "org.tainacan.mobile",
|
||||
"appName": "Tainacan",
|
||||
"webDir": "dist",
|
||||
"bundledWebRuntime": false
|
||||
}
|
||||
|
|
|
@ -2,5 +2,9 @@
|
|||
<widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
<access origin="*" />
|
||||
|
||||
<feature name="InAppBrowser">
|
||||
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
|
||||
</feature>
|
||||
|
||||
|
||||
</widget>
|
File diff suppressed because it is too large
Load Diff
25
package.json
25
package.json
|
@ -10,25 +10,26 @@
|
|||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@awesome-cordova-plugins/ionic-webview": "^5.43.0",
|
||||
"@capacitor/android": "3.5.1",
|
||||
"@awesome-cordova-plugins/core": "^5.43.0",
|
||||
"@awesome-cordova-plugins/in-app-browser": "^5.43.0",
|
||||
"@capacitor/android": "3.6.0",
|
||||
"@capacitor/app": "1.1.1",
|
||||
"@capacitor/core": "3.4.3",
|
||||
"@capacitor/core": "3.6.0",
|
||||
"@capacitor/device": "^1.1.2",
|
||||
"@capacitor/haptics": "1.1.4",
|
||||
"@capacitor/keyboard": "1.2.2",
|
||||
"@capacitor/keyboard": "1.2.3",
|
||||
"@capacitor/status-bar": "1.0.8",
|
||||
"@ionic/core": "^6.1.6",
|
||||
"@ionic/core": "^6.1.11",
|
||||
"@ionic/storage": "^3.0.6",
|
||||
"@ionic/vue": "^6.1.6",
|
||||
"@ionic/vue-router": "^6.1.6",
|
||||
"axios": "^0.26.1",
|
||||
"cordova-plugin-ionic-webview": "^5.0.0",
|
||||
"core-js": "^3.22.7",
|
||||
"@ionic/vue": "^6.1.11",
|
||||
"@ionic/vue-router": "^6.1.11",
|
||||
"axios": "^0.27.2",
|
||||
"cordova-plugin-inappbrowser": "^5.0.0",
|
||||
"core-js": "^3.23.2",
|
||||
"pinia": "^2.0.14",
|
||||
"vue": "^3.2.36",
|
||||
"vue": "^3.2.37",
|
||||
"vue-i18n": "^9.1.10",
|
||||
"vue-router": "^4.0.15",
|
||||
"vue-router": "^4.0.16",
|
||||
"vuex": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -18,7 +18,6 @@ export default defineComponent({
|
|||
mounted() {
|
||||
const device: DevicePlugin = Device;
|
||||
device.getLanguageCode().then((res) => {
|
||||
console.log("Default lang", res.value);
|
||||
if (res.value.includes("-")) {
|
||||
const language = res.value.split("-")[0];
|
||||
this.$i18n.locale = language;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
import {
|
||||
useTainacanStore
|
||||
} from '../store/storeTainacan';
|
||||
import { useWpStore } from '../store/storeWp';
|
||||
import { ref, defineComponent } from 'vue';
|
||||
import { add, documentOutline, documentAttachOutline, documentsOutline } from "ionicons/icons";
|
||||
import {
|
||||
|
@ -43,6 +44,7 @@ import {
|
|||
} from '@ionic/vue';
|
||||
import BaseLayout from '@/components/base/BaseLayout.vue';
|
||||
import ItemsList from '@/components/lists/ItemsList.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
BaseLayout,
|
||||
|
@ -78,6 +80,8 @@ export default defineComponent({
|
|||
infiniteScroll.value.$el.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
const wpStore = useWpStore();
|
||||
const actionSheetLabels = ref({
|
||||
header: '',
|
||||
button1: '',
|
||||
|
@ -113,6 +117,7 @@ export default defineComponent({
|
|||
data: 'single item',
|
||||
handler: () => {
|
||||
console.log('Item simples')
|
||||
wpStore.openAppBrowser('/collections/' + props.id + '/items/new');
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -131,6 +136,7 @@ export default defineComponent({
|
|||
return {
|
||||
isLoading,
|
||||
tainacanStore,
|
||||
wpStore,
|
||||
setIsLoading,
|
||||
loadItemsByCollection,
|
||||
doRefresh,
|
||||
|
|
|
@ -1,64 +1,40 @@
|
|||
<template>
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-content class="login-form-content" fullscreen>
|
||||
<ion-row class="ion-align-items-center ion-justify-content-center">
|
||||
<ion-col>
|
||||
<ion-img class="login-form-content__tainacan-logo" alt="Logo Tainacan" :src="image" />
|
||||
<form @submit.prevent="login">
|
||||
<ion-img
|
||||
class="login-form-content__tainacan-logo"
|
||||
alt="Logo Tainacan"
|
||||
:src="image"
|
||||
/>
|
||||
<form @submit.prevent="openLoginForm">
|
||||
<ion-list class="ion-no-margin" inset>
|
||||
<ion-item>
|
||||
<ion-label position="floating">
|
||||
{{ $t('label_site_url') }}
|
||||
{{ $t("label_site_url") }}
|
||||
</ion-label>
|
||||
<ion-input
|
||||
:placeholder="$t('placeholder_site_url')"
|
||||
autofocus="true"
|
||||
id="siteUrl"
|
||||
type="url"
|
||||
name="siteUrl"
|
||||
v-model.trim="siteUrl"
|
||||
required="true"
|
||||
autocomplete="url"
|
||||
enterkeyhint="next">
|
||||
<ion-input
|
||||
:placeholder="$t('placeholder_site_url')"
|
||||
autofocus="true"
|
||||
id="siteUrl"
|
||||
type="url"
|
||||
name="siteUrl"
|
||||
v-model.trim="siteUrl"
|
||||
required="true"
|
||||
autocomplete="url"
|
||||
enterkeyhint="next"
|
||||
>
|
||||
</ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">
|
||||
{{ $t('label_user_name') }}
|
||||
</ion-label>
|
||||
<ion-input
|
||||
:placeholder="$t('placeholder_user_name')"
|
||||
id="userLogin"
|
||||
type="text"
|
||||
name="userLogin"
|
||||
v-model="userLogin"
|
||||
required="true"
|
||||
autocomplete="username"
|
||||
enterkeyhint="next"
|
||||
inputmode="url">
|
||||
</ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">
|
||||
{{ $t('label_user_password') }}*
|
||||
</ion-label>
|
||||
<ion-input
|
||||
:placeholder="$t('placeholder_user_password')"
|
||||
id="userToken"
|
||||
type="password"
|
||||
name="userToken"
|
||||
v-model="userToken"
|
||||
required="true"
|
||||
autocomplete="new-password"
|
||||
enterkeyhint="done">
|
||||
</ion-input>
|
||||
<ion-note>{{ $t('info_application_password') }} <a id="open-explanation-modal">{{ $t('label_learn_more_here') }}</a></ion-note>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<br>
|
||||
<br />
|
||||
<ion-button type="submit" fill="clear">
|
||||
{{ $t('label_access_archive') }}
|
||||
<ion-icon slot="end" :icon="arrowForwardOutline"></ion-icon>
|
||||
{{ $t("label_access_archive") }}
|
||||
<ion-icon
|
||||
slot="end"
|
||||
:icon="arrowForwardOutline"
|
||||
></ion-icon>
|
||||
</ion-button>
|
||||
</form>
|
||||
</ion-col>
|
||||
|
@ -69,10 +45,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useTainacanStore } from '../store/storeTainacan';
|
||||
import { useWpStore } from '../store/storeWp';
|
||||
import { useTainacanStore } from "../store/storeTainacan";
|
||||
import { useWpStore } from "../store/storeWp";
|
||||
import { arrowForwardOutline } from "ionicons/icons";
|
||||
import AppPasswordModal from '../components/modals/AppPasswordModal.vue';
|
||||
import AppPasswordModal from "../components/modals/AppPasswordModal.vue";
|
||||
|
||||
import {
|
||||
IonIcon,
|
||||
|
@ -86,11 +62,12 @@ import {
|
|||
IonRow,
|
||||
IonCol,
|
||||
IonContent,
|
||||
IonNote
|
||||
} from '@ionic/vue';
|
||||
import { computed } from 'vue';
|
||||
} from "@ionic/vue";
|
||||
import { computed } from "vue";
|
||||
import { InAppBrowserEvent } from "@awesome-cordova-plugins/in-app-browser/index";
|
||||
|
||||
export default {
|
||||
props: ['pageTitle', 'pageDefaultBackLink'],
|
||||
props: ["pageTitle", "pageDefaultBackLink"],
|
||||
components: {
|
||||
IonIcon,
|
||||
IonImg,
|
||||
|
@ -103,30 +80,66 @@ export default {
|
|||
IonRow,
|
||||
IonCol,
|
||||
IonContent,
|
||||
IonNote,
|
||||
AppPasswordModal
|
||||
AppPasswordModal,
|
||||
},
|
||||
data(){
|
||||
data() {
|
||||
return {
|
||||
siteUrl: '',
|
||||
userLogin: '',
|
||||
userToken: '',
|
||||
}
|
||||
siteUrl: "",
|
||||
};
|
||||
},
|
||||
setup(){
|
||||
const image = computed (() => require('../assets/logo_square.png'));
|
||||
setup() {
|
||||
const image = computed(() => require("../assets/logo_square.png"));
|
||||
let tainacanStore = useTainacanStore();
|
||||
let wpStore = useWpStore();
|
||||
return { image, tainacanStore, wpStore, arrowForwardOutline }
|
||||
return { image, tainacanStore, wpStore, arrowForwardOutline };
|
||||
},
|
||||
methods: {
|
||||
async login(){
|
||||
await this.wpStore.login(this.siteUrl, this.userLogin, this.userToken);
|
||||
this.$router.push('/home');
|
||||
}
|
||||
}
|
||||
async openLoginForm() {
|
||||
await this.wpStore.fetchApplicationAuthorization(
|
||||
this.siteUrl,
|
||||
"_self",
|
||||
"location=no"
|
||||
);
|
||||
if (this.wpStore.authorizationURL) {
|
||||
this.wpStore.createInAppBrowser();
|
||||
this.wpStore.inAppBrowser
|
||||
.on("loadstop")
|
||||
.subscribe(this.handleBrowserLoadStop);
|
||||
}
|
||||
},
|
||||
async handleBrowserLoadStop(event: InAppBrowserEvent) {
|
||||
if (
|
||||
event.url &&
|
||||
typeof event.url == "string" &&
|
||||
event.url.split("?") &&
|
||||
event.url.split("?").length >= 2
|
||||
) {
|
||||
const params = new URLSearchParams(event.url.split("?")[1]);
|
||||
if (params.get("page") === "tainacan_admin") {
|
||||
const userLogin = params.get("user_login");
|
||||
let userToken = params.get("password");
|
||||
|
||||
}
|
||||
if (
|
||||
typeof userToken == "string" &&
|
||||
userToken.indexOf("#") >= 0
|
||||
)
|
||||
userToken = userToken.split("#")[0];
|
||||
|
||||
if (!!userLogin && !!userToken) {
|
||||
this.wpStore.inAppBrowser.hide();
|
||||
|
||||
await this.wpStore.login(
|
||||
this.siteUrl,
|
||||
userLogin,
|
||||
userToken
|
||||
);
|
||||
this.$router.push("/home");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -1,65 +1,120 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import { Storage } from '@ionic/storage' ;
|
||||
import { defineStore } from "pinia";
|
||||
import axios from "axios";
|
||||
import { Storage } from "@ionic/storage";
|
||||
import {
|
||||
InAppBrowser,
|
||||
InAppBrowserObject,
|
||||
InAppBrowserEvent
|
||||
} from "@awesome-cordova-plugins/in-app-browser/index";
|
||||
|
||||
const store = new Storage();
|
||||
|
||||
const useWpStore = defineStore('wp', {
|
||||
state () {
|
||||
return {
|
||||
userIsLoggedIn: false,
|
||||
userSiteUrl: '',
|
||||
userLogin: '',
|
||||
userToken: ''
|
||||
}
|
||||
},
|
||||
const useWpStore = defineStore("wp", {
|
||||
state() {
|
||||
return {
|
||||
userIsLoggedIn: false,
|
||||
userSiteUrl: "",
|
||||
userLogin: "",
|
||||
userToken: "",
|
||||
authorizationURL: "",
|
||||
inAppBrowser: InAppBrowserObject,
|
||||
};
|
||||
},
|
||||
|
||||
actions: {
|
||||
async login(userSiteUrl: string, userLogin: string, userToken: string) {
|
||||
try {
|
||||
this.userIsLoggedIn = true;
|
||||
this.userSiteUrl = userSiteUrl;
|
||||
this.userLogin = userLogin;
|
||||
this.userToken = userToken;
|
||||
await store.set('userIsLoggedIn', true);
|
||||
await store.set('userSiteUrl', userSiteUrl);
|
||||
await store.set('userLogin', userLogin);
|
||||
await store.set('userToken', userToken);
|
||||
} catch (err) {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = '';
|
||||
this.userToken = '';
|
||||
this.userLogin = '';
|
||||
console.error('Erro no login:', err);
|
||||
return err;
|
||||
}
|
||||
},
|
||||
async logoff() {
|
||||
try {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = '';
|
||||
this.userToken = '';
|
||||
this.userToken = '';
|
||||
await store.set('userIsLoggedIn', false);
|
||||
await store.set('userSiteUrl', '');
|
||||
await store.set('userToken', '');
|
||||
} catch (err) {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = '';
|
||||
this.userToken = '';
|
||||
this.userToken = '';
|
||||
console.error('Erro no logoff:', err);
|
||||
return err;
|
||||
}
|
||||
},
|
||||
async checkUserLogin() {
|
||||
await store.create();
|
||||
this.userIsLoggedIn = await store.get('userIsLoggedIn');
|
||||
this.userSiteUrl = await store.get('userSiteUrl');
|
||||
this.userLogin = await store.get('userLogin');
|
||||
this.userToken = await store.get('userToken');
|
||||
}
|
||||
}
|
||||
})
|
||||
export {
|
||||
useWpStore
|
||||
}
|
||||
actions: {
|
||||
async login(userSiteUrl: string, userLogin: string, userToken: string) {
|
||||
try {
|
||||
this.userIsLoggedIn = true;
|
||||
this.userSiteUrl = userSiteUrl;
|
||||
this.userLogin = userLogin;
|
||||
this.userToken = userToken;
|
||||
await store.set("userIsLoggedIn", true);
|
||||
await store.set("userSiteUrl", userSiteUrl);
|
||||
await store.set("userLogin", userLogin);
|
||||
await store.set("userToken", userToken);
|
||||
} catch (err) {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = "";
|
||||
this.userToken = "";
|
||||
this.userLogin = "";
|
||||
console.error("Erro no login:", err);
|
||||
return err;
|
||||
}
|
||||
},
|
||||
async logoff() {
|
||||
try {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = "";
|
||||
this.userToken = "";
|
||||
this.userToken = "";
|
||||
await store.set("userIsLoggedIn", false);
|
||||
await store.set("userSiteUrl", "");
|
||||
await store.set("userToken", "");
|
||||
} catch (err) {
|
||||
this.userIsLoggedIn = false;
|
||||
this.userSiteUrl = "";
|
||||
this.userToken = "";
|
||||
this.userToken = "";
|
||||
console.error("Erro no logoff:", err);
|
||||
return err;
|
||||
}
|
||||
},
|
||||
async fetchApplicationAuthorization(siteUrl: string) {
|
||||
try {
|
||||
const endpoint = siteUrl + "?rest_route=/";
|
||||
const response = await axios.get(endpoint);
|
||||
|
||||
if (
|
||||
response.data &&
|
||||
response.data.authentication &&
|
||||
response.data.authentication["application-passwords"] &&
|
||||
response.data.authentication["application-passwords"].endpoints &&
|
||||
response.data.authentication["application-passwords"].endpoints
|
||||
.authorization
|
||||
)
|
||||
this.authorizationURL =
|
||||
response.data.authentication[
|
||||
"application-passwords"
|
||||
].endpoints.authorization;
|
||||
else return false;
|
||||
} catch (err) {
|
||||
console.error("Error trying to fetch application authorization");
|
||||
return err;
|
||||
}
|
||||
},
|
||||
async checkUserLogin() {
|
||||
await store.create();
|
||||
this.userIsLoggedIn = await store.get("userIsLoggedIn");
|
||||
this.userSiteUrl = await store.get("userSiteUrl");
|
||||
this.userLogin = await store.get("userLogin");
|
||||
this.userToken = await store.get("userToken");
|
||||
},
|
||||
createInAppBrowser() {
|
||||
let tainacanAdminUrl = this.userSiteUrl + "/wp-admin/admin.php?page=tainacan_admin&mobileAppMode=true";
|
||||
if (!this.userIsLoggedIn && this.authorizationURL)
|
||||
tainacanAdminUrl = this.authorizationURL + "?app_name=TainacanMobileApp&success_url=" + tainacanAdminUrl;
|
||||
|
||||
const anInAppBrowser = InAppBrowser.create(tainacanAdminUrl);
|
||||
this.inAppBrowser = anInAppBrowser;
|
||||
},
|
||||
openAppBrowser(url: string) {
|
||||
const inAppBrowserScript = `
|
||||
window.addEventListener('hashchange', function() {
|
||||
console.log(window.location.hash);
|
||||
});
|
||||
window.history.replaceState(
|
||||
null,
|
||||
null,
|
||||
'${this.userSiteUrl}/wp-admin/admin.php?mobileAppMode=true&page=tainacan_admin#${url}'
|
||||
);
|
||||
window.history.go(0);
|
||||
`;
|
||||
if (!this.inAppBrowser || !this.inAppBrowser.executeScript)
|
||||
this.createInAppBrowser();
|
||||
|
||||
this.inAppBrowser.executeScript({ code: inAppBrowserScript });
|
||||
this.inAppBrowser.show();
|
||||
},
|
||||
},
|
||||
});
|
||||
export { useWpStore };
|
||||
|
|
Loading…
Reference in New Issue