diff --git a/README.md b/README.md index 95a2fff..75b8694 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # WatchList -WatcHList application that lets you track movies and TV +WatchList application that lets you track movies and TV Requirements: WatchList-Backend service (See my other repo) +This app has the ability to search IMDB for a movie or TV show within the API if you provide a RapidAPI IMDB key on the backend service. See the README on my WatchList-Backend repo for details. + 1. npm install 1. ionic build 1. Move contents of www to web server diff --git a/android/.idea/deploymentTargetDropDown.xml b/android/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index 93b1543..0000000 --- a/android/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..31d0754 --- /dev/null +++ b/build.bat @@ -0,0 +1,4 @@ +@echo off +ionic build +ionic cap copy +ionic cap sync \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..4644a3f --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +ionic build +ionic cap copy +ionic cap sync \ No newline at end of file diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 66be20e..18d3253 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -9,7 +9,7 @@ const routes: Routes = [ ]; @NgModule({ imports: [ - RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) + RouterModule.forRoot(routes,{ preloadingStrategy: PreloadAllModules }) ], exports: [RouterModule] }) diff --git a/src/app/core/data.service.ts b/src/app/core/data.service.ts index 0763257..1367c5c 100644 --- a/src/app/core/data.service.ts +++ b/src/app/core/data.service.ts @@ -13,6 +13,7 @@ import { Storage } from '@ionic/storage'; export class DataService { auth_key=``; backendURL=``; + IMDBSearchEnabled = false; imdb_url_missing = false; incompleteFilter = true; isAdding = false; @@ -26,7 +27,7 @@ export class DataService { watchListItems: any; watchListNames: any; // This contains a full, unfiltered copy of watchListItems that is used for the names watchListQueue: any; - watchListSources: []; + watchListSources: []; watchListTypes: []; private readonly watchListColumnSizes = { @@ -68,8 +69,8 @@ export class DataService { this.platform = platform; if (this.platform.is('android') || this.platform.is('ios')) - this.isMobilePlatform=true; - + this.isMobilePlatform=true; + this.getAuthKey(); } @@ -164,7 +165,7 @@ export class DataService { if (this.auth_key == null || this.auth_key == '') alert("Please set the Auth Key"); - else + else this.getBackendURL(); // Get Saved backend URL; } @@ -323,12 +324,12 @@ export class DataService { } getWatchListSources() { - return this.processStep(`/GetWatchListSources`,null); + return this.processStep(`/GetWatchListSources`,null); } getWatchListSourcesSubscription() { this.getWatchListSources().subscribe((response) => { - this.watchListSources=response; + this.watchListSources=response; }, error => { this.handleError(error); @@ -336,7 +337,7 @@ export class DataService { } getWatchListTVStats() { - return this.processStep(`/GetWatchListTVStats`,null); + return this.processStep(`/GetWatchListTVStats`,null); } getWatchListTypes() { @@ -366,6 +367,10 @@ export class DataService { return throwError(error || 'Node.js server error'); } + isIMDBSearchEnabled() { + return this.processStep(`/IsIMDBSearchEnabled`,null); + } + processStep(path: string, params: HttpParams): Observable { if (params == null) params = new HttpParams(); @@ -409,6 +414,16 @@ export class DataService { }, 2000); } + searchIMDB(searchTerm: string) { + let params = new HttpParams(); + + if (searchTerm !== "") { + params = params.append('SearchTerm',searchTerm); + } + + return this.processStep(`/SearchIMDB`,params); + } + async setAuthKey() { if (this.auth_key != null && this.auth_key != "") { await this.storage.set('AuthKey', this.auth_key); diff --git a/src/app/imdb-search/imdb-search-routing.module.ts b/src/app/imdb-search/imdb-search-routing.module.ts new file mode 100644 index 0000000..38a5aa7 --- /dev/null +++ b/src/app/imdb-search/imdb-search-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { IMDBSearchPage } from './imdb-search.page'; + +const routes: Routes = [ + { + path: '', + component: IMDBSearchPage, + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class IMDBSearchPageRoutingModule {} diff --git a/src/app/imdb-search/imdb-search.module.ts b/src/app/imdb-search/imdb-search.module.ts new file mode 100644 index 0000000..dccc770 --- /dev/null +++ b/src/app/imdb-search/imdb-search.module.ts @@ -0,0 +1,18 @@ +import { IonicModule } from '@ionic/angular'; +import { NgModule, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IMDBSearchPage } from './imdb-search.page'; + +import { IMDBSearchPageRoutingModule } from './imdb-search-routing.module'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + IMDBSearchPageRoutingModule + ], + declarations: [IMDBSearchPage] +}) +export class IMDBSearchPageModule {} diff --git a/src/app/imdb-search/imdb-search.page.html b/src/app/imdb-search/imdb-search.page.html new file mode 100644 index 0000000..2fca266 --- /dev/null +++ b/src/app/imdb-search/imdb-search.page.html @@ -0,0 +1,42 @@ + + + + + + IMDB Search + + + + + + + + + + + + + + + + +
+ + + + + + {{ currSearchResult['Title'] }} ( {{ currSearchResult['Year'] }} ) + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/src/app/imdb-search/imdb-search.page.scss b/src/app/imdb-search/imdb-search.page.scss new file mode 100644 index 0000000..600cf59 --- /dev/null +++ b/src/app/imdb-search/imdb-search.page.scss @@ -0,0 +1,36 @@ + +.ion-list-parent { + width: 100%; + overflow: auto; +} + +ion-col { + vertical-align: top; +} + +ion-content { + overflow: auto; +} + +ion-icon { + width: 35px; + height: 35px; +} + +ion-img { + width: 200px; + height: 200px; +} + +ion-input { + border-style: dashed; + border-width: 1px; +} + +ion-label { + font-size: 28px; +} + +ion-label.labelMobile { + font-size: 18px; +} \ No newline at end of file diff --git a/src/app/imdb-search/imdb-search.page.ts b/src/app/imdb-search/imdb-search.page.ts new file mode 100644 index 0000000..b3801f5 --- /dev/null +++ b/src/app/imdb-search/imdb-search.page.ts @@ -0,0 +1,54 @@ +import { Component } from '@angular/core'; +import { DataService } from '../core/data.service'; + +@Component({ + selector: 'app-imdbsearch', + templateUrl: 'imdb-search.page.html', + styleUrls: ['imdb-search.page.scss'] +}) +export class IMDBSearchPage { + searchTerm = ''; + searchResults: any; + + constructor(public dataService: DataService) { } + + addSearchResult(currSearchResult: any, index: number) { + const currWatchListItem: any=[]; + currWatchListItem.Name=currSearchResult['Title']; + + if (currSearchResult['Type'] == "movie") + currWatchListItem.Type=1 + else if (currSearchResult['Type'] == "series") + currWatchListItem.Type=2 + else + currWatchListItem.Type=3 // Other + + currWatchListItem.IMDB_URL=`https://www.imdb.com/title/${currSearchResult['imdbID']}/` + + this.dataService.addWatchListItem(currWatchListItem).subscribe((response) => { + this.searchResults.splice(index,1); // Remove it from the the search results since its been added + + this.dataService.getWatchListItemsSubscription(true); + }, + error => { + this.dataService.handleError(error); + }); + } + + handleKeyUp(e) { // Submit search when enter is pressed in search field + if (e.keyCode === 13) // Submit when enter is pressed + this.searchIMDB(); + } + + searchIMDB() { + if (this.searchTerm != '' && this.searchTerm != null) { + this.dataService.searchIMDB(this.searchTerm).subscribe((response) => { + this.searchResults=Object.entries(response)[0][1]; // This contains the actual search results + }, + error => { + console.log(`An error occurred searching IMDB`) + }); + } else + alert("Please enter a search term"); + } +} \ No newline at end of file diff --git a/src/app/tabs/tabs-routing.module.ts b/src/app/tabs/tabs-routing.module.ts index c289dff..0669537 100644 --- a/src/app/tabs/tabs-routing.module.ts +++ b/src/app/tabs/tabs-routing.module.ts @@ -1,7 +1,8 @@ import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; +import { RouterModule, Router, Routes } from '@angular/router'; import { TabsPage } from './tabs.page'; import { AuthGuardService as AuthGuard } from '../core/auth-guard-service'; +import { DataService } from '../core/data.service'; const routes: Routes = [ { @@ -23,6 +24,11 @@ const routes: Routes = [ loadChildren: () => import('../watchlist-queue/watchlistqueue.module').then(m => m.WatchListQueuePageModule), canActivate: [AuthGuard] }, + { + path: 'imdb-search', // The route settings are always here but this route won't get activated if IMDB API key is not provided because the IMDB Search tab gets hidden when API key is not present + loadChildren: () => import('../imdb-search/imdb-search.module').then(m => m.IMDBSearchPageModule), + canActivate: [AuthGuard] + }, { path: 'watchlist-stats', loadChildren: () => import('../watchlist-stats/watchlist-stats.modules').then(m => m.WatchListStatsPageModule), diff --git a/src/app/tabs/tabs.page.html b/src/app/tabs/tabs.page.html index 8245922..0f70c29 100644 --- a/src/app/tabs/tabs.page.html +++ b/src/app/tabs/tabs.page.html @@ -15,6 +15,11 @@ Watchlist Queue + + + IMDB Search + + Watchlist Stats diff --git a/src/app/tabs/tabs.page.ts b/src/app/tabs/tabs.page.ts index a1b2dd1..6101873 100644 --- a/src/app/tabs/tabs.page.ts +++ b/src/app/tabs/tabs.page.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { DataService } from '../core/data.service'; @Component({ selector: 'app-tabs', @@ -7,5 +8,14 @@ import { Component } from '@angular/core'; }) export class TabsPage { - constructor() {} + IMDBSearchEnabled = false; + + constructor(public dataService: DataService) { + this.dataService.isIMDBSearchEnabled().subscribe((response) => { + this.IMDBSearchEnabled=response; + }, + error => { + alert(`The error ${error.error.toString()} occurred calling isIMDBSearchEnabled() in TabsPage`) + }); + } }