File

src/app/tab1/tab1.page.ts

Implements

OnInit

Metadata

selector app-tab1
styleUrls tab1.page.scss
templateUrl tab1.page.html

Index

Properties
Methods

Constructor

constructor(modalControler: ModalController, nuevaS: NuevaServiceService, loadingController: LoadingController, controlerAceptar: AlertController, alertCtrl: AlertController, afa: AngularFireAuth, nativeStorage: NativeStorage, translate: TranslateService, appComponent: AppComponent, toastController: ToastController, menuController: MenuController)

Llama al método encargado de inicializar los elementos de la página

Parameters :
Name Type Optional Description
modalControler ModalController No

Controlador de la ventana modal

nuevaS NuevaServiceService No

Servicio propio para interactuar con Firebase

loadingController LoadingController No

Controlador del cargando...

controlerAceptar AlertController No

Controlador de la alerta

alertCtrl AlertController No

Controlador de la alerta

afa AngularFireAuth No

Módulo de autenticación de angular

nativeStorage NativeStorage No

Módulo nativo de la base de datos local

translate TranslateService No

Módulo de traducción

appComponent AppComponent No

Componente de la página principal

toastController ToastController No

Controlador de las toasts

menuController MenuController No

Methods

aceptarOferta
aceptarOferta(item: any)

Añade a los aceptados de la oferta el usuario actual

Parameters :
Name Type Optional Description
item any No

Oferta que se va a aceptar

Returns : void
animateIndicator
animateIndicator(e)
Parameters :
Name Optional
e No
Returns : void
doRefresh
doRefresh(refresher)
Parameters :
Name Optional
refresher No
Returns : void
initializeItems
initializeItems()
Returns : void
ionViewDidEnter
ionViewDidEnter()

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()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Async nuevaOfertaModal
nuevaOfertaModal()

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)

Método asíncrono que presenta el cargando...

Parameters :
Name Optional Description
msg No

Mensaje que va a mostrar

Returns : {}
Async presentToast
presentToast()

Método asíncrono que muestra un toast

Returns : any
rellenaAceptadas
rellenaAceptadas()

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)
Parameters :
Name Type Optional
cat Promise<any> No
Returns : void
updateIndicatorPosition
updateIndicatorPosition()
Returns : void

Properties

aceptadas
Type : []
Default value : []
category
Type : any
dynamicList
Decorators :
@ViewChild('dynamicList')
email
Type : any
ionInfiniteScroll
Type : IonInfiniteScroll
Decorators :
@ViewChild('infiniteScroll')
listado
Type : []
Default value : []
listado2
Type : []
Default value : []
listadoPanel
Type : []
Default value : []
listadoPanel2
Type : []
Default value : []
Public loadingController
Type : LoadingController
Controlador del cargando...
ntabs
Type : number
Default value : 2
SwipedTabsIndicator
Type : any
Default value : null
Private SwipedTabsSlider
Type : IonSlides
Decorators :
@ViewChild('SwipedTabsSlider')
tabs
Type : []
Default value : ['selectTab(0)', 'selectTab(1)']
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%;
}



Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""