Update to Angular 7

Transactions
Dan 2019-01-21 13:31:36 -07:00
parent 227b2557be
commit e7d6e8fc22
54 changed files with 4176 additions and 3884 deletions

View File

@ -1,4 +1,4 @@
# Editor configuration, see http://editorconfig.org # Editor configuration, see https://editorconfig.org
root = true root = true
[*] [*]

5
Client/.gitignore vendored
View File

@ -8,6 +8,10 @@
# dependencies # dependencies
/node_modules /node_modules
# profiling files
chrome-profiler-events.json
speed-measure-plugin.json
# IDEs and editors # IDEs and editors
/.idea /.idea
.project .project
@ -23,6 +27,7 @@
!.vscode/tasks.json !.vscode/tasks.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
.history/*
# misc # misc
/.sass-cache /.sass-cache

View File

@ -1,6 +1,6 @@
# Client # Ofbclient
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.1. This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.2.
## Development server ## Development server

View File

@ -3,7 +3,7 @@
"version": 1, "version": 1,
"newProjectRoot": "projects", "newProjectRoot": "projects",
"projects": { "projects": {
"Client": { "ofbclient": {
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"projectType": "application", "projectType": "application",
@ -19,8 +19,9 @@
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json", "tsConfig": "src/tsconfig.app.json",
"assets": [ "assets": [
"src/web-app-files", "src/favicon.ico",
"src/assets" "src/assets",
"src/web-app-files"
], ],
"styles": [ "styles": [
"src/styles.css" "src/styles.css"
@ -43,25 +44,32 @@
"aot": true, "aot": true,
"extractLicenses": true, "extractLicenses": true,
"vendorChunk": false, "vendorChunk": false,
"buildOptimizer": true "buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
} }
} }
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"options": { "options": {
"browserTarget": "Client:build" "browserTarget": "ofbclient:build"
}, },
"configurations": { "configurations": {
"production": { "production": {
"browserTarget": "Client:build:production" "browserTarget": "ofbclient:build:production"
} }
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"browserTarget": "Client:build" "browserTarget": "ofbclient:build"
} }
}, },
"test": { "test": {
@ -95,15 +103,21 @@
} }
} }
}, },
"Client-e2e": { "ofbclient-e2e": {
"root": "e2e/", "root": "e2e/",
"projectType": "application", "projectType": "application",
"prefix": "",
"architect": { "architect": {
"e2e": { "e2e": {
"builder": "@angular-devkit/build-angular:protractor", "builder": "@angular-devkit/build-angular:protractor",
"options": { "options": {
"protractorConfig": "e2e/protractor.conf.js", "protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "Client:serve" "devServerTarget": "ofbclient:serve"
},
"configurations": {
"production": {
"devServerTarget": "ofbclient:serve:production"
}
} }
}, },
"lint": { "lint": {
@ -118,5 +132,5 @@
} }
} }
}, },
"defaultProject": "Client" "defaultProject": "ofbclient"
} }

View File

@ -1,4 +1,5 @@
import { AppPage } from './app.po'; import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => { describe('workspace-project App', () => {
let page: AppPage; let page: AppPage;
@ -9,6 +10,14 @@ describe('workspace-project App', () => {
it('should display welcome message', () => { it('should display welcome message', () => {
page.navigateTo(); page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to app!'); expect(page.getTitleText()).toEqual('Welcome to ofbclient!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
}));
}); });
}); });

View File

@ -5,7 +5,7 @@ export class AppPage {
return browser.get('/'); return browser.get('/');
} }
getParagraphText() { getTitleText() {
return element(by.css('app-root h1')).getText(); return element(by.css('app-root h1')).getText();
} }
} }

7160
Client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{ {
"name": "client", "name": "ofbclient",
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
@ -11,41 +11,41 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^6.0.0", "@angular/animations": "^7.2.1",
"@angular/cdk": "^6.0.2", "@angular/cdk": "^7.2.1",
"@angular/common": "^6.0.0", "@angular/common": "~7.2.0",
"@angular/compiler": "^6.0.0", "@angular/compiler": "~7.2.0",
"@angular/core": "^6.0.0", "@angular/core": "~7.2.0",
"@angular/forms": "^6.0.0", "@angular/forms": "~7.2.0",
"@angular/http": "^6.0.0", "@angular/material": "^7.2.1",
"@angular/material": "^6.0.2", "@angular/platform-browser": "~7.2.0",
"@angular/platform-browser": "^6.0.0", "@angular/platform-browser-dynamic": "~7.2.0",
"@angular/platform-browser-dynamic": "^6.0.0", "@angular/router": "~7.2.0",
"@angular/router": "^6.0.0",
"core-js": "^2.5.4", "core-js": "^2.5.4",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"rxjs": "^6.0.0", "rxjs": "~6.3.3",
"zone.js": "^0.8.26" "tslib": "^1.9.0",
"zone.js": "~0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular/compiler-cli": "^6.0.0", "@angular-devkit/build-angular": "~0.12.0",
"@angular-devkit/build-angular": "~0.6.1", "@angular/cli": "~7.2.2",
"typescript": "~2.7.2", "@angular/compiler-cli": "~7.2.0",
"@angular/cli": "~6.0.1", "@angular/language-service": "~7.2.0",
"@angular/language-service": "^6.0.0",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4", "@types/node": "~8.9.4",
"codelyzer": "~4.2.1", "@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1", "jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1", "jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1", "karma": "~3.1.1",
"karma-chrome-launcher": "~2.2.0", "karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~1.4.2", "karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.1", "karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2", "karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.3.0", "protractor": "~5.4.0",
"ts-node": "~5.0.1", "ts-node": "~7.0.0",
"tslint": "~5.9.1" "tslint": "~5.11.0",
"typescript": "~3.2.2"
} }
} }

View File

@ -0,0 +1,66 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
//Components
import { HomeComponent } from './components/home/home.component';
import { WhoWeAreComponent } from './components/whoweare/whoweare.component';
import { ServicesComponent } from './components/services/services.component';
import { SermonsComponent } from './components/sermons/sermons.component';
import { LocationComponent } from './components/location/location.component';
import { EventsPageComponent } from './components/events-page/events-page.component';
import { ContactPageComponent } from './components/contact-page/contact-page.component';
import { SalvationPageComponent } from './components/salvation-page/salvation-page.component';
const routes =
[
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},{
path: 'home',
component: HomeComponent
},
{
path: 'whoweare',
component: WhoWeAreComponent
},
{
path: 'services',
component: ServicesComponent
},
{
path: 'contact',
component: ContactPageComponent
},
{
path: 'sermons',
component: SermonsComponent
},
{
path: 'sermons/:id',
component: SermonsComponent
},
{
path: 'location',
component: LocationComponent
},
{
path: 'events',
component: EventsPageComponent
},
{
path: 'events/:id',
component: EventsPageComponent
},
{
path: 'salvation',
component: SalvationPageComponent
}
]
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

View File

@ -4,18 +4,15 @@ import { WindowRefService } from './services/window-ref.service';
import { EmailService } from './services/email.service'; import { EmailService } from './services/email.service';
import { SermonService } from './services/sermon.service'; import { SermonService } from './services/sermon.service';
import { LoginService } from './services/login.service'; import { LoginService } from './services/login.service';
import { ProgressService } from './services/xhr-progress.service';
import { ProgressXhr } from './extensions/xhr-progress.extension';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { HttpModule, BrowserXhr } from '@angular/http'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { MatButtonModule, import { MatButtonModule,
MatInputModule, MatInputModule,
MatSliderModule, MatSliderModule,
MatSnackBarModule, MatSnackBarModule,
MatDialogModule } from '@angular/material'; MatDialogModule } from '@angular/material';
import { RouterModule } from '@angular/router';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import 'hammerjs'; import 'hammerjs';
@ -58,54 +55,8 @@ import { DurationPipe } from './pipes/duration.pipe';
import { SafeUrlPipe } from './pipes/safe-url.pipe'; import { SafeUrlPipe } from './pipes/safe-url.pipe';
import { OfbDatePipe } from './pipes/ofb-date.pipe'; import { OfbDatePipe } from './pipes/ofb-date.pipe';
// Routing
const Routes = import { AppRoutingModule } from './app-routing.module';
[
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},{
path: 'home',
component: HomeComponent
},
{
path: 'whoweare',
component: WhoWeAreComponent
},
{
path: 'services',
component: ServicesComponent
},
{
path: 'contact',
component: ContactPageComponent
},
{
path: 'sermons',
component: SermonsComponent
},
{
path: 'sermons/:id',
component: SermonsComponent
},
{
path: 'location',
component: LocationComponent
},
{
path: 'events',
component: EventsPageComponent
},
{
path: 'events/:id',
component: EventsPageComponent
},
{
path: 'salvation',
component: SalvationPageComponent
}
]
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -145,8 +96,9 @@ const Routes =
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule,
FormsModule, FormsModule,
HttpModule, HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
//Angular Material Components //Angular Material Components
MatButtonModule, MatButtonModule,
@ -154,10 +106,8 @@ const Routes =
MatSliderModule, MatSliderModule,
MatSnackBarModule, MatSnackBarModule,
MatDialogModule, MatDialogModule,
RouterModule.forRoot(Routes)
], ],
providers: [LoginService,GoogleAnalyticsService,SermonService,EventService,ProgressService,EmailService,WindowRefService,{provide:BrowserXhr,useClass:ProgressXhr}], providers: [LoginService,GoogleAnalyticsService,SermonService,EventService,EmailService,WindowRefService],
entryComponents: [AddSermonPopupComponent, entryComponents: [AddSermonPopupComponent,
LoginPopupComponent, LoginPopupComponent,
OkPopupComponent, OkPopupComponent,
@ -168,11 +118,4 @@ const Routes =
AddEventPopupComponent], AddEventPopupComponent],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { }
export class AppModule {
public routes = Routes;
}

View File

@ -27,7 +27,7 @@
</a> </a>
<p><a href="tel:+1-406-494-5028" class="phone">(406) 494 - 5028</a></p> <p><a href="tel:+1-406-494-5028" class="phone">(406) 494 - 5028</a></p>
<p>Pastor Ron Derksen</p> <p>Pastor Ron Derksen</p>
<p>Assistant Pastor Derek Loewen</p> <p>Associate Pastor Derek Loewen</p>
</div> </div>
<div id="footer-services-content" class="footer-panel"> <div id="footer-services-content" class="footer-panel">
<p>Sunday School: 10AM</p> <p>Sunday School: 10AM</p>

View File

@ -59,8 +59,8 @@ export class EventsPageComponent implements OnInit {
this.events = []; this.events = [];
} }
this.eventService.getEvents(1).subscribe( this.eventService.getEvents(1).subscribe(
events => { eventReponse => {
this.addEvents(events); this.addEvents(eventReponse.events);
this.loading = false; this.loading = false;
}, },
error => console.error(error) error => console.error(error)
@ -71,13 +71,14 @@ export class EventsPageComponent implements OnInit {
this.events = []; this.events = [];
this.loading = true; this.loading = true;
this.eventService.getSingleEvent(id).subscribe(event => { this.eventService.getSingleEvent(id).subscribe(event => {
this.events.push(event); this.events.push(event.event);
this.loading = false; this.loading = false;
this.googleAnalyticsService.shareEventConversion(event.id,event.title); this.googleAnalyticsService.shareEventConversion(event.event.id,event.event.title);
}); });
} }
addEvents(events: Event[]): void{ addEvents(events: Event[]): void{
console.log(events);
for(let i = 0; i < events.length; i++){ for(let i = 0; i < events.length; i++){
this.events.push(events[i]); this.events.push(events[i]);
} }

View File

@ -167,7 +167,7 @@ img.full {
text-align: center; text-align: center;
} }
img.full { img.full {
width: 70%; width: 90%;
} }
} }

View File

@ -7,12 +7,15 @@
<div id="content-wrapper"> <div id="content-wrapper">
<div class="row tint" *ngIf="showSpecial"> <div class="row tint" *ngIf="showSpecial" >
<div class="row-content"> <div class="row-content">
<div class="row-content-col-left">
<a href="assets/images/champ_flyer.jpg" download="champ_flyer.jpg"><img class="full" ofbFadeInOnScroll src="assets/images/home-images/tiny/champ.jpg" height="300"></a>
</div>
<div class="row-content-col-right align-top center"> <div class="row-content-col-right align-top center">
<p ofbFadeInOnScroll class="row-content-header">Champ the Smiling Trick Horse</p> <p ofbFadeInOnScroll class="row-content-header">Champ the Smiling Trick Horse</p>
<p ofbFadeInOnScroll> <p ofbFadeInOnScroll>
Come join us for this special event happening September 5th and 6th at Old Fashion Baptist!. Come join us for this special event happening September 5th and 6th at Old Fashion Baptist!
</p> </p>
<br> <br>
<p ofbFadeInOnScroll> <p ofbFadeInOnScroll>
@ -35,9 +38,6 @@
<i ofbicon>phone</i> <a href="tel:+1-406-494-5028" class="align-top">406-494-5028</a> <i ofbicon>phone</i> <a href="tel:+1-406-494-5028" class="align-top">406-494-5028</a>
</p> </p>
</div> </div>
<div class="row-content-col-left">
<a href="assets/images/champ_flyer.jpg" download="champ_flyer.jpg"><img class="full" ofbFadeInOnScroll src="assets/images/home-images/tiny/champ.jpg" height="300"></a>
</div>
</div> </div>
</div> </div>

View File

@ -98,7 +98,7 @@ export class AddEventPopupComponent implements OnInit {
this.eventService.addEvent(e).subscribe( this.eventService.addEvent(e).subscribe(
data=>{ data=>{
this.updateAddButton(true); this.updateAddButton(true);
this.MatDialogRef.close(data.sermon); this.MatDialogRef.close(data['event']);
}, },
error => { error => {
this.updateAddButton(true); this.updateAddButton(true);

View File

@ -1,19 +1,19 @@
import { OkPopupComponent } from './../ok-popup/ok-popup.component'; import { OkPopupComponent } from './../ok-popup/ok-popup.component';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { ProgressService } from './../../../services/xhr-progress.service';
import { LoginPopupComponent } from './../login-popup/login-popup.component'; import { LoginPopupComponent } from './../login-popup/login-popup.component';
import { MatDialog, MatDialogRef, MatSnackBar } from '@angular/material'; import { MatDialog, MatDialogRef, MatSnackBar } from '@angular/material';
import { Sermon } from './../../../interfaces/sermon'; import { Sermon } from './../../../interfaces/sermon';
import { SermonService } from './../../../services/sermon.service'; import { SermonService } from './../../../services/sermon.service';
import { LoginService } from './../../../services/login.service'; import { LoginService } from './../../../services/login.service';
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpEvent, HttpEventType } from '@angular/common/http';
@Component({ @Component({
selector: 'app-add-sermon-popup', selector: 'app-add-sermon-popup',
templateUrl: './add-sermon-popup.component.html', templateUrl: './add-sermon-popup.component.html',
styleUrls: ['./add-sermon-popup.component.css'] styleUrls: ['./add-sermon-popup.component.css']
}) })
export class AddSermonPopupComponent implements OnInit, OnDestroy { export class AddSermonPopupComponent implements OnInit {
public addSermonButtonText: string = "Add Sermon"; public addSermonButtonText: string = "Add Sermon";
public addSermonButtonDisabled: boolean = false; public addSermonButtonDisabled: boolean = false;
@ -25,25 +25,16 @@ export class AddSermonPopupComponent implements OnInit, OnDestroy {
public errorMessages: string[] = []; public errorMessages: string[] = [];
private _uploadTotal: number = 100;
private _uploadProgress: number = 25;
public uploadTotal: number = 100; public uploadTotal: number = 100;
public uploadProgress: number = 0; public uploadProgress: number = 0;
public monitorProgress: boolean; public monitorProgress: boolean;
private progressSubscription: Subscription; private progressSubscription: Subscription;
constructor(private progressService: ProgressService, private MatDialog: MatDialog, private MatDialogRef: MatDialogRef<AddSermonPopupComponent>, private loginService: LoginService, private sermonService: SermonService) { } constructor(private MatDialog: MatDialog, private MatDialogRef: MatDialogRef<AddSermonPopupComponent>, private loginService: LoginService, private sermonService: SermonService) { }
ngOnInit() { ngOnInit() {
this.progressSubscription = this.progressService.uploadProgress.subscribe(evt => {
this._uploadTotal = evt.total;
this._uploadProgress = evt.loaded;
});
}
ngOnDestroy(){
this.progressSubscription.unsubscribe();
} }
onSubmit(){ onSubmit(){
@ -106,30 +97,43 @@ export class AddSermonPopupComponent implements OnInit, OnDestroy {
s.title = this.sermonTitle; s.title = this.sermonTitle;
s.author = this.sermonSpeaker; s.author = this.sermonSpeaker;
s.description = this.sermonDescription; s.description = this.sermonDescription;
s.sermonDate = this.sermonDate; s.date = this.sermonDate;
//Start monitoring Progress //Start monitoring Progress
this.monitorProgress = true; this.monitorProgress = true;
let timer = setInterval(()=>{
this.uploadTotal = this._uploadTotal;
this.uploadProgress = this._uploadProgress;
},500);
this.sermonService.addSermon(s,this.sermonFile).subscribe( this.sermonService.addSermon(s,this.sermonFile).subscribe(
data=>{ data => {this.getEventMessage(data); },
this.updateAddButton(true);
this.monitorProgress = false;
clearInterval(timer);
this.MatDialogRef.close(data.sermon);
},
error => { error => {
alert(error); alert(error);
this.updateAddButton(true); this.updateAddButton(true);
this.monitorProgress = false; this.monitorProgress = false;
clearInterval(timer);
let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}}); let errorDialog = this.MatDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
}); });
} }
private getEventMessage(event: HttpEvent<any>) {
switch (event.type) {
case HttpEventType.Sent:
return;
case HttpEventType.UploadProgress:
this.uploadProgress = event.loaded;
this.uploadTotal = event.total;
return;
case HttpEventType.Response:
this.updateAddButton(true);
this.monitorProgress = false;
this.MatDialogRef.close(event['body']['sermon']);
return;
default:
return;
}
}
onFileChange(event){ onFileChange(event){
this.sermonFile = event.srcElement.files[0]; this.sermonFile = event.srcElement.files[0];
} }

View File

@ -24,7 +24,7 @@ export class LoginPopupComponent implements OnInit {
this.loginButtonText = 'Please Wait...'; this.loginButtonText = 'Please Wait...';
this.loginButtonDisabled = true; this.loginButtonDisabled = true;
this.loginService.login(this.username,this.password).subscribe( this.loginService.login(this.username,this.password).subscribe(
data => { (data:any) => {
if (data.message === 'Logged In'){ if (data.message === 'Logged In'){
this.MatDialogRef.close(true); this.MatDialogRef.close(true);
let s = this.snackbar.open("Logged In","OK"); let s = this.snackbar.open("Logged In","OK");

View File

@ -68,11 +68,11 @@ export class UpdateSermonPopupComponent implements OnInit {
s.title = this.sermonTitle; s.title = this.sermonTitle;
s.author = this.sermonSpeaker; s.author = this.sermonSpeaker;
s.description = this.sermonDescription; s.description = this.sermonDescription;
s.sermonDate = this.sermonDate; s.date = this.sermonDate;
//Start monitoring Progress //Start monitoring Progress
this.sermonService.updateSermon(s).subscribe( this.sermonService.updateSermon(s).subscribe(
data=>{ (data:any)=>{
this.MatDialogRef.close(data.sermon); this.MatDialogRef.close(data.sermon);
}, },
error => { error => {

View File

@ -5,9 +5,9 @@
<li *ngFor="let sermon of sermons; let i = index;"> <li *ngFor="let sermon of sermons; let i = index;">
<sermon-small-component <sermon-small-component
[title]="sermon.title" [title]="sermon.title"
[date]="sermon.sermonDate" [date]="sermon.date"
[delayFadeIn]="(i+1)*200" [delayFadeIn]="(i+1)*200"
[url]="sermon.url" [url]="sermon.file"
[id]="sermon.id" [id]="sermon.id"
></sermon-small-component> ></sermon-small-component>
</li> </li>

View File

@ -25,9 +25,10 @@ export class RecentSermonsComponent implements OnInit {
getSermons(): void{ getSermons(): void{
this.sermons = []; this.sermons = [];
this.loading = true; this.loading = true;
this.sermonService.getSermons(this.numberOfSermonsToShow).subscribe(sermons => { this.sermonService.getSermons(this.numberOfSermonsToShow).subscribe(response => {
this.sermons = sermons; this.sermons = response.sermons;
this.loading = false; this.loading = false;
console.log(response);
}); });
} }
} }

View File

@ -41,6 +41,7 @@ export class SermonSmallComponent implements AfterContentInit {
} }
play(): void{ play(): void{
if (this.audioPlayer.getIsPlaying() == true && this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){ if (this.audioPlayer.getIsPlaying() == true && this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){
this.audioPlayer.pause(); this.audioPlayer.pause();
} else { } else {

View File

@ -11,11 +11,11 @@
<sermon-large-component <sermon-large-component
[id]="sermon.id" [id]="sermon.id"
[title]="sermon.title" [title]="sermon.title"
[date]="sermon.sermonDate" [date]="sermon.date"
[description]="sermon.description" [description]="sermon.description"
[author]="sermon.author" [author]="sermon.author"
[delayFadeIn]="(i-((((sermons.length*10)/10)-10) > 0 ? (((sermons.length*10)/10)-10) : 0))*200" [delayFadeIn]="(i-((((sermons.length*10)/10)-10) > 0 ? (((sermons.length*10)/10)-10) : 0))*200"
[url]="sermon.url" [url]="sermon.file"
[loggedIn]="loggedIn" [loggedIn]="loggedIn"
></sermon-large-component> ></sermon-large-component>
</li> </li>

View File

@ -11,8 +11,6 @@ import { MatSnackBar, MatDialog, MatDialogConfig } from '@angular/material';
import { AddSermonPopupComponent } from '../popups/add-sermon-popup/add-sermon-popup.component'; import { AddSermonPopupComponent } from '../popups/add-sermon-popup/add-sermon-popup.component';
@Component({ @Component({
selector: 'sermons-component', selector: 'sermons-component',
templateUrl: './sermons.component.html', templateUrl: './sermons.component.html',
@ -78,8 +76,8 @@ export class SermonsComponent implements OnInit {
this.sermons = []; this.sermons = [];
this.sermonService.getSermonById(id).subscribe( this.sermonService.getSermonById(id).subscribe(
sermons => { response => {
this.sermons.push(sermons) this.sermons.push(response.sermon)
this.loading = false; this.loading = false;
}, },
error => { error => {
@ -95,8 +93,8 @@ export class SermonsComponent implements OnInit {
this.page = 1; this.page = 1;
} }
this.sermonService.searchSermons(this.searchTerm,this.page).subscribe( this.sermonService.searchSermons(this.searchTerm,this.page).subscribe(
sermons => { response => {
this.addSermons(sermons); this.addSermons(response.sermons);
this.loading = false; this.loading = false;
}, },
error => console.error(error) ); error => console.error(error) );

View File

@ -28,7 +28,7 @@ export class UpcomingEventsComponent implements OnInit {
this.events = []; this.events = [];
this.loading = true; this.loading = true;
this.eventService.getEvents(1).subscribe(events => { this.eventService.getEvents(1).subscribe(events => {
this.events = events.slice(0,this.numberOfEventsToShow); this.events = events.events.slice(0,this.numberOfEventsToShow);
this.loading = false; this.loading = false;
}); });
} }

View File

@ -1,16 +1,18 @@
export const EVENTS_ADD_URL = "/api2/events/a/"; import { environment } from '../../environments/environment';
export const EVENT_BY_ID = "/api2/events/";
export const EVENTS_BY_PAGE_URL = "/api2/events/page/"; export const EVENTS_ADD_URL = environment.baseUrl + "/api2/events/a/";
export const EVENTS_DELETE_BY_ID_URL = "/api2/events/a/"; export const EVENT_BY_ID = environment.baseUrl + "/api2/events/";
export const SERMONS_BY_ID = '/api2/sermons/'; export const EVENTS_BY_PAGE_URL = environment.baseUrl + "/api2/events/page/";
export const SERMONS_BY_PAGE_URL = '/api2/sermons/page/'; export const EVENTS_DELETE_BY_ID_URL = environment.baseUrl + "/api2/events/a/";
export const SERMONS_BY_SEARCH_URL = '/api2/sermons/search'; export const SERMONS_BY_ID = environment.baseUrl + '/api2/sermons/';
export const SERMONS_BY_PAGE_URL = environment.baseUrl + '/api2/sermons/page/';
export const SERMONS_BY_SEARCH_URL = environment.baseUrl + '/api2/sermons/search';
export const SERMON_MP3_BASE_URL = '//ofbbutte.com/static/media/'; export const SERMON_MP3_BASE_URL = '//ofbbutte.com/static/media/';
export const SERMON_ADD_URL = "/api2/sermons/a/"; export const SERMON_ADD_URL = environment.baseUrl + "/api2/sermons/a/";
export const SERMON_DELETE_URL = "/api2/sermons/a/"; export const SERMON_DELETE_URL = environment.baseUrl + "/api2/sermons/a/";
export const SERMON_UPDATE_URL = "/api2/sermons/a/"; export const SERMON_UPDATE_URL = environment.baseUrl + "/api2/sermons/a/";
export const SERMON_DOWNLOAD_URL = "/api2/sermons/download/"; export const SERMON_DOWNLOAD_URL = environment.baseUrl + "/api2/sermons/download/";
export const LOGIN_URL = '/api2/login'; export const LOGIN_URL = environment.baseUrl + '/api2/login';
export const LOGIN_VALIDATE_TOKEN = ''; export const LOGIN_VALIDATE_TOKEN = '';
export const EMAIL_URL = "/api2/email"; export const EMAIL_URL = environment.baseUrl + "/api2/email";
export const RANDOM_VERSE_URL = "//www.kingjamesbibleonline.org/popular-bible-verses-widget.php"; export const RANDOM_VERSE_URL = "//www.kingjamesbibleonline.org/popular-bible-verses-widget.php";

View File

@ -1,24 +0,0 @@
import { ProgressService } from './../services/xhr-progress.service';
import { Injectable } from '@angular/core';
import { BrowserXhr } from '@angular/http';
@Injectable()
export class ProgressXhr extends BrowserXhr {
constructor(private service: ProgressService) { super(); }
build(): any {
let xhr = super.build();
xhr.onprogress = (event) => {
this.service.downloadProgress.next(event);
};
xhr.upload.onprogress = (event) => {
this.service.uploadProgress.next(event);
};
return <any>(xhr);
}
}

View File

@ -5,3 +5,14 @@ export class Event{
endDate: Date; endDate: Date;
description: string; description: string;
} }
export class EventResponse {
status: number;
events: Event[];
}
export class SingleEventResponse {
status: number;
event: Event;
}

View File

@ -1,9 +1,19 @@
export class Sermon{ export class Sermon{
id: number; id: number;
title: string; title: string;
sermonDate: Date; date: Date;
uploadDate: Date; uploadDate: Date;
description: string; description: string;
author: string; author: string;
url: string; url: string;
} }
export class SingleSermonResponse {
status: number;
sermon: Sermon;
}
export class MultipleSermonResponse {
status: number;
sermons: Sermon[];
}

View File

@ -1,8 +1,10 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Sermon } from '../interfaces/sermon'; import { Sermon } from '../interfaces/sermon';
import { AudioStates } from '../enum/audio-states'; import { AudioStates } from '../enum/audio-states';
import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs';
import { SERMON_MP3_BASE_URL } from '../constants/urls';
@Injectable() @Injectable()
export class AudioPlayerService { export class AudioPlayerService {
@ -29,6 +31,7 @@ export class AudioPlayerService {
} }
play(src: string, metaData?: any): void{ play(src: string, metaData?: any): void{
src = SERMON_MP3_BASE_URL + src;
try{ try{
if (typeof src === 'undefined' || src == null) return; if (typeof src === 'undefined' || src == null) return;
this.loading = true; this.loading = true;

View File

@ -1,13 +1,13 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http'; import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable, throwError as observableThrowError, observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RANDOM_VERSE_URL } from '../constants/urls'; import { RANDOM_VERSE_URL } from '../constants/urls';
@Injectable() @Injectable()
export class BibleVerseService { export class BibleVerseService {
constructor(private http: Http){} constructor(private httpClient: HttpClient){}
randomVerse(){ randomVerse(){
//return this.http.get(RANDOM_VERSE_URL).map(this.gotData).catch(this.dataError); //return this.http.get(RANDOM_VERSE_URL).map(this.gotData).catch(this.dataError);
@ -16,19 +16,6 @@ export class BibleVerseService {
gotData(res: Response){ gotData(res: Response){
console.log(res); console.log(res);
} }
dataError(error: Response | any){
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return observableThrowError(errMsg);
}
} }

View File

@ -1,8 +1,7 @@
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {throwError as observableThrowError, Observable } from 'rxjs'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { map, catchError } from 'rxjs/operators';
import { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { EMAIL_URL } from '../constants/urls'; import { EMAIL_URL } from '../constants/urls';
@ -10,7 +9,7 @@ import { EMAIL_URL } from '../constants/urls';
@Injectable() @Injectable()
export class EmailService { export class EmailService {
constructor(private http: Http){ constructor(private httpClient: HttpClient){
} }
@ -28,22 +27,24 @@ export class EmailService {
hp: hp hp: hp
}; };
return this.http.post(EMAIL_URL,body,{withCredentials:true}) return this.httpClient.post(EMAIL_URL, body, {withCredentials:true})
.pipe(map(r => { return r.json(); }) .pipe(catchError(this.handleError))
,catchError(this.dataError));
} }
dataError(error: Response | any){ private handleError(error: HttpErrorResponse) {
let errMsg: string; if (error.error instanceof ErrorEvent) {
if (error instanceof Response) { // A client-side or network error occurred. Handle it accordingly.
const body = error.json() || ''; console.error('An error occurred:', error.error.message);
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else { } else {
errMsg = error.message ? error.message : error.toString(); // The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
} }
console.error(errMsg); // return an observable with a user-facing error message
return observableThrowError(error.json()); return throwError(
} 'Something bad happened; please try again later.');
};
} }

View File

@ -1,31 +1,52 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators'; import { catchError, tap, map } from 'rxjs/operators';
import { Event } from '../interfaces/event'; import { Event, EventResponse, SingleEventResponse } from '../interfaces/event';
import { EVENTS_BY_PAGE_URL, import { EVENTS_BY_PAGE_URL,
EVENT_BY_ID, EVENT_BY_ID,
EVENTS_ADD_URL, EVENTS_ADD_URL,
EVENTS_DELETE_BY_ID_URL } from '../constants/urls'; EVENTS_DELETE_BY_ID_URL } from '../constants/urls';
import { getBodyNode } from '@angular/animations/browser/src/render/shared';
@Injectable() @Injectable()
export class EventService { export class EventService {
constructor(private http: Http){ constructor(private httpClient: HttpClient){
} }
getEvents(page: number): Observable<Event[]> { getEvents(page: number): Observable<EventResponse> {
let url = EVENTS_BY_PAGE_URL + page + "?pageSize=" + 10; let url = EVENTS_BY_PAGE_URL + page + "?pageSize=" + 10;
return this.http.get(url).pipe(map(this.gotData,this),catchError(this.dataError)); return this.httpClient.get<EventResponse>(url)
.pipe(tap(e => this.setMultipleEventDates(e)),
catchError(this.handleError));
}; };
getSingleEvent(id: Number): Observable<Event>{ getSingleEvent(id: Number): Observable<SingleEventResponse>{
let url = EVENT_BY_ID + id; let url = EVENT_BY_ID + id;
return this.http.get(url).pipe(map(this.gotDataSingle,this),catchError(this.dataError)); return this.httpClient.get<SingleEventResponse>(url).pipe(tap(e => this.setSingleEventDates(e)), catchError(this.handleError));
}; };
setEventDates(event: Event): Event {
event.startDate = new Date(event.startDate);
event.endDate = new Date(event.endDate);
return event;
}
setSingleEventDates(event : SingleEventResponse) : SingleEventResponse {
event.event = this.setEventDates(event.event);
return event;
}
setMultipleEventDates(event: EventResponse) : EventResponse {
event.events.forEach(e => {
e = this.setEventDates(e);
});
return event;
}
addEvent(event: Event){ addEvent(event: Event){
let fd = new FormData(); let fd = new FormData();
fd.append("title",event.title); fd.append("title",event.title);
@ -34,28 +55,16 @@ export class EventService {
fd.append("endDate",new Date(event.endDate).getTime().toString()); //Pass date as milliseconds since 1970 fd.append("endDate",new Date(event.endDate).getTime().toString()); //Pass date as milliseconds since 1970
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString()); fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
return this.http.post(EVENTS_ADD_URL,fd,{withCredentials:true}) return this.httpClient.post(EVENTS_ADD_URL, fd, {withCredentials:true}).pipe(catchError(this.handleError));
.pipe(map(d=>{ return d.json(); })
,catchError(this.dataError));
} }
deleteEvent(eventId: number){ deleteEvent(eventId: number){
return this.http.delete(EVENTS_DELETE_BY_ID_URL,{withCredentials:true,body:{"id":eventId}}) let ro = {
.pipe(map(d => {return d.json(); }) body: {"id":eventId},
,catchError(this.dataError)); withCredentials: true
} };
gotDataSingle(res: Response){ return this.httpClient.delete(EVENTS_DELETE_BY_ID_URL, ro).pipe(catchError(this.handleError));
let body = res.json();
return this.toEvent(body.event);
}
gotData(res: Response){
let body = res.json();
body = body.events.map(e => {
return this.toEvent(e);
});
return body || { };
} }
toEvent(json: any): Event{ toEvent(json: any): Event{
@ -68,17 +77,21 @@ export class EventService {
} }
} }
dataError(error: Response | any){ private handleError(error: HttpErrorResponse) {
let errMsg: string; console.error(error);
if (error instanceof Response) { if (error.error instanceof ErrorEvent) {
const body = error.json() || ''; // A client-side or network error occurred. Handle it accordingly.
const err = body.error || JSON.stringify(body); console.error('An error occurred:', error.error.message);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else { } else {
errMsg = error.message ? error.message : error.toString(); // The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
} }
console.error(errMsg); // return an observable with a user-facing error message
return Observable.throw(errMsg); return throwError(
} 'Something bad happened; please try again later.');
};
} }

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { GoogleAnalyticsService } from './google-analytics.service';
describe('GoogleAnalyticsService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [GoogleAnalyticsService]
});
});
it('should be created', inject([GoogleAnalyticsService], (service: GoogleAnalyticsService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -1,12 +1,9 @@
import {throwError as observableThrowError, Observable , Subject, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions } from '@angular/http'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, Subject, throwError, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Sermon } from '../interfaces/sermon';
import { LOGIN_URL } from '../constants/urls'; import { LOGIN_URL } from '../constants/urls';
@Injectable() @Injectable()
@ -14,64 +11,58 @@ export class LoginService {
private loggedIn: boolean = false; private loggedIn: boolean = false;
private onChange: Subject<{isLoggedIn: boolean}>; private onChange: Subject<{isLoggedIn: boolean}>;
private lastLoginCheck: Date; private lastLoginCheck: Date;
private options: RequestOptions; private options: {};
constructor(private http: Http){ constructor(private httpClient: HttpClient){
this.options = new RequestOptions({ this.options = {
withCredentials: true withCredentials: true
}); };
this.lastLoginCheck = new Date(); this.lastLoginCheck = new Date();
this.lastLoginCheck.setHours(this.lastLoginCheck.getHours() - 2); this.lastLoginCheck.setHours(this.lastLoginCheck.getHours() - 2);
this.onChange = new Subject<{isLoggedIn: boolean}>(); this.onChange = new Subject<{isLoggedIn: boolean}>();
} }
login(username: string, password: string){ login(username: string, password: string){
return this.http.post(LOGIN_URL,{userName:username,password:password},this.options) return this.httpClient.post(LOGIN_URL, {userName: username, password: password}, this.options).pipe(catchError(this.handleError));
.pipe(map(r=> { return this.gotData(r);})
,catchError(this.dataError));
} }
isLoggedIn(fromServer: boolean = false){ isLoggedIn(fromServer: boolean = false){
var now = new Date(); var now = new Date();
var hours = Math.abs(now.valueOf() - this.lastLoginCheck.valueOf()) / 36e5; var hours = Math.abs(now.valueOf() - this.lastLoginCheck.valueOf()) / 36e5;
if (hours > 0.75 || fromServer === true){ if (hours > 0.75 || fromServer === true){
return this.http.post(LOGIN_URL + "/isloggedin",{},this.options) return this.httpClient.post(LOGIN_URL + "/isloggedin",{},this.options)
.pipe(map(d => { .pipe(map((d:any) => {
let is = d.json().loggedIn === true; let is = d.loggedIn === true;
this.loggedIn = is; this.loggedIn = is;
this.lastLoginCheck = new Date(); this.lastLoginCheck = new Date();
this.onChange.next({isLoggedIn: this.loggedIn}); this.onChange.next({isLoggedIn: this.loggedIn});
return this.loggedIn; return this.loggedIn;
}) }),
,catchError(this.dataError)); catchError(this.handleError));
} else { } else {
let val = this.loggedIn; let val = this.loggedIn;
return of(val); return of(val);
} }
} }
gotData(res: Response){
let body = res.json();
this.lastLoginCheck = new Date();
this.loggedIn = body.message === 'Logged In';
this.onChange.next({isLoggedIn: this.loggedIn});
return body;
}
dataError(error: Response | any){
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return observableThrowError(errMsg);
}
onLogin(): Observable<{isLoggedIn: boolean}>{ onLogin(): Observable<{isLoggedIn: boolean}>{
return this.onChange.asObservable(); return this.onChange.asObservable();
} }
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
} }

View File

@ -1,13 +1,11 @@
import {throwError as observableThrowError, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http'; import { HttpClient, HttpErrorResponse, HttpRequest } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { Sermon, MultipleSermonResponse, SingleSermonResponse } from '../interfaces/sermon';
import { Sermon } from '../interfaces/sermon';
import { SERMONS_BY_ID, import { SERMONS_BY_ID,
SERMONS_BY_PAGE_URL, SERMONS_BY_PAGE_URL,
SERMON_MP3_BASE_URL, SERMON_MP3_BASE_URL,
@ -20,41 +18,45 @@ import { SERMONS_BY_ID,
export class SermonService { export class SermonService {
private pageSize: number = 10; private pageSize: number = 10;
constructor(private http: Http){ constructor(private httpClient: HttpClient){
} }
getSermons(count: number): Observable<Sermon[]> { getSermons(count: number): Observable<MultipleSermonResponse> {
let url = SERMONS_BY_PAGE_URL + 1 + "?pageSize=" + 5; let url = SERMONS_BY_PAGE_URL + 1 + "?pageSize=" + 5;
return this.http.get(url).pipe(map(this.gotData),catchError(this.dataError)); return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
}; };
getSermonsByPage(page: number): Observable<Sermon[]>{ getSermonsByPage(page: number): Observable<MultipleSermonResponse>{
let url = SERMONS_BY_PAGE_URL + page + "?pageSize=" + this.pageSize; let url = SERMONS_BY_PAGE_URL + page + "?pageSize=" + this.pageSize;
return this.http.get(url).pipe(map(this.gotData),catchError(this.dataError)); return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
} }
getSermonById(id: number): Observable<Sermon>{ getSermonById(id: number): Observable<SingleSermonResponse>{
let url = SERMONS_BY_ID + id + "?pageSize=" + this.pageSize; let url = SERMONS_BY_ID + id + "?pageSize=" + this.pageSize;
return this.http.get(url).pipe(map(this.gotSermon),catchError(this.dataError)); return this.httpClient.get<SingleSermonResponse>(url).pipe(tap(e => this.setSingleDate(e)), catchError(this.handleError));
} }
searchSermons(searchTerm: string, page: number): Observable<Sermon[]>{ searchSermons(searchTerm: string, page: number): Observable<MultipleSermonResponse>{
let url = SERMONS_BY_SEARCH_URL + "?searchTerm=" + searchTerm + "&page=" + page + "&pageSize=" + this.pageSize; let url = SERMONS_BY_SEARCH_URL + "?searchTerm=" + searchTerm + "&page=" + page + "&pageSize=" + this.pageSize;
return this.http.get(url).pipe(map(this.gotData),catchError(this.dataError)); return this.httpClient.get<MultipleSermonResponse>(url).pipe(tap(e => this.setMultipleDates(e)), catchError(this.handleError));
} }
addSermon(sermon: Sermon, sermonFile: File){ addSermon(sermon: Sermon, sermonFile: File){
let fd = new FormData(); let fd = new FormData();
fd.append("title",sermon.title); fd.append("title",sermon.title);
fd.append("description",sermon.description); fd.append("description",sermon.description);
fd.append("date",new Date(sermon.sermonDate).getTime().toString()); //Pas date as milliseconds since 1970 fd.append("date",new Date(sermon.date).getTime().toString()); //Pas date as milliseconds since 1970
fd.append("author",sermon.author); fd.append("author",sermon.author);
fd.append("file",sermonFile); fd.append("file",sermonFile);
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString()); fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
return this.http.post(SERMON_ADD_URL,fd,{withCredentials:true}) const req = new HttpRequest('POST', SERMON_ADD_URL, fd, {
.pipe(map(d=>{ return d.json(); }) reportProgress: true,
,catchError(this.dataError)); withCredentials: true
});
return this.httpClient.request(req).pipe(
catchError(this.handleError)
);
} }
updateSermon(sermon: Sermon){ updateSermon(sermon: Sermon){
@ -62,60 +64,56 @@ export class SermonService {
fd.append("id",sermon.id.toString()); fd.append("id",sermon.id.toString());
fd.append("title",sermon.title); fd.append("title",sermon.title);
fd.append("description",sermon.description); fd.append("description",sermon.description);
fd.append("date",new Date(sermon.sermonDate).toUTCString()); fd.append("date",new Date(sermon.date).toUTCString());
fd.append("author",sermon.author); fd.append("author",sermon.author);
fd.append("timezoneOffset",new Date().getTimezoneOffset().toString()); fd.append("timezoneOffset",new Date().getTimezoneOffset().toString());
return this.http.put(SERMON_UPDATE_URL,fd,{withCredentials:true}) return this.httpClient.put<Sermon>(SERMON_UPDATE_URL,fd,{withCredentials:true})
.pipe(map(d => { return d.json(); }) .pipe(catchError(this.handleError));
,catchError(this.dataError));
} }
deleteSermon(sermonId: number){ deleteSermon(sermonId: number){
return this.http.delete(SERMON_DELETE_URL,{withCredentials:true,body:{"id":sermonId}}) let options = {
.pipe(map(d=>{ return d.json(); }) withCredentials: true,
,catchError(this.dataError)); body: {
} "id" : sermonId
}
gotSermon(res: Response){
let s = res.json().sermon;
s = {
id: s.id,
title: s.title,
sermonDate: new Date(s.date),
uploadDate: null,
description: s.description,
url: SERMON_MP3_BASE_URL + s.file,
author: s.author
}; };
return s || { }; return this.httpClient.delete(SERMON_DELETE_URL,options)
.pipe(catchError(this.handleError));
} }
gotData(res: Response){ setSingleDate(e : SingleSermonResponse): SingleSermonResponse {
//if (1 == 1) return MOCK; e.sermon = this.setDates(e.sermon);
let body = res.json(); return e;
body = body.sermons.map(s => { return {
id: s.id,
title: s.title,
sermonDate: new Date(s.date),
uploadDate: null,
description: s.description,
url: SERMON_MP3_BASE_URL + s.file,
author: s.author
}});
return body || { };
} }
dataError(error: Response | any){ setMultipleDates(e : MultipleSermonResponse) : MultipleSermonResponse {
let errMsg: string; e.sermons.forEach(s => {
if (error instanceof Response) { s = this.setDates(s);
const body = error.json() || ''; });
const err = body.error || JSON.stringify(body); return e;
errMsg = `${error.status} - ${error.statusText || ''} ${err}`; }
setDates(sermon: Sermon): Sermon {
sermon.date = new Date(sermon.date);
sermon.uploadDate = new Date(sermon.uploadDate);
return sermon;
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else { } else {
errMsg = error.message ? error.message : error.toString(); // The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
} }
console.error(errMsg); // return an observable with a user-facing error message
return observableThrowError(errMsg); return throwError(
} 'Something bad happened; please try again later.');
};
} }

View File

@ -1,9 +0,0 @@
import { Subject } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable()
export class ProgressService {
downloadProgress: Subject<any> = new Subject();
uploadProgress: Subject<any> = new Subject();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,9 +1,11 @@
# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
# For additional information regarding the format and rule options, please see: # For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries # https://github.com/browserslist/browserslist#queries
# For IE 9-11 support, please uncomment the last line of the file and adjust as needed #
# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
> 0.5% > 0.5%
last 2 versions last 2 versions
Firefox ESR Firefox ESR
not dead not dead
# IE 9-11 not IE 9-11

View File

@ -1,3 +1,4 @@
export const environment = { export const environment = {
production: true production: true,
baseUrl: ""
}; };

View File

@ -1,15 +1,17 @@
// This file can be replaced during build by using the `fileReplacements` array. // This file can be replaced during build by using the `fileReplacements` array.
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`. // The list of file replacements can be found in `angular.json`.
export const environment = { export const environment = {
production: false production: false,
baseUrl: "http://localhost:25776"
}; };
/* /*
* In development mode, to ignore zone related error stack frames such as * For easier debugging in development mode, you can import the following file
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
* import the following file, but please comment it out in production mode *
* because it will have performance impact when throw error * This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/ */
// import 'zone.js/dist/zone-error'; // Included with Angular CLI. // import 'zone.js/dist/zone-error'; // Included with Angular CLI.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -17,7 +17,7 @@ module.exports = function (config) {
}, },
coverageIstanbulReporter: { coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'), dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly'], reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true fixWebpackSourcePaths: true
}, },
reporters: ['progress', 'kjhtml'], reporters: ['progress', 'kjhtml'],

View File

@ -9,4 +9,4 @@ if (environment.production) {
} }
platformBrowserDynamic().bootstrapModule(AppModule) platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err)); .catch(err => console.error(err));

View File

@ -11,14 +11,17 @@
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
* *
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html * Learn more in https://angular.io/guide/browser-support
*/ */
/*************************************************************************************************** /***************************************************************************************************
* BROWSER POLYFILLS * BROWSER POLYFILLS
*/ */
/** IE9, IE10 and IE11 requires all of the following polyfills. **/ /** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills.
* This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot
*/
import 'core-js/es6/symbol'; import 'core-js/es6/symbol';
import 'core-js/es6/object'; import 'core-js/es6/object';
import 'core-js/es6/function'; import 'core-js/es6/function';
@ -40,41 +43,43 @@ import 'core-js/es6/set';
/** IE10 and IE11 requires the following for the Reflect API. */ /** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect'; // import 'core-js/es6/reflect';
/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';
/** /**
* Web Animations `@angular/platform-browser/animations` * Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
**/ */
// import 'web-animations-js'; // Run `npm install --save web-animations-js`. // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/** /**
* By default, zone.js will patch all possible macroTask and DomEvents * By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags * user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/ */
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
/*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*/
// (window as any).__Zone_enable_cross_context_check = true;
/*************************************************************************************************** /***************************************************************************************************
* Zone JS is required by default for Angular itself. * Zone JS is required by default for Angular itself.
*/ */
import 'zone.js/dist/zone'; // Included with Angular CLI. import 'zone.js/dist/zone'; // Included with Angular CLI.
/*************************************************************************************************** /***************************************************************************************************
* APPLICATION IMPORTS * APPLICATION IMPORTS
*/ */

View File

@ -1,6 +1,5 @@
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
@import '../node_modules/@angular/material/prebuilt-themes/indigo-pink.css'; @import "~@angular/material/prebuilt-themes/indigo-pink.css";
*{ *{
padding: 0px; padding: 0px;

View File

@ -2,11 +2,10 @@
"extends": "../tsconfig.json", "extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "../out-tsc/app", "outDir": "../out-tsc/app",
"module": "es2015",
"types": [] "types": []
}, },
"exclude": [ "exclude": [
"src/test.ts", "test.ts",
"**/*.spec.ts" "**/*.spec.ts"
] ]
} }

View File

@ -2,7 +2,6 @@
"extends": "../tsconfig.json", "extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "../out-tsc/spec", "outDir": "../out-tsc/spec",
"module": "commonjs",
"types": [ "types": [
"jasmine", "jasmine",
"node" "node"

View File

@ -5,15 +5,17 @@
"outDir": "./dist/out-tsc", "outDir": "./dist/out-tsc",
"sourceMap": true, "sourceMap": true,
"declaration": false, "declaration": false,
"module": "es2015",
"moduleResolution": "node", "moduleResolution": "node",
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"importHelpers": true,
"target": "es5", "target": "es5",
"typeRoots": [ "typeRoots": [
"node_modules/@types" "node_modules/@types"
], ],
"lib": [ "lib": [
"es2017", "es2018",
"dom" "dom"
] ]
} }

View File

@ -1,6 +1,6 @@
{ {
"rulesDirectory": [ "rulesDirectory": [
"node_modules/codelyzer" "codelyzer"
], ],
"rules": { "rules": {
"arrow-return-shorthand": true, "arrow-return-shorthand": true,
@ -65,6 +65,7 @@
], ],
"no-misused-new": true, "no-misused-new": true,
"no-non-null-assertion": true, "no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-shadowed-variable": true, "no-shadowed-variable": true,
"no-string-literal": false, "no-string-literal": false,
"no-string-throw": true, "no-string-throw": true,