Skip to content

Commit

Permalink
Merge pull request #19 from Sn8z/dev
Browse files Browse the repository at this point in the history
1.0.8
  • Loading branch information
Sn8z committed Sep 27, 2018
2 parents 3071a01 + bae3db2 commit 2554bbf
Show file tree
Hide file tree
Showing 8,394 changed files with 2,776 additions and 1,088,171 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@

/dist
/node_modules
yarn-error.log
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<div align="center">
<img src="images/poddr_logo.png" alt="Poddr" width="60" height="60">
<h1>Poddr</h1>
<img src="https://img.shields.io/github/release/sn8z/poddr.svg">
<img src="https://img.shields.io/github/downloads/sn8z/poddr/total.svg">
<img src="https://img.shields.io/github/release-date/sn8z/poddr.svg">
<a href="https://david-dm.org/sn8z/poddr" title="dependencies status"><img src="https://david-dm.org/sn8z/poddr/status.svg"/></a>
<img src="https://img.shields.io/github/release/sn8z/poddr.svg?style=flat-square">
<img src="https://img.shields.io/github/downloads/sn8z/poddr/total.svg?style=flat-square">
<img src="https://img.shields.io/github/release-date/sn8z/poddr.svg?style=flat-square">
<img src="https://img.shields.io/david/sn8z/poddr.svg?style=flat-square">
<img src="https://img.shields.io/badge/platforms-Windows%20%2F%20Linux%20%2F%20Mac-brightgreen.svg?style=flat-square">
</div>




Podcast client built with Electron and AngularJS.

It uses iTunes RSS feeds and search API to gather its information.
Poddr uses iTunes RSS feeds and Search API to gather information.
### Screenshots

![Screenshot](images/poddr.png)
Expand Down Expand Up @@ -37,7 +41,7 @@ Quotes from [AppImage projectpage](https://appimage.org)
> The key idea of the AppImage format is one app = one file. Every AppImage contains an app and all the files the app needs to run. In other words, each AppImage has no dependencies other than what is included in the targeted base operating system(s).
Just [download](https://github.com/Sn8z/Poddr/releases) and make the file [executable](https://discourse.appimage.org/t/how-to-make-an-appimage-executable/80)
[Download](https://github.com/Sn8z/Poddr/releases) and make the file [executable](https://discourse.appimage.org/t/how-to-make-an-appimage-executable/80)

#### Mac

Expand Down
80 changes: 44 additions & 36 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<link rel="stylesheet" type="text/css" href="../node_modules/angular-material/angular-material.css">
<link rel="stylesheet" type="text/css" href="styles/style.css">
<link rel="stylesheet" type="text/css" href="styles/scrollbar.css">
<link rel="stylesheet" type="text/css" href="styles/tooltip.css">

<script type="text/javascript" src="../node_modules/angular/angular.min.js"></script>
<script type="text/javascript" src="../node_modules/angular-aria/angular-aria.min.js"></script>
Expand Down Expand Up @@ -42,74 +43,73 @@
<md-sidenav id="left-sidenav" flex="15" md-is-locked-open="true" md-component-id="left">
<md-list class="md-dense" flex md-no-ink>
<md-list-item class="menu-item" id="toplist-item" ng-click="changeView('podcasts')">
<md-item-content layout="row" layout-align="center center">
<md-item-content class="menu-item-content" layout="row" layout-align="center center">
<md-icon class="menu-icon" md-font-library="material-icons">whatshot</md-icon>
<div class="inset">
<div class="inset menu-text">
Toplists
</div>
</md-item-content>
</md-list-item>

<md-divider></md-divider>
<md-divider class="menu-divider"></md-divider>

<md-list-item class="menu-item" id="search-item" ng-click="changeView('search')">
<md-item-content md-ink-ripple layout="row" layout-align="center center">
<md-item-content class="menu-item-content" md-ink-ripple layout="row" layout-align="center center">
<md-icon class="menu-icon" md-font-library="material-icons">search</md-icon>
<div class="inset">
<div class="inset menu-text">
Search
</div>
</md-item-content>
</md-list-item>

<md-divider></md-divider>
<md-divider class="menu-divider"></md-divider>

<md-list-item class="menu-item" id="favourite-item" ng-click="changeView('favourites')">
<md-item-content md-ink-ripple layout="row" layout-align="center center">
<md-item-content class="menu-item-content" md-ink-ripple layout="row" layout-align="center center">
<md-icon class="menu-icon" md-font-library="material-icons">favorite_border</md-icon>
<div class="inset">
<div class="inset menu-text">
Favourites
</div>
</md-item-content>
</md-list-item>

<md-divider></md-divider>
<md-divider class="menu-divider"></md-divider>

<md-list-item class="menu-item" id="about-item" ng-click="changeView('settings')">
<md-item-content md-ink-ripple layout="row" layout-align="center center">
<md-list-item class="menu-item" id="settings-item" ng-click="changeView('settings')">
<md-item-content class="menu-item-content" md-ink-ripple layout="row" layout-align="center center">
<md-icon class="menu-icon" md-font-library="material-icons">settings</md-icon>
<div class="inset">
About
<div class="inset menu-text">
Settings
</div>
</md-item-content>
</md-list-item>
</md-list>
<div style="position:absolute;bottom:0;width:100%;height:auto;">
<img ng-src='{{ playerService.episodeCover || "images/album_cover.png" }}' style="width:100%;height:auto;position:absolute;bottom:0;"
/>
<img ng-src='{{ playerService.episodeCover || "images/album_cover.png" }}' style="width:100%;height:auto;position:absolute;bottom:0;" />
</div>

</md-sidenav>
<div layout="column" flex>
<!-- Content -->

<!-- Content -->
<div ng-switch="mainContent" class="box2">
<div ng-switch-when="podcasts" style="width:100%">
<podcasts/>
<podcasts />
</div>
<div ng-switch-when="favourites" style="width:100%">
<favourites/>
<favourites />
</div>
<div ng-switch-when="search" style="width:100%">
<search/>
<search />
</div>
<div ng-switch-when="settings" style="width:100%">
<settings/>
<settings />
</div>
</div>

<md-sidenav class="md-sidenav-right" id="right-sidenav" md-whiteframe="8" md-component-id="right">
<md-content style="background-color:transparent;">
<episodes/>
<episodes />
</md-content>
</md-sidenav>

Expand All @@ -121,26 +121,34 @@
</div>
</div>
<div class="row" layout="row" style="height:100%">
<div flex="10" layout="row" layout-align="center center">
<div flex="5" layout="row" layout-align="center center">
<md-icon class="media-btn" md-font-library="material-icons" ng-click="rewind(10)">replay_10</md-icon>
</div>
<div layout="row" layout-align="center center">
<md-icon id="play-btn" md-font-library="material-icons" ng-click="togglePlay()">{{ checkPlayBtn() }}</md-icon>
</div>
<div flex layout="column" layout-align="center start" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow: 0px 0px 10px #000">
<b ng-bind="playerService.currentlyPlaying"></b>
<span class="timer-text">{{ playerService.atTime | secondsToHHmmss }} / {{ playerService.podcastDuration | secondsToHHmmss }}</span>
<div flex="5" layout="row" layout-align="center center">
<md-icon class="media-btn" md-font-library="material-icons" ng-click="forward(10)">forward_10</md-icon>
</div>
<div flex="10" layout="row" layout-align="center center">
<md-progress-circular md-mode="indeterminate" md-diameter="30" ng-show="isLoading"></md-progress-circular>
<div flex layout="column" layout-align="center start" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow: 0px 0px 10px #000">
<a href ng-click="showEpisodes(playerService.podcastID, playerService.podcastArtist, playerService.podcastcover)"
style="color: white;text-decoration: none;">
{{ playerService.currentlyPlaying }}
</a>
<span class="timer-text">{{ playerService.atTime | secondsToHHmmss }} / {{ playerService.podcastDuration |
secondsToHHmmss
}}
</span>
</div>
<div flex="5" layout="row" layout-align="center center">
<md-icon id="fav-btn" ng-hide="isPlayerFavourite()" ng-click="setFavourite()" md-font-library="material-icons">favorite_border</md-icon>
<md-progress-circular ng-if="isLoading" md-mode="indeterminate" md-diameter="25"></md-progress-circular>
</div>
<div flex="5" layout="row" layout-align="center center" ng-if="!isPlayerFavourite()">
<md-icon id="fav-btn" ng-click="setFavourite()" md-font-library="material-icons">favorite_border</md-icon>
</div>
<div flex="5" layout="row" layout-align="center center">
<md-menu>
<md-icon id="desc-btn" ng-click="$mdMenu.open()" md-font-library="material-icons">info</md-icon>
<md-menu-content style="width: auto;max-width: 450px;padding: 10px;" ng-mouseleave="$mdMenu.close()">
{{ playerService.podcastDescription | episodeDesc }}
</md-menu-content>
</md-menu>
<md-icon id="desc-btn" ng-click="showDescription(playerService.currentlyPlaying, playerService.podcastDescription | episodeDesc)"
md-font-library="material-icons">info</md-icon>
</div>
<div flex="5" layout="row" layout-align="center center">
<md-icon id="toggle-btn" ng-click="toggleSidebar()" md-font-library="material-icons">view_headline</md-icon>
Expand All @@ -149,8 +157,8 @@
<md-icon id="volume-btn" md-font-library="material-icons">{{ checkVolume() }}</md-icon>
</div>
<md-slider-container flex="10">
<md-slider id="volume-slider" onmouseup="document.activeElement.blur()" ng-model="volume" ng-change="setVolume()" flex min="0"
max="1" step="0.0001" aria-label="volume"></md-slider>
<md-slider id="volume-slider" onmouseup="document.activeElement.blur()" ng-model="volume" ng-change="setVolume()"
flex min="0" max="1" step="0.0001" aria-label="volume"></md-slider>
</md-slider-container>
<div flex="5"></div>
</div>
Expand Down
77 changes: 59 additions & 18 deletions app/scripts/app/episodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,106 @@ angular
$scope,
$rootScope,
$http,
$filter,
$mdSidenav,
ToastService,
PlayerService
) {
var parsePodcast = require("node-podcast-parser");
var log = require('electron-log');

//Calculating number of episodes to load by default based on application outer height, 55px is min height of a episode element.
const EPISODE_BASE_LIMIT = Math.floor(window.outerHeight / 55);
$scope.limit = EPISODE_BASE_LIMIT;
$scope.query = "";

$scope.albumCover = "";
$scope.isLoading = false;
$scope.nrOfItems = 20;
$scope.playPodcast = $rootScope.playPodcast;
$scope.episodes = [];
$scope.canLoadMore = false;

$scope.loadMore = function () {
$scope.nrOfItems += 10;
if ($scope.episodes.length <= $scope.nrOfItems) {
$scope.canLoadMore = false;
}
};
var allEpisodes = [];

$rootScope.fetchEpisodes = function (id, title, podcastCover) {
log.info('Fetching episodes...');
PlayerService.latestSeenArtist = title;
PlayerService.latestSeenID = id.toString();
PlayerService.latestSeenCover = podcastCover;
$scope.limit = EPISODE_BASE_LIMIT;
$scope.query = "";

$scope.episodeTitle = PlayerService.latestSeenArtist;
$scope.episodes = [];
allEpisodes = [];
$scope.isLoading = true;
$scope.nrOfItems = 20;
$scope.canLoadMore = false;
$mdSidenav("right").open().then(function () {
log.info("Looking up iTunes id: " + id);
$http.get("https://itunes.apple.com/lookup?id=" + id).then(
function successCallback(response) {
log.info('Found iTunes data.');
log.info('Getting podcastfeed...');
$http.get(response.data.results[0].feedUrl).then(
function successCallback(response) {
parsePodcast(response.data, function (err, data) {
if (err) {
log.info('Successfully fetched podcastfeed.');
log.info('Parsing podcastfeed...');
parsePodcast(response.data, function (error, data) {
if (error) {
$scope.isLoading = false;
ToastService.errorToast("Parsing podcastfeed failed.");
log.error(error);
} else {
$scope.isLoading = false;
$scope.episodes = data.episodes;
if ($scope.episodes.length > $scope.nrOfItems) {
$scope.canLoadMore = true;
}
allEpisodes = angular.copy(data.episodes);
log.info('Parsed ' + $scope.episodes.length + ' episodes.');
}
});
},
function errorCallback(response) {
function errorCallback(error) {
$scope.isLoading = false;
ToastService.errorToast("Failed to get podcast RSS feed.");
log.error(error);
}
);
},
function errorCallback(response) {
function errorCallback(error) {
$scope.isLoading = false;
ToastService.errorToast("Failed to lookup id in iTunes.");
log.error(error);
}
);
});
};

//Filter episodes
$scope.filterEpisodes = function () {
$scope.episodes = $filter('filter')(allEpisodes, $scope.query);
}

//Toggle order based on publish date
$scope.toggleOrder = true;
$scope.toggleOrderBy = function () {
$scope.toggleOrder = !$scope.toggleOrder;
if ($scope.toggleOrder) {
$scope.episodes = $filter('orderBy')($scope.episodes, '-published');
} else {
$scope.episodes = $filter('orderBy')($scope.episodes, 'published');
}
}

//Fetch and render more episodes as the user scrolls the episode list
var episodeNav = document.getElementById('right-sidenav');
var loadMoreEpisodes = function () {
//check if scroll is at bottom & if there is more episodes to load
if (episodeNav.scrollTop === (episodeNav.scrollHeight - episodeNav.offsetHeight) && $scope.limit < $scope.episodes.length) {
$scope.limit += 10;
$scope.$digest();
}
}

//Listen for the scroll event of the episode list
episodeNav.addEventListener('scroll', loadMoreEpisodes);

//Check if we need to load more episodes when the window size changes
window.addEventListener('resize', loadMoreEpisodes);

});

0 comments on commit 2554bbf

Please sign in to comment.