summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2021-01-22 11:07:40 +0100
committerByteHamster <info@bytehamster.com>2021-01-22 11:07:40 +0100
commitcdf59a1c8e99720fd737fcbcc1f5ac1eb5252890 (patch)
tree119819aaec911b7510dc3f3bb1a5a4a6ddf82c1c /app/src/main/java/de/danoeh/antennapod
parent85b897c7d778ae70d837ae0c2a9e7b4252ea8945 (diff)
parent41d23fa671a3ad7d417f4791c63d0f25634d725f (diff)
downloadAntennaPod-cdf59a1c8e99720fd737fcbcc1f5ac1eb5252890.zip
Merge branch 'develop' into fix_episodes_list_item_loading_b
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java88
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java86
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java57
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java19
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java16
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java13
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java49
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java395
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java20
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java14
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java59
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java52
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java12
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java22
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java61
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java42
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java28
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java6
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java46
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java40
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java47
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java37
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java80
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java41
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java302
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java17
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/MainPreferencesFragment.java29
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java64
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java1
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java124
67 files changed, 820 insertions, 1208 deletions
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 bff11fa5e..721291597 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
@@ -11,10 +11,15 @@ import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import com.google.android.material.snackbar.Snackbar;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
+import android.view.Menu;
+import android.view.MenuItem;
import android.widget.TextView;
@@ -67,42 +72,65 @@ public class BugReportActivity extends AppCompatActivity {
clipboard.setPrimaryClip(clip);
Snackbar.make(findViewById(android.R.id.content), R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show();
});
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.bug_report_options, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
- findViewById(R.id.btn_export_logcat).setOnClickListener(v -> {
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == R.id.export_logcat) {
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
+ alertBuilder.setMessage(R.string.confirm_export_log_dialog_message);
+ alertBuilder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
+ exportLog();
+ dialog.dismiss();
+ });
+ alertBuilder.setNegativeButton(R.string.cancel_label, null);
+ alertBuilder.show();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void exportLog() {
+ try {
+ File filename = new File(UserPreferences.getDataFolder(null), "full-logs.txt");
+ filename.createNewFile();
+ String cmd = "logcat -d -f " + filename.getAbsolutePath();
+ Runtime.getRuntime().exec(cmd);
+ //share file
try {
- File filename = new File(UserPreferences.getDataFolder(null), "full-logs.txt");
- filename.createNewFile();
- String cmd = "logcat -d -f " + filename.getAbsolutePath();
- Runtime.getRuntime().exec(cmd);
- //share file
- try {
- Intent i = new Intent(Intent.ACTION_SEND);
- i.setType("text/*");
- String authString = getString(de.danoeh.antennapod.core.R.string.provider_authority);
- Uri fileUri = FileProvider.getUriForFile(this, authString, filename);
- i.putExtra(Intent.EXTRA_STREAM, fileUri);
- i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resInfos = pm.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
- for (ResolveInfo resolveInfo : resInfos) {
- String packageName = resolveInfo.activityInfo.packageName;
- grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType("text/*");
+ String authString = getString(de.danoeh.antennapod.core.R.string.provider_authority);
+ Uri fileUri = FileProvider.getUriForFile(this, authString, filename);
+ i.putExtra(Intent.EXTRA_STREAM, fileUri);
+ i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> resInfos = pm.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
+ for (ResolveInfo resolveInfo : resInfos) {
+ String packageName = resolveInfo.activityInfo.packageName;
+ grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
- String chooserTitle = getString(de.danoeh.antennapod.core.R.string.share_file_label);
- startActivity(Intent.createChooser(i, chooserTitle));
- } catch (Exception e) {
- e.printStackTrace();
- int strResId = R.string.log_file_share_exception;
- Snackbar.make(findViewById(android.R.id.content), strResId, Snackbar.LENGTH_LONG)
- .show();
}
- } catch (IOException e) {
+ String chooserTitle = getString(de.danoeh.antennapod.core.R.string.share_file_label);
+ startActivity(Intent.createChooser(i, chooserTitle));
+ } catch (Exception e) {
e.printStackTrace();
- Snackbar.make(findViewById(android.R.id.content), e.getMessage(), Snackbar.LENGTH_LONG).show();
+ int strResId = R.string.log_file_share_exception;
+ Snackbar.make(findViewById(android.R.id.content), strResId, Snackbar.LENGTH_LONG)
+ .show();
}
- });
+ } catch (IOException e) {
+ e.printStackTrace();
+ Snackbar.make(findViewById(android.R.id.content), e.getMessage(), Snackbar.LENGTH_LONG).show();
+ }
}
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
index 1d3d9bf11..4900f0e27 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/DownloadAuthenticationActivity.java
@@ -1,62 +1,54 @@
package de.danoeh.antennapod.activity;
import android.app.Activity;
-import android.content.Intent;
import android.os.Bundle;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import android.widget.Button;
+import android.text.TextUtils;
import android.widget.EditText;
import android.widget.TextView;
-
-import org.apache.commons.lang3.Validate;
-
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedMedia;
+import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadRequest;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import io.reactivex.Completable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+import org.apache.commons.lang3.Validate;
+
/**
* Shows a username and a password text field.
* The activity MUST be started with the ARG_DOWNlOAD_REQUEST argument set to a non-null value.
- * Other arguments are optional.
- * The activity's result will be the same DownloadRequest with the entered username and password.
*/
public class DownloadAuthenticationActivity extends AppCompatActivity {
/**
- * The download request object that contains information about the resource that requires a username and a password
+ * The download request object that contains information about the resource that requires a username and a password.
*/
public static final String ARG_DOWNLOAD_REQUEST = "request";
- /**
- * True if the request should be sent to the DownloadRequester when this activity is finished, false otherwise.
- * The default value is false.
- */
- public static final String ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL = "send_to_downloadrequester";
-
- private static final String RESULT_REQUEST = "request";
private EditText etxtUsername;
private EditText etxtPassword;
+ private DownloadRequest request;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getNoTitleTheme());
super.onCreate(savedInstanceState);
-
setContentView(R.layout.download_authentication_activity);
- TextView txtvDescription = findViewById(R.id.txtvDescription);
+
etxtUsername = findViewById(R.id.etxtUsername);
etxtPassword = findViewById(R.id.etxtPassword);
- Button butConfirm = findViewById(R.id.butConfirm);
- Button butCancel = findViewById(R.id.butCancel);
Validate.isTrue(getIntent().hasExtra(ARG_DOWNLOAD_REQUEST), "Download request missing");
- DownloadRequest request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
- boolean sendToDownloadRequester = getIntent().getBooleanExtra(ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, false);
+ request = getIntent().getParcelableExtra(ARG_DOWNLOAD_REQUEST);
+ TextView txtvDescription = findViewById(R.id.txtvDescription);
String newDescription = txtvDescription.getText() + ":\n\n" + request.getTitle();
txtvDescription.setText(newDescription);
@@ -65,28 +57,42 @@ public class DownloadAuthenticationActivity extends AppCompatActivity {
etxtPassword.setText(savedInstanceState.getString("password"));
}
- butConfirm.setOnClickListener(v -> {
- String username = etxtUsername.getText().toString();
- String password = etxtPassword.getText().toString();
- request.setUsername(username);
- request.setPassword(password);
- Intent result = new Intent();
- result.putExtra(RESULT_REQUEST, request);
- setResult(Activity.RESULT_OK, result);
-
- if (sendToDownloadRequester) {
- DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
- }
- finish();
- });
+ findViewById(R.id.butConfirm).setOnClickListener(v ->
+ Completable.fromAction(this::updatePassword)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ DownloadRequester.getInstance().download(DownloadAuthenticationActivity.this, request);
+ finish();
+ }));
- butCancel.setOnClickListener(v -> {
+ findViewById(R.id.butCancel).setOnClickListener(v -> {
setResult(Activity.RESULT_CANCELED);
finish();
});
}
+ private void updatePassword() {
+ String username = etxtUsername.getText().toString();
+ String password = etxtPassword.getText().toString();
+ request.setUsername(username);
+ request.setPassword(password);
+
+ if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
+ long mediaId = request.getFeedfileId();
+ FeedMedia media = DBReader.getFeedMedia(mediaId);
+ if (media != null) {
+ FeedPreferences preferences = media.getItem().getFeed().getPreferences();
+ if (TextUtils.isEmpty(preferences.getPassword()) || TextUtils.isEmpty(preferences.getUsername())) {
+ preferences.setUsername(username);
+ preferences.setPassword(password);
+ DBWriter.setFeedPreferences(preferences);
+ }
+ }
+ }
+ }
+
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
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 d39edb9b2..d1716e009 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -16,6 +16,7 @@ import android.view.KeyEvent;
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;
@@ -542,6 +543,11 @@ public class MainActivity extends CastEnabledActivity {
//Hardware keyboard support
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ View currentFocus = getCurrentFocus();
+ if (currentFocus instanceof EditText) {
+ return super.onKeyUp(keyCode, event);
+ }
+
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
Integer customKeyCode = null;
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
index b03d1e5cd..c1d921f8c 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java
@@ -1,10 +1,9 @@
package de.danoeh.antennapod.activity;
-import android.Manifest;
+
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
@@ -17,7 +16,6 @@ import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
-import android.widget.Toast;
import com.bumptech.glide.Glide;
@@ -28,18 +26,13 @@ import org.greenrobot.eventbus.ThreadMode;
import java.text.NumberFormat;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
-import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
@@ -51,11 +44,9 @@ import de.danoeh.antennapod.core.util.ShareUtils;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.TimeSpeedConverter;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
-import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
import de.danoeh.antennapod.dialog.ShareDialog;
import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
@@ -74,8 +65,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
private static final String TAG = "MediaplayerActivity";
private static final String PREFS = "MediaPlayerActivityPreferences";
private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft";
- private static final int REQUEST_CODE_STORAGE_PLAY_VIDEO = 42;
- private static final int REQUEST_CODE_STORAGE_PLAY_AUDIO = 43;
PlaybackController controller;
@@ -664,50 +653,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
- void playExternalMedia(Intent intent, MediaType type) {
- if (intent == null || intent.getData() == null) {
- return;
- }
- if (Build.VERSION.SDK_INT >= 23
- && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
-
- if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
- Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show();
- }
-
- int code = REQUEST_CODE_STORAGE_PLAY_AUDIO;
- if (type == MediaType.VIDEO) {
- code = REQUEST_CODE_STORAGE_PLAY_VIDEO;
- }
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, code);
- return;
- }
-
- Log.d(TAG, "Received VIEW intent: " + intent.getData().getPath());
- ExternalMedia media = new ExternalMedia(intent.getData().getPath(), type);
-
- new PlaybackServiceStarter(this, media)
- .callEvenIfRunning(true)
- .startWhenPrepared(true)
- .shouldStream(false)
- .prepareImmediately(true)
- .start();
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- if (requestCode == REQUEST_CODE_STORAGE_PLAY_AUDIO) {
- playExternalMedia(getIntent(), MediaType.AUDIO);
- } else if (requestCode == REQUEST_CODE_STORAGE_PLAY_VIDEO) {
- playExternalMedia(getIntent(), MediaType.VIDEO);
- }
- } else {
- Toast.makeText(this, R.string.needs_storage_permission, Toast.LENGTH_LONG).show();
- }
- }
-
@Nullable
private static FeedItem getFeedItem(@Nullable Playable playable) {
if (playable instanceof FeedMedia) {
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 2fd537159..f53c629b9 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -4,6 +4,7 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.LightingColorFilter;
import android.os.Build;
import android.os.Bundle;
@@ -13,7 +14,6 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
-import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
@@ -88,6 +88,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
// Optional argument: specify a title for the actionbar.
private static final int RESULT_ERROR = 2;
private static final String TAG = "OnlineFeedViewActivity";
+ private static final String PREFS = "OnlineFeedViewActivityPreferences";
+ private static final String PREF_LAST_AUTO_DOWNLOAD = "lastAutoDownload";
+
private volatile List<Feed> feeds;
private Feed feed;
private String selectedDownloadUrl;
@@ -446,6 +449,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
IntentUtils.sendLocalBroadcast(this, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE);
});
+ if (UserPreferences.isEnableAutodownload()) {
+ SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE);
+ viewBinding.autoDownloadCheckBox.setChecked(preferences.getBoolean(PREF_LAST_AUTO_DOWNLOAD, true));
+ }
+
final int MAX_LINES_COLLAPSED = 10;
description.setMaxLines(MAX_LINES_COLLAPSED);
description.setOnClickListener(v -> {
@@ -512,10 +520,17 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
if (didPressSubscribe) {
didPressSubscribe = false;
if (UserPreferences.isEnableAutodownload()) {
+ boolean autoDownload = viewBinding.autoDownloadCheckBox.isChecked();
+
Feed feed1 = DBReader.getFeed(getFeedId(feed));
FeedPreferences feedPreferences = feed1.getPreferences();
- feedPreferences.setAutoDownload(viewBinding.autoDownloadCheckBox.isChecked());
+ feedPreferences.setAutoDownload(autoDownload);
feed1.savePreferences();
+
+ SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putBoolean(PREF_LAST_AUTO_DOWNLOAD, autoDownload);
+ editor.apply();
}
openFeed();
}
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
index 10292b892..d4e9ee5d9 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OpmlImportActivity.java
@@ -17,9 +17,8 @@ import de.danoeh.antennapod.asynctask.OpmlFeedQueuer;
import de.danoeh.antennapod.asynctask.OpmlImportWorker;
import de.danoeh.antennapod.core.export.opml.OpmlElement;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.util.LangUtils;
+
import org.apache.commons.io.ByteOrderMark;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.lang3.ArrayUtils;
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 d85235cf9..f0c76d545 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/SplashActivity.java
@@ -13,9 +13,9 @@ import android.widget.ProgressBar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.error.CrashReportWriter;
import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
@@ -44,13 +44,15 @@ public class SplashActivity extends AppCompatActivity {
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(() -> {
- Intent intent = new Intent(SplashActivity.this, MainActivity.class);
- startActivity(intent);
- overridePendingTransition(0, 0);
- finish();
- }, error -> {
+ .subscribe(
+ () -> {
+ Intent intent = new Intent(SplashActivity.this, MainActivity.class);
+ startActivity(intent);
+ overridePendingTransition(0, 0);
+ finish();
+ }, error -> {
error.printStackTrace();
+ CrashReportWriter.write(error);
Toast.makeText(this, error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
finish();
});
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 2d4510e8f..75198c016 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -12,12 +12,11 @@ import android.view.KeyEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
+import android.widget.EditText;
import android.widget.ImageView;
-import androidx.appcompat.view.menu.ActionMenuItem;
import androidx.core.view.WindowCompat;
import androidx.appcompat.app.ActionBar;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.Menu;
@@ -37,7 +36,6 @@ import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
@@ -88,9 +86,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
@Override
protected void onResume() {
super.onResume();
- if (TextUtils.equals(getIntent().getAction(), Intent.ACTION_VIEW)) {
- playExternalMedia(getIntent(), MediaType.VIDEO);
- } else if (PlaybackService.isCasting()) {
+ if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {
destroyingDueToReload = true;
@@ -489,6 +485,11 @@ public class VideoplayerActivity extends MediaplayerActivity {
//Hardware keyboard support
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
+ View currentFocus = getCurrentFocus();
+ if (currentFocus instanceof EditText) {
+ return super.onKeyUp(keyCode, event);
+ }
+
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
switch (keyCode) {
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 474b96c38..1b4e8b81e 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/WidgetConfigActivity.java
@@ -2,22 +2,19 @@ package de.danoeh.antennapod.activity;
import android.Manifest;
import android.app.WallpaperManager;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.widget.ImageView;
-import android.widget.RemoteViews;
-import androidx.appcompat.app.AppCompatActivity;
-
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Bundle;
import android.view.View;
-import android.widget.RelativeLayout;
+import android.widget.CheckBox;
+import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
-
+import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@@ -29,7 +26,10 @@ public class WidgetConfigActivity extends AppCompatActivity {
private SeekBar opacitySeekBar;
private TextView opacityTextView;
- private RelativeLayout widgetPreview;
+ private View widgetPreview;
+ private CheckBox ckRewind;
+ private CheckBox ckFastForward;
+ private CheckBox ckSkip;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -74,6 +74,32 @@ public class WidgetConfigActivity extends AppCompatActivity {
}
});
+
+ widgetPreview.findViewById(R.id.txtNoPlaying).setVisibility(View.GONE);
+ TextView title = widgetPreview.findViewById(R.id.txtvTitle);
+ title.setVisibility(View.VISIBLE);
+ title.setText(R.string.app_name);
+ TextView progress = widgetPreview.findViewById(R.id.txtvProgress);
+ progress.setVisibility(View.VISIBLE);
+ progress.setText(R.string.position_default_label);
+
+ ckRewind = findViewById(R.id.ckRewind);
+ ckRewind.setOnClickListener(v -> displayPreviewPanel());
+ ckFastForward = findViewById(R.id.ckFastForward);
+ ckFastForward.setOnClickListener(v -> displayPreviewPanel());
+ ckSkip = findViewById(R.id.ckSkip);
+ ckSkip.setOnClickListener(v -> displayPreviewPanel());
+ }
+
+ private void displayPreviewPanel() {
+ boolean showExtendedPreview = ckRewind.isChecked() || ckFastForward.isChecked() || ckSkip.isChecked();
+ widgetPreview.findViewById(R.id.extendedButtonsContainer)
+ .setVisibility(showExtendedPreview ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butPlay).setVisibility(showExtendedPreview ? View.GONE : View.VISIBLE);
+ widgetPreview.findViewById(R.id.butFastForward)
+ .setVisibility(ckFastForward.isChecked() ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butSkip).setVisibility(ckSkip.isChecked() ? View.VISIBLE : View.GONE);
+ widgetPreview.findViewById(R.id.butRew).setVisibility(ckRewind.isChecked() ? View.VISIBLE : View.GONE);
}
private void displayDeviceBackground() {
@@ -92,6 +118,9 @@ public class WidgetConfigActivity extends AppCompatActivity {
SharedPreferences prefs = getSharedPreferences(PlayerWidget.PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PlayerWidget.KEY_WIDGET_COLOR + appWidgetId, backgroundColor);
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_SKIP + appWidgetId, ckSkip.isChecked());
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_REWIND + appWidgetId, ckRewind.isChecked());
+ editor.putBoolean(PlayerWidget.KEY_WIDGET_FAST_FORWARD + appWidgetId, ckFastForward.isChecked());
editor.apply();
Intent resultValue = new Intent();
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
deleted file mode 100644
index cfd6ec702..000000000
--- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java
+++ /dev/null
@@ -1,395 +0,0 @@
-package de.danoeh.antennapod.activity.gpoddernet;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.ViewFlipper;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import de.danoeh.antennapod.BuildConfig;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
-import de.danoeh.antennapod.core.sync.SyncService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetServiceException;
-import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetDevice;
-
-/**
- * Guides the user through the authentication process
- * Step 1: Request username and password from user
- * Step 2: Choose device from a list of available devices or create a new one
- * Step 3: Choose from a list of actions
- */
-public class GpodnetAuthenticationActivity extends AppCompatActivity {
- private static final String TAG = "GpodnetAuthActivity";
-
- private ViewFlipper viewFlipper;
-
- private static final int STEP_DEFAULT = -1;
- private static final int STEP_LOGIN = 0;
- private static final int STEP_DEVICE = 1;
- private static final int STEP_FINISH = 2;
-
- private int currentStep = -1;
-
- private GpodnetService service;
- private volatile String username;
- private volatile String password;
- private volatile GpodnetDevice selectedDevice;
-
- private View[] views;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(savedInstanceState);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- setContentView(R.layout.gpodnetauth_activity);
- service = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetPreferences.getHostname());
-
- viewFlipper = findViewById(R.id.viewflipper);
- LayoutInflater inflater = (LayoutInflater)
- getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- views = new View[]{
- inflater.inflate(R.layout.gpodnetauth_credentials, viewFlipper, false),
- inflater.inflate(R.layout.gpodnetauth_device, viewFlipper, false),
- inflater.inflate(R.layout.gpodnetauth_finish, viewFlipper, false)
- };
- for (View view : views) {
- viewFlipper.addView(view);
- }
- advance();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void setupLoginView(View view) {
- final EditText username = view.findViewById(R.id.etxtUsername);
- final EditText password = view.findViewById(R.id.etxtPassword);
- final Button login = view.findViewById(R.id.butLogin);
- final TextView txtvError = view.findViewById(R.id.txtvError);
- final ProgressBar progressBar = view.findViewById(R.id.progBarLogin);
-
- password.setOnEditorActionListener((v, actionID, event) ->
- actionID == EditorInfo.IME_ACTION_GO && login.performClick());
-
- login.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- final String usernameStr = username.getText().toString();
- final String passwordStr = password.getText().toString();
-
- if (usernameHasUnwantedChars(usernameStr)) {
- txtvError.setText(R.string.gpodnetsync_username_characters_error);
- txtvError.setVisibility(View.VISIBLE);
- return;
- }
- if (BuildConfig.DEBUG) Log.d(TAG, "Checking login credentials");
- AsyncTask<GpodnetService, Void, Void> authTask = new AsyncTask<GpodnetService, Void, Void>() {
-
- volatile Exception exception;
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- login.setEnabled(false);
- progressBar.setVisibility(View.VISIBLE);
- txtvError.setVisibility(View.GONE);
- // hide the keyboard
- InputMethodManager inputManager = (InputMethodManager)
- getSystemService(Context.INPUT_METHOD_SERVICE);
- inputManager.hideSoftInputFromWindow(login.getWindowToken(),
- InputMethodManager.HIDE_NOT_ALWAYS);
-
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- super.onPostExecute(aVoid);
- login.setEnabled(true);
- progressBar.setVisibility(View.GONE);
-
- if (exception == null) {
- advance();
- } else {
- txtvError.setText(exception.getCause().getMessage());
- txtvError.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected Void doInBackground(GpodnetService... params) {
- try {
- params[0].authenticate(usernameStr, passwordStr);
- GpodnetAuthenticationActivity.this.username = usernameStr;
- GpodnetAuthenticationActivity.this.password = passwordStr;
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- exception = e;
- }
- return null;
- }
- };
- authTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, service);
- }
- });
- }
-
- private void setupDeviceView(View view) {
- final EditText deviceID = view.findViewById(R.id.etxtDeviceID);
- final EditText caption = view.findViewById(R.id.etxtCaption);
- final Button createNewDevice = view.findViewById(R.id.butCreateNewDevice);
- final Button chooseDevice = view.findViewById(R.id.butChooseExistingDevice);
- final TextView txtvError = view.findViewById(R.id.txtvError);
- final ProgressBar progBarCreateDevice = view.findViewById(R.id.progbarCreateDevice);
- final Spinner spinnerDevices = view.findViewById(R.id.spinnerChooseDevice);
-
-
- // load device list
- final AtomicReference<List<GpodnetDevice>> devices = new AtomicReference<>();
- new AsyncTask<GpodnetService, Void, List<GpodnetDevice>>() {
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- chooseDevice.setEnabled(false);
- spinnerDevices.setEnabled(false);
- createNewDevice.setEnabled(false);
- }
-
- @Override
- protected void onPostExecute(List<GpodnetDevice> gpodnetDevices) {
- super.onPostExecute(gpodnetDevices);
- if (gpodnetDevices != null) {
- List<String> deviceNames = new ArrayList<>();
- for (GpodnetDevice device : gpodnetDevices) {
- deviceNames.add(device.getCaption());
- }
- spinnerDevices.setAdapter(new ArrayAdapter<>(GpodnetAuthenticationActivity.this,
- android.R.layout.simple_spinner_dropdown_item, deviceNames));
- spinnerDevices.setEnabled(true);
- if (!deviceNames.isEmpty()) {
- chooseDevice.setEnabled(true);
- }
- devices.set(gpodnetDevices);
- deviceID.setText(generateDeviceID(gpodnetDevices));
- createNewDevice.setEnabled(true);
- }
- }
-
- @Override
- protected List<GpodnetDevice> doInBackground(GpodnetService... params) {
- try {
- return params[0].getDevices();
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- return null;
- }
- }
- }.execute(service);
-
-
- createNewDevice.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (checkDeviceIDText(deviceID, caption, txtvError, devices.get())) {
- final String deviceStr = deviceID.getText().toString();
- final String captionStr = caption.getText().toString();
-
- new AsyncTask<GpodnetService, Void, GpodnetDevice>() {
-
- private volatile Exception exception;
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- createNewDevice.setEnabled(false);
- chooseDevice.setEnabled(false);
- progBarCreateDevice.setVisibility(View.VISIBLE);
- txtvError.setVisibility(View.GONE);
- }
-
- @Override
- protected void onPostExecute(GpodnetDevice result) {
- super.onPostExecute(result);
- createNewDevice.setEnabled(true);
- chooseDevice.setEnabled(true);
- progBarCreateDevice.setVisibility(View.GONE);
- if (exception == null) {
- selectedDevice = result;
- advance();
- } else {
- txtvError.setText(exception.getMessage());
- txtvError.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- protected GpodnetDevice doInBackground(GpodnetService... params) {
- try {
- params[0].configureDevice(deviceStr, captionStr, GpodnetDevice.DeviceType.MOBILE);
- return new GpodnetDevice(deviceStr, captionStr, GpodnetDevice.DeviceType.MOBILE.toString(), 0);
- } catch (GpodnetServiceException e) {
- e.printStackTrace();
- exception = e;
- }
- return null;
- }
- }.execute(service);
- }
- }
- });
-
- chooseDevice.setOnClickListener(v -> {
- final int position = spinnerDevices.getSelectedItemPosition();
- if (position != AdapterView.INVALID_POSITION) {
- selectedDevice = devices.get().get(position);
- advance();
- }
- });
- }
-
-
- private String generateDeviceID(List<GpodnetDevice> gpodnetDevices) {
- // devices names must be of a certain form:
- // https://gpoddernet.readthedocs.org/en/latest/api/reference/general.html#devices
- // This is more restrictive than needed, but I think it makes for more readable names.
- String baseId = Build.MODEL.replaceAll("\\W", "");
- String id = baseId;
- int num = 0;
-
- while (isDeviceWithIdInList(id, gpodnetDevices)) {
- id = baseId + "_" + num;
- num++;
- }
-
- return id;
- }
-
- private boolean isDeviceWithIdInList(String id, List<GpodnetDevice> gpodnetDevices) {
- if (gpodnetDevices == null) {
- return false;
- }
- for (GpodnetDevice device : gpodnetDevices) {
- if (device.getId().equals(id)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean checkDeviceIDText(EditText deviceID, EditText caption, TextView txtvError, List<GpodnetDevice> devices) {
- String text = deviceID.getText().toString();
- if (text.length() == 0) {
- txtvError.setText(R.string.gpodnetauth_device_errorEmpty);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- } else if (caption.length() == 0) {
- txtvError.setText(R.string.gpodnetauth_device_caption_errorEmpty);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- } else {
- if (devices != null) {
- if (isDeviceWithIdInList(text, devices)) {
- txtvError.setText(R.string.gpodnetauth_device_errorAlreadyUsed);
- txtvError.setVisibility(View.VISIBLE);
- return false;
- }
- txtvError.setVisibility(View.GONE);
- return true;
- }
- return true;
- }
-
- }
-
- private void setupFinishView(View view) {
- final Button sync = view.findViewById(R.id.butSyncNow);
- final Button back = view.findViewById(R.id.butGoMainscreen);
-
- sync.setOnClickListener(v -> {
- finish();
- SyncService.sync(getApplicationContext());
- });
- back.setOnClickListener(v -> {
- Intent intent = new Intent(GpodnetAuthenticationActivity.this, MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- });
- }
-
- private void writeLoginCredentials() {
- if (BuildConfig.DEBUG) Log.d(TAG, "Writing login credentials");
- GpodnetPreferences.setUsername(username);
- GpodnetPreferences.setPassword(password);
- GpodnetPreferences.setDeviceID(selectedDevice.getId());
- }
-
- private void advance() {
- if (currentStep < STEP_FINISH) {
-
- View view = views[currentStep + 1];
- if (currentStep == STEP_DEFAULT) {
- setupLoginView(view);
- } else if (currentStep == STEP_LOGIN) {
- if (username == null || password == null) {
- throw new IllegalStateException("Username and password must not be null here");
- } else {
- setupDeviceView(view);
- }
- } else if (currentStep == STEP_DEVICE) {
- if (selectedDevice == null) {
- throw new IllegalStateException("Device must not be null here");
- } else {
- writeLoginCredentials();
- setupFinishView(view);
- }
- }
- if (currentStep != STEP_DEFAULT) {
- viewFlipper.showNext();
- }
- currentStep++;
- } else {
- finish();
- }
- }
-
- private boolean usernameHasUnwantedChars(String username) {
- Pattern special = Pattern.compile("[!@#$%&*()+=|<>?{}\\[\\]~]");
- Matcher containsUnwantedChars = special.matcher(username);
- return containsUnwantedChars.find();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
index 002147071..4fa8acc43 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/ChaptersListAdapter.java
@@ -22,12 +22,14 @@ import de.danoeh.antennapod.core.util.EmbeddedChapterImage;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.playback.Playable;
+import de.danoeh.antennapod.view.CircularProgressBar;
public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapter.ChapterHolder> {
private Playable media;
private final Callback callback;
private final Context context;
private int currentChapterIndex = -1;
+ private long currentChapterPosition = -1;
private boolean hasImages = false;
public ChaptersListAdapter(Context context, Callback callback) {
@@ -48,7 +50,6 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
notifyDataSetChanged();
}
-
@Override
public void onBindViewHolder(@NonNull ChapterHolder holder, int position) {
Chapter sc = getItem(position);
@@ -65,7 +66,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
holder.duration.setText(context.getString(R.string.chapter_duration,
Converter.getDurationStringLocalized(context, (int) duration)));
- if (sc.getLink() == null) {
+ if (TextUtils.isEmpty(sc.getLink())) {
holder.link.setVisibility(View.GONE);
} else {
holder.link.setVisibility(View.VISIBLE);
@@ -73,6 +74,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
holder.link.setOnClickListener(v -> IntentUtils.openInBrowser(context, sc.getLink()));
}
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_play));
+ holder.secondaryActionButton.setContentDescription(context.getString(R.string.play_chapter));
holder.secondaryActionButton.setOnClickListener(v -> {
if (callback != null) {
callback.onPlayChapterButtonClicked(position);
@@ -82,8 +84,14 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
if (position == currentChapterIndex) {
int playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
holder.itemView.setBackgroundColor(playingBackGroundColor);
+ float progress = ((float) (currentChapterPosition - sc.getStart())) / duration;
+ progress = Math.max(progress, CircularProgressBar.MINIMUM_PERCENTAGE);
+ progress = Math.min(progress, CircularProgressBar.MAXIMUM_PERCENTAGE);
+ holder.progressBar.setPercentage(progress, position);
+ holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.av_replay));
} else {
holder.itemView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));
+ holder.progressBar.setPercentage(0, null);
}
if (hasImages) {
@@ -135,6 +143,7 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
final ImageView image;
final View secondaryActionButton;
final ImageView secondaryActionIcon;
+ final CircularProgressBar progressBar;
public ChapterHolder(@NonNull View itemView) {
super(itemView);
@@ -145,14 +154,23 @@ public class ChaptersListAdapter extends RecyclerView.Adapter<ChaptersListAdapte
duration = itemView.findViewById(R.id.txtvDuration);
secondaryActionButton = itemView.findViewById(R.id.secondaryActionButton);
secondaryActionIcon = itemView.findViewById(R.id.secondaryActionIcon);
+ progressBar = itemView.findViewById(R.id.secondaryActionProgress);
}
}
public void notifyChapterChanged(int newChapterIndex) {
currentChapterIndex = newChapterIndex;
+ currentChapterPosition = getItem(newChapterIndex).getStart();
notifyDataSetChanged();
}
+ public void notifyTimeChanged(long timeMs) {
+ currentChapterPosition = timeMs;
+ // Passing an argument prevents flickering.
+ // See EpisodeItemListAdapter.notifyItemChangedCompat.
+ notifyItemChanged(currentChapterIndex, "foo");
+ }
+
private boolean ignoreChapter(Chapter c) {
return media.getDuration() > 0 && media.getDuration() < c.getStart();
}
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 7d195a9ad..0c4aaf6ed 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -1,23 +1,15 @@
package de.danoeh.antennapod.adapter;
import android.app.Activity;
-import android.content.Context;
-import android.os.Build;
-import android.text.Layout;
import android.text.format.DateUtils;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
-import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
-import com.joanzapata.iconify.widget.IconButton;
-import com.joanzapata.iconify.widget.IconTextView;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
index 540cd054c..268a21409 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadlistAdapter.java
@@ -65,6 +65,7 @@ public class DownloadlistAdapter extends BaseAdapter {
holder.title.setText(request.getTitle());
holder.secondaryActionIcon.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.navigation_cancel));
+ holder.secondaryActionButton.setContentDescription(context.getString(R.string.cancel_download_label));
holder.secondaryActionButton.setTag(downloader);
holder.secondaryActionButton.setOnClickListener(butSecondaryListener);
holder.secondaryActionProgress.setPercentage(0, request);
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 6bfd34d5c..8cb0fd30a 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
@@ -13,8 +13,6 @@ import androidx.annotation.Nullable;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.MediaType;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
-import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.playback.RemoteMedia;
import de.danoeh.antennapod.core.feed.FeedItem;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 92ed7b052..f8507ba74 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -75,7 +75,7 @@ public class NavListAdapter extends BaseAdapter
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS)) {
+ if (UserPreferences.PREF_HIDDEN_DRAWER_ITEMS.equals(key)) {
loadItems();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
index 7ce086694..01712ea29 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java
@@ -6,7 +6,6 @@ import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
-import androidx.core.view.MotionEventCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
index 8c294a9c9..919a4e217 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
@@ -13,8 +13,6 @@ import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
-import com.bumptech.glide.Glide;
-
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.Locale;
@@ -23,7 +21,6 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
-import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import jp.shts.android.library.TriangleLabelView;
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 31dfe15da..78ea3b93f 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
@@ -7,11 +7,8 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
-import de.danoeh.antennapod.core.preferences.UsageStatistics;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
-import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter;
-import de.danoeh.antennapod.dialog.StreamingConfirmationDialog;
public class PlayLocalActionButton extends ItemActionButton {
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
index 7b8659968..e45280eed 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/VisitWebsiteActionButton.java
@@ -1,8 +1,6 @@
package de.danoeh.antennapod.adapter.actionbutton;
import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
import android.view.View;
import androidx.annotation.AttrRes;
import androidx.annotation.StringRes;
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 3ac05e842..906d50c61 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java
@@ -9,10 +9,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
import io.reactivex.Observable;
/**
@@ -44,7 +44,7 @@ public class DocumentFileExportWorker {
if (outputStream == null) {
throw new IOException();
}
- writer = new OutputStreamWriter(outputStream, LangUtils.UTF_8);
+ writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
subscriber.onNext(output);
} catch (IOException e) {
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
index f81a52402..0930b59eb 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java
@@ -8,11 +8,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
import de.danoeh.antennapod.core.export.ExportWriter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.util.LangUtils;
import io.reactivex.Observable;
/**
@@ -47,7 +47,7 @@ public class ExportWorker {
return Observable.create(subscriber -> {
OutputStreamWriter writer = null;
try {
- writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
+ writer = new OutputStreamWriter(new FileOutputStream(output), Charset.forName("UTF-8"));
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
subscriber.onNext(output);
} catch (IOException e) {
diff --git a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
index 6e584d34f..7a5cf431f 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/ClientConfigurator.java
@@ -2,6 +2,7 @@ package de.danoeh.antennapod.config;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.storage.APDownloadAlgorithm;
/**
* Configures the ClientConfig class of the core package.
@@ -15,7 +16,7 @@ class ClientConfigurator {
ClientConfig.applicationCallbacks = new ApplicationCallbacksImpl();
ClientConfig.downloadServiceCallbacks = new DownloadServiceCallbacksImpl();
ClientConfig.playbackServiceCallbacks = new PlaybackServiceCallbacksImpl();
- ClientConfig.dbTasksCallbacks = new DBTasksCallbacksImpl();
+ ClientConfig.automaticDownloadAlgorithm = new APDownloadAlgorithm();
ClientConfig.castCallbacks = new CastCallbackImpl();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java
deleted file mode 100644
index c3f7ae9c8..000000000
--- a/app/src/main/java/de/danoeh/antennapod/config/DBTasksCallbacksImpl.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.danoeh.antennapod.config;
-
-import de.danoeh.antennapod.core.DBTasksCallbacks;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.storage.APDownloadAlgorithm;
-import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
-import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
-
-public class DBTasksCallbacksImpl implements DBTasksCallbacks {
-
- @Override
- public AutomaticDownloadAlgorithm getAutomaticDownloadAlgorithm() {
- return new APDownloadAlgorithm();
- }
-
- @Override
- public EpisodeCleanupAlgorithm getEpisodeCacheCleanupAlgorithm() {
- return UserPreferences.getEpisodeCleanupAlgorithm();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
index 71442f50b..f509f6dd4 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java
@@ -31,7 +31,6 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
public PendingIntent getAuthentificationNotificationContentIntent(Context context, DownloadRequest request) {
final Intent activityIntent = new Intent(context.getApplicationContext(), DownloadAuthenticationActivity.class);
activityIntent.putExtra(DownloadAuthenticationActivity.ARG_DOWNLOAD_REQUEST, request);
- activityIntent.putExtra(DownloadAuthenticationActivity.ARG_SEND_TO_DOWNLOAD_REQUESTER_BOOL, true);
return PendingIntent.getActivity(context.getApplicationContext(),
R.id.pending_intent_download_service_auth, activityIntent, PendingIntent.FLAG_ONE_SHOT);
}
@@ -54,9 +53,4 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
return PendingIntent.getActivity(context, R.id.pending_intent_download_service_autodownload_report,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
-
- @Override
- public boolean shouldCreateReport() {
- return true;
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
index 44f18e9da..f70cb26ff 100644
--- a/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
+++ b/app/src/main/java/de/danoeh/antennapod/config/PlaybackServiceCallbacksImpl.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.config;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
-import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.VideoplayerActivity;
import de.danoeh.antennapod.core.PlaybackServiceCallbacks;
@@ -22,10 +21,4 @@ public class PlaybackServiceCallbacksImpl implements PlaybackServiceCallbacks {
return i;
}
}
-
- @Override
- public boolean useQueue() {
- return true;
- }
-
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 5aee3f2be..efaff1da3 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -436,13 +436,18 @@ public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnM
}
private void deleteChecked() {
+ int countHasMedia = 0;
+ int countNoMedia = 0;
for (long id : checkedIds.toArray()) {
FeedItem episode = idMap.get(id);
- if (episode.hasMedia()) {
+ if (episode.hasMedia() && episode.getMedia().isDownloaded()) {
+ countHasMedia++;
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
+ } else {
+ countNoMedia++;
}
}
- close(R.plurals.deleted_episode_batch_label, checkedIds.size());
+ closeMore(R.plurals.deleted_multi_episode_batch_label, countNoMedia, countHasMedia);
}
private void close(@PluralsRes int msgId, int numItems) {
@@ -451,4 +456,12 @@ public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnM
getActivity().getSupportFragmentManager().popBackStack();
}
+ private void closeMore(@PluralsRes int msgId, int countNoMedia, int countHasMedia) {
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(
+ getResources().getQuantityString(msgId,
+ (countHasMedia + countNoMedia),
+ (countHasMedia + countNoMedia), countHasMedia),
+ Snackbar.LENGTH_LONG);
+ getActivity().getSupportFragmentManager().popBackStack();
+ }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
index 82010637f..80df87891 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/FilterDialog.java
@@ -3,6 +3,7 @@ package de.danoeh.antennapod.dialog;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
+import android.view.View;
import android.widget.LinearLayout;
import android.widget.RadioButton;
@@ -34,18 +35,19 @@ public abstract class FilterDialog {
builder.setTitle(R.string.filter);
LayoutInflater inflater = LayoutInflater.from(this.context);
- LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.filter_dialog, null, false);
+ View layout = inflater.inflate(R.layout.filter_dialog, null, false);
+ LinearLayout rows = layout.findViewById(R.id.filter_rows);
builder.setView(layout);
for (FeedItemFilterGroup item : FeedItemFilterGroup.values()) {
- RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null);
+ RecursiveRadioGroup row = (RecursiveRadioGroup) inflater.inflate(R.layout.filter_dialog_row, null, false);
RadioButton filter1 = row.findViewById(R.id.filter_dialog_radioButton1);
RadioButton filter2 = row.findViewById(R.id.filter_dialog_radioButton2);
filter1.setText(item.values[0].displayName);
filter1.setTag(item.values[0].filterId);
filter2.setText(item.values[1].displayName);
filter2.setTag(item.values[1].filterId);
- layout.addView(row);
+ rows.addView(row);
}
for (String filterId : filterValues) {
@@ -56,11 +58,11 @@ public abstract class FilterDialog {
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
filterValues.clear();
- for (int i = 0; i < layout.getChildCount(); i++) {
- if (!(layout.getChildAt(i) instanceof RecursiveRadioGroup)) {
+ for (int i = 0; i < rows.getChildCount(); i++) {
+ if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
continue;
}
- RecursiveRadioGroup group = (RecursiveRadioGroup) layout.getChildAt(i);
+ RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i);
if (group.getCheckedButton() != null) {
String tag = (String) group.getCheckedButton().getTag();
if (tag != null) { // Clear buttons use no tag
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java
deleted file mode 100644
index 8119dffcb..000000000
--- a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.danoeh.antennapod.dialog;
-
-import android.content.Context;
-import androidx.appcompat.app.AlertDialog;
-import android.text.Editable;
-import android.text.InputType;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-
-/**
- * Creates a dialog that lets the user change the hostname for the gpodder.net service.
- */
-public class GpodnetSetHostnameDialog {
-
- private GpodnetSetHostnameDialog(){}
-
- private static final String TAG = "GpodnetSetHostnameDialog";
-
- public static AlertDialog createDialog(final Context context) {
- AlertDialog.Builder dialog = new AlertDialog.Builder(context);
- final EditText et = new EditText(context);
- et.setText(GpodnetPreferences.getHostname());
- et.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
- dialog.setTitle(R.string.pref_gpodnet_sethostname_title)
- .setView(setupContentView(context, et))
- .setPositiveButton(R.string.confirm_label, (dialog1, which) -> {
- final Editable e = et.getText();
- if (e != null) {
- GpodnetPreferences.setHostname(e.toString());
- }
- dialog1.dismiss();
- })
- .setNegativeButton(R.string.cancel_label, (dialog1, which) -> dialog1.cancel())
- .setNeutralButton(R.string.pref_gpodnet_sethostname_use_default_host, (dialog1, which) -> {
- GpodnetPreferences.setHostname(GpodnetService.DEFAULT_BASE_HOST);
- dialog1.dismiss();
- })
- .setCancelable(true);
- return dialog.show();
- }
-
- private static View setupContentView(Context context, EditText et) {
- LinearLayout ll = new LinearLayout(context);
- ll.addView(et);
- LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) et.getLayoutParams();
- if (params != null) {
- params.setMargins(8, 8, 8, 8);
- params.width = ViewGroup.LayoutParams.MATCH_PARENT;
- params.height = ViewGroup.LayoutParams.MATCH_PARENT;
- }
- return ll;
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java
new file mode 100644
index 000000000..156c1dba8
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RemoveFeedDialog.java
@@ -0,0 +1,52 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.util.Log;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import io.reactivex.Completable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+public class RemoveFeedDialog {
+ private static final String TAG = "RemoveFeedDialog";
+
+ public static void show(Context context, Feed feed, Runnable onSuccess) {
+ int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
+ : R.string.feed_delete_confirmation_msg;
+ String message = context.getString(messageId, feed.getTitle());
+
+ ConfirmationDialog dialog = new ConfirmationDialog(context, R.string.remove_feed_label, message) {
+ @Override
+ public void onConfirmButtonPressed(DialogInterface clickedDialog) {
+ clickedDialog.dismiss();
+
+ ProgressDialog progressDialog = new ProgressDialog(context);
+ progressDialog.setMessage(context.getString(R.string.feed_remover_msg));
+ progressDialog.setIndeterminate(true);
+ progressDialog.setCancelable(false);
+ progressDialog.show();
+
+ Completable.fromCallable(() -> DBWriter.deleteFeed(context, feed.getId()).get())
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ Log.d(TAG, "Feed was deleted");
+ if (onSuccess != null) {
+ onSuccess.run();
+ }
+ progressDialog.dismiss();
+ }, error -> {
+ Log.e(TAG, Log.getStackTraceString(error));
+ progressDialog.dismiss();
+ });
+ }
+ };
+ dialog.createNewDialog().show();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
index 699c6f492..a4e49ff96 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/RenameFeedDialog.java
@@ -1,16 +1,15 @@
package de.danoeh.antennapod.dialog;
import android.app.Activity;
-import android.text.InputType;
import java.lang.ref.WeakReference;
import android.view.View;
-import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.databinding.EditTextDialogBinding;
public class RenameFeedDialog {
@@ -29,13 +28,14 @@ public class RenameFeedDialog {
}
View content = View.inflate(activity, R.layout.edit_text_dialog, null);
- EditText editText = content.findViewById(R.id.text);
- editText.setText(feed.getTitle());
+ EditTextDialogBinding alertViewBinding = EditTextDialogBinding.bind(content);
+
+ alertViewBinding.urlEditText.setText(feed.getTitle());
AlertDialog dialog = new AlertDialog.Builder(activity)
.setView(content)
.setTitle(de.danoeh.antennapod.core.R.string.rename_feed_label)
.setPositiveButton(android.R.string.ok, (d, input) -> {
- feed.setCustomTitle(editText.getText().toString());
+ feed.setCustomTitle(alertViewBinding.urlEditText.getText().toString());
DBWriter.setFeedCustomTitle(feed);
})
.setNeutralButton(de.danoeh.antennapod.core.R.string.reset, null)
@@ -44,7 +44,7 @@ public class RenameFeedDialog {
// To prevent cancelling the dialog on button click
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(
- (view) -> editText.setText(feed.getFeedTitle()));
+ (view) -> alertViewBinding.urlEditText.setText(feed.getFeedTitle()));
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
index 274c3b7bd..f1a41d753 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java
@@ -3,7 +3,6 @@ package de.danoeh.antennapod.dialog;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
@@ -88,6 +87,27 @@ public class SleepTimerDialog extends DialogFragment {
timeSetup = content.findViewById(R.id.timeSetup);
timeDisplay = content.findViewById(R.id.timeDisplay);
time = content.findViewById(R.id.time);
+ Button extendSleepFiveMinutesButton = content.findViewById(R.id.extendSleepFiveMinutesButton);
+ extendSleepFiveMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 5));
+ Button extendSleepTenMinutesButton = content.findViewById(R.id.extendSleepTenMinutesButton);
+ extendSleepTenMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 10));
+ Button extendSleepTwentyMinutesButton = content.findViewById(R.id.extendSleepTwentyMinutesButton);
+ extendSleepTwentyMinutesButton.setText(getString(R.string.extend_sleep_timer_label, 20));
+ extendSleepFiveMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(5 * 1000 * 60);
+ }
+ });
+ extendSleepTenMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(10 * 1000 * 60);
+ }
+ });
+ extendSleepTwentyMinutesButton.setOnClickListener(v -> {
+ if (controller != null) {
+ controller.extendSleepTimer(20 * 1000 * 60);
+ }
+ });
etxtTime.setText(SleepTimerPreferences.lastTimerValue());
etxtTime.postDelayed(() -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
index a8915480c..8a87fef25 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SubscriptionsFilterDialog.java
@@ -30,7 +30,8 @@ public class SubscriptionsFilterDialog {
builder.setTitle(context.getString(R.string.pref_filter_feed_title));
LayoutInflater inflater = LayoutInflater.from(context);
- LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.filter_dialog, null, false);
+ View layout = inflater.inflate(R.layout.filter_dialog, null, false);
+ LinearLayout rows = layout.findViewById(R.id.filter_rows);
builder.setView(layout);
for (SubscriptionsFilterGroup item : SubscriptionsFilterGroup.values()) {
@@ -45,7 +46,7 @@ public class SubscriptionsFilterDialog {
} else {
filter2.setVisibility(View.GONE);
}
- layout.addView(row);
+ rows.addView(row);
}
for (String filterId : filterValues) {
@@ -56,11 +57,11 @@ public class SubscriptionsFilterDialog {
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
filterValues.clear();
- for (int i = 0; i < layout.getChildCount(); i++) {
- if (!(layout.getChildAt(i) instanceof RecursiveRadioGroup)) {
+ for (int i = 0; i < rows.getChildCount(); i++) {
+ if (!(rows.getChildAt(i) instanceof RecursiveRadioGroup)) {
continue;
}
- RecursiveRadioGroup group = (RecursiveRadioGroup) layout.getChildAt(i);
+ RecursiveRadioGroup group = (RecursiveRadioGroup) rows.getChildAt(i);
if (group.getCheckedButton() != null) {
String tag = (String) group.getCheckedButton().getTag();
if (tag != null) { // Clear buttons use no tag
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
index 796ec556f..6e894176f 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.discovery;
-import android.content.Context;
-import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
index eeebd2ebf..8fbc8c76b 100644
--- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
+++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java
@@ -1,8 +1,6 @@
package de.danoeh.antennapod.discovery;
import io.reactivex.Single;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.functions.Consumer;
import java.util.List;
public interface PodcastSearcher {
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 caf489569..06a974dfd 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java
@@ -12,7 +12,6 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -30,6 +29,8 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.util.SortOrder;
+import de.danoeh.antennapod.databinding.AddfeedBinding;
+import de.danoeh.antennapod.databinding.EditTextDialogBinding;
import de.danoeh.antennapod.discovery.CombinedSearcher;
import de.danoeh.antennapod.discovery.FyydPodcastSearcher;
import de.danoeh.antennapod.discovery.ItunesPodcastSearcher;
@@ -50,7 +51,7 @@ public class AddFeedFragment extends Fragment {
private static final int REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH = 1;
private static final int REQUEST_CODE_ADD_LOCAL_FOLDER = 2;
- private EditText combinedFeedSearchBox;
+ private AddfeedBinding viewBinding;
private MainActivity activity;
@Override
@@ -59,39 +60,43 @@ public class AddFeedFragment extends Fragment {
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- View root = inflater.inflate(R.layout.addfeed, container, false);
+ viewBinding = AddfeedBinding.inflate(getLayoutInflater());
activity = (MainActivity) getActivity();
- Toolbar toolbar = root.findViewById(R.id.toolbar);
+
+ Toolbar toolbar = viewBinding.toolbar;
((MainActivity) getActivity()).setupToolbarToggle(toolbar);
- root.findViewById(R.id.btn_search_itunes).setOnClickListener(v
+ viewBinding.searchItunesButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(ItunesPodcastSearcher.class)));
- root.findViewById(R.id.btn_search_fyyd).setOnClickListener(v
+ viewBinding.searchFyydButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(FyydPodcastSearcher.class)));
- root.findViewById(R.id.btn_search_gpodder).setOnClickListener(v
+ viewBinding.searchGPodderButton.setOnClickListener(v
-> activity.loadChildFragment(new GpodnetMainFragment()));
- root.findViewById(R.id.btn_search_podcastindex).setOnClickListener(v
+ viewBinding.searchPodcastIndexButton.setOnClickListener(v
-> activity.loadChildFragment(OnlineSearchFragment.newInstance(PodcastIndexPodcastSearcher.class)));
- combinedFeedSearchBox = root.findViewById(R.id.combinedFeedSearchBox);
- combinedFeedSearchBox.setOnEditorActionListener((v, actionId, event) -> {
+ viewBinding.combinedFeedSearchEditText.setOnEditorActionListener((v, actionId, event) -> {
performSearch();
return true;
});
- root.findViewById(R.id.btn_add_via_url).setOnClickListener(v
+
+ viewBinding.addViaUrlButton.setOnClickListener(v
-> showAddViaUrlDialog());
- root.findViewById(R.id.btn_opml_import).setOnClickListener(v -> {
+ viewBinding.opmlImportButton.setOnClickListener(v -> {
try {
Intent intentGetContentAction = new Intent(Intent.ACTION_GET_CONTENT);
intentGetContentAction.addCategory(Intent.CATEGORY_OPENABLE);
intentGetContentAction.setType("*/*");
startActivityForResult(intentGetContentAction, REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found. Should never happen...");
+ e.printStackTrace();
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.unable_to_start_system_file_manager, Snackbar.LENGTH_LONG);
}
});
- root.findViewById(R.id.btn_add_local_folder).setOnClickListener(v -> {
+
+ viewBinding.addLocalFolderButton.setOnClickListener(v -> {
if (Build.VERSION.SDK_INT < 21) {
return;
}
@@ -100,29 +105,35 @@ public class AddFeedFragment extends Fragment {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CODE_ADD_LOCAL_FOLDER);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "No activity found. Should never happen...");
+ e.printStackTrace();
+ ((MainActivity) getActivity())
+ .showSnackbarAbovePlayer(R.string.unable_to_start_system_file_manager, Snackbar.LENGTH_LONG);
}
});
if (Build.VERSION.SDK_INT < 21) {
- root.findViewById(R.id.btn_add_local_folder).setVisibility(View.GONE);
+ viewBinding.addLocalFolderButton.setVisibility(View.GONE);
}
- root.findViewById(R.id.search_icon).setOnClickListener(view -> performSearch());
- return root;
+
+ viewBinding.searchButton.setOnClickListener(view -> performSearch());
+
+ return viewBinding.getRoot();
}
private void showAddViaUrlDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.add_podcast_by_url);
View content = View.inflate(getContext(), R.layout.edit_text_dialog, null);
- EditText editText = content.findViewById(R.id.text);
- editText.setHint(R.string.add_podcast_by_url_hint);
+ EditTextDialogBinding alertViewBinding = EditTextDialogBinding.bind(content);
+ 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")) {
- editText.setText(clipboardContent.trim());
+ alertViewBinding.urlEditText.setText(clipboardContent.trim());
}
- builder.setView(content);
- builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> addUrl(editText.getText().toString()));
+ builder.setView(alertViewBinding.getRoot());
+ builder.setPositiveButton(R.string.confirm_label,
+ (dialog, which) -> addUrl(alertViewBinding.urlEditText.getText().toString()));
builder.setNegativeButton(R.string.cancel_label, null);
builder.show();
}
@@ -134,8 +145,7 @@ public class AddFeedFragment extends Fragment {
}
private void performSearch() {
- String query = combinedFeedSearchBox.getText().toString();
-
+ String query = viewBinding.combinedFeedSearchEditText.getText().toString();
if (query.matches("http[s]?://.*")) {
addUrl(query);
return;
@@ -187,7 +197,6 @@ public class AddFeedFragment extends Fragment {
throw new IllegalArgumentException("Unable to retrieve document tree");
}
Feed dirFeed = new Feed(Feed.PREFIX_LOCAL_FOLDER + uri.toString(), null, documentFile.getName());
- dirFeed.setDescription(getString(R.string.local_feed_description));
dirFeed.setItems(Collections.emptyList());
dirFeed.setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
Feed fromDatabase = DBTasks.updateFeed(getContext(), dirFeed, false);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index 08da1f8d9..77b272da7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.NonNull;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
index 5a65f956c..82e2b3a6a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java
@@ -22,6 +22,8 @@ import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.CastEnabledActivity;
import de.danoeh.antennapod.activity.MainActivity;
@@ -43,7 +45,6 @@ import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
import de.danoeh.antennapod.dialog.SleepTimerDialog;
import de.danoeh.antennapod.dialog.VariableSpeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
-import de.danoeh.antennapod.view.PagerIndicatorView;
import de.danoeh.antennapod.view.PlaybackSpeedIndicatorView;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -74,7 +75,6 @@ public class AudioPlayerFragment extends Fragment implements
PlaybackSpeedIndicatorView butPlaybackSpeed;
TextView txtvPlaybackSpeed;
private ViewPager2 pager;
- private PagerIndicatorView pageIndicator;
private TextView txtvPosition;
private TextView txtvLength;
private SeekBar sbPosition;
@@ -90,6 +90,8 @@ public class AudioPlayerFragment extends Fragment implements
private PlaybackController controller;
private Disposable disposable;
private boolean showTimeLeft;
+ private boolean hasChapters = false;
+ private TabLayoutMediator tabLayoutMediator;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@@ -141,13 +143,37 @@ public class AudioPlayerFragment extends Fragment implements
});
}
});
- pageIndicator = root.findViewById(R.id.page_indicator);
- pageIndicator.setViewPager(pager);
- pageIndicator.setOnClickListener(v ->
- pager.setCurrentItem((pager.getCurrentItem() + 1) % NUM_CONTENT_FRAGMENTS));
+
+ TabLayout tabLayout = root.findViewById(R.id.sliding_tabs);
+ tabLayoutMediator = new TabLayoutMediator(tabLayout, pager, (tab, position) -> {
+ tab.view.setAlpha(1.0f);
+ switch (position) {
+ case POS_COVER:
+ tab.setText(R.string.cover_label);
+ break;
+ case POS_DESCR:
+ tab.setText(R.string.description_label);
+ break;
+ case POS_CHAPTERS:
+ tab.setText(R.string.chapters_label);
+ if (!hasChapters) {
+ tab.view.setAlpha(0.5f);
+ }
+ break;
+ default:
+ break;
+ }
+ });
+ tabLayoutMediator.attach();
return root;
}
+ public void setHasChapters(boolean hasChapters) {
+ this.hasChapters = hasChapters;
+ tabLayoutMediator.detach();
+ tabLayoutMediator.attach();
+ }
+
public View getExternalPlayerHolder() {
return getView().findViewById(R.id.playerFragment);
}
@@ -362,10 +388,6 @@ public class AudioPlayerFragment extends Fragment implements
setupOptionsMenu(media);
}
- public void setHasChapters(boolean hasChapters) {
- pageIndicator.setDisabledPage(hasChapters ? -1 : 2);
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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 6f95d71da..d781d0774 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java
@@ -106,6 +106,7 @@ public class ChaptersFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(PlaybackPositionEvent event) {
updateChapterSelection(getCurrentChapter(media));
+ adapter.notifyTimeChanged(event.getPosition());
}
private int getCurrentChapter(Playable media) {
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 59b2cd234..3519a34b4 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -4,7 +4,6 @@ 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;
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 98d6a946b..2e11ea4ec 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/DownloadLogFragment.java
@@ -4,7 +4,6 @@ import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
-import android.content.res.TypedArray;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -13,7 +12,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.ListFragment;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
@@ -176,7 +174,7 @@ public class DownloadLogFragment extends ListFragment {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) {
- case R.id.clear_history_item:
+ case R.id.clear_logs_item:
DBWriter.clearDownloadLog();
return true;
case R.id.refresh_item:
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 4ca08cbdd..ddfcd06ad 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java
@@ -130,6 +130,8 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
protected void doTint(Context themedContext) {
toolbar.getMenu().findItem(R.id.visit_website_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.location_web_site));
+ toolbar.getMenu().findItem(R.id.share_parent)
+ .setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_share));
}
};
iconTintManager.updateTint();
@@ -284,8 +286,13 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
}
private void refreshToolbarState() {
+ boolean shareLinkVisible = feed != null && feed.getLink() != null;
+ boolean downloadUrlVisible = feed != null && !feed.isLocalFeed();
+
toolbar.getMenu().findItem(R.id.reconnect_local_folder).setVisible(feed != null && feed.isLocalFeed());
- toolbar.getMenu().findItem(R.id.share_link_item).setVisible(feed != null && feed.getLink() != null);
+ toolbar.getMenu().findItem(R.id.share_download_url_item).setVisible(downloadUrlVisible);
+ toolbar.getMenu().findItem(R.id.share_link_item).setVisible(shareLinkVisible);
+ toolbar.getMenu().findItem(R.id.share_parent).setVisible(downloadUrlVisible || shareLinkVisible);
toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed != null && feed.getLink() != null
&& IntentUtils.isCallable(getContext(), new Intent(Intent.ACTION_VIEW, Uri.parse(feed.getLink()))));
}
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 681d3a88e..8e14214d2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.fragment;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.res.Configuration;
import android.content.Intent;
import android.graphics.LightingColorFilter;
@@ -36,8 +35,6 @@ import com.joanzapata.iconify.widget.IconTextView;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
-import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
@@ -65,6 +62,7 @@ import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.dialog.FilterDialog;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
@@ -298,28 +296,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- final FeedRemover remover = new FeedRemover(
- getActivity(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
- }
- };
- int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
- : R.string.feed_delete_confirmation_msg;
- ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
- R.string.remove_feed_label,
- getString(messageId, feed.getTitle())) {
-
- @Override
- public void onConfirmButtonPressed(
- DialogInterface dialog) {
- dialog.dismiss();
- remover.executeAsync();
- }
- };
- conDialog.createNewDialog().show();
+ RemoveFeedDialog.show(getContext(), feed, () ->
+ ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null));
return true;
default:
return false;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index fc3052e20..18a61f1e6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -8,10 +8,8 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.util.playback.Playable;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.core.util.playback.Timeline;
import de.danoeh.antennapod.view.ShownotesWebView;
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 669dbdac2..07f59bb42 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -17,7 +17,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
import androidx.core.text.TextUtilsCompat;
import androidx.core.util.ObjectsCompat;
import androidx.core.view.ViewCompat;
@@ -71,7 +70,6 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-import java.util.Date;
import java.util.List;
import java.util.Locale;
@@ -120,6 +118,7 @@ public class ItemFragment extends Fragment {
private View butAction2;
private ItemActionButton actionButton1;
private ItemActionButton actionButton2;
+ private View noMediaLabel;
private Disposable disposable;
private PlaybackController controller;
@@ -169,6 +168,7 @@ public class ItemFragment extends Fragment {
butAction2Icon = layout.findViewById(R.id.butAction2Icon);
butAction1Text = layout.findViewById(R.id.butAction1Text);
butAction2Text = layout.findViewById(R.id.butAction2Text);
+ noMediaLabel = layout.findViewById(R.id.noMediaLabel);
butAction1.setOnClickListener(v -> {
if (actionButton1 instanceof StreamActionButton && !UserPreferences.isStreamOverDownload()
@@ -319,7 +319,9 @@ public class ItemFragment extends Fragment {
if (media == null) {
actionButton1 = new MarkAsPlayedActionButton(item);
actionButton2 = new VisitWebsiteActionButton(item);
+ noMediaLabel.setVisibility(View.VISIBLE);
} else {
+ noMediaLabel.setVisibility(View.GONE);
if (media.getDuration() > 0) {
txtvDuration.setText(Converter.getDurationStringLong(media.getDuration()));
txtvDuration.setContentDescription(
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
index 4f99e8130..c69d46265 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -26,19 +26,15 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.NavListAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
-import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
import io.reactivex.Observable;
@@ -192,41 +188,15 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- final FeedRemover remover = new FeedRemover(getContext(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- if (selectedNavListIndex == position) {
- if (getActivity() instanceof MainActivity) {
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
- } else {
- showMainActivity(EpisodesFragment.TAG);
- }
- }
- }
- };
- int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
- : R.string.feed_delete_confirmation_msg;
- ConfirmationDialog conDialog = new ConfirmationDialog(getContext(),
- R.string.remove_feed_label,
- getString(messageId, feed.getTitle())) {
- @Override
- public void onConfirmButtonPressed(DialogInterface dialog) {
- dialog.dismiss();
- long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
- if (mediaId > 0 && FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
- Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
- remover.skipOnCompletion = true;
- int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
- if (playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
- IntentUtils.sendLocalBroadcast(getContext(),
- PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
- }
+ RemoveFeedDialog.show(getContext(), feed, () -> {
+ if (selectedNavListIndex == position) {
+ if (getActivity() instanceof MainActivity) {
+ ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
+ } else {
+ showMainActivity(EpisodesFragment.TAG);
}
- remover.executeAsync();
}
- };
- conDialog.createNewDialog().show();
+ });
return true;
default:
return super.onContextItemSelected(item);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
index d748d14c9..1aa66dcbb 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NewEpisodesFragment.java
@@ -1,7 +1,6 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
-import android.view.MenuInflater;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
index ba817650b..992b6930c 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java
@@ -90,7 +90,6 @@ public class OnlineSearchFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
- setupToolbar(root.findViewById(R.id.toolbar));
root.findViewById(R.id.spinner_country).setVisibility(INVISIBLE);
gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
@@ -110,6 +109,7 @@ public class OnlineSearchFragment extends Fragment {
txtvEmpty = root.findViewById(android.R.id.empty);
TextView txtvPoweredBy = root.findViewById(R.id.search_powered_by);
txtvPoweredBy.setText(getString(R.string.search_powered_by, searchProvider.getName()));
+ setupToolbar(root.findViewById(R.id.toolbar));
return root;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index 4549e2a09..973fcb978 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -20,6 +20,7 @@ import de.danoeh.antennapod.core.event.FeedItemEvent;
import de.danoeh.antennapod.core.event.PlaybackHistoryEvent;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
+import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
@@ -180,6 +181,12 @@ public class PlaybackHistoryFragment extends Fragment implements Toolbar.OnMenuI
refreshToolbarState();
}
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
+ loadItems();
+ refreshToolbarState();
+ }
+
private void onFragmentLoaded() {
adapter.notifyDataSetChanged();
refreshToolbarState();
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 c994b4d8b..14f355b52 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java
@@ -46,6 +46,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
private FeedDiscoverAdapter adapter;
private GridView discoverGridLayout;
private TextView errorTextView;
+ private TextView poweredByTextView;
private LinearLayout errorView;
private Button errorRetry;
@@ -63,6 +64,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
errorTextView = root.findViewById(R.id.discover_error_txtV);
errorRetry = root.findViewById(R.id.discover_error_retry_btn);
errorRetry.setOnClickListener((listener) -> loadToplist());
+ poweredByTextView = root.findViewById(R.id.discover_powered_by_itunes);
adapter = new FeedDiscoverAdapter((MainActivity) getActivity());
discoverGridLayout.setAdapter(adapter);
@@ -110,6 +112,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
discoverGridLayout.setVisibility(View.INVISIBLE);
errorView.setVisibility(View.GONE);
errorRetry.setVisibility(View.INVISIBLE);
+ poweredByTextView.setVisibility(View.VISIBLE);
ItunesTopListLoader loader = new ItunesTopListLoader(getContext());
SharedPreferences prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE);
@@ -122,6 +125,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView.
progressBar.setVisibility(View.GONE);
discoverGridLayout.setVisibility(View.INVISIBLE);
errorRetry.setVisibility(View.INVISIBLE);
+ poweredByTextView.setVisibility(View.INVISIBLE);
return;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
index 087abc327..fc500a223 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/RunningDownloadsFragment.java
@@ -6,7 +6,6 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.ListFragment;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
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 3b4246e3a..4735cab42 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -33,22 +33,18 @@ import java.util.concurrent.Callable;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.SubscriptionsAdapter;
-import de.danoeh.antennapod.core.asynctask.FeedRemover;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadService;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
-import de.danoeh.antennapod.core.util.FeedItemUtil;
-import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
import de.danoeh.antennapod.dialog.FeedSortDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
@@ -299,45 +295,13 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
new RenameFeedDialog(getActivity(), feed).show();
return true;
case R.id.remove_item:
- displayRemoveFeedDialog(feed);
+ RemoveFeedDialog.show(getContext(), feed, null);
return true;
default:
return super.onContextItemSelected(item);
}
}
- private void displayRemoveFeedDialog(Feed feed) {
- final FeedRemover remover = new FeedRemover(getContext(), feed) {
- @Override
- protected void onPostExecute(Void result) {
- super.onPostExecute(result);
- loadSubscriptions();
- }
- };
-
- int messageId = feed.isLocalFeed() ? R.string.feed_delete_confirmation_local_msg
- : R.string.feed_delete_confirmation_msg;
- String message = getString(messageId, feed.getTitle());
- ConfirmationDialog dialog = new ConfirmationDialog(getContext(), R.string.remove_feed_label, message) {
- @Override
- public void onConfirmButtonPressed(DialogInterface clickedDialog) {
- clickedDialog.dismiss();
- long mediaId = PlaybackPreferences.getCurrentlyPlayingFeedMediaId();
- if (mediaId > 0 && FeedItemUtil.indexOfItemWithMediaId(feed.getItems(), mediaId) >= 0) {
- Log.d(TAG, "Currently playing episode is about to be deleted, skipping");
- remover.skipOnCompletion = true;
- int playerStatus = PlaybackPreferences.getCurrentPlayerStatus();
- if(playerStatus == PlaybackPreferences.PLAYER_STATUS_PLAYING) {
- IntentUtils.sendLocalBroadcast(getContext(), PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
-
- }
- }
- remover.executeAsync();
- }
- };
- dialog.createNewDialog().show();
- }
-
private <T> void displayConfirmationDialog(@StringRes int title, @StringRes int message, Callable<? extends T> task) {
ConfirmationDialog dialog = new ConfirmationDialog(getActivity(), title, message) {
@Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
index 641e82b5a..ad815c3c9 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/GpodnetMainFragment.java
@@ -1,11 +1,14 @@
package de.danoeh.antennapod.fragment.gpodnet;
+import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
+import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
@@ -15,6 +18,9 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.discovery.GpodnetPodcastSearcher;
+import de.danoeh.antennapod.fragment.OnlineSearchFragment;
/**
* Main navigation hub for gpodder.net podcast directory
@@ -30,9 +36,7 @@ public class GpodnetMainFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.pager_fragment, container, false);
- Toolbar toolbar = root.findViewById(R.id.toolbar);
- toolbar.setTitle(R.string.gpodnet_main_label);
- toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
+ setupToolbar(root.findViewById(R.id.toolbar));
ViewPager2 viewPager = root.findViewById(R.id.viewpager);
GpodnetPagerAdapter pagerAdapter = new GpodnetPagerAdapter(this);
@@ -59,6 +63,33 @@ public class GpodnetMainFragment extends Fragment {
return root;
}
+ private void setupToolbar(Toolbar toolbar) {
+ toolbar.setTitle(R.string.gpodnet_main_label);
+ toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
+
+ toolbar.inflateMenu(R.menu.search);
+ MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
+ final SearchView sv = (SearchView) searchItem.getActionView();
+ sv.setQueryHint(getString(R.string.gpodnet_search_hint));
+ sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ Activity activity = getActivity();
+ if (activity != null) {
+ searchItem.collapseActionView();
+ ((MainActivity) activity).loadChildFragment(
+ OnlineSearchFragment.newInstance(GpodnetPodcastSearcher.class, query));
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ return false;
+ }
+ });
+ }
+
public static class GpodnetPagerAdapter extends FragmentStateAdapter {
GpodnetPagerAdapter(@NonNull Fragment fragment) {
@@ -68,20 +99,14 @@ public class GpodnetMainFragment extends Fragment {
@NonNull
@Override
public Fragment createFragment(int position) {
- Bundle arguments = new Bundle();
- arguments.putBoolean(PodcastListFragment.ARGUMENT_HIDE_TOOLBAR, true);
switch (position) {
case POS_TAGS:
return new TagListFragment();
case POS_TOPLIST:
- PodcastListFragment topListFragment = new PodcastTopListFragment();
- topListFragment.setArguments(arguments);
- return topListFragment;
+ return new PodcastTopListFragment();
default:
case POS_SUGGESTIONS:
- PodcastListFragment suggestionsFragment = new SuggestionListFragment();
- suggestionsFragment.setArguments(arguments);
- return suggestionsFragment;
+ return new SuggestionListFragment();
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index b3f56941b..1f5434688 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -4,12 +4,9 @@ import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
-import androidx.appcompat.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@@ -33,7 +30,6 @@ import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetPodcast;
* Displays a list of GPodnetPodcast-Objects in a GridView
*/
public abstract class PodcastListFragment extends Fragment {
- public static final String ARGUMENT_HIDE_TOOLBAR = "hideToolbar";
private static final String TAG = "PodcastListFragment";
private GridView gridView;
@@ -44,8 +40,6 @@ public abstract class PodcastListFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.gpodnet_podcast_list, container, false);
- setupToolbar(root.findViewById(R.id.toolbar));
-
gridView = root.findViewById(R.id.gridView);
progressBar = root.findViewById(R.id.progressBar);
txtvError = root.findViewById(R.id.txtvError);
@@ -59,37 +53,6 @@ public abstract class PodcastListFragment extends Fragment {
return root;
}
- private void setupToolbar(Toolbar toolbar) {
- if (getArguments() != null && getArguments().getBoolean(ARGUMENT_HIDE_TOOLBAR, false)) {
- toolbar.setVisibility(View.GONE);
- return;
- }
-
- toolbar.setTitle(R.string.gpodnet_main_label);
- toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
- toolbar.inflateMenu(R.menu.gpodder_podcasts);
-
- MenuItem searchItem = toolbar.getMenu().findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- MainActivity activity = (MainActivity)getActivity();
- if (activity != null) {
- activity.loadChildFragment(SearchListFragment.newInstance(s));
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
private void onPodcastSelected(GpodnetPodcast selection) {
Log.d(TAG, "Selected podcast: " + selection.toString());
Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
deleted file mode 100644
index 72a752bf1..000000000
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package de.danoeh.antennapod.fragment.gpodnet;
-
-import android.os.Bundle;
-import androidx.core.view.MenuItemCompat;
-import androidx.appcompat.widget.SearchView;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
-import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetServiceException;
-import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetPodcast;
-import org.apache.commons.lang3.Validate;
-
-import de.danoeh.antennapod.R;
-
-import java.util.List;
-
-/**
- * Performs a search on the gpodder.net directory and displays the results.
- */
-public class SearchListFragment extends PodcastListFragment {
- private static final String ARG_QUERY = "query";
-
- private String query;
-
- public static SearchListFragment newInstance(String query) {
- SearchListFragment fragment = new SearchListFragment();
- Bundle args = new Bundle();
- args.putString(ARG_QUERY, query);
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
- this.query = getArguments().getString(ARG_QUERY);
- } else {
- this.query = "";
- }
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- // parent already inflated menu
- MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setQuery(query, false);
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- sv.clearFocus();
- changeQuery(s);
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
- @Override
- protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException {
- return service.searchPodcasts(query, 0);
- }
-
- private void changeQuery(String query) {
- Validate.notNull(query);
-
- this.query = query;
- loadData();
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
index 53a31b68d..2c41ee070 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -1,19 +1,11 @@
package de.danoeh.antennapod.fragment.gpodnet;
-import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
-import androidx.fragment.app.ListFragment;
-import androidx.core.view.MenuItemCompat;
-import androidx.appcompat.widget.SearchView;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
-
-import de.danoeh.antennapod.R;
+import androidx.fragment.app.ListFragment;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.gpodnet.TagListAdapter;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
@@ -28,37 +20,6 @@ public class TagListFragment extends ListFragment {
private static final int COUNT = 50;
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.gpodder_podcasts, menu);
- MenuItem searchItem = menu.findItem(R.id.action_search);
- final SearchView sv = (SearchView) searchItem.getActionView();
- sv.setQueryHint(getString(R.string.gpodnet_search_hint));
- sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String s) {
- Activity activity = getActivity();
- if (activity != null) {
- sv.clearFocus();
- ((MainActivity) activity).loadChildFragment(SearchListFragment.newInstance(s));
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String s) {
- return false;
- }
- });
- }
-
- @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java
new file mode 100644
index 000000000..187e8480b
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderAuthenticationFragment.java
@@ -0,0 +1,302 @@
+package de.danoeh.antennapod.fragment.preferences;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Paint;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.ViewFlipper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import com.google.android.material.button.MaterialButton;
+import com.google.android.material.textfield.TextInputLayout;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
+import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.core.sync.SyncService;
+import de.danoeh.antennapod.core.sync.gpoddernet.GpodnetService;
+import de.danoeh.antennapod.core.sync.gpoddernet.model.GpodnetDevice;
+import de.danoeh.antennapod.core.util.FileNameGenerator;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import io.reactivex.Completable;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.schedulers.Schedulers;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Guides the user through the authentication process.
+ */
+public class GpodderAuthenticationFragment extends DialogFragment {
+ public static final String TAG = "GpodnetAuthActivity";
+
+ private ViewFlipper viewFlipper;
+
+ private static final int STEP_DEFAULT = -1;
+ private static final int STEP_HOSTNAME = 0;
+ private static final int STEP_LOGIN = 1;
+ private static final int STEP_DEVICE = 2;
+ private static final int STEP_FINISH = 3;
+
+ private int currentStep = -1;
+
+ private GpodnetService service;
+ private volatile String username;
+ private volatile String password;
+ private volatile GpodnetDevice selectedDevice;
+ private List<GpodnetDevice> devices;
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
+ dialog.setTitle(GpodnetService.DEFAULT_BASE_HOST);
+ dialog.setNegativeButton(R.string.cancel_label, null);
+ dialog.setCancelable(false);
+ this.setCancelable(false);
+
+ View root = View.inflate(getContext(), R.layout.gpodnetauth_dialog, null);
+ viewFlipper = root.findViewById(R.id.viewflipper);
+ advance();
+ dialog.setView(root);
+
+ return dialog.create();
+ }
+
+ private void setupHostView(View view) {
+ final Button selectHost = view.findViewById(R.id.chooseHostButton);
+ final RadioGroup serverRadioGroup = view.findViewById(R.id.serverRadioGroup);
+ final EditText serverUrlText = view.findViewById(R.id.serverUrlText);
+ if (!GpodnetService.DEFAULT_BASE_HOST.equals(GpodnetPreferences.getHostname())) {
+ serverUrlText.setText(GpodnetPreferences.getHostname());
+ }
+ final TextInputLayout serverUrlTextInput = view.findViewById(R.id.serverUrlTextInput);
+ serverRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {
+ serverUrlTextInput.setVisibility(checkedId == R.id.customServerRadio ? View.VISIBLE : View.GONE);
+ });
+ selectHost.setOnClickListener(v -> {
+ if (serverRadioGroup.getCheckedRadioButtonId() == R.id.customServerRadio) {
+ GpodnetPreferences.setHostname(serverUrlText.getText().toString());
+ } else {
+ GpodnetPreferences.setHostname(GpodnetService.DEFAULT_BASE_HOST);
+ }
+ service = new GpodnetService(AntennapodHttpClient.getHttpClient(), GpodnetPreferences.getHostname());
+ getDialog().setTitle(GpodnetPreferences.getHostname());
+ advance();
+ });
+ }
+
+ private void setupLoginView(View view) {
+ final EditText username = view.findViewById(R.id.etxtUsername);
+ final EditText password = view.findViewById(R.id.etxtPassword);
+ final Button login = view.findViewById(R.id.butLogin);
+ final TextView txtvError = view.findViewById(R.id.credentialsError);
+ final ProgressBar progressBar = view.findViewById(R.id.progBarLogin);
+ final TextView createAccount = view.findViewById(R.id.createAccountButton);
+
+ createAccount.setPaintFlags(createAccount.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ createAccount.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), "https://gpodder.net/register/"));
+
+ password.setOnEditorActionListener((v, actionID, event) ->
+ actionID == EditorInfo.IME_ACTION_GO && login.performClick());
+
+ login.setOnClickListener(v -> {
+ final String usernameStr = username.getText().toString();
+ final String passwordStr = password.getText().toString();
+
+ if (usernameHasUnwantedChars(usernameStr)) {
+ txtvError.setText(R.string.gpodnetsync_username_characters_error);
+ txtvError.setVisibility(View.VISIBLE);
+ return;
+ }
+
+ login.setEnabled(false);
+ progressBar.setVisibility(View.VISIBLE);
+ txtvError.setVisibility(View.GONE);
+ InputMethodManager inputManager = (InputMethodManager) getContext()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputManager.hideSoftInputFromWindow(login.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+
+ Completable.fromAction(() -> {
+ service.authenticate(usernameStr, passwordStr);
+ devices = service.getDevices();
+ GpodderAuthenticationFragment.this.username = usernameStr;
+ GpodderAuthenticationFragment.this.password = passwordStr;
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(() -> {
+ login.setEnabled(true);
+ progressBar.setVisibility(View.GONE);
+ advance();
+ }, error -> {
+ login.setEnabled(true);
+ progressBar.setVisibility(View.GONE);
+ txtvError.setText(error.getCause().getMessage());
+ txtvError.setVisibility(View.VISIBLE);
+ });
+
+ });
+ }
+
+ private void setupDeviceView(View view) {
+ final EditText deviceName = view.findViewById(R.id.deviceName);
+ final LinearLayout devicesContainer = view.findViewById(R.id.devicesContainer);
+ deviceName.setText(generateDeviceName());
+
+ MaterialButton createDeviceButton = view.findViewById(R.id.createDeviceButton);
+ createDeviceButton.setOnClickListener(v -> createDevice(view));
+
+ for (GpodnetDevice device : devices) {
+ View row = View.inflate(getContext(), R.layout.gpodnetauth_device_row, null);
+ Button selectDeviceButton = row.findViewById(R.id.selectDeviceButton);
+ selectDeviceButton.setOnClickListener(v -> {
+ selectedDevice = device;
+ advance();
+ });
+ selectDeviceButton.setText(device.getCaption());
+ devicesContainer.addView(row);
+ }
+ }
+
+ private void createDevice(View view) {
+ final EditText deviceName = view.findViewById(R.id.deviceName);
+ final TextView txtvError = view.findViewById(R.id.deviceSelectError);
+ final ProgressBar progBarCreateDevice = view.findViewById(R.id.progbarCreateDevice);
+
+ String deviceNameStr = deviceName.getText().toString();
+ if (isDeviceInList(deviceNameStr)) {
+ return;
+ }
+ progBarCreateDevice.setVisibility(View.VISIBLE);
+ txtvError.setVisibility(View.GONE);
+ deviceName.setEnabled(false);
+
+ Observable.fromCallable(() -> {
+ String deviceId = generateDeviceId(deviceNameStr);
+ service.configureDevice(deviceId, deviceNameStr, GpodnetDevice.DeviceType.MOBILE);
+ return new GpodnetDevice(deviceId, deviceNameStr, GpodnetDevice.DeviceType.MOBILE.toString(), 0);
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(device -> {
+ progBarCreateDevice.setVisibility(View.GONE);
+ selectedDevice = device;
+ advance();
+ }, error -> {
+ deviceName.setEnabled(true);
+ progBarCreateDevice.setVisibility(View.GONE);
+ txtvError.setText(error.getMessage());
+ txtvError.setVisibility(View.VISIBLE);
+ });
+ }
+
+ private String generateDeviceName() {
+ String baseName = getString(R.string.gpodnetauth_device_name_default, Build.MODEL);
+ String name = baseName;
+ int num = 1;
+ while (isDeviceInList(name)) {
+ name = baseName + " (" + num + ")";
+ num++;
+ }
+ return name;
+ }
+
+ private String generateDeviceId(String name) {
+ // devices names must be of a certain form:
+ // https://gpoddernet.readthedocs.org/en/latest/api/reference/general.html#devices
+ return FileNameGenerator.generateFileName(name).replaceAll("\\W", "_").toLowerCase(Locale.US);
+ }
+
+ private boolean isDeviceInList(String name) {
+ if (devices == null) {
+ return false;
+ }
+ String id = generateDeviceId(name);
+ for (GpodnetDevice device : devices) {
+ if (device.getId().equals(id) || device.getCaption().equals(name)) {
+ return true;
+ }
+ }
+ 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);
+
+ sync.setOnClickListener(v -> {
+ dismiss();
+ SyncService.sync(getContext());
+ });
+ }
+
+ private void writeLoginCredentials() {
+ GpodnetPreferences.setUsername(username);
+ GpodnetPreferences.setPassword(password);
+ GpodnetPreferences.setDeviceID(selectedDevice.getId());
+ }
+
+ private void advance() {
+ if (currentStep < STEP_FINISH) {
+
+ View view = viewFlipper.getChildAt(currentStep + 1);
+ if (currentStep == STEP_DEFAULT) {
+ setupHostView(view);
+ } else if (currentStep == STEP_HOSTNAME) {
+ setupLoginView(view);
+ } else if (currentStep == STEP_LOGIN) {
+ if (username == null || password == null) {
+ throw new IllegalStateException("Username and password must not be null here");
+ } else {
+ setupDeviceView(view);
+ }
+ } else if (currentStep == STEP_DEVICE) {
+ if (selectedDevice == null) {
+ throw new IllegalStateException("Device must not be null here");
+ } else {
+ writeLoginCredentials();
+ setupFinishView(view);
+ }
+ }
+ if (currentStep != STEP_DEFAULT) {
+ viewFlipper.showNext();
+ }
+ currentStep++;
+ } else {
+ dismiss();
+ }
+ }
+
+ private boolean usernameHasUnwantedChars(String username) {
+ Pattern special = Pattern.compile("[!@#$%&*()+=|<>?{}\\[\\]~]");
+ Matcher containsUnwantedChars = special.matcher(username);
+ return containsUnwantedChars.find();
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
index bec73894c..4fb734e17 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/GpodderPreferencesFragment.java
@@ -1,15 +1,12 @@
package de.danoeh.antennapod.fragment.preferences;
import android.app.Activity;
-import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.core.text.HtmlCompat;
-import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import android.text.Spanned;
import android.text.format.DateUtils;
-import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.PreferenceActivity;
@@ -17,19 +14,16 @@ import de.danoeh.antennapod.core.event.SyncServiceEvent;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.sync.SyncService;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
-import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
-
public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate";
private static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information";
private static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync";
private static final String PREF_GPODNET_FORCE_FULL_SYNC = "pref_gpodnet_force_full_sync";
private static final String PREF_GPODNET_LOGOUT = "pref_gpodnet_logout";
- private static final String PREF_GPODNET_HOSTNAME = "pref_gpodnet_hostname";
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@@ -54,6 +48,7 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void syncStatusChanged(SyncServiceEvent event) {
+ updateGpodnetPreferenceScreen();
if (!GpodnetPreferences.loggedIn()) {
return;
}
@@ -69,6 +64,10 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
private void setupGpodderScreen() {
final Activity activity = getActivity();
+ findPreference(PREF_GPODNET_LOGIN).setOnPreferenceClickListener(preference -> {
+ new GpodderAuthenticationFragment().show(getChildFragmentManager(), GpodderAuthenticationFragment.TAG);
+ return true;
+ });
findPreference(PREF_GPODNET_SETLOGIN_INFORMATION)
.setOnPreferenceClickListener(preference -> {
AuthenticationDialog dialog = new AuthenticationDialog(activity,
@@ -97,11 +96,6 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
updateGpodnetPreferenceScreen();
return true;
});
- findPreference(PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(preference -> {
- GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(
- dialog -> updateGpodnetPreferenceScreen());
- return true;
- });
}
private void updateGpodnetPreferenceScreen() {
@@ -122,7 +116,6 @@ public class GpodderPreferencesFragment extends PreferenceFragmentCompat {
} else {
findPreference(PREF_GPODNET_LOGOUT).setSummary(null);
}
- findPreference(PREF_GPODNET_HOSTNAME).setSummary(GpodnetPreferences.getHostname());
}
private void updateLastGpodnetSyncReport(boolean successful, long lastTime) {
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 99fd12021..7bf602e35 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
@@ -1,8 +1,11 @@
package de.danoeh.antennapod.fragment.preferences;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
+import android.provider.Settings;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.bytehamster.lib.preferencesearch.SearchConfiguration;
import com.bytehamster.lib.preferencesearch.SearchPreference;
@@ -20,7 +23,7 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
private static final String PREF_SCREEN_NETWORK = "prefScreenNetwork";
private static final String PREF_SCREEN_GPODDER = "prefScreenGpodder";
private static final String PREF_SCREEN_STORAGE = "prefScreenStorage";
- private static final String PREF_FAQ = "prefFaq";
+ private static final String PREF_DOCUMENTATION = "prefDocumentation";
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";
@@ -35,10 +38,18 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
setupSearch();
// If you are writing a spin-off, please update the details on screens like "About" and "Report bug"
- // and afterwards remove the following lines.
+ // and afterwards remove the following lines. Please keep in mind that AntennaPod is licensed under the GPL.
+ // This means that your application needs to be open-source under the GPL, too.
+ // It must also include a prominent copyright notice.
String packageName = getContext().getPackageName();
if (!"de.danoeh.antennapod".equals(packageName) && !"de.danoeh.antennapod.debug".equals(packageName)) {
findPreference(PREF_CATEGORY_PROJECT).setVisible(false);
+ Preference copyrightNotice = new Preference(getContext());
+ copyrightNotice.setSummary("This application is based on AntennaPod."
+ + " The AntennaPod team does NOT provide support for this unofficial version."
+ + " If you can read this message, the developers of this modification"
+ + " violate the GNU General Public License (GPL).");
+ findPreference(PREF_CATEGORY_PROJECT).getParent().addPreference(copyrightNotice);
}
}
@@ -70,10 +81,16 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
return true;
});
findPreference(PREF_NOTIFICATION).setOnPreferenceClickListener(preference -> {
- ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_notifications);
+ if (Build.VERSION.SDK_INT >= 26) {
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, getActivity().getPackageName());
+ startActivity(intent);
+ } else {
+ ((PreferenceActivity) getActivity()).openScreen(R.xml.preferences_notifications);
+ }
return true;
});
-
findPreference(PREF_ABOUT).setOnPreferenceClickListener(
preference -> {
getParentFragmentManager().beginTransaction().replace(R.id.content, new AboutFragment())
@@ -88,8 +105,8 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat {
return true;
}
);
- findPreference(PREF_FAQ).setOnPreferenceClickListener(preference -> {
- IntentUtils.openInBrowser(getContext(), "https://antennapod.org/faq.html");
+ findPreference(PREF_DOCUMENTATION).setOnPreferenceClickListener(preference -> {
+ IntentUtils.openInBrowser(getContext(), "https://antennapod.org/documentation/");
return true;
});
findPreference(PREF_VIEW_FORUM).setOnPreferenceClickListener(preference -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
index fcc37f644..77f8063f2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/NetworkPreferencesFragment.java
@@ -15,7 +15,6 @@ import org.apache.commons.lang3.ArrayUtils;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
@@ -97,8 +96,7 @@ public class NetworkPreferencesFragment extends PreferenceFragmentCompat {
private void setParallelDownloadsText(int downloads) {
final Resources res = getActivity().getResources();
- String s = String.format(Locale.getDefault(), "%d%s",
- downloads, res.getString(R.string.parallel_downloads_suffix));
+ String s = res.getString(R.string.parallel_downloads, downloads);
findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS).setSummary(s);
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
index b440d053b..0a64bbe71 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/AboutFragment.java
@@ -33,7 +33,7 @@ public class AboutFragment extends PreferenceFragmentCompat {
return true;
});
findPreference("about_privacy_policy").setOnPreferenceClickListener((preference) -> {
- IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy.html");
+ IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy/");
return true;
});
findPreference("about_licenses").setOnPreferenceClickListener((preference) -> {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
index 60d9f95dd..b844234b7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/DevelopersFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
index 6db1389ea..d759a5ff2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/SpecialThanksFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
index e8d8e113b..b77c74de6 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/about/TranslatorsFragment.java
@@ -6,8 +6,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
index 3d8f3fe09..1eecccb4c 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -48,65 +48,43 @@ public class FeedItemMenuHandler {
if (menu == null || selectedItem == null) {
return false;
}
- boolean hasMedia = selectedItem.getMedia() != null;
- boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
-
- if (!isPlaying) {
- setItemVisibility(menu, R.id.skip_episode_item, false);
- }
- boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
- if (!isInQueue) {
- setItemVisibility(menu, R.id.remove_from_queue_item, false);
- }
- if (!(!isInQueue && selectedItem.getMedia() != null)) {
- setItemVisibility(menu, R.id.add_to_queue_item, false);
- }
- if (!ShareUtils.hasLinkToShare(selectedItem)) {
- setItemVisibility(menu, R.id.visit_website_item, false);
- }
-
- boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
+ final boolean hasMedia = selectedItem.getMedia() != null;
+ final boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
+ final boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
+ final boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
+ final boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
+ setItemVisibility(menu, R.id.skip_episode_item, isPlaying);
+ setItemVisibility(menu, R.id.remove_from_queue_item, isInQueue);
+ setItemVisibility(menu, R.id.add_to_queue_item, !isInQueue && selectedItem.getMedia() != null);
+ setItemVisibility(menu, R.id.visit_website_item, !selectedItem.getFeed().isLocalFeed()
+ && ShareUtils.hasLinkToShare(selectedItem));
+ setItemVisibility(menu, R.id.share_item, !selectedItem.getFeed().isLocalFeed());
setItemVisibility(menu, R.id.remove_new_flag_item, selectedItem.isNew());
- if (selectedItem.isPlayed()) {
- setItemVisibility(menu, R.id.mark_read_item, false);
- } else {
- setItemVisibility(menu, R.id.mark_unread_item, false);
- }
-
- if (selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) {
- setItemVisibility(menu, R.id.reset_position, false);
- }
+ setItemVisibility(menu, R.id.mark_read_item, !selectedItem.isPlayed());
+ setItemVisibility(menu, R.id.mark_unread_item, selectedItem.isPlayed());
+ setItemVisibility(menu, R.id.reset_position, hasMedia && selectedItem.getMedia().getPosition() != 0);
if (!UserPreferences.isEnableAutodownload() || fileDownloaded || selectedItem.getFeed().isLocalFeed()) {
setItemVisibility(menu, R.id.activate_auto_download, false);
setItemVisibility(menu, R.id.deactivate_auto_download, false);
- } else if (selectedItem.getAutoDownload()) {
- setItemVisibility(menu, R.id.activate_auto_download, false);
} else {
- setItemVisibility(menu, R.id.deactivate_auto_download, false);
+ setItemVisibility(menu, R.id.activate_auto_download, !selectedItem.getAutoDownload());
+ setItemVisibility(menu, R.id.deactivate_auto_download, selectedItem.getAutoDownload());
}
// Display proper strings when item has no media
- if (!hasMedia && !selectedItem.isPlayed()) {
+ if (hasMedia) {
+ setItemTitle(menu, R.id.mark_read_item, R.string.mark_read_label);
+ setItemTitle(menu, R.id.mark_unread_item, R.string.mark_unread_label);
+ } else {
setItemTitle(menu, R.id.mark_read_item, R.string.mark_read_no_media_label);
- }
-
- if (!hasMedia && selectedItem.isPlayed()) {
setItemTitle(menu, R.id.mark_unread_item, R.string.mark_unread_label_no_media);
}
- boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
setItemVisibility(menu, R.id.add_to_favorites_item, !isFavorite);
setItemVisibility(menu, R.id.remove_from_favorites_item, isFavorite);
-
setItemVisibility(menu, R.id.remove_item, fileDownloaded);
-
- if (selectedItem.getFeed().isLocalFeed()) {
- setItemVisibility(menu, R.id.visit_website_item, false);
- setItemVisibility(menu, R.id.share_item, false);
- }
-
return true;
}
@@ -134,7 +112,7 @@ public class FeedItemMenuHandler {
* @param id The id of the string that is going to be replaced.
* @param noMedia The id of the new String that is going to be used.
* */
- public static void setItemTitle(Menu menu, int id, int noMedia){
+ public static void setItemTitle(Menu menu, int id, int noMedia) {
MenuItem item = menu.findItem(id);
if (item != null) {
item.setTitle(noMedia);
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
index 9ceed9369..0086a75ab 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.annotation.NonNull;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
index f755a4c84..2fd570ece 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/CircularProgressBar.java
@@ -11,7 +11,8 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.util.ThemeUtils;
public class CircularProgressBar extends View {
- private static final float EPSILON = 0.005f;
+ public static final float MINIMUM_PERCENTAGE = 0.005f;
+ public static final float MAXIMUM_PERCENTAGE = 1 - MINIMUM_PERCENTAGE;
private final Paint paintBackground = new Paint();
private final Paint paintProgress = new Paint();
@@ -74,11 +75,11 @@ public class CircularProgressBar extends View {
bounds.set(padding, padding, getWidth() - padding, getHeight() - padding);
canvas.drawArc(bounds, 0, 360, false, paintBackground);
- if (percentage > EPSILON && 1 - percentage > EPSILON) {
+ if (MINIMUM_PERCENTAGE <= percentage && percentage <= MAXIMUM_PERCENTAGE) {
canvas.drawArc(bounds, -90, percentage * 360, false, paintProgress);
}
- if (Math.abs(percentage - targetPercentage) > EPSILON) {
+ if (Math.abs(percentage - targetPercentage) > MINIMUM_PERCENTAGE) {
float speed = 0.02f;
if (Math.abs(targetPercentage - percentage) < 0.1 && targetPercentage > percentage) {
speed = 0.006f;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java b/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java
deleted file mode 100644
index 10ed98769..000000000
--- a/app/src/main/java/de/danoeh/antennapod/view/PagerIndicatorView.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package de.danoeh.antennapod.view;
-
-import android.animation.ArgbEvaluator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-import androidx.core.text.TextUtilsCompat;
-import androidx.core.view.ViewCompat;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager2.widget.ViewPager2;
-
-import java.util.Locale;
-
-public class PagerIndicatorView extends View {
- private final Paint paint = new Paint();
- private float position = 0;
- private int numPages = 0;
- private int disabledPage = -1;
- private int circleColor = 0;
- private int circleColorHighlight = -1;
- private boolean isLocaleRtl = false;
-
- public PagerIndicatorView(Context context) {
- super(context);
- setup();
- }
-
- public PagerIndicatorView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- setup();
- }
-
- public PagerIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- setup();
- }
-
- private void setup() {
- isLocaleRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
- == ViewCompat.LAYOUT_DIRECTION_RTL;
-
- paint.setAntiAlias(true);
- paint.setStyle(Paint.Style.FILL);
-
- int[] colorAttrs = new int[]{android.R.attr.textColorSecondary};
- TypedArray a = getContext().obtainStyledAttributes(colorAttrs);
- circleColorHighlight = a.getColor(0, 0xffffffff);
- circleColor = (Integer) new ArgbEvaluator().evaluate(0.8f, 0x00ffffff, circleColorHighlight);
- a.recycle();
- }
-
- /**
- * Visual and logical position distinction only happens in RTL locales (e.g. Persian)
- * where pages positions are flipped thus it does nothing in LTR locales (e.g. English)
- */
- private float logicalPositionToVisual(float position) {
- return isLocaleRtl ? numPages - 1 - position : position;
- }
-
- public void setViewPager(ViewPager2 pager) {
- numPages = pager.getAdapter().getItemCount();
- pager.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- @Override
- public void onChanged() {
- numPages = pager.getAdapter().getItemCount();
- invalidate();
- }
- });
- pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- PagerIndicatorView.this.position = logicalPositionToVisual(
- position + positionOffset);
- invalidate();
- }
- });
- }
-
- public void setDisabledPage(int disabledPage) {
- this.disabledPage = (int) logicalPositionToVisual(disabledPage);
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- for (int i = 0; i < numPages; i++) {
- if ((int) Math.floor(position) == i) {
- // This is the current dot
- drawCircle(canvas, i, (float) (1 - (position - Math.floor(position))));
- } else if ((int) Math.ceil(position) == i) {
- // This is the next dot
- drawCircle(canvas, i, (float) (position - Math.floor(position)));
- } else {
- drawCircle(canvas, i, 0);
- }
- }
- }
-
- private void drawCircle(Canvas canvas, int position, float frac) {
- float availableHeight = canvas.getHeight() - getPaddingTop() - getPaddingBottom();
- float circleRadiusSmall = availableHeight * 0.26f;
- float circleRadiusBig = availableHeight * 0.35f;
- float circleRadiusDelta = (circleRadiusBig - circleRadiusSmall);
- float start = 0.5f * (canvas.getWidth() - numPages * 1.5f * availableHeight);
- paint.setStrokeWidth(availableHeight * 0.3f);
-
- if (position == disabledPage) {
- paint.setStyle(Paint.Style.STROKE);
- } else {
- paint.setStyle(Paint.Style.FILL_AND_STROKE);
- }
-
- paint.setColor((Integer) new ArgbEvaluator().evaluate(frac, circleColor, circleColorHighlight));
- canvas.drawCircle(start + (position * 1.5f + 0.75f) * availableHeight, 0.5f * availableHeight + getPaddingTop(),
- circleRadiusSmall + frac * circleRadiusDelta, paint);
- }
-} \ No newline at end of file