diff options
author | H. Lehmann <ByteHamster@users.noreply.github.com> | 2019-07-11 12:43:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-11 12:43:30 +0200 |
commit | 9f6529d4bc82fa9b064a5dbce8c8add273371926 (patch) | |
tree | d832e4c3ff33520191eeecb703fe3460f27c8d7e | |
parent | 8e95ed75abb68100afd2572831bc71ee8dd51917 (diff) | |
parent | e78e4d56567799e080b722bd600681a731ff9d84 (diff) | |
download | AntennaPod-9f6529d4bc82fa9b064a5dbce8c8add273371926.zip |
Merge branch 'develop' into 2747-completed-downloads-update
12 files changed, 101 insertions, 43 deletions
diff --git a/app/build.gradle b/app/build.gradle index b4812e083..a9cce57d4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -139,6 +139,11 @@ dependencies { implementation "com.android.support:gridlayout-v7:$supportVersion" implementation "com.android.support:recyclerview-v7:$supportVersion" compileOnly 'com.google.android.wearable:wearable:2.2.0' + + // ViewModel and LiveData + implementation "android.arch.lifecycle:extensions:$lifecycle_version" + annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" + implementation "org.apache.commons:commons-lang3:$commonslangVersion" implementation("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") { exclude group: "org.json", module: "json" diff --git a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java index fd526d1db..fbd19f88a 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/FeedSettingsActivity.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.activity; +import android.arch.lifecycle.ViewModelProviders; import android.graphics.LightingColorFilter; import android.os.Bundle; import android.support.v4.app.FragmentManager; @@ -7,7 +8,6 @@ import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; - import android.view.MenuItem; import android.view.View; import android.widget.ImageView; @@ -19,10 +19,8 @@ import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.FastBlurTransformation; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.fragment.FeedSettingsFragment; -import io.reactivex.Maybe; -import io.reactivex.MaybeOnSubscribe; +import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; @@ -46,7 +44,6 @@ public class FeedSettingsActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.feedsettings); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1); imgvCover = findViewById(R.id.imgvCover); txtvTitle = findViewById(R.id.txtvTitle); @@ -57,14 +54,8 @@ public class FeedSettingsActivity extends AppCompatActivity { // https://github.com/bumptech/glide/issues/529 imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); - disposable = Maybe.create((MaybeOnSubscribe<Feed>) emitter -> { - Feed feed = DBReader.getFeed(feedId); - if (feed != null) { - emitter.onSuccess(feed); - } else { - emitter.onComplete(); - } - }) + long feedId = getIntent().getLongExtra(EXTRA_FEED_ID, -1); + disposable = ViewModelProviders.of(this).get(FeedSettingsViewModel.class).getFeed(feedId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { @@ -91,10 +82,6 @@ public class FeedSettingsActivity extends AppCompatActivity { fragmentTransaction.commit(); } - public Feed getFeed() { - return feed; - } - private void showHeader() { txtvTitle.setText(feed.getTitle()); 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 index 8fcdb4371..df21f713d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/gpoddernet/GpodnetAuthenticationActivity.java @@ -25,6 +25,8 @@ 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; @@ -123,6 +125,11 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { 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>() { @@ -395,4 +402,10 @@ public class GpodnetAuthenticationActivity extends AppCompatActivity { 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/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 391140258..0b38fe18a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -258,6 +258,9 @@ public class AllEpisodesFragment extends Fragment { @Override public boolean onContextItemSelected(MenuItem item) { Log.d(TAG, "onContextItemSelected() called with: " + "item = [" + item + "]"); + if (!getUserVisibleHint()) { + return false; + } if (!isVisible()) { return false; } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java index 7fd61d3ad..db9dd9530 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -44,6 +44,7 @@ public class CoverFragment extends Fragment { txtvPodcastTitle = root.findViewById(R.id.txtvPodcastTitle); txtvEpisodeTitle = root.findViewById(R.id.txtvEpisodeTitle); imgvCover = root.findViewById(R.id.imgvCover); + imgvCover.setOnClickListener(v -> onPlayPause()); return root; } @@ -114,4 +115,11 @@ public class CoverFragment extends Fragment { disposable.dispose(); } } + + void onPlayPause() { + if (controller == null) { + return; + } + controller.playPause(); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java index a20384086..4fb3d90f5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.fragment; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; @@ -7,7 +8,6 @@ import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.PreferenceFragmentCompat; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.FeedSettingsActivity; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedFilter; @@ -16,6 +16,9 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.dialog.AuthenticationDialog; import de.danoeh.antennapod.dialog.EpisodeFilterDialog; +import de.danoeh.antennapod.viewmodel.FeedSettingsViewModel; + +import static de.danoeh.antennapod.activity.FeedSettingsActivity.EXTRA_FEED_ID; public class FeedSettingsFragment extends PreferenceFragmentCompat { private static final CharSequence PREF_EPISODE_FILTER = "episodeFilter"; @@ -26,17 +29,21 @@ public class FeedSettingsFragment extends PreferenceFragmentCompat { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.feed_settings); - feed = ((FeedSettingsActivity) getActivity()).getFeed(); - feedPreferences = feed.getPreferences(); - - setupAutoDownloadPreference(); - setupKeepUpdatedPreference(); - setupAutoDeletePreference(); - setupAuthentificationPreference(); - setupEpisodeFilterPreference(); - - updateAutoDeleteSummary(); - updateAutoDownloadEnabled(); + long feedId = getArguments().getLong(EXTRA_FEED_ID); + ViewModelProviders.of(getActivity()).get(FeedSettingsViewModel.class).getFeed(feedId) + .subscribe(result -> { + feed = result; + feedPreferences = feed.getPreferences(); + + setupAutoDownloadPreference(); + setupKeepUpdatedPreference(); + setupAutoDeletePreference(); + setupAuthentificationPreference(); + setupEpisodeFilterPreference(); + + updateAutoDeleteSummary(); + updateAutoDownloadEnabled(); + }).dispose(); } private void setupEpisodeFilterPreference() { diff --git a/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java b/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java new file mode 100644 index 000000000..fe11a645c --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/viewmodel/FeedSettingsViewModel.java @@ -0,0 +1,30 @@ +package de.danoeh.antennapod.viewmodel; + +import android.arch.lifecycle.ViewModel; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.storage.DBReader; +import io.reactivex.Maybe; + +public class FeedSettingsViewModel extends ViewModel { + private Feed feed; + + public Maybe<Feed> getFeed(long feedId) { + if (feed == null) { + return loadFeed(feedId); + } else { + return Maybe.just(feed); + } + } + + private Maybe<Feed> loadFeed(long feedId) { + return Maybe.create(emitter -> { + Feed feed = DBReader.getFeed(feedId); + if (feed != null) { + this.feed = feed; + emitter.onSuccess(feed); + } else { + emitter.onComplete(); + } + }); + } +} diff --git a/app/src/main/res/layout/cover_fragment.xml b/app/src/main/res/layout/cover_fragment.xml index fec7be26c..8e0ec3679 100644 --- a/app/src/main/res/layout/cover_fragment.xml +++ b/app/src/main/res/layout/cover_fragment.xml @@ -26,7 +26,8 @@ android:contentDescription="@string/cover_label" android:scaleType="fitCenter" android:transitionName="coverTransition" - tools:src="@android:drawable/sym_def_app_icon" /> + tools:src="@android:drawable/sym_def_app_icon" + android:foreground="?attr/selectableItemBackground" /> <TextView android:id="@+id/txtvEpisodeTitle" diff --git a/build.gradle b/build.gradle index b2fdaff8a..797e7c520 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,7 @@ project.ext { targetSdkVersion = 26 supportVersion = "27.1.1" + lifecycle_version = "1.1.1" workManagerVersion = "1.0.1" awaitilityVersion = "3.1.2" commonsioVersion = "2.5" diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java index 5141e3a78..668f938a0 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/DateUtils.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import java.text.ParsePosition; import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; @@ -162,11 +163,10 @@ public class DateUtils { if (date == null) { return ""; } + GregorianCalendar now = new GregorianCalendar(); GregorianCalendar cal = new GregorianCalendar(); - cal.add(GregorianCalendar.YEAR, -1); - // some padding, because no one really remembers what day of the month it is - cal.add(GregorianCalendar.DAY_OF_MONTH, 10); - boolean withinLastYear = date.after(cal.getTime()); + cal.setTime(date); + boolean withinLastYear = now.get(Calendar.YEAR) == cal.get(Calendar.YEAR); int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL; if (withinLastYear) { format |= android.text.format.DateUtils.FORMAT_NO_YEAR; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java index f681b8062..d22d08e09 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/id3reader/ChapterReader.java @@ -1,6 +1,10 @@ package de.danoeh.antennapod.core.util.id3reader; import android.util.Log; +import de.danoeh.antennapod.core.feed.Chapter; +import de.danoeh.antennapod.core.feed.ID3Chapter; +import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; +import de.danoeh.antennapod.core.util.id3reader.model.TagHeader; import java.io.IOException; import java.io.InputStream; @@ -8,11 +12,6 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; -import de.danoeh.antennapod.core.feed.Chapter; -import de.danoeh.antennapod.core.feed.ID3Chapter; -import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; -import de.danoeh.antennapod.core.util.id3reader.model.TagHeader; - public class ChapterReader extends ID3Reader { private static final String TAG = "ID3ChapterReader"; @@ -69,11 +68,14 @@ public class ChapterReader extends ID3Reader { int descriptionLength = readString(null, input, header.getSize()); StringBuilder link = new StringBuilder(); readISOString(link, input, header.getSize() - descriptionLength); - String decodedLink = URLDecoder.decode(link.toString(), "UTF-8"); - - currentChapter.setLink(decodedLink); + try { + String decodedLink = URLDecoder.decode(link.toString(), "UTF-8"); + currentChapter.setLink(decodedLink); + Log.d(TAG, "Found link: " + currentChapter.getLink()); + } catch (IllegalArgumentException _iae) { + Log.w(TAG, "Bad URL found in ID3 data"); + } - Log.d(TAG, "Found link: " + currentChapter.getLink()); return ID3Reader.ACTION_DONT_SKIP; } break; diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 4378abe50..2fbb65744 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -642,6 +642,7 @@ <string name="gpodnetsync_error_descr">An error occurred during syncing:\u0020</string> <string name="gpodnetsync_pref_report_successful">Successful</string> <string name="gpodnetsync_pref_report_failed">Failed</string> + <string name="gpodnetsync_username_characters_error">Usernames may only contain letters, digits, hyphens and underscores.</string> <!-- Directory chooser --> <string name="selected_folder_label">Selected folder:</string> |