From dbf9bb919d40e3a33c65c62fa93415a40a900e25 Mon Sep 17 00:00:00 2001 From: PhantomPainX Date: Sat, 12 Aug 2023 15:43:51 -0400 Subject: [PATCH] feat: seen episodes history page --- src/app/app-routing.module.ts | 4 + src/app/app.component.html | 4 + .../embeds-popover.component.html | 14 +- .../embeds-popover.component.ts | 35 +- .../videos-popover.component.html | 4 +- .../user-detail/reports/reports.page.html | 2 +- .../user-detail/user-detail.page.html | 8 +- src/app/pages/auth/signin/signin.page.ts | 6 +- src/app/pages/directorio/directorio.page.ts | 2 + src/app/pages/favorites/favorites.page.ts | 2 + src/app/pages/home/home.page.html | 6 +- src/app/pages/home/home.page.ts | 33 +- .../pages/home/see-more/see-more.page.html | 2 +- src/app/pages/home/see-more/see-more.page.ts | 33 +- .../blocked-users/blocked-users.page.html | 2 +- .../seen-episodes-history-routing.module.ts | 17 + .../seen-episodes-history.module.ts | 22 ++ .../seen-episodes-history.page.html | 108 ++++++ .../seen-episodes-history.page.scss | 35 ++ .../seen-episodes-history.page.spec.ts | 17 + .../seen-episodes-history.page.ts | 322 ++++++++++++++++++ src/app/services/mysql-database.service.ts | 32 ++ src/app/services/utils.service.ts | 44 ++- .../video-player/video-player.service.ts | 14 +- 24 files changed, 713 insertions(+), 55 deletions(-) create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history-routing.module.ts create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history.module.ts create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history.page.html create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history.page.scss create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history.page.spec.ts create mode 100644 src/app/pages/seen-episodes-history/seen-episodes-history.page.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index bf8fb9f..16a834c 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -91,6 +91,10 @@ const routes: Routes = [ path: 'web-video-player', loadChildren: () => import('./modals/web-video-player/web-video-player.module').then( m => m.WebVideoPlayerPageModule) }, + { + path: 'seen-episodes-history', + loadChildren: () => import('./pages/seen-episodes-history/seen-episodes-history.module').then( m => m.SeenEpisodesHistoryPageModule) + }, ]; @NgModule({ diff --git a/src/app/app.component.html b/src/app/app.component.html index 9cfb3a6..ce22ad7 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -78,6 +78,10 @@

Invitado

Favoritos + + + Historial + Administración diff --git a/src/app/components/embeds-popover/embeds-popover.component.html b/src/app/components/embeds-popover/embeds-popover.component.html index 5dd738b..46dcfd5 100644 --- a/src/app/components/embeds-popover/embeds-popover.component.html +++ b/src/app/components/embeds-popover/embeds-popover.component.html @@ -20,7 +20,7 @@

{{ animeName }}

- + Local Web @@ -28,14 +28,18 @@

{{ animeName }}

- - {{embed.embed}} + + +

{{embed.embed}}

+
- - {{embed.embed}} + + +

{{embed.embed}}

+
diff --git a/src/app/components/embeds-popover/embeds-popover.component.ts b/src/app/components/embeds-popover/embeds-popover.component.ts index ba68d4f..2e711ce 100644 --- a/src/app/components/embeds-popover/embeds-popover.component.ts +++ b/src/app/components/embeds-popover/embeds-popover.component.ts @@ -11,6 +11,7 @@ import { VideosPopoverComponent } from '../videos-popover/videos-popover.compone import { DownloadService } from 'src/app/services/download/download.service'; import { UtilsService } from 'src/app/services/utils.service'; import { Domains } from './domains'; +import { MysqlDatabaseService } from 'src/app/services/mysql-database.service'; @Component({ selector: 'app-embeds-popover', @@ -40,6 +41,8 @@ export class EmbedsPopoverComponent implements OnInit { private videoDomains = new Domains; + public buttonsClickable: boolean = false; + constructor( public resolvers: ResolversService, public popoverCtrl: PopoverController, @@ -49,21 +52,13 @@ export class EmbedsPopoverComponent implements OnInit { public localStorage: PreferencesService, public platform: Platform, public downloadService: DownloadService, - public utils: UtilsService + public utils: UtilsService, + private database: MysqlDatabaseService ) { } - ngOnInit() { - - // se obtiene el episodio siguiente - for (let ep of this.episode.anime.episodios) { - if (ep.numero == this.episode.numero + 1) { - this.episode['nextEpisode'] = ep; - } - } - - console.log("Episodio actualizado en embeds popover: ", this.episode); + async ngOnInit() { if (!this.embedRequested) { this.localCompatible = this.embeds.filter(embed => @@ -123,9 +118,27 @@ export class EmbedsPopoverComponent implements OnInit { this.user = await this.localStorage.getUser(); } + if (!this.episode.anime.episodios) { + await this.database.getAnimeDetail(this.episode.anime.id, this.user.token).then(async (res: any) => { + this.episode.anime.episodios = res.episodios; + this.buttonsClickable = true; + }); + } else { + this.buttonsClickable = true; + } + // se obtiene el episodio siguiente + for (let ep of this.episode.anime.episodios) { + if (ep.numero == this.episode.numero + 1) { + this.episode['nextEpisode'] = ep; + } + } + + console.log("Episodio actualizado en embeds popover: ", this.episode); + this.deserveAd = await this.localStorage.getDeserveAd(); this.settings = await this.localStorage.getSettings(); }); + } else { this.webCompatible = this.embeds; this.optionValue = 'web'; diff --git a/src/app/components/videos-popover/videos-popover.component.html b/src/app/components/videos-popover/videos-popover.component.html index 58ba4a4..5c8ed41 100644 --- a/src/app/components/videos-popover/videos-popover.component.html +++ b/src/app/components/videos-popover/videos-popover.component.html @@ -25,7 +25,9 @@

{{ title }}

- {{video.label}} + +

{{video.label}}

+
diff --git a/src/app/pages/admin/see-users/user-detail/reports/reports.page.html b/src/app/pages/admin/see-users/user-detail/reports/reports.page.html index 485d477..991eec1 100644 --- a/src/app/pages/admin/see-users/user-detail/reports/reports.page.html +++ b/src/app/pages/admin/see-users/user-detail/reports/reports.page.html @@ -23,7 +23,7 @@

{{ r.reporter_user.username }}

-

{{ utils.formatDate(r.created_at) }}

+

{{ utils.formatFullDate(r.created_at) }}

diff --git a/src/app/pages/admin/see-users/user-detail/user-detail.page.html b/src/app/pages/admin/see-users/user-detail/user-detail.page.html index d5467d2..deb6bdf 100644 --- a/src/app/pages/admin/see-users/user-detail/user-detail.page.html +++ b/src/app/pages/admin/see-users/user-detail/user-detail.page.html @@ -155,7 +155,7 @@

Baneado por:

Fecha del ban:

-

{{ utils.formatDate(consultedUser.user_extra.ban_date) }}

+

{{ utils.formatFullDate(consultedUser.user_extra.ban_date) }}

@@ -163,21 +163,21 @@

Fecha del ban:

Fecha de registro

-

{{ utils.formatDate(consultedUser.date_joined) }}

+

{{ utils.formatFullDate(consultedUser.date_joined) }}

Último inicio de sesión

-

{{ utils.formatDate(consultedUser.last_login) }}

+

{{ utils.formatFullDate(consultedUser.last_login) }}

Fecha de última modificación de perfil

-

{{ utils.formatDate(consultedUser.user_extra.updated_at) }}

+

{{ utils.formatFullDate(consultedUser.user_extra.updated_at) }}

diff --git a/src/app/pages/auth/signin/signin.page.ts b/src/app/pages/auth/signin/signin.page.ts index 60c988c..b72ce15 100644 --- a/src/app/pages/auth/signin/signin.page.ts +++ b/src/app/pages/auth/signin/signin.page.ts @@ -134,7 +134,7 @@ export class SigninPage implements OnInit { GoogleAuth.signOut(); this.alertCtrl.create({ header: "Baneado por " + res.user.user_extra.ban_admin.username, - subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatDate(res.user.user_extra.ban_date) + ")", + subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatFullDate(res.user.user_extra.ban_date) + ")", message: "Si crees que esto es un error, contacta con nosotros a través del correo electrónico contacto@dangoanime.com", mode: 'ios', translucent: true, @@ -306,7 +306,7 @@ export class SigninPage implements OnInit { if (!res.user.is_active) { this.alertCtrl.create({ header: "Baneado por " + res.user.user_extra.ban_admin.username, - subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatDate(res.user.user_extra.ban_date) + ")", + subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatFullDate(res.user.user_extra.ban_date) + ")", message: "Si crees que esto es un error, contacta con nosotros a través del correo electrónico contacto@dangoanime.com", mode: 'ios', translucent: true, @@ -512,7 +512,7 @@ export class SigninPage implements OnInit { if (!res.user.is_active) { this.alertCtrl.create({ header: "Baneado por " + res.user.user_extra.ban_admin.username, - subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatDate(res.user.user_extra.ban_date) + ")", + subHeader: "Motivo: " + res.user.user_extra.ban_reason + " (" + this.utils.formatFullDate(res.user.user_extra.ban_date) + ")", message: "Si crees que esto es un error, contacta con nosotros a través del correo electrónico contacto@dangoanime.com", mode: 'ios', translucent: true, diff --git a/src/app/pages/directorio/directorio.page.ts b/src/app/pages/directorio/directorio.page.ts index 6efb478..ab4c1db 100644 --- a/src/app/pages/directorio/directorio.page.ts +++ b/src/app/pages/directorio/directorio.page.ts @@ -301,8 +301,10 @@ export class DirectorioPage implements OnInit { }); } + const subHeaderText = "Agregado el " + this.utils.formatDayPretty(anime.agregado) + " " + this.utils.formatDay(anime.agregado) + " de " + this.utils.formatMonthPretty(anime.agregado) + " del " + this.utils.formatYear(anime.agregado) + " a las " + this.utils.formatTimePretty(anime.agregado); const actionSheet = await this.actionSheetCtrl.create({ header: anime.nombre, + subHeader: subHeaderText, buttons: buttons }); await actionSheet.present(); diff --git a/src/app/pages/favorites/favorites.page.ts b/src/app/pages/favorites/favorites.page.ts index 2d276ee..8150f47 100644 --- a/src/app/pages/favorites/favorites.page.ts +++ b/src/app/pages/favorites/favorites.page.ts @@ -204,8 +204,10 @@ export class FavoritesPage implements OnInit { }); } + const subHeaderText = "Agregado el " + this.utils.formatDayPretty(anime.agregado) + " " + this.utils.formatDay(anime.agregado) + " de " + this.utils.formatMonthPretty(anime.agregado) + " del " + this.utils.formatYear(anime.agregado) + " a las " + this.utils.formatTimePretty(anime.agregado); const actionSheet = await this.actionSheetCtrl.create({ header: anime.nombre, + subHeader: subHeaderText, buttons: buttons }); await actionSheet.present(); diff --git a/src/app/pages/home/home.page.html b/src/app/pages/home/home.page.html index d43ca0d..8589717 100644 --- a/src/app/pages/home/home.page.html +++ b/src/app/pages/home/home.page.html @@ -61,8 +61,8 @@

Episodio {{ episode.nu

{{episode.anime.nombre}}

{{episode.anime.nombre}}

-

Visto {{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

-

Visto {{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

+

{{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

+

{{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

@@ -195,7 +195,7 @@

{{ anime.nombre }}

{{ episode.anime.nombre }}

Episodio {{ episode.numero }}

{{ utils.dateAgo(episode.fecha) }}

-

Visto {{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

+

{{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

diff --git a/src/app/pages/home/home.page.ts b/src/app/pages/home/home.page.ts index a201c9b..4bdd208 100644 --- a/src/app/pages/home/home.page.ts +++ b/src/app/pages/home/home.page.ts @@ -338,17 +338,26 @@ export class HomePage implements OnInit { async openProviders(event, episode) { if (!this.platform.is('capacitor')) { - const modal = await this.modalCtrl.create({ - component: WebVideoPlayerPage, - cssClass: 'rounded-modal', - breakpoints: [0, 1], - initialBreakpoint: 1, - // canDismiss: false, - componentProps: { - episode: episode - } - }) - modal.present(); + const loader = await this.utils.createIonicLoader("Cargando reproductor..."); + await loader.present(); + this.database.getAnimeDetail(episode.anime.id, this.token).then(async anime => { + await loader.dismiss(); + episode.anime = anime; + const modal = await this.modalCtrl.create({ + component: WebVideoPlayerPage, + cssClass: 'rounded-modal', + breakpoints: [0, 1], + initialBreakpoint: 1, + // canDismiss: false, + componentProps: { + episode: episode + } + }) + modal.present(); + }).catch(async () => { + await loader.dismiss(); + this.utils.showToast("Ha ocurrido un error, intenta más tarde", 2, false); + }); } else { if (!episode.anime.imagen.includes(this.domain)) { episode.anime.imagen = this.domain + episode.anime.imagen; @@ -568,8 +577,10 @@ export class HomePage implements OnInit { }); } + const subHeaderText = "Agregado el " + this.utils.formatDayPretty(anime.agregado) + " " + this.utils.formatDay(anime.agregado) + " de " + this.utils.formatMonthPretty(anime.agregado) + " del " + this.utils.formatYear(anime.agregado) + " a las " + this.utils.formatTimePretty(anime.agregado); const actionSheet = await this.actionSheetCtrl.create({ header: anime.nombre, + subHeader: subHeaderText, buttons: buttons }); await actionSheet.present(); diff --git a/src/app/pages/home/see-more/see-more.page.html b/src/app/pages/home/see-more/see-more.page.html index 49ec1a0..091b813 100644 --- a/src/app/pages/home/see-more/see-more.page.html +++ b/src/app/pages/home/see-more/see-more.page.html @@ -116,7 +116,7 @@

{{ episode.anime.nombre }}

Episodio {{ episode.numero }}

{{ utils.dateAgo(episode.fecha) }}

-

Visto {{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

+

{{utils.formatSeconds(episode.seconds_seen.seconds)}} de {{utils.formatSeconds(episode.seconds_seen.total_seconds)}}

diff --git a/src/app/pages/home/see-more/see-more.page.ts b/src/app/pages/home/see-more/see-more.page.ts index 422f086..c319114 100644 --- a/src/app/pages/home/see-more/see-more.page.ts +++ b/src/app/pages/home/see-more/see-more.page.ts @@ -460,17 +460,26 @@ export class SeeMorePage implements OnInit { async openProviders(event, episode) { if (!this.platform.is('capacitor')) { - const modal = await this.modalCtrl.create({ - component: WebVideoPlayerPage, - cssClass: 'rounded-modal', - breakpoints: [0, 1], - initialBreakpoint: 1, - // canDismiss: false, - componentProps: { - episode: episode - } - }) - modal.present(); + const loader = await this.utils.createIonicLoader("Cargando reproductor..."); + await loader.present(); + this.database.getAnimeDetail(episode.anime.id, this.token).then(async anime => { + await loader.dismiss(); + episode.anime = anime; + const modal = await this.modalCtrl.create({ + component: WebVideoPlayerPage, + cssClass: 'rounded-modal', + breakpoints: [0, 1], + initialBreakpoint: 1, + // canDismiss: false, + componentProps: { + episode: episode + } + }) + modal.present(); + }).catch(async () => { + await loader.dismiss(); + this.utils.showToast("Ha ocurrido un error, intenta más tarde", 2, false); + }); } else { const popover = await this.popoverCtrl.create({ component: ProvidersPopoverComponent, @@ -601,8 +610,10 @@ export class SeeMorePage implements OnInit { }); } + const subHeaderText = "Agregado el " + this.utils.formatDayPretty(anime.agregado) + " " + this.utils.formatDay(anime.agregado) + " de " + this.utils.formatMonthPretty(anime.agregado) + " del " + this.utils.formatYear(anime.agregado) + " a las " + this.utils.formatTimePretty(anime.agregado); const actionSheet = await this.actionSheetCtrl.create({ header: anime.nombre, + subHeader: subHeaderText, buttons: buttons }); await actionSheet.present(); diff --git a/src/app/pages/profile/blocked-users/blocked-users.page.html b/src/app/pages/profile/blocked-users/blocked-users.page.html index f3d4f9e..b0adb41 100644 --- a/src/app/pages/profile/blocked-users/blocked-users.page.html +++ b/src/app/pages/profile/blocked-users/blocked-users.page.html @@ -40,7 +40,7 @@

{{ d.blocked_user_detail.username }}

-

{{ utils.formatDate(d.created_at) }}

+

{{ utils.formatFullDate(d.created_at) }}

diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history-routing.module.ts b/src/app/pages/seen-episodes-history/seen-episodes-history-routing.module.ts new file mode 100644 index 0000000..24c85fe --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { SeenEpisodesHistoryPage } from './seen-episodes-history.page'; + +const routes: Routes = [ + { + path: '', + component: SeenEpisodesHistoryPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class SeenEpisodesHistoryPageRoutingModule {} diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history.module.ts b/src/app/pages/seen-episodes-history/seen-episodes-history.module.ts new file mode 100644 index 0000000..1cdd8e2 --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { SeenEpisodesHistoryPageRoutingModule } from './seen-episodes-history-routing.module'; + +import { SeenEpisodesHistoryPage } from './seen-episodes-history.page'; +import { LazyLoadImageModule } from 'ng-lazyload-image'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + SeenEpisodesHistoryPageRoutingModule, + LazyLoadImageModule + ], + declarations: [SeenEpisodesHistoryPage] +}) +export class SeenEpisodesHistoryPageModule {} diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history.page.html b/src/app/pages/seen-episodes-history/seen-episodes-history.page.html new file mode 100644 index 0000000..e09a26a --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history.page.html @@ -0,0 +1,108 @@ + + + + + + Historial + + + + + + + + + +

Recientes

+ +
+ + +

Antiguos

+ +
+
+
+
+ +
+
+ + + + + + + + + {{ totalResults }} resultado + {{ totalResults }} resultados + + + + + + +
+ +

No has visto ningún episodio

+

(Los episodios que salen en esta sección son los que has visto recientemente en la aplicación)

+
+ + + + + + + +

{{ episode.episode_data.anime.nombre }}

+
Episodio {{ episode.episode_data.numero }}
+

Visto {{ utils.dateAgo(episode.updated_at) }}

+

{{utils.formatSeconds(episode.seconds)}} de {{utils.formatSeconds(episode.total_seconds)}}

+
+ + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history.page.scss b/src/app/pages/seen-episodes-history/seen-episodes-history.page.scss new file mode 100644 index 0000000..2884510 --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history.page.scss @@ -0,0 +1,35 @@ +ion-item { + ion-thumbnail { + img { + border-radius: 5px; + object-fit: cover; + } + } +} + +.centerInfo { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + height: 100%; + + p.info { + text-align: center; + font-size: 11px; + margin: 0 20px; + } + + ion-icon { + font-size: 50px !important; + color: #ccc; + } +} + +ion-title[size="large"] { + font-size: 34px; + } + + ion-app.md .header-collapse-condense { + display: block; + } \ No newline at end of file diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history.page.spec.ts b/src/app/pages/seen-episodes-history/seen-episodes-history.page.spec.ts new file mode 100644 index 0000000..d37898f --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { SeenEpisodesHistoryPage } from './seen-episodes-history.page'; + +describe('SeenEpisodesHistoryPage', () => { + let component: SeenEpisodesHistoryPage; + let fixture: ComponentFixture; + + beforeEach(async(() => { + fixture = TestBed.createComponent(SeenEpisodesHistoryPage); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/seen-episodes-history/seen-episodes-history.page.ts b/src/app/pages/seen-episodes-history/seen-episodes-history.page.ts new file mode 100644 index 0000000..d881d91 --- /dev/null +++ b/src/app/pages/seen-episodes-history/seen-episodes-history.page.ts @@ -0,0 +1,322 @@ +import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { ActionSheetController, IonInfiniteScroll, ModalController, NavController, Platform, PopoverController } from '@ionic/angular'; +import { ProvidersPopoverComponent } from 'src/app/components/providers-popover/providers-popover.component'; +import { CommentPage } from 'src/app/modals/comment/comment.page'; +import { MysqlDatabaseService } from 'src/app/services/mysql-database.service'; +import { PreferencesService } from 'src/app/services/preferences/preferences.service'; +import { UtilsService } from 'src/app/services/utils.service'; +import { environment } from 'src/environments/environment.prod'; +import { EpisodePage } from '../episode/episode.page'; +import { WebVideoPlayerPage } from 'src/app/modals/web-video-player/web-video-player.page'; +import { VideoPlayerService } from 'src/app/services/video-player/video-player.service'; +import { Subscription } from 'rxjs'; + +@Component({ + selector: 'app-seen-episodes-history', + templateUrl: './seen-episodes-history.page.html', + styleUrls: ['./seen-episodes-history.page.scss'], +}) +export class SeenEpisodesHistoryPage implements OnInit { + + @ViewChild(IonInfiniteScroll) public infiniteScroll: IonInfiniteScroll; + @ViewChild('toolbar', { read: ElementRef }) public toolbar: ElementRef; + @ViewChild('sortPopover') public sortPopover: any; + public isSortPopoverOpened: boolean = false; + + public domain: string = environment.root_url; + public results: any; + private pagination: any; + private isLogged: boolean = false; + private token: string = ""; + + public totalResults: number = 0; + public noResults: boolean = false; + public loading: boolean = true; + public sortName: string = '-updated_at'; + + private episodeTimeSeenChangedSubscription: Subscription; + + constructor( + private modalCtrl: ModalController, + private database: MysqlDatabaseService, + private popoverCtrl: PopoverController, + public utils: UtilsService, + private actionSheetCtrl: ActionSheetController, + private platform: Platform, + private navCtrl: NavController, + private localStorage: PreferencesService, + private videoPlayerService: VideoPlayerService, + public zone: NgZone + ) { } + + ngOnInit() { + this.platform.ready().then(async () => { + this.isLogged = await this.localStorage.getLogged(); + if (this.isLogged) { + const user = await this.localStorage.getUser(); + this.token = user.token; + + this.episodeTimeSeenChangedSubscription = this.videoPlayerService.episodeTimeSeenChanged$.subscribe(async () => { + this.zone.run(() => { + this.getResults(this.sortName); + }); + }); + } else { + this.navCtrl.navigateRoot('/signin'); + } + + await this.getResults(this.sortName); + this.loading = false; + }); + } + + ngOnDestroy() { + if (this.episodeTimeSeenChangedSubscription) { + this.episodeTimeSeenChangedSubscription.unsubscribe(); + } + } + + private async getResults(ordering: string) : Promise { + + await this.database.getSeenEpisodesHistory(1, ordering, this.token).then(data => { + this.results = data.results; + console.log(this.results); + this.totalResults = data.count; + this.pagination = { + 'actualPage': 1, + 'hasNextPage': data.next != null, + } + // this.results = []; + // console.log(this.results); + // this.totalResults = 0; + // this.pagination = { + // 'actualPage': 1, + // 'hasNextPage': false, + // } + }); // no hay catch porque los errores se controlan en el servicio + + if (this.results.length == 0) { + this.noResults = true; + //this.infiniteScroll.disabled = true; + } + } + + public loadMoreResults(event) { + if (this.pagination.hasNextPage) { + + this.database.getSeenEpisodesHistory(this.pagination.actualPage + 1, this.sortName, this.token).then(data => { + this.results = this.results.concat(data.results); + this.pagination = { + 'actualPage': this.pagination.actualPage + 1, + 'hasNextPage': data.next != null, + } + event.target.complete(); + }); // no hay catch porque los errores se controlan en el servicio + + } else { + event.target.complete(); + this.infiniteScroll.disabled = true; + } + } + + public async goToAnimeDetail(anime: any) { + this.navCtrl.navigateForward('/detail/'+anime.id); + } + + public async openProviders(event, episode) { + + if (!this.platform.is('capacitor')) { + + const loader = await this.utils.createIonicLoader("Cargando reproductor..."); + await loader.present(); + this.database.getAnimeDetail(episode.episode_data.anime.id, this.token).then(async anime => { + await loader.dismiss(); + episode.episode_data.anime = anime; + const modal = await this.modalCtrl.create({ + component: WebVideoPlayerPage, + cssClass: 'rounded-modal', + breakpoints: [0, 1], + initialBreakpoint: 1, + // canDismiss: false, + componentProps: { + episode: episode.episode_data + } + }) + modal.present(); + }).catch(async () => { + await loader.dismiss(); + this.utils.showToast("Ha ocurrido un error, intenta más tarde", 2, false); + }); + } else { + const popover = await this.popoverCtrl.create({ + component: ProvidersPopoverComponent, + cssClass: "custom-popover", + event: event, + componentProps: { + episode: episode.episode_data, + animeImage: episode.episode_data.anime.imagen, + animeName: episode.episode_data.anime.nombre + } + }); + + await popover.present(); + } + } + + public close() { + this.navCtrl.back(); + } + + public async toggleRefresh(event) { + await this.getResults(this.sortName); + event.target.complete(); + } + + + // Opciones Extras + + private async toggleFavorite(anime: any) { + const loader = await this.utils.createLoaderToast("Espera un momento...", "sync"); + await loader.present(); + + await this.database.toggleFavoriteAnime(this.token, anime.id).then((added) => { + + loader.dismiss(); + if (added) { + this.utils.showIconToast(anime.nombre+" fue agregado a tus favoritos", "heart", 2); + } else { + this.utils.showIconToast(anime.nombre+" fue eliminado de tus favoritos", "trash", 2); + } + }).catch(() => { + loader.dismiss(); + }); + } + + private async toggleEpisode(episode: any) { + const loader = await this.utils.createIonicLoader("Espera un momento..."); + await loader.present(); + + await this.database.toggleSeenEpisode(this.token, episode.id).then((added) => { + + if (added) { + this.utils.showToast("Marcado como visto", 1, true); + } else { + this.utils.showToast("Desmarcado como visto", 1, true); + } + }).catch(error => { + console.log(error); + }); + await loader.dismiss(); + } + + private async openEpisodesModal(anime: any) { + const modal = await this.modalCtrl.create({ + component: EpisodePage, + cssClass: 'rounded-modal', + canDismiss: true, + breakpoints: [0, 1], + initialBreakpoint: 1, + componentProps: { + anime: anime, + totalEpisodes: anime.episodios.length + } + }); + await modal.present(); + } + + public async openEpisodeOptions(episode: any) { + + var buttons = [{ + text: 'Ver Detalle', + icon: 'information-circle', + handler: () => { + this.goToAnimeDetail(episode.episode_data.anime); + } + }, + { + text: 'Descargar', + icon: 'cloud-download', + handler: async () => { + if (!this.platform.is('capacitor')) { + this.utils.showToast("No disponible en la web, descarga la aplicación", 1, false); + return; + } + const popover = await this.popoverCtrl.create({ + component: ProvidersPopoverComponent, + cssClass: "custom-popover", + componentProps: { + download: true, + episode: episode.episode_data, + animeImage: episode.episode_data.anime.imagen, + animeName: episode.episode_data.anime.nombre + } + }); + + popover.present(); + } + }, { + text: 'Ver Comentarios', + icon: 'chatbubbles', + handler: () => { + this.modalCtrl.create({ + component: CommentPage, + cssClass: 'rounded-modal', + canDismiss: true, + breakpoints: [0, 1], + initialBreakpoint: 1, + componentProps: { + episode: episode.episode_data, + commentsType: 'episode' + } + }).then(modal => { + modal.present(); + }); + } + }, { + text: 'Cerrar', + role: 'cancel', + icon: 'close' + }]; + + + if (this.isLogged) { + buttons.push({ + text: 'Añadir / Eliminar de favoritos', + icon: 'heart', + handler: () => { + this.toggleFavorite(episode.episode_data.anime); + } + }, { + text: 'Marcar como visto / No visto', + icon: 'eye', + handler: () => { + this.toggleEpisode(episode.episode_data); + } + }, { + text: 'Cerrar', + role: 'cancel', + icon: 'close' + }); + } + + console.log(episode); + const actionSheet = await this.actionSheetCtrl.create({ + header: episode.episode_data.anime.nombre, + buttons: buttons + }); + await actionSheet.present(); + } + + public openSortPopover(e: Event) { + this.sortPopover.event = e; + this.isSortPopoverOpened = true; + } + + public sort(sortName) { + this.sortName = sortName; + this.isSortPopoverOpened = false; + this.results = null; + this.getResults(sortName); + } + +} diff --git a/src/app/services/mysql-database.service.ts b/src/app/services/mysql-database.service.ts index da546bd..71e7c5b 100644 --- a/src/app/services/mysql-database.service.ts +++ b/src/app/services/mysql-database.service.ts @@ -57,6 +57,7 @@ export class MysqlDatabaseService { public amrGetAnimesByLang: boolean = false; public amrGetAnimesByYear: boolean = false; public amrCheckAndroidVersion: boolean = false; + public amrGetSeenEpisodesHistory: boolean = false; public recentlyLogged$: EventEmitter = new EventEmitter(); public toggleSeenEpisode$: EventEmitter = new EventEmitter(); @@ -1323,4 +1324,35 @@ export class MysqlDatabaseService { }); } + public getSeenEpisodesHistory(page: number, ordering: string, token: string) { + return new Promise((resolve) => { + const url = this.domain + "/api/v1/seen-episode-time/?ordering="+ordering+"&page=" + page; + + let headers = { + Authorization: 'Token ' + token + } + fetch(url, { + method: 'GET', + headers: headers + }) + .then(response => response.json()) + .then(data => { + resolve(data); + }).catch(() => { + if (!this.amrGetSeenEpisodesHistory) { + this.amrGetSeenEpisodesHistory = true; + const interval = setInterval(() => { + this.getSeenEpisodesHistory(page, ordering, token).then(data => { + resolve(data); + clearInterval(interval); + this.amrGetSeenEpisodesHistory = false; + }).catch(() => { + clearInterval(interval); + }); + }, 3000); + } + }); + }); + } + } diff --git a/src/app/services/utils.service.ts b/src/app/services/utils.service.ts index 84af765..f32331c 100644 --- a/src/app/services/utils.service.ts +++ b/src/app/services/utils.service.ts @@ -201,13 +201,55 @@ export class UtilsService { return myMoment.fromNow(); } - formatDate(date: string) { + formatFullDate(date: string) { //format date in DD/MM/YYYY HH:mm let myMoment: moment.Moment = moment(date); myMoment.locale('es'); return myMoment.format('DD/MM/YYYY HH:mm:ss'); } + formatDate(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('DD/MM/YYYY'); + } + + formatTime(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('HH:mm'); + } + + formatDayPretty(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('dddd'); + } + + formatDay(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('D'); + } + + formatMonthPretty(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('MMMM'); + } + + formatYear(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('YYYY'); + } + + formatTimePretty(date: string) { + let myMoment: moment.Moment = moment(date); + myMoment.locale('es'); + return myMoment.format('LT A'); + } + getFileReader(): FileReader { const fileReader = new FileReader(); const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"]; diff --git a/src/app/services/video-player/video-player.service.ts b/src/app/services/video-player/video-player.service.ts index 1ad86e4..4dba94e 100644 --- a/src/app/services/video-player/video-player.service.ts +++ b/src/app/services/video-player/video-player.service.ts @@ -26,6 +26,7 @@ export class VideoPlayerService { public exitHandler: any; public needSeek: boolean = false; public seekTime: number = 0; + public episodeWasMarkedAsSeen: boolean = false; public episodeTimeSeenChanged$: EventEmitter = new EventEmitter(); public recentlySawVideo$: EventEmitter = new EventEmitter(); @@ -99,6 +100,8 @@ export class VideoPlayerService { async executePlayer(video: any, subtitleUrl: string, title: string, smallTitle: string, image: string, episode: any, isLogged: boolean, user: any, settings: Settings, providerName: string, videoProviderDomains: any, videoProviderQuality: string) { + this.episodeWasMarkedAsSeen = false; + let options: capVideoPlayerOptions = { mode: 'fullscreen', url: video.file, @@ -156,6 +159,7 @@ export class VideoPlayerService { if (((info.currentTime * 100) / this.videoDuration) >= 70) { // 70% console.log("Visto: "+ JSON.stringify(info)); if (isLogged && !episode.seen) { + this.episodeWasMarkedAsSeen = true; this.toggleEpisode(episode, user.token); } @@ -183,7 +187,9 @@ export class VideoPlayerService { episode.seconds_seen.total_seconds = this.videoDuration; episode.seconds_seen.episode = episode.id; - this.episodeTimeSeenChanged$.emit(true); + if (!this.episodeWasMarkedAsSeen) { + this.episodeTimeSeenChanged$.emit(true); + } }); }); } @@ -226,6 +232,7 @@ export class VideoPlayerService { // this.seconds = 0; if (isLogged && !episode.seen) { + this.episodeWasMarkedAsSeen = true; this.toggleEpisode(episode, user.token); } @@ -237,7 +244,10 @@ export class VideoPlayerService { episode.seconds_seen.seconds = this.videoDuration; episode.seconds_seen.total_seconds = this.videoDuration; episode.seconds_seen.episode = episode.id; - this.episodeTimeSeenChanged$.emit(true); + + if (!this.episodeWasMarkedAsSeen) { + this.episodeTimeSeenChanged$.emit(true); + } }); }); }