feat: view queries in; media updated
This commit is contained in:
parent
08e2c2ff3f
commit
057d75f863
49 changed files with 578 additions and 353 deletions
|
@ -1,57 +1,4 @@
|
|||
import { DateTime } from 'luxon'
|
||||
import { shuffleArray } from '../utilities/index.js'
|
||||
|
||||
export default {
|
||||
featuredWatching: (watching, count) => {
|
||||
const data = [...watching]
|
||||
return shuffleArray(data).slice(0, count)
|
||||
},
|
||||
normalizeMedia: (media, limit) => {
|
||||
const mediaData = limit ? media.slice(0, limit) : media
|
||||
return mediaData.map((item) => {
|
||||
let normalized = {
|
||||
title: item['title'],
|
||||
image: item['image'],
|
||||
url: item['url'],
|
||||
type: item['type']
|
||||
}
|
||||
|
||||
switch (item['type']) {
|
||||
case 'artist':
|
||||
normalized.alt = `${item['plays']} plays of ${item['title']}`
|
||||
normalized.subtext = `${item['plays']} plays`
|
||||
break
|
||||
case 'album':
|
||||
normalized.alt = `${item['title']} by ${item['artist']}`
|
||||
normalized.subtext = `${item['artist']}`
|
||||
break
|
||||
case 'album-release':
|
||||
normalized.alt = `${item['title']} by ${item['artist']['name']}`
|
||||
normalized.subtext = `${item['artist']['name']} / ${item['release_date_formatted']}`
|
||||
break
|
||||
case 'movie':
|
||||
normalized.alt = item['title']
|
||||
normalized.rating = item['rating']
|
||||
normalized.favorite = item['favorite']
|
||||
normalized.subtext = item.rating ? `${item['rating']} (${item['year']})` : `(${item['year']})`
|
||||
break
|
||||
case 'book':
|
||||
normalized.title = `${item['title']} by ${item['author']}`
|
||||
if (item['rating']) {
|
||||
normalized.rating = item['rating']
|
||||
normalized.subtext = item['rating']
|
||||
}
|
||||
break
|
||||
case 'tv':
|
||||
normalized.alt = item['formatted_episode']
|
||||
normalized.subtext = item['formatted_episode']
|
||||
break
|
||||
}
|
||||
|
||||
return normalized
|
||||
})
|
||||
},
|
||||
calculatePlayPercentage: (plays, mostPlayed) => `${plays/mostPlayed * 100}%`,
|
||||
bookStatus: (books, status) => books.filter(book => book['status'] === status),
|
||||
bookFavorites: (books) => books.filter(book => book.favorite === true),
|
||||
bookYearLinks: (years) => years.sort((a, b) => b.value - a.value).map((year, index) => {
|
||||
|
@ -71,7 +18,9 @@ export default {
|
|||
if (dataSlice.length === 0) return null
|
||||
if (dataSlice.length === 1) {
|
||||
const item = dataSlice[0]
|
||||
if (type === 'genre' || type === 'artist') {
|
||||
if (type === 'genre') {
|
||||
return `<a href="${item['genre_url']}">${item['genre_name']}</a>`
|
||||
} else if (type === 'artist') {
|
||||
return `<a href="${item['url']}">${item['name']}</a>`
|
||||
} else if (type === 'book') {
|
||||
return `<a href="${item['url']}">${item['title']}</a>`
|
||||
|
@ -79,7 +28,9 @@ export default {
|
|||
}
|
||||
|
||||
const allButLast = dataSlice.slice(0, -1).map(item => {
|
||||
if (type === 'genre' || type === 'artist') {
|
||||
if (type === 'genre') {
|
||||
return `<a href="${item['genre_url']}">${item['genre_name']}</a>`
|
||||
} else if (type === 'artist') {
|
||||
return `<a href="${item['url']}">${item['name']}</a>`
|
||||
} else if (type === 'book') {
|
||||
return `<a href="${item['url']}">${item['title']}</a>`
|
||||
|
@ -89,7 +40,9 @@ export default {
|
|||
let last
|
||||
const lastItem = dataSlice[dataSlice.length - 1]
|
||||
|
||||
if (type === 'genre' || type === 'artist') {
|
||||
if (type === 'genre') {
|
||||
last = `<a href="${lastItem['genre_url']}">${lastItem['genre_name']}</a>`
|
||||
} else if (type === 'artist') {
|
||||
last = `<a href="${lastItem['url']}">${lastItem['name']}</a>`
|
||||
} else if (type === 'book') {
|
||||
last = `<a href="${lastItem['url']}">${lastItem['title']}</a>`
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "coryd.dev",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "coryd.dev",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cdransf/api-text": "^1.5.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "coryd.dev",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"description": "The source for my personal site. Built using 11ty (and other tools).",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
@ -3,69 +3,71 @@ a:active > .watching.hero::after {
|
|||
border-color: var(--accent-color-hover);
|
||||
}
|
||||
|
||||
.icon-link + .watching.grid {
|
||||
.watching.hero {
|
||||
position: relative;
|
||||
display: flex;
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
|
||||
& img {
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
border-radius: var(--border-radius-slight);
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
& .meta-text {
|
||||
color: white;
|
||||
position: absolute;
|
||||
left: var(--spacing-sm);
|
||||
bottom: var(--spacing-sm);
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& .header {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
& .subheader {
|
||||
font-size: var(--font-size-sm);
|
||||
display: inline-flex;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
& .header,
|
||||
& .subheader {
|
||||
line-height: var(--line-height-md);
|
||||
text-shadow: var(--text-shadow-default);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
content: '';
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-shadow: var(--box-shadow-media);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: var(--border-default);
|
||||
border-radius: var(--border-radius-slight);
|
||||
transition: border-color var(--transition-duration-default) var(--transition-ease-in-out);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-link + .poster.grid {
|
||||
margin-top: var(--spacing-base);
|
||||
}
|
||||
|
||||
.watching {
|
||||
.poster {
|
||||
& img {
|
||||
border-radius: var(--border-radius-slight);
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.hero {
|
||||
position: relative;
|
||||
display: flex;
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
|
||||
& img {
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
border-radius: var(--border-radius-slight);
|
||||
}
|
||||
|
||||
& .meta-text {
|
||||
color: white;
|
||||
position: absolute;
|
||||
left: var(--spacing-sm);
|
||||
bottom: var(--spacing-sm);
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& .header {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
& .subheader {
|
||||
font-size: var(--font-size-sm);
|
||||
display: inline-flex;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
& .header,
|
||||
& .subheader {
|
||||
line-height: var(--line-height-md);
|
||||
text-shadow: var(--text-shadow-default);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
content: '';
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-shadow: var(--box-shadow-media);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: var(--border-default);
|
||||
border-radius: var(--border-radius-slight);
|
||||
transition: border-color var(--transition-duration-default) var(--transition-ease-in-out);
|
||||
}
|
||||
}
|
||||
|
||||
&.grid {
|
||||
&.media-grid {
|
||||
display: grid;
|
||||
gap: var(--spacing-sm);
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
|
|
@ -13,7 +13,6 @@ const fetchDataFromView = async (viewName) => {
|
|||
const { data, error } = await supabase
|
||||
.from(viewName)
|
||||
.select('*')
|
||||
.order('listened_at', { ascending: false })
|
||||
.range(rangeStart, rangeStart + PAGE_SIZE - 1)
|
||||
|
||||
if (error) {
|
||||
|
@ -23,7 +22,7 @@ const fetchDataFromView = async (viewName) => {
|
|||
|
||||
if (data.length === 0) break
|
||||
|
||||
rows = rows.concat(data)
|
||||
rows = [...rows, ...data]
|
||||
|
||||
if (data.length < PAGE_SIZE) break
|
||||
rangeStart += PAGE_SIZE
|
||||
|
@ -32,113 +31,70 @@ const fetchDataFromView = async (viewName) => {
|
|||
return rows
|
||||
}
|
||||
|
||||
const aggregateData = (data, groupByField, groupByType) => {
|
||||
const aggregation = {}
|
||||
|
||||
data.forEach(item => {
|
||||
const key = item[groupByField]
|
||||
if (!aggregation[key]) {
|
||||
let imageField = ''
|
||||
|
||||
switch (groupByType) {
|
||||
case 'artist':
|
||||
imageField = item['artist_art']
|
||||
break
|
||||
case 'album':
|
||||
imageField = item['album_art']
|
||||
break
|
||||
case 'track':
|
||||
imageField = item['album_art']
|
||||
break
|
||||
default:
|
||||
imageField = ''
|
||||
}
|
||||
|
||||
aggregation[key] = {
|
||||
title: item[groupByField],
|
||||
plays: 0,
|
||||
url: item['artist_url'],
|
||||
image: imageField,
|
||||
genre: item['artist_genres'],
|
||||
type: groupByType
|
||||
}
|
||||
|
||||
if (groupByType === 'track' || groupByType === 'album') aggregation[key]['artist'] = item['artist_name']
|
||||
}
|
||||
|
||||
aggregation[key].plays++
|
||||
})
|
||||
|
||||
return Object.values(aggregation).sort((a, b) => b['plays'] - a['plays']).map((item, index) => ({ ...item, rank: index + 1 }))
|
||||
}
|
||||
|
||||
const buildRecents = (data) => {
|
||||
return data.map(listen => ({
|
||||
title: listen['track_name'],
|
||||
artist: listen['artist_name'],
|
||||
url: listen['artist_url'],
|
||||
timestamp: listen['listened_at'],
|
||||
image: listen['album_art'],
|
||||
type: 'track'
|
||||
})).sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
|
||||
}
|
||||
|
||||
const aggregateGenres = (data) => {
|
||||
const genreAggregation = {}
|
||||
|
||||
data.forEach(item => {
|
||||
const genre = item['genre_name'] || ''
|
||||
const genreUrl = item['genre_url'] || ''
|
||||
|
||||
if (!genreAggregation[genre]) {
|
||||
genreAggregation[genre] = {
|
||||
name: genre,
|
||||
url: genreUrl,
|
||||
plays: 0,
|
||||
type: 'genre'
|
||||
}
|
||||
}
|
||||
|
||||
genreAggregation[genre]['plays']++
|
||||
})
|
||||
|
||||
return Object.values(genreAggregation).sort((a, b) => b['plays'] - a['plays'])
|
||||
}
|
||||
|
||||
export default async function () {
|
||||
export default async function fetchMusicData() {
|
||||
try {
|
||||
const [recentTracks, monthTracks, threeMonthTracks] = await Promise.all([
|
||||
const [
|
||||
recentTracks,
|
||||
weekTracks,
|
||||
weekArtists,
|
||||
weekAlbums,
|
||||
weekGenres,
|
||||
monthTracks,
|
||||
monthArtists,
|
||||
monthAlbums,
|
||||
monthGenres,
|
||||
threeMonthTracks,
|
||||
threeMonthArtists,
|
||||
threeMonthAlbums,
|
||||
threeMonthGenres,
|
||||
] = await Promise.all([
|
||||
fetchDataFromView('recent_tracks'),
|
||||
fetchDataFromView('week_tracks'),
|
||||
fetchDataFromView('week_artists'),
|
||||
fetchDataFromView('week_albums'),
|
||||
fetchDataFromView('week_genres'),
|
||||
fetchDataFromView('month_tracks'),
|
||||
fetchDataFromView('three_month_tracks')
|
||||
fetchDataFromView('month_artists'),
|
||||
fetchDataFromView('month_albums'),
|
||||
fetchDataFromView('month_genres'),
|
||||
fetchDataFromView('three_month_tracks'),
|
||||
fetchDataFromView('three_month_artists'),
|
||||
fetchDataFromView('three_month_albums'),
|
||||
fetchDataFromView('three_month_genres'),
|
||||
])
|
||||
|
||||
return {
|
||||
recent: buildRecents(recentTracks),
|
||||
recent: recentTracks,
|
||||
week: {
|
||||
artists: aggregateData(recentTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(recentTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(recentTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(recentTracks),
|
||||
totalTracks: recentTracks.length.toLocaleString('en-US')
|
||||
tracks: weekTracks,
|
||||
artists: weekArtists,
|
||||
albums: weekAlbums,
|
||||
genres: weekGenres,
|
||||
totalTracks: weekTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
month: {
|
||||
artists: aggregateData(monthTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(monthTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(monthTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(monthTracks),
|
||||
totalTracks: monthTracks.length.toLocaleString('en-US')
|
||||
tracks: monthTracks,
|
||||
artists: monthArtists,
|
||||
albums: monthAlbums,
|
||||
genres: monthGenres,
|
||||
totalTracks: monthTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
threeMonth: {
|
||||
artists: aggregateData(threeMonthTracks, 'artist_name', 'artist'),
|
||||
albums: aggregateData(threeMonthTracks, 'album_name', 'album'),
|
||||
tracks: aggregateData(threeMonthTracks, 'track_name', 'track'),
|
||||
genres: aggregateGenres(threeMonthTracks),
|
||||
totalTracks: threeMonthTracks.length.toLocaleString('en-US')
|
||||
}
|
||||
tracks: threeMonthTracks,
|
||||
artists: threeMonthArtists,
|
||||
albums: threeMonthAlbums,
|
||||
genres: threeMonthGenres,
|
||||
totalTracks: threeMonthTracks
|
||||
.reduce((acc, track) => acc + track.plays, 0)
|
||||
.toLocaleString('en-US'),
|
||||
},
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in fetching and processing music data:', error)
|
||||
console.error('Error fetching and processing music data:', error)
|
||||
return {}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ export default async function () {
|
|||
image: show['episode']['image'],
|
||||
backdrop: show['episode']['backdrop'],
|
||||
last_watched_at: show['episode']['last_watched_at'],
|
||||
grid: show['grid'],
|
||||
type: 'tv'
|
||||
}))
|
||||
|
||||
|
|
|
@ -1,44 +1,51 @@
|
|||
{%- assign hidePagination = count or data.pages.size <= 1 -%}
|
||||
{%- assign media = data.items | default: data | normalizeMedia: count -%}
|
||||
<div class="media-grid {% if shape == 'square' -%}square{%- else -%}vertical{%- endif -%}">
|
||||
{%- for item in media | default: media.size -%}
|
||||
{%- capture alt -%}{{ item.title | escape }} ({{ item.year }}){% endcapture %}
|
||||
{%- assign alt = item.alt | strip | escape -%}
|
||||
<a href="{{ item.url }}" title="{{ alt }}">
|
||||
{%- assign pageCount = pagination.pages.size | default: 0 -%}
|
||||
{%- assign hidePagination = pageCount <= 1 -%}
|
||||
<div class="media-grid {% if shape == 'poster' -%}poster{%- elsif shape == 'square' -%}square{%- elsif shape == 'vertical' -%}vertical{%- endif -%}">
|
||||
{%- for item in data limit: count -%}
|
||||
{%- assign alt = item.grid.alt | strip | escape -%}
|
||||
<a href="{{ item.grid.url }}" title="{{ alt }}">
|
||||
<div class="item">
|
||||
<div class="meta-text">
|
||||
{%- if item.title -%}
|
||||
<div class="header">{{ item.title }}</div>
|
||||
{%- endif -%}
|
||||
{%- if item.plays -%}
|
||||
<div class="subheader">{{ item.plays }} plays</div>
|
||||
{%- elsif item.subtext -%}
|
||||
<div class="subheader">{{ item.subtext }}</div>
|
||||
{%- endif -%}
|
||||
<div class="header">{{ item.grid.title }}</div>
|
||||
<div class="subheader">{{ item.grid.subtext }}</div>
|
||||
</div>
|
||||
{%- assign loadingStrategy = loading | default: 'lazy' -%}
|
||||
{%- if shape == 'square' -%}
|
||||
{%- if shape == 'poster' -%}
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.image }}?class=squaresm&type=webp 200w,
|
||||
https://cdn.coryd.dev{{ item.image }}?class=squaremd&type=webp 400w
|
||||
https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannersm&type=webp 256w,
|
||||
https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannermd&type=webp 512w
|
||||
"
|
||||
sizes="(max-width: 450px) 256px, 512px"
|
||||
src="https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannersm&type=webp"
|
||||
alt="{{ alt }}"
|
||||
loading="{{ loadingStrategy }}"
|
||||
decoding="async"
|
||||
width="256"
|
||||
height="170"
|
||||
/>
|
||||
{%- elsif shape == 'square' -%}
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.grid.image }}?class=squaresm&type=webp 200w,
|
||||
https://cdn.coryd.dev{{ item.grid.image }}?class=squaremd&type=webp 400w
|
||||
"
|
||||
sizes="(max-width: 450px) 200px, 400px"
|
||||
src="https://cdn.coryd.dev{{ item.image }}?class=squaresm&type=webp"
|
||||
src="https://cdn.coryd.dev{{ item.grid.image }}?class=squaresm&type=webp"
|
||||
alt="{{ alt }}"
|
||||
loading="{{ loadingStrategy }}"
|
||||
decoding="async"
|
||||
width="200"
|
||||
height="200"
|
||||
/>
|
||||
{%- else -%}
|
||||
{%- elsif shape == 'vertical' -%}
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.image }}?class=verticalsm&type=webp 200w,
|
||||
https://cdn.coryd.dev{{ item.image }}?class=verticalmd&type=webp 400w
|
||||
https://cdn.coryd.dev{{ item.grid.image }}?class=verticalsm&type=webp 200w,
|
||||
https://cdn.coryd.dev{{ item.grid.image }}?class=verticalmd&type=webp 400w
|
||||
"
|
||||
sizes="(max-width: 450px) 200px, 400px"
|
||||
src="https://cdn.coryd.dev{{ item.image }}?class=verticalsm&type=webp"
|
||||
src="https://cdn.coryd.dev{{ item.grid.image }}?class=verticalsm&type=webp"
|
||||
alt="{{ alt }}"
|
||||
loading="{{ loadingStrategy }}"
|
||||
decoding="async"
|
||||
|
@ -51,5 +58,5 @@
|
|||
{%- endfor -%}
|
||||
</div>
|
||||
{%- unless hidePagination -%}
|
||||
{% render "partials/nav/paginator.liquid", pagination:data %}
|
||||
{% render "partials/nav/paginator.liquid", pagination:pagination %}
|
||||
{%- endunless -%}
|
|
@ -1,22 +1,20 @@
|
|||
<div class="music-chart">
|
||||
{%- assign items = data.items | default: data -%}
|
||||
<ol type="1">
|
||||
{%- for item in items limit: count | default: items.size -%}
|
||||
{%- assign playTotal = playTotal | default: mostPlayed -%}
|
||||
{%- assign percentage = item.plays | calculatePlayPercentage: playTotal -%}
|
||||
<li value="{{ item.rank }}">
|
||||
{%- for item in data limit: count -%}
|
||||
{%- assign percentage = item.chart.percentage | append: '%' -%}
|
||||
<li value="{{ item.chart.rank }}">
|
||||
<div class="item">
|
||||
<div class="info">
|
||||
<a class="title" href="{{ item.url }}">{{ item.title }}</a>
|
||||
<a class="title" href="{{ item.chart.url }}">{{ item.chart.title }}</a>
|
||||
{%- capture playsLabel -%}
|
||||
{%- if item.plays > 1 -%}
|
||||
{%- if item.chart.plays > 1 -%}
|
||||
plays
|
||||
{%- else -%}
|
||||
play
|
||||
{%- endif -%}
|
||||
{%- endcapture -%}
|
||||
<span class="subtext">{{ item.artist }}</span>
|
||||
<span class="subtext">{{ item.plays }} {{ playsLabel }}</span>
|
||||
<span class="subtext">{{ item.chart.artist }}</span>
|
||||
<span class="subtext">{{ item.chart.plays }} {{ playsLabel }}</span>
|
||||
</div>
|
||||
{% render "partials/media/progress-bar.liquid", percentage:percentage %}
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
<div class="music-chart">
|
||||
{%- for item in data limit: 10 -%}
|
||||
{%- capture alt -%}{{ item.title | escape }} by {{ item.artist }}{%- endcapture -%}
|
||||
<div class="item">
|
||||
<div class="meta">
|
||||
<a href="{{ item.url }}">
|
||||
<a href="{{ item.chart.url }}">
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.image }}?class=w50&type=webp 50w,
|
||||
https://cdn.coryd.dev{{ item.image }}?class=w100&type=webp 100w
|
||||
https://cdn.coryd.dev{{ item.chart.image }}?class=w50&type=webp 50w,
|
||||
https://cdn.coryd.dev{{ item.chart.image }}?class=w100&type=webp 100w
|
||||
"
|
||||
sizes="(max-width: 450px) 50px, 100px"
|
||||
src="https://cdn.coryd.dev{{ item.image }}?class=w50&type=webp"
|
||||
alt="{{ alt }}"
|
||||
src="https://cdn.coryd.dev{{ item.chart.image }}?class=w50&type=webp"
|
||||
alt="{{ item.chart.alt }}"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
width="64"
|
||||
|
@ -19,12 +18,12 @@
|
|||
/>
|
||||
</a>
|
||||
<div class="meta-text">
|
||||
<a class="title" href="{{ item.url }}">{{ item.title }}</a>
|
||||
<span class="subtext">{{ item.artist }}</span>
|
||||
<a class="title" href="{{ item.chart.url }}">{{ item.chart.title }}</a>
|
||||
<span class="subtext">{{ item.chart.subtext }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timestamp">
|
||||
{{ item.timestamp | date: "%B %-d, %-I:%M%p", "America/Los_Angeles" }}
|
||||
{{ item.chart.played_at | date: "%B %-d, %-I:%M%p", "America/Los_Angeles" }}
|
||||
</div>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
{%- assign hidePagination = count or data.pages.size <= 1 -%}
|
||||
{%- assign pageCount = pagination.pages.size | default: 0 -%}
|
||||
{%- assign hidePagination = pageCount <= 1 -%}
|
||||
<div class="watching grid">
|
||||
{%- assign items = data.items | default: mediaItems -%}
|
||||
{%- for item in items limit: count -%}
|
||||
{%- capture alt -%}{{ item.title | escape }} ({{ item.year }}){% endcapture %}
|
||||
<a href="{{ item.url }}">
|
||||
{%- for item in data limit: count -%}
|
||||
{%- assign alt = item.grid.grid.alt | strip | escape -%}
|
||||
<a href="{{ item.grid.url }}">
|
||||
<div class="watching item">
|
||||
<div class="meta-text">
|
||||
{%- if item.type == 'movie' -%}
|
||||
<div class="header">{{ item.title }}</div>
|
||||
{%- if item.grid.type == 'movie' -%}
|
||||
<div class="header">{{ item.grid.title }}</div>
|
||||
<div class="subheader">
|
||||
{%- if item.rating -%}
|
||||
<span class="rating"> {{ item.rating }}</span>
|
||||
{%- if item.grid.rating -%}
|
||||
<span class="rating"> {{ item.grid.rating }}</span>
|
||||
{%- endif -%}
|
||||
({{ item.year }})
|
||||
({{ item.grid.year }})
|
||||
</div>
|
||||
{%- else -%}
|
||||
<div class="header">{{ item.title }}</div>
|
||||
<div class="subheader">({{ item.year }})</div>
|
||||
<div class="header">{{ item.grid.title }}</div>
|
||||
<div class="subheader">({{ item.grid.year }})</div>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- assign loadingStrategy = loading | default: 'lazy' -%}
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.backdrop }}?class=bannersm&type=webp 256w,
|
||||
https://cdn.coryd.dev{{ item.backdrop }}?class=bannermd&type=webp 512w
|
||||
https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannersm&type=webp 256w,
|
||||
https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannermd&type=webp 512w
|
||||
"
|
||||
sizes="(max-width: 450px) 256px, 512px"
|
||||
src="https://cdn.coryd.dev{{ item.backdrop }}?class=bannersm&type=webp"
|
||||
src="https://cdn.coryd.dev{{ item.grid.backdrop }}?class=bannersm&type=webp"
|
||||
alt="{{ alt }}"
|
||||
loading="{{ loadingStrategy }}"
|
||||
decoding="async"
|
||||
|
@ -38,5 +38,5 @@
|
|||
{%- endfor -%}
|
||||
</div>
|
||||
{%- unless hidePagination -%}
|
||||
{% render "partials/nav/paginator.liquid", pagination:data %}
|
||||
{% render "partials/nav/paginator.liquid", pagination:pagination %}
|
||||
{%- endunless -%}
|
|
@ -21,4 +21,4 @@ schema: books-year
|
|||
<p>I finished <strong class="highlight-text">{{ bookData.size }} books</strong> in <strong class="highlight-text">{{ year.value }}</strong>.{%- if favoriteBooks %} Among my favorites were {{ favoriteBooks }}.{%- endif -%}</p>
|
||||
{% endif %}
|
||||
<hr />
|
||||
{% render "partials/media/grid.liquid", data:bookData, shape: "vertical", count: 200, loading: "eager" %}
|
||||
{% render "partials/media/grid.liquid", data:bookData, shape:"vertical", count: 200, loading: "eager" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.threeMonth.albums
|
||||
size: 24
|
||||
permalink: "/music/albums/three-months/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.threeMonth.artists[0].image
|
||||
image: music.threeMonth.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.month.albums
|
||||
size: 24
|
||||
permalink: "/music/albums/this-month/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.month.artists[0].image
|
||||
image: music.month.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.week.albums
|
||||
size: 24
|
||||
permalink: "/music/albums/this-week/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.week.artists[0].image
|
||||
image: music.week.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.threeMonth.artists
|
||||
size: 24
|
||||
permalink: "/music/artists/three-months/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.threeMonth.artists[0].image
|
||||
image: music.threeMonth.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.month.artists
|
||||
size: 24
|
||||
permalink: "/music/artists/this-month/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.month.artists[0].image
|
||||
image: music.month.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -6,7 +6,7 @@ pagination:
|
|||
data: music.week.artists
|
||||
size: 24
|
||||
permalink: "/music/artists/this-week/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
|
||||
image: music.week.artists[0].image
|
||||
image: music.week.artists[0].grid.image
|
||||
schema: music
|
||||
---
|
||||
<a class="icon-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
|
||||
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/grid.liquid" data:pagination, shape: "square" %}
|
||||
{% render "partials/media/grid.liquid" data:pagination.items, pagination:pagination shape:"square" %}
|
|
@ -18,14 +18,14 @@ schema: music-index
|
|||
Artists
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.week.artists, shape: "square", count: 8, loading: "eager" %}
|
||||
{% render "partials/media/grid.liquid", data:music.week.artists, shape:"square", count: 8, loading: "eager" %}
|
||||
<h3 id="albums">
|
||||
<a class="icon-link" href="/music/albums/this-week">
|
||||
{% tablericon "vinyl" %}
|
||||
Albums
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.week.albums, shape: "square", count: 8 %}
|
||||
{% render "partials/media/grid.liquid", data:music.week.albums, shape:"square", count: 8 %}
|
||||
<h3 id="tracks">
|
||||
<a class="icon-link" href="/music/tracks/this-week">
|
||||
{% tablericon "playlist" %}
|
||||
|
@ -41,7 +41,7 @@ schema: music-index
|
|||
{% render "partials/media/music/recent", data:music.recent %}
|
||||
</div>
|
||||
<div class="tracks-chart">
|
||||
{% render "partials/media/music/chart.liquid", data:music.week.tracks, mostPlayed:music.week.tracks[0].plays, count: 10 %}
|
||||
{% render "partials/media/music/chart.liquid", data:music.week.tracks, count: 10 %}
|
||||
</div>
|
||||
</div>
|
||||
{% if albumReleases.size > 0 %}
|
||||
|
@ -49,5 +49,5 @@ schema: music-index
|
|||
{% tablericon "calendar-time" %}
|
||||
Anticipated albums
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:albumReleases.upcoming, shape: "square", count: 8 %}
|
||||
{% render "partials/media/grid.liquid", data:albumReleases.upcoming, shape:"square", count: 8 %}
|
||||
{% endif %}
|
|
@ -18,18 +18,18 @@ schema: music-period
|
|||
Artists
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.threeMonth.artists, shape: "square", count: 8, loading: "eager" %}
|
||||
{% render "partials/media/grid.liquid", data:music.threeMonth.artists, shape:"square", count: 8, loading: "eager" %}
|
||||
<h3 id="albums">
|
||||
<a class="icon-link" href="/music/albums/three-months">
|
||||
{% tablericon "vinyl" %}
|
||||
Albums
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.threeMonth.albums, shape: "square", count: 8 %}
|
||||
{% render "partials/media/grid.liquid", data:music.threeMonth.albums, shape:"square", count: 8 %}
|
||||
<h3 id="tracks">
|
||||
<a class="icon-link" href="/music/tracks/three-months">
|
||||
{% tablericon "playlist" %}
|
||||
Tracks
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/music/chart.liquid", data:music.threeMonth.tracks, mostPlayed:music.threeMonth.tracks[0].plays, count: 10 %}
|
||||
{% render "partials/media/music/chart.liquid", data:music.threeMonth.tracks, count: 10 %}
|
|
@ -18,18 +18,18 @@ schema: music-period
|
|||
Artists
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.month.artists, shape: "square", count: 8, loading: "eager" %}
|
||||
{% render "partials/media/grid.liquid", data:music.month.artists, shape:"square", count: 8, loading: "eager" %}
|
||||
<h3 id="albums">
|
||||
<a class="icon-link" href="/music/albums/this-month">
|
||||
{% tablericon "vinyl" %}
|
||||
Albums
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.month.albums, shape: "square", count: 8 %}
|
||||
{% render "partials/media/grid.liquid", data:music.month.albums, shape:"square", count: 8 %}
|
||||
<h3 id="tracks">
|
||||
<a class="icon-link" href="/music/tracks/this-month">
|
||||
{% tablericon "playlist" %}
|
||||
Tracks
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/music/chart.liquid", data:music.month.tracks, mostPlayed:music.month.tracks[0].plays, count: 10 %}
|
||||
{% render "partials/media/music/chart.liquid", data:music.month.tracks, count: 10 %}
|
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination, playTotal: music.threeMonth.tracks[0].plays %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination.items %}
|
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination, playTotal: music.month.tracks[0].plays %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination.items %}
|
|
@ -17,4 +17,4 @@ schema: music
|
|||
<p><a href="/music/concerts">You can also take a look at the concerts I've been to.</a></p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination, playTotal: music.week.tracks[0].plays %}
|
||||
{% render "partials/media/music/chart.liquid" data:pagination.items %}
|
|
@ -14,4 +14,4 @@ schema: favorite-movies
|
|||
<p>These are my favorite movies. There are many like them, but these are mine.</p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/watching/grid.liquid", data:pagination %}
|
||||
{% render "partials/media/grid.liquid", data:pagination.items, pagination:pagination, shape:"poster" %}
|
|
@ -14,4 +14,4 @@ schema: favorite-shows
|
|||
<p>These are my favorite shows. There are many like them, but these are mine.</p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/watching/grid.liquid", data:pagination %}
|
||||
{% render "partials/media/grid.liquid", data:pagination.items, pagination:pagination, shape:"poster" %}
|
|
@ -6,7 +6,7 @@ permalink: "/watching/index.html"
|
|||
updated: "now"
|
||||
schema: watching
|
||||
---
|
||||
{% assign featuredMovie = movies.recentlyWatched | featuredWatching: 1 | first %}
|
||||
{% assign featuredMovie = movies.recentlyWatched | shuffleArray | first %}
|
||||
<h2 class="watching">{{ title }}</h2>
|
||||
{% render "partials/media/watching/hero.liquid" movie:featuredMovie %}
|
||||
<p>Here's all of the TV and movies I've been watching presented in what is (hopefully) an organized fashion.</p>
|
||||
|
@ -18,27 +18,27 @@ schema: watching
|
|||
Recent movies
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:movies.recentlyWatched, shape: "vertical", count: 6 %}
|
||||
{% render "partials/media/grid.liquid", data:movies.recentlyWatched, shape:"vertical", count: 6 %}
|
||||
<h3 id="tv">
|
||||
<a class="icon-link" href="/watching/recent/shows">
|
||||
{% tablericon "device-tv-old" %}
|
||||
Recent shows
|
||||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:tv.recentlyWatched, shape: "vertical", count: 6 %}
|
||||
{% render "partials/media/grid.liquid", data:tv.recentlyWatched, shape:"vertical", count: 6 %}
|
||||
<h3 id="favorite-movies">
|
||||
<a class="icon-link" href="/watching/favorite-movies">
|
||||
{% tablericon "star" %}
|
||||
Favorite movies
|
||||
</a>
|
||||
</h3>
|
||||
{% assign favoriteMovies = movies.favorites | shuffleArray | featuredWatching: 6 %}
|
||||
{% render "partials/media/watching/grid.liquid", mediaItems:favoriteMovies, count: 6 %}
|
||||
{% assign favoriteMovies = movies.favorites | shuffleArray %}
|
||||
{% render "partials/media/grid.liquid", data:favoriteMovies, shape:"vertical", count: 6 %}
|
||||
<h3 id="favorite-shows">
|
||||
<a class="icon-link" href="/watching/favorite-shows">
|
||||
{% tablericon "star" %}
|
||||
Favorite shows
|
||||
</a>
|
||||
</h3>
|
||||
{% assign favoriteShows = tv.favorites | shuffleArray | featuredWatching: 6 %}
|
||||
{% render "partials/media/watching/grid.liquid", mediaItems:favoriteShows, count: 6 %}
|
||||
{% assign favoriteShows = tv.favorites | shuffleArray %}
|
||||
{% render "partials/media/grid.liquid", data:favoriteShows, shape:"vertical", count: 6 %}
|
|
@ -14,4 +14,4 @@ schema: watching
|
|||
<p>These are the movies I've watched recently. There are many like them, but these are mine. (Or well, all the movies I've watched — they're ordered latest watched, descending, hence the recent part).</p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/watching/grid.liquid", data:pagination %}
|
||||
{% render "partials/media/grid.liquid", data:pagination.items, pagination:pagination, shape:"poster" %}
|
|
@ -14,4 +14,4 @@ schema: watching-shows
|
|||
<p>These are the shows I've watched recently. There are many like them, but these are mine. (Or well, all the movies I've watched — they're ordered latest watched, descending, hence the recent part).</p>
|
||||
<hr />
|
||||
{% endif %}
|
||||
{% render "partials/media/watching/grid.liquid", data:pagination %}
|
||||
{% render "partials/media/grid.liquid", data:pagination.items, pagination:pagination, shape:"poster" %}
|
|
@ -8,7 +8,11 @@ SELECT
|
|||
p.featured,
|
||||
p.slug AS url,
|
||||
p.mastodon_url,
|
||||
CONCAT('/', df.filename_disk) AS image,
|
||||
CASE
|
||||
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/'
|
||||
THEN CONCAT('/', df.filename_disk)
|
||||
ELSE NULL
|
||||
END AS image,
|
||||
p.image_alt,
|
||||
|
||||
(
|
||||
|
|
|
@ -40,7 +40,7 @@ WITH search_data AS (
|
|||
SELECT
|
||||
'movie' AS content_type,
|
||||
CASE
|
||||
WHEN m.rating IS NOT NULL THEN CONCAT('🎥 ', m.title, ' (', m.rating, ')') -- Add emoji and rating for movies
|
||||
WHEN m.rating IS NOT NULL THEN CONCAT('🎥 ', m.title, ' (', m.rating, ')')
|
||||
ELSE CONCAT('🎥 ', m.title)
|
||||
END AS title,
|
||||
CONCAT('https://coryd.dev', m.url) AS url,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
CREATE OR REPLACE VIEW optimized_books AS
|
||||
SELECT
|
||||
b.date_finished,
|
||||
EXTRACT(YEAR FROM b.date_finished) AS year,
|
||||
b.author,
|
||||
b.description,
|
||||
b.title,
|
||||
|
@ -87,6 +88,19 @@ SELECT
|
|||
WHERE rbk.books_id = b.id
|
||||
) AS related_books,
|
||||
|
||||
json_build_object(
|
||||
'title', CONCAT(b.title, ' by ', b.author),
|
||||
'image', CONCAT('/', df.filename_disk),
|
||||
'url', b.slug,
|
||||
'alt', CONCAT(b.title, ' by ', b.author),
|
||||
'subtext',
|
||||
CASE
|
||||
WHEN b.star_rating IS NOT NULL
|
||||
THEN CONCAT(EXTRACT(YEAR FROM b.date_finished), ' (', b.star_rating, ')')
|
||||
ELSE EXTRACT(YEAR FROM b.date_finished)::TEXT
|
||||
END
|
||||
) AS grid,
|
||||
|
||||
CASE
|
||||
WHEN LOWER(b.read_status) = 'finished' AND b.star_rating IS NOT NULL THEN json_build_object(
|
||||
'title', b.title,
|
||||
|
|
|
@ -12,12 +12,22 @@ SELECT
|
|||
m.description,
|
||||
m.review,
|
||||
'movie' AS type,
|
||||
|
||||
m.slug AS url,
|
||||
|
||||
CONCAT('/', df.filename_disk) AS image,
|
||||
CONCAT('/', df2.filename_disk) AS backdrop,
|
||||
|
||||
json_build_object(
|
||||
'title', m.title,
|
||||
'url', m.slug,
|
||||
'image', CONCAT('/', df.filename_disk),
|
||||
'backdrop', CONCAT('/', df2.filename_disk),
|
||||
'alt', CONCAT(m.title, ' (', m.year, ')'),
|
||||
'subtext', CASE
|
||||
WHEN m.star_rating IS NOT NULL THEN CONCAT(m.year, ' (', m.star_rating, ')')
|
||||
ELSE m.year::TEXT
|
||||
END
|
||||
) AS grid,
|
||||
|
||||
(
|
||||
SELECT array_agg(t.name)
|
||||
FROM movies_tags mt
|
||||
|
@ -95,7 +105,7 @@ SELECT
|
|||
WHEN m.star_rating IS NOT NULL AND m.last_watched IS NOT NULL THEN
|
||||
json_build_object(
|
||||
'title', m.title,
|
||||
'url', CONCAT('https://coryd.dev', m.slug),
|
||||
'url', CONCAT('https://coryd.dev/movies/', m.slug),
|
||||
'date', m.last_watched,
|
||||
'description', m.description,
|
||||
'image', CONCAT('/', df.filename_disk),
|
||||
|
|
|
@ -13,7 +13,15 @@ SELECT
|
|||
'description', ar.description
|
||||
) AS artist,
|
||||
|
||||
EXTRACT(EPOCH FROM a.release_date) AS release_timestamp
|
||||
EXTRACT(EPOCH FROM a.release_date) AS release_timestamp,
|
||||
|
||||
json_build_object(
|
||||
'title', a.name,
|
||||
'image', CONCAT('/', df.filename_disk),
|
||||
'url', a.release_link,
|
||||
'alt', CONCAT(a.name, ' by ', ar.name_string),
|
||||
'subtext', CONCAT(ar.name_string, ' / ', a.release_date)
|
||||
) AS grid
|
||||
|
||||
FROM
|
||||
albums a
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
CREATE OR REPLACE VIEW month_tracks AS
|
||||
SELECT
|
||||
ol.id,
|
||||
ol.listened_at,
|
||||
ol.track_name,
|
||||
ol.artist_name,
|
||||
ol.album_name,
|
||||
ol.album_key,
|
||||
ol.artist_art,
|
||||
ol.artist_genres,
|
||||
ol.genre_name,
|
||||
ol.artist_country,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
ol.genre_url
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days'
|
||||
ORDER BY
|
||||
TO_TIMESTAMP(ol.listened_at) DESC;
|
22
views/media/music/month/albums.psql
Normal file
22
views/media/music/month/albums.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW month_albums AS
|
||||
SELECT
|
||||
ol.album_name,
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
json_build_object(
|
||||
'title', ol.album_name,
|
||||
'image', ol.album_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(ol.album_name, ' by ', ol.artist_name),
|
||||
'subtext', ol.artist_name
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days'
|
||||
GROUP BY
|
||||
ol.album_name, ol.artist_name, ol.album_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
22
views/media/music/month/artists.psql
Normal file
22
views/media/music/month/artists.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW month_artists AS
|
||||
SELECT
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.artist_art,
|
||||
ol.artist_url,
|
||||
ARRAY_AGG(DISTINCT ol.genre_name) AS genres,
|
||||
json_build_object(
|
||||
'title', ol.artist_name,
|
||||
'image', ol.artist_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name),
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days'
|
||||
GROUP BY
|
||||
ol.artist_name, ol.artist_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
17
views/media/music/month/genres.psql
Normal file
17
views/media/music/month/genres.psql
Normal file
|
@ -0,0 +1,17 @@
|
|||
CREATE OR REPLACE VIEW month_genres AS
|
||||
SELECT
|
||||
ol.genre_name,
|
||||
ol.genre_url,
|
||||
COUNT(*) AS plays,
|
||||
json_build_object(
|
||||
'alt', ol.genre_name,
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days'
|
||||
GROUP BY
|
||||
ol.genre_name, ol.genre_url
|
||||
ORDER BY
|
||||
plays DESC;
|
37
views/media/music/month/tracks.psql
Normal file
37
views/media/music/month/tracks.psql
Normal file
|
@ -0,0 +1,37 @@
|
|||
CREATE OR REPLACE VIEW month_tracks AS
|
||||
WITH track_stats AS (
|
||||
SELECT
|
||||
ol.track_name,
|
||||
ol.artist_name,
|
||||
ol.album_name,
|
||||
COUNT(*) AS plays,
|
||||
MAX(ol.listened_at) AS last_listened,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
MAX(COUNT(*)) OVER () AS most_played
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '30 days'
|
||||
GROUP BY
|
||||
ol.track_name, ol.artist_name, ol.album_name, ol.album_art, ol.artist_url
|
||||
)
|
||||
SELECT
|
||||
track_name,
|
||||
artist_name,
|
||||
album_name,
|
||||
plays,
|
||||
last_listened,
|
||||
album_art,
|
||||
artist_url,
|
||||
json_build_object(
|
||||
'title', track_name,
|
||||
'artist', artist_name,
|
||||
'url', artist_url,
|
||||
'plays', plays,
|
||||
'alt', CONCAT(track_name, ' by ', artist_name),
|
||||
'subtext', CONCAT(album_name, ' (', plays, ' plays)'),
|
||||
'percentage', ROUND((plays::decimal / most_played) * 100, 2)
|
||||
) AS chart
|
||||
FROM track_stats
|
||||
ORDER BY plays DESC, last_listened DESC;
|
|
@ -12,7 +12,15 @@ SELECT
|
|||
ol.artist_country,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
ol.genre_url
|
||||
ol.genre_url,
|
||||
json_build_object(
|
||||
'title', ol.track_name,
|
||||
'subtext', ol.artist_name,
|
||||
'alt', CONCAT(ol.track_name, ' by ', ol.artist_name),
|
||||
'url', ol.artist_url,
|
||||
'image', ol.album_art,
|
||||
'played_at', ol.listened_at
|
||||
) AS chart
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
CREATE OR REPLACE VIEW three_month_tracks AS
|
||||
SELECT
|
||||
ol.id,
|
||||
ol.listened_at,
|
||||
ol.track_name,
|
||||
ol.artist_name,
|
||||
ol.album_name,
|
||||
ol.album_key,
|
||||
ol.artist_art,
|
||||
ol.artist_genres,
|
||||
ol.genre_name,
|
||||
ol.artist_country,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
ol.genre_url
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '3 months'
|
||||
ORDER BY
|
||||
TO_TIMESTAMP(ol.listened_at) DESC;
|
22
views/media/music/three-month/albums.psql
Normal file
22
views/media/music/three-month/albums.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW three_month_albums AS
|
||||
SELECT
|
||||
ol.album_name,
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
json_build_object(
|
||||
'title', ol.album_name,
|
||||
'image', ol.album_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(ol.album_name, ' by ', ol.artist_name),
|
||||
'subtext', ol.artist_name
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '3 months'
|
||||
GROUP BY
|
||||
ol.album_name, ol.artist_name, ol.album_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
22
views/media/music/three-month/artists.psql
Normal file
22
views/media/music/three-month/artists.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW three_month_artists AS
|
||||
SELECT
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.artist_art,
|
||||
ol.artist_url,
|
||||
ARRAY_AGG(DISTINCT ol.genre_name) AS genres,
|
||||
json_build_object(
|
||||
'title', ol.artist_name,
|
||||
'image', ol.artist_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name),
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '3 months'
|
||||
GROUP BY
|
||||
ol.artist_name, ol.artist_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
17
views/media/music/three-month/genres.psql
Normal file
17
views/media/music/three-month/genres.psql
Normal file
|
@ -0,0 +1,17 @@
|
|||
CREATE OR REPLACE VIEW three_month_genres AS
|
||||
SELECT
|
||||
ol.genre_name,
|
||||
ol.genre_url,
|
||||
COUNT(*) AS plays,
|
||||
json_build_object(
|
||||
'alt', ol.genre_name,
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '3 months'
|
||||
GROUP BY
|
||||
ol.genre_name, ol.genre_url
|
||||
ORDER BY
|
||||
plays DESC;
|
37
views/media/music/three-month/tracks.psql
Normal file
37
views/media/music/three-month/tracks.psql
Normal file
|
@ -0,0 +1,37 @@
|
|||
CREATE OR REPLACE VIEW three_month_tracks AS
|
||||
WITH track_stats AS (
|
||||
SELECT
|
||||
ol.track_name,
|
||||
ol.artist_name,
|
||||
ol.album_name,
|
||||
COUNT(*) AS plays,
|
||||
MAX(ol.listened_at) AS last_listened,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
MAX(COUNT(*)) OVER () AS most_played
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '3 months'
|
||||
GROUP BY
|
||||
ol.track_name, ol.artist_name, ol.album_name, ol.album_art, ol.artist_url
|
||||
)
|
||||
SELECT
|
||||
track_name,
|
||||
artist_name,
|
||||
album_name,
|
||||
plays,
|
||||
last_listened,
|
||||
album_art,
|
||||
artist_url,
|
||||
json_build_object(
|
||||
'title', track_name,
|
||||
'artist', artist_name,
|
||||
'url', artist_url,
|
||||
'plays', plays,
|
||||
'alt', CONCAT(track_name, ' by ', artist_name),
|
||||
'subtext', CONCAT(album_name, ' (', plays, ' plays)'),
|
||||
'percentage', ROUND((plays::decimal / most_played) * 100, 2)
|
||||
) AS chart
|
||||
FROM track_stats
|
||||
ORDER BY plays DESC, last_listened DESC;
|
22
views/media/music/week/albums.psql
Normal file
22
views/media/music/week/albums.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW week_albums AS
|
||||
SELECT
|
||||
ol.album_name,
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
json_build_object(
|
||||
'title', ol.album_name,
|
||||
'image', ol.album_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(ol.album_name, ' by ', ol.artist_name),
|
||||
'subtext', ol.artist_name
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days'
|
||||
GROUP BY
|
||||
ol.album_name, ol.artist_name, ol.album_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
22
views/media/music/week/artists.psql
Normal file
22
views/media/music/week/artists.psql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE OR REPLACE VIEW week_artists AS
|
||||
SELECT
|
||||
ol.artist_name,
|
||||
COUNT(*) AS plays,
|
||||
ol.artist_art,
|
||||
ol.artist_url,
|
||||
ARRAY_AGG(DISTINCT ol.genre_name) AS genres,
|
||||
json_build_object(
|
||||
'title', ol.artist_name,
|
||||
'image', ol.artist_art,
|
||||
'url', ol.artist_url,
|
||||
'alt', CONCAT(COUNT(*), ' plays of ', ol.artist_name),
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days'
|
||||
GROUP BY
|
||||
ol.artist_name, ol.artist_art, ol.artist_url
|
||||
ORDER BY
|
||||
plays DESC;
|
17
views/media/music/week/genres.psql
Normal file
17
views/media/music/week/genres.psql
Normal file
|
@ -0,0 +1,17 @@
|
|||
CREATE OR REPLACE VIEW week_genres AS
|
||||
SELECT
|
||||
ol.genre_name,
|
||||
ol.genre_url,
|
||||
COUNT(*) AS plays,
|
||||
json_build_object(
|
||||
'alt', ol.genre_name,
|
||||
'subtext', CONCAT(COUNT(*), ' plays')
|
||||
) AS grid
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days'
|
||||
GROUP BY
|
||||
ol.genre_name, ol.genre_url
|
||||
ORDER BY
|
||||
plays DESC;
|
37
views/media/music/week/tracks.psql
Normal file
37
views/media/music/week/tracks.psql
Normal file
|
@ -0,0 +1,37 @@
|
|||
CREATE OR REPLACE VIEW week_tracks AS
|
||||
WITH track_stats AS (
|
||||
SELECT
|
||||
ol.track_name,
|
||||
ol.artist_name,
|
||||
ol.album_name,
|
||||
COUNT(*) AS plays,
|
||||
MAX(ol.listened_at) AS last_listened,
|
||||
ol.album_art,
|
||||
ol.artist_url,
|
||||
MAX(COUNT(*)) OVER () AS most_played
|
||||
FROM
|
||||
optimized_listens ol
|
||||
WHERE
|
||||
TO_TIMESTAMP(ol.listened_at) >= NOW() - INTERVAL '7 days'
|
||||
GROUP BY
|
||||
ol.track_name, ol.artist_name, ol.album_name, ol.album_art, ol.artist_url
|
||||
)
|
||||
SELECT
|
||||
track_name,
|
||||
artist_name,
|
||||
album_name,
|
||||
plays,
|
||||
last_listened,
|
||||
album_art,
|
||||
artist_url,
|
||||
json_build_object(
|
||||
'title', track_name,
|
||||
'artist', artist_name,
|
||||
'url', artist_url,
|
||||
'plays', plays,
|
||||
'alt', CONCAT(track_name, ' by ', artist_name),
|
||||
'subtext', CONCAT(album_name, ' (', plays, ' plays)'),
|
||||
'percentage', ROUND((plays::decimal / most_played) * 100, 2)
|
||||
) AS chart
|
||||
FROM track_stats
|
||||
ORDER BY plays DESC, last_listened DESC;
|
|
@ -12,6 +12,19 @@ SELECT
|
|||
CONCAT('/', df_art.filename_disk) AS image,
|
||||
CONCAT('/', df_backdrop.filename_disk) AS backdrop,
|
||||
|
||||
json_build_object(
|
||||
'title', s.title,
|
||||
'image', CONCAT('/', df_art.filename_disk),
|
||||
'backdrop', CONCAT('/', df_backdrop.filename_disk),
|
||||
'url', s.slug,
|
||||
'alt', CONCAT(s.title, ' (', s.year, ')'),
|
||||
'subtext', CASE
|
||||
WHEN MAX(e.season_number) IS NOT NULL AND MAX(e.episode_number) IS NOT NULL
|
||||
THEN CONCAT('S', MAX(e.season_number), 'E', MAX(e.episode_number))
|
||||
ELSE s.year::TEXT
|
||||
END
|
||||
) AS grid,
|
||||
|
||||
json_build_object(
|
||||
'type', 'tv',
|
||||
'title', s.title,
|
||||
|
|
Reference in a new issue