Skip to content

Migrate watch history to Jetpack Compose - #11947

Merged
Isira-Seneviratne merged 53 commits into
TeamNewPipe:refactorfrom
Isira-Seneviratne:History-Compose
Jul 10, 2026
Merged

Isira-Seneviratne merged 53 commits into
TeamNewPipe:refactorfrom
Isira-Seneviratne:History-Compose

Conversation

@Isira-Seneviratne

@Isira-Seneviratne Isira-Seneviratne commented Jan 21, 2025 •

Copy link
Copy Markdown
Member

What is it?

  • Bugfix (user facing)
  • Feature (user facing)
  • Codebase improvement (dev facing)
  • Meta improvement to the project (dev facing)

Description of the changes in your PR

  • Rewrite the watch history UI using Jetpack Compose. As part of this change, the ItemList composable was refactored to use separate data classes, in order to further decouple it from the information provided by the extractor and make it more easily reusable.
  • Clean up unused methods in StreamHistoryDAO.
  • Reimplement the watch history retrieval from the Room database using AndroidX Paging for improved efficiency, as it supports pagination.
  • Add stream card and grid composables.
  • Update several relevant dependencies, including the Compose BOM version.
  • Use loading indicator for placeholder items in ItemList.

Before/After Screenshots/Screen Record

Before After
Before After
Screen_recording_20250311_110112.mp4

Fixes the following issue(s)

  • Fixes #

APK testing

The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.

Due diligence

@github-actions github-actions Bot added the size/giant PRs with more than 750 changed lines label Jan 21, 2025
@ShareASmile ShareASmile added history Anything to do with previously watched stuff rewrite Issues and PRs related to rewrite GUI Issue is related to the graphical user interface dependency Issues and PRs related to dependencies labels Jan 21, 2025
@asandikci

Copy link
Copy Markdown

There should be a confirmation screen after "clear history" button clicked I guess

@Isira-Seneviratne
Isira-Seneviratne force-pushed the History-Compose branch 2 times, most recently from 135d560 to e5882af Compare February 9, 2025 15:08
@ShareASmile

Copy link
Copy Markdown
Collaborator

Produces Error on data export, I can export with playlist fragment to Jetpack compose PR fine (as I am currently testing the two) It looks specific to this PR or
Is it related to what is for #12415 in the first place?

Exception

  • User Action: database import or export
  • Request: Exporting database and settings
  • Content Country: GB
  • Content Language: en-GB
  • App Language: en_GB
  • Service: none
  • Timestamp: 2025-07-11T22:40:21.929+05:30
  • Package: org.schabi.newpipe.debug.HistoryCompose
  • Service: none
  • Version: 0.27.7
  • OS: Linux samsung/a22xnnxx/a22x:13/TP1A.220624.014/A226BXXU7DWH4:user/release-keys 13 - 33
Crash log

[java.lang.IllegalStateException](https://github.com/TeamNewPipe/NewPipe/pull/java.lang.IllegalStateException): Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
	at [androidx.room.RoomDatabase.assertNotMainThread](https://github.com/TeamNewPipe/NewPipe/pull/androidx.room.RoomDatabase.assertNotMainThread)(roomdatabase.android.kt:562)
	at [androidx.room.RoomDatabase.query](https://github.com/TeamNewPipe/NewPipe/pull/androidx.room.RoomDatabase.query)(roomdatabase.android.kt:612)
	at [org.schabi.newpipe.NewPipeDatabase.checkpoint](https://github.com/TeamNewPipe/NewPipe/pull/org.schabi.newpipe.NewPipeDatabase.checkpoint)(newpipedatabase.java:56)
	at [org.schabi.newpipe.settings.BackupRestoreSettingsFragment.exportDatabase](https://github.com/TeamNewPipe/NewPipe/pull/org.schabi.newpipe.settings.BackupRestoreSettingsFragment.exportDatabase)(backuprestoresettingsfragment.java:163)
	at [org.schabi.newpipe.settings.BackupRestoreSettingsFragment.requestExportPathResult](https://github.com/TeamNewPipe/NewPipe/pull/org.schabi.newpipe.settings.BackupRestoreSettingsFragment.requestExportPathResult)(backuprestoresettingsfragment.java:137)
	at [org.schabi.newpipe.settings.BackupRestoreSettingsFragment](https://github.com/TeamNewPipe/NewPipe/pull/org.schabi.newpipe.settings.BackupRestoreSettingsFragment).$r8$lambda$fGteoRaC9h1Pn2xEuX2RRkPtyno(Unknown Source:0)
	at [org.schabi.newpipe.settings.BackupRestoreSettingsFragment](https://github.com/TeamNewPipe/NewPipe/pull/org.schabi.newpipe.settings.BackupRestoreSettingsFragment)$$[ExternalSyntheticLambda8.onActivityResult](https://github.com/TeamNewPipe/NewPipe/pull/ExternalSyntheticLambda8.onActivityResult)(D8$$SyntheticClass:0)
	at [androidx.activity.result.ActivityResultRegistry.doDispatch](https://github.com/TeamNewPipe/NewPipe/pull/androidx.activity.result.ActivityResultRegistry.doDispatch)(activityresultregistry.java:414)
	at [androidx.activity.result.ActivityResultRegistry.dispatchResult](https://github.com/TeamNewPipe/NewPipe/pull/androidx.activity.result.ActivityResultRegistry.dispatchResult)(activityresultregistry.java:371)
	at [androidx.activity.ComponentActivity.onActivityResult](https://github.com/TeamNewPipe/NewPipe/pull/androidx.activity.ComponentActivity.onActivityResult)(componentactivity.java:845)
	at [androidx.fragment.app.FragmentActivity.onActivityResult](https://github.com/TeamNewPipe/NewPipe/pull/androidx.fragment.app.FragmentActivity.onActivityResult)(fragmentactivity.java:151)
	at [android.app.Activity.dispatchActivityResult](https://github.com/TeamNewPipe/NewPipe/pull/android.app.Activity.dispatchActivityResult)(activity.java:8951)
	at [android.app.ActivityThread.deliverResults](https://github.com/TeamNewPipe/NewPipe/pull/android.app.ActivityThread.deliverResults)(activitythread.java:5987)
	at [android.app.ActivityThread.handleSendResult](https://github.com/TeamNewPipe/NewPipe/pull/android.app.ActivityThread.handleSendResult)(activitythread.java:6033)
	at [android.app.servertransaction.ActivityResultItem.execute](https://github.com/TeamNewPipe/NewPipe/pull/android.app.servertransaction.ActivityResultItem.execute)(activityresultitem.java:67)
	at [android.app.servertransaction.ActivityTransactionItem.execute](https://github.com/TeamNewPipe/NewPipe/pull/android.app.servertransaction.ActivityTransactionItem.execute)(activitytransactionitem.java:45)
	at [android.app.servertransaction.TransactionExecutor.executeCallbacks](https://github.com/TeamNewPipe/NewPipe/pull/android.app.servertransaction.TransactionExecutor.executeCallbacks)(transactionexecutor.java:135)
	at [android.app.servertransaction.TransactionExecutor.execute](https://github.com/TeamNewPipe/NewPipe/pull/android.app.servertransaction.TransactionExecutor.execute)(transactionexecutor.java:95)
	at [android.app.ActivityThread](https://github.com/TeamNewPipe/NewPipe/pull/android.app.ActivityThread)$[H.handleMessage](https://github.com/TeamNewPipe/NewPipe/pull/H.handleMessage)(activitythread.java:2574)
	at [android.os.Handler.dispatchMessage](https://github.com/TeamNewPipe/NewPipe/pull/android.os.Handler.dispatchMessage)(handler.java:106)
	at [android.os.Looper.loopOnce](https://github.com/TeamNewPipe/NewPipe/pull/android.os.Looper.loopOnce)(looper.java:226)
	at [android.os.Looper.loop](https://github.com/TeamNewPipe/NewPipe/pull/android.os.Looper.loop)(looper.java:313)
	at [android.app.ActivityThread.main](https://github.com/TeamNewPipe/NewPipe/pull/android.app.ActivityThread.main)(activitythread.java:8762)
	at [java.lang.reflect.Method.invoke](https://github.com/TeamNewPipe/NewPipe/pull/java.lang.reflect.Method.invoke)(Native Method)
	at [com.android.internal.os.RuntimeInit](https://github.com/TeamNewPipe/NewPipe/pull/com.android.internal.os.RuntimeInit)$[MethodAndArgsCaller.run](https://github.com/TeamNewPipe/NewPipe/pull/MethodAndArgsCaller.run)(runtimeinit.java:604)
	at [com.android.internal.os.ZygoteInit.main](https://github.com/TeamNewPipe/NewPipe/pull/com.android.internal.os.ZygoteInit.main)(zygoteinit.java:1067)


@Isira-Seneviratne

Copy link
Copy Markdown
Member Author

Produces Error on data export, I can export with playlist fragment to Jetpack compose PR fine (as I am currently testing the two) It looks specific to this PR or
Is it related to what is for #12415 in the first place?

Yes, I had to update the Room version in this PR in order to use PagingSource.

@Isira-Seneviratne

Copy link
Copy Markdown
Member Author

@ShareASmile It should be working now.

@ShareASmile

Copy link
Copy Markdown
Collaborator

Just did a quick test and now it works flawlessly. Thank you for all your efforts :).

# Conflicts:
#	app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamMenu.kt
# Conflicts:
#	app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java
#	gradle/libs.versions.toml
@Isira-Seneviratne Isira-Seneviratne added the ready for review Most of the work is done, PR is now ready for a review label Aug 5, 2025
# Conflicts:
#	app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java
# Conflicts:
#	app/build.gradle
#	app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java
#	app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt
#	app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamStateDAO.kt
#	app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java
#	app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamUtils.kt
#	gradle/libs.versions.toml
# Conflicts:
#	app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt
#	app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt
#	app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt
#	app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java
#	app/src/main/java/org/schabi/newpipe/ui/components/about/LicenseDialog.kt
#	app/src/main/java/org/schabi/newpipe/ui/components/items/ItemList.kt
#	app/src/main/java/org/schabi/newpipe/ui/components/items/playlist/PlaylistListItem.kt
#	app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamThumbnail.kt
#	app/src/main/java/org/schabi/newpipe/ui/components/video/RelatedItems.kt
# Conflicts:
#	app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
#	app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
#	app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java
#	app/src/main/res/values-ca/strings.xml
#	app/src/main/res/values-eu/strings.xml
#	app/src/main/res/values-in/strings.xml
#	app/src/main/res/values-lv/strings.xml
@Isira-Seneviratne
Isira-Seneviratne merged commit fe08459 into TeamNewPipe:refactor Jul 10, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Rewrite Jul 10, 2026
@TobiGr

TobiGr commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor

Thank you for the work. I am sorry for not reviewing the PR. THere is one thing that should be changed imo. The play chips are too large. Can we change them to the same structure as done for the sort order? Play (headset icon | fullscreen icon | popup/pip icon)? The text is too long in German and other languages.

Screenshot_20260710-065912_NewPipe refactor nightly

@Isira-Seneviratne

Copy link
Copy Markdown
Member Author

Sure, I'll adjust the layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependency Issues and PRs related to dependencies GUI Issue is related to the graphical user interface history Anything to do with previously watched stuff ready for review Most of the work is done, PR is now ready for a review rewrite Issues and PRs related to rewrite size/giant PRs with more than 750 changed lines

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants