From 11a98b98efa1abf5f41fed59c992d55813343e55 Mon Sep 17 00:00:00 2001 From: Rok Biderman Date: Mon, 21 Mar 2022 00:39:58 -0700 Subject: [PATCH 1/3] Update deps --- app/build.gradle | 27 ++-- app/config/jacoco.gradle | 40 +++--- app/src/androidTest/AndroidManifest.xml | 11 ++ app/src/main/AndroidManifest.xml | 10 +- .../umbrella/component/DialogManager.kt | 2 +- .../umbrella/component/WebViewController.kt | 2 +- .../view/adapter/HostChecklistAdapter.kt | 2 +- .../view/controller/ChecklistController.kt | 2 +- .../controller/ChecklistCustomController.kt | 9 +- .../view/controller/DashboardController.kt | 12 +- .../difficulty/view/DifficultyController.kt | 4 +- .../umbrella/feature/main/MainActivity.kt | 4 +- .../feature/reader/view/ReaderAdapter.kt | 2 +- .../search/presenter/SearchPresenterImp.kt | 25 ++-- .../feature/search/view/SearchController.kt | 118 +++++++++--------- .../segment/view/adapter/FilterAdapter.kt | 2 +- .../view/adapter/HostSegmentAdapter.kt | 28 +++-- .../view/controller/HostSegmentController.kt | 20 +-- .../view/controller/SegmentController.kt | 78 ++++++++---- .../controller/SegmentDetailController.kt | 6 +- .../secfirst/umbrella/misc/AboutController.kt | 6 +- build.gradle | 34 ++--- gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 24 files changed, 275 insertions(+), 175 deletions(-) create mode 100644 app/src/androidTest/AndroidManifest.xml diff --git a/app/build.gradle b/app/build.gradle index 8be04ea1..01c332ea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,9 +6,6 @@ apply from: 'config/jacoco.gradle' apply from: 'config/sonarqube.gradle' android { viewBinding.enabled = true - lintOptions { - abortOnError false - } signingConfigs { umbrella_beta { keyAlias 'umbrella' @@ -27,12 +24,20 @@ android { exclude module: 'httpclient' exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-iid' + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'com.google.dagger') { + details.useVersion "HEAD-SNAPSHOT" + } + } } } packagingOptions { - exclude 'META-INF/LICENSE*' - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/NOTICE*' + jniLibs { + excludes += ['META-INF/LICENSE*', 'META-INF/NOTICE*'] + } + resources { + excludes += ['META-INF/LICENSE*', 'META-INF/DEPENDENCIES', 'META-INF/NOTICE*'] + } } androidExtensions { @@ -41,8 +46,8 @@ android { defaultConfig { applicationId "org.secfirst.umbrella" minSdkVersion 16 - compileSdkVersion 28 - targetSdkVersion 28 + compileSdkVersion 31 + targetSdkVersion 31 versionCode 56 versionName "1.0.32" multiDexEnabled true @@ -68,6 +73,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + lint { + abortOnError false + } } dependencies { @@ -92,7 +100,8 @@ dependencies { //Framework for replacing fragments implementation "com.bluelinelabs:conductor:$conductor_version" - implementation "com.bluelinelabs:conductor-support:$conductor_version_support" +// implementation "com.bluelinelabs:conductor-support:$conductor_version_support" + implementation "com.bluelinelabs:conductor-viewpager:$conductor_version_support" //OkHttp implementation "com.squareup.okhttp3:okhttp:$okhttp3" diff --git a/app/config/jacoco.gradle b/app/config/jacoco.gradle index e6673a30..7ae4abdb 100644 --- a/app/config/jacoco.gradle +++ b/app/config/jacoco.gradle @@ -12,29 +12,33 @@ jacoco { task jacocoTestReport(type: JacocoReport, dependsOn: "testDebugUnitTest") { group = "Reporting" description = "Generate Jacoco coverage reports for Debug build" - classDirectories = fileTree( - dir: "$buildDir/intermediates/classes/debug", - excludes: ['**/R.class', - '**/R$*.class', - '**/*$ViewBinder*.*', - '**/*$InjectAdapter*.*', - '**/*Injector*.*', - '**/BuildConfig.*', - '**/Manifest*.*', - '**/*Test*.*', - '**/*Activity*.*', - '**/CiMattersApplication*.*', - 'android/**/*.*'] + getClassDirectories().setFrom( + fileTree( + dir: "$buildDir/intermediates/classes/debug", + excludes: ['**/R.class', + '**/R$*.class', + '**/*$ViewBinder*.*', + '**/*$InjectAdapter*.*', + '**/*Injector*.*', + '**/BuildConfig.*', + '**/Manifest*.*', + '**/*Test*.*', + '**/*Activity*.*', + '**/CiMattersApplication*.*', + 'android/**/*.*'] + ) ) reports { xml.enabled = true html.enabled = true } - additionalSourceDirs = files(coverageSourceDirs) - sourceDirectories = files(coverageSourceDirs) - executionData = fileTree(dir: project.buildDir, includes: [ - 'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec' - ]) + getAdditionalSourceDirs().setFrom(files(coverageSourceDirs)) + getSourceDirectories().setFrom(files(coverageSourceDirs)) + getExecutionData().setFrom( + fileTree(dir: project.buildDir, includes: [ + 'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec' + ]) + ) // Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174. // We iterate through the compiled .class tree and rename $$ to $. doFirst { diff --git a/app/src/androidTest/AndroidManifest.xml b/app/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000..d914c8df --- /dev/null +++ b/app/src/androidTest/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b7b44218..071fb873 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,7 +21,9 @@ + android:screenOrientation="portrait" + tools:ignore="LockedOrientationActivity" + android:exported="true"> @@ -39,7 +41,8 @@ android:label="@string/app_calc" android:roundIcon="@mipmap/calc" android:screenOrientation="portrait" - android:targetActivity=".feature.main.MainActivity"> + android:targetActivity=".feature.main.MainActivity" + android:exported="true"> @@ -55,7 +58,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_umbrella" android:screenOrientation="portrait" - android:targetActivity=".feature.main.MainActivity"> + android:targetActivity=".feature.main.MainActivity" + android:exported="true"> diff --git a/app/src/main/java/org/secfirst/umbrella/component/DialogManager.kt b/app/src/main/java/org/secfirst/umbrella/component/DialogManager.kt index c924b105..429fb166 100644 --- a/app/src/main/java/org/secfirst/umbrella/component/DialogManager.kt +++ b/app/src/main/java/org/secfirst/umbrella/component/DialogManager.kt @@ -15,7 +15,7 @@ class DialogManager(private val controller: Controller) { } init { - controller.addLifecycleListener(object : Controller.LifecycleListener { + controller.addLifecycleListener(object : Controller.LifecycleListener() { override fun postCreateView(controller: Controller, view: View) { for (combo in combos) { combo.dialog = combo.factory.createDialog(controller.activity) diff --git a/app/src/main/java/org/secfirst/umbrella/component/WebViewController.kt b/app/src/main/java/org/secfirst/umbrella/component/WebViewController.kt index f41aebd2..c6134af3 100644 --- a/app/src/main/java/org/secfirst/umbrella/component/WebViewController.kt +++ b/app/src/main/java/org/secfirst/umbrella/component/WebViewController.kt @@ -51,7 +51,7 @@ class WebViewController(bundle: Bundle) : BaseController(bundle) { private fun setUpWebView() { webView?.let { - it.loadUrl(url) + url?.let { it1 -> it.loadUrl(it1) } it.webViewClient = object : WebViewClient() { override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) { webViewLoad?.visibility = INVISIBLE diff --git a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/adapter/HostChecklistAdapter.kt b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/adapter/HostChecklistAdapter.kt index 60d9776f..c5b78b23 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/adapter/HostChecklistAdapter.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/adapter/HostChecklistAdapter.kt @@ -3,7 +3,7 @@ package org.secfirst.umbrella.feature.checklist.view.adapter import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.support.RouterPagerAdapter +import com.bluelinelabs.conductor.viewpager.RouterPagerAdapter import org.secfirst.umbrella.R import org.secfirst.umbrella.feature.checklist.view.controller.DashboardController diff --git a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistController.kt b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistController.kt index 2c30c349..69f822d2 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistController.kt @@ -64,7 +64,7 @@ class ChecklistController(bundle: Bundle) : BaseController(bundle), ChecklistVie .setView(checklistViewDialog) .create() presenter.onAttach(this) - presenter.submitChecklist(checklistId) + checklistId?.let { presenter.submitChecklist(it) } checklistView.addNewItemChecklist.setOnClickListener { onAddItemClicked() } swipeToDeleteCallback() checkIsNavigation() diff --git a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistCustomController.kt b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistCustomController.kt index cfe3a963..793c48cd 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistCustomController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/ChecklistCustomController.kt @@ -76,8 +76,13 @@ class ChecklistCustomController(bundle: Bundle) : BaseController(bundle), Checkl private fun submitChecklist() { if (adapter.getChecklistItems().isNotEmpty()) - presenter.submitInsertCustomChecklist(checklistName, - checklistId, adapter.getChecklistItems()) + checklistName?.let { + checklistId?.let { it1 -> + presenter.submitInsertCustomChecklist( + it, + it1, adapter.getChecklistItems()) + } + } } private fun initDeleteChecklistItem(view: View) { diff --git a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/DashboardController.kt b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/DashboardController.kt index 3af3fe2a..99990b79 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/DashboardController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/checklist/view/controller/DashboardController.kt @@ -277,15 +277,17 @@ class DashboardController(bundle: Bundle) : BaseController(bundle), ChecklistVie private fun shareDocument(fileToShare: File) { val pm = context.packageManager val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, fileToShare) - val shareIntent = ShareCompat.IntentBuilder.from(activity) + val shareIntent = activity?.let { + ShareCompat.IntentBuilder(it) .setType(context.contentResolver.getType(uri)) .setStream(uri) .intent + } - shareIntent.action = Intent.ACTION_SEND - shareIntent.putExtra(Intent.EXTRA_SUBJECT, FilenameUtils.removeExtension(fileToShare.name)) - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - if (shareIntent.resolveActivity(pm) != null) + shareIntent?.action = Intent.ACTION_SEND + shareIntent?.putExtra(Intent.EXTRA_SUBJECT, FilenameUtils.removeExtension(fileToShare.name)) + shareIntent?.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + if (shareIntent?.resolveActivity(pm) != null) startActivity(Intent.createChooser(shareIntent, context.getString(R.string.export_lesson))) } diff --git a/app/src/main/java/org/secfirst/umbrella/feature/difficulty/view/DifficultyController.kt b/app/src/main/java/org/secfirst/umbrella/feature/difficulty/view/DifficultyController.kt index cf1df003..65fe8866 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/difficulty/view/DifficultyController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/difficulty/view/DifficultyController.kt @@ -42,13 +42,13 @@ class DifficultyController(bundle: Bundle) : BaseController(bundle), DifficultyV override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View { presenter.onAttach(this) - presenter.submitDifficulty(subjectId) + subjectId?.let { presenter.submitDifficulty(it) } return inflater.inflate(R.layout.difficulty_view, container, false) } private fun onDifficultClick(position: Int) { val itemSelected = difficultyAdapter.getItem(position) - presenter.saveDifficultySelect(itemSelected, subjectId) + subjectId?.let { presenter.saveDifficultySelect(itemSelected, it) } presenter.submitDifficultySelect(difficultyAdapter.getItems(position)) } diff --git a/app/src/main/java/org/secfirst/umbrella/feature/main/MainActivity.kt b/app/src/main/java/org/secfirst/umbrella/feature/main/MainActivity.kt index ab3322f6..fe8f4cb1 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/main/MainActivity.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/main/MainActivity.kt @@ -15,7 +15,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SearchView import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.attachRouter +import com.bluelinelabs.conductor.Conductor.attachRouter import com.github.tbouron.shakedetector.library.ShakeDetector import com.google.android.material.bottomnavigation.BottomNavigationView import dagger.android.AndroidInjection @@ -59,7 +59,7 @@ class MainActivity : AppCompatActivity(), AdvancedSearchPresenter { super.onCreate(savedInstanceState) setLanguage() setContentView(R.layout.main_view) - router = attachRouter(baseContainer, savedInstanceState) + router = attachRouter(this@MainActivity, baseContainer, savedInstanceState) performDI() isDeepLink() initNavigation() diff --git a/app/src/main/java/org/secfirst/umbrella/feature/reader/view/ReaderAdapter.kt b/app/src/main/java/org/secfirst/umbrella/feature/reader/view/ReaderAdapter.kt index 8950f5e3..2e65ad1c 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/reader/view/ReaderAdapter.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/reader/view/ReaderAdapter.kt @@ -3,7 +3,7 @@ package org.secfirst.umbrella.feature.reader.view import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.support.RouterPagerAdapter +import com.bluelinelabs.conductor.viewpager.RouterPagerAdapter import org.secfirst.umbrella.R import org.secfirst.umbrella.feature.reader.view.feed.FeedSettingsController import org.secfirst.umbrella.feature.reader.view.rss.RssController diff --git a/app/src/main/java/org/secfirst/umbrella/feature/search/presenter/SearchPresenterImp.kt b/app/src/main/java/org/secfirst/umbrella/feature/search/presenter/SearchPresenterImp.kt index 4cf00923..73a62ac1 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/search/presenter/SearchPresenterImp.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/search/presenter/SearchPresenterImp.kt @@ -30,6 +30,7 @@ import org.secfirst.umbrella.feature.search.interactor.SearchBaseInteractor import org.secfirst.umbrella.feature.search.view.SearchView import org.secfirst.umbrella.misc.wrapTextWithElement import javax.inject.Inject +import kotlin.collections.ArrayList class SearchPresenterImp @Inject constructor( @@ -102,7 +103,7 @@ class SearchPresenterImp @Inject const ), // We leave this one alone cause it renders the main search view SearchCriteria( - ItemCriteria.TEXT.type.toLowerCase(), + ItemCriteria.TEXT.type.lowercase(), FieldTypes.FREE_TEXT, null, null) @@ -111,9 +112,9 @@ class SearchPresenterImp @Inject const override fun getDataProvider(): DataProvider = object : DataProvider { override fun findByCriteria(text: String, vararg additional: Pair>): Flowable> { - val trimmedText = text.toLowerCase().trim() - val type = additional.find { it.first.toLowerCase().contains(ItemCriteria.TYPE.type.toLowerCase()) }?.second - val category = additional.find { it.first.toLowerCase().contains(ItemCriteria.CATEGORY.type.toLowerCase()) }?.second + val trimmedText = text.lowercase().trim() + val type = additional.find { it.first.lowercase().contains(ItemCriteria.TYPE.type.lowercase()) }?.second + val category = additional.find { it.first.lowercase().contains(ItemCriteria.CATEGORY.type.lowercase()) }?.second val categoryId = ArrayList() if (category != null) { val categoriesId = SQLite.select() @@ -122,7 +123,7 @@ class SearchPresenterImp @Inject const categoriesId.forEach { categoryId.add(it.id) } } - val difficulty = additional.find { it.first.toLowerCase().contains(ItemCriteria.DIFFICULTY.type.toLowerCase()) }?.second + val difficulty = additional.find { it.first.lowercase().contains(ItemCriteria.DIFFICULTY.type.lowercase()) }?.second val mutableMap: MutableList = mutableListOf() when (type == null) { @@ -160,7 +161,7 @@ class SearchPresenterImp @Inject const val doc = Jsoup.parse(htmlText) for (e in doc.body().allElements) { for (tn in e.textNodes()) { - tn.wrapTextWithElement(text, ""); + tn.wrapTextWithElement(text, "") } } doc.toString() @@ -180,7 +181,7 @@ class SearchPresenterImp @Inject const false -> { SQLite.select() .from(Form::class.java) - .where(Form_Table.path.like("%${text.toLowerCase().trim()}%")) + .where(Form_Table.path.like("%${text.lowercase().trim()}%")) .queryList().map { it.toSearchResult() } } } @@ -195,17 +196,20 @@ class SearchPresenterImp @Inject const category.forEach { cat.or(Content_Table.checklist_id.like("%$it%")) } op.and(cat) } + else -> {} } when (difficulty?.isNotEmpty()) { true -> { difficulty.forEach { dif.or(Content_Table.checklist_id.like("%/$it/%")) } op.and(dif) } + else -> {} } when (text.isNotEmpty()) { true -> { - op.and(Content_Table.check.like("%${text.toLowerCase().trim()}%")) + op.and(Content_Table.check.like("%${text.lowercase().trim()}%")) } + else -> {} } return SQLite.select() @@ -225,17 +229,20 @@ class SearchPresenterImp @Inject const category.forEach { cat.or(Markdown_Table.difficulty_id.like("%$it%")) } op.and(cat) } + else -> {} } when (difficulty?.isNotEmpty()) { true -> { difficulty.forEach { dif.or(Markdown_Table.difficulty_id.like("%/$it/%")) } op.and(dif) } + else -> {} } when (text.isNotEmpty()) { true -> { - op.and(Markdown_Table.text.like("%${text.toLowerCase().trim()}%")) + op.and(Markdown_Table.text.like("%${text.lowercase().trim()}%")) } + else -> {} } return SQLite.select() .from(Markdown::class.java) diff --git a/app/src/main/java/org/secfirst/umbrella/feature/search/view/SearchController.kt b/app/src/main/java/org/secfirst/umbrella/feature/search/view/SearchController.kt index 717f5cfc..1b6235d1 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/search/view/SearchController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/search/view/SearchController.kt @@ -17,60 +17,64 @@ import org.secfirst.umbrella.feature.search.presenter.SearchBasePresenter import javax.inject.Inject class SearchController(bundle: Bundle) : BaseController(bundle), SearchView { - - @Inject - internal lateinit var presenter: SearchBasePresenter - private val query by lazy { args.getString(EXTRA_SEARCH_QUERY) } - private lateinit var mainIntentAction: String - - constructor(query: String = "") : this(Bundle().apply { - putString(EXTRA_SEARCH_QUERY, query) - }) - - override fun onInject() { - DaggerSearchComponent.builder() - .application(UmbrellaApplication.instance) - .build() - .inject(this) - } - - override fun onAttach(view: View) { - super.onAttach(view) - setUpToolbar() - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View { - presenter.onAttach(this) - mainActivity.registerSearchProvider(presenter as AdvancedSearchPresenter) - mainActivity.intent.action?.let { mainIntentAction = it } - presenter.submitSearchQuery(query) - mainActivity.hideNavigation() - mainActivity.intent.action = Intent.ACTION_SEARCH - mainActivity.intent.putExtra(SearchManager.QUERY, query) - return inflater.inflate(R.layout.searching_view, container, false) - } - - override fun onDestroyView(view: View) { - super.onDestroyView(view) - mainActivity.intent.action = mainIntentAction - mainActivity.showNavigation() - mainActivity.releaseSearchProvider() - } - - override fun handleBack(): Boolean { - return super.handleBack() - } - - private fun setUpToolbar() { - searchToolbar?.let { - it.setTitle(R.string.search_results) - it.setNavigationIcon(R.drawable.ic_action_back) - it.setNavigationOnClickListener { mainActivity.onBackPressed() } - } - } - - companion object { - private const val EXTRA_SEARCH_QUERY = "search_query" - } - - } \ No newline at end of file + + @Inject + internal lateinit var presenter: SearchBasePresenter + private val query by lazy { args.getString(EXTRA_SEARCH_QUERY) } + private lateinit var mainIntentAction: String + + constructor(query: String = "") : this(Bundle().apply { + putString(EXTRA_SEARCH_QUERY, query) + }) + + override fun onInject() { + DaggerSearchComponent.builder() + .application(UmbrellaApplication.instance) + .build() + .inject(this) + } + + override fun onAttach(view: View) { + super.onAttach(view) + setUpToolbar() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup, + savedViewState: Bundle? + ): View { + presenter.onAttach(this) + mainActivity.registerSearchProvider(presenter as AdvancedSearchPresenter) + mainActivity.intent.action?.let { mainIntentAction = it } + query?.let { presenter.submitSearchQuery(it) } + mainActivity.hideNavigation() + mainActivity.intent.action = Intent.ACTION_SEARCH + mainActivity.intent.putExtra(SearchManager.QUERY, query) + return inflater.inflate(R.layout.searching_view, container, false) + } + + override fun onDestroyView(view: View) { + super.onDestroyView(view) + mainActivity.intent.action = mainIntentAction + mainActivity.showNavigation() + mainActivity.releaseSearchProvider() + } + + override fun handleBack(): Boolean { + return super.handleBack() + } + + private fun setUpToolbar() { + searchToolbar?.let { + it.setTitle(R.string.search_results) + it.setNavigationIcon(R.drawable.ic_action_back) + it.setNavigationOnClickListener { mainActivity.onBackPressed() } + } + } + + companion object { + private const val EXTRA_SEARCH_QUERY = "search_query" + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/FilterAdapter.kt b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/FilterAdapter.kt index b93a86f5..61635a62 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/FilterAdapter.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/FilterAdapter.kt @@ -14,7 +14,7 @@ import org.secfirst.umbrella.data.database.difficulty.Difficulty class FilterAdapter(context: Context, private val difficulties: List) : ArrayAdapter(context, android.R.layout.simple_dropdown_item_1line, difficulties) { - override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { return createViewFromResource(position, convertView, parent) } diff --git a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/HostSegmentAdapter.kt b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/HostSegmentAdapter.kt index 008211ee..0dd359cf 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/HostSegmentAdapter.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/adapter/HostSegmentAdapter.kt @@ -3,16 +3,18 @@ package org.secfirst.umbrella.feature.segment.view.adapter import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.support.RouterPagerAdapter +import com.bluelinelabs.conductor.viewpager.RouterPagerAdapter import org.secfirst.umbrella.feature.checklist.view.controller.ChecklistController import org.secfirst.umbrella.feature.segment.view.controller.SegmentController import org.secfirst.umbrella.feature.segment.view.controller.SegmentDetailController import org.secfirst.umbrella.misc.AppExecutors.Companion.uiContext import org.secfirst.umbrella.misc.launchSilent -class HostSegmentAdapter(host: Controller, - private val controllers: List, - private val segmentPageLimit: Int) : RouterPagerAdapter(host) { +class HostSegmentAdapter( + host: Controller, + private val controllers: List, + private val segmentPageLimit: Int +) : RouterPagerAdapter(host) { override fun configureRouter(router: Router, position: Int) { @@ -20,7 +22,13 @@ class HostSegmentAdapter(host: Controller, when (position) { 0 -> { val segmentController = controllers[position] as SegmentController - launchSilent(uiContext) { router.setRoot(RouterTransaction.with(segmentController)) } + launchSilent(uiContext) { + router.setRoot( + RouterTransaction.with( + segmentController + ) + ) + } } in 1..segmentPageLimit -> { val detailController = controllers[position] as SegmentDetailController @@ -28,7 +36,13 @@ class HostSegmentAdapter(host: Controller, } else -> { val checklistController = controllers[position] as ChecklistController - launchSilent(uiContext) { router.setRoot(RouterTransaction.with(checklistController)) } + launchSilent(uiContext) { + router.setRoot( + RouterTransaction.with( + checklistController + ) + ) + } } } } @@ -42,7 +56,7 @@ class HostSegmentAdapter(host: Controller, } in 1..segmentPageLimit -> { val currentController = controllers[position] as SegmentDetailController - currentController.getTitle() + currentController.getTitle() ?: "" } else -> { diff --git a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/HostSegmentController.kt b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/HostSegmentController.kt index 89c635f9..336ebdbc 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/HostSegmentController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/HostSegmentController.kt @@ -66,17 +66,19 @@ class HostSegmentController(bundle: Bundle) : BaseController(bundle), SegmentVie private fun initView(view: View) { setUpToolbar(view) - when { - uriString != null -> presenter.submitMarkdownsByURI(uriString) + objectIds?.let { + when { + uriString != null -> presenter.submitMarkdownsByURI(uriString!!) - enableFilter -> { - view.hostSegmentSpinner.visibility = VISIBLE - presenter.submitDifficulties(objectIds) - } + enableFilter -> { + view.hostSegmentSpinner.visibility = VISIBLE + presenter.submitDifficulties(it) + } - else -> { - presenter.submitMarkdowns(objectIds) - view.hostSegmentSpinner.visibility = INVISIBLE + else -> { + presenter.submitMarkdowns(it) + view.hostSegmentSpinner.visibility = INVISIBLE + } } } } diff --git a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentController.kt b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentController.kt index d11723fb..258142e0 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentController.kt @@ -68,7 +68,11 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { private lateinit var viewSegment: View private lateinit var tabControl: HostSegmentTabControl - constructor(markdownIds: ArrayList, checklistId: String, isFromDashboard: Boolean = false) : this(Bundle().apply { + constructor( + markdownIds: ArrayList, + checklistId: String, + isFromDashboard: Boolean = false + ) : this(Bundle().apply { putStringArrayList(EXTRA_SEGMENT, markdownIds) putString(EXTRA_CHECKLIST, checklistId) putBoolean(EXTRA_DASHBOARD, isFromDashboard) @@ -76,23 +80,31 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { override fun onInject() { DaggerSegmentComponent.builder() - .application(UmbrellaApplication.instance) - .build() - .inject(this) + .application(UmbrellaApplication.instance) + .build() + .inject(this) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup, + savedViewState: Bundle? + ): View { setHasOptionsMenu(true) tabControl = parentController as HostSegmentTabControl viewSegment = inflater.inflate(R.layout.segment_view, container, false) shareView = inflater.inflate(R.layout.share_dialog, container, false) - if (markdownIds.isNotEmpty()) { + if (markdownIds?.isNotEmpty() == true) { shareDialog = AlertDialog - .Builder(activity) - .setView(shareView) - .create() + .Builder(activity) + .setView(shareView) + .create() presenter.onAttach(this) - presenter.submitMarkdownsAndChecklist(markdownIds, checklistId) + checklistId?.let { + markdownIds?.let { it1 -> + presenter.submitMarkdownsAndChecklist(it1, it) + } + } if (isFromDashboard) { onSegmentClicked(markdownIds!!.size) } @@ -139,10 +151,12 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { launchSilent(uiContext) { markdowns.forEach { markdown -> if (markdown.isRemove) { - val segmentItem = SegmentItem(segmentClick, segmentShareClick, segmentFavoriteClick, null) + val segmentItem = + SegmentItem(segmentClick, segmentShareClick, segmentFavoriteClick, null) section.add(segmentItem) } else { - val segmentItem = SegmentItem(segmentClick, segmentShareClick, segmentFavoriteClick, markdown) + val segmentItem = + SegmentItem(segmentClick, segmentShareClick, segmentFavoriteClick, markdown) section.add(segmentItem) } } @@ -156,13 +170,25 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { private fun createChecklistCard() { checklist?.let { - segmentAdapter.add(Section(SegmentFoot(footClick, - checklistShareClick, checklistFavoriteClick, it))) + segmentAdapter.add( + Section( + SegmentFoot( + footClick, + checklistShareClick, checklistFavoriteClick, it + ) + ) + ) } } override fun showSegmentDetail(markdown: Markdown) { - parentController?.router?.pushController(RouterTransaction.with(SegmentDetailController(markdown))) + parentController?.router?.pushController( + RouterTransaction.with( + SegmentDetailController( + markdown + ) + ) + ) } @@ -193,16 +219,23 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { private fun shareDocument(fileToShare: File) { val pm = context.packageManager val uri = FileProvider.getUriForFile(context, APPLICATION_ID, fileToShare) - val shareIntent = ShareCompat.IntentBuilder.from(activity) + val shareIntent = activity?.let { + ShareCompat.IntentBuilder(it) .setType(context.contentResolver.getType(uri)) .setStream(uri) .intent + } - shareIntent.action = Intent.ACTION_SEND - shareIntent.putExtra(Intent.EXTRA_SUBJECT, removeExtension(fileToShare.name)) - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - if (shareIntent.resolveActivity(pm) != null) - startActivity(Intent.createChooser(shareIntent, context.getString(R.string.export_lesson))) + shareIntent?.action = Intent.ACTION_SEND + shareIntent?.putExtra(Intent.EXTRA_SUBJECT, removeExtension(fileToShare.name)) + shareIntent?.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + if (shareIntent?.resolveActivity(pm) != null) + startActivity( + Intent.createChooser( + shareIntent, + context.getString(R.string.export_lesson) + ) + ) } @@ -225,7 +258,8 @@ class SegmentController(bundle: Bundle) : BaseController(bundle), SegmentView { shareDialog.show() } - private fun onSegmentFavoriteClick(markdown: Markdown) = presenter.submitMarkdownFavorite(markdown) + private fun onSegmentFavoriteClick(markdown: Markdown) = + presenter.submitMarkdownFavorite(markdown) private fun onFootClicked(position: Int) { markdownIds?.let { diff --git a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentDetailController.kt b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentDetailController.kt index ab639e04..e2a0e5e8 100644 --- a/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentDetailController.kt +++ b/app/src/main/java/org/secfirst/umbrella/feature/segment/view/controller/SegmentDetailController.kt @@ -15,7 +15,7 @@ import org.secfirst.umbrella.misc.launchSilent class SegmentDetailController(bundle: Bundle) : BaseController(bundle) { - private val markdown by lazy { args.getParcelable(EXTRA_SELECTED_SEGMENT_DETAIL) as Markdown } + private val markdown by lazy { args.getParcelable(EXTRA_SELECTED_SEGMENT_DETAIL) as Markdown? } override fun onInject() {} @@ -33,10 +33,10 @@ class SegmentDetailController(bundle: Bundle) : BaseController(bundle) { val css = Github() css.addRule("body", "line-height: 1.6", "padding: 0px") view.markdownView.addStyleSheet(css) - launchSilent(uiContext) { view.markdownView.loadMarkdown(markdown.text) } + launchSilent(uiContext) { view.markdownView.loadMarkdown(markdown?.text) } } - fun getTitle() = markdown.title + fun getTitle() = markdown?.title companion object { const val EXTRA_SELECTED_SEGMENT_DETAIL = "selected_segment_detail" diff --git a/app/src/main/java/org/secfirst/umbrella/misc/AboutController.kt b/app/src/main/java/org/secfirst/umbrella/misc/AboutController.kt index 3a2c5d95..e959ff2b 100644 --- a/app/src/main/java/org/secfirst/umbrella/misc/AboutController.kt +++ b/app/src/main/java/org/secfirst/umbrella/misc/AboutController.kt @@ -12,7 +12,7 @@ import org.secfirst.umbrella.feature.base.view.BaseController class AboutController(bundle: Bundle) : BaseController(bundle) { - private val markdown by lazy { args.getParcelable(EXTRA_ABOUT) as Markdown } + private val markdown by lazy { args.getParcelable(EXTRA_ABOUT) as Markdown? } constructor(markdown: Markdown) : this(Bundle().apply { putParcelable(EXTRA_ABOUT, markdown) @@ -29,7 +29,7 @@ class AboutController(bundle: Bundle) : BaseController(bundle) { override fun onAttach(view: View) { super.onAttach(view) aboutMarkdownView.addStyleSheet(Github()) - aboutMarkdownView.loadMarkdown(markdown.text) + aboutMarkdownView.loadMarkdown(markdown?.text) setUpToolbar() } @@ -41,7 +41,7 @@ class AboutController(bundle: Bundle) : BaseController(bundle) { aboutToolbar?.let { mainActivity.setSupportActionBar(it) mainActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) - mainActivity.supportActionBar?.title = markdown.title + mainActivity.supportActionBar?.title = markdown?.title } } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 93160907..81f4a8df 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,18 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.72' + ext.kotlin_version = '1.6.10' repositories { google() + mavenCentral() jcenter() + maven { + url "https://oss.sonatype.org/content/repositories/snapshots" + } } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'org.jacoco:org.jacoco.core:0.8.1' + classpath 'org.jacoco:org.jacoco.core:0.8.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -23,6 +27,7 @@ plugins { allprojects { repositories { google() + mavenCentral() jcenter() maven { url "https://repo.eclipse.org/content/groups/releases/" } maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } @@ -51,18 +56,18 @@ detekt { ext { - minSdkVersion = 15 - targetSdkVersion = 28 - compileSdkVersion = 28 + minSdkVersion = 16 + targetSdkVersion = 31 + compileSdkVersion = 31 buildToolsVersion = '26.0.2' support_library_version = '28.0.0' support_constraint_version = '1.1.3' - dagger2_version = '2.27' + dagger2_version = '2.41' runner_version = '1.0.2' espresso_version = '3.0.2' espresso_descendant_actions = '1.4.0' - junit_version = '4.13' + junit_version = '4.13.2' rx_android_version = '2.0.2' rx_java_version = '2.1.14' retrofit_version = '2.8.1' @@ -75,18 +80,17 @@ ext { okHttpLog_version = '3.9.1' jgit_version = '3.7.1.201504261725-r' commonsIo_version = '2.6' - jackson_databind_version = '2.11.0' - jackson_yaml_version = '2.11.0' - jackson_module_version = '2.11.0' + jackson_databind_version = '2.11.1' + jackson_yaml_version = '2.11.1' + jackson_module_version = '2.11.1' hamcrest_core_version = '2.2' hamcrest_version = '2.2' test_support_version = '0.1' test_rule_version = '1.0.2' mockito_version = '3.3.3' - junit_version = '4.12' - coroutine_version = "1.3.5" - conductor_version = "3.0.0-rc4" - conductor_version_support = "3.0.0-rc2" + coroutine_version = "1.4.1" + conductor_version = "3.1.4" + conductor_version_support = "3.1.4" stepper_version = "4.3.1" multidex_version = "2.0.1" jsoup = '1.13.1' diff --git a/gradle.properties b/gradle.properties index 58be69cb..bfda95fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,10 +9,10 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m +org.gradle.jvmargs=-Xmx1536m --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true android.useAndroidX=true -android.enableJetifier=true +android.enableJetifier=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0374c08f..16efe4b4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip From 5cd43e5d575db32f894867e2da47d934e717530e Mon Sep 17 00:00:00 2001 From: Rok Biderman Date: Mon, 21 Mar 2022 00:50:44 -0700 Subject: [PATCH 2/3] Remove add-opens --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bfda95fa..80c63ab2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED +org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects From 726d1b872e8442afc3d7446a120937920fd49e80 Mon Sep 17 00:00:00 2001 From: Rok Biderman Date: Mon, 21 Mar 2022 00:55:32 -0700 Subject: [PATCH 3/3] Update image --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b37c6096..4fdf46be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: circleci/android:api-28-alpha + - image: circleci/android:api-30 environment: ANDROID_HOME: "/opt/android/sdk" JAVA_OPTIONS: "-Xms512m -Xmx3200m"