diff --git a/src/router.js b/src/router.js
index d0e03fb63c61ff3ce8565a8cb0b5a22e0de9ec37..0d368b30baaa6ce683daa2e1e1f58e3d23a61d39 100644
--- a/src/router.js
+++ b/src/router.js
@@ -29,9 +29,12 @@ import Main from './components/Main'
 import Show from './views/Show'
 import Episode from './views/Episode'
 import Browse from './views/Browse'
+import BrowseAll from './views/BrowseAll'
 import NotImplemented from './views/NotImplemented'
 import store from './store.js'
 
+import BrowseEmpty from './views/placeholder/Browse'
+
 Vue.use(Router)
 const requesttoken = axios.defaults.headers.requesttoken
 
@@ -41,7 +44,7 @@ const router = new Router({
 	routes: [
 		{
 			path: '/listening',
-			component: NotImplemented,
+			component: BrowseEmpty,
 			name: 'LISTENING',
 		},
 		{
@@ -54,6 +57,11 @@ const router = new Router({
 			component: Browse,
 			name: 'BROWSE',
 		},
+		{
+			path: '/browse/hot',
+			component: BrowseAll,
+			name: 'BROWSE',
+		},
 		{
 			path: '/browse/show/:id',
 			component: Show,
diff --git a/src/views/Browse.vue b/src/views/Browse.vue
index 1758159259fcd8a6a29c70f306ccb9253d8df534..b82afbc0647b05c46ff36f1c119ce958d5e22bf4 100644
--- a/src/views/Browse.vue
+++ b/src/views/Browse.vue
@@ -20,45 +20,73 @@
   -
   -->
 <template>
-	<div class="mainContent">
-		<div class="podcastSection">
-			<div class="podcastSectionHeader">
-				<h1>Hot podcasts</h1>
-				<a href="">Show all</a>
-			</div>
-			<div class="podcastSlider">
-				<div class="navPrev" />
-				<div class="navNext" />
-				<div
-					v-for="(podcast, idx) in podcastsHot"
-					:key="idx"
-					class="podcastCard">
-					<router-link :to="{ path: `/browse/show/${podcast.id}`}">
-						<div
-							class="podcastImage"
-							:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
-						<span class="title">
-							{{ podcast.title }}
-						</span>
-						<span class="subtitle">
-							{{ podcast.author }}
-						</span>
-					</router-link>
+	<div>
+		<BrowseEmpty v-show="pageLoading" />
+		<div
+			v-show="!pageLoading"
+			class="mainContent">
+			<div class="podcastSection">
+				<div class="podcastSectionHeader">
+					<h1>Hot podcasts</h1>
+					<a href="#/browse/hot">Show all</a>
+				</div>
+				<div class="podcastSlider">
+					<div class="navPrev" />
+					<div class="navNext" />
+					<div
+						v-for="(podcast, idx) in podcastsHot"
+						:key="idx"
+						class="podcastCard">
+						<router-link :to="{ path: `/browse/show/${podcast.id}`}">
+							<div
+								class="podcastImage"
+								:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
+							<span class="title">
+								{{ podcast.title }}
+							</span>
+							<span class="subtitle">
+								{{ podcast.author }}
+							</span>
+						</router-link>
+					</div>
 				</div>
 			</div>
-		</div>
 
-		<div class="podcastSection">
-			<div class="podcastSectionHeader">
-				<h1>New podcasts</h1>
-				<a href="">Show all</a>
+			<div class="podcastSection">
+				<div class="podcastSectionHeader">
+					<h1>New podcasts</h1>
+					<a href="#/browse/new">Show all</a>
+				</div>
+				<div class="podcastSlider">
+					<div
+						v-for="(podcast, idx) in podcastsLatest"
+						:key="idx"
+						class="podcastCard">
+						<router-link :to="{ path: `/browse/show/${podcast.id}`}">
+							<div
+								class="podcastImage"
+								:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
+							<span class="title">
+								{{ podcast.title }}
+							</span>
+							<span class="subtitle">
+								{{ podcast.author }}
+							</span>
+						</router-link>
+					</div>
+				</div>
 			</div>
-			<div class="podcastSlider">
-				<div
-					v-for="(podcast, idx) in podcastsLatest"
-					:key="idx"
-					class="podcastCard">
-					<router-link :to="{ path: `/browse/show/${podcast.id}`}">
+
+			<div class="podcastSection">
+				<div class="podcastSectionHeader">
+					<h1>Podcast charts</h1>
+					<a href="">Show all</a>
+				</div>
+				<div class="podcastSlider">
+					<div
+						v-for="(podcast, idx) in podcastsHot"
+						:key="idx"
+						class="podcastCard">
 						<div
 							class="podcastImage"
 							:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
@@ -68,30 +96,7 @@
 						<span class="subtitle">
 							{{ podcast.author }}
 						</span>
-					</router-link>
-				</div>
-			</div>
-		</div>
-
-		<div class="podcastSection">
-			<div class="podcastSectionHeader">
-				<h1>Podcast charts</h1>
-				<a href="">Show all</a>
-			</div>
-			<div class="podcastSlider">
-				<div
-					v-for="(podcast, idx) in podcastsHot"
-					:key="idx"
-					class="podcastCard">
-					<div
-						class="podcastImage"
-						:style="{ backgroundImage: `url(${podcast.smallImageURL})` }" />
-					<span class="title">
-						{{ podcast.title }}
-					</span>
-					<span class="subtitle">
-						{{ podcast.author }}
-					</span>
+					</div>
 				</div>
 			</div>
 		</div>
@@ -99,14 +104,20 @@
 </template>
 
 <script>
+import BrowseEmpty from './placeholder/Browse'
+
 import { showError } from '@nextcloud/dialogs'
 import axios from '@nextcloud/axios'
 
 export default {
 	name: 'Browse',
+	components: {
+		BrowseEmpty,
+	},
 	data: () => ({
 		podcastsHot: {},
 		podcastsLatest: {},
+		pageLoading: true,
 	}),
 	mounted() {
 		this.queryTopPodcasts()
@@ -134,6 +145,7 @@ export default {
 				await axios.get(queryURI)
 					.then(function(response) {
 						vm.podcastsLatest = response.data.data
+						vm.pageLoading = false
 					})
 			} catch (error) {
 				showError(t('podcast', 'Could not fetch podcasts from remote API'))
@@ -146,7 +158,7 @@ export default {
 
 <style lang="scss">
 .mainContent {
-	padding: 30px;
+	padding: 20px 30px;
 
 	h1 {
 		font-size: 1.6em;
@@ -155,7 +167,7 @@ export default {
 }
 
 .podcastSection {
-	margin-bottom: 30px;
+	margin-bottom: 20px;
 }
 
 .podcastSectionHeader {
diff --git a/src/views/Episode.vue b/src/views/Episode.vue
index fc8d914c9ebc78da2b4218a66b0eb24bc0135d38..d3843c21f04de9d8328cdcedac0a723331628424 100644
--- a/src/views/Episode.vue
+++ b/src/views/Episode.vue
@@ -21,7 +21,7 @@
   -->
 <template>
 	<div>
-		<ShowEmpty v-show="pageLoading" />
+		<EpisodeEmpty v-show="pageLoading" />
 		<transition name="fade">
 			<div v-show="!pageLoading">
 				<MediaHeader
@@ -77,7 +77,7 @@
 
 import { showError } from '@nextcloud/dialogs'
 import axios from '@nextcloud/axios'
-import ShowEmpty from './ShowEmpty'
+import EpisodeEmpty from './placeholder/Episode'
 import ContentCollapsable from '../components/ContentCollapsable'
 import MediaHeader from '../components/MediaHeader'
 
@@ -88,16 +88,15 @@ const timeAgo = new TimeAgo('en-US')
 export default {
 	name: 'Episode',
 	components: {
-		ShowEmpty,
+		EpisodeEmpty,
 		ContentCollapsable,
 		MediaHeader,
 	},
 	data: () => ({
 		episode: {},
-		pageLoading: false,
+		pageLoading: true,
 	}),
 	mounted() {
-		this.pageLoading = true
 		const episodeId = this.$route.params.episodeId
 		this.queryEpisode(episodeId)
 	},
diff --git a/src/views/Show.vue b/src/views/Show.vue
index 857ebe4fc6652cb29dac395ddf7455715e71ad1e..a9106671ea3475cb609bcbd671508976df07b12a 100644
--- a/src/views/Show.vue
+++ b/src/views/Show.vue
@@ -21,9 +21,9 @@
   -->
 <template>
 	<div>
-		<ShowEmpty v-show="pageLoading" />
+		<ShowEmpty v-show="loading" />
 		<transition name="fade">
-			<div v-show="!pageLoading">
+			<div v-show="!loading">
 				<MediaHeader
 					:imgurl="podcast.smallImageURL"
 					:title="podcast.title"
@@ -37,7 +37,7 @@
 					:episodes="podcast.episodes"
 					@doPlay="doPlay" />
 				<EmptyContent
-					v-show="!episodesLoaded"
+					v-show="nextPage"
 					icon="icon-loading"
 					class="tableLoading" />
 			</div>
@@ -55,7 +55,7 @@ import axios from '@nextcloud/axios'
 
 import { audioPlayer, doPlay } from '../services/player'
 
-import ShowEmpty from './ShowEmpty'
+import ShowEmpty from './placeholder/Show'
 
 export default {
 	name: 'Show',
@@ -69,9 +69,9 @@ export default {
 		podcast: {
 			episodes: [],
 		},
-		pageLoading: false,
-		episodesLoaded: false,
+		loading: true,
 		nextPage: null,
+		podcastId: null,
 	}),
 	computed: {
 		player() {
@@ -94,10 +94,14 @@ export default {
 		},
 	},
 	mounted() {
-		this.pageLoading = true
-		const podcastId = this.$route.params.id
-		this.queryPodcast(podcastId)
-		this.scroll()
+		this.podcastId = this.$route.params.id
+		this.queryPodcast(this.podcastId)
+	},
+	created() {
+	  window.addEventListener('scroll', this.handleScroll)
+	},
+	destroyed() {
+	  window.removeEventListener('scroll', this.handleScroll)
 	},
 	methods: {
 
@@ -120,16 +124,9 @@ export default {
 
 		preFill() {
 			console.log('prefilling')
-			const podcastId = this.$route.params.id
 			// this.queryPodcast(podcastId)
-			console.log(podcastId)
 		},
 
-		/**
-			 * Start playing a podcast episode
-			 * @param {Object} episode Episode object
-			 */
-
 		async queryPodcast(podcastId) {
 
 			const vm = this
@@ -154,27 +151,27 @@ export default {
 		},
 
 		processPodcast(podcast) {
+			if (podcast.meta.paging.page === podcast.meta.paging.last_page) {
+				this.nextPage = false
+				window.removeEventListener('scroll', this.handleScroll)
+			} else {
+				this.nextPage = podcast.meta.paging.next_page
+			}
 			if (podcast.meta.paging.page === 0) {
 				this.podcast = podcast.data
 			} else {
-				if (podcast.meta.paging.page === podcast.meta.paging.last_page) {
-					this.episodesLoaded = true
-				}
 				this.podcast.episodes = this.podcast.episodes.concat(podcast.data.episodes)
 			}
-			this.pageLoading = false
+			this.loading = false
 		},
 
 		/**
-		 * On scroll event, load more stations if bottom reached
+		 * On scroll event, load more episodes if bottom reached
 		 */
-		scroll() {
-			window.onscroll = () => {
-				if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
-					if (!this.episodesLoaded) {
-						const podcastId = this.$route.params.id
-						this.queryPodcast(podcastId)
-					}
+		handleScroll() {
+			if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
+				if (!this.episodesLoaded) {
+					this.queryPodcast(this.podcastId)
 				}
 			}
 		},
diff --git a/src/views/ShowEmpty.vue b/src/views/ShowEmpty.vue
deleted file mode 100644
index 65ba57315da52991ab0d389824c4b896d66e8a7d..0000000000000000000000000000000000000000
--- a/src/views/ShowEmpty.vue
+++ /dev/null
@@ -1,183 +0,0 @@
-<!--
-  - @copyright Copyright (c) 2020 Jonas Heinrich
-  -
-  - @author Jonas Heinrich <onny@project-insanity.org>
-  -
-  - @license GNU AGPL version 3 or any later version
-  -
-  - This program is free software: you can redistribute it and/or modify
-  - it under the terms of the GNU Affero General Public License as
-  - published by the Free Software Foundation, either version 3 of the
-  - License, or (at your option) any later version.
-  -
-  - This program is distributed in the hope that it will be useful,
-  - but WITHOUT ANY WARRANTY; without even the implied warranty of
-  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  - GNU Affero General Public License for more details.
-  -
-  - You should have received a copy of the GNU Affero General Public License
-  - along with this program. If not, see <http://www.gnu.org/licenses/>.
-  -
-  -->
-
-<template>
-	<div>
-		<div class="podcastHeaderEmpty">
-			<div class="podcastImageEmpty" />
-			<div class="podcastDescriptionEmpty">
-				<div class="podcastDescriptionTitle" />
-				<div
-					class="podcastDescriptionSubTitle"
-					style="max-width: 300px; width: 100%;" />
-				<div
-					class="podcastDescriptionSubTitle"
-					style="max-width: 400px; width: 100%;" />
-				<div
-					class="podcastDescriptionSubTitle"
-					style="max-width: 200px; width: 100%;" />
-			</div>
-		</div>
-		<table class="episodeTable">
-			<thead>
-				<tr>
-					<th class="iconColumn" />
-					<th class="nameColumn">
-						{{ t('podcast', 'Name') }}
-					</th>
-					<th class="actionColumn" />
-					<th class="durationColumn">
-						{{ t('podcast', 'Duration') }}
-					</th>
-					<th class="dateColumn">
-						{{ t('podcast', 'Date') }}
-					</th>
-				</tr>
-			</thead>
-			<tbody>
-				<tr v-for="index in 3" :key="index">
-					<td class="iconColumn">
-						<div class="episodeImageEmpty" />
-					</td>
-					<td class="nameColumn">
-						<div
-							class="episodeDescription"
-							style="width: 500px;" />
-						<div
-							class="episodeDescription"
-							style="width: 400px;" />
-					</td>
-					<td class="actionColumn" />
-					<td class="durationColumn" />
-					<td class="dateColumn" />
-				</tr>
-			</tbody>
-		</table>
-	</div>
-</template>
-
-<script>
-
-export default {
-	name: 'ShowEmpty',
-}
-</script>
-
-<style lang="scss">
-
-$base-color: #ddd;
-$shine-color: #e8e8e8;
-$animation-duration: 1.6s;
-$avatar-offset: 52 + 16;
-
-@mixin background-gradient {
-	background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px);
-	background-size: 600px;
-}
-
-.podcastHeaderEmpty {
-	width: 100%;
-	min-height: 300px;
-	display: flex;
-	justify-content: center;
-	padding: 40px 20px;
-	background-color: #f2f2f2;
-}
-
-.podcastImageEmpty {
-	width: 200px;
-	height: 200px;
-	flex-shrink: 0;
-	background-color: #ccc;
-	margin-right: 25px;
-	border-radius: 5px;
-
-	@include background-gradient;
-	animation: shine-avatar $animation-duration infinite linear;
-}
-
-.podcastDescriptionEmpty {
-	max-width: 500px;
-	width: 100%;
-}
-
-.podcastDescriptionTitle {
-	max-width: 500px;
-	width: 100%;
-	height: 35px;
-	border-radius: 5px;
-	margin-bottom: 30px;
-	background-color: #ddd;
-
-	@include background-gradient;
-	animation: shine-lines $animation-duration infinite linear;
-}
-
-.podcastDescriptionSubTitle {
-	height: 20px;
-	border-radius: 5px;
-	margin-bottom: 10px;
-	background-color: #ddd;
-
-	@include background-gradient;
-	animation: shine-lines $animation-duration infinite linear;
-}
-
-.episodeImageEmpty {
-	width: 74px;
-	height: 74px;
-	background-color: #ccc;
-	border-radius: 5px;
-
-	@include background-gradient;
-	animation: shine-avatar $animation-duration infinite linear;
-}
-
-.episodeDescription {
-	height: 20px;
-	border-radius: 5px;
-	margin-bottom: 10px;
-	background-color: #ddd;
-
-	@include background-gradient;
-	animation: shine-lines $animation-duration infinite linear;
-}
-
-@keyframes shine-lines {
-	0% {
-		background-position: -100px;
-	}
-	60%, 100% {
-		background-position: 500px;
-	}
-}
-
-@keyframes shine-avatar {
-	0% {
-		background-position: -100px + $avatar-offset;
-	}
-	40%, 100% {
-		background-position: 140px + $avatar-offset;
-	}
-}
-
-</style>