diff options
61 files changed, 921 insertions, 326 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e3ac1bc..2899d1fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== + +Version 1.7.1 +------------- + +* Fix for database corruption + Version 1.7.0 ------------- diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 837c412c5..891a9784c 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,107 +1,168 @@ DEVELOPERS ========== +Alan Orth Alexander Terczka +alifeflow +amhokies +Anders Bo Rasmussen Andrew Gaul Andrey Krutov Anthony Lieuallen axq +brad ByteHamster +Cameron Banga Christian Ludwig Christopher Szucko +Cj Malone Colin Willson +Cédric Cabessa +Danial Klimkin Daniel Oeh David Carver David Reiss Dean Brettle dethstar +Dirk Mueller Domingos Lopes drabux +egsavage +EirikV Eoin Mcloughlin +eraymond Ercan Erden +Falko Lehmann +Hannes Achleitner +hannesa2 Hanno Zulla heckler01 Holger Jeromin +Humberto Fraga +InsidE James Falcon +Jan Niehusmann +Jens Klingenberg Jens Müller Johan Liesén +Kaligule Katrin Leinweber -keunes +Kevin Dalley Koen Glotzbach +kroegerama +Kurian Vithayathil LatinSuD Lee Yeong Khang lightonflux ligi +Luis Cruz +Marc Lasson Martin Fietz Martin Olsson mat tso +mateoeh +Matthew Gaffen Matthias Schütz +Maurice Gilden +Meir Schwarz Michael Kaiser Michael Scarito Mike Chelen +minusf +MolarAmbiguity Mounir Lamouri +mr-intj Nis Wechselberg +Oliver Crow +orelogo Paul Ortyl +Raghul +Raghul Jagannathan recalculated Ross Harrison +Sam Lee Sam Whited +saqura +Selivanov Pavel +Serge Seth Golub +sevenmaster +Shantana Hardy Simon Danner Simon Rutishauser Simon Schubert +Soso Tughushi +Spencer Visick Stefan Mitrik Terence Eden Tim Butram Tobias Preuss Tom Hennen +Tom Tom tommy watson +tuxayo twiceyuan Udi Finkelstein +VarunBarad volhol Volker Hollich WangYun William Seemann +ydinath TRANSLATORS =========== -Arabic: abuzar3.khalid, iDemo -Azerbaijani: phoenixar -Catalan: dvd1985, javiercoll, xc70 -Catalan (Spain): javiercoll -Chinese (China): bebeauties38, dudeG, Felix2yu, gaohongyuan, Guaidaodl, linxiangyu, molisiye, tupunco, wongsyrone, yangyang, YogaGuru +Arabic: abdelrahman.fahem93, abdunnasir, abuzar3.khalid, desha, iDemo, mohamedagamy, msahouli, nabilMaghura +Asturian (Spain): enolp +Azerbaijani: danieloeh, kotfenix +Bulgarian: solusitor +Catalan: dvd1985, exort12, javiercoll, lambdani, marcmetallextrem, xc70 +Catalan (Spain): 00c0c0, javiercoll +Chinese: dillonbecker, RainSlide, xukeek, yangyang +Chinese (China): bebeauties38, domingos86, dudeG, ErlichLiu, Felix2yu, gaohongyuan, Guaidaodl, Huck0, iconteral, jhxie, kavdx, kyleehee, linxiangyu, molisiye, owen8877, RainSlide, stellaxuyi, tupunco, wi24rd, wongsyrone, xukeek, yangyang, yiqiok, YogaGuru +Chinese (Taiwan): gugod, nigelinux, pggdt, ymhuang0808 Czech (Czech Republic): elich, Hanzmeister, mcepl, petnek, svetlemodry -Danish: CasperHN -Dutch: e2jk, glotzbach, rwv +Danish: CasperHN, jhertel +Dutch: e2jk, glotzbach, rwv, Vistaus English: mfietz, sterylmreep +Estonian: Eraser Finnish: danieloeh -French: cactux, ChaoticMind, clombion, e2jk, lacouture, Matth78, mfietz, repat, sterylmreep, vcariven -German: 112358, altegedanken, bitsunited, ChaoticMind, Chaquotay, dab0015, DJaeger, HolgerJeromin, kalei, lohmann, mfietz, nilso, picsel2, repat, SAPlayer, schafia, ypid -Greek: AlexanderKanetakis -Hebrew (Israel): amir.dafnyman -Hindi (India): purple.coder, siddhusengar -Hungarian: glatz.balazs, naren93 -Indonesian: luke137, silvanael16 -Italian: aalex70, apanontin, Guybrush88, theloca95 -Italian (Italy): aalex70, apanontin, Guybrush88, m.chinni, theloca95 +French: cactux, ChaoticMind, clombion, e2jk, lacouture, Matth78, mfietz, Poussinou, PRIMOKORN, repat, sterylmreep, TacoTheDank, Tilwa, vcariven, whenrow +Galician: antiparvos, pikamoku, Raichely +German: 112358, altegedanken, barilla, bitsunited, Buggi, ceving, ChaoticMind, Chaquotay, dab0015, dadosch, DerSilly, DJaeger, elkangaroo, enz, fidel, finsterwalder, Foso, GNi33, HolgerJeromin, kalei, lohmann, LostInWeb, mfietz, nilso, repat, SAPlayer, schafia, Schroedingberg, sevenmaster, sucaml, Teaspoon, theonlytruth, weltenwort, Wyrrrd, ypid +Greek: antonist, danieloeh, hua2016s, MSavoritias, pavlosv +Hebrew (Israel): amir.dafnyman, E1i9, mongoose4004, pinkasey, rellieberman, Yaron, הלוי11 +Hindi (India): nmabhinandan, purple.coder, siddhusengar +Hungarian: glatz.balazs, lna91, naren93, tszauer, ttyborg42 +Icelandic: marthjod +Indonesian: jff, luke137, rezafaiza, silvanael16 +Italian: aalex70, allin, apanontin, Bonnee, giuseppep, Guybrush88, marco_pag, neonsoftware, sevenmaster, theloca95 +Italian (Italy): aalex70, allin, apanontin, Bonnee, buongiorgio, giuseppep, Guybrush88, m.chinni, neonsoftware, nixxo, sevenmaster, theloca95 Japanese: Naofumi, RACER1, sh3llc4t, TranslatorG Kannada (India): thejeshgn -Korean: changwoo, halcyonest, seungrye, skcha +Korean: changwoo, seungrye, skcha Korean (South Korea): changwoo, seungrye +Lithuanian: naglis +Macedonian: krisfremen Norwegian: hakonanes, timbast -Norwegian Bokmål: hakonanes -Norwegian Bokmål (Norway): hakonanes, kongk, swordfighter, timbast -Polish: Iwangelion, maniexx, thedead4fun -Polish (Poland): Iwangelion, lomapur, maniexx, Mephistofeles, shark103, tyle -Portuguese: emansije, smarquespt -Portuguese (Brazil): alexupits, edman, Firmino, lipefire, lucasmotacr, mbaltar, rogervezaro, SamWilliam, silvanael16 -Romanian (Romania): corneliu.e, fuzzmz -Russian (Russia): astra1, Duke_Raven, mercutiy, null, overmind88, phoenixar, s.chebotar, skvheadless, whereisthetea, zhenya97 -Spanish: coperfix, dvd1985, Fitoschido, frandavid100, javiercoll, LatinSuD, tres.14159 -Spanish (Spain): dvd1985, e2jk, frandavid100 -Swedish (Sweden): albin.brantin, Bio, bpnilsson, ChaoticMind, Lumen, nilso, SharpMelon, TwoD -Turkish: basarancaner, brsata, overbite -Ukrainian (Ukraine): older, zhenya97 -Vietnamese: ppanhh, vietnamesel10n +Norwegian Bokmål: corkie, hakonanes +Norwegian Bokmål (Norway): corkie, hakonanes, kongk, timbast +Persian: ahangarha, F7D +Polish: Iwangelion, maniexx, mfloryan, thedead4fun +Polish (Poland): d6210809, Iwangelion, lomapur, mandlus, maniexx, Mephistofeles, shark103, tyle +Portuguese: domingos86, emansije, smarquespt +Portuguese (Brazil): alexupits, alysonborges, arua, caioau, carlo_valente, castrors, deandreamatias, edman, Firmino, jackmiras, Junin, lipefire, lluccia, lucasmotacr, mbaltar, rogervezaro, RubeensVinicius, SamWilliam, silvanael16 +Romanian (Romania): corneliu.e, fuzzmz, ralienpp +Russian (Russia): astra1, btimofeev, Duke_Raven, GaynullinDima, MegMasters98, mercutiy, null, overmind88, s.chebotar, shams4real, skvheadless, un_logic, whereisthetea, zhenya97 +Slovenian (Slovenia): panter23 +Spanish: AleksSyntek, coperfix, deandreamatias, domingos86, dvd1985, Fitoschido, frandavid100, hard_ware, javiercoll, Juanmuto, lambdani, LatinSuD, leogrignafini, palopezv, TacoTheDank, tres.14159, wakutiteo +Spanish (Spain): dvd1985, e2jk, frandavid100, hard_ware, palopezv, Raichely, TacoTheDank +Swahili (Kenya): BonfaceKilz +Swedish (Sweden): albin.brantin, Bio, bpnilsson, ChaoticMind, jony08, nilso, SharpMelon, TwoD +Telugu: veeven +Turkish: basarancaner, brsata, Erdy, golcuk, overbite +Ukrainian (Ukraine): older, sergiyr, zhenya97 +Vietnamese: abnvolk, nguyenvui, ppanhh, vietnamesel10n Vietnamese (Vietnam): bizover diff --git a/app/build.gradle b/app/build.gradle index a5cdf8a38..d8602d55e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,7 +43,7 @@ android { versionCode getMyVersionCode() versionName "${getMyVersionName()}" testApplicationId "de.test.antennapod" - testInstrumentationRunner "de.test.antennapod.AntennaPodTestRunner" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" generatedDensities = [] } @@ -120,6 +120,10 @@ android { additionalParameters "--no-version-vectors" } + testOptions { + animationsDisabled = true + } + flavorDimensions "market" productFlavors { free { @@ -184,6 +188,11 @@ dependencies { implementation 'com.github.ByteHamster:SearchPreference:v1.0.8' androidTestImplementation "com.jayway.android.robotium:robotium-solo:$robotiumSoloVersion" + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-intents:3.0.2' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test:rules:1.0.2' } play { diff --git a/app/proguard.cfg b/app/proguard.cfg index 90c46345d..6bb98dc9e 100644 --- a/app/proguard.cfg +++ b/app/proguard.cfg @@ -71,8 +71,6 @@ -dontwarn android.support.v7.** -dontwarn com.google.android.wearable.** --keepattributes *Annotation* - -keep class org.shredzone.flattr4j.** { *; } -dontwarn org.shredzone.flattr4j.** @@ -94,6 +92,7 @@ -keepclassmembers class ** { public void onEvent*(**); } +-keep class de.danoeh.antennapod.core.event.* # android-iconify -keep class com.joanzapata.** { *; } diff --git a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java b/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java deleted file mode 100644 index c321e6494..000000000 --- a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.test.antennapod; - -import android.test.InstrumentationTestRunner; -import android.test.suitebuilder.TestSuiteBuilder; - -import junit.framework.TestSuite; - -public class AntennaPodTestRunner extends InstrumentationTestRunner { - - @Override - public TestSuite getAllTests() { - return new TestSuiteBuilder(AntennaPodTestRunner.class) - .includeAllPackagesUnderHere() - .excludePackages("de.test.antennapod.gpodnet") - .build(); - } - -} diff --git a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java new file mode 100644 index 000000000..f9ecacda5 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java @@ -0,0 +1,38 @@ +package de.test.antennapod; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +import java.util.concurrent.atomic.AtomicInteger; + +public class NthMatcher { + public static <T> Matcher<T> first(final Matcher<T> matcher) { + return nth(matcher, 1); + } + + public static <T> Matcher<T> second(final Matcher<T> matcher) { + return nth(matcher, 2); + } + + private static <T> Matcher<T> nth(final Matcher<T> matcher, final int index) { + return new BaseMatcher<T>() { + AtomicInteger count = new AtomicInteger(0); + + @Override + public boolean matches(final Object item) { + if (matcher.matches(item)) { + if (count.incrementAndGet() == index) { + return true; + } + } + return false; + } + + @Override + public void describeTo(final Description description) { + description.appendText("should return first matching item"); + } + }; + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java index a880c330b..91e31e73c 100644 --- a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java +++ b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java @@ -1,43 +1,43 @@ package de.test.antennapod.gpodnet; -import android.test.AndroidTestCase; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import android.support.test.runner.AndroidJUnit4; import de.danoeh.antennapod.core.gpoddernet.GpodnetService; import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetDevice; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; import static java.util.Collections.singletonList; /** * Test class for GpodnetService */ -public class GPodnetServiceTest extends AndroidTestCase { +@Ignore +@RunWith(AndroidJUnit4.class) +public class GPodnetServiceTest { private GpodnetService service; private static final String USER = ""; private static final String PW = ""; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Before + protected void setUp() { service = new GpodnetService(); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - private void authenticate() throws GpodnetServiceException { service.authenticate(USER, PW); } + @Test public void testUploadSubscription() throws GpodnetServiceException { authenticate(); ArrayList<String> l = new ArrayList<>(); @@ -45,6 +45,7 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadSubscriptions(USER, "radio", l); } + @Test public void testUploadSubscription2() throws GpodnetServiceException { authenticate(); ArrayList<String> l = new ArrayList<>(); @@ -53,6 +54,7 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadSubscriptions(USER, "radio", l); } + @Test public void testUploadChanges() throws GpodnetServiceException { authenticate(); String[] URLS = {"http://bitsundso.de/feed", "http://gamesundso.de/feed", "http://cre.fm/feed/mp3/", "http://freakshow.fm/feed/m4a/"}; @@ -63,53 +65,63 @@ public class GPodnetServiceTest extends AndroidTestCase { service.uploadChanges(USER, "radio", added, removed); } + @Test public void testGetSubscriptionChanges() throws GpodnetServiceException { authenticate(); service.getSubscriptionChanges(USER, "radio", 1362322610L); } + @Test public void testGetSubscriptionsOfUser() throws GpodnetServiceException { authenticate(); service.getSubscriptionsOfUser(USER); } + @Test public void testGetSubscriptionsOfDevice() throws GpodnetServiceException { authenticate(); service.getSubscriptionsOfDevice(USER, "radio"); } + @Test public void testConfigureDevices() throws GpodnetServiceException { authenticate(); service.configureDevice(USER, "foo", "This is an updated caption", GpodnetDevice.DeviceType.LAPTOP); } + @Test public void testGetDevices() throws GpodnetServiceException { authenticate(); service.getDevices(USER); } + @Test public void testGetSuggestions() throws GpodnetServiceException { authenticate(); service.getSuggestions(10); } + @Test public void testTags() throws GpodnetServiceException { service.getTopTags(20); } + @Test public void testPodcastForTags() throws GpodnetServiceException { List<GpodnetTag> tags = service.getTopTags(20); service.getPodcastsForTag(tags.get(1), 10); } + @Test public void testSearch() throws GpodnetServiceException { service.searchPodcasts("linux", 64); } + @Test public void testToplist() throws GpodnetServiceException { service.getPodcastToplist(10); } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java index 6156da926..9a60b04b8 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java @@ -2,16 +2,14 @@ package de.test.antennapod.ui; import android.content.Context; import android.content.SharedPreferences; -import android.test.ActivityInstrumentationTestCase2; -import android.test.FlakyTest; +import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.espresso.intent.Intents; +import android.support.test.filters.FlakyTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; import android.widget.ListView; - import com.robotium.solo.Solo; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import com.robotium.solo.Timeout; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; @@ -23,25 +21,46 @@ import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; import de.danoeh.antennapod.fragment.PlaybackHistoryFragment; import de.danoeh.antennapod.fragment.QueueFragment; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.longClick; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static de.test.antennapod.NthMatcher.first; +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertEquals; /** * User interface tests for MainActivity */ -public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { +@RunWith(AndroidJUnit4.class) +public class MainActivityTest { private Solo solo; private UITestUtils uiTestUtils; - private SharedPreferences prefs; - public MainActivityTest() { - super(MainActivity.class); - } + @Rule + public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class); - @Override - protected void setUp() throws Exception { - super.setUp(); - Context context = getInstrumentation().getTargetContext(); + @Before + public void setUp() throws IOException { + Intents.init(); + Context context = mActivityRule.getActivity(); uiTestUtils = new UITestUtils(context); uiTestUtils.setup(); @@ -54,30 +73,26 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv // override first launch preference // do this BEFORE calling getActivity()! - prefs = getInstrumentation().getTargetContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE); + prefs = context.getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE); prefs.edit().putBoolean(MainActivity.PREF_IS_FIRST_LAUNCH, false).commit(); - solo = new Solo(getInstrumentation(), getActivity()); + solo = new Solo(getInstrumentation(), mActivityRule.getActivity()); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { uiTestUtils.tearDown(); solo.finishOpenedActivities(); - + Intents.release(); PodDBAdapter.deleteDatabase(); - - // reset preferences prefs.edit().clear().commit(); - - super.tearDown(); } private void openNavDrawer() { - solo.clickOnImageButton(0); - getInstrumentation().waitForIdleSync(); + onView(withId(R.id.drawer_layout)).perform(DrawerActions.open()); } + @Test public void testAddFeed() throws Exception { uiTestUtils.addHostedFeedData(); final Feed feed = uiTestUtils.hostedFeeds.get(0); @@ -89,10 +104,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv solo.waitForView(R.id.butSubscribe); assertEquals(solo.getString(R.string.subscribe_label), solo.getButton(0).getText().toString()); solo.clickOnButton(0); - solo.waitForText(solo.getString(R.string.subscribed_label)); + assertTrue(solo.waitForText(solo.getString(R.string.open_podcast), 0, Timeout.getLargeTimeout(), false)); } - @FlakyTest(tolerance = 3) + + @Test + @FlakyTest public void testClickNavDrawer() throws Exception { uiTestUtils.addLocalFeedData(false); @@ -150,57 +167,60 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString(); } - @SuppressWarnings("unchecked") - @FlakyTest(tolerance = 3) + + @Test + @FlakyTest public void testGoToPreferences() { openNavDrawer(); - solo.clickOnText(solo.getString(R.string.settings_label)); - solo.waitForActivity(PreferenceActivity.class); + onView(withText(R.string.settings_label)).perform(click()); + intended(hasComponent(PreferenceActivity.class.getName())); } + @Test public void testDrawerPreferencesHideSomeElements() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.episodes_label)); - solo.clickOnText(solo.getString(R.string.playback_history_label)); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(first(withText(R.string.queue_label))).perform(longClick()); + onView(withText(R.string.episodes_label)).perform(click()); + onView(withText(R.string.playback_history_label)).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(2, hidden.size()); assertTrue(hidden.contains(EpisodesFragment.TAG)); assertTrue(hidden.contains(PlaybackHistoryFragment.TAG)); } + @Test public void testDrawerPreferencesUnhideSomeElements() { List<String> hidden = Arrays.asList(PlaybackHistoryFragment.TAG, DownloadsFragment.TAG); UserPreferences.setHiddenDrawerItems(hidden); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.downloads_label)); - solo.clickOnText(solo.getString(R.string.queue_label)); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(first(withText(R.string.queue_label))).perform(longClick()); + + onView(withText(R.string.downloads_label)).perform(click()); + onView(withText(R.string.queue_label)).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(2, hidden.size()); assertTrue(hidden.contains(QueueFragment.TAG)); assertTrue(hidden.contains(PlaybackHistoryFragment.TAG)); } + + @Test public void testDrawerPreferencesHideAllElements() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); - String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles); + String[] titles = mActivityRule.getActivity().getResources().getStringArray(R.array.nav_drawer_titles); openNavDrawer(); - solo.clickLongOnText(solo.getString(R.string.queue_label)); - solo.waitForDialogToOpen(); + onView(first(withText(R.string.queue_label))).perform(longClick()); for (String title : titles) { - solo.clickOnText(title); + onView(first(withText(title))).perform(click()); } - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(titles.length, hidden.size()); for (String tag : MainActivity.NAV_DRAWER_TAGS) { @@ -208,21 +228,85 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv } } + @Test public void testDrawerPreferencesHideCurrentElement() { UserPreferences.setHiddenDrawerItems(new ArrayList<>()); - openNavDrawer(); - String downloads = solo.getString(R.string.downloads_label); - solo.clickOnText(downloads); - solo.waitForView(android.R.id.list); + onView(withText(R.string.downloads_label)).perform(click()); openNavDrawer(); - solo.clickLongOnText(downloads); - solo.waitForDialogToOpen(); - solo.clickOnText(downloads); - solo.clickOnText(solo.getString(R.string.confirm_label)); - solo.waitForDialogToClose(); + + onView(first(withText(R.string.queue_label))).perform(longClick()); + onView(first(withText(R.string.downloads_label))).perform(click()); + onView(withText(R.string.confirm_label)).perform(click()); + List<String> hidden = UserPreferences.getHiddenDrawerItems(); assertEquals(1, hidden.size()); assertTrue(hidden.contains(DownloadsFragment.TAG)); } + + @Test + public void testBackButtonBehaviorGoToPage() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.subscriptions_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertEquals(solo.getString(R.string.subscriptions_label), getActionbarTitle()); + } + + @Test + public void testBackButtonBehaviorOpenDrawer() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_open_drawer)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertTrue(((MainActivity)solo.getCurrentActivity()).isDrawerOpen()); + } + + @Test + public void testBackButtonBehaviorDoubleTap() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_double_tap)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + solo.goBack(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } + + @Test + public void testBackButtonBehaviorPrompt() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_show_prompt)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + solo.clickOnText(solo.getString(R.string.yes)); + solo.waitForDialogToClose(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } + + @Test + public void testBackButtonBehaviorDefault() { + openNavDrawer(); + solo.clickOnText(solo.getString(R.string.settings_label)); + solo.clickOnText(solo.getString(R.string.user_interface_label)); + solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title)); + solo.clickOnText(solo.getString(R.string.back_button_default)); + solo.goBackToActivity(MainActivity.class.getSimpleName()); + solo.goBack(); + assertTrue(solo.getCurrentActivity().isFinishing()); + } } diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java index 293ed2848..55ed998bb 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java @@ -59,7 +59,7 @@ public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActi .clear() .putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false) .putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false) - .putBoolean(UserPreferences.PREF_SONIC, true) + .putString(UserPreferences.PREF_MEDIA_PLAYER, "sonic") .commit(); solo = new Solo(getInstrumentation(), getActivity()); diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 9a5ea437c..f217ecffa 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -1,15 +1,14 @@ package de.test.antennapod.ui; -import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Resources; -import android.test.ActivityInstrumentationTestCase2; - +import android.preference.PreferenceManager; +import android.support.test.espresso.contrib.RecyclerViewActions; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; import com.robotium.solo.Solo; import com.robotium.solo.Timeout; - -import java.util.Arrays; -import java.util.concurrent.TimeUnit; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -17,36 +16,58 @@ import de.danoeh.antennapod.core.storage.APCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm; import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm; import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm; +import de.danoeh.antennapod.fragment.EpisodesFragment; +import de.danoeh.antennapod.fragment.QueueFragment; +import de.danoeh.antennapod.fragment.SubscriptionFragment; -public class PreferencesTest extends ActivityInstrumentationTestCase2<PreferenceActivity> { +import org.hamcrest.Matcher; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; - private static final String TAG = "PreferencesTest"; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class PreferencesTest { private Solo solo; - private Context context; private Resources res; + private SharedPreferences prefs; - public PreferencesTest() { - super(PreferenceActivity.class); - } + @Rule + public ActivityTestRule<PreferenceActivity> mActivityRule = new ActivityTestRule<>(PreferenceActivity.class); - @Override - public void setUp() throws Exception { - super.setUp(); - solo = new Solo(getInstrumentation(), getActivity()); + @Before + public void setUp() { + solo = new Solo(getInstrumentation(), mActivityRule.getActivity()); Timeout.setSmallTimeout(500); Timeout.setLargeTimeout(1000); - context = getInstrumentation().getTargetContext(); - res = getActivity().getResources(); - UserPreferences.init(context); + res = mActivityRule.getActivity().getResources(); + UserPreferences.init(mActivityRule.getActivity()); + + prefs = PreferenceManager.getDefaultSharedPreferences(mActivityRule.getActivity()); + prefs.edit().clear(); + prefs.edit().putBoolean(UserPreferences.PREF_ENABLE_AUTODL, true).commit(); } - @Override - public void tearDown() throws Exception { + @After + public void tearDown() { solo.finishOpenedActivities(); - super.tearDown(); + prefs.edit().clear(); } + @Test public void testSwitchTheme() { final int theme = UserPreferences.getTheme(); int otherTheme; @@ -55,13 +76,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - solo.clickOnText(solo.getString(R.string.user_interface_label)); - solo.clickOnText(solo.getString(R.string.pref_set_theme_title)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(otherTheme)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_set_theme_title)); + onView(withText(otherTheme)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout())); } + @Test public void testSwitchThemeBack() { final int theme = UserPreferences.getTheme(); int otherTheme; @@ -70,33 +91,23 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - solo.clickOnText(solo.getString(R.string.user_interface_label)); - solo.clickOnText(solo.getString(R.string.pref_set_theme_title)); - solo.waitForDialogToOpen(1000); - solo.clickOnText(solo.getString(otherTheme)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_set_theme_title)); + onView(withText(otherTheme)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout())); } - public void testExpandNotification() { - solo.clickOnText(solo.getString(R.string.user_interface_label)); - final int priority = UserPreferences.getNotifyPriority(); - solo.clickOnText(solo.getString(R.string.pref_expandNotify_title)); - assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_expandNotify_title)); - assertTrue(solo.waitForCondition(() -> priority == UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout())); - } - + @Test public void testEnablePersistentPlaybackControls() { - solo.clickOnText(solo.getString(R.string.user_interface_label)); final boolean persistNotify = UserPreferences.isPersistNotify(); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_persistNotify_title)); + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_persistNotify_title)); assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_persistNotify_title)); + clickPreference(withText(R.string.pref_persistNotify_title)); assertTrue(solo.waitForCondition(() -> persistNotify == UserPreferences.isPersistNotify(), Timeout.getLargeTimeout())); } + @Test public void testSetLockscreenButtons() { solo.clickOnText(solo.getString(R.string.user_interface_label)); solo.scrollDown(); @@ -123,6 +134,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout())); } + @Test public void testEnqueueAtFront() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean enqueueAtFront = UserPreferences.enqueueAtFront(); @@ -134,6 +146,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> enqueueAtFront == UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout())); } + @Test public void testHeadPhonesDisconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect(); @@ -143,6 +156,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect == UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout())); } + @Test public void testHeadPhonesReconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); if(UserPreferences.isPauseOnHeadsetDisconnect() == false) { @@ -156,6 +170,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> unpauseOnHeadsetReconnect == UserPreferences.isUnpauseOnHeadsetReconnect(), Timeout.getLargeTimeout())); } + @Test public void testBluetoothReconnect() { solo.clickOnText(solo.getString(R.string.playback_pref)); if(UserPreferences.isPauseOnHeadsetDisconnect() == false) { @@ -169,6 +184,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> unpauseOnBluetoothReconnect == UserPreferences.isUnpauseOnBluetoothReconnect(), Timeout.getLargeTimeout())); } + @Test public void testContinuousPlayback() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean continuousPlayback = UserPreferences.isFollowQueue(); @@ -180,6 +196,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> continuousPlayback == UserPreferences.isFollowQueue(), Timeout.getLargeTimeout())); } + @Test public void testAutoDelete() { solo.clickOnText(solo.getString(R.string.storage_pref)); final boolean autoDelete = UserPreferences.isAutoDelete(); @@ -189,17 +206,15 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> autoDelete == UserPreferences.isAutoDelete(), Timeout.getLargeTimeout())); } + @Test public void testPlaybackSpeeds() { - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_playback_speed_title)); - solo.waitForDialogToOpen(1000); + clickPreference(withText(R.string.playback_pref)); + clickPreference(withText(R.string.pref_playback_speed_title)); assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0])); - solo.clickOnText(solo.getString(R.string.cancel_label)); - solo.waitForDialogToClose(1000); + onView(withText(R.string.cancel_label)).perform(click()); } + @Test public void testPauseForInterruptions() { solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss(); @@ -209,6 +224,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> pauseForFocusLoss == UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout())); } + @Test public void testDisableUpdateInterval() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum)); @@ -217,31 +233,31 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == 0, 1000)); } + @Test public void testSetUpdateInterval() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title)); - solo.waitForDialogToOpen(); - solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); - solo.waitForDialogToOpen(); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_autoUpdateIntervallOrTime_title)); + onView(withText(R.string.pref_autoUpdateIntervallOrTime_Interval)).perform(click()); String search = "12 " + solo.getString(R.string.pref_update_interval_hours_plural); - solo.clickOnText(search); - solo.waitForDialogToClose(); + onView(withText(search)).perform(click()); assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == TimeUnit.HOURS.toMillis(12), Timeout.getLargeTimeout())); } + @Test public void testMobileUpdates() { - solo.clickOnText(solo.getString(R.string.network_pref)); + clickPreference(withText(R.string.network_pref)); final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate(); - solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title)); + clickPreference(withText(R.string.pref_mobileUpdate_title)); assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout())); - solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title)); + clickPreference(withText(R.string.pref_mobileUpdate_title)); assertTrue(solo.waitForCondition(() -> mobileUpdates == UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout())); } + @Test public void testSetSequentialDownload() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "1"); @@ -249,9 +265,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 1, Timeout.getLargeTimeout())); } + @Test public void testSetParallelDownloads() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "10"); @@ -259,50 +276,50 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 10, Timeout.getLargeTimeout())); } + @Test public void testSetParallelDownloadsInvalidInput() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_parallel_downloads_title)); solo.waitForDialogToOpen(); solo.clearEditText(0); solo.enterText(0, "0"); - assertEquals("1", solo.getEditText(0).getText().toString()); + assertEquals("", solo.getEditText(0).getText().toString()); solo.clearEditText(0); solo.enterText(0, "100"); - assertEquals("50", solo.getEditText(0).getText().toString()); + assertEquals("", solo.getEditText(0).getText().toString()); } + @Test public void testSetEpisodeCache() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); String entry = entries[entries.length/2]; final int value = Integer.valueOf(values[values.length/2]); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(); solo.clickOnText(entry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == value, Timeout.getLargeTimeout())); } + @Test public void testSetEpisodeCacheMin() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); String minEntry = entries[0]; final int minValue = Integer.valueOf(values[0]); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - if(!UserPreferences.isEnableAutodownload()) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - } - solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); + + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(1000); solo.scrollUp(); solo.clickOnText(minEntry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == minValue, Timeout.getLargeTimeout())); } + @Test public void testSetEpisodeCacheMax() { String[] entries = res.getStringArray(R.array.episode_cache_size_entries); String[] values = res.getStringArray(R.array.episode_cache_size_values); @@ -311,24 +328,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - if(!UserPreferences.isEnableAutodownload()) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - } solo.clickOnText(solo.getString(R.string.pref_episode_cache_title)); solo.waitForDialogToOpen(); solo.clickOnText(maxEntry); assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == maxValue, Timeout.getLargeTimeout())); } + @Test public void testAutomaticDownload() { final boolean automaticDownload = UserPreferences.isEnableAutodownload(); - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.waitForText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_automatic_download_title)); + assertTrue(solo.waitForCondition(() -> automaticDownload != UserPreferences.isEnableAutodownload(), Timeout.getLargeTimeout())); if(UserPreferences.isEnableAutodownload() == false) { - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_automatic_download_title)); } assertTrue(solo.waitForCondition(() -> UserPreferences.isEnableAutodownload() == true, Timeout.getLargeTimeout())); final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery(); @@ -343,6 +358,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> enableWifiFilter == UserPreferences.isEnableAutodownloadWifiFilter(), Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupQueueOnly() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -356,6 +372,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupNeverAlg() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -369,6 +386,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupClassic() { solo.clickOnText(solo.getString(R.string.network_pref)); solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); @@ -386,12 +404,14 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupNumDays() { - solo.clickOnText(solo.getString(R.string.network_pref)); - solo.clickOnText(solo.getString(R.string.pref_automatic_download_title)); - solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title)); - solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening)); - solo.clickOnText("5"); + clickPreference(withText(R.string.network_pref)); + clickPreference(withText(R.string.pref_automatic_download_title)); + clickPreference(withText(R.string.pref_episode_cleanup_title)); + solo.waitForDialogToOpen(); + String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 5, 5); + onView(withText(search)).perform(click()); assertTrue(solo.waitForCondition(() -> { EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm(); if (alg instanceof APCleanupAlgorithm) { @@ -403,15 +423,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } - + @Test public void testRewindChange() { int seconds = UserPreferences.getRewindSecs(); int deltas[] = res.getIntArray(R.array.seek_delta_values); - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); - solo.clickOnText(solo.getString(R.string.pref_rewind)); + clickPreference(withText(R.string.playback_pref)); + clickPreference(withText(R.string.pref_rewind)); solo.waitForDialogToOpen(); int currentIndex = Arrays.binarySearch(deltas, seconds); @@ -419,24 +437,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference // Find next value (wrapping around to next) int newIndex = (currentIndex + 1) % deltas.length; - - solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); - solo.clickOnButton("Confirm"); + onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click()); + onView(withText("Confirm")).perform(click()); solo.waitForDialogToClose(); assertTrue(solo.waitForCondition(() -> UserPreferences.getRewindSecs() == deltas[newIndex], Timeout.getLargeTimeout())); } + @Test public void testFastForwardChange() { - solo.clickOnText(solo.getString(R.string.playback_pref)); - solo.scrollDown(); - solo.scrollDown(); + clickPreference(withText(R.string.playback_pref)); for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind int seconds = UserPreferences.getFastForwardSecs(); int deltas[] = res.getIntArray(R.array.seek_delta_values); - solo.clickOnText(solo.getString(R.string.pref_fast_forward)); + clickPreference(withText(R.string.pref_fast_forward)); solo.waitForDialogToOpen(); int currentIndex = Arrays.binarySearch(deltas, seconds); @@ -445,12 +461,52 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference // Find next value (wrapping around to next) int newIndex = (currentIndex + 1) % deltas.length; - solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); - solo.clickOnButton("Confirm"); + onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click()); + onView(withText("Confirm")).perform(click()); solo.waitForDialogToClose(); assertTrue(solo.waitForCondition(() -> UserPreferences.getFastForwardSecs() == deltas[newIndex], Timeout.getLargeTimeout())); } } + + @Test + public void testBackButtonBehaviorGoToPageSelector() { + clickPreference(withText(R.string.user_interface_label)); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.queue_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(QueueFragment.TAG), + Timeout.getLargeTimeout())); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.episodes_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(EpisodesFragment.TAG), + Timeout.getLargeTimeout())); + clickPreference(withText(R.string.pref_back_button_behavior_title)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.back_button_go_to_page)); + solo.waitForDialogToOpen(); + solo.clickOnText(solo.getString(R.string.subscriptions_label)); + solo.clickOnText(solo.getString(R.string.confirm_label)); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE, + Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(SubscriptionFragment.TAG), + Timeout.getLargeTimeout())); + } + + private void clickPreference(Matcher<View> matcher) { + onView(withId(R.id.list)) + .perform(RecyclerViewActions.actionOnItem(hasDescendant(matcher), click())); + } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9bb89d02a..cff85e905 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.danoeh.antennapod" android:installLocation="auto" - android:versionCode="1070000" - android:versionName="1.7.0"> + android:versionCode="1070195" + android:versionName="1.7.1"> <!-- Version code schema: "1.2.3-SNAPSHOT" -> 1020300 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 f506921d2..5595aeac4 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java @@ -27,6 +27,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.Toast; import com.bumptech.glide.Glide; @@ -123,6 +124,8 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi private Subscription subscription; + private long lastBackButtonPressTime = 0; + @Override public void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getNoTitleTheme()); @@ -643,10 +646,40 @@ public class MainActivity extends CastEnabledActivity implements NavDrawerActivi @Override public void onBackPressed() { - if(isDrawerOpen()) { + if (isDrawerOpen()) { drawerLayout.closeDrawer(navDrawer); - } else { + } else if (getSupportFragmentManager().getBackStackEntryCount() != 0) { super.onBackPressed(); + } else { + switch (UserPreferences.getBackButtonBehavior()) { + case OPEN_DRAWER: + drawerLayout.openDrawer(navDrawer); + break; + case SHOW_PROMPT: + new AlertDialog.Builder(this) + .setMessage(R.string.close_prompt) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> MainActivity.super.onBackPressed()) + .setNegativeButton(R.string.no, null) + .setCancelable(false) + .show(); + break; + case DOUBLE_TAP: + if (lastBackButtonPressTime < System.currentTimeMillis() - 2000) { + Toast.makeText(this, R.string.double_tap_toast, Toast.LENGTH_SHORT).show(); + lastBackButtonPressTime = System.currentTimeMillis(); + } else { + super.onBackPressed(); + } + break; + case GO_TO_PAGE: + if (getLastNavFragment().equals(UserPreferences.getBackButtonGoToPage())) { + super.onBackPressed(); + } else { + loadFragment(UserPreferences.getBackButtonGoToPage(), null); + } + break; + default: super.onBackPressed(); + } } } diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java index 18116420d..fee03a3f6 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/AllEpisodesRecycleAdapter.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.adapter; import android.os.Build; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; @@ -52,7 +53,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR private final ActionButtonUtils actionButtonUtils; private final boolean showOnlyNewEpisodes; - private int position = -1; + private FeedItem selectedItem; private final int playingBackGroundColor; private final int normalBackGroundColor; @@ -108,7 +109,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR final FeedItem item = itemAccess.getItem(position); if (item == null) return; holder.itemView.setOnLongClickListener(v -> { - this.position = holder.getAdapterPosition(); + this.selectedItem = item; return false; }); holder.item = item; @@ -202,6 +203,11 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR .into(new CoverTarget(item.getFeed().getImageLocation(), holder.placeholder, holder.cover, mainActivityRef.get())); } + @Nullable + public FeedItem getSelectedItem() { + return selectedItem; + } + @Override public long getItemId(int position) { FeedItem item = itemAccess.getItem(position); @@ -213,16 +219,6 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR return itemAccess.getCount(); } - public FeedItem getItem(int position) { - return itemAccess.getItem(position); - } - - public int getPosition() { - int pos = position; - position = -1; // reset - return pos; - } - private final View.OnClickListener secondaryActionListener = new View.OnClickListener() { @Override public void onClick(View v) { 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 ff7af97f6..eeec9ff49 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -275,14 +275,10 @@ public class AllEpisodesFragment extends Fragment { if(item.getItemId() == R.id.share_item) { return true; // avoids that the position is reset when we need it in the submenu } - int pos = listAdapter.getPosition(); - if(pos < 0) { - return false; - } - FeedItem selectedItem = itemAccess.getItem(pos); + FeedItem selectedItem = listAdapter.getSelectedItem(); if (selectedItem == null) { - Log.i(TAG, "Selected item at position " + pos + " was null, ignoring selection"); + Log.i(TAG, "Selected item was null, ignoring selection"); return super.onContextItemSelected(item); } diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java index 1d93afad9..a9a82d749 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -227,6 +227,30 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc return true; }); + ui.findPreference(UserPreferences.PREF_BACK_BUTTON_BEHAVIOR) + .setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue.equals("page")) { + final Context context = ui.getActivity(); + final String[] navTitles = context.getResources().getStringArray(R.array.back_button_go_to_pages); + final String[] navTags = context.getResources().getStringArray(R.array.back_button_go_to_pages_tags); + final String choice[] = { UserPreferences.getBackButtonGoToPage() }; + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.back_button_go_to_page_title); + builder.setSingleChoiceItems(navTitles, ArrayUtils.indexOf(navTags, UserPreferences.getBackButtonGoToPage()), (dialogInterface, i) -> { + if (i >= 0) { + choice[0] = navTags[i]; + } + }); + builder.setPositiveButton(R.string.confirm_label, (dialogInterface, i) -> UserPreferences.setBackButtonGoToPage(choice[0])); + builder.setNegativeButton(R.string.cancel_label, null); + builder.create().show(); + return true; + } else { + return true; + } + }); + if (Build.VERSION.SDK_INT >= 26) { ui.findPreference(UserPreferences.PREF_EXPANDED_NOTIFICATION).setVisible(false); } diff --git a/app/src/main/res/layout/all_episodes_fragment.xml b/app/src/main/res/layout/all_episodes_fragment.xml index 7dd447bb2..89f900a1f 100644 --- a/app/src/main/res/layout/all_episodes_fragment.xml +++ b/app/src/main/res/layout/all_episodes_fragment.xml @@ -10,12 +10,12 @@ android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbarStyle="outsideOverlay" + android:clipToPadding="false" android:paddingTop="@dimen/list_vertical_padding" android:paddingBottom="@dimen/list_vertical_padding" - android:clipToPadding="false" - tools:listitem="@layout/new_episodes_listitem" - tools:itemCount="13"/> + android:scrollbarStyle="outsideOverlay" + tools:itemCount="13" + tools:listitem="@layout/new_episodes_listitem" /> <ProgressBar android:id="@+id/progLoading" diff --git a/app/src/main/res/layout/audio_controls.xml b/app/src/main/res/layout/audio_controls.xml index 852b6e922..f03e4c03f 100644 --- a/app/src/main/res/layout/audio_controls.xml +++ b/app/src/main/res/layout/audio_controls.xml @@ -21,6 +21,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:text="1.00x"/> </LinearLayout> @@ -35,6 +36,7 @@ android:layout_width="32dp" android:layout_height="32dp" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:gravity="center" android:text="-" android:textStyle="bold" @@ -48,6 +50,7 @@ android:layout_height="32dp" android:minWidth="0dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:gravity="center" android:text="+" android:textStyle="bold" @@ -60,7 +63,9 @@ android:layout_width="match_parent" android:layout_height="32dp" android:layout_toRightOf="@id/butDecSpeed" + android:layout_toEndOf="@id/butDecSpeed" android:layout_toLeftOf="@id/butIncSpeed" + android:layout_toStartOf="@id/butIncSpeed" android:layout_centerVertical="true" android:max="40"/> @@ -79,6 +84,7 @@ android:layout_height="wrap_content" android:layout_marginTop="-12dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:orientation="horizontal" android:gravity="center"> @@ -101,6 +107,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:orientation="horizontal" android:gravity="center"> diff --git a/app/src/main/res/layout/authentication_dialog.xml b/app/src/main/res/layout/authentication_dialog.xml index 00e74c9e1..187045c63 100644 --- a/app/src/main/res/layout/authentication_dialog.xml +++ b/app/src/main/res/layout/authentication_dialog.xml @@ -67,8 +67,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -78,8 +80,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> diff --git a/app/src/main/res/layout/directory_chooser.xml b/app/src/main/res/layout/directory_chooser.xml index 14e2f6a38..5b9269607 100644 --- a/app/src/main/res/layout/directory_chooser.xml +++ b/app/src/main/res/layout/directory_chooser.xml @@ -33,8 +33,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -44,8 +46,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> @@ -62,6 +66,7 @@ android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:background="?attr/selectableItemBackground" android:src="?attr/navigation_up" @@ -77,6 +82,7 @@ android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:layout_toRightOf="@id/butNavUp" + android:layout_toEndOf="@id/butNavUp" android:text="@string/selected_folder_label" android:textStyle="bold" tools:background="@android:color/holo_green_dark"> @@ -87,9 +93,11 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvSelectedFolderLabel" android:layout_margin="8dp" android:layout_toRightOf="@id/butNavUp" + android:layout_toEndOf="@id/butNavUp" android:ellipsize="start" android:scrollHorizontally="true" android:singleLine="true" diff --git a/app/src/main/res/layout/download_authentication_activity.xml b/app/src/main/res/layout/download_authentication_activity.xml index f6925dc3a..3414a5e00 100644 --- a/app/src/main/res/layout/download_authentication_activity.xml +++ b/app/src/main/res/layout/download_authentication_activity.xml @@ -77,8 +77,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label"/> @@ -88,8 +90,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label"/> </RelativeLayout> diff --git a/app/src/main/res/layout/downloaded_episodeslist_item.xml b/app/src/main/res/layout/downloaded_episodeslist_item.xml index 770b88c7e..66ae6c180 100644 --- a/app/src/main/res/layout/downloaded_episodeslist_item.xml +++ b/app/src/main/res/layout/downloaded_episodeslist_item.xml @@ -13,6 +13,7 @@ android:layout_gravity="center_vertical" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:contentDescription="@string/cover_label" android:scaleType="centerCrop" @@ -24,7 +25,9 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" @@ -74,6 +77,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/downloadlist_item.xml b/app/src/main/res/layout/downloadlist_item.xml index 97f3ac1a1..668ec817a 100644 --- a/app/src/main/res/layout/downloadlist_item.xml +++ b/app/src/main/res/layout/downloadlist_item.xml @@ -17,6 +17,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:ellipsize="end" android:lines="1" @@ -48,6 +49,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorPrimary" @@ -60,6 +62,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorPrimary" diff --git a/app/src/main/res/layout/downloadlog_item.xml b/app/src/main/res/layout/downloadlog_item.xml index 712dda63e..505102ea4 100644 --- a/app/src/main/res/layout/downloadlog_item.xml +++ b/app/src/main/res/layout/downloadlog_item.xml @@ -17,6 +17,7 @@ android:layout_height="48sp" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:textSize="48sp" android:gravity="center" /> @@ -26,7 +27,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvIcon" android:layout_alignLeft="@id/txtvIcon" + android:layout_alignStart="@id/txtvIcon" android:layout_alignRight="@id/txtvIcon" + android:layout_alignEnd="@id/txtvIcon" android:layout_marginTop="8dp" android:text="{fa-repeat}" tools:text="↻" /> @@ -38,7 +41,9 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" tools:text="Media file" tools:background="@android:color/holo_green_dark" /> @@ -50,8 +55,11 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_toLeftOf="@id/txtvType" + android:layout_toStartOf="@id/txtvType" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" android:minLines="1" android:maxLines="2" @@ -64,8 +72,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_below="@id/txtvTitle" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginBottom="8dp" tools:text="January 23" tools:background="@android:color/holo_green_dark" /> @@ -76,7 +86,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvDate" android:layout_toRightOf="@id/txtvIcon" + android:layout_toEndOf="@id/txtvIcon" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_micro" tools:text="@string/design_time_downloaded_log_failure_reason" diff --git a/app/src/main/res/layout/ellipsize_start_listitem.xml b/app/src/main/res/layout/ellipsize_start_listitem.xml index 4a70ff982..1b6c48152 100644 --- a/app/src/main/res/layout/ellipsize_start_listitem.xml +++ b/app/src/main/res/layout/ellipsize_start_listitem.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:background="@android:color/darker_gray"> + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:background="@android:color/darker_gray"> <TextView android:id="@+id/txtvTitle" - android:textColor="?android:attr/textColorPrimary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="@dimen/text_size_small" - android:singleLine="true" android:layout_margin="16dp" android:ellipsize="start" - tools:text="List item title" - tools:background="@android:color/holo_green_dark"/> + android:singleLine="true" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/text_size_small" + tools:background="@android:color/holo_green_dark" + tools:text="List item title" /> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/feedinfo.xml b/app/src/main/res/layout/feedinfo.xml index bb544d289..50061c4d8 100644 --- a/app/src/main/res/layout/feedinfo.xml +++ b/app/src/main/res/layout/feedinfo.xml @@ -36,7 +36,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="0" app:layout_column="0" @@ -60,6 +62,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="1" app:layout_column="0" @@ -83,6 +86,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" app:layout_row="2" app:layout_column="0" android:lines="1" diff --git a/app/src/main/res/layout/feeditem_fragment.xml b/app/src/main/res/layout/feeditem_fragment.xml index a6ce221db..78c0b3b16 100644 --- a/app/src/main/res/layout/feeditem_fragment.xml +++ b/app/src/main/res/layout/feeditem_fragment.xml @@ -32,6 +32,7 @@ android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:contentDescription="@string/cover_label" android:gravity="center_vertical" @@ -45,6 +46,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/imgvCover" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" tools:text="Podcast title" tools:background="@android:color/holo_green_dark" /> @@ -54,6 +56,7 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvPodcast" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:ellipsize="end" @@ -67,6 +70,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_below="@id/txtvTitle" tools:text="00:42:23" tools:background="@android:color/holo_green_dark"/> @@ -77,8 +81,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvTitle" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -98,7 +104,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:orientation="horizontal" tools:background="@android:color/holo_blue_bright"> @@ -108,6 +116,7 @@ android:layout_height="48dp" android:layout_gravity="center_vertical" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_weight="1" android:background="?attr/selectableItemBackground" android:ellipsize="end" @@ -123,6 +132,7 @@ android:layout_height="48dp" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_weight="1" android:background="?attr/selectableItemBackground" android:ellipsize="end" diff --git a/app/src/main/res/layout/feeditemlist_header.xml b/app/src/main/res/layout/feeditemlist_header.xml index 1478e35d7..e1f451e9e 100644 --- a/app/src/main/res/layout/feeditemlist_header.xml +++ b/app/src/main/res/layout/feeditemlist_header.xml @@ -19,10 +19,12 @@ android:layout_width="@dimen/thumbnail_length_onlinefeedview" android:layout_height="@dimen/thumbnail_length_onlinefeedview" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_centerVertical="true" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:contentDescription="@string/cover_label" tools:src="@drawable/ic_stat_antenna_default" @@ -33,8 +35,10 @@ android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/show_info_label" @@ -62,9 +66,12 @@ android:layout_alignParentTop="true" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_toLeftOf="@id/butShowInfo" + android:layout_toStartOf="@id/butShowInfo" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:maxLines="2" android:shadowColor="@color/black" @@ -80,8 +87,13 @@ android:layout_below="@id/txtvTitle" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" + android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_toLeftOf="@id/butShowSettings" + android:layout_toStartOf="@id/butShowSettings" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:lines="1" android:shadowColor="@color/black" diff --git a/app/src/main/res/layout/feeditemlist_item.xml b/app/src/main/res/layout/feeditemlist_item.xml index 5a2f091ec..adf0748eb 100644 --- a/app/src/main/res/layout/feeditemlist_item.xml +++ b/app/src/main/res/layout/feeditemlist_item.xml @@ -13,6 +13,7 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_weight="1" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" @@ -24,6 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" @@ -36,9 +38,11 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginBottom="4dp" android:layout_toLeftOf="@id/statusUnread" + android:layout_toStartOf="@id/statusUnread" tools:text="Episode title" tools:background="@android:color/holo_green_dark" /> @@ -48,6 +52,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_below="@id/txtvItemname" tools:text="00:42:23" tools:background="@android:color/holo_green_dark" /> @@ -57,8 +62,10 @@ android:layout_width="@dimen/enc_icons_size" android:layout_height="@dimen/enc_icons_size" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:contentDescription="@string/in_queue_label" android:src="?attr/stat_playlist" android:visibility="visible" @@ -71,7 +78,9 @@ android:layout_height="@dimen/enc_icons_size" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/imgvInPlaylist" + android:layout_toStartOf="@id/imgvInPlaylist" tools:ignore="ContentDescription" tools:src="@drawable/ic_hearing_white_18dp" tools:background="@android:color/holo_red_light" /> @@ -83,7 +92,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvItemname" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/imgvType" + android:layout_toStartOf="@id/imgvType" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -92,16 +103,18 @@ style="?android:attr/progressBarStyleHorizontal" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_alignBottom="@id/txtvPublished" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" + android:layout_toStartOf="@id/txtvPublished" android:layout_toLeftOf="@id/txtvPublished" + android:layout_toEndOf="@id/txtvLenSize" android:layout_toRightOf="@id/txtvLenSize" - android:layout_alignTop="@id/txtvPublished" - android:layout_alignBottom="@id/txtvPublished" - tools:background="@android:color/holo_blue_light" + android:layoutDirection="ltr" + android:indeterminate="false" android:max="100" android:progress="42" - android:indeterminate="false" /> + tools:background="@android:color/holo_blue_light" /> </RelativeLayout> diff --git a/app/src/main/res/layout/feedsettings.xml b/app/src/main/res/layout/feedsettings.xml index 23d116d4c..9e5f2245b 100644 --- a/app/src/main/res/layout/feedsettings.xml +++ b/app/src/main/res/layout/feedsettings.xml @@ -39,7 +39,8 @@ app:layout_row="0" app:layout_column="0" app:layout_gravity="center_vertical" - android:layout_marginRight="10dp" /> + android:layout_marginRight="10dp" + android:layout_marginEnd="10dp" /> <Spinner android:layout_width="wrap_content" @@ -97,6 +98,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="0" app:layout_column="0" @@ -119,6 +121,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" app:layout_row="1" app:layout_column="0" diff --git a/app/src/main/res/layout/gpodnet_podcast_listitem.xml b/app/src/main/res/layout/gpodnet_podcast_listitem.xml index bbe8e65d6..27a8bbdca 100644 --- a/app/src/main/res/layout/gpodnet_podcast_listitem.xml +++ b/app/src/main/res/layout/gpodnet_podcast_listitem.xml @@ -15,8 +15,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" android:cropToPadding="true" @@ -30,6 +32,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/txtvTitle" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:orientation="horizontal"> <ImageView @@ -37,6 +40,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="-4dp" + android:layout_marginEnd="-4dp" android:src="?attr/feed" /> <TextView @@ -56,7 +60,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/subscribers_container" + android:layout_toStartOf="@id/subscribers_container" android:layout_alignTop="@id/imgvCover" android:maxLines="2" android:includeFontPadding="false" @@ -69,6 +75,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_below="@id/txtvTitle" android:textSize="14sp" android:textColor="?android:attr/textColorSecondary" diff --git a/app/src/main/res/layout/gpodnet_tag_listitem.xml b/app/src/main/res/layout/gpodnet_tag_listitem.xml index 9e545e59d..a377f9ba1 100644 --- a/app/src/main/res/layout/gpodnet_tag_listitem.xml +++ b/app/src/main/res/layout/gpodnet_tag_listitem.xml @@ -13,6 +13,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:lines="1" @@ -25,7 +26,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" tools:text="301" diff --git a/app/src/main/res/layout/gpodnetauth_credentials.xml b/app/src/main/res/layout/gpodnetauth_credentials.xml index a290b682b..f995ae4cc 100644 --- a/app/src/main/res/layout/gpodnetauth_credentials.xml +++ b/app/src/main/res/layout/gpodnetauth_credentials.xml @@ -59,6 +59,7 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtPassword" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:text="@string/gpodnetauth_login_butLabel" android:layout_margin="8dp"/> @@ -68,7 +69,9 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtPassword" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_toLeftOf="@id/butLogin" + android:layout_toStartOf="@id/butLogin" android:textColor="@color/download_failed_red" android:textSize="@dimen/text_size_small" android:maxLines="2" @@ -84,7 +87,8 @@ android:layout_height="wrap_content" android:visibility="gone" android:layout_alignTop="@+id/butLogin" - android:layout_toLeftOf="@+id/butLogin"/> + android:layout_toLeftOf="@+id/butLogin" + android:layout_toStartOf="@+id/butLogin"/> <TextView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/gpodnetauth_device.xml b/app/src/main/res/layout/gpodnetauth_device.xml index 38455f02c..5840fe955 100644 --- a/app/src/main/res/layout/gpodnetauth_device.xml +++ b/app/src/main/res/layout/gpodnetauth_device.xml @@ -41,7 +41,8 @@ android:textColor="?android:attr/textColorSecondary" android:layout_margin="8dp" android:layout_alignTop="@+id/etxtDeviceID" - android:layout_alignLeft="@+id/etxtCaption"/> + android:layout_alignLeft="@+id/etxtCaption" + android:layout_alignStart="@+id/etxtCaption"/> <EditText android:id="@+id/etxtDeviceID" @@ -49,7 +50,9 @@ android:layout_height="wrap_content" android:layout_below="@id/etxtCaption" android:layout_toRightOf="@id/txtvDeviceID" + android:layout_toEndOf="@id/txtvDeviceID" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_margin="8dp"/> <Button @@ -58,6 +61,7 @@ android:layout_height="wrap_content" android:layout_margin="8dp" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_below="@id/etxtDeviceID" android:text="@string/gpodnetauth_device_butCreateNewDevice"/> @@ -66,8 +70,10 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_below="@id/etxtDeviceID" android:layout_toLeftOf="@id/butCreateNewDevice" + android:layout_toStartOf="@id/butCreateNewDevice" android:textColor="@color/download_failed_red" android:layout_margin="16dp" android:textSize="@dimen/text_size_small" @@ -80,6 +86,7 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/butCreateNewDevice" android:layout_toLeftOf="@id/butCreateNewDevice" + android:layout_toStartOf="@id/butCreateNewDevice" android:textColor="@color/download_failed_red" android:textSize="@dimen/text_size_medium" android:visibility="gone" @@ -102,7 +109,9 @@ android:text="@string/gpodnetauth_device_butChoose" android:layout_below="@+id/spinnerChooseDevice" android:layout_alignLeft="@+id/butCreateNewDevice" - android:layout_alignRight="@+id/butCreateNewDevice"/> + android:layout_alignStart="@+id/butCreateNewDevice" + android:layout_alignRight="@+id/butCreateNewDevice" + android:layout_alignEnd="@+id/butCreateNewDevice"/> <Spinner android:id="@+id/spinnerChooseDevice" @@ -110,7 +119,9 @@ android:layout_height="wrap_content" android:layout_below="@id/txtvChooseExistingDevice" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_margin="8dp" - android:layout_alignParentRight="true"/> + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"/> </RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/itemdescription_listitem.xml b/app/src/main/res/layout/itemdescription_listitem.xml index 51bc9a5eb..9d03e30a3 100644 --- a/app/src/main/res/layout/itemdescription_listitem.xml +++ b/app/src/main/res/layout/itemdescription_listitem.xml @@ -17,8 +17,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:textSize="14sp" android:textColor="?android:textColorSecondary" android:ellipsize="end" @@ -31,8 +33,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/txtvPubDate" + android:layout_toStartOf="@id/txtvPubDate" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary" android:ellipsize="end" diff --git a/app/src/main/res/layout/itunes_podcast_listitem.xml b/app/src/main/res/layout/itunes_podcast_listitem.xml index 1e6e5a836..4848563b1 100644 --- a/app/src/main/res/layout/itunes_podcast_listitem.xml +++ b/app/src/main/res/layout/itunes_podcast_listitem.xml @@ -16,8 +16,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" android:cropToPadding="true" @@ -29,6 +31,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_centerVertical="true" android:orientation="vertical"> diff --git a/app/src/main/res/layout/mediaplayerinfo_activity.xml b/app/src/main/res/layout/mediaplayerinfo_activity.xml index 21c4940b5..c9e93e149 100644 --- a/app/src/main/res/layout/mediaplayerinfo_activity.xml +++ b/app/src/main/res/layout/mediaplayerinfo_activity.xml @@ -47,6 +47,7 @@ android:paddingTop="8dp" android:layout_alignParentBottom="true" android:background="?attr/overlay_drawable" + android:layoutDirection="ltr" android:orientation="vertical"> @@ -59,8 +60,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:text="@string/position_default_label" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_micro" @@ -71,8 +74,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:text="@string/position_default_label" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_micro" @@ -84,9 +89,13 @@ android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_toLeftOf="@id/txtvLength" + android:layout_toStartOf="@id/txtvLength" android:layout_toRightOf="@id/txtvPosition" + android:layout_toEndOf="@id/txtvPosition" android:max="500" tools:background="@android:color/holo_green_dark" /> @@ -106,7 +115,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_centerHorizontal="true" android:background="?attr/selectableItemBackground" android:contentDescription="@string/pause_label" @@ -120,7 +131,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butPlay" + android:layout_toStartOf="@id/butPlay" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/rewind_label" android:src="?attr/av_rew_big" @@ -134,7 +147,9 @@ android:layout_height="wrap_content" android:layout_below="@id/butRev" android:layout_alignLeft="@id/butRev" + android:layout_alignStart="@id/butRev" android:layout_alignRight="@id/butRev" + android:layout_alignEnd="@id/butRev" android:layout_marginTop="-8dp" android:gravity="center" android:text="30" @@ -147,6 +162,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butRev" + android:layout_toStartOf="@id/butRev" android:background="?attr/selectableItemBackground" android:contentDescription="@string/set_playback_speed_label" android:src="?attr/av_fast_forward" @@ -161,6 +177,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toLeftOf="@id/butRev" + android:layout_toStartOf="@id/butRev" android:background="?attr/selectableItemBackground" android:contentDescription="@string/cast_disconnect_label" android:src="?attr/ic_cast_disconnect" @@ -175,7 +192,9 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toRightOf="@id/butPlay" + android:layout_toEndOf="@id/butPlay" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/fast_forward_label" android:src="?attr/av_ff_big" @@ -189,7 +208,9 @@ android:layout_height="wrap_content" android:layout_below="@id/butFF" android:layout_alignLeft="@id/butFF" + android:layout_alignStart="@id/butFF" android:layout_alignRight="@id/butFF" + android:layout_alignEnd="@id/butFF" android:layout_marginTop="-8dp" android:gravity="center" android:text="30" @@ -202,6 +223,7 @@ android:layout_width="@dimen/audioplayer_playercontrols_length" android:layout_height="@dimen/audioplayer_playercontrols_length" android:layout_toRightOf="@id/butFF" + android:layout_toEndOf="@id/butFF" android:background="?attr/selectableItemBackground" android:scaleType="fitCenter" android:src="?attr/av_skip_big" diff --git a/app/src/main/res/layout/nav_feedlistitem.xml b/app/src/main/res/layout/nav_feedlistitem.xml index 18b5255aa..9f19157fc 100644 --- a/app/src/main/res/layout/nav_feedlistitem.xml +++ b/app/src/main/res/layout/nav_feedlistitem.xml @@ -5,7 +5,6 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="@dimen/listitem_iconwithtext_height" - android:paddingRight="@dimen/listitem_threeline_verticalpadding" tools:background="@android:color/darker_gray"> <ImageView @@ -14,6 +13,7 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" @@ -21,6 +21,7 @@ android:layout_marginTop="4dp" android:layout_marginBottom="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" tools:src="@drawable/ic_stat_antenna_default" tools:background="@android:color/holo_green_dark"/> @@ -29,10 +30,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" + android:layout_marginRight="@dimen/listitem_icon_rightpadding" + android:layout_marginEnd="@dimen/listitem_icon_rightpadding" android:lines="1" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> @@ -42,7 +47,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/txtvCount" + android:layout_toStartOf="@id/txtvCount" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" android:layout_alignWithParentIfMissing="true" android:lines="1" android:text="{fa-exclamation-circle}" @@ -63,8 +70,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/itxtvFailure" + android:layout_toStartOf="@id/itxtvFailure" android:layout_alignWithParentIfMissing="true" tools:text="Navigation feed item title" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/nav_list.xml b/app/src/main/res/layout/nav_list.xml index e2fe61e28..2d044f548 100644 --- a/app/src/main/res/layout/nav_list.xml +++ b/app/src/main/res/layout/nav_list.xml @@ -24,6 +24,7 @@ android:layout_height="@dimen/thumbnail_length_navlist" android:layout_marginBottom="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" android:layout_marginTop="4dp" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" @@ -39,6 +40,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_weight="1" android:gravity="center_vertical" android:text="@string/settings_label" diff --git a/app/src/main/res/layout/nav_listitem.xml b/app/src/main/res/layout/nav_listitem.xml index d62672c34..c140533e6 100644 --- a/app/src/main/res/layout/nav_listitem.xml +++ b/app/src/main/res/layout/nav_listitem.xml @@ -13,12 +13,14 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" android:scaleType="centerInside" android:padding="4dp" android:layout_marginLeft="@dimen/listitem_icon_leftpadding" + android:layout_marginStart="@dimen/listitem_icon_leftpadding" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" tools:src="@drawable/ic_new_releases_white_24dp" @@ -36,8 +38,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_marginRight="48dp" + android:layout_marginEnd="48dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" tools:text="Navigation item title" tools:background="@android:color/holo_green_dark" /> @@ -50,8 +55,11 @@ android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_marginLeft="12dp" + android:layout_marginStart="12dp" android:layout_marginRight="@dimen/listitem_icon_rightpadding" + android:layout_marginEnd="@dimen/listitem_icon_rightpadding" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/new_episodes_listitem.xml b/app/src/main/res/layout/new_episodes_listitem.xml index 5e0d7451b..150d692e7 100644 --- a/app/src/main/res/layout/new_episodes_listitem.xml +++ b/app/src/main/res/layout/new_episodes_listitem.xml @@ -26,6 +26,7 @@ android:layout_gravity="center_vertical" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:background="@color/light_gray" android:ellipsize="end" @@ -37,8 +38,10 @@ android:layout_height="64dp" android:layout_width="64dp" android:layout_alignLeft="@id/txtvPlaceholder" + android:layout_alignStart="@id/txtvPlaceholder" android:layout_alignTop="@id/txtvPlaceholder" android:layout_alignRight="@id/txtvPlaceholder" + android:layout_alignEnd="@id/txtvPlaceholder" android:layout_alignBottom="@id/txtvPlaceholder" android:contentDescription="@string/cover_label" tools:src="@tools:sample/avatars" /> @@ -50,7 +53,9 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1"> @@ -61,8 +66,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" tools:text="@sample/episodes.json/data/status_label"/> <TextView @@ -71,8 +78,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/statusUnread" + android:layout_toStartOf="@id/statusUnread" tools:text="@sample/episodes.json/data/title" /> <RelativeLayout @@ -82,7 +91,9 @@ android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:layout_alignParentRight="true"> + android:layout_alignParentStart="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"> <TextView android:id="@+id/txtvDuration" @@ -90,6 +101,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" tools:text="@sample/episodes.json/data/duration" /> <ImageView @@ -97,7 +109,9 @@ android:layout_width="@dimen/enc_icons_size" android:layout_height="@dimen/enc_icons_size" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:contentDescription="@string/in_queue_label" android:src="?attr/stat_playlist" tools:src="@sample/inplaylist" /> @@ -109,6 +123,7 @@ android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/imgvInPlaylist" + android:layout_toStartOf="@id/imgvInPlaylist" android:ellipsize="end" tools:text="@sample/episodes.json/data/published_at" /> diff --git a/app/src/main/res/layout/onlinefeedview_header.xml b/app/src/main/res/layout/onlinefeedview_header.xml index 491d955fb..4217322e4 100644 --- a/app/src/main/res/layout/onlinefeedview_header.xml +++ b/app/src/main/res/layout/onlinefeedview_header.xml @@ -10,6 +10,7 @@ android:layout_width="@dimen/thumbnail_length_onlinefeedview" android:layout_height="@dimen/thumbnail_length_onlinefeedview" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" @@ -24,10 +25,13 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginBottom="8dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginTop="16dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:gravity="center_vertical" android:maxLines="2" @@ -41,7 +45,9 @@ android:layout_below="@id/txtvTitle" android:layout_marginBottom="8dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:ellipsize="end" android:lines="1" android:textColor="?android:attr/textColorSecondary" @@ -61,7 +67,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:layout_marginTop="8dp" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/text_size_micro" /> @@ -80,7 +88,9 @@ android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" android:layout_marginRight="16dp" + android:layout_marginEnd="16dp" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/text_size_small" tools:text="@string/design_time_lorem_ipsum" diff --git a/app/src/main/res/layout/opml_selection.xml b/app/src/main/res/layout/opml_selection.xml index 3133debd1..f8f37b5ac 100644 --- a/app/src/main/res/layout/opml_selection.xml +++ b/app/src/main/res/layout/opml_selection.xml @@ -32,8 +32,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/horizontal_divider" + android:layout_toStartOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/cancel_label" /> @@ -43,8 +45,10 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_toRightOf="@id/horizontal_divider" + android:layout_toEndOf="@id/horizontal_divider" android:background="?android:attr/selectableItemBackground" android:text="@string/confirm_label" /> </RelativeLayout> diff --git a/app/src/main/res/layout/queue_listitem.xml b/app/src/main/res/layout/queue_listitem.xml index 7d18b386d..6b41b68d5 100644 --- a/app/src/main/res/layout/queue_listitem.xml +++ b/app/src/main/res/layout/queue_listitem.xml @@ -60,7 +60,9 @@ android:layout_height="wrap_content" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_textleftpadding" + android:layout_marginStart="@dimen/listitem_threeline_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_textrightpadding" + android:layout_marginEnd="@dimen/listitem_threeline_textrightpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" tools:background="@android:color/holo_red_dark"> @@ -73,9 +75,11 @@ android:layout_height="wrap_content" android:lines="2" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginLeft="8dp" - android:gravity="right|top" + android:layout_marginStart="8dp" + android:gravity="end|top" android:text="Feb\n12" tools:background="@android:color/holo_blue_light" /> @@ -85,7 +89,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/txtvPubDate" + android:layout_toStartOf="@id/txtvPubDate" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:text="Queue item title" android:ellipsize="end" @@ -98,7 +104,9 @@ android:layout_below="@id/txtvTitle" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" - android:layout_alignParentRight="true"> + android:layout_alignParentStart="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"> <TextView android:id="@+id/txtvProgressLeft" @@ -106,6 +114,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_marginBottom="0dp" android:text="00:42:23" tools:background="@android:color/holo_blue_light"/> @@ -116,6 +125,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_marginBottom="0dp" tools:text="Jan 23" tools:background="@android:color/holo_green_dark" /> @@ -126,6 +136,7 @@ android:layout_width="match_parent" android:layout_height="4dp" android:layout_below="@id/txtvProgressLeft" + android:layoutDirection="ltr" android:max="100" tools:background="@android:color/holo_blue_light" /> diff --git a/app/src/main/res/layout/searchlist_item.xml b/app/src/main/res/layout/searchlist_item.xml index 83ba39cd5..50374c737 100644 --- a/app/src/main/res/layout/searchlist_item.xml +++ b/app/src/main/res/layout/searchlist_item.xml @@ -12,8 +12,10 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:contentDescription="@string/cover_label" android:scaleType="centerCrop" tools:src="@drawable/ic_stat_antenna_default" @@ -23,8 +25,11 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_marginRight="@dimen/listitem_threeline_verticalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_verticalpadding" android:layout_toRightOf="@id/imgvFeedimage" + android:layout_toEndOf="@id/imgvFeedimage" android:orientation="vertical" tools:background="@android:color/holo_red_dark"> diff --git a/app/src/main/res/layout/simplechapter_item.xml b/app/src/main/res/layout/simplechapter_item.xml index 28cdb08c3..0d02eac1a 100644 --- a/app/src/main/res/layout/simplechapter_item.xml +++ b/app/src/main/res/layout/simplechapter_item.xml @@ -13,6 +13,7 @@ android:layout_height="match_parent" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:gravity="center_vertical" tools:text="Start" tools:background="@android:color/holo_green_dark" /> @@ -22,7 +23,9 @@ android:layout_height="match_parent" android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginStart="@dimen/listitem_threeline_horizontalpadding" android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" + android:layout_marginEnd="@dimen/listitem_threeline_horizontalpadding" android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:layout_weight="1" android:gravity="center_vertical" diff --git a/app/src/main/res/layout/statistics_listitem.xml b/app/src/main/res/layout/statistics_listitem.xml index 20e01bf32..b186add9e 100644 --- a/app/src/main/res/layout/statistics_listitem.xml +++ b/app/src/main/res/layout/statistics_listitem.xml @@ -4,7 +4,10 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="@dimen/listitem_iconwithtext_height" + android:paddingLeft="@dimen/listitem_threeline_verticalpadding" + android:paddingStart="@dimen/listitem_threeline_verticalpadding" android:paddingRight="@dimen/listitem_threeline_verticalpadding" + android:paddingEnd="@dimen/listitem_threeline_verticalpadding" tools:background="@android:color/darker_gray"> <ImageView @@ -13,13 +16,13 @@ android:layout_width="@dimen/thumbnail_length_navlist" android:layout_height="@dimen/thumbnail_length_navlist" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_centerVertical="true" android:adjustViewBounds="true" android:cropToPadding="true" android:scaleType="centerCrop" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" - android:layout_marginLeft="@dimen/listitem_icon_leftpadding" tools:src="@drawable/ic_stat_antenna_default" tools:background="@android:color/holo_green_dark"/> @@ -28,10 +31,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/list_vertical_padding" + android:layout_marginStart="@dimen/list_vertical_padding" android:lines="1" android:textColor="?android:attr/textColorTertiary" android:textSize="@dimen/text_size_navdrawer" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_centerVertical="true" tools:text="23" tools:background="@android:color/holo_green_dark"/> @@ -47,8 +52,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/listitem_iconwithtext_textleftpadding" + android:layout_marginStart="@dimen/listitem_iconwithtext_textleftpadding" android:layout_toRightOf="@id/imgvCover" + android:layout_toEndOf="@id/imgvCover" android:layout_toLeftOf="@id/txtvTime" + android:layout_toStartOf="@id/txtvTime" android:layout_alignWithParentIfMissing="true" tools:text="Navigation feed item title" tools:background="@android:color/holo_green_dark"/> diff --git a/app/src/main/res/layout/videoplayer_activity.xml b/app/src/main/res/layout/videoplayer_activity.xml index 10fbf8f49..ebea0c618 100644 --- a/app/src/main/res/layout/videoplayer_activity.xml +++ b/app/src/main/res/layout/videoplayer_activity.xml @@ -25,6 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:layoutDirection="ltr" android:orientation="horizontal"> <ImageButton @@ -68,6 +69,7 @@ android:layout_width="match_parent" android:layout_height="50dp" android:background="#80000000" + android:layoutDirection="ltr" android:paddingTop="8dp"> <TextView @@ -75,10 +77,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginTop="4dp" android:text="@string/position_default_label" android:textColor="@color/white" @@ -89,10 +94,13 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_marginBottom="8dp" android:layout_marginLeft="8dp" + android:layout_marginStart="8dp" android:layout_marginRight="8dp" + android:layout_marginEnd="8dp" android:layout_marginTop="4dp" android:text="@string/position_default_label" android:textColor="@color/white" @@ -103,7 +111,9 @@ android:layout_width="0px" android:layout_height="wrap_content" android:layout_toLeftOf="@+id/txtvLength" + android:layout_toStartOf="@+id/txtvLength" android:layout_toRightOf="@+id/txtvPosition" + android:layout_toEndOf="@+id/txtvPosition" android:layout_centerInParent="true" android:max="500" /> diff --git a/app/src/main/res/xml/preferences_user_interface.xml b/app/src/main/res/xml/preferences_user_interface.xml index da694b844..1d970a5f7 100644 --- a/app/src/main/res/xml/preferences_user_interface.xml +++ b/app/src/main/res/xml/preferences_user_interface.xml @@ -57,4 +57,14 @@ android:summary="@string/pref_lockscreen_background_sum" android:title="@string/pref_lockscreen_background_title"/> </PreferenceCategory> + <PreferenceCategory android:title="@string/behavior"> + <ListPreference + android:entryValues="@array/back_button_behavior_values" + android:entries="@array/back_button_behavior_options" + android:key="prefBackButtonBehavior" + android:title="@string/pref_back_button_behavior_title" + android:summary="@string/pref_back_button_behavior_sum" + android:defaultValue="default" + app:useStockLayout="true"/> + </PreferenceCategory> </PreferenceScreen> diff --git a/build.gradle b/build.gradle index 790ce4699..144a291df 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ project.ext { minSdkVersion = 14 targetSdkVersion = 26 - supportVersion = "27.1.0" + supportVersion = "27.1.1" awaitilityVersion = "3.1.2" commonsioVersion = "2.5" commonslangVersion = "3.6" diff --git a/contributers.template.py b/contributers.template.py index 3127baa0c..0f4d78698 100755 --- a/contributers.template.py +++ b/contributers.template.py @@ -6,7 +6,15 @@ TRANSIFEX_USER = "" TRANSIFEX_PW = "" print('DEVELOPERS\n==========\n') -p = subprocess.Popen("git log --format='%aN' | sort -fu", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +p = subprocess.Popen("git log --format='%aN' --no-merges " + +"| grep -v '@' " # No email adresses + +"| grep -v 'no.reply' " # no.reply + +"| sed -e 's/^\(Daniel\|daniel oeh\|danieloeh\)$/Daniel Oeh/I'" # Duplicate name + +"| sed -e 's/^keunes$/Koen Glotzbach/'" # Duplicate name + +"| sed -e 's/^H. Lehmann$/ByteHamster/'" # Duplicate name + +"| sed -e 's/^domingos86$/Domingos Lopes/'" # Duplicate name + +"| sed -e 's/^orionlee$/Sam Lee/'" # Duplicate name + +"| sort -fu", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in p.stdout.readlines(): output = line.decode() print(output, end='') @@ -17,6 +25,7 @@ language_codes = { "af": "Afrikaans", "ak_GH": "Akan (Ghana)", "ak": "Akan", + "ast_ES": "Asturian (Spain)", "sq_AL": "Albanian (Albania)", "sq": "Albanian", "am_ET": "Amharic (Ethiopia)", diff --git a/core/build.gradle b/core/build.gradle index 0a6d4c36b..80adefa60 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -10,7 +10,7 @@ android { versionCode 1 versionName "1.0" testApplicationId "de.danoeh.antennapod.core.tests" - testInstrumentationRunner "de.danoeh.antennapod.core.AntennaPodTestRunner" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -83,6 +83,9 @@ dependencies { } testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test:rules:1.0.2' } diff --git a/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java b/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java deleted file mode 100644 index 5d086c054..000000000 --- a/core/src/androidTest/java/de/danoeh/antennapod/core/AntennaPodTestRunner.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.danoeh.antennapod.core; - -import android.test.InstrumentationTestRunner; -import android.test.suitebuilder.TestSuiteBuilder; - -import junit.framework.TestSuite; - -public class AntennaPodTestRunner extends InstrumentationTestRunner { - - @Override - public TestSuite getAllTests() { - return new TestSuiteBuilder(AntennaPodTestRunner.class) - .includeAllPackagesUnderHere() - .build(); - } -}
\ No newline at end of file diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index e6b5f9e1b..c44999c88 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -52,6 +52,8 @@ public class UserPreferences { public static final String PREF_COMPACT_NOTIFICATION_BUTTONS = "prefCompactNotificationButtons"; public static final String PREF_LOCKSCREEN_BACKGROUND = "prefLockscreenBackground"; private static final String PREF_SHOW_DOWNLOAD_REPORT = "prefShowDownloadReport"; + public static final String PREF_BACK_BUTTON_BEHAVIOR = "prefBackButtonBehavior"; + private static final String PREF_BACK_BUTTON_GO_TO_PAGE = "prefBackButtonGoToPage"; // Queue private static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront"; @@ -809,4 +811,29 @@ public class UserPreferences { public enum VideoBackgroundBehavior { STOP, PICTURE_IN_PICTURE, CONTINUE_PLAYING } + + public enum BackButtonBehavior { + DEFAULT, OPEN_DRAWER, DOUBLE_TAP, SHOW_PROMPT, GO_TO_PAGE + } + + public static BackButtonBehavior getBackButtonBehavior() { + switch (prefs.getString(PREF_BACK_BUTTON_BEHAVIOR, "default")) { + case "default": return BackButtonBehavior.DEFAULT; + case "drawer": return BackButtonBehavior.OPEN_DRAWER; + case "doubletap": return BackButtonBehavior.DOUBLE_TAP; + case "prompt": return BackButtonBehavior.SHOW_PROMPT; + case "page": return BackButtonBehavior.GO_TO_PAGE; + default: return BackButtonBehavior.DEFAULT; + } + } + + public static String getBackButtonGoToPage() { + return prefs.getString(PREF_BACK_BUTTON_GO_TO_PAGE, "QueueFragment"); + } + + public static void setBackButtonGoToPage(String tag) { + prefs.edit() + .putString(PREF_BACK_BUTTON_GO_TO_PAGE, tag) + .apply(); + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index ffbe7e7d1..ae1e9de86 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -13,8 +13,6 @@ import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.support.annotation.NonNull; -import android.support.annotation.VisibleForTesting; -import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; @@ -66,7 +64,6 @@ import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.storage.DownloadRequester; -import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.syndication.handler.FeedHandler; import de.danoeh.antennapod.core.syndication.handler.FeedHandlerResult; import de.danoeh.antennapod.core.syndication.handler.UnsupportedFeedtypeException; @@ -251,7 +248,6 @@ public class DownloadService extends Service { public void onCreate() { Log.d(TAG, "Service started"); isRunning = true; - PodDBAdapter.getInstance().open(); // Prevent thrashing the database by opening and closing rapidly handler = new Handler(); reportQueue = Collections.synchronizedList(new ArrayList<>()); downloads = Collections.synchronizedList(new ArrayList<>()); @@ -331,7 +327,6 @@ public class DownloadService extends Service { // start auto download in case anything new has shown up DBTasks.autodownloadUndownloadedItems(getApplicationContext()); - PodDBAdapter.getInstance().close(); } private void setupNotificationBuilders() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index f2be7fbb1..aea043a91 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -1097,7 +1097,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { } else { state = PlaybackStateCompat.STATE_NONE; } - sessionState.setState(state, mediaPlayer.getPosition(), mediaPlayer.getPlaybackSpeed()); + sessionState.setState(state, getCurrentPosition(), getCurrentPlaybackSpeed()); long capabilities = PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD @@ -1637,6 +1637,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { } public float getCurrentPlaybackSpeed() { + if(mediaPlayer == null) { + return 1.0f; + } return mediaPlayer.getPlaybackSpeed(); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 8ebd8eeb5..4566df2fc 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -301,7 +301,6 @@ public class PodDBAdapter { private static Context context; private static volatile SQLiteDatabase db; - private static int counter = 0; public static void init(Context context) { PodDBAdapter.context = context.getApplicationContext(); @@ -321,9 +320,6 @@ public class PodDBAdapter { } public synchronized PodDBAdapter open() { - counter++; - Log.v(TAG, "Opening DB #" + counter); - if (db == null || !db.isOpen() || db.isReadOnly()) { db = openDb(); } @@ -334,7 +330,6 @@ public class PodDBAdapter { SQLiteDatabase newDb; try { newDb = SingletonHolder.dbHelper.getWritableDatabase(); - newDb.enableWriteAheadLogging(); } catch (SQLException ex) { Log.e(TAG, Log.getStackTraceString(ex)); newDb = SingletonHolder.dbHelper.getReadableDatabase(); @@ -343,14 +338,7 @@ public class PodDBAdapter { } public synchronized void close() { - counter--; - Log.v(TAG, "Closing DB #" + counter); - - if (counter == 0) { - Log.v(TAG, "Closing DB, really"); - db.close(); - db = null; - } + // do nothing } public static boolean deleteDatabase() { diff --git a/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml b/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml new file mode 100644 index 000000000..5f58e8421 --- /dev/null +++ b/core/src/main/res/drawable/overlay_drawable_dark_trueblack.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + + <item> + <shape android:shape="rectangle" > + <solid android:color="#45B3E1" /> + </shape> + </item> + <item android:top="1dp"> + <shape android:shape="rectangle" > + <solid android:color="@color/black" /> + </shape> + </item> + +</layer-list>
\ No newline at end of file diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 7e2fed054..12961504c 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -277,4 +277,32 @@ <item>@string/select_all_above</item> <item>@string/select_all_below</item> </string-array> + + <string-array name="back_button_behavior_options"> + <item>@string/back_button_default</item> + <item>@string/back_button_go_to_page</item> + <item>@string/back_button_open_drawer</item> + <item>@string/back_button_double_tap</item> + <item>@string/back_button_show_prompt</item> + </string-array> + + <string-array name="back_button_behavior_values"> + <item>default</item> + <item>page</item> + <item>drawer</item> + <item>doubletap</item> + <item>prompt</item> + </string-array> + + <string-array name="back_button_go_to_pages"> + <item>@string/queue_label</item> + <item>@string/episodes_label</item> + <item>@string/subscriptions_label</item> + </string-array> + + <string-array name="back_button_go_to_pages_tags"> + <item>QueueFragment</item> + <item>EpisodesFragment</item> + <item>SubscriptionFragment</item> + </string-array> </resources> diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index 37ad81639..f172b0f6d 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -31,7 +31,7 @@ <color name="highlight_light">#DDDDDD</color> <color name="highlight_dark">#414141</color> - <color name="highlight_trueblack">#000000</color> + <color name="highlight_trueblack">#414141</color> <color name="antennapod_blue">#147BAF</color> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index ad91ecc76..9dd928311 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -470,6 +470,17 @@ <string name="pref_videoBehavior_sum">Behavior when leaving video playback</string> <string name="stop_playback">Stop playback</string> <string name="continue_playback">Continue audio playback</string> + <string name="behavior">Behavior</string> + <string name="pref_back_button_behavior_title">Back Button Behavior</string> + <string name="pref_back_button_behavior_sum">Change behavior of the back button.</string> + <string name="back_button_default">Default</string> + <string name="back_button_open_drawer">Open navigation drawer</string> + <string name="back_button_double_tap">Double tap to exit</string> + <string name="back_button_show_prompt">Confirm to exit</string> + <string name="close_prompt">Are you sure you want to close AntennaPod?</string> + <string name="double_tap_toast">Tap back button again to exit</string> + <string name="back_button_go_to_page">Go to page…</string> + <string name="back_button_go_to_page_title">Select page</string> <!-- Auto-Flattr dialog --> <string name="auto_flattr_enable">Enable automatic flattring</string> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index 353050066..60296c64f 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -168,13 +168,14 @@ <style name="Theme.Base.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.Dark"> <item name="progressBarTheme">@style/ProgressBarTrueBlack</item> <item type="attr" name="non_transparent_background">@color/black</item> - <item type="attr" name="overlay_background">@color/overlay_dark</item> - <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item> + <item type="attr" name="overlay_background">@color/black</item> + <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> <item type="attr" name="dragview_float_background">@color/black</item> <item type="attr" name="nav_drawer_background">@color/black</item> <item name="android:textColorPrimary">@color/white</item> <item name="android:color">@color/white</item> + <item name="android:colorBackground">@color/black</item> <item name="android:windowBackground">@color/black</item> <item name="android:actionBarStyle">@color/black</item> <item name="colorPrimary">@color/black</item> @@ -350,13 +351,14 @@ <item name="progressBarTheme">@style/ProgressBarTrueBlack</item> <item type="attr" name="non_transparent_background">@color/black</item> <item type="attr" name="overlay_background">@color/black</item> - <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item> + <item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> <item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> <item type="attr" name="dragview_float_background">@color/black</item> <item type="attr" name="nav_drawer_background">@color/black</item> <item type="attr" name="currently_playing_background">@color/highlight_trueblack</item> <item name="android:textColorPrimary">@color/white</item> <item name="android:color">@color/white</item> + <item name="android:colorBackground">@color/black</item> <item name="android:windowBackground">@color/black</item> <item name="android:actionBarStyle">@color/black</item> <item name="colorPrimary">@color/black</item> |