diff --git a/client/app/routes/MediaItems/Album.tsx b/client/app/routes/MediaItems/Album.tsx index d6ae430..4806384 100644 --- a/client/app/routes/MediaItems/Album.tsx +++ b/client/app/routes/MediaItems/Album.tsx @@ -19,42 +19,58 @@ export async function clientLoader({ params }: LoaderFunctionArgs) { export default function Album() { const album = useLoaderData() as Album; - const [period, setPeriod] = useState('week') + const [period, setPeriod] = useState("week"); - console.log(album) + console.log(album); return ( - { - r.artists = [] - r.tracks = [] - for (let i = 0; i < r.albums.length; i ++) { - if (r.albums[i].id === id) { - delete r.albums[i] - } - } - return r - }} - subContent={
- {album.listen_count &&

{album.listen_count} play{ album.listen_count > 1 ? 's' : ''}

} - {

{timeListenedString(album.time_listened)}

} - {

Listening since {new Date(album.first_listen * 1000).toLocaleDateString()}

} -
} - > -
- -
-
- - - + { + r.artists = []; + r.tracks = []; + for (let i = 0; i < r.albums.length; i++) { + if (r.albums[i].id === id) { + delete r.albums[i]; + } + } + return r; + }} + subContent={ +
+ {album.listen_count && ( +

+ {album.listen_count} play{album.listen_count > 1 ? "s" : ""} +

+ )} + { +

+ {timeListenedString(album.time_listened)} +

+ } + { +

+ Listening since{" "} + {new Date(album.first_listen * 1000).toLocaleDateString()} +

+ }
+ } + > +
+ +
+
+ + + +
); } diff --git a/client/app/routes/MediaItems/Artist.tsx b/client/app/routes/MediaItems/Artist.tsx index 20b4f88..3f9485c 100644 --- a/client/app/routes/MediaItems/Artist.tsx +++ b/client/app/routes/MediaItems/Artist.tsx @@ -20,50 +20,66 @@ export async function clientLoader({ params }: LoaderFunctionArgs) { export default function Artist() { const artist = useLoaderData() as Artist; - const [period, setPeriod] = useState('week') + const [period, setPeriod] = useState("week"); // remove canonical name from alias list - console.log(artist.aliases) + console.log(artist.aliases); let index = artist.aliases.indexOf(artist.name); if (index !== -1) { artist.aliases.splice(index, 1); } return ( - { - r.albums = [] - r.tracks = [] - for (let i = 0; i < r.artists.length; i ++) { - if (r.artists[i].id === id) { - delete r.artists[i] - } - } - return r - }} - subContent={
- {artist.listen_count &&

{artist.listen_count} play{ artist.listen_count > 1 ? 's' : ''}

} - {

{timeListenedString(artist.time_listened)}

} - {

Listening since {new Date(artist.first_listen * 1000).toLocaleDateString()}

} -
} - > -
- + { + r.albums = []; + r.tracks = []; + for (let i = 0; i < r.artists.length; i++) { + if (r.artists[i].id === id) { + delete r.artists[i]; + } + } + return r; + }} + subContent={ +
+ {artist.listen_count && ( +

+ {artist.listen_count} play{artist.listen_count > 1 ? "s" : ""} +

+ )} + { +

+ {timeListenedString(artist.time_listened)} +

+ } + { +

+ Listening since{" "} + {new Date(artist.first_listen * 1000).toLocaleDateString()} +

+ }
-
-
- - - -
- + } + > +
+ +
+
+
+ + +
+ +
); } diff --git a/client/app/routes/MediaItems/Track.tsx b/client/app/routes/MediaItems/Track.tsx index 5f61dcd..5690232 100644 --- a/client/app/routes/MediaItems/Track.tsx +++ b/client/app/routes/MediaItems/Track.tsx @@ -8,55 +8,73 @@ import ActivityGrid from "~/components/ActivityGrid"; import { timeListenedString } from "~/utils/utils"; export async function clientLoader({ params }: LoaderFunctionArgs) { - let res = await fetch(`/apis/web/v1/track?id=${params.id}`); - if (!res.ok) { - throw new Response("Failed to load track", { status: res.status }); - } - const track: Track = await res.json(); - res = await fetch(`/apis/web/v1/album?id=${track.album_id}`) - if (!res.ok) { - throw new Response("Failed to load album for track", { status: res.status }) - } - const album: Album = await res.json() - return {track: track, album: album}; + let res = await fetch(`/apis/web/v1/track?id=${params.id}`); + if (!res.ok) { + throw new Response("Failed to load track", { status: res.status }); + } + const track: Track = await res.json(); + res = await fetch(`/apis/web/v1/album?id=${track.album_id}`); + if (!res.ok) { + throw new Response("Failed to load album for track", { + status: res.status, + }); + } + const album: Album = await res.json(); + return { track: track, album: album }; } export default function Track() { - const { track, album } = useLoaderData(); - const [period, setPeriod] = useState('week') + const { track, album } = useLoaderData(); + const [period, setPeriod] = useState("week"); - return ( - { - r.albums = [] - r.artists = [] - for (let i = 0; i < r.tracks.length; i ++) { - if (r.tracks[i].id === id) { - delete r.tracks[i] - } - } - return r - }} - subContent={
- appears on {album.title} - {track.listen_count &&

{track.listen_count} play{ track.listen_count > 1 ? 's' : ''}

} - {

{timeListenedString(track.time_listened)}

} - {

Listening since {new Date(track.first_listen * 1000).toLocaleDateString()}

} -
} - > -
- -
-
- - -
-
- ) + return ( + { + r.albums = []; + r.artists = []; + for (let i = 0; i < r.tracks.length; i++) { + if (r.tracks[i].id === id) { + delete r.tracks[i]; + } + } + return r; + }} + subContent={ +
+ appears on {album.title} + {track.listen_count && ( +

+ {track.listen_count} play{track.listen_count > 1 ? "s" : ""} +

+ )} + { +

+ {timeListenedString(track.time_listened)} +

+ } + { +

+ Listening since{" "} + {new Date(track.first_listen * 1000).toLocaleDateString()} +

+ } +
+ } + > +
+ +
+
+ + +
+
+ ); } diff --git a/client/app/utils/utils.ts b/client/app/utils/utils.ts index fb3fc4f..2c82bd8 100644 --- a/client/app/utils/utils.ts +++ b/client/app/utils/utils.ts @@ -1,102 +1,108 @@ -import Timeframe from "~/types/timeframe" +import Timeframe from "~/types/timeframe"; const timeframeToInterval = (timeframe: Timeframe): string => { - switch (timeframe) { - case Timeframe.Day: - return "1 day" - case Timeframe.Week: - return "1 week" - case Timeframe.Month: - return "1 month" - case Timeframe.Year: - return "1 year" - case Timeframe.AllTime: - return "99 years" - } -} + switch (timeframe) { + case Timeframe.Day: + return "1 day"; + case Timeframe.Week: + return "1 week"; + case Timeframe.Month: + return "1 month"; + case Timeframe.Year: + return "1 year"; + case Timeframe.AllTime: + return "99 years"; + } +}; function timeSince(date: Date) { - const now = new Date(); - const seconds = Math.floor((now.getTime() - date.getTime()) / 1000); - - const intervals = [ - { label: 'year', seconds: 31536000 }, - { label: 'month', seconds: 2592000 }, - { label: 'week', seconds: 604800 }, - { label: 'day', seconds: 86400 }, - { label: 'hour', seconds: 3600 }, - { label: 'minute', seconds: 60 }, - { label: 'second', seconds: 1 }, - ]; - - for (const interval of intervals) { - const count = Math.floor(seconds / interval.seconds); - if (count >= 1) { - return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`; - } + const now = new Date(); + const seconds = Math.floor((now.getTime() - date.getTime()) / 1000); + + const intervals = [ + { label: "year", seconds: 31536000 }, + { label: "month", seconds: 2592000 }, + { label: "week", seconds: 604800 }, + { label: "day", seconds: 86400 }, + { label: "hour", seconds: 3600 }, + { label: "minute", seconds: 60 }, + { label: "second", seconds: 1 }, + ]; + + for (const interval of intervals) { + const count = Math.floor(seconds / interval.seconds); + if (count >= 1) { + return `${count} ${interval.label}${count !== 1 ? "s" : ""} ago`; } - - return 'just now'; + } + + return "just now"; } -export { timeSince } +export { timeSince }; type hsl = { - h: number, - s: number, - l: number, -} - + h: number; + s: number; + l: number; +}; + const hexToHSL = (hex: string): hsl => { - let r = 0, g = 0, b = 0; - hex = hex.replace('#', ''); - - if (hex.length === 3) { - r = parseInt(hex[0] + hex[0], 16); - g = parseInt(hex[1] + hex[1], 16); - b = parseInt(hex[2] + hex[2], 16); - } else if (hex.length === 6) { - r = parseInt(hex.substring(0, 2), 16); - g = parseInt(hex.substring(2, 4), 16); - b = parseInt(hex.substring(4, 6), 16); - } - - r /= 255; - g /= 255; - b /= 255; - - const max = Math.max(r, g, b), min = Math.min(r, g, b); - let h = 0, s = 0, l = (max + min) / 2; - - if (max !== min) { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: h = ((g - b) / d + (g < b ? 6 : 0)); break; - case g: h = ((b - r) / d + 2); break; - case b: h = ((r - g) / d + 4); break; - } - h /= 6; + let r = 0, + g = 0, + b = 0; + hex = hex.replace("#", ""); + + if (hex.length === 3) { + r = parseInt(hex[0] + hex[0], 16); + g = parseInt(hex[1] + hex[1], 16); + b = parseInt(hex[2] + hex[2], 16); + } else if (hex.length === 6) { + r = parseInt(hex.substring(0, 2), 16); + g = parseInt(hex.substring(2, 4), 16); + b = parseInt(hex.substring(4, 6), 16); + } + + r /= 255; + g /= 255; + b /= 255; + + const max = Math.max(r, g, b), + min = Math.min(r, g, b); + let h = 0, + s = 0, + l = (max + min) / 2; + + if (max !== min) { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; } - - return { - h: Math.round(h * 360), - s: Math.round(s * 100), - l: Math.round(l * 100) - }; + h /= 6; + } + + return { + h: Math.round(h * 360), + s: Math.round(s * 100), + l: Math.round(l * 100), + }; }; const timeListenedString = (seconds: number) => { - if (!seconds) return "" - - if (seconds > (120 * 60) - 1) { - let hours = Math.floor(seconds / 60 / 60) - return `${hours} hours listened` - } else { - let minutes = Math.floor(seconds / 60) - return `${minutes} minutes listened` - } - } + if (!seconds) return ""; + + let minutes = Math.floor(seconds / 60); + return `${minutes} minutes listened`; +}; -export {hexToHSL, timeListenedString} -export type {hsl} \ No newline at end of file +export { hexToHSL, timeListenedString }; +export type { hsl };