All src files update
parent
c22da5c6de
commit
fbb92cae1e
|
|
@ -4,6 +4,9 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"servehelena":"ng serve -host 192.168.43.144",
|
||||
"servebutte":"ng serve -host 192.168.2.5",
|
||||
"servebutteprod":"ng serve -host 192.168.2.5",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
|
|
@ -13,11 +16,13 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^4.0.0",
|
||||
"@angular/cdk": "^2.0.0-beta.8",
|
||||
"@angular/common": "^4.0.0",
|
||||
"@angular/compiler": "^4.0.0",
|
||||
"@angular/core": "^4.0.0",
|
||||
"@angular/forms": "^4.0.0",
|
||||
"@angular/http": "^4.0.0",
|
||||
"@angular/material": "^2.0.0-beta.8",
|
||||
"@angular/platform-browser": "^4.0.0",
|
||||
"@angular/platform-browser-dynamic": "^4.0.0",
|
||||
"@angular/router": "^4.0.0",
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
<!--The content below is only a placeholder and can be replaced.-->
|
||||
<div style="text-align:center">
|
||||
<h1>
|
||||
Welcome to {{title}}!
|
||||
</h1>
|
||||
<img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</div>
|
||||
<h2>Here are some links to help you start: </h2>
|
||||
<ul>
|
||||
<li>
|
||||
<h2><a target="_blank" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
|
||||
</li>
|
||||
<li>
|
||||
<h2><a target="_blank" href="https://blog.angular.io//">Angular blog</a></h2>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app';
|
||||
}
|
||||
|
|
@ -1,16 +1,160 @@
|
|||
import { WindowRefService } from './services/window-ref.service';
|
||||
import { EmailService } from './services/email.service';
|
||||
import { SermonService } from './services/sermon.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 } from '@angular/core';
|
||||
import { NgModule, Component } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule, BrowserXhr } from '@angular/http';
|
||||
import { MdButtonModule,
|
||||
MdInputModule,
|
||||
MdSliderModule,
|
||||
MdSnackBarModule,
|
||||
MdDialogModule,
|
||||
MdCardModule } from '@angular/material';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
//import 'hammerjs';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
//Components
|
||||
import { AppComponent } from './components/app/app.component';
|
||||
import { MenuComponent } from './components/menu/menu.component';
|
||||
import { IconButtonComponent } from './components/icon-button/icon-button.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { WhoWeAreComponent } from './components/whoweare/whoweare.component';
|
||||
import { ServicesComponent } from './components/services/services.component';
|
||||
import { SecondaryPageComponent } from './components/secondary-page/secondary-page.component';
|
||||
import { RecentSermonsComponent } from './components/recent-sermons/recent-sermons.component';
|
||||
import { SermonSmallComponent } from './components/sermon-small/sermon-small.component';
|
||||
import { DateComponent } from './components/date/date.component';
|
||||
import { UpcomingEventsComponent } from './components/upcoming-events/upcoming-events.component';
|
||||
import { EventComponent } from './components/event/event.component';
|
||||
import { SermonsComponent } from './components/sermons/sermons.component';
|
||||
import { AudioPlayerComponent } from './components/audio-player/audio-player.component';
|
||||
import { LocationComponent } from './components/location/location.component';
|
||||
import { SermonLargeComponent } from './components/sermon-large/sermon-large.component';
|
||||
import { AddSermonPopupComponent } from './components/popups/add-sermon-popup/add-sermon-popup.component';
|
||||
import { LoginPopupComponent } from './components/popups/login-popup/login-popup.component';
|
||||
import { InputPopupComponent } from './components/popups/input-popup/input-popup.component';
|
||||
|
||||
//Directives
|
||||
import { FadeInOnScrollDirective } from './directives/fade-in-on-scroll.directive';
|
||||
import { IconDirective } from './directives/icon.directive';
|
||||
|
||||
//Pipes
|
||||
import { DurationPipe } from './pipes/duration.pipe';
|
||||
import { OkPopupComponent } from './components/popups/ok-popup/ok-popup.component';
|
||||
import { YesNoPopupComponent } from './components/popups/yes-no-popup/yes-no-popup.component';
|
||||
import { UpdateSermonPopupComponent } from './components/popups/update-sermon-popup/update-sermon-popup.component';
|
||||
import { ContactPageComponent } from './components/contact-page/contact-page.component';
|
||||
import { SharePopupComponent } from './components/popups/share-popup/share-popup.component';
|
||||
import { SafeUrlPipe } from './pipes/safe-url.pipe';
|
||||
import { EventsPageComponent } from './components/events-page/events-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',
|
||||
redirectTo: 'sermons/0'
|
||||
},
|
||||
{
|
||||
path: 'sermons/:id',
|
||||
component: SermonsComponent
|
||||
},
|
||||
{
|
||||
path: 'location',
|
||||
component: LocationComponent
|
||||
},
|
||||
{
|
||||
path: 'events',
|
||||
component: EventsPageComponent
|
||||
}
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
AppComponent,
|
||||
MenuComponent,
|
||||
IconButtonComponent,
|
||||
HomeComponent,
|
||||
WhoWeAreComponent,
|
||||
ServicesComponent,
|
||||
FadeInOnScrollDirective,
|
||||
IconDirective,
|
||||
SecondaryPageComponent,
|
||||
RecentSermonsComponent,
|
||||
SermonSmallComponent,
|
||||
DateComponent,
|
||||
UpcomingEventsComponent,
|
||||
EventComponent,
|
||||
SermonsComponent,
|
||||
AudioPlayerComponent,
|
||||
DurationPipe,
|
||||
LocationComponent,
|
||||
SermonLargeComponent,
|
||||
AddSermonPopupComponent,
|
||||
LoginPopupComponent,
|
||||
OkPopupComponent,
|
||||
InputPopupComponent,
|
||||
YesNoPopupComponent,
|
||||
UpdateSermonPopupComponent,
|
||||
ContactPageComponent,
|
||||
SharePopupComponent,
|
||||
SafeUrlPipe,
|
||||
EventsPageComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpModule,
|
||||
BrowserAnimationsModule,
|
||||
//Angular Material Components
|
||||
MdButtonModule,
|
||||
MdInputModule,
|
||||
MdSliderModule,
|
||||
MdSnackBarModule,
|
||||
MdDialogModule,
|
||||
MdCardModule,
|
||||
RouterModule.forRoot(Routes)
|
||||
|
||||
],
|
||||
providers: [],
|
||||
providers: [LoginService,SermonService,ProgressService,EmailService,WindowRefService,{provide:BrowserXhr,useClass:ProgressXhr}],
|
||||
entryComponents: [AddSermonPopupComponent,
|
||||
LoginPopupComponent,
|
||||
OkPopupComponent,
|
||||
InputPopupComponent,
|
||||
YesNoPopupComponent,
|
||||
UpdateSermonPopupComponent,
|
||||
SharePopupComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
export class AppModule {
|
||||
public routes = Routes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
|
||||
|
||||
header{
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height: 50px;
|
||||
color: white;
|
||||
vertical-align: middle;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#header-background{
|
||||
background-color: rgb(0, 188, 212);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
box-shadow: 0 2px 5px 0 rgba(0,0,0,0.24);
|
||||
}
|
||||
|
||||
#logo{
|
||||
margin-left: -5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#main-menu-button{
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.hideOnMobile{
|
||||
display:inline-block;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.header-button, .header-button-home{
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
|
||||
.content{
|
||||
margin-top: 50px;
|
||||
min-height: 100%;
|
||||
margin-bottom: -130px;
|
||||
padding-bottom: 130px;
|
||||
}
|
||||
|
||||
footer{
|
||||
background-color: rgb(50,50,50);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
#footer-content{
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-panel{
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: calc(33% - 20px);
|
||||
margin: 10px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
@media(max-width: 900px){
|
||||
.header-button, .hideOnMobile{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 800px){
|
||||
footer{
|
||||
height: 360px;
|
||||
}
|
||||
.footer-panel{
|
||||
display: block;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
.content{
|
||||
margin-bottom: -350px;
|
||||
padding-bottom: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
.copyright{
|
||||
font-size: 18px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
a{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a:visited{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.audio-player-filler{
|
||||
height: 70px;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.audio-player{
|
||||
position: fixed;
|
||||
bottom: -65px;
|
||||
width: 100%;
|
||||
height: 65px;
|
||||
text-align: center;
|
||||
background-color: rgb(100,100,100);
|
||||
box-shadow: 0 -2px 5px 0 rgba(0,0,0,0.24);
|
||||
background-color: rgb(100,100,100);
|
||||
color: white;
|
||||
transition: .5s ease-in-out bottom;
|
||||
}
|
||||
|
||||
.audio-player-slide-up{
|
||||
bottom:0;
|
||||
}
|
||||
|
||||
audio-player-component{
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<header>
|
||||
<div id="header-background" [ngStyle]="{'opacity':headerOpacity}"></div>
|
||||
<button md-button class="header-button-home" routerLink="/home"><img id="logo" src="assets/images/logo.png" height="30" alt="logo"> Old Fashion Baptist</button>
|
||||
<span class="hideOnMobile"></span>
|
||||
<button md-button class="header-button" routerLink="/whoweare">Who We Are!</button>
|
||||
<button md-button class="header-button" routerLink="/services">Service Times</button>
|
||||
<button md-button class="header-button" routerLink="/location">Location</button>
|
||||
<button md-button class="header-button" routerLink="/sermons">Sermons</button>
|
||||
<button md-icon-button id="main-menu-button"
|
||||
(click)="mainMenuClick()">
|
||||
<i ofbicon class="example-icon" style="line-height:20px;">menu</i>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div id="footer-content">
|
||||
<div id="footer-contact-content" class="footer-panel">
|
||||
<a target="_blank" href="https://www.google.com/maps/place/Old+Fashion+Baptist+Church/@45.9814004,-112.5320574,11.87z/data=!4m12!1m6!3m5!1s0x535b078c3c74ea33:0xac299097142c5894!2sOld+Fashion+Baptist+Church!8m2!3d45.951287!4d-112.511978!3m4!1s0x535b078c3c74ea33:0xac299097142c5894!8m2!3d45.951287!4d-112.511978">
|
||||
<p>5003 Wynne Ave</p>
|
||||
<p>Butte, MT 59701</p>
|
||||
</a>
|
||||
<p><a href="tel:+1-406-494-5028" class="phone">(406) 494 - 5028</a></p>
|
||||
<p>Pastor Ron Derksen</p>
|
||||
</div>
|
||||
<div id="footer-services-content" class="footer-panel">
|
||||
<p>Sunday School: 10AM</p>
|
||||
<p>Sunday Worship: 11AM</p>
|
||||
<p>Sunday Evening: 7PM</p>
|
||||
<p>Wednesday Evening: 7PM</p>
|
||||
</div>
|
||||
<div id="footer-website-content" class="footer-panel">
|
||||
<p><i ofbicon class="copyright">copyright</i> Copyright {{copyrightYear}}</p>
|
||||
<p>Old Fashion Baptist</p>
|
||||
<p><a routerLink="/home">ofbbutte.com</a></p>
|
||||
<p>Powered by God</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="audio-player-filler" [hidden]="!showAudioPlayer" ></div>
|
||||
</footer>
|
||||
|
||||
<div class="audio-player" [class.audio-player-slide-up]="showAudioPlayer">
|
||||
<audio-player-component (closed)="audioPlayerClosed()" (started)="audioPlayerStarted()"></audio-player-component>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<menu-component [menuOpen]="menuOpen" (closed)="mainMenuClick()"></menu-component>
|
||||
|
||||
|
||||
|
|
@ -1,15 +1,17 @@
|
|||
import { TestBed, async } from '@angular/core/testing';
|
||||
/* tslint:disable:no-unused-variable */
|
||||
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
});
|
||||
TestBed.compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
|
|
@ -17,16 +19,16 @@ describe('AppComponent', () => {
|
|||
expect(app).toBeTruthy();
|
||||
}));
|
||||
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
it(`should have as title 'app works!'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
expect(app.title).toEqual('app works!');
|
||||
}));
|
||||
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
expect(compiled.querySelector('h1').textContent).toContain('app works!');
|
||||
}));
|
||||
});
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import { Component, Inject, Injectable, HostListener } from '@angular/core';
|
||||
import { Router, NavigationStart, Event } from '@angular/router';
|
||||
import { EventService } from '../../services/event.service';
|
||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||
import { BibleVerseService } from '../../services/bible-verse.service';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css'],
|
||||
providers:[EventService, AudioPlayerService, BibleVerseService]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'app works w!';
|
||||
menuOpen: boolean = false;
|
||||
headerOpacity: number = 0;
|
||||
fadeHeader: boolean = true;
|
||||
copyrightYear: number = (new Date()).getUTCFullYear();
|
||||
lastRoute: string = '';
|
||||
currRoute: string = '';
|
||||
lastScrollPos: number = 0;
|
||||
showAudioPlayer: boolean = false;
|
||||
|
||||
constructor(private router: Router, private audioPlayerService: AudioPlayerService){
|
||||
this.router.events.subscribe((event:Event) => {
|
||||
if(event instanceof NavigationStart) {
|
||||
console.log("last: " + this.lastRoute + "; curr: " + this.currRoute + "; evt: " + event.url);
|
||||
this.lastRoute = this.currRoute;
|
||||
this.currRoute = event.url;
|
||||
|
||||
|
||||
let doc = document.documentElement;
|
||||
let scrollPos = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||||
//console.log("Scroll: " + scrollPos + "; lastRoute: " + this.lastRoute + "; thisRoute: " + event.url);
|
||||
if (event.url === '/home'){
|
||||
this.fadeHeader = true;
|
||||
this.headerOpacity = 0;
|
||||
} else {
|
||||
this.fadeHeader = false;
|
||||
this.headerOpacity = 1;
|
||||
}
|
||||
if (this.lastRoute === event.url){
|
||||
window.scrollTo(0,this.lastScrollPos);
|
||||
//console.log("Last POS");
|
||||
} else {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
this.lastRoute = event.url;
|
||||
this.lastScrollPos = scrollPos;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
mainMenuClick(){
|
||||
this.menuOpen = !this.menuOpen;
|
||||
}
|
||||
|
||||
audioPlayerClosed(): void{
|
||||
this.showAudioPlayer = false;
|
||||
this.audioPlayerService.updateAudioPlayerOpen(this.showAudioPlayer);
|
||||
}
|
||||
|
||||
audioPlayerStarted(): void{
|
||||
this.showAudioPlayer = true;
|
||||
this.audioPlayerService.updateAudioPlayerOpen(this.showAudioPlayer);
|
||||
}
|
||||
|
||||
@HostListener('window:scroll', ['$event'])
|
||||
onScroll(event){
|
||||
if (!this.fadeHeader){
|
||||
return;
|
||||
}
|
||||
//this.scrollElement = event.target.documentElement || event.target.body || window;
|
||||
let scrollTop = event.target.documentElement.scrollTop || event.target.body.scrollTop || window.pageYOffset;
|
||||
let allIn = 100;
|
||||
this.headerOpacity = scrollTop / allIn;
|
||||
this.headerOpacity = this.headerOpacity > 1 ? 1 : this.headerOpacity;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
.wrapper{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.audio-control-button{
|
||||
font-size: 40px;
|
||||
margin: 10px;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.padding5{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.duration{
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.audio-control-button:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.audio-control-button-c{
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.slider{
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.slider-control{
|
||||
width: 100%;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.text{
|
||||
text-align: center;
|
||||
margin-top: -15px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<div class="wrapper">
|
||||
<div class="slider">
|
||||
<span [ngSwitch]="audioState" >
|
||||
<span *ngSwitchDefault><i ofbicon class="audio-control-button">slow_motion_video</i></span>
|
||||
<span *ngSwitchCase="audioStates.Loading"><i ofbicon class="audio-control-button padding5">slow_motion_video</i></span>
|
||||
<span *ngSwitchCase="audioStates.Paused"><i ofbicon (click)="play()" class="audio-control-button padding5">play_arrow</i></span>
|
||||
<span *ngSwitchCase="audioStates.Playing"><i ofbicon (click)="pause()" class="audio-control-button padding5">pause</i></span>
|
||||
<span *ngSwitchCase="audioStates.Error"><i ofbicon (click)="play()" class="audio-control-button padding5">play_arrow</i></span>
|
||||
</span>
|
||||
<md-slider class="slider-control padding5" min="0" [max]="audioDuration" [value]="currentTime" (change)="changeTime($event)"></md-slider>
|
||||
<span class="duration padding5">{{ currentTime | duration:audioDuration }}</span>
|
||||
<span><i ofbicon class="audio-control-button padding5" (click)="close()">close</i></span>
|
||||
</div>
|
||||
<div [ngSwitch]="audioState" class="text">
|
||||
<div *ngSwitchCase="audioStates.Loading">
|
||||
Loading...
|
||||
</div>
|
||||
<div *ngSwitchCase="audioStates.Paused">
|
||||
{{ audioFileTitle }}
|
||||
</div>
|
||||
<div *ngSwitchCase="audioStates.Playing">
|
||||
{{ audioFileTitle }}
|
||||
</div>
|
||||
<div *ngSwitchCase="audioStates.Error">
|
||||
Error Playing... {{ errorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core';
|
||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||
import { AudioStates } from '../../enum/audio-states';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'audio-player-component',
|
||||
templateUrl: './audio-player.component.html',
|
||||
styleUrls: ['./audio-player.component.css'],
|
||||
})
|
||||
export class AudioPlayerComponent implements OnInit, OnDestroy {
|
||||
audioStates = AudioStates; //Store reference to enum so we can access it in the template
|
||||
audioState: AudioStates;
|
||||
|
||||
audioFileId: number;
|
||||
audioFileTitle: string;
|
||||
audioFileAuthor: string;
|
||||
audioDuration: number;
|
||||
currentTime: number;
|
||||
|
||||
primarySourceUrl: string = '';
|
||||
errorMessage: string = 'Unknown Error';
|
||||
private interval: any;
|
||||
|
||||
onStateChangedSubscription: any;
|
||||
|
||||
@Output()
|
||||
closed: EventEmitter<string> = new EventEmitter();
|
||||
@Output()
|
||||
started: EventEmitter<string> = new EventEmitter();
|
||||
|
||||
constructor(private audioPlayerService: AudioPlayerService){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void{
|
||||
this.onStateChangedSubscription = this.audioPlayerService.onStateChanged().subscribe(({metaData,state,error})=>{
|
||||
this.parseMetaData(metaData);
|
||||
this.audioState = state;
|
||||
this.errorMessage = error;
|
||||
this.audioDuration = this.audioPlayerService.getDuration();
|
||||
this.currentTime = this.audioPlayerService.getCurrentTime();
|
||||
if (this.audioState == AudioStates.Loading){
|
||||
this.started.emit("loading");
|
||||
}
|
||||
if (this.audioState == AudioStates.Playing){
|
||||
this.started.emit("playing");
|
||||
this.interval = setInterval(()=>{
|
||||
this.audioDuration = this.audioPlayerService.getDuration();
|
||||
this.currentTime = this.audioPlayerService.getCurrentTime();
|
||||
},1000);
|
||||
} else {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
play(): void{
|
||||
this.audioPlayerService.resume();
|
||||
}
|
||||
|
||||
pause(): void{
|
||||
this.audioPlayerService.pause();
|
||||
}
|
||||
|
||||
close(): void{
|
||||
this.audioPlayerService.stop();
|
||||
this.closed.emit("closed");
|
||||
}
|
||||
|
||||
changeTime(event){
|
||||
this.audioPlayerService.setPosition(event.value);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void{
|
||||
this.onStateChangedSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
private parseMetaData(metaData): void{
|
||||
this.audioFileId = metaData.id;
|
||||
this.audioFileTitle = metaData.title;
|
||||
this.audioFileAuthor = metaData.author;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
.full-width{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.errorMessages{
|
||||
color: white;
|
||||
background-color: rgb(255,90,90);
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<br>
|
||||
<div *ngIf="!formSubmitted">
|
||||
<form class="form" #contactForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput type="text" placeholder="Name" required value="" [(ngModel)]="name" name="name" >
|
||||
</md-input-container>
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput type="email" placeholder="Email" required value="" [(ngModel)]="email" name="email" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$">
|
||||
</md-input-container>
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput type="tel" placeholder="Phone" value="" [(ngModel)]="phone" name="phone">
|
||||
</md-input-container>
|
||||
<md-input-container class="full-width">
|
||||
<textarea mdInput type="text" placeholder="Message" required value="" [(ngModel)]="body" name="body" rows="5" ></textarea>
|
||||
</md-input-container>
|
||||
<md-input-container class="hide">
|
||||
<input mdInput type="text" placeholder="hp" required value="" [(ngModel)]="hp" name="subject">
|
||||
</md-input-container>
|
||||
<div class="errorMessages" *ngIf="errorMessages.length > 0">
|
||||
<p *ngFor="let error of errorMessages">{{error}}</p>
|
||||
</div>
|
||||
<button md-raised-button type="submit" [disabled]="!contactForm.form.valid || submitButtonDisabled">{{submitButtonText}}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngIf="formSubmitted">
|
||||
<p><b>Thank You!</b></p>
|
||||
<p>Your message has been sent.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContactPageComponent } from './contact-page.component';
|
||||
|
||||
describe('ContactPageComponent', () => {
|
||||
let component: ContactPageComponent;
|
||||
let fixture: ComponentFixture<ContactPageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ContactPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ContactPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import { Router } from '@angular/router';
|
||||
import { MdDialogConfig } from '@angular/material';
|
||||
import { OkPopupComponent } from './../popups/ok-popup/ok-popup.component';
|
||||
import { EmailService } from './../../services/email.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MdDialog } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'app-contact-page',
|
||||
templateUrl: './contact-page.component.html',
|
||||
styleUrls: ['./contact-page.component.css']
|
||||
})
|
||||
export class ContactPageComponent implements OnInit {
|
||||
public submitButtonText: string = "Submit";
|
||||
public submitButtonDisabled: boolean = false;
|
||||
public formSubmitted: boolean = false;
|
||||
|
||||
public name: string;
|
||||
public email: string;
|
||||
public phone: string;
|
||||
public body: string;
|
||||
public hp: string = ".";
|
||||
|
||||
public errorMessages: string[] = [];
|
||||
|
||||
|
||||
constructor(private emailService: EmailService,
|
||||
private mdDialog: MdDialog,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
this.errorMessages = [];
|
||||
if (this.name == null || this.name == ""){
|
||||
this.errorMessages.push("Please enter a name");
|
||||
}
|
||||
if (this.email == null || this.email == ""){
|
||||
this.errorMessages.push("Please enter an email address");
|
||||
}
|
||||
if (this.body == null || this.body == ""){
|
||||
this.errorMessages.push("Please enter a message");
|
||||
}
|
||||
if (this.errorMessages.length > 0){ return; }
|
||||
|
||||
this.submitButtonText = "Please Wait...";
|
||||
this.submitButtonDisabled = true;
|
||||
this.emailService.sendEmail(this.name,
|
||||
this.email,
|
||||
this.phone,
|
||||
this.body,
|
||||
this.hp)
|
||||
.subscribe(
|
||||
success => {this.emailSuccess();},
|
||||
error => {this.emailError();});
|
||||
}
|
||||
|
||||
private emailSuccess(){
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { title:'Email Sent','message':'Thank You! Your message has been sent.' };
|
||||
let popup = this.mdDialog.open(OkPopupComponent,opts);
|
||||
this.submitButtonText = "Submit";
|
||||
this.submitButtonDisabled = false;
|
||||
popup.afterClosed().subscribe(()=>{
|
||||
this.formSubmitted = true;
|
||||
});
|
||||
}
|
||||
|
||||
private emailError(){
|
||||
console.log("error");
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { title:'Email Error','message':'Please make sure that you have entered a valid email address.' };
|
||||
let popup = this.mdDialog.open(OkPopupComponent,opts);
|
||||
this.submitButtonText = "Submit";
|
||||
this.submitButtonDisabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MONTHS } from '../../constants/months';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'date-component',
|
||||
template: '<div class="wrapper"><div class="month">{{ month }}</div><div class="day">{{ day }}</div></div>',
|
||||
styles: ['.month{ color:white; background-color:red; width:40px; font-size: .75rem; text-align:center; } .day{ text-align:center; background:linear-gradient(to bottom, #ededed 0%,#ffffff 100%); }'],
|
||||
})
|
||||
export class DateComponent implements OnInit {
|
||||
@Input()
|
||||
date: Date = new Date();
|
||||
month: number;
|
||||
day: number;
|
||||
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void{
|
||||
let monthNum = this.date.getMonth();
|
||||
this.month = MONTHS[monthNum];
|
||||
this.day = this.date.getDate();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
.inner-wrapper{
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.title{
|
||||
display: table;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.title-text{
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
padding-left: 10px;
|
||||
font-size: .95rem;
|
||||
}
|
||||
|
||||
a{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<div class="wrapper" [@inout]="startFadeIn">
|
||||
<div class="inner-wrapper">
|
||||
<div class="title">
|
||||
<a></a>
|
||||
<date-component class="title-date" [date]="startDate"></date-component>
|
||||
<span class="title-text">{{ title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import { Component, AfterContentInit, Input } from '@angular/core';
|
||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'event-component',
|
||||
templateUrl: './event.component.html',
|
||||
styleUrls: ['./event.component.css'],
|
||||
animations:[
|
||||
trigger("inout",[
|
||||
state("1", style({ opacity: '1', transform:'translateX(0)' })),
|
||||
state("0",style({ opacity: '0', transform:'translateX(5%)' })),
|
||||
transition('* => 1',[
|
||||
animate('500ms ease-in-out')
|
||||
]),
|
||||
transition(':enter',[
|
||||
animate('0ms')
|
||||
])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class EventComponent implements AfterContentInit {
|
||||
@Input()
|
||||
title: string;
|
||||
@Input()
|
||||
description: string;
|
||||
@Input()
|
||||
startDate: Date;
|
||||
@Input()
|
||||
endDate: Date;
|
||||
public startFadeIn: boolean = false;
|
||||
@Input()
|
||||
public delayFadeIn: number = 100;
|
||||
|
||||
constructor(){
|
||||
console.log(this.title);
|
||||
}
|
||||
|
||||
ngAfterContentInit(): void{
|
||||
console.log(this.delayFadeIn);
|
||||
setTimeout(() => this.startFadeIn = true, this.delayFadeIn);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li{
|
||||
margin: 40px 0px 40px 0px; /* top right bottom left */
|
||||
}
|
||||
|
||||
li:first-child{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
li:last-child{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.side-bar{
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.width100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fab-buttons{
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media(max-width:800px){
|
||||
.mobile-search{
|
||||
display: block;
|
||||
}
|
||||
.fab-buttons{
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<ul>
|
||||
<li *ngFor="let event of events; let i = index;">
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<div class="fab-buttons" >
|
||||
<button md-fab *ngIf="loggedIn" (click)="addEvent()"><i ofbicon>add</i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
<button md-raised-button class="width100" (click)="addEvent()" >Add Event</button>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EventsPageComponent } from './events-page.component';
|
||||
|
||||
describe('EventsPageComponent', () => {
|
||||
let component: EventsPageComponent;
|
||||
let fixture: ComponentFixture<EventsPageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ EventsPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EventsPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Event } from '../../interfaces/event';
|
||||
|
||||
import { LoginService } from '../../services/login.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-events-page',
|
||||
templateUrl: './events-page.component.html',
|
||||
styleUrls: ['./events-page.component.css']
|
||||
})
|
||||
export class EventsPageComponent implements OnInit {
|
||||
|
||||
public events: Event[];
|
||||
public loggedIn: boolean;
|
||||
|
||||
constructor(private loginService: LoginService) {
|
||||
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is });
|
||||
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
addEvent(){
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
#content-wrapper{
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
a{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a:visited{
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
img{
|
||||
width: 70%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.inline-block{
|
||||
display: inline-block;
|
||||
width: calc(60% - 10px);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.row{
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.row-background{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: -1000;
|
||||
left: 0;
|
||||
top: -10px;
|
||||
|
||||
}
|
||||
|
||||
.row-content{
|
||||
width: 1000px;
|
||||
margin: auto;
|
||||
max-width: 100%;
|
||||
overflow: hidden; /*Keep floating children inside this element */
|
||||
}
|
||||
|
||||
.row-content-single-col{
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.row-content-col-left, .row-content-col-right{
|
||||
display: inline-block;
|
||||
width: calc(50% - 5px);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.row-content-col-right{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.row-content-header{
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.15em;
|
||||
}
|
||||
|
||||
.align-top{
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#background-image{
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
z-index: -1000;
|
||||
}
|
||||
|
||||
@media(min-width:400px){
|
||||
#background-image{
|
||||
top: -15px;
|
||||
}
|
||||
}
|
||||
@media(min-width:500px){
|
||||
#background-image{
|
||||
top: -30px;
|
||||
}
|
||||
}
|
||||
@media(min-width:700px){
|
||||
#background-image{
|
||||
top: -45px;
|
||||
}
|
||||
}
|
||||
@media(min-width:900px){
|
||||
#background-image{
|
||||
top: -60px;
|
||||
}
|
||||
}
|
||||
@media(min-width:1100px){
|
||||
#background-image{
|
||||
top: -75px;
|
||||
}
|
||||
}
|
||||
@media(min-width:1300px){
|
||||
#background-image{
|
||||
top: -100px;
|
||||
}
|
||||
}
|
||||
|
||||
#filler{
|
||||
width: 100%;
|
||||
padding-bottom: 35%;
|
||||
}
|
||||
|
||||
|
||||
.tint{
|
||||
background-color: rgb(240,240,240);
|
||||
border-top: 1px solid rgb(200,200,200);
|
||||
border-bottom: 1px solid rgb(220,220,220);
|
||||
}
|
||||
|
||||
.see-through{
|
||||
background-color: rgba(0,0,0,.8);
|
||||
}
|
||||
|
||||
.see-through-light{
|
||||
background-color: rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
|
||||
.verse{
|
||||
font-style: italic;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media(max-width: 850px){
|
||||
.row-content-col-left, .row-content-col-right{
|
||||
display: block;
|
||||
width: 100%;
|
||||
float:none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
|
||||
<img id="background-image" src="assets/images/home-images/sunset_b.jpg" alt="background image" width="100%">
|
||||
|
||||
<div id="filler">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content-wrapper">
|
||||
|
||||
<div class="row">
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-left align-top">
|
||||
<p ofbFadeInOnScroll class="row-content-header">...that ye also may have fellowship with us...</p>
|
||||
<p ofbFadeInOnScroll>It is exciting to gather together in the name of the Lord and
|
||||
we sincerily hope that YOU will join us. Guests are always welcome at Old Fashion
|
||||
Baptist and we look forward to seeing you!</p>
|
||||
<p class="verse" ofbFadeInOnScroll>For where two or three are gathered together in my name, there am I in the midst of them. - Matthew 18:20</p>
|
||||
<p ofbFadeInOnScroll><i ofbicon>info_outline</i> <a href="#" routerLink="/whoweare" class="align-top">Learn more about us</a></p>
|
||||
</div>
|
||||
<div class="row-content-col-right">
|
||||
<!-- <img ofbFadeInOnScroll src="assets/images/home-images/2-church-color.png"> -->
|
||||
<img ofbFadeInOnScroll src="assets/images/home-images/family.jpg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row tint">
|
||||
<div class="row-content">
|
||||
<div class="row-content-single-col">
|
||||
<p ofbFadeInOnScroll ofbGrowWhenCenter class="verse">O give thanks unto the Lord; for he is good: because his mercy endureth for ever. - Psalm 118:1</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-right align-top">
|
||||
<p ofbFadeInOnScroll class="row-content-header">Need a ride?</p>
|
||||
<p ofbFadeInOnScroll>
|
||||
Want to come but don't have a way to get here? We would be happy
|
||||
to pick you up! Give us a call to schedule a ride on Sunday Morning.
|
||||
</p>
|
||||
<br>
|
||||
<p ofbFadeInOnScroll>
|
||||
<i ofbicon>phone</i> <a href="tel:+1-406-494-5028" class="align-top">406-494-5028</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="row-content-col-left">
|
||||
<img ofbFadeInOnScroll src="assets/images/home-images/bus2.jpg" height="200">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row tint">
|
||||
<div class="row-content">
|
||||
<div class="row-content-single-col">
|
||||
<p ofbFadeInOnScroll class="verse">The fear of the LORD is the beginning of wisdom: and the knowledge of the holy is understanding. - Proverbs 9:10</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="row-content">
|
||||
<div class="row-content-col-left align-top">
|
||||
<p ofbFadeInOnScroll class="row-content-header">The Holy Bible</p>
|
||||
<div ofbFadeInOnScroll>
|
||||
Here at Old Fashion Baptist Church we love the Word of God!
|
||||
<p class="verse">In the beginning was the Word, and the Word was with God, and the Word was God. - John 1:1</p>
|
||||
We encourage you to come and join as as we study, teach and preach Gods Word!
|
||||
<br><br>
|
||||
<p>
|
||||
<i ofbicon>directions</i> <a target="_blank" class="align-top" href="https://www.google.com/maps/place/Old+Fashion+Baptist+Church/@45.9814004,-112.5320574,11.87z/data=!4m12!1m6!3m5!1s0x535b078c3c74ea33:0xac299097142c5894!2sOld+Fashion+Baptist+Church!8m2!3d45.951287!4d-112.511978!3m4!1s0x535b078c3c74ea33:0xac299097142c5894!8m2!3d45.951287!4d-112.511978">Get Directions</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-content-col-right">
|
||||
<img ofbFadeInOnScroll src="assets/images/home-images/bible.jpg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { Component, HostListener } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'home-component',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.css'],
|
||||
})
|
||||
export class HomeComponent {
|
||||
backgroundTop: string = "0px";
|
||||
|
||||
@HostListener('window:scroll', ['$event'])
|
||||
onScroll(event){
|
||||
let scrollTop = event.target.documentElement.scrollTop || event.target.body.scrollTop || window.pageYOffset;
|
||||
//this.backgroundTop = Math.min((scrollTop * .30),100) * -1 + "px";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import { Component, OnChanges, SimpleChanges, Input } from '@angular/core';
|
||||
import { trigger, transition, state, style, animate } from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'icon-button-component',
|
||||
template: `<button md-button *ngIf="routerLink" [@menuOpened]="menuOpened" class="width100" style="text-align: left;" routerLink="{{routerLink}}"><i ofbicon [iconName]="icon">{{icon}}</i> {{text}}</button>
|
||||
<button md-button *ngIf="!routerLink" [@menuOpened]="menuOpened" class="width100" style="text-align: left;"><i ofbicon [iconName]="icon">{{icon}}</i> {{text}}</button>`,
|
||||
styles: ['.width100{width: 100%;}button{font-size: 16px;margin-bottom: 10px;}'],
|
||||
animations: [trigger(
|
||||
'menuOpened',
|
||||
[
|
||||
state('1',style({transform:'translateX(0)'})),
|
||||
state('0',style({transform: 'translateX(80%)'})),
|
||||
transition("0 => 1", [
|
||||
animate('400ms ease-in-out')
|
||||
]),
|
||||
transition("1 => 0", [
|
||||
animate('300ms ease-in-out')
|
||||
])
|
||||
])]
|
||||
})
|
||||
export class IconButtonComponent implements OnChanges {
|
||||
@Input()
|
||||
public routerLink: string;
|
||||
@Input()
|
||||
public icon: string;
|
||||
@Input()
|
||||
public text: string;
|
||||
@Input()
|
||||
public menuOpen: boolean = true;
|
||||
public menuOpened: boolean = false;
|
||||
@Input()
|
||||
public animationDelay: number = 100;
|
||||
|
||||
ngOnChanges(changes: SimpleChanges){
|
||||
var self = this;
|
||||
if(changes.hasOwnProperty("menuOpen")){
|
||||
if (self.menuOpen === true){
|
||||
setTimeout(function(){ self.menuOpened = self.menuOpen; },self.animationDelay);
|
||||
} else {
|
||||
setTimeout(function(){ self.menuOpened = self.menuOpen; },self.animationDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
.map{
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
#verseFrame{
|
||||
display: block;
|
||||
border: none;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent class="mapWrapper">
|
||||
<p *ngIf="mapLoading">Loading Map...</p>
|
||||
<iframe class="map" (load)="mapLoaded()" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2773.999802164379!2d-112.51416668494458!3d45.951286979109824!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x535b078c3c74ea33%3A0xac299097142c5894!2sOld+Fashion+Baptist+Church!5e0!3m2!1sen!2sus!4v1493451790286" frameborder="0" style="border:0" allowfullscreen></iframe>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
We are located South West of the Copper King hotel in Butte, Montana just off of Motor View Road.
|
||||
<br><br>
|
||||
<iframe id="verseFrame" (load)="verseLoaded()" src="http://www.kingjamesbibleonline.org/popular-bible-verses-widget.php">
|
||||
|
||||
</iframe>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LocationComponent } from './location.component';
|
||||
|
||||
describe('LocationComponent', () => {
|
||||
let component: LocationComponent;
|
||||
let fixture: ComponentFixture<LocationComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LocationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LocationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { BibleVerseService } from './../../services/bible-verse.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'location-component',
|
||||
templateUrl: './location.component.html',
|
||||
styleUrls: ['./location.component.css']
|
||||
})
|
||||
export class LocationComponent implements OnInit {
|
||||
public mapLoading: boolean = true;
|
||||
|
||||
constructor(private bibleVerseService: BibleVerseService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.bibleVerseService.randomVerse().subscribe(
|
||||
verse => {
|
||||
|
||||
},
|
||||
error => console.log(error) );
|
||||
}
|
||||
|
||||
mapLoaded(){
|
||||
this.mapLoading = false;
|
||||
}
|
||||
|
||||
verseLoaded(){
|
||||
console.log("DONE");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
|
||||
#menu-background{
|
||||
position:fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,.7);
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.width100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#close-button{
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
|
||||
#header-menu{
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 160px;
|
||||
overflow-y: auto;
|
||||
background-color: rgba(50,50,50,1);
|
||||
color: white;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
|
||||
<div id="menu-background" [@backgroundMenuOpen]="menuOpen" (click)="menuClick($event)">
|
||||
<div id="header-menu" [@menuOpen]="menuOpen">
|
||||
<ul class="width100">
|
||||
<button md-icon-button id="close-button" (click)="menuClick($event)"><i ofbicon>close</i></button>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="0" icon="help_outline" routerLink="/whoweare" text="Who We Are"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="50" icon="access_time" routerLink="/services" text="Service Times"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="100" icon="place" routerLink="/location" text="Location"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="150" icon="headset" routerLink="/sermons" text="Sermons"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="200" icon="event" routerLink="/events" text="Events"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="250" icon="mail_outline" routerLink="/contact" text="Contact"></icon-button-component></li>
|
||||
<li class="width100"><icon-button-component [menuOpen]="menuOpen" animationDelay="300" icon="input" (click)="showLogin($event)" text="Login"></icon-button-component></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import { Component,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter } from '@angular/core';
|
||||
import { trigger,
|
||||
state,
|
||||
style,
|
||||
transition,
|
||||
animate } from '@angular/animations';
|
||||
import { MdDialog } from '@angular/material';
|
||||
import { LoginPopupComponent } from '../popups/login-popup/login-popup.component';
|
||||
|
||||
@Component({
|
||||
selector: 'menu-component',
|
||||
templateUrl: './menu.component.html',
|
||||
styleUrls: ['./menu.component.css'],
|
||||
animations: [
|
||||
trigger('menuOpen', [
|
||||
state('1', style({transform: 'translateX(0)'})),
|
||||
state('0', style({transform: 'translateX(100%)'})),
|
||||
transition('0 => 1', [
|
||||
animate('400ms ease-in-out', style({transform: 'translateX(0)'}))
|
||||
]),
|
||||
transition('1 => 0', [
|
||||
animate('400ms 100ms ease-in-out', style({transform: 'translateX(100%)'}))
|
||||
])
|
||||
]),
|
||||
trigger('backgroundMenuOpen', [
|
||||
state('1', style({opacity: '1'})),
|
||||
state('0', style({opacity: '0', display:'none'})),
|
||||
transition('0 => 1', [
|
||||
animate('400ms ease-in-out', style({opacity: '1'}))
|
||||
]),
|
||||
transition('1 => 0', [
|
||||
animate('400ms 100ms ease-in-out', style({opacity: '0'}))
|
||||
])
|
||||
])]
|
||||
})
|
||||
export class MenuComponent {
|
||||
@Input()
|
||||
menuOpen: boolean = false;
|
||||
@Output()
|
||||
closed: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
constructor(private mdDialog: MdDialog){
|
||||
|
||||
}
|
||||
|
||||
menuClick(event): void{
|
||||
event.stopPropagation();
|
||||
this.menuOpen = !this.menuOpen;
|
||||
this.closed.emit(this.menuOpen);
|
||||
}
|
||||
|
||||
showLogin(event){
|
||||
event.preventDefault();
|
||||
let dialog = this.mdDialog.open(LoginPopupComponent);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
.full-width{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
form{
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.progressPct{
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.progressBar{
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
|
||||
button{
|
||||
margin: 20px 0px 20px 20px;
|
||||
}
|
||||
|
||||
.first{
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.errorMessages{
|
||||
color: white;
|
||||
background-color: rgb(255,90,90);
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<div md-dialog-title>
|
||||
Add Sermon<br>
|
||||
<div *ngIf="monitorProgress">
|
||||
<span class="progressPct">{{ uploadProgress/uploadTotal | percent:'1.0-2' }}</span>
|
||||
<md-slider class="progressBar" min="0" [max]="uploadTotal" step="1" [value]="uploadProgress"></md-slider>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div md-dialog-content>
|
||||
|
||||
<form #addSermonForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput placeholder="Title" required [(ngModel)]="sermonTitle" name="title" >
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<input mdInput placeholder="Date" required [ngModel]="sermonDate | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="sermonDate = $event" name="date" type="datetime-local">
|
||||
</md-input-container>
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput placeholder="Speaker" required [(ngModel)]="sermonSpeaker" name="speaker" >
|
||||
</md-input-container>
|
||||
<md-input-container class="full-width">
|
||||
<input mdInput placeholder="Description" required [(ngModel)]="sermonDescription" name="description" >
|
||||
</md-input-container>
|
||||
|
||||
<input type="file" (change)="onFileChange($event)" placeholder="Choose File" accept=".mp3,audio/mpeg3" >
|
||||
<br><br>
|
||||
<div *ngIf="errorMessages.length > 0" class="errorMessages">
|
||||
<p *ngFor="let error of errorMessages">
|
||||
{{error}}
|
||||
</p>
|
||||
</div>
|
||||
<button md-raised-button class="first" (click)="cancel($event)" >Cancel</button><!--
|
||||
--><button md-raised-button type="submit" [disabled]="!addSermonForm.form.valid || addSermonButtonDisabled">{{ addSermonButtonText }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddSermonPopupComponent } from './add-sermon-popup.component';
|
||||
|
||||
describe('AddSermonPopupComponent', () => {
|
||||
let component: AddSermonPopupComponent;
|
||||
let fixture: ComponentFixture<AddSermonPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AddSermonPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddSermonPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { ProgressService } from './../../../services/xhr-progress.service';
|
||||
import { LoginPopupComponent } from './../login-popup/login-popup.component';
|
||||
import { MdDialog, MdDialogRef, MdSnackBar } from '@angular/material';
|
||||
import { Sermon } from './../../../interfaces/sermon';
|
||||
import { SermonService } from './../../../services/sermon.service';
|
||||
import { LoginService } from './../../../services/login.service';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-sermon-popup',
|
||||
templateUrl: './add-sermon-popup.component.html',
|
||||
styleUrls: ['./add-sermon-popup.component.css']
|
||||
})
|
||||
export class AddSermonPopupComponent implements OnInit, OnDestroy {
|
||||
public addSermonButtonText: string = "Add Sermon";
|
||||
public addSermonButtonDisabled: boolean = false;
|
||||
|
||||
public sermonTitle: string;
|
||||
public sermonDate: Date = new Date();
|
||||
public sermonSpeaker: string;
|
||||
public sermonDescription: string;
|
||||
public sermonFile: File;
|
||||
|
||||
public errorMessages: string[] = [];
|
||||
|
||||
private _uploadTotal: number = 100;
|
||||
private _uploadProgress: number = 25;
|
||||
public uploadTotal: number = 100;
|
||||
public uploadProgress: number = 0;
|
||||
public monitorProgress: boolean;
|
||||
|
||||
private progressSubscription: Subscription;
|
||||
|
||||
constructor(private progressService: ProgressService, private mdDialog: MdDialog, private mdDialogRef: MdDialogRef<AddSermonPopupComponent>, private loginService: LoginService, private sermonService: SermonService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.progressSubscription = this.progressService.uploadProgress.subscribe(evt => {
|
||||
this._uploadTotal = evt.total;
|
||||
this._uploadProgress = evt.loaded;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(){
|
||||
this.progressSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
this.updateAddButton(false);
|
||||
|
||||
//First check to see if we are logged in
|
||||
this.loginService.isLoggedIn(true).subscribe(is => {
|
||||
if (is === true){
|
||||
this.addSermon();
|
||||
} else {
|
||||
let popup = this.mdDialog.open(LoginPopupComponent);
|
||||
popup.afterClosed().subscribe(r => {
|
||||
if (r === true){
|
||||
this.addSermon();
|
||||
} else {
|
||||
this.updateAddButton(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error =>{
|
||||
this.updateAddButton(true);
|
||||
let errorDialog = this.mdDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||
});
|
||||
}
|
||||
|
||||
updateAddButton(enable: boolean){
|
||||
if (enable){
|
||||
this.addSermonButtonText = "Add Sermon";
|
||||
} else {
|
||||
this.addSermonButtonText = "Please Wait...";
|
||||
}
|
||||
this.addSermonButtonDisabled = !enable;
|
||||
}
|
||||
|
||||
private addSermon(): void {
|
||||
//Check fields
|
||||
this.errorMessages = [];
|
||||
if (this.sermonTitle == null || this.sermonTitle == ""){
|
||||
this.errorMessages.push("Please enter a title");
|
||||
}
|
||||
if (this.sermonDate == null){
|
||||
this.errorMessages.push("Please enter a sermon date");
|
||||
}
|
||||
if (this.sermonSpeaker == null || this.sermonSpeaker == ""){
|
||||
this.errorMessages.push("Please enter a speaker");
|
||||
}
|
||||
if (this.sermonDescription == null || this.sermonDescription == ""){
|
||||
this.errorMessages.push("Please enter a description");
|
||||
}
|
||||
if (this.sermonFile == null){
|
||||
this.errorMessages.push("Please add a sermon MP3 file");
|
||||
}
|
||||
if (this.sermonFile != null && this.sermonFile.type != 'audio/mp3'){
|
||||
console.log(this.sermonFile.type);
|
||||
this.errorMessages.push("File must be a MP3");
|
||||
}
|
||||
if (this.errorMessages.length > 0){ this.updateAddButton(true); return; }
|
||||
|
||||
let s = new Sermon();
|
||||
s.title = this.sermonTitle;
|
||||
s.author = this.sermonSpeaker;
|
||||
s.description = this.sermonDescription;
|
||||
s.sermonDate = this.sermonDate;
|
||||
|
||||
//Start monitoring Progress
|
||||
this.monitorProgress = true;
|
||||
let timer = setInterval(()=>{
|
||||
this.uploadTotal = this._uploadTotal;
|
||||
this.uploadProgress = this._uploadProgress;
|
||||
},500);
|
||||
this.sermonService.addSermon(s,this.sermonFile).subscribe(
|
||||
data=>{
|
||||
console.log(data);
|
||||
this.updateAddButton(true);
|
||||
this.monitorProgress = false;
|
||||
clearInterval(timer);
|
||||
this.mdDialogRef.close(data.sermon);
|
||||
},
|
||||
error => {
|
||||
alert(error);
|
||||
this.updateAddButton(true);
|
||||
this.monitorProgress = false;
|
||||
clearInterval(timer);
|
||||
let errorDialog = this.mdDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||
});
|
||||
}
|
||||
|
||||
onFileChange(event){
|
||||
this.sermonFile = event.srcElement.files[0];
|
||||
}
|
||||
|
||||
cancel(evt){
|
||||
evt.preventDefault();
|
||||
this.mdDialogRef.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
.align-right{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.display-block{
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<div md-dialog-title>{{title}}</div>
|
||||
<div md-dialog-content>
|
||||
{{message}}<br>
|
||||
<md-input-container>
|
||||
<input mdInput [(ngModel)]="searchTerm" (keyup.enter)="onEnter()" name="search" placeholder="Search">
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div md-dialog-actions class="align-right display-block">
|
||||
<button md-raised-button (click)="ok()" class="display-inline">OK</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InputPopupComponent } from './input-popup.component';
|
||||
|
||||
describe('InputPopupComponent', () => {
|
||||
let component: InputPopupComponent;
|
||||
let fixture: ComponentFixture<InputPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ InputPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InputPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import { MdDialogRef } from '@angular/material';
|
||||
import { MD_DIALOG_DATA } from '@angular/material';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-input-popup',
|
||||
templateUrl: './input-popup.component.html',
|
||||
styleUrls: ['./input-popup.component.css']
|
||||
})
|
||||
export class InputPopupComponent implements OnInit {
|
||||
|
||||
public title: string;
|
||||
public message: string;
|
||||
public searchTerm: string = "";
|
||||
|
||||
constructor(@Inject(MD_DIALOG_DATA) public data: any, private mdDialogRef: MdDialogRef<InputPopupComponent>) {
|
||||
this.title = data.title;
|
||||
this.message = data.message;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ok(){
|
||||
this.mdDialogRef.close(this.searchTerm);
|
||||
}
|
||||
|
||||
onEnter(){
|
||||
this.mdDialogRef.close(this.searchTerm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
.input-container{
|
||||
display: block;
|
||||
padding: 10px 0px 10px 0px;
|
||||
}
|
||||
|
||||
button{
|
||||
margin: 20px 0px 20px 20px;
|
||||
}
|
||||
|
||||
.first{
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<div md-dialog-title>
|
||||
Login
|
||||
</div>
|
||||
<div md-dialog-content>
|
||||
<form class="form" #loginForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<md-input-container class="input-container">
|
||||
<input mdInput placeholder="Username" required value="" [(ngModel)]="username" name="username">
|
||||
</md-input-container>
|
||||
<md-input-container class="input-container">
|
||||
<input type="password" mdInput placeholder="Password" required value="" [(ngModel)]="password" name="password">
|
||||
</md-input-container>
|
||||
<button md-raised-button type="button" class="first" (click)="cancel()">Cancel</button><!--
|
||||
--><button md-raised-button type="submit" [disabled]="!loginForm.form.valid || loginButtonDisabled">{{loginButtonText}}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginPopupComponent } from './login-popup.component';
|
||||
|
||||
describe('LoginPopupComponent', () => {
|
||||
let component: LoginPopupComponent;
|
||||
let fixture: ComponentFixture<LoginPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LoginPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoginPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||
import { MdSnackBar, MdDialogRef, MdDialog, MdDialogConfig } from '@angular/material';
|
||||
import { LoginService } from './../../../services/login.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-login-popup',
|
||||
templateUrl: './login-popup.component.html',
|
||||
styleUrls: ['./login-popup.component.css']
|
||||
})
|
||||
export class LoginPopupComponent implements OnInit {
|
||||
public loginButtonText: string = 'Login';
|
||||
public loginButtonDisabled: boolean = false;
|
||||
public username: string;
|
||||
public password: string;
|
||||
|
||||
constructor(private mdDialog: MdDialog, private mdDialogRef: MdDialogRef<LoginPopupComponent>, private loginService: LoginService, private snackbar: MdSnackBar) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
this.loginButtonText = 'Please Wait...';
|
||||
this.loginButtonDisabled = true;
|
||||
this.loginService.login(this.username,this.password).subscribe(
|
||||
data => {
|
||||
if (data.message === 'Logged In'){
|
||||
this.mdDialogRef.close(true);
|
||||
let s = this.snackbar.open("Logged In","OK");
|
||||
s.onAction().subscribe(()=>{ s.dismiss(); });
|
||||
s.afterOpened().subscribe(()=>{ setTimeout(()=>{ s.dismiss(); },3000); });
|
||||
} else {
|
||||
this.showLoginError(data.message);
|
||||
}
|
||||
console.log(data);
|
||||
this.loginButtonText = 'Login';
|
||||
this.loginButtonDisabled = false;
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
this.showLoginError(error);
|
||||
this.loginButtonText = 'Login';
|
||||
this.loginButtonDisabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
showLoginError(message: string){
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { title:'Login Error','message':message };
|
||||
let popup = this.mdDialog.open(OkPopupComponent,opts);
|
||||
}
|
||||
|
||||
cancel(){
|
||||
this.mdDialogRef.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<div md-dialog-title>{{title}}</div>
|
||||
<div md-dialog-content>{{message}}</div>
|
||||
<div md-dialog-actions>
|
||||
<button md-raised-button (click)="close()">OK</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OkPopupComponent } from './ok-popup.component';
|
||||
|
||||
describe('OkPopupComponent', () => {
|
||||
let component: OkPopupComponent;
|
||||
let fixture: ComponentFixture<OkPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OkPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OkPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { MdDialogRef } from '@angular/material';
|
||||
import { MD_DIALOG_DATA } from '@angular/material';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ok-popup',
|
||||
templateUrl: './ok-popup.component.html',
|
||||
styleUrls: ['./ok-popup.component.css']
|
||||
})
|
||||
export class OkPopupComponent implements OnInit {
|
||||
|
||||
public title: string;
|
||||
public message: string;
|
||||
|
||||
constructor(@Inject(MD_DIALOG_DATA) public data: any, private mdDialogRef: MdDialogRef<OkPopupComponent>) {
|
||||
this.title = data.title;
|
||||
this.message = data.message;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
close(){
|
||||
this.mdDialogRef.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
.width100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.shareHeader{
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.social-wrapper{
|
||||
box-sizing: border-box;
|
||||
width: calc(100% - 10px);
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.social-wrapper:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.social-wrapper > span{
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.facebook{
|
||||
background-color: #3B5998;
|
||||
}
|
||||
|
||||
.facebook:hover{
|
||||
background-color: #3B5998;
|
||||
}
|
||||
|
||||
.twitter{
|
||||
background-color: #55acee;
|
||||
}
|
||||
|
||||
.copy{
|
||||
background-color: #7d7d7d;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<div md-dialog-title>Share</div>
|
||||
<div md-dialog-content>
|
||||
<a [href]="facebookIframeUrl | safeUrl" target="_blank">
|
||||
<div class="social-wrapper facebook" data-network="facebook" draggable="false" style="display: inline-block;">
|
||||
<svg fill="#fff" preserveAspectRatio="xMidYMid meet" height="1.2em" width="1.2em" viewBox="0 0 40 40">
|
||||
<g>
|
||||
<path d="m21.7 16.7h5v5h-5v11.6h-5v-11.6h-5v-5h5v-2.1c0-2 0.6-4.5 1.8-5.9 1.3-1.3 2.8-2 4.7-2h3.5v5h-3.5c-0.9 0-1.5 0.6-1.5 1.5v3.5z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="st-label">Share</span>
|
||||
</div>
|
||||
</a>
|
||||
<a [href]="twitterUrl | safeUrl" target="_blank">
|
||||
<div class="social-wrapper twitter" data-network="facebook" draggable="false" style="display: inline-block;">
|
||||
<svg fill="#fff" preserveAspectRatio="xMidYMid meet" height="1.2em" width="1.2em" viewBox="0 0 40 40">
|
||||
<g>
|
||||
<path d="m31.5 11.7c1.3-0.8 2.2-2 2.7-3.4-1.4 0.7-2.7 1.2-4 1.4-1.1-1.2-2.6-1.9-4.4-1.9-1.7 0-3.2 0.6-4.4 1.8-1.2 1.2-1.8 2.7-1.8 4.4 0 0.5 0.1 0.9 0.2 1.3-5.1-0.1-9.4-2.3-12.7-6.4-0.6 1-0.9 2.1-0.9 3.1 0 2.2 1 3.9 2.8 5.2-1.1-0.1-2-0.4-2.8-0.8 0 1.5 0.5 2.8 1.4 4 0.9 1.1 2.1 1.8 3.5 2.1-0.5 0.1-1 0.2-1.6 0.2-0.5 0-0.9 0-1.1-0.1 0.4 1.2 1.1 2.3 2.1 3 1.1 0.8 2.3 1.2 3.6 1.3-2.2 1.7-4.7 2.6-7.6 2.6-0.7 0-1.2 0-1.5-0.1 2.8 1.9 6 2.8 9.5 2.8 3.5 0 6.7-0.9 9.4-2.7 2.8-1.8 4.8-4.1 6.1-6.7 1.3-2.6 1.9-5.3 1.9-8.1v-0.8c1.3-0.9 2.3-2 3.1-3.2-1.1 0.5-2.3 0.8-3.5 1z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="st-label">Tweet</span>
|
||||
</div>
|
||||
</a>
|
||||
<a (click)="copyLink(shareText)">
|
||||
<div class="social-wrapper copy" data-network="facebook" draggable="false" style="display: inline-block;">
|
||||
<svg fill="#fff" preserveAspectRatio="xMidYMid meet" height="1.2em" width="1.2em" viewBox="0 0 40 40">
|
||||
<g>
|
||||
<path d="m30 26.8c2.7 0 4.8 2.2 4.8 4.8s-2.1 5-4.8 5-4.8-2.3-4.8-5c0-0.3 0-0.7 0-1.1l-11.8-6.8c-0.9 0.8-2.1 1.3-3.4 1.3-2.7 0-5-2.3-5-5s2.3-5 5-5c1.3 0 2.5 0.5 3.4 1.3l11.8-6.8c-0.1-0.4-0.2-0.8-0.2-1.1 0-2.8 2.3-5 5-5s5 2.2 5 5-2.3 5-5 5c-1.3 0-2.5-0.6-3.4-1.4l-11.8 6.8c0.1 0.4 0.2 0.8 0.2 1.2s-0.1 0.8-0.2 1.2l11.9 6.8c0.9-0.7 2.1-1.2 3.3-1.2z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="st-label">Copy Link</span>
|
||||
</div>
|
||||
</a>
|
||||
<md-input-container class="width100">
|
||||
<input mdInput #shareText value="{{shareUrl}}">
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div md-dialog-actions>
|
||||
<button md-raised-button (click)="close()">OK</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SharePopupComponent } from './share-popup.component';
|
||||
|
||||
describe('SharePopupComponent', () => {
|
||||
let component: SharePopupComponent;
|
||||
let fixture: ComponentFixture<SharePopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SharePopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SharePopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import { MdDialogRef, MdSnackBar } from '@angular/material';
|
||||
import { MD_DIALOG_DATA } from '@angular/material';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-share-popup',
|
||||
templateUrl: './share-popup.component.html',
|
||||
styleUrls: ['./share-popup.component.css']
|
||||
})
|
||||
export class SharePopupComponent implements OnInit {
|
||||
//private urlPartA: string = "https://www.facebook.com/plugins/share_button.php?href=";
|
||||
//private urlPartB: string = "&layout=button_count&size=large&mobile_iframe=true&width=106&height=28&appId";
|
||||
private urlPartA: string = "https://www.facebook.com/sharer/sharer.php?kid_directed_site=0&u=";
|
||||
private urlPartB: string = "&display=popup&ref=plugin&src=share_button";
|
||||
private twitterPartA: string = "https://twitter.com/intent/tweet?text=";
|
||||
private twitterPartB: string = "https://twitter.com/intent/tweet?text=ShareThis&url=http%3A%2F%2Fwww.sharethis.com%2F";
|
||||
public twitterUrl: string;
|
||||
private sermonId: string;
|
||||
public facebookIframeUrl: string;
|
||||
private shareBaseUrl: string = "https://ofbbutte.com/api/share/s";
|
||||
public shareUrl: string;
|
||||
|
||||
constructor(@Inject(MD_DIALOG_DATA) public data: any, private mdDialogRef: MdDialogRef<SharePopupComponent>, private snackbar: MdSnackBar) {
|
||||
this.sermonId = data.sermonId;
|
||||
this.shareUrl = this.shareBaseUrl + this.sermonId;
|
||||
this.facebookIframeUrl = this.urlPartA + this.shareUrl + this.urlPartB;
|
||||
this.twitterUrl = this.twitterPartA + data.sermonTitle + " - " + data.sermonDescription + "&url=" + this.shareUrl;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
close(){
|
||||
this.mdDialogRef.close();
|
||||
}
|
||||
|
||||
copyLink(target){
|
||||
console.log(target);
|
||||
target.select();
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
var msg = successful ? 'successful' : 'unsuccessful';
|
||||
console.log('Copying text command was ' + msg);
|
||||
target.blur();
|
||||
let s = this.snackbar.open("Link Copied","OK");
|
||||
s.onAction().subscribe(()=>{ s.dismiss(); });
|
||||
s.afterOpened().subscribe(()=>{ setTimeout(()=>{ s.dismiss(); },3000); });
|
||||
} catch (err) {
|
||||
console.log('Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
md-input-container{
|
||||
display:block;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
button{
|
||||
margin: 20px 0px 20px 20px;
|
||||
}
|
||||
|
||||
.first{
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<div md-dialog-title>
|
||||
Add Sermon
|
||||
</div>
|
||||
<div md-dialog-content>
|
||||
|
||||
<form #updateSermonForm="ngForm" (ngSubmit)="onSubmit()">
|
||||
<md-input-container class="example-full-width">
|
||||
<input mdInput required [(ngModel)]="sermonTitle" name="title" placeholder="Title">
|
||||
</md-input-container>
|
||||
<md-input-container>
|
||||
<input mdInput required [ngModel]="sermonDate | date:'yyyy-MM-ddTHH:mm'" (ngModelChange)="sermonDate = $event" name="date" type="datetime-local" placeholder="Choose a date">
|
||||
</md-input-container>
|
||||
<md-input-container class="example-full-width">
|
||||
<input mdInput required [(ngModel)]="sermonSpeaker" name="speaker" placeholder="Speaker">
|
||||
</md-input-container>
|
||||
<md-input-container class="example-full-width">
|
||||
<input mdInput required [(ngModel)]="sermonDescription" name="description" placeholder="Description">
|
||||
</md-input-container>
|
||||
|
||||
<button md-raised-button class="first" type="button" (click)="cancel()" >Cancel</button><!--
|
||||
--><button md-raised-button type="submit" [disabled]="!updateSermonForm.form.valid || updateSermonButtonDisabled">{{ updateSermonButtonText }}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UpdateSermonPopupComponent } from './update-sermon-popup.component';
|
||||
|
||||
describe('UpdateSermonPopupComponent', () => {
|
||||
let component: UpdateSermonPopupComponent;
|
||||
let fixture: ComponentFixture<UpdateSermonPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ UpdateSermonPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UpdateSermonPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import { LoginPopupComponent } from './../login-popup/login-popup.component';
|
||||
import { OkPopupComponent } from './../ok-popup/ok-popup.component';
|
||||
import { Sermon } from './../../../interfaces/sermon';
|
||||
import { SermonService } from './../../../services/sermon.service';
|
||||
import { LoginService } from './../../../services/login.service';
|
||||
import { MdDialog, MdDialogRef, MD_DIALOG_DATA } from '@angular/material';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-update-sermon-popup',
|
||||
templateUrl: './update-sermon-popup.component.html',
|
||||
styleUrls: ['./update-sermon-popup.component.css']
|
||||
})
|
||||
export class UpdateSermonPopupComponent implements OnInit {
|
||||
public updateSermonButtonText: string = "Update Sermon";
|
||||
public updateSermonButtonDisabled: boolean = false;
|
||||
|
||||
public sermonId: number;
|
||||
public sermonTitle: string;
|
||||
public sermonDate: Date = new Date();
|
||||
public sermonSpeaker: string;
|
||||
public sermonDescription: string;
|
||||
|
||||
constructor(@Inject(MD_DIALOG_DATA) private data: any,
|
||||
private mdDialog: MdDialog,
|
||||
private mdDialogRef: MdDialogRef<UpdateSermonPopupComponent>,
|
||||
private loginService: LoginService,
|
||||
private sermonService: SermonService) {
|
||||
|
||||
this.sermonId = this.data.id;
|
||||
this.sermonTitle = this.data.title;
|
||||
this.sermonDate = this.data.date;
|
||||
this.sermonSpeaker = this.data.author;
|
||||
this.sermonDescription = this.data.description;
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onSubmit(){
|
||||
this.updateButton(false);
|
||||
|
||||
//First check to see if we are logged in
|
||||
this.loginService.isLoggedIn(true).subscribe(is => {
|
||||
if (is === true){
|
||||
this.updateSermon();
|
||||
} else {
|
||||
let popup = this.mdDialog.open(LoginPopupComponent);
|
||||
popup.afterClosed().subscribe(r => {
|
||||
if (r === true){
|
||||
this.updateSermon();
|
||||
} else {
|
||||
this.updateButton(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error =>{
|
||||
this.updateButton(true);
|
||||
let errorDialog = this.mdDialog.open(OkPopupComponent,{data:{title:'Upload Error',message:'There was an error uploading the sermon\n' + error}});
|
||||
});
|
||||
}
|
||||
|
||||
private updateSermon(): void {
|
||||
let s = new Sermon;
|
||||
s.id = this.sermonId;
|
||||
s.title = this.sermonTitle;
|
||||
s.author = this.sermonSpeaker;
|
||||
s.description = this.sermonDescription;
|
||||
s.sermonDate = this.sermonDate;
|
||||
|
||||
//Start monitoring Progress
|
||||
this.sermonService.updateSermon(s).subscribe(
|
||||
data=>{
|
||||
console.log(data);
|
||||
this.mdDialogRef.close(data.sermon);
|
||||
},
|
||||
error => {
|
||||
this.updateButton(true);
|
||||
let errorDialog = this.mdDialog.open(OkPopupComponent,{data:{title:'Update Error',message:'There was an error updating the sermon\n' + error}});
|
||||
});
|
||||
}
|
||||
|
||||
updateButton(enable: boolean){
|
||||
if (enable){
|
||||
this.updateSermonButtonText = "Update Sermon";
|
||||
} else {
|
||||
this.updateSermonButtonText = "Please Wait...";
|
||||
}
|
||||
this.updateSermonButtonDisabled = !enable;
|
||||
}
|
||||
|
||||
cancel(){
|
||||
this.mdDialogRef.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<div md-dialog-title>{{title}}</div>
|
||||
<div md-dialog-content>{{message}}</div>
|
||||
<div md-dialog-actions>
|
||||
<button md-raised-button (click)="yes()">YES</button>
|
||||
<button md-raised-button (click)="no()">NO</button>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { YesNoPopupComponent } from './yes-no-popup.component';
|
||||
|
||||
describe('YesNoPopupComponent', () => {
|
||||
let component: YesNoPopupComponent;
|
||||
let fixture: ComponentFixture<YesNoPopupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ YesNoPopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(YesNoPopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import { MdDialogRef } from '@angular/material';
|
||||
import { MD_DIALOG_DATA } from '@angular/material';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-yes-no-popup',
|
||||
templateUrl: './yes-no-popup.component.html',
|
||||
styleUrls: ['./yes-no-popup.component.css']
|
||||
})
|
||||
export class YesNoPopupComponent implements OnInit {
|
||||
|
||||
public title: string;
|
||||
public message: string;
|
||||
|
||||
constructor(@Inject(MD_DIALOG_DATA) public data: any, private mdDialogRef: MdDialogRef<YesNoPopupComponent>) {
|
||||
this.title = data.title;
|
||||
this.message = data.message;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
yes(){
|
||||
this.mdDialogRef.close(true);
|
||||
}
|
||||
|
||||
no(){
|
||||
this.mdDialogRef.close(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
.sermon-header{
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid gray;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li{
|
||||
padding: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<div class="sermon-container">
|
||||
<p class="sermon-header" >Recent Sermons</p>
|
||||
<p *ngIf="loading">Loading...</p>
|
||||
<ul class="sermons">
|
||||
<li *ngFor="let sermon of sermons; let i = index;">
|
||||
<sermon-small-component
|
||||
[title]="sermon.title"
|
||||
[date]="sermon.sermonDate"
|
||||
[delayFadeIn]="(i+1)*200"
|
||||
[url]="sermon.url"
|
||||
[id]="sermon.id"
|
||||
></sermon-small-component>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Sermon } from '../../interfaces/sermon';
|
||||
import { SermonService } from '../../services/sermon.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'recent-sermons-component',
|
||||
templateUrl: './recent-sermons.component.html',
|
||||
styleUrls: ['./recent-sermons.component.css']
|
||||
})
|
||||
export class RecentSermonsComponent implements OnInit {
|
||||
sermons: Sermon[];
|
||||
loading: boolean = false;
|
||||
@Input()
|
||||
numberOfSermonsToShow = 3;
|
||||
|
||||
constructor(private sermonService: SermonService){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getSermons();
|
||||
}
|
||||
|
||||
getSermons(): void{
|
||||
this.sermons = [];
|
||||
this.loading = true;
|
||||
this.sermonService.getSermons(this.numberOfSermonsToShow).subscribe(sermons => {
|
||||
this.sermons = sermons;
|
||||
this.loading = false;
|
||||
console.log(this.sermons)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
#content{
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.main-content{
|
||||
width: 70%;
|
||||
display: table-cell;
|
||||
padding: 20px 10px 10px 10px;
|
||||
}
|
||||
|
||||
.side-bar{
|
||||
width: 30%;
|
||||
display: table-cell;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.align-top{
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@media(max-width:800px){
|
||||
.side-bar{
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.hide-on-mobile{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-content{
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<div id="content-wrapper">
|
||||
<div id="content">
|
||||
<div class="main-content align-top">
|
||||
<ng-content select="[mainContent]"></ng-content>
|
||||
</div><!--
|
||||
--><div class="side-bar align-top" [class.hide-on-mobile]="hideSideBarOnMobile">
|
||||
<ng-content select="[sideBar]"></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'secondary-page-component',
|
||||
templateUrl: './secondary-page.component.html',
|
||||
styleUrls: ['./secondary-page.component.css'],
|
||||
})
|
||||
export class SecondaryPageComponent implements OnInit {
|
||||
@Input()
|
||||
public hideSideBarOnMobile: boolean;
|
||||
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
.wrapper{
|
||||
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.photo{
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
max-width: 100px;
|
||||
margin: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fade{
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 20px;
|
||||
padding-bottom: 2px;
|
||||
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ffffff+100&0+0,0.8+100 */
|
||||
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,0.8) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,0.8) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,0.8) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ccffffff',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
.photo button{
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
button img{
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.info{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 2px 2px 8px 5px;
|
||||
box-sizing: border-box;
|
||||
width: calc(100% - 100px);
|
||||
overflow-y: hidden;
|
||||
position: relative;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.title{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.date, .author{
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.description{
|
||||
font-size: 14px;
|
||||
color: darkgray;
|
||||
word-wrap: none;
|
||||
border-top: 0px solid lightgray;
|
||||
padding-top:6px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.expanded{
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.expanded-content{
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.buttons, .buttons-edit{
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.buttons button{
|
||||
display: inline-block;
|
||||
width: 33.33333%;
|
||||
}
|
||||
|
||||
.border{
|
||||
margin: 0px 5px 0px 5px;
|
||||
border-top: 1px inset lightgray;
|
||||
}
|
||||
|
||||
.buttons-edit button{
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<div class="wrapper" [@inout]="startFadeIn">
|
||||
<div class="photo">
|
||||
<button md-button (click)="play()">
|
||||
<img src="../../assets/images/facebookplay.png" />
|
||||
</button>
|
||||
</div><!--
|
||||
--><div class="info" (click)="toggleState()">
|
||||
<span class="title">{{ title }}</span>
|
||||
<br>
|
||||
<span class="date">{{ date |date:'yyyy-MM-dd' }}</span> | <span class="author">{{ author }}</span>
|
||||
<br>
|
||||
<p class="description" [@toggleAnimationFade]="state">
|
||||
{{ description }}
|
||||
</p>
|
||||
<div class="fade"><i ofbicon *ngIf="state === 'closed'">arrow_drop_down</i><i ofbicon *ngIf="state === 'open'">arrow_drop_up</i></div>
|
||||
</div>
|
||||
<div class="expanded" [@toggleAnimation]="state" (click)="toggleState()">
|
||||
<p class="expanded-content">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<button md-button class="action pct40" (click)="play()" ><i ofbicon>headset</i> Listen</button><!--
|
||||
--><button md-button class="action pct50" (click)="download()" ><i ofbicon>file_download</i> Download</button><!--
|
||||
--><button md-button class="action pct10" (click)="share()" ><i ofbicon>share</i> Share</button>
|
||||
</div>
|
||||
<div class="buttons-edit" *ngIf="loggedIn">
|
||||
<div class="border"></div>
|
||||
<button md-button class="action" (click)="edit()" ><i ofbicon>edit</i> Edit</button><!--
|
||||
--><button md-button class="action" (click)="delete()" ><i ofbicon>delete_forever</i> Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
.inner-wrapper{
|
||||
position:relative;
|
||||
|
||||
padding: 0px 0px 10px 0px;
|
||||
padding: 10px;
|
||||
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.title{
|
||||
display: inline-block;
|
||||
font-size: 1.15em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.action-buttons{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.speaker-date{
|
||||
font-style: italic;
|
||||
color: darkslategray;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.description{
|
||||
margin: 15px 0px 15px 0px;
|
||||
}
|
||||
|
||||
@media(max-width:700px){
|
||||
.speaker-date{
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<div class="wrapper" [@inout]="startFadeIn">
|
||||
<div class="inner-wrapper">
|
||||
<p class="title">{{ title }}</p>
|
||||
<div class="speaker-date">
|
||||
<p>{{ author }} | {{ date |date:'yyyy-MM-dd' }}</p>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="description">{{ description }}</div><!--
|
||||
--><div class="action-buttons">
|
||||
<button md-button class="action pct40" (click)="play()" ><i ofbicon>headset</i> Listen</button><!--
|
||||
--><button md-button class="action pct50" (click)="download()" ><i ofbicon>file_download</i> Download</button><!--
|
||||
--><button md-button class="action pct10" (click)="share()" ><i ofbicon>share</i> Share</button>
|
||||
</div><!--
|
||||
--><div class="action-buttons" *ngIf="loggedIn">
|
||||
<button md-button class="action" (click)="edit()" ><i ofbicon>edit</i> Edit</button><!--
|
||||
--><button md-button class="action" (click)="delete()" ><i ofbicon>delete_forever</i> Delete</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SermonLargeComponent } from './sermon-large.component';
|
||||
|
||||
describe('SermonLargeComponent', () => {
|
||||
let component: SermonLargeComponent;
|
||||
let fixture: ComponentFixture<SermonLargeComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SermonLargeComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SermonLargeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import { SharePopupComponent } from './../popups/share-popup/share-popup.component';
|
||||
import { Sermon } from './../../interfaces/sermon';
|
||||
import { UpdateSermonPopupComponent } from './../popups/update-sermon-popup/update-sermon-popup.component';
|
||||
import { SermonService } from './../../services/sermon.service';
|
||||
import { YesNoPopupComponent } from './../popups/yes-no-popup/yes-no-popup.component';
|
||||
import { MdDialog, MdDialogConfig, MdSnackBar } from '@angular/material';
|
||||
import { Component, OnInit, Input, AfterContentInit } from '@angular/core';
|
||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||
import { SermonSmallComponent } from '../sermon-small/sermon-small.component';
|
||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||
import { SERMON_DOWNLOAD_URL } from '../../constants/urls';
|
||||
|
||||
@Component({
|
||||
selector: 'sermon-large-component',
|
||||
templateUrl: './sermon-large-pic.component.html',
|
||||
styleUrls: ['./sermon-large-pic.component.css'],
|
||||
animations:[
|
||||
trigger("inout",[
|
||||
state("1", style({ opacity: '1' })),
|
||||
state("0",style({ opacity: '0' })),
|
||||
transition('* => 1',[
|
||||
animate('500ms ease-in-out')
|
||||
]),
|
||||
transition(':enter',[
|
||||
animate('0ms')
|
||||
])
|
||||
]),
|
||||
trigger('toggleAnimation', [
|
||||
state('open', style({
|
||||
height: '*',
|
||||
})),
|
||||
state('closed', style({
|
||||
height: '0px',
|
||||
})),
|
||||
transition('open <=> closed', animate('500ms ease-in-out'))
|
||||
]),
|
||||
trigger('toggleAnimationFade', [
|
||||
state('open', style({
|
||||
opacity: 0,
|
||||
})),
|
||||
state('closed', style({
|
||||
opacity: 1,
|
||||
})),
|
||||
transition('open <=> closed', animate('500ms ease-in-out'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class SermonLargeComponent extends SermonSmallComponent implements OnInit, AfterContentInit {
|
||||
|
||||
public state: string = 'closed';
|
||||
|
||||
@Input()
|
||||
public loggedIn: boolean;
|
||||
|
||||
constructor(private aplayer: AudioPlayerService
|
||||
,private dialog: MdDialog
|
||||
,private sermonService: SermonService
|
||||
,private snackbar: MdSnackBar) {
|
||||
super(aplayer);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
toggleState(){
|
||||
this.state = this.state === 'open' ? 'closed' : 'open'
|
||||
}
|
||||
|
||||
download(){
|
||||
window.location.href = SERMON_DOWNLOAD_URL + this.id;
|
||||
}
|
||||
|
||||
share(){
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { sermonId: this.id, sermonTitle: this.title, sermonDescription: this.description };
|
||||
let dialog = this.dialog.open(SharePopupComponent, opts);
|
||||
}
|
||||
|
||||
edit(){
|
||||
let config = new MdDialogConfig();
|
||||
config.data = {
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
date: this.date,
|
||||
author: this.author
|
||||
};
|
||||
let dialog = this.dialog.open(UpdateSermonPopupComponent,config);
|
||||
|
||||
dialog.afterClosed().subscribe(s => {
|
||||
s = s as Sermon;
|
||||
if (s){
|
||||
this.title = s.title;
|
||||
this.description = s.description;
|
||||
this.author = s.author;
|
||||
this.date = s.date;
|
||||
|
||||
let snack = this.snackbar.open(s.title + " was updated!", "Ok");
|
||||
snack.onAction().subscribe(()=>{
|
||||
snack.dismiss();
|
||||
});
|
||||
setTimeout(()=>{snack.dismiss();},3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
delete(){
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { title:'Delete','message':'Are you sure you want to delete "' + this.title + '"?' };
|
||||
let dialog = this.dialog.open(YesNoPopupComponent, opts);
|
||||
|
||||
dialog.afterClosed().subscribe(s => {
|
||||
s = s as boolean;
|
||||
if (s === true){
|
||||
this.sermonService.deleteSermon(this.id).subscribe(
|
||||
success => { console.log(success); },
|
||||
error => { console.log(error); }
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
|
||||
.inner-wrapper{
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.title{
|
||||
display: table;
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.title-text{
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
padding-left: 10px;
|
||||
font-size: .95rem;
|
||||
}
|
||||
|
||||
button{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ofb-button{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<div class="wrapper" [@inout]="startFadeIn">
|
||||
<div class="inner-wrapper">
|
||||
<div class="title">
|
||||
<button md-button (click)="play()"></button>
|
||||
<date-component class="title-date" [date]="date"></date-component>
|
||||
<span class="title-text">{{ title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import { Component, AfterContentInit, Input } from '@angular/core';
|
||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||
|
||||
@Component({
|
||||
selector: 'sermon-small-component',
|
||||
templateUrl: './sermon-small.component.html',
|
||||
styleUrls: ['./sermon-small.component.css'],
|
||||
animations:[
|
||||
trigger("inout",[
|
||||
state("1", style({ opacity: '1', transform:'translateX(0)' })),
|
||||
state("0",style({ opacity: '0', transform:'translateX(5%)' })),
|
||||
transition('* => 1',[
|
||||
animate('500ms ease-in-out')
|
||||
]),
|
||||
transition(':enter',[
|
||||
animate('0ms')
|
||||
])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class SermonSmallComponent implements AfterContentInit {
|
||||
@Input()
|
||||
id: number;
|
||||
@Input()
|
||||
title: string;
|
||||
@Input()
|
||||
description: string;
|
||||
@Input()
|
||||
date: Date;
|
||||
@Input()
|
||||
author: string;
|
||||
@Input()
|
||||
url: string;
|
||||
public startFadeIn: boolean = false;
|
||||
@Input()
|
||||
public delayFadeIn: number = 100;
|
||||
|
||||
constructor(private audioPlayer: AudioPlayerService){
|
||||
|
||||
}
|
||||
|
||||
play(): void{
|
||||
if (this.audioPlayer.getIsPlaying() == true && this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){
|
||||
this.audioPlayer.pause();
|
||||
} else {
|
||||
if (this.audioPlayer.getMetaData() != null && this.audioPlayer.getMetaData().id == this.id){
|
||||
this.audioPlayer.resume();
|
||||
} else {
|
||||
this.audioPlayer.play(this.url,{id:this.id,title:this.title,author:this.author});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterContentInit(): void{
|
||||
setTimeout(() => this.startFadeIn = true, this.delayFadeIn);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li{
|
||||
margin: 40px 0px 40px 0px; /* top right bottom left */
|
||||
}
|
||||
|
||||
li:first-child{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
li:last-child{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.side-bar{
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.width100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-search{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fab-buttons{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#audio-player-filler{
|
||||
height: 60px;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
@media(max-width:800px){
|
||||
.mobile-search{
|
||||
display: block;
|
||||
}
|
||||
.fab-buttons{
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<div class="mobile-search">
|
||||
<md-input-container class="width100">
|
||||
<input #searchMobile mdInput placeholder="Search Sermons" [value]="searchTerm" (keyup)="searchChange(searchMobile.value)">
|
||||
</md-input-container>
|
||||
<br><br>
|
||||
</div>
|
||||
<ul>
|
||||
<li *ngFor="let sermon of sermons; let i = index;">
|
||||
<sermon-large-component
|
||||
[id]="sermon.id"
|
||||
[title]="sermon.title"
|
||||
[date]="sermon.sermonDate"
|
||||
[description]="sermon.description"
|
||||
[author]="sermon.author"
|
||||
[delayFadeIn]="(i-((((sermons.length*10)/10)-10) > 0 ? (((sermons.length*10)/10)-10) : 0))*200"
|
||||
[url]="sermon.url"
|
||||
[loggedIn]="loggedIn"
|
||||
></sermon-large-component>
|
||||
</li>
|
||||
<button md-button class="width100" style="text-align: center;" (click)="loadMoreSermonsClick()">
|
||||
<i ofbicon *ngIf="loading">access_time</i><span *ngIf="loading"> Loading...</span>
|
||||
<i ofbicon *ngIf="!loading">expand_more</i><span *ngIf="!loading"> Load More</span>
|
||||
</button>
|
||||
</ul>
|
||||
<div class="fab-buttons" >
|
||||
<button md-fab (click)="searchFabClick()"><i ofbicon>search</i></button>
|
||||
<button md-fab *ngIf="loggedIn" (click)="addSermon()"><i ofbicon>add</i></button>
|
||||
<div id="audio-player-filler" *ngIf="audioPlayerOpen"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
<div class="search-bar">
|
||||
<md-input-container class="width100">
|
||||
<input #search mdInput placeholder="Search Sermons" [value]="searchTerm" (keyup)="searchChange(search.value)">
|
||||
</md-input-container>
|
||||
</div>
|
||||
<button md-raised-button class="width100" (click)="addSermon()" >Add Sermon</button>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
import { InputPopupComponent } from './../popups/input-popup/input-popup.component';
|
||||
import { AudioPlayerService } from './../../services/audio-player.service';
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { SermonService } from '../../services/sermon.service';
|
||||
import { LoginService } from '../../services/login.service';
|
||||
import { Sermon } from '../../interfaces/sermon';
|
||||
import { MdSnackBar, MdDialog, MdDialogConfig } from '@angular/material';
|
||||
|
||||
import { AddSermonPopupComponent } from '../popups/add-sermon-popup/add-sermon-popup.component';
|
||||
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
|
||||
@Component({
|
||||
selector: 'sermons-component',
|
||||
templateUrl: './sermons.component.html',
|
||||
styleUrls: ['./sermons.component.css'],
|
||||
})
|
||||
export class SermonsComponent implements OnInit {
|
||||
|
||||
|
||||
public sermons: Sermon[];
|
||||
public loading: boolean = false;
|
||||
public page: number = 1;
|
||||
public searchTerm: string = '';
|
||||
public loggedIn: boolean = false;
|
||||
public audioPlayerOpen: boolean;
|
||||
private searchWait: any;
|
||||
private dialogConfig: MdDialogConfig;
|
||||
|
||||
|
||||
constructor(private loginService: LoginService,
|
||||
private snackbar: MdSnackBar,
|
||||
private dialog: MdDialog,
|
||||
private sermonService: SermonService,
|
||||
private route: ActivatedRoute,
|
||||
private location: Location,
|
||||
private audioPlayerService: AudioPlayerService){
|
||||
|
||||
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is; });
|
||||
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
||||
this.audioPlayerService.onAudioPlayerOpenClose.subscribe(is => { this.audioPlayerOpen = is; });
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void{
|
||||
this.route.params
|
||||
// (+) converts string 'id' to a number
|
||||
.subscribe((params: Params) => {
|
||||
let id = +params['id'];
|
||||
id = Number.isNaN(id) ? -1 : id;
|
||||
if (id > -1){
|
||||
this.page = 0;
|
||||
this.getSingleSermon(id);
|
||||
} else {
|
||||
this.getSermons(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
searchChange(searchTerm): void{
|
||||
this.searchTerm = searchTerm;
|
||||
if (this.searchWait) clearTimeout(this.searchWait);
|
||||
this.searchWait = setTimeout(()=>this.getSermons(true),400);
|
||||
}
|
||||
|
||||
loadMoreSermonsClick(): void{
|
||||
this.page++;
|
||||
//this.location.go("/sermons/" + this.page);
|
||||
this.getSermons(false);
|
||||
}
|
||||
|
||||
getSingleSermon(id: number){
|
||||
this.loading = true;
|
||||
this.sermons = this.sermons || [];
|
||||
this.sermons = [];
|
||||
|
||||
this.sermonService.getSermonById(id).subscribe(
|
||||
sermons => {
|
||||
this.sermons.push(sermons)
|
||||
this.loading = false;
|
||||
},
|
||||
error => {
|
||||
this.getSermons(true);
|
||||
} );
|
||||
}
|
||||
|
||||
getSermons(clearExisting): void{
|
||||
this.loading = true;
|
||||
this.sermons = this.sermons || [];
|
||||
if (clearExisting) {
|
||||
this.sermons = [];
|
||||
this.page = 1;
|
||||
}
|
||||
this.sermonService.searchSermons(this.searchTerm,this.page).subscribe(
|
||||
sermons => {
|
||||
this.addSermons(sermons);
|
||||
this.loading = false;
|
||||
},
|
||||
error => console.log(error) );
|
||||
}
|
||||
|
||||
addSermons(sermons: Sermon[]): void{
|
||||
for(let i = 0; i < sermons.length; i++){
|
||||
this.sermons.push(sermons[i]);
|
||||
}
|
||||
}
|
||||
|
||||
addSermon(){
|
||||
let dialog = this.dialog.open(AddSermonPopupComponent,this.dialogConfig);
|
||||
|
||||
dialog.afterClosed().subscribe(s => {
|
||||
s = s as Sermon;
|
||||
if (s){
|
||||
this.sermons.unshift(s);
|
||||
let snack = this.snackbar.open(s.title + " was added!", "Ok");
|
||||
snack.onAction().subscribe(()=>{
|
||||
snack.dismiss();
|
||||
});
|
||||
setTimeout(()=>{snack.dismiss();},3000);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
searchFabClick(){
|
||||
let opts = new MdDialogConfig;
|
||||
opts.data = { title:'Search','message':'' };
|
||||
|
||||
let dialog = this.dialog.open(InputPopupComponent,opts);
|
||||
|
||||
dialog.afterClosed().subscribe(search => {
|
||||
if (typeof search !== 'undefined' && this.searchTerm != search){
|
||||
this.searchTerm = search;
|
||||
this.searchChange(this.searchTerm);
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
.verse{
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.reference{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.side-bar-header{
|
||||
text-align: center;
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
.section-header{
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid gray;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
img{
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
-webkit-box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
-moz-box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true">
|
||||
<div mainContent>
|
||||
<div>
|
||||
<p ofbFadeInOnScroll class="section-header">Service Times</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Join Us every Sunday and Wednesday for challenging messages from the Bible and fellowship with others!
|
||||
Bring the whole family!
|
||||
<br><br>
|
||||
Nursery is available during all services.
|
||||
</p>
|
||||
<br>
|
||||
<div ofbFadeInOnScroll class="imageBorder">
|
||||
<img class="image" src="assets/images/sign.png" alt="Church Image" />
|
||||
</div>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Sunday School 10 AM</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
During the Sunday morning service, kids are allowed to separate from the adults to attend a class that is appropriate for thier age group. We have a nursery and Sunday School classes for all age groups.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Sunday Morning 11 AM</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Sunday Morning church service immediately follows Sunday School service with a short break inbetween. Nursery and childrens church for ages up through age 4 is available during the Sunday morning hour.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Sunday Evening 7 PM</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Sunday night is the last opportunity to hear a great message before the work week starts. We encourage you to come visit us each sunday night at 7 P.M. Nursery services are available.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Wednesday Evening 7 PM</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Join us on Wednesday night for a Bible study that will surely challenge you in your walk with the Lord. Wednesday evening is a great time to come and hear a great message from the Bible to stay focused during the week. Nursery and childrens church are also available.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header"></p>
|
||||
<div ofbFadeInOnScroll class="section-paragraph">
|
||||
<p class="verse">Not forsaking the assembling of ourselves together, as the manner of some is; but exhorting one another: and so much the more, as ye see the day approaching.</p>
|
||||
<p class="verse reference">Hebrews 10:25</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar class="side-bar">
|
||||
<upcoming-events-component [numberOfEventsToShow]="4" ></upcoming-events-component>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import { WindowRefService } from './../../services/window-ref.service';
|
||||
import { Component, HostListener, OnInit } from '@angular/core';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'services-component',
|
||||
templateUrl: './services.component.html',
|
||||
styleUrls: ['./services.component.css'],
|
||||
})
|
||||
export class ServicesComponent implements OnInit {
|
||||
|
||||
public columnCount: number = 2;
|
||||
private smallColumnCount: number = 1;
|
||||
private medColumnCount: number = 2;
|
||||
private smallWidth: number = 500;
|
||||
|
||||
constructor(private windowRef: WindowRefService){ }
|
||||
|
||||
ngOnInit(){
|
||||
let event = { target:this.windowRef.getWindow() };
|
||||
this.onResize(event);
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event) {
|
||||
if (event.target.innerWidth < this.smallWidth){
|
||||
this.columnCount = this.smallColumnCount;
|
||||
} else {
|
||||
this.columnCount = this.medColumnCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
.event-header{
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid gray;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
ul{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
li{
|
||||
padding: 5px;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<div class="event-container">
|
||||
<p class="event-header" >Upcoming Events</p>
|
||||
<p *ngIf="loading">Loading...</p>
|
||||
<ul class="events">
|
||||
<li *ngFor="let event of events; let i = index;">
|
||||
<event-component
|
||||
[title]="event.title"
|
||||
[startDate]="event.startDate"
|
||||
[delayFadeIn]="(i+1)*200"
|
||||
></event-component>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Event } from '../../interfaces/event';
|
||||
import { EventService } from '../../services/event.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'upcoming-events-component',
|
||||
templateUrl: './upcoming-events.component.html',
|
||||
styleUrls: ['./upcoming-events.component.css']
|
||||
})
|
||||
export class UpcomingEventsComponent implements OnInit {
|
||||
events: Event[];
|
||||
loading: boolean = false;
|
||||
@Input()
|
||||
numberOfEventsToShow = 3;
|
||||
|
||||
constructor(private eventService: EventService){
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getSermons();
|
||||
}
|
||||
|
||||
getSermons(): void{
|
||||
this.events = [];
|
||||
this.loading = true;
|
||||
this.eventService.getEvents(this.numberOfEventsToShow).then(events => {
|
||||
this.events = events;
|
||||
this.loading = false;
|
||||
console.log(this.events)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
.main-content-header{
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
|
||||
.side-bar-header{
|
||||
text-align: center;
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
.section-header{
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid gray;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
img{
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
-webkit-box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
-moz-box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<secondary-page-component [hideSideBarOnMobile]="true" >
|
||||
<div mainContent>
|
||||
<div>
|
||||
<p ofbFadeInOnScroll class="section-header">Who We Are</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Old Fashion Baptist Church is a small church located in Butte, Montana. We meet regularly throughout the week
|
||||
to spread the word of God as well as encourage and challenge believers in their Christian life.
|
||||
For service times click <a routerLink="/services">here</a>. Contact information and directions are available
|
||||
<a routerLink="/contact">here</a>
|
||||
</p>
|
||||
<br><br>
|
||||
<div ofbFadeInOnScroll class="imageBorder">
|
||||
<img class="image" src="assets/images/home-images/church.jpg" alt="Church Image" />
|
||||
</div>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">What to expect</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Sometimes it can be difficult to attend if you are not familiar with church and don't know what to expect.
|
||||
One thing you can always expect is to be welcomed at Old Fashion Baptist. We count it a privalege to have
|
||||
visitors attend our church services so the first thing you will find is a friendly church family.
|
||||
<br><br>
|
||||
Each service begins with a few songs along with prayer. Prayer and praise are a great way to help prepare
|
||||
our hearts for the message that follows. You can expect the message to last aproximately 45 - 60
|
||||
minutes and will be straight from the Bible. We want you to know that the message is from the Bible and will
|
||||
turn to verses throughout the service. You are welcome to just listen or follow along in your Bible.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Nursery</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
Nursery workers are available for every service. Our nursery is available so that you can attend the church service
|
||||
without interruption.
|
||||
</p>
|
||||
|
||||
<br><br>
|
||||
<p ofbFadeInOnScroll class="section-header">Kids</p>
|
||||
<p ofbFadeInOnScroll class="section-paragraph">
|
||||
We also offer Sunday School classes for all age groups of kids. This is a great opportunity for
|
||||
children to recieve a message that is appropriate for their age.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div sideBar ofbFadeInOnScroll>
|
||||
<recent-sermons-component [numberOfSermonsToShow]="4" ></recent-sermons-component>
|
||||
</div>
|
||||
</secondary-page-component>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'whoweare-component',
|
||||
templateUrl: './whoweare.component.html',
|
||||
styleUrls: ['./whoweare.component.css'],
|
||||
})
|
||||
export class WhoWeAreComponent {
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +1,42 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Client</title>
|
||||
<base href="/">
|
||||
<meta charset="utf-8">
|
||||
<title>Ofb1</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<style>
|
||||
.loader-background{
|
||||
background-color: rgb(0, 188, 212);
|
||||
position: fixed;
|
||||
left:0px;
|
||||
top:0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.loader {
|
||||
color: #ffffff;
|
||||
margin: 100px auto;
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
}
|
||||
.loader-small{
|
||||
color: #ffffff;
|
||||
margin: 20px auto;
|
||||
position: relative;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<body>
|
||||
<app-root>
|
||||
<div class="loader-background">
|
||||
<div class="loader">Old Fashion Baptist</div>
|
||||
<div class="loader-small">Please Wait...</div>
|
||||
</div>
|
||||
</app-root>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
@ -1 +1,53 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
||||
@import '../node_modules/@angular/material/prebuilt-themes/indigo-pink.css';
|
||||
|
||||
|
||||
*{
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/*MATERIAL FONT FOR ICONS*/
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(./assets/fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular'),
|
||||
url(./assets/fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
||||
url(./assets/fonts/MaterialIcons-Regular.woff) format('woff'),
|
||||
url(./assets/fonts/MaterialIcons-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
.material-icon {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px; /* Preferred icon size */
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* Support for Safari and Chrome. */
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
/* Support for Firefox. */
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
||||
/* END MATERIAL FONT ICONS*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
export const MONTHS = {
|
||||
0: "JAN",
|
||||
1: "FEB",
|
||||
2: "MAR",
|
||||
3: "APR",
|
||||
4: "MAY",
|
||||
5: "JUN",
|
||||
6: "JUL",
|
||||
7: "AUG",
|
||||
8: "SEP",
|
||||
9: "OCT",
|
||||
10: "NOV",
|
||||
11: "DEC"
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
export const SERMONS_BY_ID = '//ofbbutte.com/api/sermons/';
|
||||
export const SERMONS_BY_PAGE_URL = '//ofbbutte.com/api/sermons/page/';
|
||||
export const SERMONS_BY_SEARCH_URL = '//ofbbutte.com/api/sermons/search';
|
||||
export const SERMON_MP3_BASE_URL = '//ofbbutte.com/static/media/';
|
||||
export const SERMON_ADD_URL = "//ofbbutte.com/api/sermons/a/";
|
||||
export const SERMON_DELETE_URL = "//ofbbutte.com/api/sermons/a/";
|
||||
export const SERMON_UPDATE_URL = "//ofbbutte.com/api/sermons/a/";
|
||||
export const SERMON_DOWNLOAD_URL = "//ofbbutte.com/api/sermons/download/";
|
||||
export const LOGIN_URL = '//ofbbutte.com/api/login';
|
||||
export const LOGIN_VALIDATE_TOKEN = '';
|
||||
export const EMAIL_URL = "//ofbbutte.com/api/email";
|
||||
export const RANDOM_VERSE_URL = "//www.kingjamesbibleonline.org/popular-bible-verses-widget.php";
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import { Directive,
|
||||
ElementRef,
|
||||
Input,
|
||||
HostListener,
|
||||
HostBinding,
|
||||
OnInit } from '@angular/core';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: '[ofbFadeInOnScroll]',
|
||||
host:{
|
||||
//'[class.animation-fade-in]':'true',
|
||||
'[style.transition]':'"all .5s ease-in-out"'
|
||||
}
|
||||
|
||||
})
|
||||
export class FadeInOnScrollDirective implements OnInit {
|
||||
@HostBinding('style.opacity')
|
||||
opacity: number = 0;
|
||||
|
||||
constructor(private el: ElementRef) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void{
|
||||
this.checkScroll();
|
||||
}
|
||||
|
||||
checkScroll(): void{
|
||||
if (this.opacity === 1) return;
|
||||
let viewPort = this.el.nativeElement.getBoundingClientRect();
|
||||
let winHeight = window.innerHeight;
|
||||
let dif = winHeight - viewPort.top;
|
||||
let maxMargin = 100;
|
||||
if (dif >= 50 && this.opacity != 1){
|
||||
this.opacity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:scroll', ['$event'])
|
||||
onScroll(event){
|
||||
this.checkScroll();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
export const ICONS = {
|
||||
access_time: '',
|
||||
add: '',
|
||||
close: '',
|
||||
copyright: '',
|
||||
delete_forever: '',
|
||||
arrow_drop_down: '',
|
||||
arrow_drop_up: '',
|
||||
directions: '',
|
||||
edit: '',
|
||||
event: '',
|
||||
expand_more: '',
|
||||
file_download: '',
|
||||
headset: '',
|
||||
help_outline: '',
|
||||
info_outline: '',
|
||||
input: '',
|
||||
mail_outline: '',
|
||||
menu: '',
|
||||
pause: '',
|
||||
phone: '',
|
||||
place: '',
|
||||
play_arrow: '',
|
||||
search: '',
|
||||
share: '',
|
||||
slow_motion_video: '',
|
||||
};
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import { Directive,
|
||||
ElementRef,
|
||||
OnInit,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges } from '@angular/core';
|
||||
import { ICONS } from './icon-code-map';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: '[ofbicon]',
|
||||
host:{
|
||||
'[class.material-icon]':'true'
|
||||
}
|
||||
|
||||
})
|
||||
export class IconDirective implements OnInit, OnChanges {
|
||||
@Input()
|
||||
iconName: string;
|
||||
iconCode: string;
|
||||
|
||||
constructor(private el: ElementRef) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void{
|
||||
if (this.el.nativeElement.innerText != ''){
|
||||
this.iconName = this.el.nativeElement.innerText;
|
||||
this.setIcon();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void{
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
setIcon(){
|
||||
let iconCode = ICONS[this.iconName];
|
||||
if (typeof iconCode !== 'undefined'){
|
||||
this.iconCode = iconCode;
|
||||
this.el.nativeElement.innerHTML = this.iconCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export enum AudioStates{
|
||||
Loading,
|
||||
Paused,
|
||||
Playing,
|
||||
Error
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export interface Event{
|
||||
id: number,
|
||||
title: string,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
description: string
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export class Sermon{
|
||||
id: number;
|
||||
title: string;
|
||||
sermonDate: Date;
|
||||
uploadDate: Date;
|
||||
description: string;
|
||||
author: string;
|
||||
url: string;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue