Merge branch 'main' into 11-basic-textual-search-on-the-collection-items-list.

This commit is contained in:
mateuswetah 2022-06-30 09:27:03 -03:00
commit c3bdb4cd50
14 changed files with 552 additions and 20370 deletions

View File

@ -1,6 +1,6 @@
{ {
"appId": "io.ionic.starter", "appId": "org.tainacan.mobile",
"appName": "tainacan-mobile", "appName": "Tainacan",
"webDir": "dist", "webDir": "dist",
"bundledWebRuntime": false "bundledWebRuntime": false
} }

View File

@ -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"> <widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<access origin="*" /> <access origin="*" />
<feature name="InAppBrowser">
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
</feature>
</widget> </widget>

20391
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,25 +10,26 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@awesome-cordova-plugins/ionic-webview": "^5.43.0", "@awesome-cordova-plugins/core": "^5.43.0",
"@capacitor/android": "3.5.1", "@awesome-cordova-plugins/in-app-browser": "^5.43.0",
"@capacitor/android": "3.6.0",
"@capacitor/app": "1.1.1", "@capacitor/app": "1.1.1",
"@capacitor/core": "3.4.3", "@capacitor/core": "3.6.0",
"@capacitor/device": "^1.1.2", "@capacitor/device": "^1.1.2",
"@capacitor/haptics": "1.1.4", "@capacitor/haptics": "1.1.4",
"@capacitor/keyboard": "1.2.2", "@capacitor/keyboard": "1.2.3",
"@capacitor/status-bar": "1.0.8", "@capacitor/status-bar": "1.0.8",
"@ionic/core": "^6.1.6", "@ionic/core": "^6.1.11",
"@ionic/storage": "^3.0.6", "@ionic/storage": "^3.0.6",
"@ionic/vue": "^6.1.6", "@ionic/vue": "^6.1.11",
"@ionic/vue-router": "^6.1.6", "@ionic/vue-router": "^6.1.11",
"axios": "^0.26.1", "axios": "^0.27.2",
"cordova-plugin-ionic-webview": "^5.0.0", "cordova-plugin-inappbrowser": "^5.0.0",
"core-js": "^3.22.7", "core-js": "^3.23.2",
"pinia": "^2.0.14", "pinia": "^2.0.14",
"vue": "^3.2.36", "vue": "^3.2.37",
"vue-i18n": "^9.1.10", "vue-i18n": "^9.1.10",
"vue-router": "^4.0.15", "vue-router": "^4.0.16",
"vuex": "^4.0.2" "vuex": "^4.0.2"
}, },
"devDependencies": { "devDependencies": {

View File

@ -18,7 +18,6 @@ export default defineComponent({
mounted() { mounted() {
const device: DevicePlugin = Device; const device: DevicePlugin = Device;
device.getLanguageCode().then((res) => { device.getLanguageCode().then((res) => {
console.log("Default lang", res.value);
if (res.value.includes("-")) { if (res.value.includes("-")) {
const language = res.value.split("-")[0]; const language = res.value.split("-")[0];
this.$i18n.locale = language; this.$i18n.locale = language;

View File

@ -68,7 +68,7 @@ export default {
}, },
methods: { methods: {
async logOff(){ async logOff(){
await this.wpStore.userLogOff(); await this.wpStore.logoff();
this.$router.go(); this.$router.go();
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<ion-row class="items-list-container"> <ion-row class="items-list-container">
<ion-col size="4" v-for="item of items" :key="item.id"> <ion-col size="4" v-for="item of items" :key="item.id">
<ion-card button color="light" > <ion-card @click="openItemEdition(item)" button color="light" >
<ion-img :src="(item.thumbnail && item.thumbnail['tainacan-medium'] && item.thumbnail['tainacan-medium'][0]) ? item.thumbnail['tainacan-medium'][0] : thumbnailPlaceholder" :alt="(item.thumbnail_alt ? item.thumbnail_alt : (item.title ? item.title : 'Imagem de item sem título'))"></ion-img> <ion-img :src="(item.thumbnail && item.thumbnail['tainacan-medium'] && item.thumbnail['tainacan-medium'][0]) ? item.thumbnail['tainacan-medium'][0] : thumbnailPlaceholder" :alt="(item.thumbnail_alt ? item.thumbnail_alt : (item.title ? item.title : 'Imagem de item sem título'))"></ion-img>
<ion-card-header> <ion-card-header>
<ion-card-title>{{ item.title ? item.title : $t('label_item_without_title') }}</ion-card-title> <ion-card-title>{{ item.title ? item.title : $t('label_item_without_title') }}</ion-card-title>
@ -22,6 +22,8 @@ import {
} from '@ionic/vue'; } from '@ionic/vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { useWpStore } from '@/store/storeWp';
import { InAppBrowserEvent } from '@awesome-cordova-plugins/in-app-browser';
export default { export default {
props: [ props: [
"items" "items"
@ -35,8 +37,24 @@ export default {
IonCardTitle IonCardTitle
}, },
setup() { setup() {
const wpStore = useWpStore();
const thumbnailPlaceholder = computed (() => require('../../assets/placeholder_square_small.png')); const thumbnailPlaceholder = computed (() => require('../../assets/placeholder_square_small.png'));
return { thumbnailPlaceholder }
const openItemEdition = function(item: any) {
wpStore.openInAppBrowser('?page=tainacan_admin&mobileAppMode=true&itemEditionMode=true#/collections/' + item.collection_id + '/items/' + item.id + '/edit');
wpStore.listenEventInAppBrowser((event: InAppBrowserEvent) => {
if (event &&
event.data &&
event.data.type === 'item_updated' &&
event.data.item &&
event.data.item.status !== 'auto-draft'
) {
wpStore.hideInAppBrowser();
}
});
}
return { thumbnailPlaceholder, wpStore, openItemEdition }
} }
} }
</script> </script>

View File

@ -0,0 +1,39 @@
<template>
<ion-modal ref="modal" trigger="open-explanation-modal" :initial-breakpoint="0.9" :breakpoints="[0, 0.5, 0.75, 1.0]">
<ion-content
style="font-size: 0.9375rem; opacity: 0.85"
class="ion-padding">
<h1>Application Passwords</h1>
<p><em>Application passwords</em> are a safe way to peform operations without using your actual website password. To generate one, you must:
<ol>
<li>Open a web browser and login do your website traditional login page (usually <em>"https://your-website.com.br/wp-admin"</em>).</li>
<li>Go to your profile page by clicking on your picture in the upper right corner.</li>
<li>Scroll down to the "Application passwords" section. There should be a text input labelled "New name to the application password".</li>
<li>Fill in the text input with any value to identify this password (you can have multiple), for example: "Tainacan Mobile".</li>
<li>Click on the "Add new application password" button.</li>
</ol>
</p>
<p>With this steps completed, you will receive a code, that may look like this:</p>
<pre><code>vlOh CdaH UqWw YV7X beou 6MFY</code></pre>
<p>Copy this code and <strong>keep it safe somewhere</strong>. You won't be able to access it later. Finally, paste it on this app login screen.</p>
<p>While it should be kept logged in, if you ever loose your access to the app, you can revogate the previous passwords and generate new ones in the same screen.</p>
</ion-content>
</ion-modal>
</template>
<script lang="ts">
import {
IonModal,
IonContent
} from '@ionic/vue';
export default {
components: {
IonModal,
IonContent
},
setup() {
return {}
}
}
</script>

View File

@ -12,8 +12,8 @@ export const translationStrings = {
placeholder_site_url: 'https://my-tainacan-archive.com', placeholder_site_url: 'https://my-tainacan-archive.com',
label_user_name: 'User name', label_user_name: 'User name',
placeholder_user_name: 'your user name', placeholder_user_name: 'your user name',
label_user_password: 'User password', label_user_password: 'User application password',
placeholder_user_password: 'your password here', placeholder_user_password: 'your application password here',
label_access_archive: 'Access archive', label_access_archive: 'Access archive',
label_item_without_title: 'Item without title', label_item_without_title: 'Item without title',
label_collection_without_name: 'Collection without name', label_collection_without_name: 'Collection without name',
@ -27,7 +27,9 @@ export const translationStrings = {
label_option_single_item: 'Single empty item', label_option_single_item: 'Single empty item',
label_cancel: 'Cancel', label_cancel: 'Cancel',
label_search: 'Search', label_search: 'Search',
label_no_results_found: 'No results found' label_no_results_found: 'No results found',
info_application_password: 'This password is not the same of your WordPress admin.',
label_learn_more_here: 'Learn more here'
}, },
pt: { pt: {
collections: "Coleções", collections: "Coleções",
@ -42,8 +44,8 @@ export const translationStrings = {
placeholder_site_url: 'https://meu-acervo-tainacan.com', placeholder_site_url: 'https://meu-acervo-tainacan.com',
label_user_name: 'Nome de usuário', label_user_name: 'Nome de usuário',
placeholder_user_name: 'seu nome de usuário aqui', placeholder_user_name: 'seu nome de usuário aqui',
label_user_password: 'Senha do usuário', label_user_password: 'Senha do usuário da aplicação',
placeholder_user_password: 'sua senha de usuário aqui', placeholder_user_password: 'sua senha de usuário da aplicação aqui',
label_access_archive: 'Acessar acervo', label_access_archive: 'Acessar acervo',
label_item_without_title: 'Item sem título', label_item_without_title: 'Item sem título',
label_collection_without_name: 'Coleção sem nome', label_collection_without_name: 'Coleção sem nome',
@ -57,6 +59,8 @@ export const translationStrings = {
label_option_single_item: 'Um item vazio', label_option_single_item: 'Um item vazio',
label_cancel: 'Cancelar', label_cancel: 'Cancelar',
label_search: 'Buscar', label_search: 'Buscar',
label_no_results_found: 'Nenhum resultado encontrado' label_no_results_found: 'Nenhum resultado encontrado',
info_application_password: 'Esta senha não é a mesma do seu painel admin do WordPress.',
label_learn_more_here: 'Saiba mais aqui.'
} }
} }

View File

@ -39,6 +39,7 @@
import { import {
useTainacanStore useTainacanStore
} from '../store/storeTainacan'; } from '../store/storeTainacan';
import { useWpStore } from '../store/storeWp';
import { ref, defineComponent } from 'vue'; import { ref, defineComponent } from 'vue';
import { add, documentOutline, documentAttachOutline, documentsOutline } from "ionicons/icons"; import { add, documentOutline, documentAttachOutline, documentsOutline } from "ionicons/icons";
import { import {
@ -52,9 +53,12 @@ import {
IonToolbar, IonToolbar,
IonSearchbar, IonSearchbar,
IonSpinner, IonSpinner,
IonInfiniteScrollContent
} from '@ionic/vue'; } from '@ionic/vue';
import BaseLayout from '@/components/base/BaseLayout.vue'; import BaseLayout from '@/components/base/BaseLayout.vue';
import ItemsList from '@/components/lists/ItemsList.vue'; import ItemsList from '@/components/lists/ItemsList.vue';
import { InAppBrowserEvent } from '@awesome-cordova-plugins/in-app-browser';
export default defineComponent({ export default defineComponent({
components: { components: {
BaseLayout, BaseLayout,
@ -68,6 +72,7 @@ export default defineComponent({
IonToolbar, IonToolbar,
IonSearchbar, IonSearchbar,
IonSpinner, IonSpinner,
IonInfiniteScrollContent
}, },
props: { props: {
id: String, id: String,
@ -113,6 +118,8 @@ export default defineComponent({
infiniteScroll.value.$el.disabled = false; infiniteScroll.value.$el.disabled = false;
} }
} }
const wpStore = useWpStore();
const actionSheetLabels = ref({ const actionSheetLabels = ref({
header: '', header: '',
button1: '', button1: '',
@ -147,7 +154,18 @@ export default defineComponent({
icon: documentOutline, icon: documentOutline,
data: 'single item', data: 'single item',
handler: () => { handler: () => {
console.log('Item simples') wpStore.openInAppBrowser('?page=tainacan_admin&mobileAppMode=true&itemEditionMode=true#/collections/' + props.id + '/items/new');
wpStore.listenEventInAppBrowser((event: InAppBrowserEvent) => {
if (event &&
event.data &&
event.data.type === 'item_updated' &&
event.data.item &&
event.data.item.status !== 'auto-draft'
) {
wpStore.hideInAppBrowser();
loadItemsByCollection({}, true);
}
});
}, },
}, },
{ {
@ -167,6 +185,7 @@ export default defineComponent({
isLoading, isLoading,
isSearching, isSearching,
tainacanStore, tainacanStore,
wpStore,
setIsLoading, setIsLoading,
loadItemsByCollection, loadItemsByCollection,
doRefresh, doRefresh,

View File

@ -36,6 +36,7 @@ import {
IonToolbar, IonToolbar,
IonSearchbar, IonSearchbar,
IonSpinner, IonSpinner,
IonInfiniteScrollContent
} from '@ionic/vue'; } from '@ionic/vue';
import BaseLayout from '@/components/base/BaseLayout.vue'; import BaseLayout from '@/components/base/BaseLayout.vue';
import { ref } from 'vue'; import { ref } from 'vue';
@ -51,6 +52,7 @@ export default {
IonToolbar, IonToolbar,
IonSearchbar, IonSearchbar,
IonSpinner, IonSpinner,
IonInfiniteScrollContent
}, },
setup() { setup() {
const isLoading = ref(false); const isLoading = ref(false);

View File

@ -3,75 +3,55 @@
<ion-content class="login-form-content" fullscreen> <ion-content class="login-form-content" fullscreen>
<ion-row class="ion-align-items-center ion-justify-content-center"> <ion-row class="ion-align-items-center ion-justify-content-center">
<ion-col> <ion-col>
<ion-img class="login-form-content__tainacan-logo" alt="Logo Tainacan" :src="image" /> <ion-img
<form @submit.prevent="login"> class="login-form-content__tainacan-logo"
alt="Logo Tainacan"
:src="image"
/>
<form @submit.prevent="openLoginForm">
<ion-list class="ion-no-margin" inset> <ion-list class="ion-no-margin" inset>
<ion-item> <ion-item>
<ion-label position="floating"> <ion-label position="floating">
{{ $t('label_site_url') }} {{ $t("label_site_url") }}
</ion-label> </ion-label>
<ion-input <ion-input
:placeholder="$t('placeholder_site_url')" :placeholder="$t('placeholder_site_url')"
autofocus="true" autofocus="true"
id="siteUrl" id="siteUrl"
type="url" type="url"
name="siteUrl" name="siteUrl"
v-model.trim="siteUrl" v-model.trim="siteUrl"
required="true" required="true"
autocomplete="url" autocomplete="url"
enterkeyhint="next"> 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="userPassword"
type="password"
name="userPassword"
v-model="userPassword"
required="true"
autocomplete="new-password"
enterkeyhint="done">
</ion-input> </ion-input>
</ion-item> </ion-item>
</ion-list> </ion-list>
<br> <br />
<ion-button type="submit" fill="clear"> <ion-button type="submit" fill="clear">
{{ $t('label_access_archive') }} {{ $t("label_access_archive") }}
<ion-icon slot="end" :icon="arrowForwardOutline"></ion-icon> <ion-icon
slot="end"
:icon="arrowForwardOutline"
></ion-icon>
</ion-button> </ion-button>
</form> </form>
</ion-col> </ion-col>
</ion-row> </ion-row>
<app-password-modal />
</ion-content> </ion-content>
</ion-page> </ion-page>
</template> </template>
<script lang="ts"> <script lang="ts">
import { useTainacanStore } from '../store/storeTainacan'; import { useTainacanStore } from "../store/storeTainacan";
import { useWpStore } from '../store/storeWp'; import { useWpStore } from "../store/storeWp";
import { arrowForwardOutline } from "ionicons/icons"; import { arrowForwardOutline } from "ionicons/icons";
import AppPasswordModal from "../components/modals/AppPasswordModal.vue";
import { import {
IonIcon,
IonImg, IonImg,
IonPage, IonPage,
IonList, IonList,
@ -81,12 +61,15 @@ import {
IonLabel, IonLabel,
IonRow, IonRow,
IonCol, IonCol,
IonContent IonContent,
} from '@ionic/vue'; } from "@ionic/vue";
import { computed } from 'vue'; import { computed } from "vue";
import { InAppBrowserEvent } from "@awesome-cordova-plugins/in-app-browser/index";
export default { export default {
props: ['pageTitle', 'pageDefaultBackLink'], props: ["pageTitle", "pageDefaultBackLink"],
components: { components: {
IonIcon,
IonImg, IonImg,
IonPage, IonPage,
IonList, IonList,
@ -96,32 +79,65 @@ export default {
IonLabel, IonLabel,
IonRow, IonRow,
IonCol, IonCol,
IonContent IonContent,
AppPasswordModal,
}, },
data(){ data() {
return { return {
siteUrl: '', siteUrl: "",
userLogin: '', };
userPassword: '',
}
}, },
setup(){ setup() {
const image = computed (() => require('../assets/logo_square.png')); const image = computed(() => require("../assets/logo_square.png"));
let tainacanStore = useTainacanStore(); let tainacanStore = useTainacanStore();
let wpStore = useWpStore(); let wpStore = useWpStore();
return { image, tainacanStore, wpStore, arrowForwardOutline } return { image, tainacanStore, wpStore, arrowForwardOutline };
}, },
methods: { methods: {
async login(){ async openLoginForm() {
await this.wpStore.userLogin(this.siteUrl); this.wpStore.userSiteUrl = this.siteUrl;
// this.tainacanStore.siteUrl = this.siteUrl; await this.wpStore.fetchApplicationAuthorization(this.siteUrl);
// this.tainacanStore.userLogin = this.userLogin; if (this.wpStore.authorizationURL) {
// this.tainacanStore.userPassword = this.userPassword; this.wpStore.createInAppBrowser('?page=tainacan_mobile_app');
this.$router.push('/home'); this.wpStore.inAppBrowser
} .on("loadstop")
} .subscribe(this.handleBrowserLoadStop);
}
},
async handleBrowserLoadStop(event: InAppBrowserEvent) {
console.log(event)
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_mobile_app" ) {
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) {
await this.wpStore.login(
this.siteUrl,
userLogin,
userToken
);
this.$router.push("/home");
}
this.wpStore.inAppBrowser.hide();
}
}
},
},
};
</script> </script>
<style> <style>

View File

@ -16,10 +16,7 @@ const useTainacanStore = defineStore("tainacan", {
nextItemsByCollectionPage: 1, nextItemsByCollectionPage: 1,
items: [], items: [],
nextItemsPage: 1, nextItemsPage: 1,
totalItems: 0, totalItems: 0
siteUrl: "",
userLogin: "",
userPassword: "",
}; };
}, },
@ -29,6 +26,7 @@ const useTainacanStore = defineStore("tainacan", {
const wpStore = useWpStore(); const wpStore = useWpStore();
let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collections?`; let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collections?`;
const authorization = 'Basic ' + btoa(wpStore.userLogin + ':' + wpStore.userToken);
if (params && params.perPage) if (params && params.perPage)
endpoint += '&perpage=' + params.perPage; endpoint += '&perpage=' + params.perPage;
@ -36,7 +34,11 @@ const useTainacanStore = defineStore("tainacan", {
if (params && params.orderBy) if (params && params.orderBy)
endpoint += '&orderby=' + params.orderBy; endpoint += '&orderby=' + params.orderBy;
const response = await axios.get(endpoint); const response = await axios.get(endpoint, {
headers: {
authorization: authorization
}
});
this.collections = response.data; this.collections = response.data;
this.totalCollections = response.headers['x-wp-total']; this.totalCollections = response.headers['x-wp-total'];
@ -55,8 +57,13 @@ const useTainacanStore = defineStore("tainacan", {
const wpStore = useWpStore(); const wpStore = useWpStore();
const endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collections?perpage=4&orderby=modified`; const endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collections?perpage=4&orderby=modified`;
const authorization = 'Basic ' + btoa(wpStore.userLogin + ':' + wpStore.userToken);
const response = await axios.get(endpoint); const response = await axios.get(endpoint, {
headers: {
authorization: authorization
}
});
this.homeCollections = response.data; this.homeCollections = response.data;
this.totalHomeCollections = response.headers['x-wp-total']; this.totalHomeCollections = response.headers['x-wp-total'];
@ -75,6 +82,7 @@ const useTainacanStore = defineStore("tainacan", {
const wpStore = useWpStore(); const wpStore = useWpStore();
let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collection/${collectionId}/items?fetch_only=id,title,thumbnail`; let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collection/${collectionId}/items?fetch_only=id,title,thumbnail`;
const authorization = 'Basic ' + btoa(wpStore.userLogin + ':' + wpStore.userToken);
if (params && params.perPage) if (params && params.perPage)
endpoint += '&perpage=' + params.perPage; endpoint += '&perpage=' + params.perPage;
@ -96,7 +104,11 @@ const useTainacanStore = defineStore("tainacan", {
endpoint += '&paged=' + this.nextItemsByCollectionPage; endpoint += '&paged=' + this.nextItemsByCollectionPage;
const response = await axios.get(endpoint); const response = await axios.get(endpoint, {
headers: {
authorization: authorization
}
});
this.collectionItems.push(...response.data.items); this.collectionItems.push(...response.data.items);
this.totalCollectionItems = response.headers['x-wp-total']; this.totalCollectionItems = response.headers['x-wp-total'];
@ -120,8 +132,14 @@ const useTainacanStore = defineStore("tainacan", {
const wpStore = useWpStore(); const wpStore = useWpStore();
const endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/items?fetch_only=id,title,thumbnail&perpage=12&orderby=modified`; const endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/items?fetch_only=id,title,thumbnail&perpage=12&orderby=modified`;
const authorization = 'Basic ' + btoa(wpStore.userLogin + ':' + wpStore.userToken);
const response = await axios.get(endpoint, {
headers: {
authorization: authorization
}
});
const response = await axios.get(endpoint);
this.homeItems = response.data.items; this.homeItems = response.data.items;
this.totalHomeItems = response.headers['x-wp-total']; this.totalHomeItems = response.headers['x-wp-total'];
@ -138,6 +156,7 @@ const useTainacanStore = defineStore("tainacan", {
const wpStore = useWpStore(); const wpStore = useWpStore();
let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/items?fetch_only=id,title,thumbnail`; let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/items?fetch_only=id,title,thumbnail`;
const authorization = 'Basic ' + btoa(wpStore.userLogin + ':' + wpStore.userToken);
if (params && params.perPage) if (params && params.perPage)
endpoint += '&perpage=' + params.perPage; endpoint += '&perpage=' + params.perPage;
@ -148,14 +167,19 @@ const useTainacanStore = defineStore("tainacan", {
if (params && params.search && params.search !== '') if (params && params.search && params.search !== '')
endpoint += '&search=' + params.search endpoint += '&search=' + params.search
if(params.reset){ if (params.reset) {
this.items = []; this.items = [];
this.nextItemsPage = 1; this.nextItemsPage = 1;
} }
endpoint += '&paged=' + this.nextItemsPage; endpoint += '&paged=' + this.nextItemsPage;
const response = await axios.get(endpoint); const response = await axios.get(endpoint, {
headers: {
authorization: authorization
}
});
this.items.push(...response.data.items); this.items.push(...response.data.items);
this.totalItems = response.headers['x-wp-total']; this.totalItems = response.headers['x-wp-total'];

View File

@ -1,50 +1,151 @@
import { defineStore } from 'pinia'; import { defineStore } from "pinia";
import { Storage } from '@ionic/storage' ; import axios from "axios";
import { Storage } from "@ionic/storage";
import {
InAppBrowser,
InAppBrowserObject,
} from "@awesome-cordova-plugins/in-app-browser/index";
const store = new Storage(); const store = new Storage();
const useWpStore = defineStore('wp', { const useWpStore = defineStore("wp", {
state () { state() {
return { return {
userIsLoggedIn: false, userIsLoggedIn: false,
userSiteUrl: '', userSiteUrl: "",
} userLogin: "",
}, userToken: "",
authorizationURL: "",
inAppBrowser: InAppBrowserObject,
};
},
actions: { actions: {
async userLogin(userSiteUrl: string) { async login(userSiteUrl: string, userLogin: string, userToken: string) {
try { try {
this.userIsLoggedIn = true; this.userIsLoggedIn = true;
this.userSiteUrl = userSiteUrl; this.userSiteUrl = userSiteUrl;
await store.set('userIsLoggedIn', true); this.userLogin = userLogin;
await store.set('userSiteUrl', userSiteUrl); this.userToken = userToken;
} catch (err) { await store.set("userIsLoggedIn", true);
this.userIsLoggedIn = false; await store.set("userSiteUrl", userSiteUrl);
await store.set('userIsLoggedIn', false); await store.set("userLogin", userLogin);
console.error('Erro no login:', err); await store.set("userToken", userToken);
return err; } catch (err) {
} this.userIsLoggedIn = false;
}, this.userSiteUrl = "";
async userLogOff() { this.userToken = "";
try { this.userLogin = "";
this.userIsLoggedIn = false; delete this.inAppBrowser;
this.userSiteUrl = null; console.error("Erro no login:", err);
await store.set('userIsLoggedIn', false); return err;
await store.set('userSiteUrl', null); }
} catch (err) { },
this.userIsLoggedIn = false; async logoff() {
await store.set('userIsLoggedIn', false); try {
console.error('Erro no login:', err); this.userIsLoggedIn = false;
return err; this.userSiteUrl = "";
} this.userToken = "";
}, this.userToken = "";
async checkUserLogin() { delete this.inAppBrowser;
await store.create(); await store.set("userIsLoggedIn", false);
this.userIsLoggedIn = await store.get('userIsLoggedIn'); await store.set("userSiteUrl", "");
this.userSiteUrl = await store.get('userSiteUrl'); await store.set("userToken", "");
} } catch (err) {
this.userIsLoggedIn = false;
this.userSiteUrl = "";
this.userToken = "";
this.userToken = "";
delete this.inAppBrowser;
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(url = '',extraParams = 'location=no,fullscreen=no,zoom=no,hardwareback=yes') {
let tainacanAdminUrl = this.userSiteUrl + "/wp-admin/admin.php" + url;
if (!this.userIsLoggedIn && this.authorizationURL)
tainacanAdminUrl = this.authorizationURL + "?app_name=TainacanMobileApp&success_url=" + tainacanAdminUrl;
const anInAppBrowser = InAppBrowser.create(tainacanAdminUrl, '_blank', extraParams);
this.inAppBrowser = anInAppBrowser;
},
openInAppBrowser(url: string) {
if (!this.inAppBrowser || !this.inAppBrowser.executeScript)
this.createInAppBrowser(url, 'hidden=yes,location=no,fullscreen=no,zoom=no,hardwareback=yes');
const urlRedirectionScript = `
try {
window.history.replaceState(
null,
null,
'${this.userSiteUrl}/wp-admin/admin.php?page=tainacan_mobile_app'
);
window.history.pushState(
null,
null,
'${this.userSiteUrl}/wp-admin/admin.php${url}'
);
window.history.go(0);
} catch(err){
console.log('catch', err);
}`;
this.inAppBrowser.executeScript({ code: urlRedirectionScript });
this.inAppBrowser.show();
},
hideInAppBrowser() {
if (this.inAppBrowser && this.inAppBrowser.hide)
this.inAppBrowser.hide();
},
listenEventInAppBrowser(event: any) {
this.inAppBrowser.on('message').subscribe(event);
this.inAppBrowser.on('exit').subscribe(() => {
delete this.inAppBrowser;
});
this.inAppBrowser.on("loadstop").subscribe((event: any) => {
if (
event.url &&
typeof event.url == "string" &&
event.url.split("?") &&
event.url.split("?").length >= 2
) {
const params = event.url.split("?")[1];
if ( params.indexOf("tainacan_mobile_app") >= 0)
this.inAppBrowser.hide();
}
});
} }
}) },
export { });
useWpStore export { useWpStore };
}