Merge pull request #5515 from ByteHamster/feed-statistics-table
Show more detailed feed statistics
This commit is contained in:
commit
cf58b364f1
|
@ -1,13 +1,12 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.StatisticsItem;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateFormatter;
|
||||
import de.danoeh.antennapod.fragment.FeedStatisticsDialogFragment;
|
||||
import de.danoeh.antennapod.view.PieChartView;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -18,10 +17,12 @@ import java.util.List;
|
|||
*/
|
||||
public class PlaybackStatisticsListAdapter extends StatisticsListAdapter {
|
||||
|
||||
private final Fragment fragment;
|
||||
boolean countAll = true;
|
||||
|
||||
public PlaybackStatisticsListAdapter(Context context) {
|
||||
super(context);
|
||||
public PlaybackStatisticsListAdapter(Fragment fragment) {
|
||||
super(fragment.getContext());
|
||||
this.fragment = fragment;
|
||||
}
|
||||
|
||||
public void setCountAll(boolean countAll) {
|
||||
|
@ -60,16 +61,9 @@ public class PlaybackStatisticsListAdapter extends StatisticsListAdapter {
|
|||
holder.value.setText(Converter.shortLocalizedDuration(context, time));
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
|
||||
dialog.setTitle(statsItem.feed.getTitle());
|
||||
dialog.setMessage(context.getString(R.string.statistics_details_dialog,
|
||||
countAll ? statsItem.episodesStartedIncludingMarked : statsItem.episodesStarted,
|
||||
statsItem.episodes, Converter.shortLocalizedDuration(context,
|
||||
countAll ? statsItem.timePlayedCountAll : statsItem.timePlayed),
|
||||
Converter.shortLocalizedDuration(context, statsItem.time)));
|
||||
dialog.setPositiveButton(android.R.string.ok, null);
|
||||
dialog.show();
|
||||
FeedStatisticsDialogFragment yourDialogFragment = FeedStatisticsDialogFragment.newInstance(
|
||||
statsItem.feed.getId(), statsItem.feed.getTitle());
|
||||
yourDialogFragment.show(fragment.getChildFragmentManager().beginTransaction(), "DialogFragment");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,15 @@ import android.graphics.LightingColorFilter;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -20,55 +28,37 @@ import androidx.appcompat.widget.AppCompatDrawableManager;
|
|||
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.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;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedFunding;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
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.syndication.HtmlToPlainText;
|
||||
import de.danoeh.antennapod.fragment.preferences.StatisticsFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedFunding;
|
||||
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.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Displays information about a feed.
|
||||
|
@ -82,24 +72,17 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
|
|||
|
||||
private Feed feed;
|
||||
private Disposable disposable;
|
||||
private Disposable disposableStatistics;
|
||||
private ImageView imgvCover;
|
||||
private TextView txtvTitle;
|
||||
private TextView txtvDescription;
|
||||
private TextView lblStatistics;
|
||||
private TextView txtvPodcastTime;
|
||||
private TextView txtvPodcastSpace;
|
||||
private TextView txtvPodcastEpisodeCount;
|
||||
private TextView txtvFundingUrl;
|
||||
private TextView lblSupport;
|
||||
private Button btnvOpenStatistics;
|
||||
private TextView txtvUrl;
|
||||
private TextView txtvAuthorHeader;
|
||||
private ImageView imgvBackground;
|
||||
private View infoContainer;
|
||||
private View header;
|
||||
private Toolbar toolbar;
|
||||
private ToolbarIconTintManager iconTintManager;
|
||||
|
||||
public static FeedInfoFragment newInstance(Feed feed) {
|
||||
FeedInfoFragment fragment = new FeedInfoFragment();
|
||||
|
@ -137,7 +120,7 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
|
|||
|
||||
AppBarLayout appBar = root.findViewById(R.id.appBar);
|
||||
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
|
||||
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
|
||||
ToolbarIconTintManager iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
|
||||
@Override
|
||||
protected void doTint(Context themedContext) {
|
||||
toolbar.getMenu().findItem(R.id.visit_website_item)
|
||||
|
@ -161,23 +144,20 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
|
|||
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
|
||||
|
||||
txtvDescription = root.findViewById(R.id.txtvDescription);
|
||||
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);
|
||||
lblSupport = root.findViewById(R.id.lblSupport);
|
||||
txtvFundingUrl = root.findViewById(R.id.txtvFundingUrl);
|
||||
|
||||
txtvUrl.setOnClickListener(copyUrlToClipboard);
|
||||
|
||||
btnvOpenStatistics.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
StatisticsFragment fragment = new StatisticsFragment();
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
|
||||
}
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
getParentFragmentManager().beginTransaction().replace(R.id.statisticsFragmentContainer,
|
||||
FeedStatisticsFragment.newInstance(feedId, false), "feed_statistics_fragment")
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
root.findViewById(R.id.btnvOpenStatistics).setOnClickListener(view -> {
|
||||
StatisticsFragment fragment = new StatisticsFragment();
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
|
||||
});
|
||||
|
||||
return root;
|
||||
|
@ -199,7 +179,6 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
|
|||
.subscribe(result -> {
|
||||
feed = result;
|
||||
showFeed();
|
||||
loadStatistics();
|
||||
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
|
||||
}
|
||||
|
||||
|
@ -274,53 +253,12 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
|
|||
refreshToolbarState();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshToolbarState() {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
|
||||
public class FeedStatisticsDialogFragment extends DialogFragment {
|
||||
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String EXTRA_FEED_TITLE = "de.danoeh.antennapod.extra.feedTitle";
|
||||
|
||||
public static FeedStatisticsDialogFragment newInstance(long feedId, String feedTitle) {
|
||||
FeedStatisticsDialogFragment fragment = new FeedStatisticsDialogFragment();
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(EXTRA_FEED_ID, feedId);
|
||||
arguments.putString(EXTRA_FEED_TITLE, feedTitle);
|
||||
fragment.setArguments(arguments);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
|
||||
dialog.setPositiveButton(android.R.string.ok, null);
|
||||
dialog.setTitle(getArguments().getString(EXTRA_FEED_TITLE));
|
||||
dialog.setView(R.layout.feed_statistics_dialog);
|
||||
return dialog.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
getChildFragmentManager().beginTransaction().replace(R.id.statisticsContainer,
|
||||
FeedStatisticsFragment.newInstance(feedId, true), "feed_statistics_fragment")
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.format.Formatter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.StatisticsItem;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.databinding.FeedStatisticsBinding;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FeedStatisticsFragment extends Fragment {
|
||||
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
|
||||
private static final String EXTRA_DETAILED = "de.danoeh.antennapod.extra.detailed";
|
||||
|
||||
private long feedId;
|
||||
private Disposable disposable;
|
||||
private FeedStatisticsBinding viewBinding;
|
||||
|
||||
public static FeedStatisticsFragment newInstance(long feedId, boolean detailed) {
|
||||
FeedStatisticsFragment fragment = new FeedStatisticsFragment();
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(EXTRA_FEED_ID, feedId);
|
||||
arguments.putBoolean(EXTRA_DETAILED, detailed);
|
||||
fragment.setArguments(arguments);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
viewBinding = FeedStatisticsBinding.inflate(inflater);
|
||||
loadStatistics();
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
private void loadStatistics() {
|
||||
disposable =
|
||||
Observable.fromCallable(() -> {
|
||||
List<StatisticsItem> statisticsData = DBReader.getStatistics();
|
||||
for (StatisticsItem statisticsItem : statisticsData) {
|
||||
if (statisticsItem.feed.getId() == feedId) {
|
||||
return statisticsItem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::showStats, Throwable::printStackTrace);
|
||||
}
|
||||
|
||||
private void showStats(StatisticsItem s) {
|
||||
viewBinding.startedTotalLabel.setText(String.format(Locale.getDefault(), "%d / %d",
|
||||
s.episodesStarted, s.episodes));
|
||||
viewBinding.timePlayedLabel.setText(Converter.shortLocalizedDuration(getContext(), s.timePlayed));
|
||||
viewBinding.durationPlayedLabel.setText(Converter.shortLocalizedDuration(getContext(), s.timePlayedCountAll));
|
||||
viewBinding.totalDurationLabel.setText(Converter.shortLocalizedDuration(getContext(), s.time));
|
||||
viewBinding.onDeviceLabel.setText(String.format(Locale.getDefault(), "%d", s.episodesDownloadCount));
|
||||
viewBinding.spaceUsedLabel.setText(Formatter.formatShortFileSize(getContext(), s.totalDownloadSize));
|
||||
|
||||
if (!getArguments().getBoolean(EXTRA_DETAILED)) {
|
||||
for (int i = 0; i < viewBinding.getRoot().getChildCount(); i++) {
|
||||
View child = viewBinding.getRoot().getChildAt(i);
|
||||
if ("detailed".equals(child.getTag())) {
|
||||
child.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,7 +68,7 @@ public class PlaybackStatisticsFragment extends Fragment {
|
|||
View root = inflater.inflate(R.layout.statistics_activity, container, false);
|
||||
feedStatisticsList = root.findViewById(R.id.statistics_list);
|
||||
progressBar = root.findViewById(R.id.progressBar);
|
||||
listAdapter = new PlaybackStatisticsListAdapter(getContext());
|
||||
listAdapter = new PlaybackStatisticsListAdapter(this);
|
||||
listAdapter.setCountAll(countAll);
|
||||
feedStatisticsList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
feedStatisticsList.setAdapter(listAdapter);
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TableRow
|
||||
android:tag="detailed">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_episodes_started_total" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/startedTotalLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0 / 0" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_time_played" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timePlayedLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0 min" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:tag="detailed">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_duration_played_episodes" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/durationPlayedLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0 min" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:tag="detailed">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_total_duration" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/totalDurationLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0 min" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_episodes_on_device" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/onDeviceLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/statistics_space_used" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/spaceUsedLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
tools:text="0 MB" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/statisticsContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp" />
|
|
@ -1,211 +1,164 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
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">
|
||||
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">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:id="@+id/appBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsing_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/windowBackground"
|
||||
app:contentScrim="?android:attr/windowBackground"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:scrimAnimationDuration="200">
|
||||
android:id="@+id/collapsing_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/windowBackground"
|
||||
app:contentScrim="?android:attr/windowBackground"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:scrimAnimationDuration="200">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imgvBackground"
|
||||
style="@style/BigBlurryBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="232dp"
|
||||
android:background="@color/image_readability_tint"
|
||||
app:layout_collapseMode="parallax"
|
||||
app:layout_collapseParallaxMultiplier="0.6" />
|
||||
android:id="@+id/imgvBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="232dp"
|
||||
android:background="@color/image_readability_tint"
|
||||
style="@style/BigBlurryBackground"
|
||||
app:layout_collapseMode="parallax"
|
||||
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" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
layout="@layout/feeditemlist_header"
|
||||
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:layout_collapseMode="pin"
|
||||
app:navigationContentDescription="@string/toolbar_back_button_content_description"
|
||||
app:navigationIcon="?homeAsUpIndicator" />
|
||||
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:layout_collapseMode="pin"
|
||||
app:navigationContentDescription="@string/toolbar_back_button_content_description"
|
||||
app:navigationIcon="?homeAsUpIndicator" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/infoContainer"
|
||||
android:id="@+id/infoContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblUrl"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing">
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:maxLines="4"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
tools:background="@android:color/holo_green_dark"
|
||||
tools:text="http://www.example.com/feed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblUrl"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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" />
|
||||
android:id="@+id/lblSupport"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="@string/support_funding_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:maxLines="4"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
tools:background="@android:color/holo_green_dark"
|
||||
tools:text="http://www.example.com/feed" />
|
||||
android:id="@+id/txtvFundingUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="8"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:linksClickable="true"
|
||||
android:autoLink="web"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblSupport"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="@string/support_funding_label"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
tools:background="@android:color/holo_red_light" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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/txtvFundingUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="8"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:linksClickable="true"
|
||||
android:autoLink="web"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
android:id="@+id/txtvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/design_time_lorem_ipsum"
|
||||
android:textIsSelectable="true"
|
||||
tools:background="@android:color/holo_green_dark" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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" />
|
||||
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" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/design_time_lorem_ipsum"
|
||||
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>
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/statisticsFragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<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" />
|
||||
android:id="@+id/btnvOpenStatistics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="0dp"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/statistics_view_all"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
|
||||
<!-- Statistics fragment -->
|
||||
<string name="total_time_listened_to_podcasts">Total time of episodes played:</string>
|
||||
<string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
|
||||
<string name="statistics_mode">Statistics mode</string>
|
||||
<string name="statistics_mode_normal">Calculate duration that was actually played. Playing twice is counted twice, while marking as played is not counted</string>
|
||||
<string name="statistics_mode_count_all">Sum up all episodes marked as played</string>
|
||||
|
@ -707,9 +706,12 @@
|
|||
<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_time_played">Time played:</string>
|
||||
<string name="statistics_total_duration">Total duration (estimate):</string>
|
||||
<string name="statistics_duration_played_episodes">Duration of played episodes:</string>
|
||||
<string name="statistics_episodes_on_device">Episodes on the device:</string>
|
||||
<string name="statistics_space_used">Space used:</string>
|
||||
<string name="statistics_episodes_started_total">Episodes started/total:</string>
|
||||
<string name="statistics_view_all">View for all podcasts »</string>
|
||||
|
||||
<!-- AntennaPodSP -->
|
||||
|
|
Loading…
Reference in New Issue