From 7afb7f63e51dcbe7d283c7174b686690e032b2de Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 22 Nov 2025 15:30:45 -0500 Subject: [PATCH 1/6] feat: add show description to show detail page (#152) --- src/app/Schedule/SchedulePage.tsx | 3 +++ src/app/Schedule/ShowDetailsPage.tsx | 32 +++++++++++++++++----------- src/services/ScheduleService.ts | 14 ++++++++++++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/app/Schedule/SchedulePage.tsx b/src/app/Schedule/SchedulePage.tsx index b3332f2..b5d2e38 100644 --- a/src/app/Schedule/SchedulePage.tsx +++ b/src/app/Schedule/SchedulePage.tsx @@ -92,9 +92,12 @@ export default function SchedulePage({ currentShow }: SchedulePageProps) { show.name, ); + const showDetails = await scheduleService.getShowById(show.id); + if (showWithArchiveData && showWithArchiveData.archives.length > 0) { navigation.navigate('ShowDetails' as WmbrRouteName, { show: showWithArchiveData, + showDescription: showDetails?.description || '', }); } else { // If no archives found, show info message diff --git a/src/app/Schedule/ShowDetailsPage.tsx b/src/app/Schedule/ShowDetailsPage.tsx index d1eb0b9..58794cb 100644 --- a/src/app/Schedule/ShowDetailsPage.tsx +++ b/src/app/Schedule/ShowDetailsPage.tsx @@ -61,6 +61,7 @@ const CIRCLE_DIAMETER = 16; // Route params for ShowDetailsPage export type ShowDetailsPageRouteParams = { show: Show; + showDescription: string; }; export default function ShowDetailsPage() { @@ -69,7 +70,7 @@ export default function ShowDetailsPage() { const route = useRoute, string>>(); - const show: Show = route.params!.show; + const { show, showDescription } = route.params; const headerHeight = useHeaderHeight(); @@ -306,9 +307,14 @@ export default function ShowDetailsPage() { {/* Show Info */} {show.name} - {formatShowTime(show)} - {show.hosts && ( - Hosted by {show.hosts} + + {formatShowTime(show)} + {show.hosts && ( + Hosted by {show.hosts} + )} + + {showDescription && ( + {showDescription} )} {archives.length} archived episode @@ -473,27 +479,29 @@ const styles = StyleSheet.create({ infoSection: { paddingHorizontal: 20, paddingBottom: 30, + flexDirection: 'column', + rowGap: 8, }, showTitle: { color: COLORS.TEXT.PRIMARY, fontSize: 32, fontWeight: 'bold', - marginBottom: 8, }, showSchedule: { - color: COLORS.TEXT.SECONDARY, - fontSize: 16, - marginBottom: 4, + color: COLORS.TEXT.TERTIARY, + fontSize: 14, }, showHosts: { - color: COLORS.TEXT.SECONDARY, + color: COLORS.TEXT.TERTIARY, + fontSize: 14, + }, + showDescription: { + color: COLORS.TEXT.PRIMARY, fontSize: 16, - marginBottom: 8, }, archiveCount: { - color: COLORS.TEXT.SECONDARY, + color: COLORS.TEXT.TERTIARY, fontSize: 14, - fontWeight: '500', }, archivesSection: { paddingHorizontal: 20, diff --git a/src/services/ScheduleService.ts b/src/services/ScheduleService.ts index d2ea02e..76faa1a 100644 --- a/src/services/ScheduleService.ts +++ b/src/services/ScheduleService.ts @@ -192,6 +192,20 @@ export class ScheduleService { return weeksSince % 2 === 0; } + async getShowById(showId: string): Promise { + try { + const scheduleData = await this.fetchSchedule(); + + const matchingShow = + scheduleData.shows.find(show => show.id === showId) || null; + + return matchingShow; + } catch (error) { + debugError('Error getting show by ID:', error); + return null; + } + } + // Helper method to find the previous show based on current time async findPreviousShow( currentShowName: string, From 11e73925f4f7e36f985c844d2225f62e415596fa Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 6 Dec 2025 13:54:12 -0500 Subject: [PATCH 2/6] chore: greatly simplify show data retrieval --- src/app/Schedule/SchedulePage.tsx | 18 +++++++----------- src/app/Schedule/ShowDetailsPage.tsx | 11 +++++++---- src/services/ScheduleService.ts | 14 -------------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/src/app/Schedule/SchedulePage.tsx b/src/app/Schedule/SchedulePage.tsx index b5d2e38..60ce201 100644 --- a/src/app/Schedule/SchedulePage.tsx +++ b/src/app/Schedule/SchedulePage.tsx @@ -79,7 +79,7 @@ export default function SchedulePage({ currentShow }: SchedulePageProps) { } }, [scheduleService]); - const handleShowPress = async (show: ScheduleShow) => { + const handleShowPress = async (scheduleShow: ScheduleShow) => { try { // Fetch archives for this show from the recently played service const recentlyPlayedService = RecentlyPlayedService.getInstance(); @@ -88,22 +88,18 @@ export default function SchedulePage({ currentShow }: SchedulePageProps) { await recentlyPlayedService.fetchShowsCacheOnly(); // find the show from the cache - const showWithArchiveData = recentlyPlayedService.getShowByName( - show.name, - ); - - const showDetails = await scheduleService.getShowById(show.id); + const show = recentlyPlayedService.getShowByName(scheduleShow.name); - if (showWithArchiveData && showWithArchiveData.archives.length > 0) { + if (show && show.archives.length > 0) { navigation.navigate('ShowDetails' as WmbrRouteName, { - show: showWithArchiveData, - showDescription: showDetails?.description || '', + show, + scheduleShow, }); } else { // If no archives found, show info message Alert.alert( - show.name, - `No archived episodes found for "${show.name}". This show may not have been archived yet or may use a different name in the archive system.`, + scheduleShow.name, + `No archived episodes found for "${scheduleShow.name}". This show may not have been archived yet or may use a different name in the archive system.`, [{ text: 'OK' }], ); } diff --git a/src/app/Schedule/ShowDetailsPage.tsx b/src/app/Schedule/ShowDetailsPage.tsx index 58794cb..70b7d16 100644 --- a/src/app/Schedule/ShowDetailsPage.tsx +++ b/src/app/Schedule/ShowDetailsPage.tsx @@ -54,6 +54,7 @@ import { generateDarkGradientColors, generateGradientColors, } from '@utils/GradientColors'; +import { ScheduleShow } from '@customTypes/Schedule'; const { width } = Dimensions.get('window'); const CIRCLE_DIAMETER = 16; @@ -61,7 +62,7 @@ const CIRCLE_DIAMETER = 16; // Route params for ShowDetailsPage export type ShowDetailsPageRouteParams = { show: Show; - showDescription: string; + scheduleShow: ScheduleShow; }; export default function ShowDetailsPage() { @@ -70,7 +71,7 @@ export default function ShowDetailsPage() { const route = useRoute, string>>(); - const { show, showDescription } = route.params; + const { show, scheduleShow } = route.params; const headerHeight = useHeaderHeight(); @@ -313,8 +314,10 @@ export default function ShowDetailsPage() { Hosted by {show.hosts} )} - {showDescription && ( - {showDescription} + {scheduleShow.description && ( + + {scheduleShow.description} + )} {archives.length} archived episode diff --git a/src/services/ScheduleService.ts b/src/services/ScheduleService.ts index 76faa1a..d2ea02e 100644 --- a/src/services/ScheduleService.ts +++ b/src/services/ScheduleService.ts @@ -192,20 +192,6 @@ export class ScheduleService { return weeksSince % 2 === 0; } - async getShowById(showId: string): Promise { - try { - const scheduleData = await this.fetchSchedule(); - - const matchingShow = - scheduleData.shows.find(show => show.id === showId) || null; - - return matchingShow; - } catch (error) { - debugError('Error getting show by ID:', error); - return null; - } - } - // Helper method to find the previous show based on current time async findPreviousShow( currentShowName: string, From 0d2ad21ca3b50ba5566ae136c22c1bb57af9a73e Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 6 Dec 2025 14:26:35 -0500 Subject: [PATCH 3/6] fix: fix Show Details Page crash when linked from Home --- src/app/Schedule/ShowDetailsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/Schedule/ShowDetailsPage.tsx b/src/app/Schedule/ShowDetailsPage.tsx index 70b7d16..558da5c 100644 --- a/src/app/Schedule/ShowDetailsPage.tsx +++ b/src/app/Schedule/ShowDetailsPage.tsx @@ -62,7 +62,7 @@ const CIRCLE_DIAMETER = 16; // Route params for ShowDetailsPage export type ShowDetailsPageRouteParams = { show: Show; - scheduleShow: ScheduleShow; + scheduleShow?: ScheduleShow; }; export default function ShowDetailsPage() { @@ -314,7 +314,7 @@ export default function ShowDetailsPage() { Hosted by {show.hosts} )} - {scheduleShow.description && ( + {scheduleShow?.description && ( {scheduleShow.description} From 517d9d08975165473ca9de315325946122a1e5a4 Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 6 Dec 2025 14:36:36 -0500 Subject: [PATCH 4/6] fix: add show details when navigating from home --- src/app/Home/index.tsx | 16 +++++++++++++--- src/app/Schedule/ShowDetailsPage.tsx | 4 ++-- src/services/ScheduleService.ts | 13 +++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/app/Home/index.tsx b/src/app/Home/index.tsx index cabf6d0..04f9d40 100644 --- a/src/app/Home/index.tsx +++ b/src/app/Home/index.tsx @@ -35,6 +35,7 @@ import { COLORS, CORE_COLORS } from '@utils/Colors'; import { formatArchiveDate } from '@utils/DateTime'; import HomeNowPlaying from './HomeNowPlaying'; +import { ScheduleService } from '@services/ScheduleService'; const streamUrl = 'https://wmbr.org:8002/hi'; @@ -56,6 +57,8 @@ export default function HomeScreen() { liveStreamUrl: streamUrl, }); + const scheduleService = ScheduleService.getInstance(); + const isPlaying = playbackState?.state === State.Playing; const navigation = @@ -231,17 +234,19 @@ export default function HomeScreen() { await TrackPlayer.seekTo(newPosition); }, [progress.position, progress.duration]); - const handleOpenShowDetails = useCallback(() => { + const handleOpenShowDetails = useCallback(async () => { const show = archiveState.currentShow; if (!show) return; + const scheduleShow = await scheduleService.getShowById(show.id); + // Navigate to Schedule tab with complete stack state navigation.navigate('Schedule' as WmbrRouteName, { // Specify the complete stack path state: { routes: [ { name: 'ScheduleMain' }, - { name: 'ShowDetails', params: { show } }, + { name: 'ShowDetails', params: { show, scheduleShow } }, { name: 'ArchivedShowView', params: { show, archive: archiveState.currentArchive }, @@ -249,7 +254,12 @@ export default function HomeScreen() { ], }, }); - }, [archiveState.currentShow, archiveState.currentArchive, navigation]); + }, [ + archiveState.currentShow, + archiveState.currentArchive, + scheduleService, + navigation, + ]); if (showSplash) return ; diff --git a/src/app/Schedule/ShowDetailsPage.tsx b/src/app/Schedule/ShowDetailsPage.tsx index 558da5c..70b7d16 100644 --- a/src/app/Schedule/ShowDetailsPage.tsx +++ b/src/app/Schedule/ShowDetailsPage.tsx @@ -62,7 +62,7 @@ const CIRCLE_DIAMETER = 16; // Route params for ShowDetailsPage export type ShowDetailsPageRouteParams = { show: Show; - scheduleShow?: ScheduleShow; + scheduleShow: ScheduleShow; }; export default function ShowDetailsPage() { @@ -314,7 +314,7 @@ export default function ShowDetailsPage() { Hosted by {show.hosts} )} - {scheduleShow?.description && ( + {scheduleShow.description && ( {scheduleShow.description} diff --git a/src/services/ScheduleService.ts b/src/services/ScheduleService.ts index d2ea02e..1abc0a4 100644 --- a/src/services/ScheduleService.ts +++ b/src/services/ScheduleService.ts @@ -192,6 +192,19 @@ export class ScheduleService { return weeksSince % 2 === 0; } + async getShowById(showId: string): Promise { + try { + const scheduleData = await this.fetchSchedule(); + + const matchingShow = scheduleData.shows.find(show => show.id === showId); + + return matchingShow; + } catch (error) { + debugError('Error getting show by ID:', error); + return; + } + } + // Helper method to find the previous show based on current time async findPreviousShow( currentShowName: string, From 0991f76e01e9149f5d5a1a214c1386ae07c8d66c Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 6 Dec 2025 14:43:27 -0500 Subject: [PATCH 5/6] fix: scheduleShow still might be undefined, even if we try to pass it --- src/app/Schedule/ShowDetailsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/Schedule/ShowDetailsPage.tsx b/src/app/Schedule/ShowDetailsPage.tsx index 70b7d16..558da5c 100644 --- a/src/app/Schedule/ShowDetailsPage.tsx +++ b/src/app/Schedule/ShowDetailsPage.tsx @@ -62,7 +62,7 @@ const CIRCLE_DIAMETER = 16; // Route params for ShowDetailsPage export type ShowDetailsPageRouteParams = { show: Show; - scheduleShow: ScheduleShow; + scheduleShow?: ScheduleShow; }; export default function ShowDetailsPage() { @@ -314,7 +314,7 @@ export default function ShowDetailsPage() { Hosted by {show.hosts} )} - {scheduleShow.description && ( + {scheduleShow?.description && ( {scheduleShow.description} From e63cb01f09158d2817bc919cab670d1935f112b3 Mon Sep 17 00:00:00 2001 From: Jay Sitter Date: Sat, 6 Dec 2025 14:52:45 -0500 Subject: [PATCH 6/6] test: add test for show description --- __tests__/SchedulePage.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/__tests__/SchedulePage.test.tsx b/__tests__/SchedulePage.test.tsx index 5dde382..8c9f550 100644 --- a/__tests__/SchedulePage.test.tsx +++ b/__tests__/SchedulePage.test.tsx @@ -27,6 +27,7 @@ describe('SchedulePage', () => { expect(screen.getByText('Archives')).toBeTruthy(); expect(screen.getByText('88.1 FM')).toBeTruthy(); expect(screen.getByText(/archived episode/)).toBeTruthy(); + expect(screen.getByText('post music for post people.')).toBeTruthy(); }); test('navigates to ArchivedShowView when tapping an archive in ShowDetails', async () => {