src/app/tab1/tab1.page.ts
| selector | app-tab1 |
| styleUrls | tab1.page.scss |
| templateUrl | tab1.page.html |
Properties |
Methods |
constructor(modalControler: ModalController, nuevaS: NuevaServiceService, loadingController: LoadingController, controlerAceptar: AlertController, alertCtrl: AlertController, afa: AngularFireAuth, nativeStorage: NativeStorage, translate: TranslateService, appComponent: AppComponent, toastController: ToastController, menuController: MenuController)
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Defined in src/app/tab1/tab1.page.ts:49
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Llama al método encargado de inicializar los elementos de la página
Parameters :
|
| aceptarOferta | ||||||||
aceptarOferta(item: any)
|
||||||||
|
Defined in src/app/tab1/tab1.page.ts:166
|
||||||||
|
Añade a los aceptados de la oferta el usuario actual
Parameters :
Returns :
void
|
| animateIndicator | ||||
animateIndicator(e)
|
||||
|
Defined in src/app/tab1/tab1.page.ts:235
|
||||
|
Parameters :
Returns :
void
|
| doRefresh | ||||
doRefresh(refresher)
|
||||
|
Defined in src/app/tab1/tab1.page.ts:112
|
||||
|
Parameters :
Returns :
void
|
| initializeItems |
initializeItems()
|
|
Defined in src/app/tab1/tab1.page.ts:127
|
|
Returns :
void
|
| ionViewDidEnter |
ionViewDidEnter()
|
|
Defined in src/app/tab1/tab1.page.ts:88
|
|
Situa el indicador de los segments. Llama al método del servicio para leer las ofertas y rellena el array del panel Recupera el email del usuario actual y lo sustituye en el AppComponent
Returns :
void
|
| ionViewWillEnter |
ionViewWillEnter()
|
|
Defined in src/app/tab1/tab1.page.ts:210
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Defined in src/app/tab1/tab1.page.ts:79
|
|
Returns :
void
|
| Async nuevaOfertaModal |
nuevaOfertaModal()
|
|
Defined in src/app/tab1/tab1.page.ts:135
|
|
Método asíncrono que muestra la modal para una nueva oferta. Cuando se cierra vuelve a rellenar el listado
Returns :
any
|
| Async presentLoading | ||||||
presentLoading(msg)
|
||||||
|
Defined in src/app/tab1/tab1.page.ts:246
|
||||||
|
Método asíncrono que presenta el cargando...
Parameters :
Returns :
{}
|
| Async presentToast |
presentToast()
|
|
Defined in src/app/tab1/tab1.page.ts:285
|
|
Método asíncrono que muestra un toast
Returns :
any
|
| rellenaAceptadas |
rellenaAceptadas()
|
|
Defined in src/app/tab1/tab1.page.ts:258
|
|
Rellena la lista de las oferas aceptadas de la misma forma que rellena las del primer segment, pero filtrandolas (solo aparecen las ofrecidas por el usuario actual y las que el usuario actual ha aceptado)
Returns :
void
|
| updateCat | ||||||
updateCat(cat: Promise
|
||||||
|
Defined in src/app/tab1/tab1.page.ts:218
|
||||||
|
Parameters :
Returns :
void
|
| updateIndicatorPosition |
updateIndicatorPosition()
|
|
Defined in src/app/tab1/tab1.page.ts:226
|
|
Returns :
void
|
| aceptadas |
Type : []
|
Default value : []
|
|
Defined in src/app/tab1/tab1.page.ts:38
|
| category |
Type : any
|
|
Defined in src/app/tab1/tab1.page.ts:49
|
| dynamicList |
Decorators :
@ViewChild('dynamicList')
|
|
Defined in src/app/tab1/tab1.page.ts:33
|
Type : any
|
|
Defined in src/app/tab1/tab1.page.ts:44
|
| ionInfiniteScroll |
Type : IonInfiniteScroll
|
Decorators :
@ViewChild('infiniteScroll')
|
|
Defined in src/app/tab1/tab1.page.ts:32
|
| listado |
Type : []
|
Default value : []
|
|
Defined in src/app/tab1/tab1.page.ts:40
|
| listado2 |
Type : []
|
Default value : []
|
|
Defined in src/app/tab1/tab1.page.ts:35
|
| listadoPanel |
Type : []
|
Default value : []
|
|
Defined in src/app/tab1/tab1.page.ts:41
|
| listadoPanel2 |
Type : []
|
Default value : []
|
|
Defined in src/app/tab1/tab1.page.ts:36
|
| Public loadingController |
Type : LoadingController
|
|
Defined in src/app/tab1/tab1.page.ts:66
|
|
Controlador del cargando...
|
| ntabs |
Type : number
|
Default value : 2
|
|
Defined in src/app/tab1/tab1.page.ts:48
|
| SwipedTabsIndicator |
Type : any
|
Default value : null
|
|
Defined in src/app/tab1/tab1.page.ts:46
|
| Private SwipedTabsSlider |
Type : IonSlides
|
Decorators :
@ViewChild('SwipedTabsSlider')
|
|
Defined in src/app/tab1/tab1.page.ts:31
|
| tabs |
Type : []
|
Default value : ['selectTab(0)', 'selectTab(1)']
|
|
Defined in src/app/tab1/tab1.page.ts:47
|
import {Component, OnInit, ViewChild} from '@angular/core';
import {
AlertController,
IonInfiniteScroll,
IonSlides,
LoadingController,
MenuController,
ModalController,
ToastController
} from '@ionic/angular';
import {ModalNuevaPage} from '../modals/modal-nueva/modal-nueva.page';
import {NuevaServiceService} from '../services/nueva-service.service';
import {AngularFireAuth} from 'angularfire2/auth';
import {NativeStorage} from '@ionic-native/native-storage/ngx';
import {TranslateService} from '@ngx-translate/core';
import {AppComponent} from '../app.component';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page implements OnInit {
@ViewChild('SwipedTabsSlider') private SwipedTabsSlider: IonSlides;
@ViewChild('infiniteScroll') ionInfiniteScroll: IonInfiniteScroll;
@ViewChild('dynamicList') dynamicList;
listado2 = [];
listadoPanel2 = [];
aceptadas = [];
listado = [];
listadoPanel = [];
email: any;
SwipedTabsIndicator: any = null;
tabs = ['selectTab(0)', 'selectTab(1)'];
ntabs = 2;
category: any;
/**
* Llama al método encargado de inicializar los elementos de la página
* @param modalControler Controlador de la ventana modal
* @param nuevaS Servicio propio para interactuar con Firebase
* @param loadingController Controlador del cargando...
* @param controlerAceptar Controlador de la alerta
* @param alertCtrl Controlador de la alerta
* @param afa Módulo de autenticación de angular
* @param nativeStorage Módulo nativo de la base de datos local
* @param translate Módulo de traducción
* @param appComponent Componente de la página principal
* @param toastController Controlador de las toasts
*/
constructor(private modalControler: ModalController,
private nuevaS: NuevaServiceService,
public loadingController: LoadingController,
private controlerAceptar: AlertController,
private alertCtrl: AlertController,
private afa: AngularFireAuth,
private nativeStorage: NativeStorage,
private translate: TranslateService,
private appComponent: AppComponent,
private toastController: ToastController,
private menuController: MenuController) {
this.menuController.enable(true);
this.initializeItems();
}
ngOnInit() {
}
/**
* Situa el indicador de los segments.
* Llama al método del servicio para leer las ofertas y rellena el array del panel
* Recupera el email del usuario actual y lo sustituye en el AppComponent
*/
ionViewDidEnter() {
this.SwipedTabsIndicator = document.getElementById('indicator');
this.presentLoading(this.translate.instant('loading'));
this.nuevaS.leeOfertasFiltradas().then(
querySnapshot => {
this.listado = [];
querySnapshot.forEach((doc) => {
this.listado.push({id: doc.id, ...doc.data()});
});
this.listadoPanel = this.listado;
this.rellenaAceptadas();
this.email = this.afa.auth.currentUser.email;
console.log(this.email);
this.appComponent.setEmail(this.email);
}
);
}
/* Esta función es llamada por el componente Refresher de IONIC v4 */
doRefresh(refresher) {
this.nuevaS.leeOfertasFiltradas().then(
querySnapshot => {
this.listado = [];
querySnapshot.forEach((doc) => {
this.listado.push({id: doc.id, ...doc.data()});
});
this.listadoPanel = this.listado;
this.rellenaAceptadas();
refresher.target.complete();
}
);
}
initializeItems() {
this.listadoPanel = this.listado;
}
/**
* Método asíncrono que muestra la modal para una nueva oferta.
* Cuando se cierra vuelve a rellenar el listado
*/
async nuevaOfertaModal() {
const modal = await this.modalControler.create({
component: ModalNuevaPage
});
await modal.present();
await modal.onDidDismiss()
.then(response => {
this.nuevaS.leeOfertasFiltradas()
.then(querySnapshot => {
this.listado = [];
/* Es un hack para solucionar un bug con el refresher y las listas
dinámicas (ngFor) */
querySnapshot.forEach((doc) => {
this.listado.push({id: doc.id, ...doc.data()});
// this.mostarConfirmacion();
});
this.listadoPanel = this.listado;
});
this.rellenaAceptadas();
})
.catch(response => console.log(response));
}
/**
* Añade a los aceptados de la oferta el usuario actual
* @param item Oferta que se va a aceptar
*/
aceptarOferta(item: any) {
this.presentLoading(this.translate.instant('saving'));
this.aceptadas = item.aceptada;
this.aceptadas.push(this.afa.auth.currentUser.email);
// Guarda los datos del usuario con el nuevo array de aceptadas
const data = {
tipo: item.tipo,
plazas: item.plazas - 1,
fecha: item.fecha,
ofertante: item.ofertante,
lugar: item.lugar,
aceptada: this.aceptadas
};
// Llama al método de actualizarOferta del servicio, y vuelve a poner el array a vacio si tiene exito
this.nuevaS.actualizaOferta(item.id, data)
.then(() => {
console.log('ID insertado (por si lo necesitamos para algo...): ', item.id);
this.aceptadas = [];
this.presentToast();
})
.catch((error) => {
console.error('Error insertando documento: ', error);
});
// Vuelve a actualizar la lista del panel
this.nuevaS.leeOfertasFiltradas().then(
querySnapshot => {
this.listado = [];
querySnapshot.forEach((doc) => {
this.listado.push({id: doc.id, ...doc.data()});
});
this.listadoPanel = this.listado;
// this.rellenaAceptadas();
}
);
this.rellenaAceptadas();
this.loadingController.dismiss();
}
ionViewWillEnter() {
this.category = '0';
this.SwipedTabsSlider.length().then(l => { // no sería necesario aquí, solo en ngOnInit
this.ntabs = l;
});
}
/* Actualiza la categoría que esté en ese momento activa*/
updateCat(cat: Promise<any>) {
cat.then(dat => {
this.category = dat;
this.category = +this.category;
});
}
/* El método que permite actualizar el indicado cuando se cambia de slide*/
updateIndicatorPosition() {
this.SwipedTabsSlider.getActiveIndex().then(i => {
if (this.ntabs > i) {
this.SwipedTabsIndicator.style.webkitTransform = 'translate3d(' + (i * 100) + '%,0,0)';
}
});
}
/* El método que anima la "rayita" mientras nos estamos deslizando por el slide*/
animateIndicator(e) {
if (this.SwipedTabsIndicator) {
this.SwipedTabsIndicator.style.webkitTransform = 'translate3d(' +
((e.target.swiper.progress * (this.ntabs - 1)) * 100) + '%,0,0)';
}
}
/**
* Método asíncrono que presenta el cargando...
* @param msg Mensaje que va a mostrar
*/
async presentLoading(msg) {
const myloading = await this.loadingController.create({
message: msg
});
return await myloading.present();
}
/**
* Rellena la lista de las oferas aceptadas de la misma forma que rellena
* las del primer segment, pero filtrandolas (solo aparecen las ofrecidas por el
* usuario actual y las que el usuario actual ha aceptado)
*/
rellenaAceptadas() {
this.listadoPanel2 = [];
this.nuevaS.leeOfertasAceptadas().then(
querySnapshot3 => {
this.listado2 = [];
querySnapshot3.forEach((doc) => {
this.listado2.push({id: doc.id, ...doc.data()});
});
this.listado2.forEach((elemento) => {
if (elemento.ofertante === this.afa.auth.currentUser.email) {
this.listadoPanel2.push(elemento);
}
elemento.aceptada.forEach((emails) => {
if (emails === this.afa.auth.currentUser.email) {
this.listadoPanel2.push(elemento);
}
});
});
this.loadingController.dismiss();
}
);
}
/**
* Método asíncrono que muestra un toast
*/
async presentToast() {
const toast = await this.toastController.create({
message: this.translate.instant('acept_offer'),
duration: 3000
});
toast.present();
}
}
<ion-header no-border color="primary">
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-menu-toggle>
<ion-button>
<ion-icon name="menu" slot="icon-only"></ion-icon>
</ion-button>
</ion-menu-toggle>
</ion-buttons>
<ion-title>
ShareAce
</ion-title>
</ion-toolbar>
<ion-segment [(ngModel)]="category" (ionChange)="slides.slideTo(category)"
style="background-color:var(--ion-color-primary-tint)"
color="black">
<ion-segment-button layout="icon-start" value="0" style="--padding-end:0px;--padding-start:0px">
<ion-icon name="mail" style="margin-right:1px;zoom:0.8"></ion-icon>
<ion-label>{{'offers'|translate}}</ion-label>
</ion-segment-button>
<ion-segment-button layout="icon-start" value="1" style="--padding-end:0px;--padding-start:0px">
<ion-icon name="contacts" style="margin-right:1px;zoom:0.8"></ion-icon>
<ion-label>{{'accepted'|translate}}</ion-label>
</ion-segment-button>
</ion-segment>
<div id='indicator' class="SwipedTabs-indicatorSegment" [ngStyle]="
{'width.%': (100/this.tabs.length)}" style="margin-top:2px" color="primary"></div>
</ion-header>
<ion-content>
<ion-slides #slides (ionSlideTransitionStart)="updateIndicatorPosition();updateCat(slides.getActiveIndex())"
(ionSlideWillChange)="updateIndicatorPosition()" (ionSlideDidChange)="updateIndicatorPosition()"
#SwipedTabsSlider
(ionSlideDrag)="animateIndicator($event)">
<ion-slide>
<ion-content class="fixed-scroll">
<ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content
pullingIcon="arrow-dropdown"
pullingText="{{'drop'|translate}}"
refreshingSpinner="crescent"
refreshingText="{{'loading'|translate}}...">
</ion-refresher-content>
</ion-refresher>
<ion-list #dynamicList id="dynamicList">
<ion-item *ngFor="let item of listadoPanel;let i = index">
<ion-label><h2>{{item.tipo|translate}}</h2>
<p>{{'there_is'|translate}} {{item.plazas}} {{'available_seats'|translate}}.</p>
<p>{{ 'date' | translate}}: {{item.fecha}}</p>
<p>{{'offered_by'|translate}}: {{item.ofertante}}</p>
<p>{{'place'|translate}}: {{item.lugar}}</p>
</ion-label>
<ion-icon (click)="aceptarOferta(item)" name="checkmark-circle-outline"
style="font-size:30px"></ion-icon>
</ion-item>
</ion-list>
</ion-content>
</ion-slide>
<ion-slide>
<ion-content class="fixed-scroll">
<ion-content class="fixed-scroll">
<ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content
pullingIcon="arrow-dropdown"
pullingText="Arrastra para refrescar"
refreshingSpinner="crescent"
refreshingText="Cargando...">
</ion-refresher-content>
</ion-refresher>
<ion-list #dynamicList id="dynamicList2">
<ion-item *ngFor="let item of listadoPanel2;let i = index">
<ion-label><h2>{{item.tipo|translate}}</h2>
<p>{{'there_is'|translate}} {{item.plazas}} {{'available_seats'|translate}}.</p>
<p>{{ 'date' | translate}}: {{item.fecha}}</p>
<p>{{'offered_by'|translate}}: {{item.ofertante}}</p>
<p>{{'place'|translate}}: {{item.lugar}}</p></ion-label>
</ion-item>
</ion-list>
</ion-content>
</ion-content>
</ion-slide>
</ion-slides>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button (click)="nuevaOfertaModal()">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
tab1.page.scss
.welcome-card ion-img {
max-height: 35vh;
overflow: hidden;
}
/* la "rayita" que indica la navegación entre slides */
.SwipedTabs-indicatorSegment{
-webkit-transition: 0s all;
-moz-transition: 0s all;
-o-transition: 0s all;
transition: 0s all;
transform-origin: left 0;
height: 2px;
position: relative;
top: -2px;
background-color: var(--ion-color-primary) !important;
}
.button-native{
padding:0px !important;
}
ion-slide.swiper-slide {
display:block;
}
.slides{
height: 100%;
}