Release ArchiveTune Nightly artifact, generated on 2026/07/24 - 07:32:20 (UTC +0)
π MVP Committer
Congratulations to @rukamori for contributing 113 commit(s) in this release! π
π Contribution Leaderboard
π₯ @rukamori: 113 commit(s)
π₯ @mikooochi: 61 commit(s)
π₯ @ffelixm: 8 commit(s)
π€ @gallegonovato: 8 commit(s)
π€ @midomizo933: 3 commit(s)
π€ @ooobamboo: 2 commit(s)
π€ @ValteMCPE: 2 commit(s)
π€ @Mickael81: 2 commit(s)
π€ @adam-adrian: 2 commit(s)
π€ @beebtw: 2 commit(s)
π€ @Anonymous: 2 commit(s)
π€ @IIXII-L192: 1 commit(s)
π€ @avatrax6: 1 commit(s)
π€ @marstraveler01: 1 commit(s)
π€ @Simone20031: 1 commit(s)
β¨ Changelog
30d9a77- "refactor(MainActivity): update visible condition in AnimatedVisibility using playerBottomSheetState #1019" by (@rukamori)bfae1cc- "refactor(MainActivity): replace playerBottomSheetState isCollapsed and isDismissed with isExpandedOrExpanding" by (@rukamori)59b4c96- "feat(QRCParser): add BetterLyrics Portato support #1060" by (@rukamori)53c9906- "feat(YTPlayerUtils): add ANDROID_VR_1_65_10 client and update client ordering logic in getOrderedStreamClients" by (@rukamori)9559ff8- "refactor(StreamClientUtils): replace ANDROID_VR_NO_AUTH with ANDROID_VR_1_65_10" by (@rukamori)a636357- "refactor(YouTubeLoginRepository): extract verificationAuthState and reorder accountInfo invocation" by (@rukamori)b36ceb6- "refactor(LoginViewModel): remove LoginEvent and delegate login initiation to startLogin" by (@rukamori)02d5a0e- "refactor(LoginScreen): extract YouTubeLoginWebViewClient" by (@rukamori)2672807- "refactor(App): replace visitorData with sessionId in authState check" by (@rukamori)0e9b892- "refactor(YTPlayerUtils): extract mintWebPlaybackPoTokens and add isForbiddenPlayerRequest" by (@rukamori)b345c9b- "refactor(PoTokenExtractionActivity): use YouTube.currentPlaybackAuthState to derive tokenBindingId and persistedVisitorData in completeIfReady" by (@rukamori)69072ce- "refactor(BrowserSupportPageRepository): remove existing start.io integration" by (@mikooochi)0aa793c- "feat(MediaItemExt): replace platform-specific null check with direct uri conversion for notification artwork" by (@mikooochi)09975ef- "feat(MediaItemExt): add conditional uri generation for ice cream build to avoid Android 15 metadata artwork crash" by (@rukamori)b5bcd42- "fix(CanvasArtworkPlayer): stop unsupported Canvas retry crashes #1047" by (@rukamori)01d373e- "feat(CanvasArtworkPlaybackCache): add media codec check to validate canvas video compatibility #1047" by (@rukamori)034ef42- "fix(MainActivity): replace playerBottomSheetState.isExpanded with playerBottomSheetState.isExpandedOrExpanding in shouldHideStatusBars condition #1038" by (@rukamori)9537323- "fix(App): use when (result) to handle GatekeeperResult.Allowed and Unavailable cases with Unit handling, replace if condition with retryable check" by (@rukamori)f1c4790- "fix(GatekeeperViewModel): handle blocked result by sending message through channel" by (@rukamori)f4d12df- "fix(GatekeeperRepository): handle IOException by returning Unavailable instead of Blocked" by (@rukamori)715b836- "update domain" by (@rukamori)6caef14- "fix(recognition,downloads,aod,sleeptimer,lyrics,gms): recognition flow, download controls, AOD touch, sleep timer pause, synced lyrics & Start.io GPL compliance (#1053)" by (@IIXII-L192)df82fcf- "bump release" by (@rukamori)169f858- "fix(FadingEdge): swap Color.Black and Color.Transparent in horizontalGradient colors" by (@rukamori)cb57019- "feat(OnlinePlaylistScreen): add fallbackPlaySong fallback to playerConnection.playQueue via toPlaylistPlaybackEndpoint" by (@rukamori)0c42fde- "refactor(MediaDetailHero): replace Row with BoxWithConstraints and use fadingEdge for MediaDetailPrimaryActions" by (@rukamori)a2b2a60- "refactor(MediaDetailHero): add horizontalScroll with LaunchedEffect to MediaDetailPrimaryActions" by (@rukamori)3248c0b- "refactor(MediaDetailHero): make MediaDetailHero MediaDetailPrimaryActions MediaDetailAction MediaDetailIconAction public and replace constrainWidth" by (@rukamori)64ea48c- "refactor(Queue): replace dragInfo pair with QueueDragInfo and QueueDragDestination" by (@rukamori)4d21e6c- "refactor(LibraryPlaylistsScreen): replace Row toggle with DropdownMenuItem and IconButton using weight and spacedBy" by (@rukamori)e188193- "refactor(MediaDetailHero): replace horizontalScroll row with MediaDetailBalancedActionLayout using layoutId MediaDetailActionLayoutId" by (@rukamori)22fd494- "refactor(PlaylistMenu): add catch for CancellationException and make PlaylistMenu public" by (@rukamori)42d097c- "fix(OnlinePlaylistViewModel): use compareAndSet" by (@rukamori)2addb5c- "feat(DatabaseDao): add clearAlbumSongs to delete song_album_map by" by (@rukamori)6a12e2b- "refactor(constant): remove AiProvider CLAUDE and OPENROUTER support" by (@rukamori)8db146b- "refactor(StartIoSupportAdRepository): add SupportAdMode enum with Rewarded and Automatic fallback handling" by (@rukamori)5e78cdd- "fix(BotGuardTokenGenerator): use stable continuation APIs #1034" by (@rukamori)76abc3f- "refactor(BotGuardTokenGenerator): wrap JS bridge callbacks in dispatchBridgeCallback with tryResume to prevent resume crashes #1034" by (@rukamori)4f4301f- "refactor(LocalPlaylistScreen): extract isReorderingEnabled and isSwipeToDeleteEnabled flags to simplify swipe/drag logic #1034" by (@rukamori)a1fd55d- "feat(PlayerConnection): expose extractorAuthenticationEvents and updateExtractorBearerToken" by (@rukamori)601ccc5- "refactor(MusicService): replace static bearer with InMemoryBearerTokenRepository and handleExtractorStreamHttpFailure for 401/403/410" by (@rukamori)63d9c33- "fix(PlayerMenu): invert V5 condition and set requireVertical for V7 in PlayerMenu canvas action" by (@rukamori)832c643- "refactor(PlayerMenu): gate refetch canvas to v5 only" by (@rukamori)aa53554- "refactor(ArchiveTuneCanvas): add forceRefresh param with CacheControl no-cache and CancellationException rethrow #530" by (@mikooochi)2c62309- "feat(AppleMusicProvider): add forceRefresh param to bypass cache and set Cache-Control no-cache header" by (@mikooochi)961ba9a- "feat(Player): collect canvasArtworkUpdates to guard v7CanvasArtwork via canvasArtworkRevision" by (@mikooochi)c26333d- "feat(CanvasArtworkResolver): add refetchCanvasArtworkForPlayback with forceRefresh param and CanvasArtworkPlaybackCache.replace" by (@mikooochi)0bc4b24- "feat(CanvasArtworkPlaybackCache): add replace() to overwrite CanvasCacheEntry for mediaId" by (@mikooochi)91c8e81- "feat(PlayerMenu): add refetch_canvas NewAction gated by ArchiveTuneCanvasKey and PlayerDesignStyle" by (@mikooochi)57ab119- "feat(PlayerConnection): add refetchCanvasArtwork with CanvasArtworkUpdate and CanvasArtworkRefetchResult" by (@mikooochi)f5138eb- "feat(ResolveSpotifyPlaylistDownloadsUseCase): add ResolveSpotifyPlaylistDownloadsUseCase resolving tracks to SpotifyDownloadItem with MAX_CONCURRENT_RESOLUTIONS=8" by (@mikooochi)496be8f- "feat(SpotifyPlaylistScreen): add download action with HeaderDownloadState and SpotifyPlaylistEvent handling" by (@mikooochi)4ca11a1- "feat(SpotifyPlaylistViewModel): add SpotifyPlaylistEvent and resolveDownloads with DownloadsResolved event" by (@mikooochi)35e84b9- "merge branch development" by (@mikooochi)7ed49ea- "Merge branch 'translate'" by (@mikooochi)b674ce6- "refactor(PlayerMenu): replace YouTubeQueue.radio with startRadioSeamlessly in PlayerMenu #1032" by (@mikooochi)4bff772- "feat(MediaDetailHero): add MediaDetailRemovalConfirmationDialog with LocalMenuState on onToggleAdd" by (@mikooochi)bba710f- "feat(BottomSheetMenu): add showDialog/dismissDialog with dialogContent state to MenuState" by (@mikooochi)b5bcf9c- "refactor(CustomizeBackground): remove unused matchParentSize and weight layout imports" by (@mikooochi)a3c3cf2- "Merge branch 'dev' of github-mikooochi:rukamori/ArchiveTune into dev" by (@mikooochi)2348922- "feat(CustomizeBackground): add persistBackgroundImagePermission and responsive CustomizeBackgroundContent layout with SnackbarHost" by (@mikooochi)0db0761- "feat(LyricsScreen): add LyricsBackgroundStyle enum and LyricsScreenBackground with LyricsBackgroundStyleKey preference" by (@mikooochi)2c47918- "fix: don't force-collapse bottom sheet on gesture cancel" by (@ooobamboo)b016a97- "refactor(core): populate endpoint with anyWatchEndpoint and watchEndpoint across page models" by (@mikooochi)57e97f9- "fix(OnlinePlaylistViewModel): apply filterVideo with HideVideoKey to playlist songs loading" by (@mikooochi)e056c95- "fix(LocalPlaylistViewModel): filter playlist songs by HideVideoKey dataStore preference" by (@mikooochi)89e9c90- "refactor(LibraryViewModels): apply filterVideo with HideVideoKey in LibrarySongs and ArtistSongs viewmodels" by (@mikooochi)d3739cb- "feat(CachePlaylistViewModel): apply filterVideo with HideVideoKey to cached playlist flow" by (@mikooochi)1bb0829- "fix(AutoPlaylistViewModel): include HideVideoKey in liked songs Triple and pass hideVideo to database.likedSongs" by (@mikooochi)8446613- "refactor(ArtistViewModel): apply filterVideo with HideVideoKey alongside filterExplicit in librarySongs and artist sections" by (@mikooochi)9a218f5- "feat(ArtistItemsViewModel): apply filterVideo with HideVideoKey to artist items flow" by (@mikooochi)290c105- "refactor(AlbumViewModel): combine HideVideoKey DataStore with albumWithSongs and apply filterVideo" by (@mikooochi)8a301be- "fix(SyncUtils): preserve metadata via update(dbSong, mediaMetadata) in like and library sync paths" by (@mikooochi)0d94b4b- "feat(MusicService): add hideMusicVideos filtering via HideVideoKey and removeMusicVideoItems" by (@mikooochi)2ede851- "feat(MediaMetadata): add isMusicVideo field to MediaMetadata and Song.toMediaMetadata" by (@mikooochi)bd763e8- "fix(MediaItemExt): set MusicVideo artwork via buildYTThumbnailUrl and propagate isMusicVideo in ExtraIsMusicVideo" by (@mikooochi)bcfa250- "fix(ListExt): implement filterVideo to filter songs where song.isMusicVideo is true" by (@mikooochi)064f725- "fix(MusicDatabase): bump CURRENT_VERSION from 32 to 33" by (@mikooochi)333a866- "refactor(DatabaseDao): replace set_video_id join with isMusicVideo filter in library and liked song queries" by (@mikooochi)2f9776c- "feat(SongEntity): add isMusicVideo ColumnInfo field with defaultValue 0 to SongEntity" by (@mikooochi)d2f9f50- "refactor(JavaScriptPlanCompiler): indentation and control flow in findDeclaration and normalizedDeclaration" by (@mikooochi)4cf98c8- "refactor(JavaScriptPlanCompiler): change findDeclarationStart to return Int and add var prefix in normalizedDeclaration with IDENTIFIER_PATTERN" by (@mikooochi)43a6388- "feat(MusicService): add removeBlockedArtistItems and filterPlaybackContent to enforce blockedArtistIds in queue" by (@mikooochi)e4143eb- "feat(Queue): add filterBlockedArtists and hasBlockedArtist to exclude blocked artist MediaItems" by (@mikooochi)de6e567- "refactor(Updater): add downloadUrl to ReleaseInfo and workflow fallback via CanaryWorkflowRunsUrl #1025" by (@rukamori)0e75286- "refactor(UpdateScreen): guard onCheckForUpdate with updateCheckJob and use getLatestCanaryReleaseInfo" by (@rukamori)0f581ec- "fix(AiContentFilterRepository): replace tryResume with coroutines resume for continuation completion" by (@rukamori)53b612f- "update fastlane metadata" by (@rukamori)1e4e68c- "fix(LibraryScreen): anchor refresh indicator below app bar" by (@rukamori)5728238- "refactor(ExpressivePullToRefreshBox): replace indicatorPadding with indicatorOffset Dp param using offset modifier" by (@rukamori)115d0de- "feat: implement ai filtering with morphe patches AiSlopList.com" by (@rukamori)758294e- "Translated using Weblate (Turkish)" by (@avatrax6)4215586- "fix(PlaylistCoverRepository): sync remote and preserve local covers" by (@rukamori)407cb49- "fix(LyricsPreloadManager): atomic insert-or-replace-not-found persistence" by (@rukamori)68c8478- "Merge branch" by (@rukamori)1fcfe69- "fix(NetworkGatekeeper): clarify unverified build warning" by (@rukamori)1133e9b- "fix(GatekeeperRepository): recover from transient gate failures" by (@rukamori)a006558- "Translated using Weblate (German)" by (@ffelixm)659194e- "Translated using Weblate (German)" by (@ffelixm)7ab1695- "Translated using Weblate (German)" by (@ffelixm)109eedb- "Kotlin Header" by (@rukamori)5660187- "chore: remove unused heading text from library" by (@rukamori)a48646b- "fix(CreatePlaylistDialog): persist playlists before dismissing" by (@rukamori)0ab8fdd- "Translated using Weblate (Arabic (Egyptian))" by (@midomizo933)b160adf- "Translated using Weblate (Arabic (Egyptian))" by (@midomizo933)932878e- "Translated using Weblate (Arabic)" by (@midomizo933)0821698- "Translated using Weblate (Spanish)" by (@gallegonovato)b9b14aa- "Translated using Weblate (Spanish)" by (@gallegonovato)f0827ec- "Translated using Weblate (Spanish)" by (@gallegonovato)78688f7- "patch lyrics search dialog ui issue" by (@rukamori)772ee02- "fix equalizer hero color" by (@rukamori)8158ced- "Translated using Weblate (Portuguese (Brazil))" by (@ValteMCPE)6117c14- "Translated using Weblate (Portuguese (Brazil))" by (@ValteMCPE)5f0ed66- "Translated using Weblate (French)" by (@Mickael81)1b23e1d- "Translated using Weblate (French)" by (@Mickael81)5a8a69c- "Translated using Weblate (German)" by (@ffelixm)06aab1f- "chore: cleanup unused drawable resources" by (@rukamori)3efda47- "fix(LyricsMenu): resolve composable shape conversion error" by (@rukamori)c357612- "chore: cleanup unused resources" by (@rukamori)65514c2- "feat: extended equalizer control basic with advanced and reformat kotlin structure" by (@rukamori)35c2861- "extend search lyrics dialog" by (@rukamori)eca6092- "fix(AutoPlaylistScreen): keep search results below app bar" by (@rukamori)60c3078- "fix(LibraryMixScreen): restore top playlist quick access" by (@rukamori)3a3db0e- "feat(CachePlaylistScreen): align remaining playlist detail screens" by (@rukamori)615f764- "Translated using Weblate (German)" by (@ffelixm)205d0e1- "fix gatekeeper parameter mismatch" by (@rukamori)1a957ac- "Fix/liked songs sort stability (#1022)" by (@ooobamboo, @rukamori)70caa9a- "fix(ui): adapt thumbnail ratios and optimize image loading (#1012)" by (@adam-adrian, @rukamori)1cc0ca0- "fix(LyricsHelper): force fresh cancellable lyrics searches" by (@rukamori)43b7fc1- "feat(GatekeeperRepository): add startup network gate" by (@rukamori)5c26beb- "Translated using Weblate (Spanish)" by (@gallegonovato)4fbafa4- "Translated using Weblate (Urdu)" by (@beebtw)41c5fe5- "Translated using Weblate (Spanish)" by (@gallegonovato)8918621- "Translated using Weblate (Spanish)" by (@gallegonovato)e213fd2- "Translated using Weblate (German)" by (@ffelixm)b255df6- "fix(AutoPlaylistScreen): remove invalid padding import" by (@rukamori)c430e6b- "feat(MediaDetailHero): unify responsive media detail actions" by (@rukamori)63d86a6- "Translated using Weblate (Urdu)" by (@beebtw)a32ca8a- "Translated using Weblate (Spanish)" by (@gallegonovato)624a4ab- "Translated using Weblate (Spanish)" by (@gallegonovato)90fd7b6- "Translated using Weblate (Vietnamese)" by (@marstraveler01)4776544- "Translated using Weblate (German)" by (@ffelixm)ade089a- "Translated using Weblate (German)" by (@ffelixm)e3f2758- "refactor(SettingsScreen): group settings into sections" by (@rukamori)74002e9- "fix(AboutScreen): tighten section spacing" by (@rukamori)907a0f7- "fix(AlbumScreen): restore media screen structure" by (@rukamori)8b9db66- "feat: reconstruct album and playlist screen data" by (@rukamori)a0356e5- "fix(CoilBitmapLoader): prevent recycled artwork crash" by (@rukamori)79ab042- "refactor(ArtistScreen): compact playback actions and release spacing" by (@rukamori)5fe40d4- "Translated using Weblate (Portuguese (Brazil))" by (@Anonymous)9a02c12- "Translated using Weblate (Japanese)" by (@Anonymous)479dfd3- "fix: resolve compose compilation" by (@rukamori)2270939- "feat: remap structure screen" by (@rukamori)b2a37c7- "fix(StartIoSupportAdRepository): preserve SDK retry after no fill" by (@rukamori)193b07b- "fix(StartIoSupportAdRepository): match nullable failure callback" by (@rukamori)81ee123- "patching issue" by (@rukamori)7359783- "fix(SupportArchiveTuneSection): correct Compose and preference APIs" by (@rukamori)7947388- "fix(build.gradle): make task validation cache-safe" by (@rukamori)e7be1b0- "fix(AboutScreen): use standalone lead developer shape" by (@rukamori)bc1fad8- "Patch" by (@rukamori)b7eaa79- "fix(DownloadLibraryViewModel): queue subsequent downloaded songs" by (@rukamori)f9153cf- "fix(SearchScreen): fill active suggestion segment" by (@rukamori)e5d073d- "fix(HistoryScreen): fill segmented active song highlight" by (@rukamori)471e735- "fix(UpdateScreen): round standalone list surfaces" by (@rukamori)f0199e4- "refactor: playback error data and cleanup unused resources" by (@rukamori)e7684e4- "fix(MainActivity): avoid stale nav entry viewmodel access" by (@rukamori)60f1585- "refactor(UpdateScreen): reconstruct update status" by (@rukamori)4323b7e- "fix(UpdateScreen): add tonal segmented surfaces" by (@rukamori)132fc35- "fix(SpotifyAuth): harden shared token refresh to prevent rate limit" by (@rukamori)dd31522- "fix(UpdateScreen): move shape conversion into composition" by (@rukamori)461edc1- "style: rconstruct data update and history" by (@rukamori)ca2de9a- "fix(AlbumPage): restore companion parser scope" by (@rukamori)0fe0d49- "fix(MiniPlayer): align paired floating surfaces" by (@rukamori)4c9fea2- "fix(MusicServiceWidgetUpdater): stop continuous widget battery drain #1017" by (@rukamori)f24aacc- "fix(CoilBitmapLoader): prevent blurry notification artwork #1011" by (@rukamori)4e923aa- "fix(FloatingNavigationToolbar): restore stable destination measurement" by (@mikooochi)c3600c4- "chore: decrease navigation bar height" by (@mikooochi)f8df05e- "chore: rename mismatch settings data builder" by (@mikooochi)c005f1c- "refactor(FloatingNavigationToolbar): tighten persistent control spacing" by (@mikooochi)d50bcd3- "fix(BackupAndRestore): repair scheduled backup layout structure" by (@mikooochi)bb40a3b- "fix(MainActivity): disambiguate FAB visibility animation" by (@mikooochi)08d6eb0- "refactor(MainActivity): detach overflow FAB from navbar" by (@mikooochi)7ed410e- "cleanup unused string" by (@mikooochi)128a210- "remove unused preference key" by (@mikooochi)27abfcb- "fix(FloatingNavigationToolbar): distribute navigation destinations evenly" by (@mikooochi)7a94509- "refactor(ScheduledBackupRepository): adjust Cursor::readDisplayName call in use block" by (@mikooochi)63c93af- "refactor(FloatingNavigationToolbar): remove weight import and resolve onDoubleClick return" by (@mikooochi)93c7f41- "refactor(MiniPlayerComponents): restore circular artwork progress and use short navigation bar instead floating toolbar" by (@mikooochi)b91402a- "feat(BackupAndRestore): add scheduled auto backups" by (@mikooochi)7bc1583- "fix(AccountSettings): avoid false logged-out label" by (@mikooochi)97b8ee1- "refactor(SpotifyAuth): use URI.create for HttpURLConnection in performGetRequest" by (@mikooochi)2720503- "fix(AboutScreen): resolve RowScope weight modifier" by (@mikooochi)263654d- "feat(MiniPlayerComponents): reconstruct miniplayer" by (@mikooochi)f066aa9- "fix(CanvasArtworkResolver): reject mismatched canvas artwork" by (@mikooochi)11ce643- "feat(AboutScreen): reconstruct layout" by (@rukamori)edd6115- "fix(HistoryViewModel): integrate lazy load to prevent laggy" by (@rukamori)c4d4734- "feat(library/search): add icon in tabs row" by (@rukamori)a415396- "feat: improve AI playlist mixes and enable swipe-to-queue by default (#1014)" by (@Simone20031, @rukamori)8d1bfed- "refactor(playback): remove MediaController and extract shouldShowPlaybackNotification" by (@rukamori)8cbc767- "feat(player): lazy-load, cache, and display real bitrate & sample rate fallbacks for local audio (#1000)" by (@adam-adrian, @rukamori)ad6416a- "fix(HistoryScreen): remove remember wrapper from MaterialShapes and fix trailing comma" by (@rukamori)601cf21- "chore(proguard-rules): add NewPipeExtractor keep rules and reflection attributes" by (@rukamori)144fa13- "feat: remap account structure and reformat kotlin structure" by (@rukamori)0176e15- "remap history screen" by (@rukamori)d668229- "chore(Updater): Switch GitHub releases repo to canary" by (@rukamori)