Google Analytics
parent
efd886cd09
commit
4d0d5644dd
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Chrome against localhost",
|
||||||
|
"url": "http://localhost:4200",
|
||||||
|
"webRoot": "${workspaceRoot}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { EventService } from './services/event.service';
|
import { EventService } from './services/event.service';
|
||||||
|
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
||||||
import { WindowRefService } from './services/window-ref.service';
|
import { WindowRefService } from './services/window-ref.service';
|
||||||
import { EmailService } from './services/email.service';
|
import { EmailService } from './services/email.service';
|
||||||
import { SermonService } from './services/sermon.service';
|
import { SermonService } from './services/sermon.service';
|
||||||
|
|
@ -156,7 +157,7 @@ const Routes =
|
||||||
RouterModule.forRoot(Routes)
|
RouterModule.forRoot(Routes)
|
||||||
|
|
||||||
],
|
],
|
||||||
providers: [LoginService,SermonService,EventService,ProgressService,EmailService,WindowRefService,{provide:BrowserXhr,useClass:ProgressXhr}],
|
providers: [LoginService,GoogleAnalyticsService,SermonService,EventService,ProgressService,EmailService,WindowRefService,{provide:BrowserXhr,useClass:ProgressXhr}],
|
||||||
entryComponents: [AddSermonPopupComponent,
|
entryComponents: [AddSermonPopupComponent,
|
||||||
LoginPopupComponent,
|
LoginPopupComponent,
|
||||||
OkPopupComponent,
|
OkPopupComponent,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
import { GoogleAnalyticsService } from './../../services/google-analytics.service';
|
||||||
import { Component, Inject, Injectable, HostListener } from '@angular/core';
|
import { Component, Inject, Injectable, HostListener } from '@angular/core';
|
||||||
import { Router, NavigationStart, Event } from '@angular/router';
|
import { Router, NavigationEnd, Event } from '@angular/router';
|
||||||
import { EventService } from '../../services/event.service';
|
import { EventService } from '../../services/event.service';
|
||||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||||
import { BibleVerseService } from '../../services/bible-verse.service';
|
import { BibleVerseService } from '../../services/bible-verse.service';
|
||||||
|
|
@ -23,16 +24,21 @@ export class AppComponent {
|
||||||
lastScrollPos: number = 0;
|
lastScrollPos: number = 0;
|
||||||
showAudioPlayer: boolean = false;
|
showAudioPlayer: boolean = false;
|
||||||
|
|
||||||
constructor(private router: Router, private audioPlayerService: AudioPlayerService){
|
constructor(private router: Router,
|
||||||
|
private audioPlayerService: AudioPlayerService,
|
||||||
|
private googleAnalyticsService: GoogleAnalyticsService){
|
||||||
this.router.events.subscribe((event:Event) => {
|
this.router.events.subscribe((event:Event) => {
|
||||||
if(event instanceof NavigationStart) {
|
if(event instanceof NavigationEnd) {
|
||||||
this.lastRoute = this.currRoute;
|
this.lastRoute = this.currRoute;
|
||||||
this.currRoute = event.url;
|
this.currRoute = event.urlAfterRedirects;
|
||||||
|
|
||||||
|
|
||||||
let doc = document.documentElement;
|
let doc = document.documentElement;
|
||||||
let scrollPos = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
let scrollPos = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||||||
if (event.url === '/home'){
|
|
||||||
|
let url = event.urlAfterRedirects;
|
||||||
|
|
||||||
|
if (url === '/home'){
|
||||||
this.fadeHeader = true;
|
this.fadeHeader = true;
|
||||||
this.headerOpacity = 0;
|
this.headerOpacity = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -46,6 +52,8 @@ export class AppComponent {
|
||||||
}
|
}
|
||||||
this.lastRoute = event.url;
|
this.lastRoute = event.url;
|
||||||
this.lastScrollPos = scrollPos;
|
this.lastScrollPos = scrollPos;
|
||||||
|
// Google Analytics
|
||||||
|
googleAnalyticsService.pageView(url.substr(1),url);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { GoogleAnalyticsService } from './../../services/google-analytics.service';
|
||||||
import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core';
|
import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core';
|
||||||
import { AudioPlayerService } from '../../services/audio-player.service';
|
import { AudioPlayerService } from '../../services/audio-player.service';
|
||||||
import { AudioStates } from '../../enum/audio-states';
|
import { AudioStates } from '../../enum/audio-states';
|
||||||
|
|
@ -29,7 +30,8 @@ export class AudioPlayerComponent implements OnInit, OnDestroy {
|
||||||
@Output()
|
@Output()
|
||||||
started: EventEmitter<string> = new EventEmitter();
|
started: EventEmitter<string> = new EventEmitter();
|
||||||
|
|
||||||
constructor(private audioPlayerService: AudioPlayerService){
|
constructor(private audioPlayerService: AudioPlayerService,
|
||||||
|
private googleAnalyticsService: GoogleAnalyticsService){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,20 +43,44 @@ export class AudioPlayerComponent implements OnInit, OnDestroy {
|
||||||
this.audioDuration = this.audioPlayerService.getDuration();
|
this.audioDuration = this.audioPlayerService.getDuration();
|
||||||
this.currentTime = this.audioPlayerService.getCurrentTime();
|
this.currentTime = this.audioPlayerService.getCurrentTime();
|
||||||
if (this.audioState == AudioStates.Loading){
|
if (this.audioState == AudioStates.Loading){
|
||||||
this.started.emit("loading");
|
this.started.emit("loading");
|
||||||
}
|
}
|
||||||
if (this.audioState == AudioStates.Playing){
|
if (this.audioState == AudioStates.Playing){
|
||||||
this.started.emit("playing");
|
this.started.emit("playing");
|
||||||
this.interval = setInterval(()=>{
|
this.interval = setInterval(()=>{
|
||||||
this.audioDuration = this.audioPlayerService.getDuration();
|
this.audioDuration = this.audioPlayerService.getDuration();
|
||||||
this.currentTime = this.audioPlayerService.getCurrentTime();
|
this.currentTime = this.audioPlayerService.getCurrentTime();
|
||||||
},1000);
|
},1000);
|
||||||
} else {
|
} else {
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
}
|
}
|
||||||
|
this.sendGoogleAnalytics(state,error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendGoogleAnalytics(state: AudioStates, error: any){
|
||||||
|
switch (state) {
|
||||||
|
case AudioStates.Error:
|
||||||
|
this.googleAnalyticsService.audioError(this.audioFileId, this.audioFileTitle, error)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AudioStates.Loading:
|
||||||
|
this.googleAnalyticsService.loadingSermon(this.audioFileId,this.audioFileTitle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AudioStates.Paused:
|
||||||
|
this.googleAnalyticsService.pauseSermon(this.audioFileId,this.audioFileTitle,this.audioPlayerService.getCurrentTime())
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AudioStates.Playing:
|
||||||
|
this.googleAnalyticsService.playSermon(this.audioFileId,this.audioFileTitle,this.audioPlayerService.getCurrentTime())
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
play(): void{
|
play(): void{
|
||||||
this.audioPlayerService.resume();
|
this.audioPlayerService.resume();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { GoogleAnalyticsService } from './../../services/google-analytics.service';
|
||||||
import { MdDialog, MdDialogConfig, MdSnackBar } from '@angular/material';
|
import { MdDialog, MdDialogConfig, MdSnackBar } from '@angular/material';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { EventService } from './../../services/event.service';
|
import { EventService } from './../../services/event.service';
|
||||||
|
|
@ -28,7 +29,8 @@ export class EventsPageComponent implements OnInit {
|
||||||
private dialog: MdDialog,
|
private dialog: MdDialog,
|
||||||
private snackbar: MdSnackBar,
|
private snackbar: MdSnackBar,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private audioPlayerService: AudioPlayerService) {
|
private audioPlayerService: AudioPlayerService,
|
||||||
|
private googleAnalyticsService: GoogleAnalyticsService) {
|
||||||
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is; });
|
this.loginService.isLoggedIn(true).subscribe(is => { this.loggedIn = is; });
|
||||||
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
this.loginService.onLogin().subscribe(is => { this.loggedIn = is.isLoggedIn; });
|
||||||
this.audioPlayerService.onAudioPlayerOpenClose.subscribe(is => this.audioPlayerOpen = is);
|
this.audioPlayerService.onAudioPlayerOpenClose.subscribe(is => this.audioPlayerOpen = is);
|
||||||
|
|
@ -41,7 +43,7 @@ export class EventsPageComponent implements OnInit {
|
||||||
id = Number.isNaN(id) ? -1 : id;
|
id = Number.isNaN(id) ? -1 : id;
|
||||||
if (id > -1){
|
if (id > -1){
|
||||||
this.getSingleEvent(id);
|
this.getSingleEvent(id);
|
||||||
this.showAllButtonVisible = true;
|
this.showAllButtonVisible = true;
|
||||||
} else {
|
} else {
|
||||||
this.getEvents(true);
|
this.getEvents(true);
|
||||||
this.showAllButtonVisible = false;
|
this.showAllButtonVisible = false;
|
||||||
|
|
@ -71,6 +73,7 @@ export class EventsPageComponent implements OnInit {
|
||||||
this.eventService.getSingleEvent(id).subscribe(event => {
|
this.eventService.getSingleEvent(id).subscribe(event => {
|
||||||
this.events.push(event);
|
this.events.push(event);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.googleAnalyticsService.shareEventConversion(event.id,event.title);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div md-dialog-title>Share</div>
|
<div md-dialog-title>Share</div>
|
||||||
<div md-dialog-content>
|
<div md-dialog-content>
|
||||||
<a [href]="facebookIframeUrl | safeUrl" target="_blank">
|
<a (click)="facebookShare()" [href]="facebookIframeUrl | safeUrl" target="_blank">
|
||||||
<div class="social-wrapper facebook" data-network="facebook" draggable="false" style="display: inline-block;">
|
<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">
|
<svg fill="#fff" preserveAspectRatio="xMidYMid meet" height="1.2em" width="1.2em" viewBox="0 0 40 40">
|
||||||
<g>
|
<g>
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
<span class="st-label">Share</span>
|
<span class="st-label">Share</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a [href]="twitterUrl | safeUrl" target="_blank">
|
<a (click)="twitterShare()" [href]="twitterUrl | safeUrl" target="_blank">
|
||||||
<div class="social-wrapper twitter" data-network="facebook" draggable="false" style="display: inline-block;">
|
<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">
|
<svg fill="#fff" preserveAspectRatio="xMidYMid meet" height="1.2em" width="1.2em" viewBox="0 0 40 40">
|
||||||
<g>
|
<g>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { GoogleAnalyticsService } from './../../../services/google-analytics.service';
|
||||||
import { MdDialogRef, MdSnackBar } from '@angular/material';
|
import { MdDialogRef, MdSnackBar } from '@angular/material';
|
||||||
import { DOCUMENT } from '@angular/platform-browser';
|
import { DOCUMENT } from '@angular/platform-browser';
|
||||||
import { MD_DIALOG_DATA } from '@angular/material';
|
import { MD_DIALOG_DATA } from '@angular/material';
|
||||||
|
|
@ -24,7 +25,8 @@ export class SharePopupComponent implements OnInit {
|
||||||
constructor(@Inject(MD_DIALOG_DATA) public data: any,
|
constructor(@Inject(MD_DIALOG_DATA) public data: any,
|
||||||
@Inject(DOCUMENT) private document,
|
@Inject(DOCUMENT) private document,
|
||||||
private mdDialogRef: MdDialogRef<SharePopupComponent>,
|
private mdDialogRef: MdDialogRef<SharePopupComponent>,
|
||||||
private snackbar: MdSnackBar) {
|
private snackbar: MdSnackBar,
|
||||||
|
private googleAnalyticsService: GoogleAnalyticsService) {
|
||||||
this.id = data.id;
|
this.id = data.id;
|
||||||
let port = this.document.location.port ? ":"+this.document.location.port : "";
|
let port = this.document.location.port ? ":"+this.document.location.port : "";
|
||||||
this.shareUrl = this.document.location.protocol +'//'+ this.document.location.hostname + port + this.shareBaseUrl + data.prefix + this.id;
|
this.shareUrl = this.document.location.protocol +'//'+ this.document.location.hostname + port + this.shareBaseUrl + data.prefix + this.id;
|
||||||
|
|
@ -48,8 +50,25 @@ export class SharePopupComponent implements OnInit {
|
||||||
let s = this.snackbar.open("Link Copied","OK");
|
let s = this.snackbar.open("Link Copied","OK");
|
||||||
s.onAction().subscribe(()=>{ s.dismiss(); });
|
s.onAction().subscribe(()=>{ s.dismiss(); });
|
||||||
s.afterOpened().subscribe(()=>{ setTimeout(()=>{ s.dismiss(); },3000); });
|
s.afterOpened().subscribe(()=>{ setTimeout(()=>{ s.dismiss(); },3000); });
|
||||||
|
this.share("link");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Oops, unable to copy');
|
console.error('Oops, unable to copy');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
share(method: string){
|
||||||
|
if (this.data.prefix === 's'){
|
||||||
|
this.googleAnalyticsService.shareSermon(Number(this.id),this.data.title,method);
|
||||||
|
} else if (this.data.prefix === 'e'){
|
||||||
|
this.googleAnalyticsService.shareEvent(Number(this.id),this.data.title,method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
facebookShare(){
|
||||||
|
this.share('facebook');
|
||||||
|
}
|
||||||
|
|
||||||
|
twitterShare(){
|
||||||
|
this.share('twitter');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GoogleAnalyticsService } from './google-analytics.service';
|
||||||
|
|
||||||
|
describe('GoogleAnalyticsService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [GoogleAnalyticsService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([GoogleAnalyticsService], (service: GoogleAnalyticsService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
declare var gtag;
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GoogleAnalyticsService {
|
||||||
|
|
||||||
|
private trackingId: string = 'UA-107601801-1';
|
||||||
|
private baseUrl: string = 'https://ofbbutte.com';
|
||||||
|
private lastSermonId: number = 0;
|
||||||
|
private lastSermonStartPos: number = 0;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
public pageView(title: string, path: string){
|
||||||
|
gtag('config', this.trackingId, {
|
||||||
|
'page_title': title,
|
||||||
|
'page_location': this.baseUrl + path,
|
||||||
|
'page_path': path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public searchSermon(searchTerm: string){
|
||||||
|
gtag('event', 'search', {
|
||||||
|
'search_term': searchTerm
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public shareSermon(id: number, title: string, method: string){
|
||||||
|
gtag('event', 'share', {
|
||||||
|
'method': method,
|
||||||
|
'content_type': 'audio',
|
||||||
|
'content_id': id,
|
||||||
|
'content_title': title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public shareEvent(id: number, title: string, method: string){
|
||||||
|
gtag('event', 'share', {
|
||||||
|
'method': method,
|
||||||
|
'content_type': 'event',
|
||||||
|
'content_id': id,
|
||||||
|
'content_title': title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public shareSermonConversion(id: number, title: string){
|
||||||
|
gtag('event', 'share_conversion', {
|
||||||
|
'content_type': 'audio',
|
||||||
|
'content_id': id,
|
||||||
|
'content_title': title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public shareEventConversion(id: number, title: string){
|
||||||
|
gtag('event', 'share_conversion', {
|
||||||
|
'content_type': 'event',
|
||||||
|
'content_id': id,
|
||||||
|
'content_title': title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadingSermon(id: number, title: string){
|
||||||
|
gtag('event', 'audio_loading', {
|
||||||
|
'audio_id': id,
|
||||||
|
'audio_title': title
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public playSermon(id: number, title: string, position: number){
|
||||||
|
this.lastSermonId = id;
|
||||||
|
this.lastSermonStartPos = position;
|
||||||
|
gtag('event', 'audio_play', {
|
||||||
|
'audio_id': id,
|
||||||
|
'audio_title': title,
|
||||||
|
'audio_start_position': position
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public pauseSermon(id: number, title: string, position: number){
|
||||||
|
let duration = null;
|
||||||
|
let lastStartPos = null;
|
||||||
|
if (id == this.lastSermonId){
|
||||||
|
duration = position - this.lastSermonStartPos;
|
||||||
|
lastStartPos = this.lastSermonStartPos;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
gtag('event', 'audio_pause', {
|
||||||
|
'audio_id': id,
|
||||||
|
'audio_title': title,
|
||||||
|
'audio_start_position': lastStartPos,
|
||||||
|
'audio_pause_position': position,
|
||||||
|
'audio_listen_duration': duration
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public audioError(id: number, title: string, error: string){
|
||||||
|
gtag('event', 'audio_error', {
|
||||||
|
'audio_id': id,
|
||||||
|
'audio_title': title,
|
||||||
|
'audio_error_message': error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,18 @@
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Old Fashion Baptist Church</title>
|
<title>Old Fashion Baptist Church</title>
|
||||||
|
|
||||||
|
<!-- Google Analytics -->
|
||||||
|
<!-- Global Site Tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-107601801-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-107601801-1', { 'send_page_view': false });
|
||||||
|
</script>
|
||||||
|
<!---->
|
||||||
|
|
||||||
<!-- Favicons -->
|
<!-- Favicons -->
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/web-app-files/apple-touch-icon.png?v=LbWKNzlwGb">
|
<link rel="apple-touch-icon" sizes="180x180" href="/web-app-files/apple-touch-icon.png?v=LbWKNzlwGb">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
BUILD_ANGULAR_ARG=$1
|
BUILD_ANGULAR_ARG=$1
|
||||||
BUILD_ANGULAR=false
|
BUILD_ANGULAR=true
|
||||||
if [ "$BUILD_ANGULAR_ARG" = -ng ]; then
|
if [ "$BUILD_ANGULAR_ARG" = -ng ]; then
|
||||||
BUILD_ANGULAR=true
|
BUILD_ANGULAR=true
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue