Skip to content

Commit

Permalink
Merge pull request #275 from bcc-code/feature/document-models
Browse files Browse the repository at this point in the history
extract shared code into DocumentList
  • Loading branch information
SimonSimCity authored Feb 2, 2024
2 parents dc21075 + 2e2f536 commit 0e63b93
Show file tree
Hide file tree
Showing 18 changed files with 290 additions and 242 deletions.
181 changes: 181 additions & 0 deletions components/DocumentList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<script setup lang="ts">
import type {
IAllDocumentModels,
TrackModel,
SectionHeaderModel,
} from "@bcc-code/bmm-sdk-fetch";
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
type IDiscoverableGroup = {
header: SectionHeaderModel | null;
items: Exclude<IAllDocumentModels, SectionHeaderModel>[];
};
const { t } = useI18n();
const props = defineProps<{
items: IAllDocumentModels[] | null | undefined;
pending: boolean;
}>();
const convertModels = (models: IAllDocumentModels[]) => {
let currentSection: IDiscoverableGroup["items"] = [];
const result: IDiscoverableGroup[] = [];
models.forEach((el, i) => {
if (el.type === "section_header") {
currentSection = [];
result.push({
header: el,
items: currentSection,
});
} else if (i === 0) {
currentSection = [el];
result.push({
header: null,
items: currentSection,
});
} else {
currentSection.push(el);
}
});
return result;
};
const { setQueue } = useNuxtApp().$mediaPlayer;
const playItem = (item: TrackModel, group: IDiscoverableGroup) => {
const items = group.items.filter((c): c is TrackModel => c.type === "track");
setQueue(
items,
items.findIndex((track) => track.id === item.id),
);
};
// We remove the hostname so that we use SPA links (without full page refresh)
const parseLink = (link: string) => {
const url = new URL(link);
return url.pathname + url.search + url.hash;
};
const breakpoints = useBreakpoints(breakpointsTailwind);
const isSmallScreen = breakpoints.smallerOrEqual("lg");
</script>

<template>
<div>
<template v-if="props.pending">
<ul>
<li
v-for="index in 5"
:key="index"
class="my-6 h-11 w-full animate-pulse rounded-lg bg-background-2"
></li>
</ul>
</template>
<template v-else-if="props.items"
><template
v-for="group in convertModels(props.items)"
:key="group.header?.id || 0"
>
<PageHeading v-if="group.header" :level="3">
<div class="flex items-center justify-between">
<div>
<NuxtLink
v-if="typeof group.header.link === 'string'"
:to="parseLink(group.header.link)"
>
{{ group.header.title }}
</NuxtLink>
<span v-else>{{ group.header.title }}</span>
</div>
<NuxtLink
v-if="group.header.link"
:to="parseLink(group.header.link)"
>
<ButtonStyled intent="secondary" size="small">
<span class="whitespace-nowrap">
{{ t("home.list.see-all") }}
</span>
</ButtonStyled>
</NuxtLink>
</div>
</PageHeading>
<div
v-if="group.header?.useCoverCarousel"
class="flex flex-row flex-wrap gap-6"
>
<template
v-for="item in group.items.slice(0, isSmallScreen ? 4 : 6)"
:key="item.id"
>
<NuxtLink
v-if="item.type === 'album'"
:to="{ name: 'album-id', params: { id: item.id } }"
>
<ItemCard :item="item" />
</NuxtLink>
<NuxtLink
v-else-if="item.type === 'playlist'"
:to="{ name: 'playlist-curated-id', params: { id: item.id } }"
>
<ItemCard :item="item" />
</NuxtLink>
<NuxtLink
v-else-if="item.type === 'podcast'"
:to="{ name: 'playlist-podcast-id', params: { id: item.id } }"
>
<ItemCard :item="item" />
</NuxtLink>
<div
v-else
class="grid w-52 flex-shrink-0 basis-52 gap-4"
style="background-color: rgba(255, 0, 0, 0.4); color: red"
>
"{{ item.type }}" is not yet implemented ...
</div>
</template>
</div>
<ol
v-else
class="w-full divide-y divide-label-separator grid grid-cols-tracklist"
>
<template v-for="item in group.items" :key="item.id">
<h2
v-if="item.type === 'chapter_header'"
class="text-2xl font-extrabold pt-10 pb-4"
>
{{ item.title }}
</h2>
<TrackItem
v-else-if="item.type === 'track'"
:track="item"
:is-track-type-known="true"
show-thumbnail
@play-track="playItem(item, group)"
></TrackItem>
<ContributorListItem
v-else-if="item.type === 'contributor'"
:contributor="item"
></ContributorListItem>
<AlbumItem v-else-if="item.type === 'album'" :album="item" />
<PlaylistItem
v-else-if="item.type === 'playlist'"
:playlist="item"
/>
<PodcastItem v-else-if="item.type === 'podcast'" :podcast="item" />
<li v-else>
<div style="background-color: rgba(255, 0, 0, 0.4); color: red">
"{{ item.type }}" is not yet implemented ...
</div>
</li>
</template>
</ol>
</template>
</template>
<template v-else>
<div style="background-color: rgba(255, 0, 0, 0.4); color: red">
This list is empty 😔
</div>
</template>
</div>
</template>
28 changes: 28 additions & 0 deletions composables/browse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,31 @@ export function useBrowse() {
useLazyAsyncData("browse", () => new BrowseApi().browseGet()),
);
}

export function useBrowseEvents() {
return reactiveApi(
useLazyAsyncData("browse-events", () => new BrowseApi().browseEventsGet()),
);
}

export function useBrowseAudiobooks() {
return reactiveApi(
useLazyAsyncData("browse-audiobooks", () =>
new BrowseApi().browseAudiobooksGet(),
),
);
}

export function useBrowseMusic() {
return reactiveApi(
useLazyAsyncData("browse-music", () => new BrowseApi().browseMusicGet()),
);
}

export function useBrowsePodcast() {
return reactiveApi(
useLazyAsyncData("browse-podcast", () =>
new BrowseApi().browsePodcastsGet(),
),
);
}
28 changes: 2 additions & 26 deletions composables/discover.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,10 @@
import { DiscoverApi } from "@bcc-code/bmm-sdk-fetch";
import type {
DiscoverGetRequest,
SectionHeaderModel,
IAllDocumentModels,
} from "@bcc-code/bmm-sdk-fetch";

export type IDiscoverableGroup = {
header: SectionHeaderModel | null;
items: Exclude<IAllDocumentModels, SectionHeaderModel>[];
};
import type { DiscoverGetRequest } from "@bcc-code/bmm-sdk-fetch";

export function useDiscover(requestParameters: DiscoverGetRequest) {
return reactiveApi(
useLazyAsyncData("discover", () =>
new DiscoverApi().discoverGet(requestParameters).then((d) => {
let currentSection: IDiscoverableGroup["items"] = [];
const result: IDiscoverableGroup[] = [];
d.forEach((el) => {
if (el.type === "section_header") {
currentSection = [];
result.push({
header: el,
items: currentSection,
});
} else {
currentSection.push(el);
}
});
return result;
}),
new DiscoverApi().discoverGet(requestParameters),
),
);
}
8 changes: 8 additions & 0 deletions composables/playlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ export function useCuratedPlaylists() {
useLazyAsyncData("playlists", () => new PlaylistApi().playlistGet()),
);
}

export function useFeaturedPlaylists() {
return reactiveApi(
useLazyAsyncData("playlists-featured", () =>
new PlaylistApi().playlistDocumentsGet(),
),
);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"dependencies": {
"@auth0/auth0-vue": "^2.3.3",
"@bcc-code/bmm-sdk-fetch": "^7.1.0",
"@bcc-code/bmm-sdk-fetch": "^7.3.0",
"@headlessui/vue": "^1.7.17",
"@microsoft/applicationinsights-web": "^3.0.7",
"@pinia/nuxt": "^0.5.1",
Expand Down
8 changes: 8 additions & 0 deletions pages/browse/audiobooks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts" setup>
const { data: models, pending } = useBrowseAudiobooks();
setTitleOfDocumentList(models);
</script>

<template>
<DocumentList :items="models?.items" :pending="pending"></DocumentList>
</template>
8 changes: 8 additions & 0 deletions pages/browse/events.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts" setup>
const { data: models, pending } = useBrowseEvents();
setTitleOfDocumentList(models);
</script>

<template>
<DocumentList :items="models?.items" :pending="pending"></DocumentList>
</template>
46 changes: 2 additions & 44 deletions pages/browse/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,9 @@
const { t } = useI18n();
toolbarTitleStore().setReactiveToolbarTitle(() => t("nav.browse"));
const { data: browseSections, pending } = useBrowse();
const { data: models, pending } = useBrowse();
</script>

<template>
<div>
<PageHeading class="mb-6">{{ $t("nav.browse") }}</PageHeading>
<template v-if="pending">
<ul>
<li
v-for="index in 5"
:key="index"
class="my-6 h-11 w-full animate-pulse rounded-lg bg-background-2"
></li>
</ul>
</template>
<ul v-else>
<template v-for="section in browseSections" :key="section.id || 0">
<PageHeading v-if="section.type === 'section_header'" :level="3">
<div class="flex items-center justify-between">
<div>
<a v-if="typeof section.link === 'string'" :href="section.link">
{{ section.title }}
</a>
<span v-else>{{ section.title }}</span>
</div>
<a v-if="section.link" :href="section.link">
<ButtonStyled intent="secondary" size="small">
<span class="whitespace-nowrap">
{{ t("home.list.see-all") }}
</span>
</ButtonStyled>
</a>
</div>
</PageHeading>
<AlbumItem v-else-if="section.type === 'album'" :album="section" />
<PlaylistItem
v-else-if="section.type === 'playlist'"
:playlist="section"
/>
<PodcastItem
v-else-if="section.type === 'podcast'"
:podcast="section"
/>
<p v-else style="color: red">This is not implemented yet</p>
</template>
</ul>
</div>
<DocumentList :items="models" :pending="pending"></DocumentList>
</template>
7 changes: 6 additions & 1 deletion pages/browse/music.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<script lang="ts" setup>
const { data: models, pending } = useBrowseMusic();
setTitleOfDocumentList(models);
</script>

<template>
<h1>The route {{ useRoute().name }} has not been implemented yet.</h1>
<DocumentList :items="models?.items" :pending="pending"></DocumentList>
</template>
7 changes: 6 additions & 1 deletion pages/browse/podcasts.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<script lang="ts" setup>
const { data: models, pending } = useBrowsePodcast();
setTitleOfDocumentList(models);
</script>

<template>
<h1>The route {{ useRoute().name }} has not been implemented yet.</h1>
<DocumentList :items="models?.items" :pending="pending"></DocumentList>
</template>
7 changes: 6 additions & 1 deletion pages/featured.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<script lang="ts" setup>
const { data: models, pending } = useFeaturedPlaylists();
setTitleOfDocumentList(models);
</script>

<template>
<h1>The route {{ useRoute().name }} has not been implemented yet.</h1>
<DocumentList :items="models?.items" :pending="pending"></DocumentList>
</template>
Loading

0 comments on commit 0e63b93

Please sign in to comment.