diff options
Diffstat (limited to 'app/src/main/java')
15 files changed, 146 insertions, 122 deletions
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 9e71ac1db..3b28a5e27 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java @@ -101,7 +101,6 @@ public class OnlineFeedViewActivity extends AppCompatActivity { private static final String PREF_LAST_AUTO_DOWNLOAD = "lastAutoDownload"; private volatile List<Feed> feeds; - private Feed feed; private String selectedDownloadUrl; private Downloader downloader; private String username = null; @@ -289,13 +288,11 @@ public class OnlineFeedViewActivity extends AppCompatActivity { private void startFeedDownload(String url) { Log.d(TAG, "Starting feed download"); - url = URLChecker.prepareURL(url); - feed = new Feed(url, null); - DownloadRequest request = DownloadRequestCreator.create(feed) + selectedDownloadUrl = URLChecker.prepareURL(url); + DownloadRequest request = DownloadRequestCreator.create(new Feed(selectedDownloadUrl, null)) .withAuthentication(username, password) .withInitiatedByUser(true) .build(); - feed.setFile_url(request.getDestination()); download = Observable.fromCallable(() -> { feeds = DBReader.getFeedList(); @@ -305,16 +302,16 @@ public class OnlineFeedViewActivity extends AppCompatActivity { }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(this::checkDownloadResult, + .subscribe(status -> checkDownloadResult(status, request.getDestination()), error -> Log.e(TAG, Log.getStackTraceString(error))); } - private void checkDownloadResult(@NonNull DownloadStatus status) { + private void checkDownloadResult(@NonNull DownloadStatus status, String destination) { if (status.isCancelled()) { return; } if (status.isSuccessful()) { - parseFeed(); + parseFeed(destination); } else if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) { if (!isFinishing() && !isPaused) { if (username != null && password != null) { @@ -338,7 +335,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity { .subscribe( feeds -> { OnlineFeedViewActivity.this.feeds = feeds; - handleUpdatedFeedStatus(feed); + handleUpdatedFeedStatus(); }, error -> Log.e(TAG, Log.getStackTraceString(error)) ); } @@ -346,16 +343,12 @@ public class OnlineFeedViewActivity extends AppCompatActivity { @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(DownloadEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); - handleUpdatedFeedStatus(feed); + handleUpdatedFeedStatus(); } - private void parseFeed() { - if (feed == null || (feed.getFile_url() == null && feed.isDownloaded())) { - throw new IllegalStateException("feed must be non-null and downloaded when parseFeed is called"); - } + private void parseFeed(String destination) { Log.d(TAG, "Parsing feed"); - - parser = Maybe.fromCallable(this::doParseFeed) + parser = Maybe.fromCallable(() -> doParseFeed(destination)) .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableMaybeObserver<FeedHandlerResult>() { @@ -384,14 +377,17 @@ public class OnlineFeedViewActivity extends AppCompatActivity { * @throws Exception If unsuccessful but we do not know a resolution. */ @Nullable - private FeedHandlerResult doParseFeed() throws Exception { + private FeedHandlerResult doParseFeed(String destination) throws Exception { FeedHandler handler = new FeedHandler(); + Feed feed = new Feed(selectedDownloadUrl, null); + feed.setFile_url(destination); + File destinationFile = new File(destination); try { return handler.parseFeed(feed); } catch (UnsupportedFeedtypeException e) { Log.d(TAG, "Unsupported feed type detected"); if ("html".equalsIgnoreCase(e.getRootElement())) { - boolean dialogShown = showFeedDiscoveryDialog(new File(feed.getFile_url()), feed.getDownload_url()); + boolean dialogShown = showFeedDiscoveryDialog(destinationFile, selectedDownloadUrl); if (dialogShown) { return null; // Should not display an error message } else { @@ -404,7 +400,7 @@ public class OnlineFeedViewActivity extends AppCompatActivity { Log.e(TAG, Log.getStackTraceString(e)); throw e; } finally { - boolean rc = new File(feed.getFile_url()).delete(); + boolean rc = destinationFile.delete(); Log.d(TAG, "Deleted feed source file. Result: " + rc); } } @@ -420,8 +416,6 @@ public class OnlineFeedViewActivity extends AppCompatActivity { int resId = R.string.no_feed_url_podcast_found_by_search; Snackbar.make(findViewById(android.R.id.content), resId, Snackbar.LENGTH_LONG).show(); } - this.feed = feed; - this.selectedDownloadUrl = feed.getDownload_url(); viewBinding.backgroundImage.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); @@ -459,15 +453,15 @@ public class OnlineFeedViewActivity extends AppCompatActivity { description.setText(HtmlToPlainText.getPlainText(feed.getDescription())); viewBinding.subscribeButton.setOnClickListener(v -> { - if (feedInFeedlist(feed)) { + if (feedInFeedlist()) { openFeed(); } else { Feed f = new Feed(selectedDownloadUrl, null, feed.getTitle()); - f.setPreferences(feed.getPreferences()); - this.feed = f; - DownloadService.download(this, false, DownloadRequestCreator.create(f).build()); + DownloadService.download(this, false, DownloadRequestCreator.create(f) + .withAuthentication(username, password) + .build()); didPressSubscribe = true; - handleUpdatedFeedStatus(feed); + handleUpdatedFeedStatus(); } }); @@ -531,72 +525,62 @@ public class OnlineFeedViewActivity extends AppCompatActivity { } }); } - handleUpdatedFeedStatus(feed); + handleUpdatedFeedStatus(); } private void openFeed() { // feed.getId() is always 0, we have to retrieve the id from the feed list from // the database - Intent intent = MainActivity.getIntentToOpenFeed(this, getFeedId(feed)); + Intent intent = MainActivity.getIntentToOpenFeed(this, getFeedId()); intent.putExtra(MainActivity.EXTRA_STARTED_FROM_SEARCH, getIntent().getBooleanExtra(MainActivity.EXTRA_STARTED_FROM_SEARCH, false)); finish(); startActivity(intent); } - private void handleUpdatedFeedStatus(Feed feed) { - if (feed != null) { - if (DownloadService.isDownloadingFile(feed.getDownload_url())) { - viewBinding.subscribeButton.setEnabled(false); - viewBinding.subscribeButton.setText(R.string.subscribing_label); - } else if (feedInFeedlist(feed)) { - viewBinding.subscribeButton.setEnabled(true); - viewBinding.subscribeButton.setText(R.string.open_podcast); - if (didPressSubscribe) { - didPressSubscribe = false; - if (UserPreferences.isEnableAutodownload()) { - boolean autoDownload = viewBinding.autoDownloadCheckBox.isChecked(); - - Feed feed1 = DBReader.getFeed(getFeedId(feed)); - FeedPreferences feedPreferences = feed1.getPreferences(); - feedPreferences.setAutoDownload(autoDownload); - DBWriter.setFeedPreferences(feedPreferences); - - SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE); - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean(PREF_LAST_AUTO_DOWNLOAD, autoDownload); - editor.apply(); - } - openFeed(); - } - } else { - viewBinding.subscribeButton.setEnabled(true); - viewBinding.subscribeButton.setText(R.string.subscribe_label); + private void handleUpdatedFeedStatus() { + if (DownloadService.isDownloadingFile(selectedDownloadUrl)) { + viewBinding.subscribeButton.setEnabled(false); + viewBinding.subscribeButton.setText(R.string.subscribing_label); + } else if (feedInFeedlist()) { + viewBinding.subscribeButton.setEnabled(true); + viewBinding.subscribeButton.setText(R.string.open_podcast); + if (didPressSubscribe) { + didPressSubscribe = false; if (UserPreferences.isEnableAutodownload()) { - viewBinding.autoDownloadCheckBox.setVisibility(View.VISIBLE); + boolean autoDownload = viewBinding.autoDownloadCheckBox.isChecked(); + + Feed feed1 = DBReader.getFeed(getFeedId()); + FeedPreferences feedPreferences = feed1.getPreferences(); + feedPreferences.setAutoDownload(autoDownload); + DBWriter.setFeedPreferences(feedPreferences); + + SharedPreferences preferences = getSharedPreferences(PREFS, MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean(PREF_LAST_AUTO_DOWNLOAD, autoDownload); + editor.apply(); } + openFeed(); + } + } else { + viewBinding.subscribeButton.setEnabled(true); + viewBinding.subscribeButton.setText(R.string.subscribe_label); + if (UserPreferences.isEnableAutodownload()) { + viewBinding.autoDownloadCheckBox.setVisibility(View.VISIBLE); } } } - private boolean feedInFeedlist(Feed feed) { - if (feeds == null || feed == null) { - return false; - } - for (Feed f : feeds) { - if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { - return true; - } - } - return false; + private boolean feedInFeedlist() { + return getFeedId() != 0; } - private long getFeedId(Feed feed) { - if (feeds == null || feed == null) { + private long getFeedId() { + if (feeds == null) { return 0; } for (Feed f : feeds) { - if (f.getIdentifyingValue().equals(feed.getIdentifyingValue())) { + if (f.getDownload_url().equals(selectedDownloadUrl)) { return f.getId(); } } 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 954a6c2f6..9ffade1ca 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java @@ -36,6 +36,7 @@ import androidx.core.view.WindowCompat; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import com.bumptech.glide.Glide; import de.danoeh.antennapod.R; +import de.danoeh.antennapod.dialog.VariableSpeedDialog; import de.danoeh.antennapod.event.playback.BufferUpdateEvent; import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.event.PlayerErrorEvent; @@ -591,6 +592,7 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. menu.findItem(R.id.player_switch_to_audio_only).setVisible(true); menu.findItem(R.id.audio_controls).setIcon(R.drawable.ic_sliders); + menu.findItem(R.id.playback_speed).setVisible(true); return true; } @@ -640,6 +642,8 @@ public class VideoplayerActivity extends CastEnabledActivity implements SeekBar. } else if (item.getItemId() == R.id.share_item && feedItem != null) { ShareDialog shareDialog = ShareDialog.newInstance(feedItem); shareDialog.show(getSupportFragmentManager(), "ShareEpisodeDialog"); + } else if (item.getItemId() == R.id.playback_speed) { + new VariableSpeedDialog().show(getSupportFragmentManager(), null); } else { return false; } 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 bf508cdd8..6fcdca416 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -237,6 +237,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder> // reset for re-use holder.count.setVisibility(View.GONE); holder.count.setOnClickListener(null); + holder.count.setClickable(false); String tag = fragmentTags.get(position); if (tag.equals(QueueFragment.TAG)) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java index a7986e144..4ebfcff5b 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsRecyclerAdapter.java @@ -39,7 +39,7 @@ import de.danoeh.antennapod.core.storage.NavDrawerData; import de.danoeh.antennapod.fragment.FeedItemlistFragment; import de.danoeh.antennapod.fragment.SubscriptionFragment; import de.danoeh.antennapod.model.feed.Feed; -import jp.shts.android.library.TriangleLabelView; +import de.danoeh.antennapod.ui.common.TriangleLabelView; /** * Adapter for subscriptions 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 52df91282..120134344 100644 --- a/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java +++ b/app/src/main/java/de/danoeh/antennapod/config/DownloadServiceCallbacksImpl.java @@ -32,7 +32,7 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks { activityIntent.setAction("request" + request.getFeedfileId()); activityIntent.putExtra(DownloadAuthenticationActivity.ARG_DOWNLOAD_REQUEST, request); return PendingIntent.getActivity(context.getApplicationContext(), - R.id.pending_intent_download_service_auth, activityIntent, + request.getSource().hashCode(), activityIntent, PendingIntent.FLAG_ONE_SHOT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0)); } 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 d82b3ff0c..f1befcd94 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -80,6 +80,11 @@ public class CompletedDownloadsFragment extends Fragment toolbar.setTitle(R.string.downloads_label); toolbar.inflateMenu(R.menu.downloads_completed); toolbar.setOnMenuItemClickListener(this); + toolbar.setOnLongClickListener(v -> { + recyclerView.scrollToPosition(5); + recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); + return false; + }); refreshToolbarState(); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { 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 7902a4988..bca0f8640 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java @@ -185,6 +185,9 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); + if (header == null || infoContainer == null) { + return; + } int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing); header.setPadding(horizontalSpacing, header.getPaddingTop(), horizontalSpacing, header.getPaddingBottom()); infoContainer.setPadding(horizontalSpacing, infoContainer.getPaddingTop(), 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 80a65e518..77d0c4555 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -129,6 +129,12 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem speedDialBinding = MultiSelectSpeedDialBinding.bind(viewBinding.getRoot()); viewBinding.toolbar.inflateMenu(R.menu.feedlist); viewBinding.toolbar.setOnMenuItemClickListener(this); + viewBinding.toolbar.setOnLongClickListener(v -> { + viewBinding.recyclerView.scrollToPosition(5); + viewBinding.recyclerView.post(() -> viewBinding.recyclerView.smoothScrollToPosition(0)); + viewBinding.appBar.setExpanded(true); + return false; + }); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); @@ -162,8 +168,11 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem public void onScrolled(@NonNull RecyclerView view, int deltaX, int deltaY) { super.onScrolled(view, deltaX, deltaY); boolean hasMorePages = feed != null && feed.isPaged() && feed.getNextPageLink() != null; - nextPageLoader.getRoot().setVisibility( - (viewBinding.recyclerView.isScrolledToBottom() && hasMorePages) ? View.VISIBLE : View.GONE); + boolean pageLoaderVisible = viewBinding.recyclerView.isScrolledToBottom() && hasMorePages; + nextPageLoader.getRoot().setVisibility(pageLoaderVisible ? View.VISIBLE : View.GONE); + viewBinding.recyclerView.setPadding( + viewBinding.recyclerView.getPaddingLeft(), 0, viewBinding.recyclerView.getPaddingRight(), + pageLoaderVisible ? nextPageLoader.getRoot().getMeasuredHeight() : 0); } }); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java index 9d5376c2a..0ff0bd24a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java @@ -58,6 +58,11 @@ public class InboxFragment extends EpisodesListFragment implements Toolbar.OnMen toolbar = inboxContainer.findViewById(R.id.toolbar); toolbar.setOnMenuItemClickListener(this); toolbar.inflateMenu(R.menu.inbox); + toolbar.setOnLongClickListener(v -> { + recyclerView.scrollToPosition(5); + recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); + return false; + }); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); 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 3bdc0e49f..375356c2c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -39,6 +39,7 @@ import de.danoeh.antennapod.adapter.actionbutton.StreamActionButton; import de.danoeh.antennapod.adapter.actionbutton.VisitWebsiteActionButton; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.service.download.DownloadRequest; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.event.FeedItemEvent; import de.danoeh.antennapod.event.PlayerStatusEvent; @@ -54,6 +55,7 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.DateFormatter; import de.danoeh.antennapod.core.util.FeedItemUtil; +import de.danoeh.antennapod.ui.common.CircularProgressBar; import de.danoeh.antennapod.ui.common.ThemeUtils; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.Timeline; @@ -106,7 +108,7 @@ public class ItemFragment extends Fragment { private TextView txtvDuration; private TextView txtvPublished; private ImageView imgvCover; - private ProgressBar progbarDownload; + private CircularProgressBar progbarDownload; private ProgressBar progbarLoading; private TextView butAction1Text; private TextView butAction2Text; @@ -158,7 +160,7 @@ public class ItemFragment extends Fragment { imgvCover = layout.findViewById(R.id.imgvCover); imgvCover.setOnClickListener(v -> openPodcast()); - progbarDownload = layout.findViewById(R.id.progbarDownload); + progbarDownload = layout.findViewById(R.id.circularProgressBar); progbarLoading = layout.findViewById(R.id.progbarLoading); butAction1 = layout.findViewById(R.id.butAction1); butAction2 = layout.findViewById(R.id.butAction2); @@ -311,10 +313,11 @@ public class ItemFragment extends Fragment { progbarDownload.setVisibility(View.GONE); if (item.hasMedia() && downloaderList != null) { for (Downloader downloader : downloaderList) { - if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA - && downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) { + DownloadRequest request = downloader.getDownloadRequest(); + if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA + && request.getFeedfileId() == item.getMedia().getId()) { progbarDownload.setVisibility(View.VISIBLE); - progbarDownload.setProgress(downloader.getDownloadRequest().getProgressPercent()); + progbarDownload.setPercentage(0.01f * Math.max(1, request.getProgressPercent()), request); } } } 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 8bcef4181..a22edbc76 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -51,6 +51,11 @@ public class PlaybackHistoryFragment extends EpisodesListFragment implements Too toolbar = historyContainer.findViewById(R.id.toolbar); toolbar.setTitle(R.string.playback_history_label); toolbar.setOnMenuItemClickListener(this); + toolbar.setOnLongClickListener(v -> { + recyclerView.scrollToPosition(5); + recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); + return false; + }); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 433193f10..370deee76 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -445,6 +445,11 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi View root = inflater.inflate(R.layout.queue_fragment, container, false); toolbar = root.findViewById(R.id.toolbar); toolbar.setOnMenuItemClickListener(this); + toolbar.setOnLongClickListener(v -> { + recyclerView.scrollToPosition(5); + recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); + return false; + }); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); 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 94c0b0a41..578a2fa84 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -125,6 +125,11 @@ public class SubscriptionFragment extends Fragment View root = inflater.inflate(R.layout.fragment_subscriptions, container, false); toolbar = root.findViewById(R.id.toolbar); toolbar.setOnMenuItemClickListener(this); + toolbar.setOnLongClickListener(v -> { + subscriptionRecycler.scrollToPosition(5); + subscriptionRecycler.post(() -> subscriptionRecycler.smoothScrollToPosition(0)); + return false; + }); displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; if (savedInstanceState != null) { displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); @@ -146,13 +151,8 @@ public class SubscriptionFragment extends Fragment } subscriptionRecycler = root.findViewById(R.id.subscriptions_grid); - GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), - prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()), - RecyclerView.VERTICAL, - false); - subscriptionRecycler.setLayoutManager(gridLayoutManager); + setColumnNumber(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns())); subscriptionRecycler.addItemDecoration(new SubscriptionsRecyclerAdapter.GridDividerItemDecorator()); - gridLayoutManager.setSpanCount(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns())); registerForContextMenu(subscriptionRecycler); subscriptionAddButton = root.findViewById(R.id.subscriptions_add); progressBar = root.findViewById(R.id.progLoading); @@ -239,9 +239,9 @@ public class SubscriptionFragment extends Fragment } private void setColumnNumber(int columns) { - GridLayoutManager gridLayoutManager = (GridLayoutManager) subscriptionRecycler.getLayoutManager(); - gridLayoutManager.setSpanCount(columns); - subscriptionAdapter.notifyDataSetChanged(); + GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), + columns, RecyclerView.VERTICAL, false); + subscriptionRecycler.setLayoutManager(gridLayoutManager); prefs.edit().putInt(PREF_NUM_COLUMNS, columns).apply(); refreshToolbarState(); } 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 e2c5036df..7f5205db4 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 @@ -17,6 +17,13 @@ import de.danoeh.antennapod.activity.BugReportActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.fragment.preferences.about.AboutFragment; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Locale; public class MainPreferencesFragment extends PreferenceFragmentCompat { @@ -106,7 +113,7 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat { } ); findPreference(PREF_DOCUMENTATION).setOnPreferenceClickListener(preference -> { - IntentUtils.openInBrowser(getContext(), "https://antennapod.org/documentation/"); + IntentUtils.openInBrowser(getContext(), getLocalizedWebsiteLink() + "/documentation/"); return true; }); findPreference(PREF_VIEW_FORUM).setOnPreferenceClickListener(preference -> { @@ -114,7 +121,7 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat { return true; }); findPreference(PREF_CONTRIBUTE).setOnPreferenceClickListener(preference -> { - IntentUtils.openInBrowser(getContext(), "https://antennapod.org/contribute/"); + IntentUtils.openInBrowser(getContext(), getLocalizedWebsiteLink() + "/contribute/"); return true; }); findPreference(PREF_SEND_BUG_REPORT).setOnPreferenceClickListener(preference -> { @@ -123,6 +130,20 @@ public class MainPreferencesFragment extends PreferenceFragmentCompat { }); } + private String getLocalizedWebsiteLink() { + try (InputStream is = getContext().getAssets().open("website-languages.txt")) { + String[] languages = IOUtils.toString(is, StandardCharsets.UTF_8.name()).split("\n"); + String deviceLanguage = Locale.getDefault().getLanguage(); + if (ArrayUtils.contains(languages, deviceLanguage) && !"en".equals(deviceLanguage)) { + return "https://antennapod.org/" + deviceLanguage; + } else { + return "https://antennapod.org"; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private void setupSearch() { SearchPreference searchPreference = findPreference("searchPreference"); SearchConfiguration config = searchPreference.getSearchConfiguration(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java index 358985cea..e3e069868 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/synchronization/GpodderAuthenticationFragment.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.fragment.preferences.synchronization; import android.app.Dialog; import android.content.Context; -import android.graphics.Paint; import android.os.Build; import android.os.Bundle; import android.view.View; @@ -12,31 +11,20 @@ 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 java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.sync.SynchronizationCredentials; import de.danoeh.antennapod.core.service.download.AntennapodHttpClient; import de.danoeh.antennapod.core.sync.SyncService; +import de.danoeh.antennapod.core.sync.SynchronizationCredentials; import de.danoeh.antennapod.core.sync.SynchronizationProviderViewData; import de.danoeh.antennapod.core.sync.SynchronizationSettings; import de.danoeh.antennapod.core.util.FileNameGenerator; -import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.net.sync.gpoddernet.GpodnetService; import de.danoeh.antennapod.net.sync.gpoddernet.model.GpodnetDevice; import io.reactivex.Completable; @@ -44,6 +32,11 @@ 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. */ @@ -70,7 +63,7 @@ public class GpodderAuthenticationFragment extends DialogFragment { @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { AlertDialog.Builder dialog = new AlertDialog.Builder(getContext()); - dialog.setTitle(GpodnetService.DEFAULT_BASE_HOST); + dialog.setTitle(R.string.gpodnetauth_login_butLabel); dialog.setNegativeButton(R.string.cancel_label, null); dialog.setCancelable(false); this.setCancelable(false); @@ -85,23 +78,13 @@ public class GpodderAuthenticationFragment extends DialogFragment { 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(SynchronizationCredentials.getHosturl())) { - serverUrlText.setText(SynchronizationCredentials.getHosturl()); - } - 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 -> { - SynchronizationCredentials.clear(getContext()); - if (serverRadioGroup.getCheckedRadioButtonId() == R.id.customServerRadio) { - SynchronizationCredentials.setHosturl(serverUrlText.getText().toString()); - } else { - SynchronizationCredentials.setHosturl(GpodnetService.DEFAULT_BASE_HOST); + if (serverUrlText.getText().length() == 0) { + return; } + SynchronizationCredentials.clear(getContext()); + SynchronizationCredentials.setHosturl(serverUrlText.getText().toString()); service = new GpodnetService(AntennapodHttpClient.getHttpClient(), SynchronizationCredentials.getHosturl(), SynchronizationCredentials.getDeviceID(), SynchronizationCredentials.getUsername(), SynchronizationCredentials.getPassword()); @@ -116,12 +99,8 @@ public class GpodderAuthenticationFragment extends DialogFragment { 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); final TextView createAccountWarning = view.findViewById(R.id.createAccountWarning); - createAccount.setPaintFlags(createAccount.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - createAccount.setOnClickListener(v -> IntentUtils.openInBrowser(getContext(), "https://gpodder.net/register/")); - if (SynchronizationCredentials.getHosturl().startsWith("http://")) { createAccountWarning.setVisibility(View.VISIBLE); } |