From bb45f3b6b8e729d4f3998088364914efdbd41105 Mon Sep 17 00:00:00 2001 From: Mohamed Sameh Date: Tue, 11 Feb 2020 16:55:42 +0200 Subject: [PATCH 01/15] Add voice data checks for Read Aloud --- .../core/main/KiwixTextToSpeech.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java index 9c39ccd48..714eb6f6e 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java @@ -131,8 +131,26 @@ public class KiwixTextToSpeech { context.getResources().getString(R.string.tts_lang_not_supported), Toast.LENGTH_LONG).show(); } else { + // check if voice needs to be installed for API below 21 + if(VERSION.SDK_INT < VERSION_CODES.LOLLIPOP + && tts.getFeatures(locale).contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)){ + Toast.makeText(context, + context.getResources().getString(R.string.tts_lang_not_supported), + Toast.LENGTH_LONG).show(); + return; + } + tts.setLanguage(locale); + // check if voice needs to be installed for API 21 or higher + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP + && tts.getVoice().getFeatures().contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)){ + Toast.makeText(context, + context.getResources().getString(R.string.tts_lang_not_supported), + Toast.LENGTH_LONG).show(); + return; + } + if (requestAudioFocus()) { loadURL(webView); } From 29368b1afe092c6ff5ae2f52acf55376f078c21e Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Wed, 12 Feb 2020 09:30:43 +0000 Subject: [PATCH 02/15] #1766 Fix Tag Display Behaviour - correct inversion and add rule --- .../kiwix/kiwixmobile/core/zim_manager/TagsView.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/TagsView.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/TagsView.kt index 2c9ef33de..180c338fb 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/TagsView.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/TagsView.kt @@ -43,15 +43,20 @@ class TagsView(context: Context, attrs: AttributeSet) : ChipGroup(context, attrs fun render(tags: List) { tag_picture.selectBy(tags.isYesOrNotDefined()) tag_video.selectBy(tags.isYesOrNotDefined()) - tag_text_only.selectBy(tags.isDefinedAndNo() && tags.isDefinedAndNo()) - tag_short_text.selectBy(tags.isDefinedAndNo()) + val shortTextIsSelected = tags.isDefinedAndNo() + tag_text_only.selectBy( + tags.isDefinedAndNo() && + tags.isDefinedAndNo() && + !shortTextIsSelected + ) + tag_short_text.selectBy(shortTextIsSelected) } private inline fun List.isYesOrNotDefined() = isYes() || !isDefined() private inline fun List.isDefinedAndNo() = - !isDefined() && !isYes() + isDefined() && !isYes() private inline fun List.isYes() = filterIsInstance().getOrNull(0)?.value == YES From 0153b4514d314ff3dbec6f0ec9b71f76e5bfb072 Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Wed, 12 Feb 2020 11:11:23 +0000 Subject: [PATCH 03/15] #12 Make three options to deactivate sidebars, tabs and reading - deactivate based on build --- buildSrc/src/main/kotlin/custom/CustomApps.kt | 3 + .../core/di/modules/ActivityModule.kt | 6 +- .../core/main/CoreMainActivity.java | 62 +++++++++++-------- .../kiwix/kiwixmobile/core/main/MainMenu.kt | 41 ++++++++---- .../custom/main/CustomMainActivity.kt | 39 ++++++++++++ 5 files changed, 112 insertions(+), 39 deletions(-) diff --git a/buildSrc/src/main/kotlin/custom/CustomApps.kt b/buildSrc/src/main/kotlin/custom/CustomApps.kt index a93a5ee03..6f165054a 100644 --- a/buildSrc/src/main/kotlin/custom/CustomApps.kt +++ b/buildSrc/src/main/kotlin/custom/CustomApps.kt @@ -213,6 +213,9 @@ private fun NamedDomainObjectContainer.create( applicationIdSuffix = ".kiwixcustom${customApp.name}" buildConfigField("String", "ZIM_URL", "\"${customApp.url}\"") buildConfigField("String", "ENFORCED_LANG", "\"${customApp.enforcedLanguage}\"") + buildConfigField("Boolean", "DISABLE_SIDEBAR", "false") + buildConfigField("Boolean", "DISABLE_READ_ALOUD", "false") + buildConfigField("Boolean", "DISABLE_TABS", "false") configureStrings(customApp.displayName) } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/ActivityModule.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/ActivityModule.kt index db0254c4e..a9cb6d35d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/ActivityModule.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/ActivityModule.kt @@ -57,13 +57,17 @@ abstract class ActivityModule { menu: Menu, webViews: MutableList, urlIsValid: Boolean, - menuClickListener: MenuClickListener + menuClickListener: MenuClickListener, + disableReadAloud: Boolean, + disableTabs: Boolean ): MainMenu = MainMenu( activity, zimReaderContainer.zimFileReader, menu, webViews, urlIsValid, + disableReadAloud, + disableTabs, menuClickListener ) } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.java b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.java index 8019fef23..b9293f27b 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.java +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.java @@ -175,7 +175,7 @@ public abstract class CoreMainActivity extends BaseActivity @BindView(R2.id.activity_main_fullscreen_button) ImageButton exitFullscreenButton; @BindView(R2.id.activity_main_drawer_layout) - DrawerLayout drawerLayout; + protected DrawerLayout drawerLayout; @BindView(R2.id.activity_main_nav_view) NavigationView tableDrawerRightContainer; @BindView(R2.id.activity_main_content_frame) @@ -285,7 +285,7 @@ public abstract class CoreMainActivity extends BaseActivity Menu menu = mode.getMenu(); // Inflate custom menu icon. getMenuInflater().inflate(R.menu.menu_webview_action, menu); - readAloudSelection(menu); + configureWebViewSelectionHandler(menu); } super.onActionModeStarted(mode); } @@ -296,7 +296,7 @@ public abstract class CoreMainActivity extends BaseActivity super.onActionModeFinished(mode); } - private void readAloudSelection(Menu menu) { + protected void configureWebViewSelectionHandler(Menu menu) { if (menu != null) { menu.findItem(R.id.menu_speak_text) .setOnMenuItemClickListener(item -> { @@ -525,7 +525,7 @@ public abstract class CoreMainActivity extends BaseActivity ContextCompat.getDrawable(this, R.drawable.ic_round_add_white_36dp)); actionBar.setDisplayShowTitleEnabled(false); - drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); + setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); bottomToolbar.setVisibility(View.GONE); contentFrame.setVisibility(View.GONE); progressBar.setVisibility(View.GONE); @@ -550,7 +550,7 @@ public abstract class CoreMainActivity extends BaseActivity actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setDisplayShowTitleEnabled(true); - drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); + setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); closeAllTabsButton.setImageDrawable( ContextCompat.getDrawable(this, R.drawable.ic_close_black_24dp)); startAnimation(tabSwitcherRoot, R.anim.slide_up); @@ -563,6 +563,10 @@ public abstract class CoreMainActivity extends BaseActivity } } + protected void setDrawerLockMode(int lockMode) { + drawerLayout.setDrawerLockMode(lockMode); + } + @OnClick(R2.id.bottom_toolbar_arrow_back) void goBack() { if (getCurrentWebView().canGoBack()) { @@ -1506,10 +1510,14 @@ public abstract class CoreMainActivity extends BaseActivity @Override public boolean onCreateOptionsMenu(Menu menu) { - mainMenu = menuFactory.create(menu, webViewList, !urlIsInvalid(), this); + mainMenu = createMainMenu(menu); return true; } + @NotNull protected MainMenu createMainMenu(Menu menu) { + return menuFactory.create(menu, webViewList, !urlIsInvalid(), this, false, false); + } + protected boolean urlIsInvalid() { return getCurrentWebView().getUrl() == null; } @@ -1675,28 +1683,32 @@ public abstract class CoreMainActivity extends BaseActivity } if (handleEvent) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - - builder.setPositiveButton(android.R.string.yes, (dialog, id) -> { - if (isOpenNewTabInBackground) { - newTabInBackground(url); - Snackbar.make(snackbarRoot, R.string.new_tab_snack_bar, Snackbar.LENGTH_LONG) - .setAction(getString(R.string.open), v -> { - if (webViewList.size() > 1) selectTab(webViewList.size() - 1); - }) - .setActionTextColor(getResources().getColor(R.color.white)) - .show(); - } else { - newTab(url); - } - }); - builder.setNegativeButton(android.R.string.no, null); - builder.setMessage(getString(R.string.open_in_new_tab)); - AlertDialog dialog = builder.create(); - dialog.show(); + showOpenInNewTabDialog(url); } } + protected void showOpenInNewTabDialog(String url) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + builder.setPositiveButton(android.R.string.yes, (dialog, id) -> { + if (isOpenNewTabInBackground) { + newTabInBackground(url); + Snackbar.make(snackbarRoot, R.string.new_tab_snack_bar, Snackbar.LENGTH_LONG) + .setAction(getString(R.string.open), v -> { + if (webViewList.size() > 1) selectTab(webViewList.size() - 1); + }) + .setActionTextColor(getResources().getColor(R.color.white)) + .show(); + } else { + newTab(url); + } + }); + builder.setNegativeButton(android.R.string.no, null); + builder.setMessage(getString(R.string.open_in_new_tab)); + AlertDialog dialog = builder.create(); + dialog.show(); + } + @Override public void setHomePage(View view) { getCurrentWebView().deactivateNightMode(); diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainMenu.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainMenu.kt index f6f256a97..1a268b34b 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainMenu.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainMenu.kt @@ -22,6 +22,7 @@ import android.content.res.Configuration import android.view.Menu import android.view.MenuItem import android.widget.TextView +import androidx.core.view.isVisible import org.kiwix.kiwixmobile.core.Intents.internal import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.intent @@ -42,6 +43,8 @@ class MainMenu( menu: Menu, webViews: MutableList, urlIsValid: Boolean, + disableReadAloud: Boolean = false, + disableTabs: Boolean = false, private val menuClickListener: MenuClickListener ) { @@ -50,7 +53,9 @@ class MainMenu( menu: Menu, webViews: MutableList, urlIsValid: Boolean, - menuClickListener: MenuClickListener + menuClickListener: MenuClickListener, + disableReadAloud: Boolean, + disableTabs: Boolean ): MainMenu } @@ -72,29 +77,39 @@ class MainMenu( } private val search = menu.findItem(R.id.menu_search) - private val tabSwitcher = menu.findItem(R.id.menu_tab_switcher) - private val tabSwitcherTextView = - tabSwitcher.actionView.findViewById(R.id.ic_tab_switcher_text) + private var tabSwitcher: MenuItem? = menu.findItem(R.id.menu_tab_switcher) + private var tabSwitcherTextView: TextView? = + tabSwitcher?.actionView?.findViewById(R.id.ic_tab_switcher_text) private val bookmarks = menu.findItem(R.id.menu_bookmarks_list) private val history = menu.findItem(R.id.menu_history) private val library = menu.findItem(R.id.menu_openfile) private val addNote = menu.findItem(R.id.menu_add_note) private val randomArticle = menu.findItem(R.id.menu_random_article) private val fullscreen = menu.findItem(R.id.menu_fullscreen) - private val readAloud = menu.findItem(R.id.menu_read_aloud) + private var readAloud: MenuItem? = menu.findItem(R.id.menu_read_aloud) private val hostBooks = menu.findItem(R.id.menu_host_books) private val help = menu.findItem(R.id.menu_help) private val settings = menu.findItem(R.id.menu_settings) private val supportKiwix = menu.findItem(R.id.menu_support_kiwix) init { + if (disableReadAloud) { + readAloud?.isVisible = false + readAloud = null + } + if (disableTabs) { + tabSwitcher?.isVisible = false + tabSwitcherTextView?.isVisible = false + tabSwitcher = null + tabSwitcherTextView = null + } randomArticle.setShowAsAction( if (activity.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) MenuItem.SHOW_AS_ACTION_IF_ROOM else MenuItem.SHOW_AS_ACTION_NEVER ) - tabSwitcher.actionView.setOnClickListener { menuClickListener.onTabMenuClicked() } + tabSwitcher?.actionView?.setOnClickListener { menuClickListener.onTabMenuClicked() } help.menuItemClickListener { activity.start() } settings.menuItemClickListener { activity.startActivityForResult( @@ -149,7 +164,7 @@ class MainMenu( } fun updateTabIcon(tabs: Int) { - tabSwitcherTextView.text = if (tabs > 99) ":D" else "$tabs" + tabSwitcherTextView?.text = if (tabs > 99) ":D" else "$tabs" } private fun navigateToSearch(zimFileReader: ZimFileReader): Boolean { @@ -164,15 +179,15 @@ class MainMenu( } fun onTextToSpeechStartedTalking() { - readAloud.setTitle(R.string.menu_read_aloud_stop) + readAloud?.setTitle(R.string.menu_read_aloud_stop) } fun onTextToSpeechStoppedTalking() { - readAloud.setTitle(R.string.menu_read_aloud) + readAloud?.setTitle(R.string.menu_read_aloud) } - private fun setVisibility(visibility: Boolean, vararg menuItems: MenuItem) { - menuItems.forEach { it.isVisible = visibility } + private fun setVisibility(visibility: Boolean, vararg menuItems: MenuItem?) { + menuItems.forEach { it?.isVisible = visibility } } fun tryExpandSearch(zimFileReader: ZimFileReader?) { @@ -182,8 +197,8 @@ class MainMenu( } } -private fun MenuItem.menuItemClickListener(function: (MenuItem) -> Unit) { - setOnMenuItemClickListener { +private fun MenuItem?.menuItemClickListener(function: (MenuItem) -> Unit) { + this?.setOnMenuItemClickListener { function.invoke(it) true } diff --git a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomMainActivity.kt b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomMainActivity.kt index 12aa2f83f..5719b513a 100644 --- a/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomMainActivity.kt +++ b/custom/src/main/java/org/kiwix/kiwixmobile/custom/main/CustomMainActivity.kt @@ -28,11 +28,14 @@ import android.os.Bundle import android.provider.Settings import android.util.Log import android.view.Menu +import android.widget.ImageView import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import androidx.drawerlayout.widget.DrawerLayout import org.kiwix.kiwixmobile.core.di.components.CoreComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start import org.kiwix.kiwixmobile.core.main.CoreMainActivity +import org.kiwix.kiwixmobile.core.main.MainMenu import org.kiwix.kiwixmobile.core.main.WebViewCallback import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.utils.DialogShower @@ -72,6 +75,19 @@ class CustomMainActivity : CoreMainActivity() { return } openObbOrZim() + setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) + if (BuildConfig.DISABLE_SIDEBAR) { + val toolbarToc = findViewById(R.id.bottom_toolbar_toc) + toolbarToc.isEnabled = false + toolbarToc.alpha = .25f + } + } + + override fun setDrawerLockMode(lockMode: Int) { + super.setDrawerLockMode( + if (BuildConfig.DISABLE_SIDEBAR) DrawerLayout.LOCK_MODE_LOCKED_CLOSED + else lockMode + ) } @TargetApi(VERSION_CODES.M) @@ -152,4 +168,27 @@ class CustomMainActivity : CoreMainActivity() { override fun manageZimFiles(tab: Int) { // Do nothing } + + override fun createMainMenu(menu: Menu?): MainMenu { + return menuFactory.create( + menu!!, + webViewList, + !urlIsInvalid(), + this, + BuildConfig.DISABLE_READ_ALOUD, + BuildConfig.DISABLE_TABS + ) + } + + override fun showOpenInNewTabDialog(url: String?) { + if (BuildConfig.DISABLE_TABS) return + super.showOpenInNewTabDialog(url) + } + + override fun configureWebViewSelectionHandler(menu: Menu?) { + if (BuildConfig.DISABLE_READ_ALOUD) { + menu?.findItem(org.kiwix.kiwixmobile.core.R.id.menu_speak_text)?.isVisible = false + } + super.configureWebViewSelectionHandler(menu) + } } From 226e787f66b9ad1b6810af70ad2ae99d9f553f5c Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Wed, 12 Feb 2020 15:32:05 +0000 Subject: [PATCH 04/15] #12 Make three options to deactivate sidebars, tabs and reading - read from json - tidy file up --- buildSrc/src/main/kotlin/custom/CustomApp.kt | 35 ++- buildSrc/src/main/kotlin/custom/CustomApps.kt | 209 ++---------------- custom/build.gradle.kts | 3 - custom/src/customexample/info.json | 5 +- 4 files changed, 56 insertions(+), 196 deletions(-) diff --git a/buildSrc/src/main/kotlin/custom/CustomApp.kt b/buildSrc/src/main/kotlin/custom/CustomApp.kt index 8146610d6..cb125b0a6 100644 --- a/buildSrc/src/main/kotlin/custom/CustomApp.kt +++ b/buildSrc/src/main/kotlin/custom/CustomApp.kt @@ -18,32 +18,55 @@ package custom +import org.json.simple.JSONObject import java.text.ParseException import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +const val dateFormat = "YYYY-MM" + data class CustomApp( val name: String, val url: String, val enforcedLanguage: String, val displayName: String, - val versionName: String = parseVersionNameFromUrlOrUsePattern(url, "YYYY-MM") + val versionName: String, + val disableSideBar: Boolean = false, + val disableTabs: Boolean = false, + val disableReadAloud: Boolean = false ) { - val versionCode: Int = formatDate("YYDDD0").toInt() + constructor(name: String, parsedJson: JSONObject) : this( + name, + parsedJson.getAndCast("zim_url"), + parsedJson.getAndCast("enforced_lang"), + parsedJson.getAndCast("app_name"), + readVersionOrInfer(parsedJson), + parsedJson.getAndCast("disable_sidebar") ?: false, + parsedJson.getAndCast("disable_tabs") ?: false, + parsedJson.getAndCast("disable_read_aloud") ?: false + ) + + val versionCode: Int = formatCurrentDate("YYDDD0").toInt() + + companion object { + private fun readVersionOrInfer(parsedJson: JSONObject) = + (parsedJson.getAndCast("version_name") + ?: versionNameFromUrl(parsedJson.getAndCast("zim_url"))) + ?: formatCurrentDate() + } } -private fun parseVersionNameFromUrlOrUsePattern(url: String, pattern: String) = +private fun versionNameFromUrl(url: String) = url.substringAfterLast("_") .substringBeforeLast(".") .takeIf { try { - SimpleDateFormat(pattern, Locale.ROOT).parse(it) != null + SimpleDateFormat(dateFormat, Locale.ROOT).parse(it) != null } catch (parseException: ParseException) { false } } - ?: formatDate(pattern) -private fun formatDate(pattern: String) = +private fun formatCurrentDate(pattern: String = dateFormat) = Date().let(SimpleDateFormat(pattern, Locale.ROOT)::format) diff --git a/buildSrc/src/main/kotlin/custom/CustomApps.kt b/buildSrc/src/main/kotlin/custom/CustomApps.kt index 6f165054a..31c7351b9 100644 --- a/buildSrc/src/main/kotlin/custom/CustomApps.kt +++ b/buildSrc/src/main/kotlin/custom/CustomApps.kt @@ -24,202 +24,39 @@ import org.json.simple.JSONObject import org.json.simple.parser.JSONParser import java.io.File +typealias ProductFlavors = NamedDomainObjectContainer + object CustomApps { - private val example = CustomApp( - name = "customexample", - url = "http://download.kiwix.org/zim/wikipedia_fr_test.zim", - enforcedLanguage = "en", - displayName = "Test Custom App" - ) - private val phet = CustomApp( - name = "phet", - url = "http://download.kiwix.org/zim/phet/phet_mul_2018-09.zim", - enforcedLanguage = "en", - displayName = "PhET" - ) - private val tunisie = CustomApp( - name = "tunisie", - url = "http://download.kiwix.org/zim/wikipedia_fr_tunisie_novid.zim", - enforcedLanguage = "fr", - versionName = "2018-07", - displayName = "Encyclopédie de la Tunisie" - ) - private val venezuela = CustomApp( - name = "venezuela", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_es_venezuela_2018-07.zim", - enforcedLanguage = "es", - displayName = "Enciclopedia de Venezuela" - ) - private val wikimed = CustomApp( - name = "wikimed", - url = "http://download.kiwix.org/zim/wikipedia_en_medicine_novid.zim", - enforcedLanguage = "en", - versionName = "2018-08", - displayName = "Medical Wikipedia" - ) - private val wikimedar = CustomApp( - name = "wikimedar", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_ar_medicine_novid_2018-08.zim", - enforcedLanguage = "ar", - displayName = "وِيكيبيديا الطبية (بلا اتصال بالانترنت)" - ) - private val wikimedde = CustomApp( - name = "wikimedde", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_de_medicine_novid_2018-10.zim", - enforcedLanguage = "de", - displayName = "Wikipedia Medizin (Offline)" - ) - private val wikimedes = CustomApp( - name = "wikimedes", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_es_medicine_novid_2018-10.zim", - enforcedLanguage = "es", - displayName = "Wikipedia Médica (Offline)" - ) - private val wikimedfa = CustomApp( - name = "wikimedfa", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_fa_medicine_novid_2018-07.zim", - enforcedLanguage = "fa", - displayName = "ویکی‌پدیای پزشکی (آفلاین)" - ) - private val wikimedfr = CustomApp( - name = "wikimedfr", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_fr_medicine_novid_2018-07.zim", - enforcedLanguage = "fr", - displayName = "Wikipédia médicale" - ) - private val wikimedja = CustomApp( - name = "wikimedja", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_ja_medicine_novid_2018-07.zim", - enforcedLanguage = "ja", - displayName = "医療ウィキペディア(オフライン)" - ) - private val wikimedmini = CustomApp( - name = "wikimedmini", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_en_medicine_nodet_2018-07.zim", - enforcedLanguage = "en", - displayName = "Offline WikiMed mini" - ) - private val wikimedor = CustomApp( - name = "wikimedor", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_or_medicine_novid_2018-07.zim", - enforcedLanguage = "or", - displayName = "ମେଡିକାଲ ଉଇକିପିଡିଆ (ଅଫଲାଇନ)" - ) - private val wikimedpt = CustomApp( - name = "wikimedpt", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_pt_medicine_2018-10.zim", - enforcedLanguage = "pt", - displayName = "Wikipédia Médica (Offline)" - ) - private val wikimedzh = CustomApp( - name = "wikimedzh", - url = "http://download.kiwix.org/zim/wikipedia/wikipedia_zh_medicine_novid_2018-07.zim", - enforcedLanguage = "zh", - displayName = "醫學維基百科(離線版)" - ) - private val wikispecies = CustomApp( - name = "wikispecies", - url = "http://download.kiwix.org/zim/wikispecies/wikispecies_en_all_novid_2018-08.zim", - enforcedLanguage = "en", - displayName = "WikiSpecies" - ) - private val wikivoyage = CustomApp( - name = "wikivoyage", - url = "http://download.kiwix.org/zim/wikivoyage/wikivoyage_en_all_novid_2018-10.zim", - enforcedLanguage = "en", - displayName = "Wikivoyage" - ) - private val wikivoyageeurope = CustomApp( - name = "wikivoyageeurope", - url = "http://download.kiwix.org/zim/wikivoyage/wikivoyage_en_europe_novid_2018-10.zim", - enforcedLanguage = "en", - displayName = "Wikivoyage European Travels" - ) - private val wikivoyagede = CustomApp( - name = "wikivoyagede", - url = "http://download.kiwix.org/zim/wikivoyage/wikivoyage_de_all_novid_2018-10.zim", - enforcedLanguage = "de", - displayName = "Wikivoyage auf Deutsch" - ) - private val all = listOf( - example, - phet, - tunisie, - venezuela, - wikimed, - wikimedar, - wikimedde, - wikimedes, - wikimedfa, - wikimedfr, - wikimedja, - wikimedmini, - wikimedor, - wikimedpt, - wikimedzh, - wikispecies, - wikivoyage, - wikivoyageeurope, - wikivoyagede - ) - fun createStatically(productFlavors: NamedDomainObjectContainer) { - productFlavors.create(all) + fun createDynamically(srcFolder: File, productFlavors: ProductFlavors) { + productFlavors.create(customApps(srcFolder)) } - fun createDynamically( - srcFolder: File, - productFlavors: NamedDomainObjectContainer - ) { - productFlavors.create( - srcFolder.walk() - .filter { it.name == "info.json" } - .map { - val parsedJson = JSONParser().parse(it.readText()) as JSONObject - createCustomAppFromJson( - it.parentFile.name, - parsedJson.getAndCast("zim_url"), - parsedJson.getAndCast("enforced_lang"), - parsedJson.getAndCast("app_name"), - parsedJson.getAndCast("version_name") - ) - }.toList() - ) + private fun customApps(srcFolder: File) = srcFolder.walk() + .filter { it.name == "info.json" } + .map { CustomApp(it.parentFile.name, JSONParser().parse(it.readText()) as JSONObject) } + .toList() +} + +fun ProductFlavors.create(customApps: List) { + customApps.forEach { customApp -> + this.create(customApp.name) { + versionName = customApp.versionName + versionCode = customApp.versionCode + applicationIdSuffix = ".kiwixcustom${customApp.name}" + buildConfigField("String", "ZIM_URL", "\"${customApp.url}\"") + buildConfigField("String", "ENFORCED_LANG", "\"${customApp.enforcedLanguage}\"") + buildConfigField("Boolean", "DISABLE_SIDEBAR", "${customApp.disableSideBar}") + buildConfigField("Boolean", "DISABLE_TABS", "${customApp.disableTabs}") + buildConfigField("Boolean", "DISABLE_READ_ALOUD", "${customApp.disableReadAloud}") + configureStrings(customApp.displayName) + } } } -fun NamedDomainObjectContainer.create(customApps: List) { - customApps.forEach(this::create) -} - -private fun createCustomAppFromJson( - name: String, - url: String, - enforcedLanguage: String, - displayName: String, - versionName: String? -) = if (versionName == null) CustomApp(name, url, enforcedLanguage, displayName) -else CustomApp(name, url, enforcedLanguage, displayName, versionName) - fun JSONObject.getAndCast(columnName: String): T = getOrDefault(columnName, null) as T -private fun NamedDomainObjectContainer.create( - customApp: CustomApp -) { - create(customApp.name) { - versionName = customApp.versionName - versionCode = customApp.versionCode - applicationIdSuffix = ".kiwixcustom${customApp.name}" - buildConfigField("String", "ZIM_URL", "\"${customApp.url}\"") - buildConfigField("String", "ENFORCED_LANG", "\"${customApp.enforcedLanguage}\"") - buildConfigField("Boolean", "DISABLE_SIDEBAR", "false") - buildConfigField("Boolean", "DISABLE_READ_ALOUD", "false") - buildConfigField("Boolean", "DISABLE_TABS", "false") - configureStrings(customApp.displayName) - } -} - fun ProductFlavor.configureStrings(appName: String) { resValue("string", "app_name", appName) resValue("string", "app_search_string", "Search $appName") diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index acb1cb61e..d30e8f6ae 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -21,9 +21,6 @@ android { flavorDimensions("default") productFlavors { - - // Uncomment for static productFlavors - // CustomApps.createStatically(this) CustomApps.createDynamically(project.file("src"), this) all { File("$projectDir/src", "$name/$name.zim").let { diff --git a/custom/src/customexample/info.json b/custom/src/customexample/info.json index 661d4fd4a..495a11431 100644 --- a/custom/src/customexample/info.json +++ b/custom/src/customexample/info.json @@ -1,6 +1,9 @@ { "app_name": "Test Custom App", "zim_url": "http://download.kiwix.org/zim/wikipedia_fr_test.zim", - "enforced_lang": "en" + "enforced_lang": "en", + "disable_sidebar": false, + "disable_tabs": false, + "disable_read_aloud": false } From 2ead1030759ef5d31824db98065fd4569b3dc3ab Mon Sep 17 00:00:00 2001 From: Mohamed Sameh Date: Wed, 12 Feb 2020 22:41:40 +0200 Subject: [PATCH 05/15] Use ContextExtensionKt.toast and unify checking conditions for voice data checks --- .../core/main/KiwixTextToSpeech.java | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java index 714eb6f6e..102d0dca6 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.java @@ -39,6 +39,7 @@ import org.kiwix.kiwixmobile.core.CoreApp; import org.kiwix.kiwixmobile.core.R; import org.kiwix.kiwixmobile.core.utils.LanguageUtils; import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer; +import org.kiwix.kiwixmobile.core.extensions.ContextExtensionsKt; import static org.kiwix.kiwixmobile.core.utils.Constants.TAG_KIWIX; @@ -131,23 +132,14 @@ public class KiwixTextToSpeech { context.getResources().getString(R.string.tts_lang_not_supported), Toast.LENGTH_LONG).show(); } else { - // check if voice needs to be installed for API below 21 - if(VERSION.SDK_INT < VERSION_CODES.LOLLIPOP - && tts.getFeatures(locale).contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)){ - Toast.makeText(context, - context.getResources().getString(R.string.tts_lang_not_supported), - Toast.LENGTH_LONG).show(); - return; - } - tts.setLanguage(locale); - // check if voice needs to be installed for API 21 or higher - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP - && tts.getVoice().getFeatures().contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)){ - Toast.makeText(context, - context.getResources().getString(R.string.tts_lang_not_supported), - Toast.LENGTH_LONG).show(); + if ((VERSION.SDK_INT < VERSION_CODES.LOLLIPOP // check if voice needs to be installed for API below 21 + && tts.getFeatures(locale).contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)) + // check if voice needs to be installed for API 21 or higher + ||(VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP + && tts.getVoice().getFeatures().contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED))){ + ContextExtensionsKt.toast(this.context,R.string.tts_lang_not_supported,Toast.LENGTH_LONG); return; } From 80f3294782cfa6b5963fd1dc5fcaef23587bec35 Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Fri, 14 Feb 2020 14:22:53 +0000 Subject: [PATCH 06/15] #1771 Crash Report 3.2: java.lang.IllegalArgumentException CompatFindActionModeCallback.findAll - don't use null and correct searchActivity view states --- .idea/codeStyles/Project.xml | 3 --- .../main/CompatFindActionModeCallback.java | 8 +++--- .../kiwixmobile/core/search/SearchActivity.kt | 17 +++++++------ .../core/search/viewmodel/SearchViewModel.kt | 12 +++------ .../core/search/viewmodel/State.kt | 7 +++--- .../search/viewmodel/SearchViewModelTest.kt | 25 +++++++------------ 6 files changed, 30 insertions(+), 42 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 580e9334d..6b0453612 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -45,9 +45,6 @@