Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamStateEntity.Companion.PLAYBACK_FINISHED_END_MILLISECONDS
import org.schabi.newpipe.database.stream.model.StreamStateEntity.Companion.STREAM_PROGRESS_MILLIS
import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.util.image.ImageStrategy
Expand Down Expand Up @@ -52,6 +53,23 @@
}
}

/**
* The video will be considered as finished, if the time left is less than
* [PLAYBACK_FINISHED_END_MILLISECONDS] and the progress is at least 3/4 of the video length.
* The state will be saved anyway, so that it can be shown under stream info items, but the
* player will not resume if a state is considered as finished. Finished streams are also the
* ones that can be filtered out in the feed fragment.
* @return whether the stream is finished or not
*
* TODO: We already have isFinished method under StreamStateEntity in future we can club into

Check warning on line 64 in app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this TODO comment.

See more on https://sonarcloud.io/project/issues?id=TeamNewPipe_NewPipe&issues=AaBh0vuiVUdjwKfDFLN8&open=AaBh0vuiVUdjwKfDFLN8&pullRequest=13809
* helper class
*/
fun isFinished(): Boolean {
val durationInSeconds = streamEntity.duration
return progressMillis >= durationInSeconds * 1000 - PLAYBACK_FINISHED_END_MILLISECONDS &&
progressMillis >= durationInSeconds * 1000 * 3 / 4
}

companion object {
const val STREAM_LATEST_DATE = "latestAccess"
const val STREAM_WATCH_COUNT = "watchCount"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public class StatisticsPlaylistFragment
/* Used for independent events */
private Subscription databaseSubscription;
private HistoryRecordManager recordManager;
private boolean isFullyWatchedFilterApply = true;

private List<StreamStatisticsEntry> processResult(final List<StreamStatisticsEntry> results) {
final Comparator<StreamStatisticsEntry> comparator;
Expand All @@ -78,6 +79,12 @@ private List<StreamStatisticsEntry> processResult(final List<StreamStatisticsEnt
return null;
}
Collections.sort(results, comparator.reversed());

// Filter fully watched videos
if (!isFullyWatchedFilterApply) {
return results.stream().filter(it -> !it.isFinished()).toList();
}

return results;
}

Expand Down Expand Up @@ -277,6 +284,10 @@ public void handleResult(@NonNull final List<StreamStatisticsEntry> result) {
PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this);

headerBinding.sortButton.setOnClickListener(view -> toggleSortMode());
headerBinding.fullyWatchedFilterButtonCheckBox.setOnClickListener(view -> {
isFullyWatchedFilterApply = !isFullyWatchedFilterApply;
startLoading(true);
});

hideLoading();
}
Expand Down
108 changes: 77 additions & 31 deletions app/src/main/res/layout/statistic_playlist_control.xml
Original file line number Diff line number Diff line change
@@ -1,41 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<RelativeLayout
android:id="@+id/sortButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">

<ImageView
android:id="@+id/sortButtonIcon"
android:layout_width="48dp"
android:layout_height="28dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="@drawable/ic_filter_list"
tools:ignore="ContentDescription,RtlHardcoded" />

<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/sortButtonText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@id/sortButtonIcon"
android:gravity="left|center"
android:text="@string/title_most_played"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="RtlHardcoded" />
</RelativeLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<RelativeLayout
android:id="@+id/sortButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/fullyWatchedFilterButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1">

<ImageView
android:id="@+id/sortButtonIcon"
android:layout_width="48dp"
android:layout_height="28dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:src="@drawable/ic_filter_list"
tools:ignore="ContentDescription" />

<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/sortButtonText"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_toEndOf="@id/sortButtonIcon"
android:gravity="start|center_vertical"
android:text="@string/title_most_played"
android:textSize="15sp"
android:textStyle="bold" />

</RelativeLayout>

<RelativeLayout
android:id="@+id/fullyWatchedFilterButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
app:layout_constraintStart_toEndOf="@id/sortButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1">

<CheckBox
android:id="@+id/fullyWatchedFilterButtonCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:checked="false" />

<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/fullyWatchedFilterButtonText"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_toEndOf="@id/fullyWatchedFilterButtonCheckBox"
android:gravity="start|center_vertical"
android:text="@string/title_hide_watched"
android:textSize="15sp"
android:textStyle="bold" />

</RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

<include
android:id="@+id/playlist_control"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -905,4 +905,5 @@
<string name="api23_requirement_dialog_title">NewPipe is dropping support for Android 5</string>
<string name="api23_requirement_dialog_message">Unfortunately NewPipe depends on a few libraries that dropped support for Android 5.0 and 5.1. The next NewPipe release will therefore only work on devices with Android 6 or higher, sadly. Read more in the blogpost.</string>
<string name="api23_requirement_dialog_blogpost">Blogpost</string>
<string name="title_hide_watched">Hide Watched</string>
</resources>
Loading