diff options
Diffstat (limited to 'app/src/main/java')
53 files changed, 232 insertions, 1259 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java index 534d48479..8ce894684 100644 --- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java +++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java @@ -1,10 +1,10 @@ package de.danoeh.antennapod; -import android.app.Application; import android.content.ComponentName; import android.content.Intent; import android.os.StrictMode; +import androidx.multidex.MultiDexApplication; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.fonts.FontAwesomeModule; import com.joanzapata.iconify.fonts.MaterialModule; @@ -18,7 +18,7 @@ import de.danoeh.antennapod.spa.SPAUtil; import org.greenrobot.eventbus.EventBus; /** Main application class. */ -public class PodcastApp extends Application { +public class PodcastApp extends MultiDexApplication { // make sure that ClientConfigurator executes its static code static { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java index f7c96a93a..64e5a109c 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java @@ -3,9 +3,6 @@ package de.danoeh.antennapod.activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.util.Log; @@ -14,6 +11,7 @@ import com.google.android.material.snackbar.Snackbar; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ShareCompat; import androidx.core.content.FileProvider; @@ -32,7 +30,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.Charset; -import java.util.List; /** * Displays the 'crash report' screen @@ -102,21 +99,14 @@ public class BugReportActivity extends AppCompatActivity { Runtime.getRuntime().exec(cmd); //share file try { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/*"); - String authString = getString(de.danoeh.antennapod.core.R.string.provider_authority); - Uri fileUri = FileProvider.getUriForFile(this, authString, filename); - intent.putExtra(Intent.EXTRA_STREAM, fileUri); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - String chooserTitle = getString(de.danoeh.antennapod.core.R.string.share_file_label); - Intent chooser = Intent.createChooser(intent, chooserTitle); - List<ResolveInfo> resInfos = getPackageManager() - .queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY); - for (ResolveInfo resolveInfo : resInfos) { - String packageName = resolveInfo.activityInfo.packageName; - grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - startActivity(chooser); + String authority = getString(R.string.provider_authority); + Uri fileUri = FileProvider.getUriForFile(this, authority, filename); + + new ShareCompat.IntentBuilder(this) + .setType("text/*") + .addStream(fileUri) + .setChooserTitle(R.string.share_file_label) + .startChooser(); } catch (Exception e) { e.printStackTrace(); int strResId = R.string.log_file_share_exception; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java index 3e4782f1f..3f7a5db68 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -18,7 +18,6 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; -import android.widget.FrameLayout; import android.widget.Toast; import androidx.annotation.NonNull; @@ -29,6 +28,7 @@ import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentContainerView; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.recyclerview.widget.RecyclerView; @@ -248,7 +248,7 @@ public class MainActivity extends CastEnabledActivity { public void setPlayerVisible(boolean visible) { getBottomSheet().setLocked(!visible); - FrameLayout mainView = findViewById(R.id.main_view); + FragmentContainerView mainView = findViewById(R.id.main_view); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mainView.getLayoutParams(); params.setMargins(0, 0, 0, visible ? (int) getResources().getDimension(R.dimen.external_player_height) : 0); mainView.setLayoutParams(params); diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java index 3f01a2b2d..7a26759cc 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -35,6 +35,7 @@ import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.DownloadRequestCreator; import de.danoeh.antennapod.core.feed.FeedUrlNotFoundException; +import de.danoeh.antennapod.core.util.DownloadErrorLabel; import de.danoeh.antennapod.discovery.CombinedSearcher; import de.danoeh.antennapod.discovery.PodcastSearchResult; import de.danoeh.antennapod.event.FeedListUpdateEvent; @@ -44,7 +45,7 @@ import de.danoeh.antennapod.core.glide.FastBlurTransformation; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadRequest; -import de.danoeh.antennapod.core.service.download.DownloadStatus; +import de.danoeh.antennapod.model.download.DownloadStatus; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.service.download.HttpDownloader; import de.danoeh.antennapod.core.service.playback.PlaybackService; @@ -52,7 +53,7 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.parser.feed.FeedHandler; import de.danoeh.antennapod.parser.feed.FeedHandlerResult; -import de.danoeh.antennapod.core.util.DownloadError; +import de.danoeh.antennapod.model.download.DownloadError; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.URLChecker; @@ -133,10 +134,10 @@ public class OnlineFeedViewActivity extends AppCompatActivity { String feedUrl = null; if (getIntent().hasExtra(ARG_FEEDURL)) { feedUrl = getIntent().getStringExtra(ARG_FEEDURL); - } else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) - || TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { - feedUrl = TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND) - ? getIntent().getStringExtra(Intent.EXTRA_TEXT) : getIntent().getDataString(); + } else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_SEND)) { + feedUrl = getIntent().getStringExtra(Intent.EXTRA_TEXT); + } else if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) { + feedUrl = getIntent().getDataString(); } if (feedUrl == null) { @@ -325,7 +326,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity { dialog.show(); } } else { - showErrorDialog(status.getReason().getErrorString(OnlineFeedViewActivity.this), status.getReasonDetailed()); + showErrorDialog(getString(DownloadErrorLabel.from(status.getReason())), status.getReasonDetailed()); } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java index 1fc16ab32..05a514c76 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/PreferenceActivity.java @@ -4,7 +4,6 @@ import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.provider.Settings; -import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -131,12 +130,6 @@ public class PreferenceActivity extends AppCompatActivity implements SearchPrefe } @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - return true; - } - - @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java index f0c76d545..ecf490f48 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java @@ -12,8 +12,8 @@ import androidx.appcompat.app.AppCompatActivity; import android.widget.ProgressBar; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.error.CrashReportWriter; +import de.danoeh.antennapod.storage.database.PodDBAdapter; import io.reactivex.Completable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java index 4ff2a5775..954a6c2f6 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -91,6 +91,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. private PlaybackController controller; private boolean showTimeLeft = false; private boolean isFavorite = false; + private boolean switchToAudioOnly = false; private Disposable disposable; private float prog; @@ -119,6 +120,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. protected void onResume() { super.onResume(); StorageUtils.checkStorageAvailability(this); + switchToAudioOnly = false; if (PlaybackService.isCasting()) { Intent intent = PlaybackService.getPlayerActivityIntent(this); if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) { @@ -149,8 +151,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. @Override public void onUserLeaveHint() { - if (!PictureInPictureUtil.isInPictureInPictureMode(this) && UserPreferences.getVideoBackgroundBehavior() - == UserPreferences.VideoBackgroundBehavior.PICTURE_IN_PICTURE) { + if (!PictureInPictureUtil.isInPictureInPictureMode(this)) { compatEnterPictureInPicture(); } } @@ -480,9 +481,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "Videosurface was destroyed"); videoSurfaceCreated = false; - if (controller != null && !destroyingDueToReload - && UserPreferences.getVideoBackgroundBehavior() - != UserPreferences.VideoBackgroundBehavior.CONTINUE_PLAYING) { + if (controller != null && !destroyingDueToReload && !switchToAudioOnly) { controller.notifyVideoSurfaceAbandoned(); } } @@ -590,17 +589,16 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. menu.findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive()); menu.findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive()); - if (PictureInPictureUtil.supportsPictureInPicture(this)) { - menu.findItem(R.id.player_go_to_picture_in_picture).setVisible(true); - } + menu.findItem(R.id.player_switch_to_audio_only).setVisible(true); menu.findItem(R.id.audio_controls).setIcon(R.drawable.ic_sliders); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.player_go_to_picture_in_picture) { - compatEnterPictureInPicture(); + if (item.getItemId() == R.id.player_switch_to_audio_only) { + switchToAudioOnly = true; + finish(); return true; } if (item.getItemId() == android.R.id.home) { diff --git a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java index 674071294..7245ce675 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java @@ -12,7 +12,7 @@ import androidx.appcompat.app.AppCompatActivity; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.receiver.PlayerWidget; -import de.danoeh.antennapod.core.widget.WidgetUpdaterJobService; +import de.danoeh.antennapod.core.widget.WidgetUpdaterWorker; public class WidgetConfigActivity extends AppCompatActivity { private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; @@ -47,7 +47,7 @@ public class WidgetConfigActivity extends AppCompatActivity { opacityTextView = findViewById(R.id.widget_opacity_textView); opacitySeekBar = findViewById(R.id.widget_opacity_seekBar); widgetPreview = findViewById(R.id.widgetLayout); - findViewById(R.id.butConfirm).setOnClickListener(this::confirmCreateWidget); + findViewById(R.id.butConfirm).setOnClickListener(v -> confirmCreateWidget()); opacitySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -94,7 +94,7 @@ public class WidgetConfigActivity extends AppCompatActivity { widgetPreview.findViewById(R.id.butRew).setVisibility(ckRewind.isChecked() ? View.VISIBLE : View.GONE); } - private void confirmCreateWidget(View v) { + private void confirmCreateWidget() { int backgroundColor = getColorWithAlpha(PlayerWidget.DEFAULT_COLOR, opacitySeekBar.getProgress()); SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, MODE_PRIVATE); @@ -109,7 +109,7 @@ public class WidgetConfigActivity extends AppCompatActivity { resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_OK, resultValue); finish(); - WidgetUpdaterJobService.performBackgroundUpdate(this); + WidgetUpdaterWorker.enqueueWork(this); } private int getColorWithAlpha(int color, int opacity) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java index 072ca8acf..e46073457 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java @@ -17,11 +17,14 @@ import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadRequestCreator; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.Downloader; -import de.danoeh.antennapod.core.service.download.DownloadStatus; +import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.model.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; -import de.danoeh.antennapod.core.util.DownloadError; +import de.danoeh.antennapod.model.download.DownloadError; +import de.danoeh.antennapod.core.util.DownloadErrorLabel; import de.danoeh.antennapod.model.feed.Feed; +import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.ui.common.ThemeUtils; import de.danoeh.antennapod.view.viewholder.DownloadLogItemViewHolder; @@ -109,7 +112,7 @@ public class DownloadLogAdapter extends BaseAdapter { holder.icon.setText("{fa-times-circle}"); } holder.icon.setContentDescription(context.getString(R.string.error_label)); - holder.reason.setText(status.getReason().getErrorString(context)); + holder.reason.setText(DownloadErrorLabel.from(status.getReason())); holder.reason.setVisibility(View.VISIBLE); holder.tapForDetails.setVisibility(View.VISIBLE); @@ -156,8 +159,15 @@ public class DownloadLogAdapter extends BaseAdapter { holder.secondaryActionButton.setContentDescription(context.getString(R.string.cancel_download_label)); holder.secondaryActionButton.setVisibility(View.VISIBLE); holder.secondaryActionButton.setTag(downloader); - holder.secondaryActionButton.setOnClickListener(v -> - listFragment.onListItemClick(null, holder.itemView, position, 0)); + holder.secondaryActionButton.setOnClickListener(v -> { + DownloadService.cancel(context, request.getSource()); + if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { + FeedMedia media = DBReader.getFeedMedia(request.getFeedfileId()); + FeedItem feedItem = media.getItem(); + feedItem.disableAutoDownload(); + DBWriter.setFeedItem(feedItem); + } + }); holder.reason.setVisibility(View.GONE); holder.tapForDetails.setVisibility(View.GONE); holder.icon.setTextColor(ThemeUtils.getColorFromAttr(context, R.attr.colorPrimary)); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadStatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadStatisticsListAdapter.java deleted file mode 100644 index 684ba281d..000000000 --- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadStatisticsListAdapter.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.danoeh.antennapod.adapter; - -import android.content.Context; -import android.text.format.Formatter; - -import java.util.List; -import java.util.Locale; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.storage.StatisticsItem; -import de.danoeh.antennapod.view.PieChartView; - -/** - * Adapter for the download statistics list. - */ -public class DownloadStatisticsListAdapter extends StatisticsListAdapter { - - public DownloadStatisticsListAdapter(Context context) { - super(context); - } - - @Override - String getHeaderCaption() { - return context.getString(R.string.total_size_downloaded_podcasts); - } - - @Override - String getHeaderValue() { - return Formatter.formatShortFileSize(context, (long) pieChartData.getSum()); - } - - @Override - PieChartView.PieChartData generateChartData(List<StatisticsItem> statisticsData) { - float[] dataValues = new float[statisticsData.size()]; - for (int i = 0; i < statisticsData.size(); i++) { - StatisticsItem item = statisticsData.get(i); - dataValues[i] = item.totalDownloadSize; - } - return new PieChartView.PieChartData(dataValues); - } - - @Override - void onBindFeedViewHolder(StatisticsHolder holder, StatisticsItem item) { - holder.value.setText(Formatter.formatShortFileSize(context, item.totalDownloadSize) - + " • " - + String.format(Locale.getDefault(), "%d%s", - item.episodesDownloadCount, context.getString(R.string.episodes_suffix))); - } - -} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java index 5ddb6407c..f790a5784 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java @@ -80,8 +80,6 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> { } new PlaybackServiceStarter(getContext(), playable) - .shouldStream(true) - .startWhenPrepared(true) .callEvenIfRunning(true) .start(); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/PlaybackStatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/PlaybackStatisticsListAdapter.java deleted file mode 100644 index 26674b2b2..000000000 --- a/app/src/main/java/de/danoeh/antennapod/adapter/PlaybackStatisticsListAdapter.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.danoeh.antennapod.adapter; - -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; -import java.util.List; - -/** - * Adapter for the playback statistics list. - */ -public class PlaybackStatisticsListAdapter extends StatisticsListAdapter { - - private final Fragment fragment; - boolean countAll = true; - - public PlaybackStatisticsListAdapter(Fragment fragment) { - super(fragment.getContext()); - this.fragment = fragment; - } - - public void setCountAll(boolean countAll) { - this.countAll = countAll; - } - - @Override - String getHeaderCaption() { - long usageCounting = UserPreferences.getUsageCountingDateMillis(); - if (usageCounting > 0) { - String date = DateFormatter.formatAbbrev(context, new Date(usageCounting)); - return context.getString(R.string.statistics_counting_since, date); - } else { - return context.getString(R.string.total_time_listened_to_podcasts); - } - } - - @Override - String getHeaderValue() { - return Converter.shortLocalizedDuration(context, (long) pieChartData.getSum()); - } - - @Override - PieChartView.PieChartData generateChartData(List<StatisticsItem> statisticsData) { - float[] dataValues = new float[statisticsData.size()]; - for (int i = 0; i < statisticsData.size(); i++) { - StatisticsItem item = statisticsData.get(i); - dataValues[i] = countAll ? item.timePlayedCountAll : item.timePlayed; - } - return new PieChartView.PieChartData(dataValues); - } - - @Override - void onBindFeedViewHolder(StatisticsHolder holder, StatisticsItem statsItem) { - long time = countAll ? statsItem.timePlayedCountAll : statsItem.timePlayed; - holder.value.setText(Converter.shortLocalizedDuration(context, time)); - - holder.itemView.setOnClickListener(v -> { - FeedStatisticsDialogFragment yourDialogFragment = FeedStatisticsDialogFragment.newInstance( - statsItem.feed.getId(), statsItem.feed.getTitle()); - yourDialogFragment.show(fragment.getChildFragmentManager().beginTransaction(), "DialogFragment"); - }); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java deleted file mode 100644 index 23b5cfdce..000000000 --- a/app/src/main/java/de/danoeh/antennapod/adapter/StatisticsListAdapter.java +++ /dev/null @@ -1,123 +0,0 @@ -package de.danoeh.antennapod.adapter; - -import android.content.Context; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.RequestOptions; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.glide.ApGlideSettings; -import de.danoeh.antennapod.core.storage.StatisticsItem; -import de.danoeh.antennapod.view.PieChartView; - -import java.util.List; - -/** - * Parent Adapter for the playback and download statistics list. - */ -public abstract class StatisticsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { - private static final int TYPE_HEADER = 0; - private static final int TYPE_FEED = 1; - final Context context; - private List<StatisticsItem> statisticsData; - PieChartView.PieChartData pieChartData; - - StatisticsListAdapter(Context context) { - this.context = context; - } - - @Override - public int getItemCount() { - return statisticsData.size() + 1; - } - - @Override - public int getItemViewType(int position) { - return position == 0 ? TYPE_HEADER : TYPE_FEED; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - LayoutInflater inflater = LayoutInflater.from(context); - if (viewType == TYPE_HEADER) { - View view = inflater.inflate(R.layout.statistics_listitem_total, parent, false); - TextView totalText = view.findViewById(R.id.total_description); - totalText.setText(getHeaderCaption()); - return new HeaderHolder(view); - } - return new StatisticsHolder(inflater.inflate(R.layout.statistics_listitem, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder h, int position) { - if (getItemViewType(position) == TYPE_HEADER) { - HeaderHolder holder = (HeaderHolder) h; - holder.pieChart.setData(pieChartData); - holder.totalTime.setText(getHeaderValue()); - } else { - StatisticsHolder holder = (StatisticsHolder) h; - StatisticsItem statsItem = statisticsData.get(position - 1); - Glide.with(context) - .load(statsItem.feed.getImageUrl()) - .apply(new RequestOptions() - .placeholder(R.color.light_gray) - .error(R.color.light_gray) - .diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY) - .fitCenter() - .dontAnimate()) - .into(holder.image); - - holder.title.setText(statsItem.feed.getTitle()); - holder.chip.setTextColor(pieChartData.getColorOfItem(position - 1)); - onBindFeedViewHolder(holder, statsItem); - } - } - - public void update(List<StatisticsItem> statistics) { - statisticsData = statistics; - pieChartData = generateChartData(statistics); - notifyDataSetChanged(); - } - - static class HeaderHolder extends RecyclerView.ViewHolder { - TextView totalTime; - PieChartView pieChart; - - HeaderHolder(View itemView) { - super(itemView); - totalTime = itemView.findViewById(R.id.total_time); - pieChart = itemView.findViewById(R.id.pie_chart); - } - } - - static class StatisticsHolder extends RecyclerView.ViewHolder { - ImageView image; - TextView title; - TextView value; - TextView chip; - - StatisticsHolder(View itemView) { - super(itemView); - image = itemView.findViewById(R.id.imgvCover); - title = itemView.findViewById(R.id.txtvTitle); - value = itemView.findViewById(R.id.txtvValue); - chip = itemView.findViewById(R.id.chip); - } - } - - abstract String getHeaderCaption(); - - abstract String getHeaderValue(); - - abstract PieChartView.PieChartData generateChartData(List<StatisticsItem> statisticsData); - - abstract void onBindFeedViewHolder(StatisticsHolder holder, StatisticsItem item); -} diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java index 5ab354d05..8351d1fb5 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java @@ -33,7 +33,6 @@ import java.util.Locale; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.feed.LocalFeedUpdater; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.NavDrawerData; import de.danoeh.antennapod.fragment.FeedItemlistFragment; @@ -255,7 +254,7 @@ public class SubscriptionsRecyclerAdapter extends SelectableAdapter<Subscription if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) { Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed; boolean textAndImageCombind = feed.isLocalFeed() - && LocalFeedUpdater.getDefaultIconUrl(itemView.getContext()).equals(feed.getImageUrl()); + && feed.getImageUrl() != null && feed.getImageUrl().startsWith(Feed.PREFIX_GENERATIVE_COVER); new CoverLoader(mainActivityRef.get()) .withUri(feed.getImageUrl()) .withPlaceholderView(feedTitle, textAndImageCombind) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java index 974b12bab..983ae3df9 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java @@ -41,8 +41,6 @@ public class PlayActionButton extends ItemActionButton { } new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) - .startWhenPrepared(true) - .shouldStream(false) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java index ab2122b12..ce251f5a6 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java @@ -37,8 +37,6 @@ public class PlayLocalActionButton extends ItemActionButton { new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) - .startWhenPrepared(true) - .shouldStream(true) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java index 94c446f50..2f5cb5430 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java @@ -47,8 +47,6 @@ public class StreamActionButton extends ItemActionButton { } new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) - .startWhenPrepared(true) - .shouldStream(true) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java index 73e19c746..8acfcb58f 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java @@ -36,7 +36,7 @@ public class DocumentFileExportWorker { OutputStreamWriter writer = null; try { Uri uri = output.getUri(); - outputStream = context.getContentResolver().openOutputStream(uri); + outputStream = context.getContentResolver().openOutputStream(uri, "wt"); if (outputStream == null) { throw new IOException(); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java new file mode 100644 index 000000000..50fb0651f --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/DownloadLogDetailsDialog.java @@ -0,0 +1,59 @@ +package de.danoeh.antennapod.dialog; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.model.download.DownloadStatus; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.event.MessageEvent; +import de.danoeh.antennapod.model.feed.Feed; +import de.danoeh.antennapod.model.feed.FeedMedia; +import org.greenrobot.eventbus.EventBus; + +public class DownloadLogDetailsDialog extends AlertDialog.Builder { + + public DownloadLogDetailsDialog(@NonNull Context context, DownloadStatus status) { + super(context); + + String url = "unknown"; + String message = context.getString(R.string.download_successful); + if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { + FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); + if (media != null) { + url = media.getDownload_url(); + } + } else if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { + Feed feed = DBReader.getFeed(status.getFeedfileId()); + if (feed != null) { + url = feed.getDownload_url(); + } + } + + if (!status.isSuccessful()) { + message = status.getReasonDetailed(); + } + + String messageFull = context.getString(R.string.download_error_details_message, message, url); + setTitle(R.string.download_error_details); + setMessage(messageFull); + setPositiveButton(android.R.string.ok, null); + setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> { + ClipboardManager clipboard = (ClipboardManager) getContext() + .getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText(context.getString(R.string.download_error_details), messageFull); + clipboard.setPrimaryClip(clip); + EventBus.getDefault().post(new MessageEvent(context.getString(R.string.copied_to_clipboard))); + }); + } + + @Override + public AlertDialog show() { + AlertDialog dialog = super.show(); + ((TextView) dialog.findViewById(android.R.id.message)).setTextIsSelectable(true); + return dialog; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java index 5cc1f99c6..841c121e9 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java @@ -10,24 +10,14 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import android.widget.Button; import android.widget.CheckBox; -import android.widget.TextView; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.playback.PlaybackController; -import de.danoeh.antennapod.view.PlaybackSpeedSeekBar; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - import java.util.List; -import java.util.Locale; public class PlaybackControlsDialog extends DialogFragment { private PlaybackController controller; private AlertDialog dialog; - private PlaybackSpeedSeekBar speedSeekBar; - private TextView txtvPlaybackSpeed; public static PlaybackControlsDialog newInstance() { Bundle arguments = new Bundle(); @@ -48,12 +38,10 @@ public class PlaybackControlsDialog extends DialogFragment { public void loadMediaInfo() { setupUi(); setupAudioTracks(); - updateSpeed(new SpeedChangedEvent(getCurrentPlaybackSpeedMultiplier())); } }; controller.init(); setupUi(); - EventBus.getDefault().register(this); } @Override @@ -61,7 +49,6 @@ public class PlaybackControlsDialog extends DialogFragment { super.onStop(); controller.release(); controller = null; - EventBus.getDefault().unregister(this); } @NonNull @@ -75,15 +62,6 @@ public class PlaybackControlsDialog extends DialogFragment { } private void setupUi() { - txtvPlaybackSpeed = dialog.findViewById(R.id.txtvPlaybackSpeed); - speedSeekBar = dialog.findViewById(R.id.speed_seek_bar); - speedSeekBar.setProgressChangedListener(speed -> { - if (controller != null) { - controller.setPlaybackSpeed(speed); - } - }); - updateSpeed(new SpeedChangedEvent(controller.getCurrentPlaybackSpeedMultiplier())); - final CheckBox stereoToMono = dialog.findViewById(R.id.stereo_to_mono); stereoToMono.setChecked(UserPreferences.stereoToMono()); if (controller != null && !controller.canDownmix()) { @@ -111,12 +89,6 @@ public class PlaybackControlsDialog extends DialogFragment { }); } - @Subscribe(threadMode = ThreadMode.MAIN) - public void updateSpeed(SpeedChangedEvent event) { - txtvPlaybackSpeed.setText(String.format(Locale.getDefault(), "%.2fx", event.getNewSpeed())); - speedSeekBar.updateSpeed(event.getNewSpeed()); - } - private void setupAudioTracks() { List<String> audioTracks = controller.getAudioTracks(); int selectedAudioTrack = controller.getSelectedAudioTrack(); diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java index 22f62d410..a38463c4a 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java @@ -32,8 +32,6 @@ public class StreamingConfirmationDialog { private void stream() { new PlaybackServiceStarter(context, playable) .callEvenIfRunning(true) - .startWhenPrepared(true) - .shouldStream(true) .shouldStreamThisTime(true) .start(); } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java index 767845cb4..c8096e9c5 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearchResult.java @@ -39,10 +39,6 @@ public class PodcastSearchResult { this.author = author; } - private PodcastSearchResult(String title, @Nullable String imageUrl, @Nullable String feedUrl) { - this(title, imageUrl, feedUrl, ""); - } - public static PodcastSearchResult dummy() { return new PodcastSearchResult("", "", "", ""); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index 120d1def8..ee56bb9f9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.fragment; import android.content.ActivityNotFoundException; +import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; @@ -140,9 +141,12 @@ public class AddFeedFragment extends Fragment { alertViewBinding.urlEditText.setHint(R.string.add_podcast_by_url_hint); ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); - String clipboardContent = clipboard.getText() != null ? clipboard.getText().toString() : ""; - if (clipboardContent.trim().startsWith("http")) { - alertViewBinding.urlEditText.setText(clipboardContent.trim()); + final ClipData clipData = clipboard.getPrimaryClip(); + if (clipData != null && clipData.getItemCount() > 0 && clipData.getItemAt(0).getText() != null) { + final String clipboardContent = clipData.getItemAt(0).getText().toString(); + if (clipboardContent.trim().startsWith("http")) { + alertViewBinding.urlEditText.setText(clipboardContent.trim()); + } } builder.setView(alertViewBinding.getRoot()); builder.setPositiveButton(R.string.confirm_label, diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java index 04ad6e2bd..de63227e5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -71,7 +71,7 @@ public class ChaptersFragment extends AppCompatDialogFragment { } Chapter chapter = adapter.getItem(pos); controller.seekTo((int) chapter.getStart()); - updateChapterSelection(pos); + updateChapterSelection(pos, true); }); recyclerView.setAdapter(adapter); @@ -117,7 +117,7 @@ public class ChaptersFragment extends AppCompatDialogFragment { @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(PlaybackPositionEvent event) { - updateChapterSelection(getCurrentChapter(media)); + updateChapterSelection(getCurrentChapter(media), false); adapter.notifyTimeChanged(event.getPosition()); } @@ -160,10 +160,10 @@ public class ChaptersFragment extends AppCompatDialogFragment { } adapter.setMedia(media); int positionOfCurrentChapter = getCurrentChapter(media); - updateChapterSelection(positionOfCurrentChapter); + updateChapterSelection(positionOfCurrentChapter, true); } - private void updateChapterSelection(int position) { + private void updateChapterSelection(int position, boolean scrollTo) { if (adapter == null) { return; } @@ -171,8 +171,8 @@ public class ChaptersFragment extends AppCompatDialogFragment { if (position != -1 && focusedChapter != position) { focusedChapter = position; adapter.notifyChapterChanged(focusedChapter); - if (layoutManager.findFirstCompletelyVisibleItemPosition() >= position - || layoutManager.findLastCompletelyVisibleItemPosition() <= position) { + if (scrollTo && (layoutManager.findFirstCompletelyVisibleItemPosition() >= position + || layoutManager.findLastCompletelyVisibleItemPosition() <= position)) { layoutManager.scrollToPositionWithOffset(position, 100); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index 14b8cf6ed..cf0a96e91 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -35,6 +35,7 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.download.AutoUpdateManager; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; +import de.danoeh.antennapod.ui.common.PagedToolbarFragment; import de.danoeh.antennapod.view.EmptyViewHandler; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java index f43828000..9f0995f38 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java @@ -1,38 +1,28 @@ package de.danoeh.antennapod.fragment; -import android.app.Dialog; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ListView; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.ListFragment; -import com.google.android.material.snackbar.Snackbar; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.DownloadLogAdapter; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloadLogEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; -import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadService; -import de.danoeh.antennapod.core.service.download.DownloadStatus; +import de.danoeh.antennapod.model.download.DownloadStatus; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.download.AutoUpdateManager; -import de.danoeh.antennapod.model.feed.Feed; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; +import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog; +import de.danoeh.antennapod.ui.common.PagedToolbarFragment; import de.danoeh.antennapod.view.EmptyViewHandler; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -105,51 +95,8 @@ public class DownloadLogFragment extends ListFragment { super.onListItemClick(l, v, position, id); Object item = adapter.getItem(position); - if (item instanceof Downloader) { - DownloadRequest downloadRequest = ((Downloader) item).getDownloadRequest(); - DownloadService.cancel(getContext(), downloadRequest.getSource()); - - if (downloadRequest.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { - FeedMedia media = DBReader.getFeedMedia(downloadRequest.getFeedfileId()); - FeedItem feedItem = media.getItem(); - feedItem.disableAutoDownload(); - DBWriter.setFeedItem(feedItem); - } - } else if (item instanceof DownloadStatus) { - DownloadStatus status = (DownloadStatus) item; - String url = "unknown"; - String message = getString(R.string.download_successful); - if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { - FeedMedia media = DBReader.getFeedMedia(status.getFeedfileId()); - if (media != null) { - url = media.getDownload_url(); - } - } else if (status.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { - Feed feed = DBReader.getFeed(status.getFeedfileId()); - if (feed != null) { - url = feed.getDownload_url(); - } - } - - if (!status.isSuccessful()) { - message = status.getReasonDetailed(); - } - - String messageFull = getString(R.string.download_error_details_message, message, url); - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle(R.string.download_error_details); - builder.setMessage(messageFull); - builder.setPositiveButton(android.R.string.ok, null); - builder.setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> { - ClipboardManager clipboard = (ClipboardManager) getContext() - .getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText(getString(R.string.download_error_details), messageFull); - clipboard.setPrimaryClip(clip); - ((MainActivity) getActivity()).showSnackbarAbovePlayer( - R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT); - }); - Dialog dialog = builder.show(); - ((TextView) dialog.findViewById(android.R.id.message)).setTextIsSelectable(true); + if (item instanceof DownloadStatus) { + new DownloadLogDetailsDialog(getContext(), (DownloadStatus) item).show(); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java index bc3884b37..4467a0cf0 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadsFragment.java @@ -19,6 +19,7 @@ import com.google.android.material.tabs.TabLayoutMediator; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.ui.common.PagedToolbarFragment; /** * Shows the CompletedDownloadsFragment and the RunningDownloadsFragment. diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java index cfa226f8f..bb987666e 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java @@ -18,6 +18,7 @@ import com.google.android.material.tabs.TabLayoutMediator; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.ui.common.PagedToolbarFragment; public class EpisodesFragment extends PagedToolbarFragment { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java index 9b2156a2b..0a402a14b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -28,6 +28,7 @@ import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.event.PlayerStatusEvent; import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; +import de.danoeh.antennapod.ui.common.PagedToolbarFragment; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import org.greenrobot.eventbus.EventBus; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java index ccc4e2e5f..d396a3cd4 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java @@ -42,10 +42,11 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; 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.ui.statistics.StatisticsFragment; +import de.danoeh.antennapod.ui.statistics.feed.FeedStatisticsFragment; import de.danoeh.antennapod.view.ToolbarIconTintManager; import io.reactivex.Completable; import io.reactivex.Maybe; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index d6ff15799..fbba99663 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -9,6 +9,7 @@ import android.os.Handler; import android.os.Looper; import android.util.Log; import android.view.ContextMenu; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -19,14 +20,13 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.google.android.material.appbar.AppBarLayout; @@ -35,43 +35,36 @@ import com.google.android.material.snackbar.Snackbar; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconTextView; import com.leinardi.android.speeddial.SpeedDialView; - -import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; -import org.apache.commons.lang3.Validate; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.List; -import java.util.Set; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; -import de.danoeh.antennapod.event.FavoritesEvent; -import de.danoeh.antennapod.event.FeedItemEvent; -import de.danoeh.antennapod.event.FeedListUpdateEvent; -import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; -import de.danoeh.antennapod.event.PlayerStatusEvent; -import de.danoeh.antennapod.event.QueueEvent; -import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.feed.FeedEvent; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.FastBlurTransformation; +import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; import de.danoeh.antennapod.core.service.download.DownloadService; +import de.danoeh.antennapod.model.download.DownloadStatus; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.FeedItemPermutors; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; +import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog; import de.danoeh.antennapod.dialog.FilterDialog; import de.danoeh.antennapod.dialog.RemoveFeedDialog; import de.danoeh.antennapod.dialog.RenameItemDialog; -import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; +import de.danoeh.antennapod.event.FavoritesEvent; +import de.danoeh.antennapod.event.FeedItemEvent; +import de.danoeh.antennapod.event.FeedListUpdateEvent; +import de.danoeh.antennapod.event.PlayerStatusEvent; +import de.danoeh.antennapod.event.QueueEvent; +import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; +import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler; +import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.model.feed.Feed; @@ -80,12 +73,18 @@ import de.danoeh.antennapod.model.feed.FeedItemFilter; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.ToolbarIconTintManager; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; +import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; -import android.view.KeyEvent; -import androidx.fragment.app.Fragment; +import org.apache.commons.lang3.Validate; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.List; +import java.util.Set; /** * Displays a list of FeedItems. @@ -547,17 +546,34 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem ((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE); } }); - txtvFailure.setOnClickListener(v -> { - Intent intent = new Intent(getContext(), MainActivity.class); - intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG); - Bundle args = new Bundle(); - args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG); - intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args); - startActivity(intent); - }); + txtvFailure.setOnClickListener(v -> showErrorDetails()); headerCreated = true; } + private void showErrorDetails() { + Maybe.fromCallable( + () -> { + List<DownloadStatus> feedDownloadLog = DBReader.getFeedDownloadLog(feedID); + if (feedDownloadLog.size() == 0 || feedDownloadLog.get(0).isSuccessful()) { + return null; + } + return feedDownloadLog.get(0); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + downloadStatus -> new DownloadLogDetailsDialog(getContext(), downloadStatus).show(), + error -> error.printStackTrace(), + () -> { + Intent intent = new Intent(getContext(), MainActivity.class); + intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG); + Bundle args = new Bundle(); + args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG); + intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args); + startActivity(intent); + }); + } + private void showFeedInfo() { if (feed != null) { FeedInfoFragment fragment = FeedInfoFragment.newInstance(feed); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsDialogFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsDialogFragment.java deleted file mode 100644 index 33710b2c4..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsDialogFragment.java +++ /dev/null @@ -1,42 +0,0 @@ -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(); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsFragment.java deleted file mode 100644 index e85c2a386..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedStatisticsFragment.java +++ /dev/null @@ -1,93 +0,0 @@ -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); - - 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); - } - } - } - - 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)); - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (disposable != null) { - disposable.dispose(); - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 715786921..7d9814998 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -283,7 +283,7 @@ public class ItemFragment extends Fragment { if (item.getPubDate() != null) { String pubDateStr = DateFormatter.formatAbbrev(getActivity(), item.getPubDate()); txtvPublished.setText(pubDateStr); - txtvPublished.setContentDescription(DateFormatter.formatForAccessibility(getContext(), item.getPubDate())); + txtvPublished.setContentDescription(DateFormatter.formatForAccessibility(item.getPubDate())); } RequestOptions options = new RequestOptions() diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java deleted file mode 100644 index f79bffabc..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.danoeh.antennapod.fragment; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.Fragment; -import androidx.viewpager2.widget.ViewPager2; - -/** - * Fragment with a ViewPager where the displayed items influence the top toolbar's menu. - * All items share the same general menu items and are just allowed to show/hide them. - */ -public abstract class PagedToolbarFragment extends Fragment { - private Toolbar toolbar; - private ViewPager2 viewPager; - - /** - * Invalidate the toolbar menu if the current child fragment is visible. - * @param child The fragment to invalidate - */ - void invalidateOptionsMenuIfActive(@NonNull Fragment child) { - Fragment visibleChild = getChildFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem()); - if (visibleChild == child) { - visibleChild.onPrepareOptionsMenu(toolbar.getMenu()); - } - } - - protected void setupPagedToolbar(Toolbar toolbar, ViewPager2 viewPager) { - this.toolbar = toolbar; - this.viewPager = viewPager; - - toolbar.setOnMenuItemClickListener(item -> { - Fragment child = getChildFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem()); - if (child != null) { - return child.onOptionsItemSelected(item); - } - return false; - }); - viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageSelected(int position) { - Fragment child = getChildFragmentManager().findFragmentByTag("f" + position); - if (child != null) { - child.onPrepareOptionsMenu(toolbar.getMenu()); - } - } - }); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java index 8bfcfd1ed..f76b902cd 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java @@ -119,13 +119,12 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView. String countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, Locale.getDefault().getCountry()); if (countryCode.equals(ItunesTopListLoader.DISCOVER_HIDE_FAKE_COUNTRY_CODE)) { - errorTextView.setText(String.format(getResources().getString(R.string.discover_is_hidden), - getResources().getString(R.string.discover_hide))); + errorTextView.setText(R.string.discover_is_hidden); errorView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); - discoverGridLayout.setVisibility(View.INVISIBLE); - errorRetry.setVisibility(View.INVISIBLE); - poweredByTextView.setVisibility(View.INVISIBLE); + discoverGridLayout.setVisibility(View.GONE); + errorRetry.setVisibility(View.GONE); + poweredByTextView.setVisibility(View.GONE); return; } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index be23775ca..0142498a8 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -343,8 +343,8 @@ public class SearchFragment extends Fragment { return new Pair<>(Collections.emptyList(), Collections.emptyList()); } long feed = getArguments().getLong(ARG_FEED); - List<FeedItem> items = FeedSearcher.searchFeedItems(getContext(), query, feed); - List<Feed> feeds = FeedSearcher.searchFeeds(getContext(), query); + List<FeedItem> items = FeedSearcher.searchFeedItems(query, feed); + List<Feed> feeds = FeedSearcher.searchFeeds(query); return new Pair<>(items, feeds); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 9f6167c65..ec3240496 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -29,6 +29,7 @@ import com.joanzapata.iconify.Iconify; import com.leinardi.android.speeddial.SpeedDialView; import de.danoeh.antennapod.dialog.TagSettingsDialog; +import de.danoeh.antennapod.ui.statistics.StatisticsFragment; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -230,6 +231,9 @@ public class SubscriptionFragment extends Fragment } else if (itemId == R.id.action_search) { ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance()); return true; + } else if (itemId == R.id.action_statistics) { + ((MainActivity) getActivity()).loadChildFragment(new StatisticsFragment()); + return true; } return false; } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java b/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java index 992c925f3..5cd0f26ab 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/actions/FeedMultiSelectActionHandler.java @@ -8,8 +8,6 @@ import androidx.core.util.Consumer; import com.google.android.material.snackbar.Snackbar; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -66,9 +64,6 @@ public class FeedMultiSelectActionHandler { preferenceSwitchDialog.openDialog(); } - private static final DecimalFormat SPEED_FORMAT = - new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US)); - private void playbackSpeedPrefHandler() { PlaybackSpeedFeedSettingDialogBinding viewBinding = PlaybackSpeedFeedSettingDialogBinding.inflate(activity.getLayoutInflater()); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java index 62e2e30d1..655cd6ed4 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagFragment.java @@ -15,8 +15,6 @@ import de.danoeh.antennapod.net.sync.gpoddernet.model.GpodnetTag; * Use the newInstance method of this class to create a new TagFragment. */ public class TagFragment extends PodcastListFragment { - - private static final String TAG = "TagFragment"; private static final int PODCAST_COUNT = 50; private GpodnetTag tag; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadStatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadStatisticsFragment.java deleted file mode 100644 index ff94cc20c..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/DownloadStatisticsFragment.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.adapter.DownloadStatisticsListAdapter; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.StatisticsItem; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; - -import java.util.Collections; -import java.util.List; - -/** - * Displays the 'download statistics' screen - */ -public class DownloadStatisticsFragment extends Fragment { - private static final String TAG = DownloadStatisticsFragment.class.getSimpleName(); - - private Disposable disposable; - private RecyclerView downloadStatisticsList; - private ProgressBar progressBar; - private DownloadStatisticsListAdapter listAdapter; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View root = inflater.inflate(R.layout.statistics_activity, container, false); - downloadStatisticsList = root.findViewById(R.id.statistics_list); - progressBar = root.findViewById(R.id.progressBar); - listAdapter = new DownloadStatisticsListAdapter(getContext()); - downloadStatisticsList.setLayoutManager(new LinearLayoutManager(getContext())); - downloadStatisticsList.setAdapter(listAdapter); - return root; - } - - @Override - public void onStart() { - super.onStart(); - refreshDownloadStatistics(); - } - - private void refreshDownloadStatistics() { - progressBar.setVisibility(View.VISIBLE); - downloadStatisticsList.setVisibility(View.GONE); - loadStatistics(); - } - - private void loadStatistics() { - if (disposable != null) { - disposable.dispose(); - } - - disposable = - Observable.fromCallable(() -> { - List<StatisticsItem> statisticsData = DBReader.getStatistics(); - Collections.sort(statisticsData, (item1, item2) -> - Long.compare(item2.totalDownloadSize, item1.totalDownloadSize)); - return statisticsData; - }) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - listAdapter.update(result); - progressBar.setVisibility(View.GONE); - downloadStatisticsList.setVisibility(View.VISIBLE); - }, error -> Log.e(TAG, Log.getStackTraceString(error))); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java index 5156de432..075d01b8b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/ImportExportPreferencesFragment.java @@ -5,8 +5,6 @@ import android.app.ProgressDialog; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.util.Log; @@ -17,7 +15,9 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts.GetContent; import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; +import androidx.core.app.ShareCompat; import androidx.core.content.FileProvider; import androidx.preference.PreferenceFragmentCompat; import com.google.android.material.snackbar.Snackbar; @@ -31,7 +31,6 @@ import de.danoeh.antennapod.core.export.ExportWriter; import de.danoeh.antennapod.core.export.favorites.FavoritesWriter; import de.danoeh.antennapod.core.export.html.HtmlWriter; import de.danoeh.antennapod.core.export.opml.OpmlWriter; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DatabaseExporter; import io.reactivex.Completable; import io.reactivex.Observable; @@ -42,7 +41,6 @@ import io.reactivex.schedulers.Schedulers; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.Locale; public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { @@ -104,15 +102,13 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { private void setupStorageScreen() { findPreference(PREF_OPML_EXPORT).setOnPreferenceClickListener( preference -> { - openExportPathPicker(CONTENT_TYPE_OPML, dateStampFilename(DEFAULT_OPML_OUTPUT_NAME), - chooseOpmlExportPathLauncher, new OpmlWriter()); + openExportPathPicker(Export.OPML, chooseOpmlExportPathLauncher, new OpmlWriter()); return true; } ); findPreference(PREF_HTML_EXPORT).setOnPreferenceClickListener( preference -> { - openExportPathPicker(CONTENT_TYPE_HTML, dateStampFilename(DEFAULT_HTML_OUTPUT_NAME), - chooseHtmlExportPathLauncher, new HtmlWriter()); + openExportPathPicker(Export.HTML, chooseHtmlExportPathLauncher, new HtmlWriter()); return true; }); findPreference(PREF_OPML_IMPORT).setOnPreferenceClickListener( @@ -136,13 +132,12 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { }); findPreference(PREF_FAVORITE_EXPORT).setOnPreferenceClickListener( preference -> { - openExportPathPicker(CONTENT_TYPE_HTML, dateStampFilename(DEFAULT_FAVORITES_OUTPUT_NAME), - chooseFavoritesExportPathLauncher, new FavoritesWriter()); + openExportPathPicker(Export.FAVORITES, chooseFavoritesExportPathLauncher, new FavoritesWriter()); return true; }); } - private void exportWithWriter(ExportWriter exportWriter, final Uri uri) { + private void exportWithWriter(ExportWriter exportWriter, Uri uri, Export exportType) { Context context = getActivity(); progressDialog.show(); if (uri == null) { @@ -152,7 +147,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { .subscribe(output -> { Uri fileUri = FileProvider.getUriForFile(context.getApplicationContext(), context.getString(R.string.provider_authority), output); - showExportSuccessDialog(output.toString(), fileUri); + showExportSuccessDialog(output.toString(), fileUri, exportType); }, this::showExportErrorDialog, progressDialog::dismiss); } else { DocumentFileExportWorker worker = new DocumentFileExportWorker(exportWriter, context, uri); @@ -160,7 +155,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(output -> - showExportSuccessDialog(output.getUri().toString(), output.getUri()), + showExportSuccessDialog(output.getUri().toString(), output.getUri(), exportType), this::showExportErrorDialog, progressDialog::dismiss); } } @@ -196,25 +191,18 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { builder.show(); } - private void showExportSuccessDialog(final String path, final Uri streamUri) { + private void showExportSuccessDialog(String path, Uri streamUri, Export exportType) { final AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); alert.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss()); alert.setTitle(R.string.export_success_title); alert.setMessage(getContext().getString(R.string.export_success_sum, path)); alert.setPositiveButton(R.string.send_label, (dialog, which) -> { - Intent sendIntent = new Intent(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.opml_export_label)); - sendIntent.putExtra(Intent.EXTRA_STREAM, streamUri); - sendIntent.setType("text/plain"); - sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - Intent chooserIntent = Intent.createChooser(sendIntent, getString(R.string.send_label)); - List<ResolveInfo> resInfoList = getContext().getPackageManager() - .queryIntentActivities(sendIntent, PackageManager.MATCH_DEFAULT_ONLY); - for (ResolveInfo resolveInfo : resInfoList) { - String packageName = resolveInfo.activityInfo.packageName; - getContext().grantUriPermission(packageName, streamUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - getContext().startActivity(chooserIntent); + new ShareCompat.IntentBuilder(getContext()) + .setType(exportType.contentType) + .setSubject(getString(exportType.labelResId)) + .addStream(streamUri) + .setChooserTitle(R.string.send_label) + .startChooser(); }); alert.create().show(); } @@ -233,7 +221,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { return; } final Uri uri = result.getData().getData(); - exportWithWriter(new OpmlWriter(), uri); + exportWithWriter(new OpmlWriter(), uri, Export.OPML); } private void chooseHtmlExportPathResult(final ActivityResult result) { @@ -241,7 +229,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { return; } final Uri uri = result.getData().getData(); - exportWithWriter(new HtmlWriter(), uri); + exportWithWriter(new HtmlWriter(), uri, Export.HTML); } private void chooseFavoritesExportPathResult(final ActivityResult result) { @@ -249,7 +237,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { return; } final Uri uri = result.getData().getData(); - exportWithWriter(new FavoritesWriter(), uri); + exportWithWriter(new FavoritesWriter(), uri, Export.FAVORITES); } private void restoreDatabaseResult(final ActivityResult result) { @@ -263,7 +251,6 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { .observeOn(AndroidSchedulers.mainThread()) .subscribe(() -> { showDatabaseImportSuccessDialog(); - UserPreferences.unsetUsageCountingDate(); progressDialog.dismiss(); }, this::showExportErrorDialog); } @@ -291,11 +278,12 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { startActivity(intent); } - private void openExportPathPicker(String contentType, String title, - final ActivityResultLauncher<Intent> result, ExportWriter writer) { + private void openExportPathPicker(Export exportType, ActivityResultLauncher<Intent> result, ExportWriter writer) { + String title = dateStampFilename(exportType.outputNameTemplate); + Intent intentPickAction = new Intent(Intent.ACTION_CREATE_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) - .setType(contentType) + .setType(exportType.contentType) .putExtra(Intent.EXTRA_TITLE, title); // Creates an implicit intent to launch a file manager which lets @@ -309,7 +297,7 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { // If we are using a SDK lower than API 21 or the implicit intent failed // fallback to the legacy export process - exportWithWriter(writer, null); + exportWithWriter(writer, null, exportType); } private static class BackupDatabase extends ActivityResultContracts.CreateDocument { @@ -321,4 +309,21 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat { .setType("application/x-sqlite3"); } } + + private enum Export { + OPML(CONTENT_TYPE_OPML, DEFAULT_OPML_OUTPUT_NAME, R.string.opml_export_label), + HTML(CONTENT_TYPE_HTML, DEFAULT_HTML_OUTPUT_NAME, R.string.html_export_label), + FAVORITES(CONTENT_TYPE_HTML, DEFAULT_FAVORITES_OUTPUT_NAME, R.string.favorites_export_label); + + final String contentType; + final String outputNameTemplate; + @StringRes + final int labelResId; + + Export(String contentType, String outputNameTemplate, int labelResId) { + this.contentType = contentType; + this.outputNameTemplate = outputNameTemplate; + this.labelResId = labelResId; + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java index 891d3737b..e2c5036df 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java @@ -29,7 +29,6 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat { private static final String PREF_VIEW_FORUM = "prefViewForum"; private static final String PREF_SEND_BUG_REPORT = "prefSendBugReport"; private static final String PREF_CATEGORY_PROJECT = "project"; - private static final String STATISTICS = "statistics"; private static final String PREF_ABOUT = "prefAbout"; private static final String PREF_NOTIFICATION = "notifications"; private static final String PREF_CONTRIBUTE = "prefContribute"; @@ -106,14 +105,6 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat { return true; } ); - findPreference(STATISTICS).setOnPreferenceClickListener( - preference -> { - getParentFragmentManager().beginTransaction() - .replace(R.id.settingsContainer, new StatisticsFragment()) - .addToBackStack(getString(R.string.statistics_label)).commit(); - return true; - } - ); findPreference(PREF_DOCUMENTATION).setOnPreferenceClickListener(preference -> { IntentUtils.openInBrowser(getContext(), "https://antennapod.org/documentation/"); return true; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java index 7fa2ed4d1..933a7d456 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackPreferencesFragment.java @@ -13,7 +13,6 @@ import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; import de.danoeh.antennapod.core.preferences.UsageStatistics; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; import de.danoeh.antennapod.dialog.SkipPreferenceDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; import java.util.Map; @@ -54,11 +53,6 @@ public class PlaybackPreferencesFragment extends PreferenceFragmentCompat { SkipPreferenceDialog.showSkipPreference(activity, SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, null); return true; }); - if (!PictureInPictureUtil.supportsPictureInPicture(activity)) { - ListPreference behaviour = findPreference(UserPreferences.PREF_VIDEO_BEHAVIOR); - behaviour.setEntries(R.array.video_background_behavior_options_without_pip); - behaviour.setEntryValues(R.array.video_background_behavior_values_without_pip); - } findPreference(PREF_PLAYBACK_PREFER_STREAMING).setOnPreferenceChangeListener((preference, newValue) -> { // Update all visible lists to reflect new streaming action button EventBus.getDefault().post(new UnreadItemsUpdateEvent()); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java deleted file mode 100644 index ba6164212..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/PlaybackStatisticsFragment.java +++ /dev/null @@ -1,197 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.RadioButton; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.adapter.PlaybackStatisticsListAdapter; -import de.danoeh.antennapod.core.dialog.ConfirmationDialog; -import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.storage.StatisticsItem; -import io.reactivex.Completable; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; - -import java.util.Collections; -import java.util.List; - -/** - * Displays the 'playback statistics' screen - */ -public class PlaybackStatisticsFragment extends Fragment { - private static final String TAG = PlaybackStatisticsFragment.class.getSimpleName(); - private static final String PREF_NAME = "StatisticsActivityPrefs"; - private static final String PREF_COUNT_ALL = "countAll"; - - private Disposable disposable; - private RecyclerView feedStatisticsList; - private ProgressBar progressBar; - private PlaybackStatisticsListAdapter listAdapter; - private boolean countAll = false; - private SharedPreferences prefs; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - prefs = getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - countAll = prefs.getBoolean(PREF_COUNT_ALL, false); - setHasOptionsMenu(true); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - 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(this); - listAdapter.setCountAll(countAll); - feedStatisticsList.setLayoutManager(new LinearLayoutManager(getContext())); - feedStatisticsList.setAdapter(listAdapter); - return root; - } - - @Override - public void onStart() { - super.onStart(); - refreshStatistics(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - if (disposable != null) { - disposable.dispose(); - } - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.statistics, menu); - menu.findItem(R.id.statistics_reset).setEnabled(!countAll); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.statistics_mode) { - selectStatisticsMode(); - return true; - } - if (item.getItemId() == R.id.statistics_reset) { - confirmResetStatistics(); - return true; - } - return super.onOptionsItemSelected(item); - } - - private void selectStatisticsMode() { - View contentView = View.inflate(getContext(), R.layout.statistics_mode_select_dialog, null); - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setView(contentView); - builder.setTitle(R.string.statistics_mode); - - if (countAll) { - ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).setChecked(true); - } else { - ((RadioButton) contentView.findViewById(R.id.statistics_mode_normal)).setChecked(true); - } - - builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { - countAll = ((RadioButton) contentView.findViewById(R.id.statistics_mode_count_all)).isChecked(); - listAdapter.setCountAll(countAll); - prefs.edit().putBoolean(PREF_COUNT_ALL, countAll).apply(); - refreshStatistics(); - getActivity().invalidateOptionsMenu(); - }); - - builder.show(); - } - - private void confirmResetStatistics() { - if (!countAll) { - ConfirmationDialog conDialog = new ConfirmationDialog( - getActivity(), - R.string.statistics_reset_data, - R.string.statistics_reset_data_msg) { - - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - doResetStatistics(); - } - }; - conDialog.createNewDialog().show(); - } - } - - private void doResetStatistics() { - progressBar.setVisibility(View.VISIBLE); - feedStatisticsList.setVisibility(View.GONE); - if (disposable != null) { - disposable.dispose(); - } - - disposable = Completable.fromFuture(DBWriter.resetStatistics()) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(() -> { - refreshStatistics(); - UserPreferences.resetUsageCountingDate(); - }, error -> Log.e(TAG, Log.getStackTraceString(error))); - } - - private void refreshStatistics() { - progressBar.setVisibility(View.VISIBLE); - feedStatisticsList.setVisibility(View.GONE); - loadStatistics(); - } - - private void loadStatistics() { - if (disposable != null) { - disposable.dispose(); - } - disposable = Observable.fromCallable(this::fetchStatistics) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> { - listAdapter.update(result); - progressBar.setVisibility(View.GONE); - feedStatisticsList.setVisibility(View.VISIBLE); - }, error -> Log.e(TAG, Log.getStackTraceString(error))); - } - - private List<StatisticsItem> fetchStatistics() { - List<StatisticsItem> statisticsData = DBReader.getStatistics(); - if (countAll) { - Collections.sort(statisticsData, (item1, item2) -> - Long.compare(item2.timePlayedCountAll, item1.timePlayedCountAll)); - } else { - Collections.sort(statisticsData, (item1, item2) -> - Long.compare(item2.timePlayed, item1.timePlayed)); - } - return statisticsData; - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java deleted file mode 100644 index 2c72ab75b..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StatisticsFragment.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.danoeh.antennapod.fragment.preferences; - -import android.os.Bundle; -import android.view.LayoutInflater; -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; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.PreferenceActivity; - -/** - * Displays the 'statistics' screen - */ -public class StatisticsFragment extends Fragment { - - public static final String TAG = "StatisticsFragment"; - - private static final int POS_LISTENED_HOURS = 0; - private static final int POS_SPACE_TAKEN = 1; - private static final int TOTAL_COUNT = 2; - - - private TabLayout tabLayout; - private ViewPager2 viewPager; - private Toolbar toolbar; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - setHasOptionsMenu(true); - - 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); - new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { - switch (position) { - case POS_LISTENED_HOURS: - tab.setText(R.string.playback_statistics_label); - break; - case POS_SPACE_TAKEN: - tab.setText(R.string.download_statistics_label); - break; - default: - break; - } - }).attach(); - - 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; - } - - @Override - public void onStart() { - super.onStart(); - if (getActivity().getClass() == PreferenceActivity.class) { - ((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.statistics_label); - } - } - - public static class StatisticsPagerAdapter extends FragmentStateAdapter { - - StatisticsPagerAdapter(@NonNull Fragment fragment) { - super(fragment); - } - - @NonNull - @Override - public Fragment createFragment(int position) { - switch (position) { - case POS_LISTENED_HOURS: - return new PlaybackStatisticsFragment(); - default: - case POS_SPACE_TAKEN: - return new DownloadStatisticsFragment(); - } - } - - @Override - public int getItemCount() { - return TOTAL_COUNT; - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java index e5617b8ea..00ff9fb64 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java @@ -10,7 +10,6 @@ import de.danoeh.antennapod.dialog.ChooseDataFolderDialog; import java.io.File; public class StoragePreferencesFragment extends PreferenceFragmentCompat { - private static final String TAG = "StoragePrefFragment"; private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; private static final String PREF_IMPORT_EXPORT = "prefImportExport"; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java index 3d9709f74..19099a380 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/SwipePreferencesFragment.java @@ -11,8 +11,6 @@ import de.danoeh.antennapod.fragment.QueueFragment; public class SwipePreferencesFragment extends PreferenceFragmentCompat { private static final String PREF_SWIPE_FEED = "prefSwipeFeed"; private static final String PREF_SWIPE_QUEUE = "prefSwipeQueue"; - //private static final String PREF_SWIPE_INBOX = "prefSwipeInbox"; - //private static final String PREF_SWIPE_EPISODES = "prefSwipeEpisodes"; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java index 20cef1313..caa8031ae 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/ContributorsPagerFragment.java @@ -17,19 +17,12 @@ import de.danoeh.antennapod.activity.PreferenceActivity; * Displays the 'about->Contributors' pager screen. */ public class ContributorsPagerFragment extends Fragment { - - public static final String TAG = "StatisticsFragment"; - private static final int POS_DEVELOPERS = 0; private static final int POS_TRANSLATORS = 1; private static final int POS_SPECIAL_THANKS = 2; private static final int TOTAL_COUNT = 3; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java index 9dfe6840c..358985cea 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java @@ -250,18 +250,6 @@ public class GpodderAuthenticationFragment extends DialogFragment { return false; } - private GpodnetDevice findDevice(String id) { - if (devices == null) { - return null; - } - for (GpodnetDevice device : devices) { - if (device.getId().equals(id)) { - return device; - } - } - return null; - } - private void setupFinishView(View view) { final Button sync = view.findViewById(R.id.butSyncNow); diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java index af35bbac9..a2c5ca3ff 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java @@ -39,9 +39,6 @@ public class PreferenceUpgrader { private static void upgrade(int oldVersion, Context context) { if (oldVersion == -1) { //New installation - if (UserPreferences.getUsageCountingDateMillis() < 0) { - UserPreferences.resetUsageCountingDate(); - } return; } if (oldVersion < 1070196) { @@ -93,9 +90,6 @@ public class PreferenceUpgrader { UserPreferences.setEnqueueLocation(enqueueLocation); } } - if (oldVersion < 1080100) { - prefs.edit().putString(UserPreferences.PREF_VIDEO_BEHAVIOR, "pip").apply(); - } if (oldVersion < 2010300) { // Migrate hardware button preferences if (prefs.getBoolean("prefHardwareForwardButtonSkips", false)) { diff --git a/app/src/main/java/de/danoeh/antennapod/view/PieChartView.java b/app/src/main/java/de/danoeh/antennapod/view/PieChartView.java deleted file mode 100644 index ab4920119..000000000 --- a/app/src/main/java/de/danoeh/antennapod/view/PieChartView.java +++ /dev/null @@ -1,149 +0,0 @@ -package de.danoeh.antennapod.view; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatImageView; -import io.reactivex.annotations.Nullable; - -public class PieChartView extends AppCompatImageView { - private PieChartDrawable drawable; - - public PieChartView(Context context) { - super(context); - setup(); - } - - public PieChartView(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - setup(); - } - - public PieChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - setup(); - } - - @SuppressLint("ClickableViewAccessibility") - private void setup() { - drawable = new PieChartDrawable(); - setImageDrawable(drawable); - } - - /** - * Set of data values to display. - */ - public void setData(PieChartData data) { - drawable.data = data; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int width = getMeasuredWidth(); - setMeasuredDimension(width, width / 2); - } - - public static class PieChartData { - private static final int[] COLOR_VALUES = new int[]{0xFF3775E6, 0xffe51c23, 0xffff9800, 0xff259b24, 0xff9c27b0, - 0xff0099c6, 0xffdd4477, 0xff66aa00, 0xffb82e2e, 0xff316395, - 0xff994499, 0xff22aa99, 0xffaaaa11, 0xff6633cc, 0xff0073e6}; - - private final float valueSum; - private final float[] values; - - public PieChartData(float[] values) { - this.values = values; - float valueSum = 0; - for (float datum : values) { - valueSum += datum; - } - this.valueSum = valueSum; - } - - public float getSum() { - return valueSum; - } - - public float getPercentageOfItem(int index) { - if (valueSum == 0) { - return 0; - } - return values[index] / valueSum; - } - - public boolean isLargeEnoughToDisplay(int index) { - return getPercentageOfItem(index) > 0.04; - } - - public int getColorOfItem(int index) { - if (!isLargeEnoughToDisplay(index)) { - return Color.GRAY; - } - return COLOR_VALUES[index % COLOR_VALUES.length]; - } - } - - private static class PieChartDrawable extends Drawable { - private static final float PADDING_DEGREES = 3f; - private PieChartData data; - private final Paint paint; - - private PieChartDrawable() { - paint = new Paint(); - paint.setFlags(Paint.ANTI_ALIAS_FLAG); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeJoin(Paint.Join.ROUND); - paint.setStrokeCap(Paint.Cap.ROUND); - } - - @Override - public void draw(@NonNull Canvas canvas) { - final float strokeSize = getBounds().height() / 30f; - paint.setStrokeWidth(strokeSize); - - float radius = getBounds().height() - strokeSize; - float center = getBounds().width() / 2.f; - RectF arcBounds = new RectF(center - radius, strokeSize, center + radius, strokeSize + radius * 2); - - float startAngle = 180; - for (int i = 0; i < data.values.length; i++) { - if (!data.isLargeEnoughToDisplay(i)) { - break; - } - paint.setColor(data.getColorOfItem(i)); - float padding = i == 0 ? PADDING_DEGREES / 2 : PADDING_DEGREES; - float sweepAngle = (180f - PADDING_DEGREES) * data.getPercentageOfItem(i); - canvas.drawArc(arcBounds, startAngle + padding, sweepAngle - padding, false, paint); - startAngle = startAngle + sweepAngle; - } - - paint.setColor(Color.GRAY); - float sweepAngle = 360 - startAngle - PADDING_DEGREES / 2; - if (sweepAngle > PADDING_DEGREES) { - canvas.drawArc(arcBounds, startAngle + PADDING_DEGREES, sweepAngle - PADDING_DEGREES, false, paint); - } - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int alpha) { - } - - @Override - public void setColorFilter(ColorFilter cf) { - } - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java index d231e522f..c1ab3a7a6 100644 --- a/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java +++ b/app/src/main/java/de/danoeh/antennapod/view/viewholder/EpisodeItemViewHolder.java @@ -104,7 +104,7 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder { title.setText(item.getTitle()); leftPadding.setContentDescription(item.getTitle()); pubDate.setText(DateFormatter.formatAbbrev(activity, item.getPubDate())); - pubDate.setContentDescription(DateFormatter.formatForAccessibility(activity, item.getPubDate())); + pubDate.setContentDescription(DateFormatter.formatForAccessibility(item.getPubDate())); isNew.setVisibility(item.isNew() ? View.VISIBLE : View.GONE); isFavorite.setVisibility(item.isTagged(FeedItem.TAG_FAVORITE) ? View.VISIBLE : View.GONE); isInQueue.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE); |