diff --git a/README.md b/README.md index 9dd7420..387ffba 100644 --- a/README.md +++ b/README.md @@ -36,4 +36,3 @@ The website makes use of SVG files. Make sure your web server is configured to p ### Credits: * Some icons used are provided by _feather_: https://www.github.com/colebemis/feather -* RSS feed generation is done with _podcastfeed_: https://www.github.com/torann/podcastfeed diff --git a/composer.json b/composer.json index feb78a4..923b1c0 100644 --- a/composer.json +++ b/composer.json @@ -7,8 +7,7 @@ "require": { "php": ">=5.6.4", "laravel/framework": "5.5.*", - "laravel/tinker": "~1.0", - "torann/podcastfeed": "^0.2.2" + "laravel/tinker": "~1.0" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index 28e8cf4..42fc5fa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1cae6beacabbf92528e5f3b3aef29cf0", + "content-hash": "a227793fb94a414365706d2a530b7e23", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -2117,56 +2117,6 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "time": "2016-09-20T12:50:39+00:00" }, - { - "name": "torann/podcastfeed", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/Torann/podcastfeed.git", - "reference": "6c4bd157a3eaaaa62aa71f665566ed2050973664" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Torann/podcastfeed/zipball/6c4bd157a3eaaaa62aa71f665566ed2050973664", - "reference": "6c4bd157a3eaaaa62aa71f665566ed2050973664", - "shasum": "" - }, - "require": { - "illuminate/support": "~5.1", - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.2-dev" - } - }, - "autoload": { - "psr-4": { - "Torann\\PodcastFeed\\": "src/Torann/PodcastFeed/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD 2-Clause" - ], - "authors": [ - { - "name": "Daniel Stainback", - "email": "daniel@lyften.com" - } - ], - "description": "Generate RSS feeds for podcasts in Laravel 5.", - "keywords": [ - "feed", - "laravel", - "podcast", - "podcast generator", - "rss", - "xml" - ], - "time": "2016-09-01T20:24:17+00:00" - }, { "name": "vlucas/phpdotenv", "version": "v2.4.0", diff --git a/config/app.php b/config/app.php index 552596b..135e977 100644 --- a/config/app.php +++ b/config/app.php @@ -177,11 +177,6 @@ App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, - /* - * https://github.com/Torann/podcastfeed - */ - Torann\PodcastFeed\PodcastFeedServiceProvider::class, - ], /* @@ -218,7 +213,6 @@ 'Mail' => Illuminate\Support\Facades\Mail::class, 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, - 'PodcastFeed' => Torann\PodcastFeed\Facades\PodcastFeed::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redis' => Illuminate\Support\Facades\Redis::class, diff --git a/config/podcast-feed.php b/config/podcast-feed.php deleted file mode 100644 index 1d125d0..0000000 --- a/config/podcast-feed.php +++ /dev/null @@ -1,16 +0,0 @@ - [ - 'title' => 'Steamchat Podcast', - 'subtitle' => 'A podcast all about Valve and the community', - 'description' => 'Sam, Saurabh and Brad discuss Valve, their games, and most importantly, the community and their discussions in the Steam Users\' Forums.', - 'author' => 'Sam, Saurabh, Brad', - 'email' => 'sam@flamov.com', - 'category' => 'Technology', - 'language' => 'en-us', - 'copyright' => '© Steamchat Podcast', - ] - -]; diff --git a/resources/assets/images/global/more-icon-google.svg b/resources/assets/images/global/more-icon-google.svg new file mode 100644 index 0000000..0c96fbd --- /dev/null +++ b/resources/assets/images/global/more-icon-google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/images/global/more-icon-itunes.svg b/resources/assets/images/global/more-icon-itunes.svg new file mode 100644 index 0000000..123928b --- /dev/null +++ b/resources/assets/images/global/more-icon-itunes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/images/global/more-icon-rss.svg b/resources/assets/images/global/more-icon-rss.svg new file mode 100644 index 0000000..b12fb93 --- /dev/null +++ b/resources/assets/images/global/more-icon-rss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/images/seo/podcast-feed-logo.png b/resources/assets/images/seo/podcast-feed-logo.png new file mode 100644 index 0000000..196dabe Binary files /dev/null and b/resources/assets/images/seo/podcast-feed-logo.png differ diff --git a/resources/assets/js/modules/sidebar.js b/resources/assets/js/modules/archive.js similarity index 70% rename from resources/assets/js/modules/sidebar.js rename to resources/assets/js/modules/archive.js index b44fd6e..2d5f251 100644 --- a/resources/assets/js/modules/sidebar.js +++ b/resources/assets/js/modules/archive.js @@ -1,65 +1,64 @@ -var $archives; - -var episodeCache = { +let $archives; +const episodeCache = { years: {}, categories: {} }; function createCache() { - $archives.$sidebar.$years = $archives.$sidebar.getElementsByClassName('js-year'); $archives.$sidebar.$categories = $archives.$sidebar.getElementsByClassName('js-category'); - var i, targetElement; - - var filterArray = function(key, attribute) { + const filterArray = function(key, attribute) { return Array.prototype.filter.call($archives.$episodes, function(episode) { return episode.getAttribute(attribute) === key; }); }; // Cache episodes by year - for (i = 0; i < $archives.$sidebar.$years.length; i++) { - + for (let i = 0; i < $archives.$sidebar.$years.length; i++) { // Get the element - targetElement = $archives.$sidebar.$years[i]; + let targetElement = $archives.$sidebar.$years[i]; // Get the year value - var targetYear = targetElement.value; + const targetYear = targetElement.value; // Check if the object property already exists if (episodeCache.years.hasOwnProperty(targetYear) === false) { episodeCache.years[targetYear] = filterArray(targetYear, 'data-year'); } - } // Cache episodes by category - for (i = 0; i < $archives.$sidebar.$categories.length; i++) { - + for (let i = 0; i < $archives.$sidebar.$categories.length; i++) { // Get the element - targetElement = $archives.$sidebar.$categories[i]; + let targetElement = $archives.$sidebar.$categories[i]; // Get the category value - var targetCategory = targetElement.value; + const targetCategory = targetElement.value; // Check if the object property already exists if (targetCategory !== 'all' && episodeCache.categories.hasOwnProperty(targetCategory) === false) { episodeCache.categories[targetCategory] = filterArray(targetCategory, 'data-category'); } - } } function searchBehaviour() { + let value = this.value; + + // Ignore non-alphanumeric and whitespace characters + value = value.replace(/[^a-zA-Z0-9]/gi, ' '); - var value = this.value; - var regex = new RegExp(value, 'gi'); + // Then replace multiple spaces with a single space + value = value.replace(/\s\s+/g, ' '); - for (var i = 0; i < $archives.$episodes.length; i++) { - var targetElement = $archives.$episodes[i]; - if (targetElement.getAttribute('data-description').search(regex) < 0) { + const regex = new RegExp(value, 'gi'); + + for (let i = 0; i < $archives.$episodes.length; i++) { + const targetElement = $archives.$episodes[i]; + let description = targetElement.getAttribute('data-description'); + if (description.search(regex) < 0) { targetElement.classList.add('filter-description'); } else { @@ -75,22 +74,16 @@ function searchBehaviour() { } updateFilteringDisplay(); - } function yearsBehaviour() { - - var i; - - var totalLength = $archives.$sidebar.$years.length; - - var yearsActive = 0; - for (i = 0; i < $archives.$sidebar.$years.length; i++) { + const totalLength = $archives.$sidebar.$years.length; + let yearsActive = 0; + for (let i = 0; i < $archives.$sidebar.$years.length; i++) { if ($archives.$sidebar.$years[i].checked === true) { yearsActive++; } } - yearsActive = totalLength - (totalLength - yearsActive); // If this is the last checkbox checked, prevent it from becoming unchecked @@ -98,26 +91,22 @@ function yearsBehaviour() { this.checked = true; } else { - this.disabled = false; - var selectedYear = episodeCache.years[this.value]; + const selectedYear = episodeCache.years[this.value]; // Loop through the year of episodes corresponding to the year checkbox value - for (i = 0; i < selectedYear.length; i++) { - - var targetEpisode = selectedYear[i]; - + for (let i = 0; i < selectedYear.length; i++) { + const targetEpisode = selectedYear[i]; if (this.checked === true) { targetEpisode.classList.remove('filter-year'); } else { targetEpisode.classList.add('filter-year'); } - } // Disable last checkbox if only one left, otherwise enable all checkboxes - for (i = 0; i < $archives.$sidebar.$years.length; i++) { + for (let i = 0; i < $archives.$sidebar.$years.length; i++) { if (yearsActive <= 1 && $archives.$sidebar.$years[i].checked === true) { $archives.$sidebar.$years[i].disabled = true; break; @@ -130,58 +119,49 @@ function yearsBehaviour() { } updateFilteringDisplay(); - } function categoryBehaviour() { - - var i; - var selectedCategory = this.value; + const selectedCategory = this.value; if (selectedCategory === 'all') { - for (i = 0; i < $archives.$episodes.length; i++) { + for (let i = 0; i < $archives.$episodes.length; i++) { $archives.$episodes[i].classList.remove('filter-category'); } } else { - - for (i = 0; i < $archives.$episodes.length; i++) { + for (let i = 0; i < $archives.$episodes.length; i++) { $archives.$episodes[i].classList.add('filter-category'); } - var targetCategory = episodeCache.categories[selectedCategory]; - for (i = 0; i < targetCategory.length; i++) { + const targetCategory = episodeCache.categories[selectedCategory]; + for (let i = 0; i < targetCategory.length; i++) { targetCategory[i].classList.remove('filter-category'); } - } updateFilteringDisplay(); - } function resetBehaviour(event) { - if (event !== null) { event.preventDefault(); } - var i; - // Reset the search field $archives.$sidebar.$search.value = ''; $archives.$sidebar.$search.classList.remove('active'); // Reset the year inputs - for (i = 0; i < $archives.$sidebar.$years.length; i++) { - var targetCheckbox = $archives.$sidebar.$years[i]; + for (let i = 0; i < $archives.$sidebar.$years.length; i++) { + const targetCheckbox = $archives.$sidebar.$years[i]; targetCheckbox.checked = true; targetCheckbox.disabled = false; } // Reset the category inputs - for (i = 0; i < $archives.$sidebar.$categories.length; i++) { - var targetCategory = $archives.$sidebar.$categories[i]; + for (let i = 0; i < $archives.$sidebar.$categories.length; i++) { + const targetCategory = $archives.$sidebar.$categories[i]; if (targetCategory.value === 'all') { targetCategory.checked = true; break; @@ -189,30 +169,27 @@ function resetBehaviour(event) { } // Reset the episode elements - for (i = 0; i < $archives.$episodes.length; i++) { + for (let i = 0; i < $archives.$episodes.length; i++) { $archives.$episodes[i].classList.remove('filter-description', 'filter-year', 'filter-category'); } // Update filering display updateFilteringDisplay(); - } function updateFilteringDisplay() { + const total = $archives.$episodes.length; + let hiding = 0; - var total = $archives.$episodes.length; - var hiding = 0; - - var filterClasses = [ + const filterClasses = [ 'filter-description', 'filter-year', 'filter-category' ]; // Function to check if any of the filter classes are present in the element class list - var checkClass = function(element) { - var containCount = 0; - for (var i = 0; i < filterClasses.length; i++) { + const checkClass = function(element) { + for (let i = 0; i < filterClasses.length; i++) { if (element.classList.contains(filterClasses[i]) === true) { return true; } @@ -221,14 +198,13 @@ function updateFilteringDisplay() { }; // Loop through each episode elements and increase the hiding count if it contains any filter classes - for (var i = 0; i < $archives.$episodes.length; i++) { + for (let i = 0; i < $archives.$episodes.length; i++) { if (checkClass($archives.$episodes[i]) === true) { hiding++; } } - var showing = total - hiding; - + const showing = total - hiding; if (showing < total) { $archives.$counter.innerHTML = 'Showing ' + showing + ' of ' + total + ' episodes:'; $archives.classList.add('filtering'); @@ -244,13 +220,9 @@ function updateFilteringDisplay() { else { $archives.classList.remove('empty'); } - } export function init(element) { - - var i; - // Cache element selectors $archives = element; $archives.$sidebar = $archives.getElementsByClassName('js-sidebar')[0]; @@ -262,7 +234,7 @@ export function init(element) { /*** Bind sidebar scrolling ***/ window.addEventListener('scroll', function() { - var padding = 40; + const padding = 40; if (window.scrollY > ($archives.offsetTop - padding)) { $archives.$sidebar.classList.add('sticky'); } @@ -275,7 +247,7 @@ export function init(element) { createCache(); /*** Bind Show Button ***/ - var show = $archives.getElementsByClassName('js-show'); + const show = $archives.getElementsByClassName('js-show'); if (show.length > 0) { show[0].addEventListener('click', function(event) { event.preventDefault(); @@ -290,19 +262,18 @@ export function init(element) { $archives.$sidebar.$search.addEventListener('input', searchBehaviour); /*** Bind Year Inputs ***/ - for (i = 0; i < $archives.$sidebar.$years.length; i++) { + for (let i = 0; i < $archives.$sidebar.$years.length; i++) { $archives.$sidebar.$years[i].addEventListener('change', yearsBehaviour); } /*** Bind Category Inputs ***/ - for (i = 0; i < $archives.$sidebar.$categories.length; i++) { + for (let i = 0; i < $archives.$sidebar.$categories.length; i++) { $archives.$sidebar.$categories[i].addEventListener('change', categoryBehaviour); } /*** Bind Reset Button ***/ - var reset = $archives.getElementsByClassName('js-reset'); - for (i = 0; i < reset.length; i++) { + const reset = $archives.getElementsByClassName('js-reset'); + for (let i = 0; i < reset.length; i++) { reset[i].addEventListener('click', resetBehaviour); } - } diff --git a/resources/assets/js/modules/listen.js b/resources/assets/js/modules/listen.js index 49e2571..ee622dc 100644 --- a/resources/assets/js/modules/listen.js +++ b/resources/assets/js/modules/listen.js @@ -1,20 +1,17 @@ function listenBehaviour(event) { - event.preventDefault(); - var target = document.getElementsByClassName('js-audio')[0]; - + const target = document.getElementsByClassName('js-audio')[0]; if (target.paused === true || target.stopped === true) { target.play(); } else { target.pause(); } - } export function init(elements) { - for (var i = 0; i < elements.length; i++) { + for (let i = 0; i < elements.length; i++) { elements[i].addEventListener('click', listenBehaviour); } } diff --git a/resources/assets/js/modules/player.js b/resources/assets/js/modules/player.js index 9bf453d..625f216 100644 --- a/resources/assets/js/modules/player.js +++ b/resources/assets/js/modules/player.js @@ -1,18 +1,17 @@ function player(element) { - - var Vue = require('vue'); + const Vue = require('vue'); return new Vue({ el: element, template: `
-
- +
@@ -61,6 +60,7 @@ function player(element) { }, methods: { getEpisode: function(episode, autoplay) { + const self = this; // Clear episode data and reset player state this.episodeData = false; @@ -68,8 +68,6 @@ function player(element) { this.isPlaying = this.isReady = false; this.currentTime = 0; - var self = this; - if (episode === 'latest') { episode = '/api/latest'; } @@ -77,13 +75,10 @@ function player(element) { episode = '/api/episode/' + episode; } - var request = new XMLHttpRequest(); + const request = new XMLHttpRequest(); request.open('GET', episode, true); - request.onload = function() { - if (request.status >= 200 && request.status < 400) { - // Store the episode data self.episodeData = JSON.parse(request.responseText); @@ -106,40 +101,33 @@ function player(element) { else { self.isLoading = false; } - } - }; - request.send(); - }, loaded: function() { - if (this.isReady === false) { // Start playing the audio once its ready to be played this.isReady = true; this.isLoading = false; - this.togglePlay(true); + this.togglePlay(true, null); } - }, - togglePlay: function(target) { + togglePlay: function(target, event) { + const self = this; - var self = this; + if (event !== null) { + event.preventDefault(); + } // Do not do anything if the player is still in a loading state if (this.isLoading === false) { - if (this.isReady === false) { - // If the audio element is not ready yet, start loading it this.isLoading = true; this.$refs.audioElement.load(); - } else { - // Otherwise call the pause/play methods if (target === false) { this.$refs.audioElement.pause(); @@ -148,8 +136,8 @@ function player(element) { else if (target === true) { // Attempt autoplay for Safari 11 // More info: https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/ - var promiseError = false; - var promise = this.$refs.audioElement.play(); + let promiseError = false; + const promise = this.$refs.audioElement.play(); promise.catch(function(error) { promiseError = true; self.isPlaying = false; @@ -159,38 +147,31 @@ function player(element) { } }); } - } - } - }, stop: function() { - // Call the pause method on the audio element this.$refs.audioElement.pause(); this.isPlaying = false; - }, moveLine: function(event) { - // Move the seek line depending on the window y-coordinate during hover event this.lineHover = ((event.pageX - 2) / window.innerWidth) * 100; this.hoverTime = this.episodeData.duration * (event.pageX / window.innerWidth); - }, changeTime: function(event) { - // Change audio element time by calculating the target time by y-coordinate and total duration if (this.isReady === true) { - var coordinateX = event.pageX / window.innerWidth; + const coordinateX = event.pageX / window.innerWidth; this.$refs.audioElement.currentTime = this.episodeData.duration * coordinateX; this.updateTime(); } - + }, + showBuffering: function() { + this.isBuffering = true; }, updateTime: function() { - // Hide buffering state this.isBuffering = false; @@ -201,19 +182,17 @@ function player(element) { else { return null; } - }, formatTime: function(target) { - // Returns a HH:MM:SS formatted time string target = Number(target); - var hours = Math.floor(target / 3600), - minutes = Math.floor(target % 3600 / 60), - seconds = Math.floor(target % 3600 % 60); + const hours = Math.floor(target / 3600); + const minutes = Math.floor(target % 3600 / 60); + const seconds = Math.floor(target % 3600 % 60); return (hours < 10 ? '0' : '') + hours + ':' + (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds; - }, - toggleMute: function() { + toggleMute: function(event) { + event.preventDefault(); // Toggle between mute (0) and normal volume (100) if (this.volume === 0) { @@ -222,12 +201,10 @@ function player(element) { else { this.volume = 0; } - } }, computed: { durationCurrent: function() { - // Returns timestamp for current time or hover-position time if (this.isReady === true) { if (this.movingLine === true) { @@ -240,16 +217,12 @@ function player(element) { else { return false; } - }, durationTotal: function() { - // Returns timestamp for total duration return this.formatTime(this.episodeData.duration); - }, linePosition: function() { - // Returns CSS left-position for seek line hover position if (this.isReady === true && this.movingLine === true) { return this.lineHover + '%'; @@ -257,31 +230,23 @@ function player(element) { else { return false; } - }, progressWidth: function() { - // Returns CSS position for progress cover element - var targetWidth; - + let targetWidth; if (this.isReady === true) { targetWidth = (this.currentTime / this.episodeData.duration) * 100; } else { targetWidth = 0; } - return targetWidth + '%'; - }, isMuted: function() { - // Returns boolean if audio is currently muted (0) return parseInt(this.volume, 10) === 0; - }, playerBackground: function() { - // Returns CSS background-image if (this.episodeData !== false && this.episodeData.background !== null) { return 'url(' + this.episodeData.background + ')'; @@ -289,10 +254,8 @@ function player(element) { else { return null; } - }, playerColour: function() { - // Returns CSS background-color if (this.episodeData !== false && this.episodeData.colour !== null) { return this.episodeData.colour; @@ -300,12 +263,10 @@ function player(element) { else { return null; } - } }, watch: { isPlaying: function(value) { - // Update the document title if audio is playing if (value === true) { document.title = 'Playing ' + this.episodeData.title; @@ -313,34 +274,29 @@ function player(element) { else { document.title = this.pageTitle; } - }, volume: function(value) { - // Convert the volume percentage into a valid input-slider value if (this.isReady === true) { this.$refs.audioElement.volume = parseInt(value, 10) * 0.01; } - } }, mounted: function() { + const self = this; // Once mounted, get the latest episode this.getEpisode('latest', false); - var self = this; - - var loadEpisode = function(event) { + const loadEpisode = function(event) { event.preventDefault(); self.getEpisode(this.getAttribute('data-id'), true); window.scrollTo(0, 0); }; - var buttons = document.body.getElementsByClassName('js-play'); - // Bind the archive play buttons - for (var i = 0; i < buttons.length; i++) { + const buttons = document.body.getElementsByClassName('js-play'); + for (let i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', loadEpisode); } @@ -350,14 +306,10 @@ function player(element) { self.stop(); } }); - } }); - } export function init(element) { - return player(element); - } diff --git a/resources/assets/js/scripts.js b/resources/assets/js/scripts.js index 7623037..2521ca6 100755 --- a/resources/assets/js/scripts.js +++ b/resources/assets/js/scripts.js @@ -1,34 +1,32 @@ -var sidebar = require('./modules/sidebar.js'); -var player = require('./modules/player.js'); -var listen = require('./modules/listen.js'); +const archive = require('./modules/archive.js'); +const player = require('./modules/player.js'); +const listen = require('./modules/listen.js'); (function(){ - // Bind the archive behaviours - var $sidebar = document.getElementsByClassName('js-archives'); - if ($sidebar.length > 0) { - sidebar.init($sidebar[0]); + const $archive = document.getElementsByClassName('js-archives'); + if ($archive.length > 0) { + archive.init($archive[0]); } // Bind the player - var $player = document.getElementsByClassName('js-player'); + const $player = document.getElementsByClassName('js-player'); if ($player.length > 0) { player.init($player[0]); } // Bind any listening elements - var $listen = document.getElementsByClassName('js-listen'); + const $listen = document.getElementsByClassName('js-listen'); if ($listen.length > 0) { listen.init($listen); } // Bind hamburger - var $menu = document.body.getElementsByClassName('js-menu')[0]; - $menu.$hamburger = $menu.getElementsByClassName('js-hamburger'); - $menu.$hamburger[0].addEventListener('click', function(event) { + const $menu = document.body.getElementsByClassName('js-menu')[0]; + const $hamburger = $menu.getElementsByClassName('js-hamburger'); + $hamburger[0].addEventListener('click', function(event) { event.preventDefault(); $menu.classList.toggle('open'); document.body.classList.toggle('noscroll'); }); - })(); diff --git a/resources/assets/sass/episode.scss b/resources/assets/sass/episode.scss index aa921c6..c88b35c 100755 --- a/resources/assets/sass/episode.scss +++ b/resources/assets/sass/episode.scss @@ -152,6 +152,23 @@ $buttonWidth: 100px; text-decoration: none; } +.content .sidebar > ul.more > li a { + display: inline-block; + padding-left: 15px + 5px; + background: left center no-repeat transparent; + background-size: contain; +} + +$list: "rss", "itunes", "google"; + +@each $service in $list { + + .content .sidebar > ul.more > li.#{$service} a { + background-image: url("../../images/global/more-icon-#{$service}.svg"); + } + +} + .content .sidebar > ul > li a:hover { text-decoration: underline; } @@ -174,24 +191,55 @@ $buttonWidth: 100px; width: 50%; } - .content .sidebar > ul:first-child { + .content .sidebar > ul.info { float: left; } - .content .sidebar > ul:last-child { + .content .sidebar > ul.tools { float: right; } + .content .sidebar > ul.more { + clear: both; + float: none; + padding-top: $paddingSmall; + width: auto; + text-align: center; + font-size: 0; + } + .content .sidebar > ul > li { margin-bottom: 5px; font-size: 12px; line-height: 12px; } + .content .sidebar > ul.more > li { + display: inline-block; + margin-right: 10px; + } + + .content .sidebar > ul.more > li.title, + .content .sidebar > ul.more > li:last-child { + margin-right: 0; + } + + .content .sidebar > ul.more > li.title { + display: block; + } + + .content .sidebar > ul.more > li.title { + text-align: center; + } + .content .sidebar > ul:first-child > li { text-align: left; } + .content .sidebar > ul.more > li a { + padding-left: 15px + 2px; + } + .content .sidebar > ul .title { font-size: 14px; line-height: 14px; diff --git a/resources/assets/sass/global.scss b/resources/assets/sass/global.scss index d7c9f61..828b5aa 100755 --- a/resources/assets/sass/global.scss +++ b/resources/assets/sass/global.scss @@ -40,7 +40,7 @@ .content h1 { margin-bottom: 20px; font-size: 32px; - @include lineHeight(32px); + line-height: 40px; color: $colour-steamchat; } diff --git a/resources/assets/sass/index.scss b/resources/assets/sass/index.scss index 256c0a9..0e6d61a 100755 --- a/resources/assets/sass/index.scss +++ b/resources/assets/sass/index.scss @@ -14,7 +14,7 @@ /* CONTENT */ -.archives > .sidebar, +.archives > .sidebar > .container, .archives > .list > .episode { border-radius: 2px; background: $colour-white; @@ -23,7 +23,7 @@ @media (max-width: $breakpointSmall) { - .archives > .sidebar, + .archives > .sidebar > .container, .archives > .list > .episode { border-radius: 0; } diff --git a/resources/assets/sass/modules/global/footer.scss b/resources/assets/sass/modules/global/footer.scss index 1a884ca..03255c7 100644 --- a/resources/assets/sass/modules/global/footer.scss +++ b/resources/assets/sass/modules/global/footer.scss @@ -1,4 +1,6 @@ .global-footer { + z-index: 10; + position: relative; margin: 0 auto 0 auto; padding: 0 $paddingLarge $paddingLarge $paddingLarge; width: 100%; diff --git a/resources/assets/sass/modules/index/sidebar.scss b/resources/assets/sass/modules/index/sidebar.scss index c841e29..75e1017 100644 --- a/resources/assets/sass/modules/index/sidebar.scss +++ b/resources/assets/sass/modules/index/sidebar.scss @@ -1,4 +1,8 @@ .archives > .sidebar > .container { + padding-top: $paddingSmall; +} + +.archives > .sidebar .filters { padding: 0 $paddingSmall $paddingSmall $paddingSmall; } @@ -9,9 +13,13 @@ line-height: 18px; } +.archives > .sidebar h2:first-child { + margin-top: 0; +} + /* SHOW */ -.archives > .sidebar > .show { +.archives > .sidebar .show { display: none; } @@ -169,12 +177,68 @@ $circleSize: $inputSize - 10px; +/* MORE */ + +.archives .sidebar .more { + margin-top: $paddingSmall; +} + +.archives .sidebar .more, +.archives .sidebar .more a { + color: $colour-grey; +} + +.archives .sidebar .more p, +.archives .sidebar .more a { + font-size: 14px; + line-height: 14px; +} + +.archives .sidebar .more p { + margin-top: 0; +} + +.archives .sidebar .more a:hover { + color: $colour-greyDark; +} + +.archives .sidebar .more .list { + margin-top: 10px; +} + +.archives .sidebar .more .list > li { + margin-bottom: 10px; +} + +.archives .sidebar .more .list > li:last-child { + margin-bottom: 0; +} + +.archives .sidebar .more .list > li > a { + display: block; + padding-left: 15px + 5px; + background: left center no-repeat transparent; + background-size: contain; +} + +$list: "rss", "itunes", "google"; + +@each $service in $list { + + .archives .sidebar .more .list > li.#{$service} > a { + background-image: url("../../images/global/more-icon-#{$service}.svg"); + } + +} + + + /* RESPONSIVE */ @media (max-width: $breakpointSmall) { - .archives > .sidebar { - margin-bottom: $paddingSmall; + .archives > .sidebar > .container { + padding-top: 0; } .archives > .sidebar h2 { @@ -184,17 +248,13 @@ $circleSize: $inputSize - 10px; line-height: 14px; } - .archives > .sidebar > .container { - display: none; - } - /* SHOW */ - .archives > .sidebar > .container { + .archives > .sidebar .filters { display: none; } - .archives > .sidebar.active > .container { + .archives > .sidebar.active .filters { display: block; } @@ -202,7 +262,7 @@ $circleSize: $inputSize - 10px; $showIconWidth: 12px; $showIconHeight: 14px; - .archives > .sidebar > .show { + .archives > .sidebar .show { position: relative; display: block; padding: 0 ($paddingSmall + $showIconWidth) 0 $paddingSmall; @@ -210,30 +270,30 @@ $circleSize: $inputSize - 10px; color: inherit; } - .archives > .sidebar.active > .show { + .archives > .sidebar.active .show { margin-bottom: 10px; } - .archives > .sidebar > .show > .wrapper { + .archives > .sidebar .show > .wrapper { position: relative; } - .archives > .sidebar.active > .show .text.open, - .archives > .sidebar > .show .text.close { + .archives > .sidebar.active .show .text.open, + .archives > .sidebar .show .text.close { display: none; } - .archives > .sidebar.active > .show .text.close { + .archives > .sidebar.active .show .text.close { display: block; } - .archives > .sidebar > .show:after, - .archives > .sidebar > .show > .wrapper { + .archives > .sidebar .show:after, + .archives > .sidebar .show > .wrapper { top: 50%; @include transform(translateY(-50%)); } - .archives > .sidebar > .show:after { + .archives > .sidebar .show:after { content: ""; position: absolute; right: $paddingSmall; @@ -338,6 +398,32 @@ $circleSize: $inputSize - 10px; height: $circleSize; } + /* MORE */ + + .archives .sidebar .more { + margin-bottom: $paddingSmall; + } + + .archives .sidebar .more p, + .archives .sidebar .more .list { + text-align: center; + } + + .archives .sidebar .more .list { + font-size: 0; + line-height: 0; + } + + .archives .sidebar .more .list > li { + display: inline-block; + margin-right: 10px; + margin-bottom: 0; + } + + .archives .sidebar .more .list > li:last-child { + margin-right: 0; + } + } @@ -365,8 +451,10 @@ $circleSize: $inputSize - 10px; @media (min-width: $breakpointSmall + 1px) { .archives > .sidebar.sticky { + z-index: 0; position: fixed; top: $paddingLarge; + height: 100%; @include calc(max-height, "100% - #{$paddingLarge * 2}"); overflow: hidden; overflow-y: scroll; diff --git a/resources/views/layouts/about.blade.php b/resources/views/layouts/about.blade.php index 085863e..ae65971 100644 --- a/resources/views/layouts/about.blade.php +++ b/resources/views/layouts/about.blade.php @@ -8,7 +8,7 @@

Steamchat (formerly "Steamcast") is a podcast that hosts discussions about Valve, Steam, digital distribution, PC games and other related subjects such as the art and design of video games and other topical video game-related subjects.

-

Steamchat is an audio-only podcast, with episodes lasting for around an hour in length. New episodes are published on our website, on our RSS feed, and on the iTunes Store.

+

Steamchat is an audio-only podcast, with episodes lasting for around an hour in length. New episodes are published on our website, our RSS feed, the iTunes Store, and the Google Play Store.

History

@@ -24,7 +24,7 @@

We love to hear from our listeners, and have always kept our promise to read and discuss every email and message we get on the show. If you would like for us to discuss something on the show, or just want to get in touch, please feel free to send us an email at podcast@thesteamchat.com.

-

The source code for this website is also avaliable on GitHub.

+

The source code for this website is also avaliable on GitHub.

diff --git a/resources/views/layouts/episode.blade.php b/resources/views/layouts/episode.blade.php index 349a46a..ebdccdd 100644 --- a/resources/views/layouts/episode.blade.php +++ b/resources/views/layouts/episode.blade.php @@ -16,13 +16,14 @@

{{ $episode->getTitle(false) }}

{{ date_format(new DateTime($episode->release_date), 'jS F Y') }}

+

{{ $episode->description }}

@isset($episode->transcript_url)
A transcript for this episode is avaliable - +
View
@@ -37,20 +38,33 @@ diff --git a/resources/views/layouts/index.blade.php b/resources/views/layouts/index.blade.php index ed0c569..8c97ac9 100644 --- a/resources/views/layouts/index.blade.php +++ b/resources/views/layouts/index.blade.php @@ -12,52 +12,74 @@
@@ -69,7 +91,7 @@ @foreach($episodes as $episode) -
+

{{ $episode->getTitle(false) }}

{{ date_format(new DateTime($episode->release_date), 'jS F Y') }} – {{ $episode->file_duration }} @isset($episode->transcript_url)– Transcript avaliable @endisset

diff --git a/resources/views/misc/podcast-feed.blade.php b/resources/views/misc/podcast-feed.blade.php new file mode 100644 index 0000000..d775557 --- /dev/null +++ b/resources/views/misc/podcast-feed.blade.php @@ -0,0 +1,43 @@ + + + + Steamchat + https://www.thesteamchat.com + en-us + © Steamchat + Steamchat is a podcast on all things Valve + Sam, Saurabh, Brad + Steamchat is a podcast that hosts discussions about Valve, Steam, digital distribution, PC games and other related subjects such as the art and design of video games and other topical video game-related subjects. + Steamchat is a podcast that hosts discussions about Valve, Steam, digital distribution, PC games and other related subjects such as the art and design of video games and other topical video game-related subjects. + + Samuel Kindler + sam@flamov.com + + + + + + + + + no + + @foreach ($episodes as $episode) + + + Steamchat {{ $episode->getTitle(false) }} + Steamchat + {{ $episode->description }} + {{ $episode->description }} + + {{ $episode->file_url }} + {{ date_format(new \DateTime($episode->release_date), 'D, j M o') }} 00:00:00 GMT + {{ $episode->file_duration }} + Steam, Steampowered, Steam Powered, Valve, Video Games, Computer Games, Half-Life 2, Half-Life 2 Episode 1, Half-Life 2: Episode 2, Half-Life 2: Episode 3, Team Fortress 2, Left 4 Dead, Left 4 Dead 2 + + + @endforeach + + + + \ No newline at end of file diff --git a/resources/views/partials/footer.blade.php b/resources/views/partials/footer.blade.php index 5856e15..3ab0617 100644 --- a/resources/views/partials/footer.blade.php +++ b/resources/views/partials/footer.blade.php @@ -5,7 +5,7 @@

This website is not affiliated with, maintained, authorized, endorsed or sponsored by Valve Corporation, or any of its affiliates. All product and company names, logos, and brands are trademarks (™) or registered (®) trademarks of their respective owners.

- + diff --git a/resources/views/partials/header.blade.php b/resources/views/partials/header.blade.php index a0099d3..af56674 100644 --- a/resources/views/partials/header.blade.php +++ b/resources/views/partials/header.blade.php @@ -43,7 +43,7 @@ @endif @endif - + diff --git a/routes/web.php b/routes/web.php index cd7981b..f6a6a08 100644 --- a/routes/web.php +++ b/routes/web.php @@ -33,8 +33,11 @@ // Get all unique release date years $years = Episode::where('active', true) ->select(DB::raw('DISTINCT YEAR(release_date)')) - ->orderBy('release_date', 'desc') - ->get(); + ->get() + ->toArray(); + + // Sort array of years in descending order + rsort($years); return view('layouts.index', [ 'episodes' => $episodes, @@ -108,31 +111,26 @@ })->name('about'); -// RSS feed XML -Route::get('/steamchat_feed_mp3.xml', function(){ +// RSS feed XML (MP3) +Route::get('/steamchat_feed_mp3.xml', function () { $episodes = Episode::orderBy('release_date', 'desc') ->where('active', true) ->get(); - PodcastFeed::setHeader([ - 'link' => route('index'), - 'image' => asset('images/global/og_image.png') + $content = view('misc.podcast-feed', [ + 'episodes' => $episodes ]); - foreach($episodes as $episode) { - PodcastFeed::addMedia([ - 'title' => $episode->title, - 'description' => $episode->description, - 'publish_at' => $episode->release_date, - 'guid' => $episode->file_url, - 'url' => $episode->file_url, - 'type' => 'audio/mpeg', - 'duration' => $episode->file_duration - ]); - } + return response($content)->withHeaders([ + 'Content-Type' => 'text/xml' + ]); + +})->name('feed-mp3'); + +// RSS feed XML (M4A) +Route::get('/steamchat_feed_m4a.xml', function () { - return Response::make(PodcastFeed::toString()) - ->header('Content-Type', 'text/xml'); + return redirect()->route('feed-mp3'); -})->name('feed'); +})->name('feed-m4a'); \ No newline at end of file