Add podcast specific statistics to podcast info screen (#4601)
This commit is contained in:
parent
3a87982628
commit
4a4392e797
|
@ -18,6 +18,7 @@ import androidx.appcompat.widget.Toolbar;
|
|||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
|
@ -25,6 +26,7 @@ import android.view.MenuInflater;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
@ -43,22 +45,24 @@ import de.danoeh.antennapod.core.glide.FastBlurTransformation;
|
|||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.storage.StatisticsItem;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.LangUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
||||
import de.danoeh.antennapod.fragment.preferences.StatisticsFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import de.danoeh.antennapod.view.ToolbarIconTintManager;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.Maybe;
|
||||
import io.reactivex.MaybeOnSubscribe;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Displays information about a feed.
|
||||
|
@ -71,13 +75,15 @@ public class FeedInfoFragment extends Fragment {
|
|||
|
||||
private Feed feed;
|
||||
private Disposable disposable;
|
||||
private Disposable disposableStatistics;
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private TextView txtvDescription;
|
||||
private TextView lblLanguage;
|
||||
private TextView txtvLanguage;
|
||||
private TextView lblAuthor;
|
||||
private TextView txtvAuthor;
|
||||
private TextView lblStatistics;
|
||||
private TextView txtvPodcastTime;
|
||||
private TextView txtvPodcastSpace;
|
||||
private TextView txtvPodcastEpisodeCount;
|
||||
private Button btnvOpenStatistics;
|
||||
private TextView txtvUrl;
|
||||
private TextView txtvAuthorHeader;
|
||||
private ImageView imgvBackground;
|
||||
|
@ -144,13 +150,23 @@ public class FeedInfoFragment extends Fragment {
|
|||
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
|
||||
|
||||
txtvDescription = root.findViewById(R.id.txtvDescription);
|
||||
lblLanguage = root.findViewById(R.id.lblLanguage);
|
||||
txtvLanguage = root.findViewById(R.id.txtvLanguage);
|
||||
lblAuthor = root.findViewById(R.id.lblAuthor);
|
||||
txtvAuthor = root.findViewById(R.id.txtvDetailsAuthor);
|
||||
lblStatistics = root.findViewById(R.id.lblStatistics);
|
||||
txtvPodcastSpace = root.findViewById(R.id.txtvPodcastSpaceUsed);
|
||||
txtvPodcastEpisodeCount = root.findViewById(R.id.txtvPodcastEpisodeCount);
|
||||
txtvPodcastTime = root.findViewById(R.id.txtvPodcastTime);
|
||||
btnvOpenStatistics = root.findViewById(R.id.btnvOpenStatistics);
|
||||
txtvUrl = root.findViewById(R.id.txtvUrl);
|
||||
|
||||
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
||||
|
||||
btnvOpenStatistics.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
StatisticsFragment fragment = new StatisticsFragment();
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
|
||||
}
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -170,6 +186,7 @@ public class FeedInfoFragment extends Fragment {
|
|||
.subscribe(result -> {
|
||||
feed = result;
|
||||
showFeed();
|
||||
loadStatistics();
|
||||
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
|
||||
}
|
||||
|
||||
|
@ -212,30 +229,61 @@ public class FeedInfoFragment extends Fragment {
|
|||
txtvDescription.setText(description);
|
||||
|
||||
if (!TextUtils.isEmpty(feed.getAuthor())) {
|
||||
txtvAuthor.setText(feed.getAuthor());
|
||||
txtvAuthorHeader.setText(feed.getAuthor());
|
||||
} else {
|
||||
lblAuthor.setVisibility(View.GONE);
|
||||
txtvAuthor.setVisibility(View.GONE);
|
||||
}
|
||||
if (!TextUtils.isEmpty(feed.getLanguage())) {
|
||||
txtvLanguage.setText(LangUtils.getLanguageString(feed.getLanguage()));
|
||||
} else {
|
||||
lblLanguage.setVisibility(View.GONE);
|
||||
txtvLanguage.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}");
|
||||
Iconify.addIcons(txtvUrl);
|
||||
|
||||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private void loadStatistics() {
|
||||
if (disposableStatistics != null) {
|
||||
disposableStatistics.dispose();
|
||||
}
|
||||
|
||||
disposableStatistics =
|
||||
Observable.fromCallable(() -> {
|
||||
List<StatisticsItem> statisticsData = DBReader.getStatistics();
|
||||
|
||||
for (StatisticsItem statisticsItem : statisticsData) {
|
||||
if (statisticsItem.feed.getId() == feed.getId()) {
|
||||
return statisticsItem;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
txtvPodcastTime.setText(Converter.shortLocalizedDuration(
|
||||
getContext(), result.timePlayed));
|
||||
txtvPodcastSpace.setText(Formatter.formatShortFileSize(
|
||||
getContext(), result.totalDownloadSize));
|
||||
txtvPodcastEpisodeCount.setText(String.format(Locale.getDefault(),
|
||||
"%d%s", result.episodesDownloadCount,
|
||||
getString(R.string.episodes_suffix)));
|
||||
}, error -> {
|
||||
Log.d(TAG, Log.getStackTraceString(error));
|
||||
lblStatistics.setVisibility(View.GONE);
|
||||
txtvPodcastSpace.setVisibility(View.GONE);
|
||||
txtvPodcastTime.setVisibility(View.GONE);
|
||||
txtvPodcastEpisodeCount.setVisibility(View.GONE);
|
||||
btnvOpenStatistics.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
|
||||
if (disposableStatistics != null) {
|
||||
disposableStatistics.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.adapter.PlaybackStatisticsListAdapter;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
|
@ -79,7 +78,6 @@ public class PlaybackStatisticsFragment extends Fragment {
|
|||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
||||
refreshStatistics();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
@ -30,6 +31,7 @@ public class StatisticsFragment extends Fragment {
|
|||
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager2 viewPager;
|
||||
private Toolbar toolbar;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -43,6 +45,7 @@ public class StatisticsFragment extends Fragment {
|
|||
|
||||
View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
|
||||
viewPager = rootView.findViewById(R.id.viewpager);
|
||||
toolbar = rootView.findViewById(R.id.toolbar);
|
||||
viewPager.setAdapter(new StatisticsPagerAdapter(this));
|
||||
// Give the TabLayout the ViewPager
|
||||
tabLayout = rootView.findViewById(R.id.sliding_tabs);
|
||||
|
@ -59,7 +62,12 @@ public class StatisticsFragment extends Fragment {
|
|||
}
|
||||
}).attach();
|
||||
|
||||
rootView.findViewById(R.id.toolbar).setVisibility(View.GONE);
|
||||
if (getActivity().getClass() == PreferenceActivity.class) {
|
||||
rootView.findViewById(R.id.toolbar).setVisibility(View.GONE);
|
||||
} else {
|
||||
toolbar.setTitle(getString(R.string.statistics_label));
|
||||
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
|
||||
}
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
@ -67,7 +75,9 @@ public class StatisticsFragment extends Fragment {
|
|||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
||||
if (getActivity().getClass() == PreferenceActivity.class) {
|
||||
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StatisticsPagerAdapter extends FragmentStateAdapter {
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
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="match_parent">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBar"
|
||||
|
@ -16,34 +17,35 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/windowBackground"
|
||||
app:contentScrim="?android:attr/windowBackground"
|
||||
app:scrimAnimationDuration="200"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:scrimAnimationDuration="200">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvBackground"
|
||||
style="@style/BigBlurryBackground"
|
||||
android:background="@color/image_readability_tint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="232dp"
|
||||
android:background="@color/image_readability_tint"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:layout_collapseParallaxMultiplier="0.6"/>
|
||||
app:layout_collapseParallaxMultiplier="0.6" />
|
||||
|
||||
<include layout="@layout/feeditemlist_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:layout_collapseParallaxMultiplier="0.6"/>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<include
|
||||
layout="@layout/feeditemlist_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:layout_collapseParallaxMultiplier="0.6" />
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:navigationIcon="?homeAsUpIndicator"
|
||||
android:layout_alignParentTop="true"
|
||||
android:id="@+id/toolbar"
|
||||
app:layout_collapseMode="pin"/>
|
||||
app:layout_collapseMode="pin"
|
||||
app:navigationIcon="?homeAsUpIndicator" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
@ -52,68 +54,30 @@
|
|||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:clipToPadding="false"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/infoContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/infoContainer"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing">
|
||||
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.Heading"
|
||||
android:id="@+id/lblAuthor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/author_label"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:background="@android:color/holo_red_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDetailsAuthor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="Daniel Oeh"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.Heading"
|
||||
android:id="@+id/lblLanguage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/language_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:background="@android:color/holo_red_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvLanguage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="English"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.Heading"
|
||||
android:id="@+id/lblUrl"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="@string/url_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:background="@android:color/holo_red_light"/>
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvUrl"
|
||||
|
@ -123,24 +87,100 @@
|
|||
android:maxLines="4"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
tools:text="http://www.example.com/feed"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
tools:background="@android:color/holo_green_dark"
|
||||
tools:text="http://www.example.com/feed" />
|
||||
|
||||
<TextView
|
||||
style="@style/AntennaPod.TextView.Heading"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/description_label"/>
|
||||
android:textSize="18sp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="@string/description_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textIsSelectable="true"
|
||||
android:text="@string/design_time_lorem_ipsum"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
android:textIsSelectable="true"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblStatistics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/statistics_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_listened_for" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPodcastTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_episodes_on_device" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPodcastEpisodeCount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_space_used" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvPodcastSpaceUsed"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp" />
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnvOpenStatistics"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="0dp"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/statistics_view_all" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
@ -719,6 +719,10 @@
|
|||
<string name="keep_updated">Keep Updated</string>
|
||||
<string name="keep_updated_summary">Include this podcast when (auto-)refreshing all podcasts</string>
|
||||
<string name="auto_download_disabled_globally">Auto download is disabled in the main AntennaPod settings</string>
|
||||
<string name="statistics_listened_for">Listened for:</string>
|
||||
<string name="statistics_episodes_on_device">Episodes on the device:</string>
|
||||
<string name="statistics_space_used">Space used:</string>
|
||||
<string name="statistics_view_all">View for all podcasts »</string>
|
||||
|
||||
<!-- Progress information -->
|
||||
<string name="progress_upgrading_database">Upgrading the database</string>
|
||||
|
|
Loading…
Reference in New Issue