diff --git a/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/BookDownloadManagerTest.java b/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/BookDownloadManagerTest.java index 777af1a..462a1b6 100644 --- a/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/BookDownloadManagerTest.java +++ b/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/BookDownloadManagerTest.java @@ -40,9 +40,12 @@ import static org.mockito.Mockito.when; public class BookDownloadManagerTest extends MBTestCase implements Injector { ObjectGraph mObjectGraph; - @Inject BookDownloadManager bookDownloadManager; - @Inject RefreshManager refreshManager; - @Inject Books installedBooks; + @Inject + BookDownloadManager bookDownloadManager; + @Inject + RefreshManager refreshManager; + @Inject + Books installedBooks; @Override public void inject(Object o) { @@ -56,7 +59,7 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector { } Observable installableBooks() { - return refreshManager.getAvailableModulesFlat() + return refreshManager.getFlatModules() .filter(new Func1() { @Override public Boolean call(Book book) { @@ -121,6 +124,7 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector { Injector i; ConnectivityManager manager; DownloadPrefs prefs; + BookDownloadManagerTestModules(Injector i) { this.i = i; diff --git a/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/RefreshManagerTest.java b/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/RefreshManagerTest.java index eabc467..8fa9a13 100644 --- a/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/RefreshManagerTest.java +++ b/app/src/androidTest/java/org/bspeice/minimalbible/test/activity/downloader/manager/RefreshManagerTest.java @@ -72,7 +72,7 @@ public class RefreshManagerTest extends MBTestCase implements Injector { } public void testGetAvailableModulesFlattened() throws Exception { - rM.getAvailableModulesFlat() + rM.getFlatModules() .toBlocking() .forEach(new Action1() { @Override @@ -134,15 +134,15 @@ public class RefreshManagerTest extends MBTestCase implements Injector { long fourteenDaysAgo = Calendar.getInstance().getTime().getTime() - 1209600; long sixteenDaysAgo = Calendar.getInstance().getTime().getTime() - 1382400; - assertFalse(rM.doReload(true, fourteenDaysAgo, false)); - assertFalse(rM.doReload(true, fourteenDaysAgo, true)); - assertFalse(rM.doReload(true, sixteenDaysAgo, false)); - assertTrue(rM.doReload(true, sixteenDaysAgo, true)); + assertFalse(rM.doReload(true, fourteenDaysAgo, ConnectivityManager.TYPE_DUMMY)); + assertFalse(rM.doReload(true, fourteenDaysAgo, ConnectivityManager.TYPE_WIFI)); + assertFalse(rM.doReload(true, sixteenDaysAgo, ConnectivityManager.TYPE_DUMMY)); + assertTrue(rM.doReload(true, sixteenDaysAgo, ConnectivityManager.TYPE_WIFI)); - assertFalse(rM.doReload(false, fourteenDaysAgo, true)); - assertFalse(rM.doReload(false, fourteenDaysAgo, false)); - assertFalse(rM.doReload(false, sixteenDaysAgo, true)); - assertFalse(rM.doReload(false, sixteenDaysAgo, false)); + assertFalse(rM.doReload(false, fourteenDaysAgo, ConnectivityManager.TYPE_WIFI)); + assertFalse(rM.doReload(false, fourteenDaysAgo, ConnectivityManager.TYPE_DUMMY)); + assertFalse(rM.doReload(false, sixteenDaysAgo, ConnectivityManager.TYPE_WIFI)); + assertFalse(rM.doReload(false, sixteenDaysAgo, ConnectivityManager.TYPE_DUMMY)); } @Module(injects = {RefreshManagerTest.class, RefreshManager.class}) @@ -151,6 +151,7 @@ public class RefreshManagerTest extends MBTestCase implements Injector { Collection installers; ConnectivityManager manager; DownloadPrefs prefs; + RMTModules(Collection installers) { this.installers = installers; diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/BaseFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/BaseFragment.java index 582711a..ea8194a 100644 --- a/app/src/main/java/org/bspeice/minimalbible/activity/BaseFragment.java +++ b/app/src/main/java/org/bspeice/minimalbible/activity/BaseFragment.java @@ -12,15 +12,29 @@ import com.readystatesoftware.systembartint.SystemBarTintManager; */ public class BaseFragment extends Fragment { + protected static SystemBarTintManager.SystemBarConfig getConfig(Activity context) { + return new SystemBarTintManager(context).getConfig(); + } + /** * Calculate the offset we need to display properly if the System bar is translucent * @param context The {@link android.app.Activity} we are displaying in * @param view The {@link android.view.View} we need to calculate the offset for. */ + @SuppressWarnings("unused") protected static void setInsets(Activity context, View view) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; - SystemBarTintManager tintManager = new SystemBarTintManager(context); - SystemBarTintManager.SystemBarConfig config = tintManager.getConfig(); + SystemBarTintManager.SystemBarConfig config = getConfig(context); view.setPadding(0, config.getPixelInsetTop(true), config.getPixelInsetRight(), config.getPixelInsetBottom()); } + + protected static void setInsetsSpinner(Activity context, View view) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; + SystemBarTintManager.SystemBarConfig config = getConfig(context); + int marginTopBottom = config.getPixelInsetBottom() / 3; + view.setPadding(0, config.getPixelInsetTop(true) + marginTopBottom, + config.getPixelInsetRight(), + marginTopBottom); + } + } diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/BookListFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/BookListFragment.java index 9450144..e2f3db1 100644 --- a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/BookListFragment.java +++ b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/BookListFragment.java @@ -8,12 +8,16 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ArrayAdapter; import android.widget.ListView; +import android.widget.Spinner; +import android.widget.SpinnerAdapter; import android.widget.Toast; import org.bspeice.minimalbible.Injector; import org.bspeice.minimalbible.R; import org.bspeice.minimalbible.activity.BaseFragment; +import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager; import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager; import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.BookCategory; @@ -36,18 +40,18 @@ import rx.functions.Func2; */ public class BookListFragment extends BaseFragment { - /** - * The fragment argument representing the section number for this fragment. - * Not a candidate for Dart (yet) because I would have to write a Parcelable around it. - */ protected static final String ARG_BOOK_CATEGORY = "book_category"; @Inject protected DownloadPrefs downloadPrefs; protected ProgressDialog refreshDialog; + @Inject RefreshManager refreshManager; + @Inject + LocaleManager localeManager; @InjectView(R.id.lst_download_available) ListView downloadsAvailable; - @Inject RefreshManager refreshManager; + @InjectView(R.id.spn_available_languages) + Spinner availableLanguages; private LayoutInflater inflater; /** @@ -121,7 +125,7 @@ public class BookListFragment extends BaseFragment { } // Listen for the books! - refreshManager.getAvailableModulesFlat() + refreshManager.getFlatModules() .filter(new Func1() { @Override public Boolean call(Book book) { @@ -143,12 +147,13 @@ public class BookListFragment extends BaseFragment { public void call(List books) { downloadsAvailable.setAdapter( new BookListAdapter(inflater, books, (DownloadActivity)getActivity())); + availableLanguages.setAdapter(getLocaleSpinner()); if (BookListFragment.this.getActivity() != null) { // On a screen rotate, getActivity() will be null. But, the activity // will already have been set up correctly, so we don't need to worry // about it. // If not null, we need to set it up now. - setInsets(BookListFragment.this.getActivity(), downloadsAvailable); + setInsetsSpinner(BookListFragment.this.getActivity(), availableLanguages); } if (refreshDialog != null) { refreshDialog.cancel(); @@ -157,35 +162,45 @@ public class BookListFragment extends BaseFragment { }); } - private class DownloadDialogListener implements - DialogInterface.OnClickListener { - @Override + @SuppressWarnings("ConstantConditions") + // getAvailableLanguagesList() will not return null + SpinnerAdapter getLocaleSpinner() { + ArrayAdapter adapter = new ArrayAdapter(this.getActivity(), + android.R.layout.simple_spinner_item, + localeManager.getAvailableLanguagesList().toArray()); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + return adapter; + } + + private class DownloadDialogListener implements + DialogInterface.OnClickListener { + @Override public void onClick(@NotNull DialogInterface dialog, int which) { downloadPrefs.hasShownDownloadDialog(true); - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - // Clicked ready to continue - allow downloading in the future - downloadPrefs.hasEnabledDownload(true); + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + // Clicked ready to continue - allow downloading in the future + downloadPrefs.hasEnabledDownload(true); - // And warn them that it has been enabled in the future. - Toast.makeText(getActivity(), - "Downloading now enabled. Disable in settings.", - Toast.LENGTH_SHORT).show(); - refreshModules(); - break; + // And warn them that it has been enabled in the future. + Toast.makeText(getActivity(), + "Downloading now enabled. Disable in settings.", + Toast.LENGTH_SHORT).show(); + refreshModules(); + break; - // case DialogInterface.BUTTON_NEGATIVE: - default: - // Clicked to not download - Permanently disable downloading - downloadPrefs.hasEnabledDownload(false); - Toast.makeText(getActivity(), - "Disabling downloading. Re-enable it in settings.", - Toast.LENGTH_SHORT).show(); - refreshModules(); - break; - } - } - } + // case DialogInterface.BUTTON_NEGATIVE: + default: + // Clicked to not download - Permanently disable downloading + downloadPrefs.hasEnabledDownload(false); + Toast.makeText(getActivity(), + "Disabling downloading. Re-enable it in settings.", + Toast.LENGTH_SHORT).show(); + refreshModules(); + break; + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivityModules.java b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivityModules.java index 017b7db..bb940e7 100644 --- a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivityModules.java +++ b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivityModules.java @@ -7,6 +7,7 @@ import org.bspeice.minimalbible.Injector; import org.bspeice.minimalbible.MinimalBibleModules; import org.bspeice.minimalbible.activity.downloader.manager.BookDownloadManager; import org.bspeice.minimalbible.activity.downloader.manager.InstalledManager; +import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager; import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager; import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.BookCategory; @@ -112,4 +113,9 @@ public class DownloadActivityModules { return new RefreshManager(installers, prefs, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); } + + @Provides + LocaleManager provideLocaleManager(RefreshManager refreshManager) { + return new LocaleManager(refreshManager); + } } diff --git a/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/LocaleManager.kt b/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/LocaleManager.kt new file mode 100644 index 0000000..b711423 --- /dev/null +++ b/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/LocaleManager.kt @@ -0,0 +1,22 @@ +package org.bspeice.minimalbible.activity.downloader.manager + +import org.crosswire.common.util.Language + +class LocaleManager(val rM: RefreshManager) { + + val currentLanguage = Language.DEFAULT_LANG.getName() + val languageModuleMap = rM.flatModules + .map { it.getLanguage() ?: Language(Language.UNKNOWN_LANG_CODE) } + .groupBy { it.getName() } + + val availableLanguages = languageModuleMap.map { it.getKey() } + val availableLanguagesList = availableLanguages.toSortedList {(left, right) -> + // Prioritize our current language first + if (left == currentLanguage) + -1 + else if (right == currentLanguage) + 1 + else + left.compareTo(right) + }.toBlocking().first() +} \ No newline at end of file diff --git a/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/RefreshManager.kt b/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/RefreshManager.kt index e073cc0..c573dd8 100644 --- a/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/RefreshManager.kt +++ b/app/src/main/kotlin/org/bspeice/minimalbible/activity/downloader/manager/RefreshManager.kt @@ -8,6 +8,7 @@ import rx.schedulers.Schedulers import java.util.Calendar import org.bspeice.minimalbible.activity.downloader.DownloadPrefs import android.net.ConnectivityManager +import org.crosswire.jsword.book.BookComparators /** * Created by bspeice on 10/22/14. @@ -21,19 +22,23 @@ class RefreshManager(val installers: Collection, Observable.from(installers) .map { if (doReload()) { - it.reloadBookList() + it.reloadBookList() // TODO: Handle InstallException } mapOf(Pair(it, it.getBooks())) } .subscribeOn(Schedulers.io()) .cache(); - val availableModulesFlat: Observable - get() = availableModules + val flatModules: Observable = + availableModules // Map -> Lists .flatMap { Observable.from(it.values()) } // Lists -> Single list - .flatMap { Observable.from(it) }; + .flatMap { Observable.from(it) } + + val flatModulesSorted = flatModules.toSortedList {(book1, book2) -> + BookComparators.getInitialComparator().compare(book1, book2) + }; // Constructor - Split from the value creation because `subscribe` returns // the subscriber object, not the underlying value @@ -43,8 +48,9 @@ class RefreshManager(val installers: Collection, val fifteenDaysAgo = Calendar.getInstance().getTime().getTime() - 1296000 - fun doReload(enabledDownload: Boolean, lastUpdated: Long, onWifi: Boolean): Boolean = - if (!enabledDownload || !onWifi) + fun doReload(enabledDownload: Boolean, lastUpdated: Long, + networkState: Int? = ConnectivityManager.TYPE_DUMMY): Boolean = + if (!enabledDownload || networkState == ConnectivityManager.TYPE_WIFI) false else if (lastUpdated < fifteenDaysAgo) true @@ -53,12 +59,7 @@ class RefreshManager(val installers: Collection, fun doReload(): Boolean = doReload(prefs.hasEnabledDownload(), prefs.downloadRefreshedOn(), - // TODO: Functional is awesome, but this might be a bit ridiculous - (if (connManager?.getActiveNetworkInfo() != null) - connManager!!.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI - else - false) - ) + connManager?.getActiveNetworkInfo()?.getType()) fun installerFromBook(b: Book): Observable = Observable.just( availableModules.filter { diff --git a/app/src/main/res/layout/fragment_download.xml b/app/src/main/res/layout/fragment_download.xml index ab2dd9f..6142dd1 100644 --- a/app/src/main/res/layout/fragment_download.xml +++ b/app/src/main/res/layout/fragment_download.xml @@ -4,12 +4,19 @@ android:layout_height="match_parent" tools:context="org.bspeice.minimalbible.DownloadActivity$PlaceholderFragment" > - + android:layout_alignParentTop="true" /> + + +