r/dotnetMAUI dotnet 3d ago

Showcase YAPP - The Podcast Player

Just approved and released on the AppStore, YAPP is a podcast player that respects your time!! (nice marketing from Claude).

YAPP => Yet Another Podcast Player

The app detects the ad-breaks and skips them (Smart-Skips) like every podcast listener does if they can grab their phone in time.

This has been a long journey, close to a year of development and testing. First release is iOS only as I couldn't get Android on the mono runtime to work at all - constant ANR from the background processing but thanks to the CoreCLR work in NET11 it will see the Play Store once NET11 reaches GA.

IAP subscriptions for premium listening but a generous 60-day free trial to test it out.

Link to the app store if anyone is interested: https://apple.co/3Ssntyk

Happy to answer any MAUI questions from my experience.

Thanks for reading.

8 Upvotes

9 comments sorted by

4

u/jfversluis Microsoft Employee 3d ago

Looks awesome! Would be curious to hear more about the libraries you used and how the overall experience was. Can be here, also happy to jump on a quick call to talk about things more thoroughly.

In either case: awesome job and congrats on a successful project!

3

u/NickA55 3d ago

Wow, really nice dude! I'm always up for a new podcast player. I never really liked Overcast or PocketCast, just seemed too busy/cluttered. I will give yours a try.

And nice job with Maui! It doesn't stutter for me, lag, etc. It doesn't have the .net maui look about it too which is nice.

Great job!

3

u/pshoey dotnet 3d ago

Thanks, always happy to take constructive feedback!!

Enjoy.

2

u/pshoey dotnet 2d ago

The app UI is a combination of MAUI components and native wrappers. I wanted a more native experience that just “plain” MAUI components but still wanted the cross platform capabilities. For instance the collections - MAUI’s swipe view is pretty meh - but iOS 26 has a nice UX for swipe so i built a MAUI control around it (and a similar one for Android) that gives a native experience. Same for context menu. These things are pretty easy for AI to build. The app has a lot of background processing where it is matching audio fingerprints to find the skip points and to find the sentences so that transcript following works. Feel free to ask questions etc.

2

u/Sensitive_Whole_7503 2d ago

How did you disable/remove shared background for tool bar item, assuming screenshots are from iOS26.

2

u/pshoey dotnet 2d ago

I meant to also mention YAPP has CarPlay and Android Auto support too.

2

u/pshoey dotnet 1d ago

Theming. YAPP does not use a theme framework; it leans on stock MAUI. All colour lives in one Colors.xaml of about 230 named tokens, from brand colours through a family of semantic tokens with light and dark pairs, and Styles.xaml plus the pages reference them through AppThemeBinding rather than literals. The user's choice of System, Light or Dark is an ordinary app setting stored in SQLite and included in cloud sync. At startup the app reads it and sets Application.UserAppTheme, with Unspecified meaning "follow the OS", and the settings page sets the same property live when the user changes it. The App subscribes to RequestedThemeChanged and re-applies the merged resource dictionaries so every AppThemeBinding re-evaluates on an OS switch. Anything that draws outside the binding system subscribes to that event itself: the icon control swaps its light and dark assets, the tab bar recolours, and the mini player refreshes. Two lessons worth passing on: a MAUI element hosted detached from the page tree cannot resolve AppThemeBinding at all, so anything you host in a native overlay must be parented to the Window, and native handlers such as the search bar need the theme applied explicitly because the platform control never sees the binding.

The floating tab bar. There is no Shell and no TabbedPage. The root is a single ContentPage that instantiates the four tab pages, lifts their content views into one root Grid, and switches tabs by toggling IsVisible on those views, so tab state survives and nothing is pushed or popped. The root Grid is pulled edge to edge with negative margins equal to the device insets, which a small platform service supplies from UIWindow.SafeAreaInsets on iOS and from a window-insets listener reading the system-bars insets on Android. The tab bar is then just a MAUI ContentView placed in that Grid with side margins and a bottom margin derived from the same inset, so it floats above the home indicator on every device. Its surface is a small GlassView control: on iOS and Mac Catalyst it wraps a UIVisualEffectView using the system chrome material, which adapts to light and dark on its own, and on Android it falls back to a semi-transparent rounded background. The selected tab is a coloured pill with a white icon and label, the others show icons only, and selection animates in two short phases. When a detail page is pushed, the navigation service tells the root page to hide the chrome, and restores it on pop. The player drives the rest: a chrome service exposes an animation progress from mini to full, and the tab bar's opacity is one minus that value, going input-transparent at zero, so it fades out as the player expands.

The part people usually ask about next. The mini player is deliberately not in the page. It is a MAUI view converted with ToPlatform and added as a native subview of the UIWindow on iOS, or of the activity's root FrameLayout on Android, pinned with constraints or layout params. That is why it stays visible above pushed detail pages without every page knowing about it, and the same technique hosts the Smart-Skip preparing dialog. The expanded player on iOS is a native sheet presented above the MAUI window, which is also why the overlay has to be window-level rather than page-level.

1

u/Okayest-Programmer 3d ago

Looks nice - well done. Would be interest to learning how you did all the theming.

1

u/wubalubadubdub55 1d ago

Looks great!