From 3733c20db3c32333d54c539c53c866ffda1e496a Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Thu, 15 Jun 2023 00:40:18 +0200
Subject: [PATCH] feat: add read-only playlists store

refs #127
---
 src/stores/auth.ts      | 12 ++++++++++++
 src/stores/playlists.ts | 36 ++++++++++++++++++++++++++++++++++++
 src/types.ts            |  2 ++
 3 files changed, 50 insertions(+)
 create mode 100644 src/stores/playlists.ts

diff --git a/src/stores/auth.ts b/src/stores/auth.ts
index deac4b69..a9c98eb6 100644
--- a/src/stores/auth.ts
+++ b/src/stores/auth.ts
@@ -156,3 +156,15 @@ export const steeringAuthInit: { getRequestDefaults: () => RequestInit } = {
     }
   },
 }
+
+export const tankAuthInit: { getRequestDefaults: () => RequestInit } = {
+  getRequestDefaults() {
+    const authStore = useAuthStore()
+
+    return {
+      headers: {
+        Authorization: `Bearer ${authStore.currentUser?.tankSessionToken}`,
+      },
+    }
+  },
+}
diff --git a/src/stores/playlists.ts b/src/stores/playlists.ts
new file mode 100644
index 00000000..2d1dcc93
--- /dev/null
+++ b/src/stores/playlists.ts
@@ -0,0 +1,36 @@
+import { defineStore } from 'pinia'
+
+import { tankAuthInit } from '@/stores/auth'
+import { APIListPaginated, APIRetrieve, createExtendableAPI, createTankURL } from '@/api'
+import { Playlist } from '@/types'
+
+/**
+ * Calculates the duration of a playlist.
+ * May return null if the playlist contains entries with an invalid duration.
+ * @param playlist
+ */
+export function calculatePlaylistDurationInSeconds(playlist: Playlist) {
+  let duration = 0
+  for (const entry of playlist.entries) {
+    // entry.duration may be null/NaN if the entry references
+    // a stream or other resources without an inherent duration
+    if (typeof entry.duration !== 'number' || isNaN(entry.duration)) {
+      return null
+    }
+    // entry.duration is in nanoseconds
+    duration += entry.duration / 1_000_000_000
+  }
+
+  return duration
+}
+
+export const usePlaylistStore = defineStore('playlists', () => {
+  const endpoint = createTankURL.prefix('playlists')
+  const { base, ...api } = createExtendableAPI<Playlist>(endpoint, tankAuthInit)
+  const { list } = APIListPaginated(api)
+  return {
+    ...base,
+    list,
+    ...APIRetrieve(api),
+  }
+})
diff --git a/src/types.ts b/src/types.ts
index cb073861..cf8d029f 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,5 @@
 import { components as steeringComponents } from '@/steering-types'
+import { components as tankComponents } from '@/tank-types'
 
 export type Module = {
   icon: string
@@ -17,3 +18,4 @@ export type PaginationData = {
 
 export type TimeSlot = Required<steeringComponents['schemas']['TimeSlot']>
 export type Show = Required<steeringComponents['schemas']['Show']>
+export type Playlist = Required<tankComponents['schemas']['store.Playlist']>
-- 
GitLab