Giter Site home page Giter Site logo

orizens / echoes-player Goto Github PK

View Code? Open in Web Editor NEW
848.0 49.0 352.0 22.97 MB

Echoes Player: the missing Media Player experience for Youtube - Built with Angular (9), ngrx (9), Angular CLI, Boostrap (SASS), Youtube api

Home Page: https://echoesplayer.netlify.app

License: MIT License

Shell 0.07% JavaScript 1.94% TypeScript 70.09% HTML 4.35% CSS 13.09% SCSS 10.46% Procfile 0.01%
angular ngrx bootstrap sass angular-cli typescript angular-example-app angular-example redux ngrx-example

echoes-player's People

Contributors

orizens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

echoes-player's Issues

Issue while Demo test application

Hi,

There seems to be an issue with the demo code and Augury Dev Tools Extension
Is this an issue with the app...or with the chrome extention?

See below...


Demo

Thanks!

#UX: letter spacing and URL color might need an update

I like the overall UI / card look, but I have two suggestions.

  1. Rehaul either the chosen font-family, or if you want to stick with it, increase the letter-spacing since basically everything feels crammed together.

  2. The link url color is too light, and make readability a little difficult (and more so combined with the compressed letters)


Perhaps this may not be the same for all users since there are fallback fonts, but here is how it looks on my computer (Chromium on Linux)

Screenshot from 2019-10-31 08-58-22

Use of reselect library

I just bought your book Reactive Programming with Angular and ngrx. Thanks for putting together such a good book.

The official ngrx example uses a library called reselect. I don't fully understand the reason behind using that library, but I think it is to prevent a trip to the server to retrieve the data if the data is already available in the redux store.

Will the reselect library be useful in the echoes-player to improve performance?

repeat in filtered now playlist

Expected Behavior

Given now playlist is filtered
And the first track in the filtered list is not the first track in the non-filtered list
And the repeat button is "on" 
When the last track has ended
Then the first track in the filtered playlist should play 

Actual Behavior

the first track in the NON-filtered behavior is played

ngrx routing vs angular routing

Hi, why you have deleted the routing from ngrx? I'm curious, because I start new project and I don't know what to choose.

node-sass version needed 4.14.0

npm installed just a minute ago, had error

ERROR in Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js):
SassError: expected selector.

72 │ /deep/ .btn.active{
│ ^

\njs\echoes-player\src\app\containers\app-navbar\app-navbar-menu\app-navbar-menu.component.scss 72:3 root stylesheet

node-sass version update to 4.14.0 solved it

Missing Chapter Branches as per the book

Hello, I just bought your book "Reactive Programming with Angular and ngrx"

It is an awesome book!, however the code for chapters is missing as I can't find the branches as you described in your book in page 14

These are the available branches for each chapter:
1.	Chapter 2 – git checkout chapter-02
2.	Chapter 3 – git checkout chapter-03
3.	Chapter 4 – git checkout chapter-04
4.	Chapter 5 – git checkout chapter-05
5.	Chapter 6 – git checkout chapter-06
6.	Chapter 7 – git checkout chapter-07

Firebase Integration

Add firebase integration:

  • use firebase Auth
  • use firebase firestore for state
  • Echoes Chat Rooms

Error retrieving media results

I often have these errors when searching/loading media results:

Http failure response for https://www.googleapis.com/youtube/v3/search?part=snippet,id&maxResults=20&key=AIzaSyB9cgwdwPyk6RcTNr86pZ1t-NqxL-EzNe4&q=house%20mix%202021&type=video&videoType=any&videoDuration=any&videoDefinition=any: 403 Forbidden The request cannot be completed because you have exceeded your <a href="/youtube/v3/getting-started#quota">quota</a>.

Show a Playlist on load

Hi,

I must say I really like this project and its complexity. I am a bit new to angular2 and this concept of Store is also something that seems cool, but I've been trying to understand it for a few days now, and it's getting frustrating, cuz I can't make it work, although my goal seems really simple:

I would like to replace the default search page to display a list of a specific playlist. If anyone could point me in the direction of what I should be doing, at least in theory, I would be really really grateful.

Thanks in advance!

Issue On WebApp: Maximising the video, Click on it to pause/resume, Escape button does not minimise it again.

When I click on the video icon on bottom-left corner to maximise the video on web app, it maximises and on clicking 'ESC' button, it gets minimised again and take me back to the app. But on clicking the video for pausing/resuming it, when video is in maximised state on app, 'ESC' button does not work to minimise it. It gets stuck here, and i could not move back and forth inside the app. In that scenario, I switched to previous page. Is it an existing issue or any feature, I am unaware of?

ERROR TypeError: Cannot read property 'getVideoUrl' of undefined

Hello,
I bought your book on Amazon. I am a beginner in javascript developer and I tried hosting the echoes-player code base as a firebase app. It works very well locally but after hosting it throws an error above whenever I click on any video.
ERROR TypeError: Cannot read property 'getVideoUrl' of undefined
Any ideas on what I am doing wrong? I haven't edited the code apart from changing my client id and api key for the google project.

On a separate note, are the chapter wise examples hosted anywhere? I couldn't download them from the link in the book. It directs me to echoes player repository.

Cannot read property 'query of undefined

<div class="form-group search"> <span class="fa fa-search"> <input id="employee-search" typeahead (typeaheadSelected)="handleSelectSuggestion($event)" type="search" class="form-control" autocomplete="off" [value]="query.query" #employeeSearch name="employeeSearch" (input)="onQueryChange(employeeSearch.value)"> </span> </div>

In my component where I want to use the typeahead:
`@Component({
selector: 'app-create-call',
templateUrl: './create-call.component.html',
styleUrls: ['./create-call.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CreateCallComponent implements OnInit {

// proof of concept...

@Input() query;
@Output() change = new EventEmitter();
@Output() search = new EventEmitter();
@Output() typing = new EventEmitter<string>();

@ViewChild('employeeSearch') employeeSearch;

// end proof of concept
....

the typeahead 'directive' (really a component) itself:

@Component({ selector: '[typeahead]', template: <ng-template #suggestionsTplRef>
<section class="list-group results" *ngIf="showSuggestions">
<div class="typeahead-backdrop" (click)="hideSuggestions()">
<button type="button" class="list-group-item"
*ngFor="let result of results; let i = index;"
[class.active]="markIsActive(i, result)"
(click)="handleSelectSuggestion(result)">
<span *ngIf="!typeaheadItemTpl"> {{ result }}
<template [ngTemplateOutlet]="typeaheadItemTpl" [ngTemplateOutletContext]="{ $implicit: {result: result, index: i} }">


`,
styleUrls:['typeahead.directive.css']
})
export class TypeAheadComponent implements OnInit, OnDestroy {

@Output() typeaheadSelected = new EventEmitter<string>();
@Input() typeaheadItemTpl: TemplateRef<any>; // allow custom template for suggestion

private showSuggestions: boolean = false;
private results: string[];
private suggestionIndex: number = 0;
private subscriptions: Subscription[];
private activeResult: string;

@ViewChild('suggestionsTplRef') suggestionsTplRef;

@HostListener('keydown', ['$event'])
handleEsc(event: KeyboardEvent) {

    if (event.keyCode === Key.Escape) {
        this.hideSuggestions();
        event.preventDefault();
    }
}

/** 1. element - to listen for input events
 *  2. viewContainer - in order to render the template as a sibling
 *  3. jsonp - start requests as a jsonp to the search API
 *  4. cdr - change detection reference to apply changes within this component and its siblings
 */
constructor(private element: ElementRef, private viewContainer: ViewContainerRef, private jsonp: Jsonp, private cdr: ChangeDetectorRef) {}

ngOnInit() {
    this.subscriptions = [
        this.filterEnterEvent(),
        this.listenAndSuggest(),
        this.navigateWithArrows()
    ];
    this.renderTemplate();
}

ngOnDestroy() {
    this.subscriptions.forEach(sub => sub.unsubscribe());
    this.subscriptions.length = 0;
}

/** Uses the “viewContainer” in order to render the template as a sibling to the actual element.
 * “createEmbeddedView” function takes a template reference and inserts it, compiled with the data, 
 *  into the last view position in the html container. The actual “viewContainer” is the element that wraps the input element (in this case). 
 *  A second argument determines  the index at which this template should be rendered. */
renderTemplate() {
    this.viewContainer.createEmbeddedView(this.suggestionsTplRef);
    this.cdr.markForCheck();
}

/** support selection of a result with the enter key, this code listens to keydown strokes on the input element,
 * allows only Enter key to pass on to the stream and then invokes the “handleSelectSuggestion” which eventually – emits
 * an event for the selected result. */
filterEnterEvent() {
    return Observable.fromEvent(this.element.nativeElement, 'keydown')
        .filter((e: KeyboardEvent) => e.keyCode === Key.Enter)
        .subscribe((event: Event) => {
            event.preventDefault();
            this.handleSelectSuggestion(this.activeResult);
        });
}

/** Makes a jsonp call to get the list of suggestions according to the value of the input
 *  listens to keyup strokes (since we do want to allow a character to apply into the input),
 *  filtering out any non characters keys with “validateKeyCode()“. I use “distinctUntilChanged()”
 *  to filter the stream for the same value – which again prevents unnecessary requests.
 * Then, the filter for an empty string becomes relevant before the code makes the actual request */
listenAndSuggest() {
    return Observable.fromEvent(this.element.nativeElement, 'keyup')
        .filter(this.validateKeyCode)
        .map((e: any) => e.target.value)
        .debounceTime(400)
        .concat()
        .distinctUntilChanged()
        .filter((query: string) => query.length > 0)
        .switchMap((query: string) => this.suggest(query))  // this.engageService.GetEmployee(term)
        .subscribe((results: string[]) => {
            this.results = results;
            this.showSuggestions = true;
            this.cdr.markForCheck();
        });
}

navigateWithArrows() {
    return Observable.fromEvent(this.element.nativeElement, 'keydown')
        .filter((e: any) => e.keyCode === Key.ArrowDown || e.keyCode === Key.ArrowUp)
        .map((e: any) => e.keyCode)
        .subscribe((keyCode: number) => {
            let step = keyCode === Key.ArrowDown ? 1 : -1;
            const topLimit = 9;
            const bottomLimit = 0;
            this.suggestionIndex += step;
            if (this.suggestionIndex === topLimit + 1) {
                this.suggestionIndex = bottomLimit;
            }
            if (this.suggestionIndex === bottomLimit - 1) {
                this.suggestionIndex = topLimit;
            }
            this.showSuggestions = true;
            // this.renderTemplate();
            this.cdr.markForCheck();
        });
}


suggest(query: string) {

    const url = 'http://suggestqueries.google.com/complete/search';
    const searchConfig: URLSearchParams = new URLSearchParams();

    const searchParams = {
        hl: 'en',
        ds: 'yt',
        xhr: 't',
        client: 'youtube',
        q: query,
        callback: 'JSONP_CALLBACK'
    };

    Object.keys(searchParams).forEach(param => searchConfig.set(param, searchParams[param]));
    const options: RequestOptionsArgs = {
        search: searchConfig
    };
    return this.jsonp.get(url, options)
        .map(response => response.json()[1])
        .map(results => results.map(result => result[0]));
}

markIsActive(index: number, result: string) {
    const isActive = index === this.suggestionIndex;
    if (isActive) {
        this.activeResult = result;
    }
}

handleSelectSuggestion(suggestion: string) {
    this.hideSuggestions();
    this.typeaheadSelected.emit(suggestion);
}

validateKeyCode(event: KeyboardEvent) {
    return event.keyCode !== Key.Tab
        && event.keyCode !== Key.Shift
        && event.keyCode !== Key.ArrowLeft
        && event.keyCode !== Key.ArrowUp
        && event.keyCode !== Key.ArrowRight
        && event.keyCode !== Key.ArrowDown;
}

hideSuggestions() {
    this.showSuggestions = false;
}

hasItemTemplate() {
    return this.typeaheadItemTpl !== undefined;
}

}`

Sync book edition and repo

The book Reactive Programming with Angular and ngrx is awesome. Yet the way code snipptes are represented affects its value. It would be excellent to have a new edition to meet the updates in this repo and also to enhance the way code is introduced. Theoretically, it clarifies the concepts well. Practically, the reader is lost since the book reference code snippets and paths that does not exist anymore (or it seems to be).

Error during running the http-server

When i tried to run ng serve, it will work properly without any issue, when i used http-server for running the application i am getting below error:

Please help me.

GET http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js 0 ()
now-playlist.component.ts.NowPlaylistComponent.html:10 ERROR TypeError: Cannot read property 'match' of undefined
at MediaParserService.webpackJsonp../src/app/core/services/media-parser.service.ts.MediaParserService.extractTracks (media-parser.service.ts:15)
at NowPlaylistTrackComponent.webpackJsonp../src/app/core/components/now-playing/now-playlist/now-playlist-track.component.ts.NowPlaylistTrackComponent.extractTracks (now-playlist-track.component.ts:91)
at NowPlaylistTrackComponent.webpackJsonp../src/app/core/components/now-playing/now-playlist/now-playlist-track.component.ts.NowPlaylistTrackComponent.ngAfterContentInit (now-playlist-track.component.ts:86)
at callProviderLifecycles (core.js:12508)
at callElementProvidersLifecycles (core.js:12482)
at callLifecycleHooksChildrenFirst (core.js:12465)
at checkAndUpdateView (core.js:13610)
at callViewAction (core.js:13960)
at execEmbeddedViewsAction (core.js:13918)
at checkAndUpdateView (core.js:13607)
View_NowPlaylistComponent_1 @ now-playlist.component.ts.NowPlaylistComponent.html:10
webpackJsonp../node_modules/@angular/core/esm5/core.js.DebugContext_.logError @ core.js:14797
webpackJsonp../node_modules/@angular/core/esm5/core.js.ErrorHandler.handleError @ core.js:1497
(anonymous) @ core.js:5849
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:388
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:138
webpackJsonp../node_modules/@angular/core/esm5/core.js.NgZone.runOutsideAngular @ core.js:4647
webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationRef.tick @ core.js:5849
webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationRef._loadComponent @ core.js:5908
webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationRef.bootstrap @ core.js:5796
(anonymous) @ core.js:5525
webpackJsonp../node_modules/@angular/core/esm5/core.js.PlatformRef._moduleDoBootstrap @ core.js:5525
(anonymous) @ core.js:5444
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:388
onInvoke @ core.js:4699
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:387
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:138
(anonymous) @ zone.js:872
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:421
onInvokeTask @ core.js:4690
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:420
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:188
drainMicroTaskQueue @ zone.js:595
Promise.then (async)
scheduleMicroTask @ zone.js:578
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:410
onScheduleTask @ zone.js:297
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:401
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:232
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:252
scheduleResolveOrReject @ zone.js:862
ZoneAwarePromise.then @ zone.js:962
webpackJsonp../node_modules/@angular/router/esm5/router.js.RouterInitializer.appInitializer @ router.js:7166
webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationInitStatus.runInitializers @ core.js:3549
(anonymous) @ core.js:5442
_callAndReportToErrorHandler @ core.js:5614
(anonymous) @ core.js:5440
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:388
onInvoke @ core.js:4699
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:387
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:138
webpackJsonp../node_modules/@angular/core/esm5/core.js.NgZone.run @ core.js:4516
webpackJsonp../node_modules/@angular/core/esm5/core.js.PlatformRef.bootstrapModuleFactory @ core.js:5431
./src/main.ts @ main.ts:11
webpack_require @ bootstrap 456367255ed6233fe7b3:54
0 @ main.ts:11
webpack_require @ bootstrap 456367255ed6233fe7b3:54
webpackJsonpCallback @ bootstrap 456367255ed6233fe7b3:25
(anonymous) @ main.bundle.js:1
now-playlist.component.ts.NowPlaylistComponent.html:10 ERROR CONTEXT

Page not refreshed after clicking logout

Nothing happens after clicking logout button now matter how long i wait. It turns out that I have to click anywhere on the website again to let the page refresh.

Tested on the latest Safari.

Different code for the same logic?

in playlists.component.ts, playSelectedPlaylist calls this.userPlayerService.playSelectedPlaylist(playlist);
but
in youtube-playlists.component.ts, playPlaylist calls this.appPlayerApi.playPlaylist(media);

I have found any difference between playing youtube search playlist and playing user playlist. From my understanding, they both do something like queue videos to the now play list and select first video to play and maybe more. So, Is there anything i am missing?

App dosen't start.

Uncaught SyntaxError: Unexpected token V in JSON at position 0
    at Object.parse (<anonymous>)
    at index.js:48
    at Array.reduce (<anonymous>)
    at Object.exports.rehydrateApplicationState (index.js:25)
    at index.js:107
    at compose.js:13
    at Array.reduceRight (<anonymous>)
    at compose.js:13
    at Object.<anonymous> (index.ts:24)
    at __webpack_require__ (bootstrap 0b10127…:52)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.