From 6f88daf695b4cba39565b7ea305b927ad472cf85 Mon Sep 17 00:00:00 2001 From: rob Date: Tue, 27 Sep 2022 00:36:04 -0400 Subject: [PATCH] Shing/Venue channel feed integration (sidebar/home) --- app/controllers/home.js | 2 + app/services/venue.js | 66 +++++++++++++++++++++++++++ app/views/author/index.pug | 8 ++-- app/views/components/navbar.pug | 10 ++-- app/views/components/off-canvas.pug | 2 +- app/views/components/page-sidebar.pug | 28 +++++++++++- app/views/venue/embed.pug | 3 +- 7 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 app/services/venue.js diff --git a/app/controllers/home.js b/app/controllers/home.js index b19484f..3217b85 100644 --- a/app/controllers/home.js +++ b/app/controllers/home.js @@ -24,6 +24,8 @@ class HomeController extends SiteController { dtp.app.use('/', router); router.use(this.dtp.services.gabTV.channelMiddleware()); + router.use(this.dtp.services.venue.channelMiddleware()); + router.use(async (req, res, next) => { res.locals.currentView = 'home'; return next(); diff --git a/app/services/venue.js b/app/services/venue.js new file mode 100644 index 0000000..66bc3ba --- /dev/null +++ b/app/services/venue.js @@ -0,0 +1,66 @@ +// venue.js +// Copyright (C) 2022 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const fetch = require('node-fetch'); // jshint ignore:line + +const CACHE_DURATION = 60 * 5; + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class VenueService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + channelMiddleware ( ) { + return async (req, res, next) => { + try { + if (!res.locals.site || !res.locals.site.shingChannelSlug) { + return next(); + } + res.locals.shingChannelFeed = await this.getChannelFeed(res.locals.site.shingChannelSlug, { allowCache: true }); + return next(); + } catch (error) { + this.log.error('failed to populate Shing.tv channel feed', { error }); + return next(); + } + }; + } + + async getChannelFeed (channelSlug, options) { + const { cache: cacheService } = this.dtp.services; + const cacheKey = `venue:ch:${channelSlug}`; + + options = Object.assign({ + allowCache: true, + }, options); + + let json; + if (options.allowCache) { + json = await cacheService.getObject(cacheKey); + if (json) { + return json; + } + } + + const response = await fetch(`https://shing.tv/channel/${channelSlug}/feed/json`); + if (!response.ok) { + throw new SiteError(500, 'Failed to fetch Shing channel feed'); + } + json = await response.json(); + + await cacheService.setObjectEx(cacheKey, CACHE_DURATION, json); + + return json; + } +} + +module.exports = { + slug: 'venue', + name: 'venue', + create: (dtp) => { return new VenueService(dtp); }, +}; \ No newline at end of file diff --git a/app/views/author/index.pug b/app/views/author/index.pug index ed34e8a..be9710a 100644 --- a/app/views/author/index.pug +++ b/app/views/author/index.pug @@ -36,10 +36,10 @@ block content div(class="uk-width-1-1 uk-width-2-3@m") +renderSectionTitle('Recent Comments', { url: '/author/comments', title: 'See All', label: 'SEE ALL' }) - ul.uk-list.uk-list-divider - each comment in comments - li - .uk-tile.uk-tile-default.uk-padding-small.uk-padding-remove-horizontal + .uk-tile.uk-tile-default.uk-tile-small + ul#post-comment-list.uk-list.uk-list-divider.uk-list-large + each comment in comments + li .uk-margin a(href=`/post/${comment.resource.slug}`).uk-display-block.uk-link-reset +renderPostSummary(comment.resource) diff --git a/app/views/components/navbar.pug b/app/views/components/navbar.pug index bdbd20a..ca5e25d 100644 --- a/app/views/components/navbar.pug +++ b/app/views/components/navbar.pug @@ -16,15 +16,17 @@ nav(uk-navbar).uk-navbar-container.uk-position-fixed.uk-position-top li(class={ 'uk-active': currentView === 'home' }) a(href="/", title= "Home") +renderButtonIcon('fa-home', 'Home') - li(class={ 'uk-active': currentView === 'chat' }) - a(href="/chat", title= "chat") - +renderButtonIcon('fa-comment-alt', 'Chat') + + if user + li(class={ 'uk-active': currentView === 'chat' }) + a(href="/chat", title= "chat") + +renderButtonIcon('fa-comment-alt', 'Chat') if site.shingWidgetKey && site.shingChannelSlug li(class={ 'uk-active': currentView === 'venue' }) a(href="/venue", title= "Live") span - img(src="https://shing.tv/img/icon/shing.tv/icon-32x32.png") + i.fas.fa-tv span(class="uk-visible@m").uk-margin-small-left Live each menuItem in mainMenu diff --git a/app/views/components/off-canvas.pug b/app/views/components/off-canvas.pug index 40cb6a4..09fc725 100644 --- a/app/views/components/off-canvas.pug +++ b/app/views/components/off-canvas.pug @@ -23,7 +23,7 @@ mixin renderMenuItem (iconClass, label) if site.shingWidgetKey li(class={ "uk-active": (currentView === 'venue') }) a(href='/venue').uk-display-block - +renderMenuItem('fa-home', 'Watch Live') + +renderMenuItem('fa-tv', 'Watch Live') each menuItem in mainMenu li(class={ 'uk-active': (pageSlug === menuItem.slug) }) diff --git a/app/views/components/page-sidebar.pug b/app/views/components/page-sidebar.pug index 9c5da78..d0916c8 100644 --- a/app/views/components/page-sidebar.pug +++ b/app/views/components/page-sidebar.pug @@ -13,13 +13,37 @@ mixin renderSidebarEpisode(episode) .uk-text-small Posted: #{moment(episode.date_modified).format("MMM DD YYYY HH:MM a")} mixin renderPageSidebar ( ) + //- + //- Announcements + //- if Array.isArray(announcements) && (announcements.length > 0) ul.uk-list.uk-margin each announcement in announcements li +renderAnnouncement(announcement) - //- Gab TV 3 Most Recent Episodes + //- + //- Shing.tv Channel Integration + //- + if shingChannelFeed && Array.isArray(shingChannelFeed.items) && (shingChannelFeed.items.length > 0) + .uk-margin + +renderSectionTitle(shingChannelFeed.title, { + label: 'Tune In', + title: shingChannelFeed.title, + url: '/venue', + }) + ul.uk-list + each item in shingChannelFeed.items.slice(0, 3) + li + a(href= item.url).uk-display-block + .uk-card.uk-card-default.uk-card-small + img(src= item.image.url).responsive + .uk-card-body + .uk-text-bold.uk-text-truncate= item.title + .uk-text-small!= item.summary + //- + //- Gab TV channel integration + //- if gabTvChannel .uk-margin +renderSectionTitle('Gab TV', { @@ -32,7 +56,9 @@ mixin renderPageSidebar ( ) li +renderSidebarEpisode(episode) + //- //- Newsletter Signup + //- div(uk-sticky={ offset: 60, bottom: '#dtp-content-grid' }, style="z-index: initial;").uk-margin +renderSectionTitle('Mailing List') form(method="post", action="/newsletter", onsubmit="return dtp.app.submitForm(event, 'Subscribe to newsletter');").uk-form diff --git a/app/views/venue/embed.pug b/app/views/venue/embed.pug index 893344c..3c0c4ff 100644 --- a/app/views/venue/embed.pug +++ b/app/views/venue/embed.pug @@ -1,5 +1,6 @@ extends ../layouts/main block content - - var shingBaseUrl = (process.env.NODE_ENV === 'production') ? 'https://shing.tv' : 'http://localhost:3333'; + //- - var shingBaseUrl = (process.env.NODE_ENV === 'production') ? 'https://shing.tv' : 'http://localhost:3333'; + - var shingBaseUrl = 'https://shing.tv'; iframe(src= `${shingBaseUrl}/channel/${site.shingChannelSlug}/embed/venue?k=${site.shingWidgetKey}`, style="width: 100%; height: 720px;", allowfullscreen) \ No newline at end of file