From 1e31497f103ad68a6df09e28076f3cb981272ac4 Mon Sep 17 00:00:00 2001 From: Zihan Pan Date: Sun, 20 Oct 2024 19:57:23 +1100 Subject: [PATCH 1/3] Fix categories searching problem of photo uploading --- .../upload/categories/CategoriesPresenter.kt | 515 +++++++++--------- 1 file changed, 265 insertions(+), 250 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt index 1822df8302..b57017a0ed 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt @@ -1,5 +1,6 @@ package fr.free.nrw.commons.upload.categories +import android.annotation.SuppressLint import android.text.TextUtils import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -27,288 +28,302 @@ import javax.inject.Singleton */ @Singleton class CategoriesPresenter - @Inject - constructor( - private val repository: UploadRepository, - @param:Named(CommonsApplicationModule.IO_THREAD) private val ioScheduler: Scheduler, - @param:Named(CommonsApplicationModule.MAIN_THREAD) private val mainThreadScheduler: Scheduler, - ) : CategoriesContract.UserActionListener { - companion object { - private val DUMMY: CategoriesContract.View = proxy() - } +@Inject +constructor( + private val repository: UploadRepository, + @param:Named(CommonsApplicationModule.IO_THREAD) private val ioScheduler: Scheduler, + @param:Named(CommonsApplicationModule.MAIN_THREAD) private val mainThreadScheduler: Scheduler, +) : CategoriesContract.UserActionListener { + companion object { + private val DUMMY: CategoriesContract.View = proxy() + } - var view = DUMMY - private val compositeDisposable = CompositeDisposable() - private val searchTerms = PublishSubject.create() - private var categoryList: MutableLiveData> = MutableLiveData() + var view = DUMMY + private val compositeDisposable = CompositeDisposable() + private val searchTerms = PublishSubject.create() + private var categoryList: MutableLiveData> = MutableLiveData() - /** - * Current media - */ - private var media: Media? = null + /** + * Current media + */ + private var media: Media? = null - /** - * helper class for editing categories - */ - @Inject - lateinit var categoryEditHelper: CategoryEditHelper + /** + * helper class for editing categories + */ + @Inject + lateinit var categoryEditHelper: CategoryEditHelper - override fun onAttachView(view: CategoriesContract.View) { - this.view = view - compositeDisposable.add( - searchTerms - .observeOn(mainThreadScheduler) - .doOnNext { - view.showProgress(true) - }.switchMap(::searchResults) - .map { repository.selectedCategories + it } - .map { it.distinctBy { categoryItem -> categoryItem.name } } - .observeOn(mainThreadScheduler) - .subscribe( - { - setCategoryListValue(it) - view.showProgress(false) - if (it.isEmpty()) { - view.showError(R.string.no_categories_found) - } - }, - { t: Throwable? -> - view.showProgress(false) + @SuppressLint("TimberArgCount") + override fun onAttachView(view: CategoriesContract.View) { + this.view = view + compositeDisposable.add( + searchTerms + .observeOn(mainThreadScheduler) + .doOnNext { + view.showProgress(true) + }.switchMap(::searchResults) + .map { repository.selectedCategories + it } + .map { it.distinctBy { categoryItem -> categoryItem.name } } + .observeOn(mainThreadScheduler) + .subscribe( + { + setCategoryListValue(it) + view.showProgress(false) + if (it.isEmpty() && !isInitialLoad) { view.showError(R.string.no_categories_found) - Timber.e(t) - }, - ), - ) - } + } + }, + { t: Throwable? -> + view.showProgress(false) + view.showError(R.string.no_categories_found) + Timber.e(t) + }, + ), + ) + + //isInitialLoad = false + } - /** - * If media is null : Fetches categories from server according to the term - * Else : Fetches existing categories by their name, fetches categories from server according - * to the term and combines both in a list - */ - private fun searchResults(term: String): Observable>? { - if (media == null) { - return repository - .searchAll(term, getImageTitleList(), repository.selectedDepictions) - .subscribeOn(ioScheduler) - .map { - it.filter { categoryItem -> - !repository.isSpammyCategory(categoryItem.name) || + private var isInitialLoad = true //avoid initial empty content of edittext lead to showError + + + /** + * If media is null : Fetches categories from server according to the term + * Else : Fetches existing categories by their name, fetches categories from server according + * to the term and combines both in a list + */ + private fun searchResults(term: String): Observable>? { + if (media == null) { + return repository + .searchAll(term, getImageTitleList(), repository.selectedDepictions) + .subscribeOn(ioScheduler) + .map { + it.filter { categoryItem -> + !repository.isSpammyCategory(categoryItem.name) || categoryItem.name == term - } } - } else { - return Observable - .zip( - repository - .getCategories(repository.selectedExistingCategories) - .map { list -> - list.map { - CategoryItem(it.name, it.description, it.thumbnail, true) - } - }, - repository.searchAll(term, getImageTitleList(), repository.selectedDepictions), - ) { it1, it2 -> - it1 + it2 - }.subscribeOn(ioScheduler) - .map { - it.filter { categoryItem -> - !repository.isSpammyCategory(categoryItem.name) || + } + } else { + return Observable + .zip( + repository + .getCategories(repository.selectedExistingCategories) + .map { list -> + list.map { + CategoryItem(it.name, it.description, it.thumbnail, true) + } + }, + repository.searchAll(term, getImageTitleList(), repository.selectedDepictions), + ) { it1, it2 -> + it1 + it2 + }.subscribeOn(ioScheduler) + .map { + it.filter { categoryItem -> + !repository.isSpammyCategory(categoryItem.name) || categoryItem.name == term - } - }.map { it.filterNot { categoryItem -> categoryItem.thumbnail == "hidden" } } - } + } + }.map { it.filterNot { categoryItem -> categoryItem.thumbnail == "hidden" } } } + } - override fun onDetachView() { - view = DUMMY - compositeDisposable.clear() - } + override fun onDetachView() { + view = DUMMY + compositeDisposable.clear() + isInitialLoad = true + } - /** - * asks the repository to fetch categories for the query - * @param query - */ - override fun searchForCategories(query: String) { - searchTerms.onNext(query) + /** + * asks the repository to fetch categories for the query + * @param query + */ + override fun searchForCategories(query: String) { + if (query.isBlank()) { + if (!isInitialLoad) { + view.showError(R.string.no_categories_found) + } + return } + isInitialLoad = false + searchTerms.onNext(query) + } - /** - * Returns image title list from UploadItem - * @return - */ - private fun getImageTitleList(): List = - repository.uploads - .map { it.uploadMediaDetails[0].captionText } - .filterNot { TextUtils.isEmpty(it) } + /** + * Returns image title list from UploadItem + * @return + */ + private fun getImageTitleList(): List = + repository.uploads + .map { it.uploadMediaDetails[0].captionText } + .filterNot { TextUtils.isEmpty(it) } - /** - * Verifies the number of categories selected, prompts the user if none selected - */ - override fun verifyCategories() { - val selectedCategories = repository.selectedCategories - if (selectedCategories.isNotEmpty()) { - repository.setSelectedCategories(selectedCategories.map { it.name }) - view.goToNextScreen() - } else { - view.showNoCategorySelected() - } + /** + * Verifies the number of categories selected, prompts the user if none selected + */ + override fun verifyCategories() { + val selectedCategories = repository.selectedCategories + if (selectedCategories.isNotEmpty()) { + repository.setSelectedCategories(selectedCategories.map { it.name }) + view.goToNextScreen() + } else { + view.showNoCategorySelected() } + } - /** - * ask repository to handle category clicked - * - * @param categoryItem - */ - override fun onCategoryItemClicked(categoryItem: CategoryItem) { - repository.onCategoryClicked(categoryItem, media) - } + /** + * ask repository to handle category clicked + * + * @param categoryItem + */ + override fun onCategoryItemClicked(categoryItem: CategoryItem) { + repository.onCategoryClicked(categoryItem, media) + } - /** - * Attaches view and media - */ - override fun onAttachViewWithMedia( - view: CategoriesContract.View, - media: Media, - ) { - this.view = view - this.media = media - repository.selectedExistingCategories = view.existingCategories - compositeDisposable.add( - searchTerms - .observeOn(mainThreadScheduler) - .doOnNext { - view.showProgress(true) - }.switchMap(::searchResults) - .map { repository.selectedCategories + it } - .map { it.distinctBy { categoryItem -> categoryItem.name } } - .observeOn(mainThreadScheduler) - .subscribe( - { - setCategoryListValue(it) - view.showProgress(false) - if (it.isEmpty()) { - view.showError(R.string.no_categories_found) - } - }, - { t: Throwable? -> - view.showProgress(false) + /** + * Attaches view and media + */ + override fun onAttachViewWithMedia( + view: CategoriesContract.View, + media: Media, + ) { + this.view = view + this.media = media + repository.selectedExistingCategories = view.existingCategories + compositeDisposable.add( + searchTerms + .observeOn(mainThreadScheduler) + .doOnNext { + view.showProgress(true) + }.switchMap(::searchResults) + .map { repository.selectedCategories + it } + .map { it.distinctBy { categoryItem -> categoryItem.name } } + .observeOn(mainThreadScheduler) + .subscribe( + { + setCategoryListValue(it) + view.showProgress(false) + if (it.isEmpty() && !isInitialLoad) { view.showError(R.string.no_categories_found) - Timber.e(t) - }, - ), - ) - } + } + }, + { t: Throwable? -> + view.showProgress(false) + view.showError(R.string.no_categories_found) + Timber.e(t) + }, + ), + ) + } - /** - * Clears previous selections - */ - override fun clearPreviousSelection() { - repository.cleanup() - } + /** + * Clears previous selections + */ + override fun clearPreviousSelection() { + repository.cleanup() + } - /** - * Gets the selected categories and send them for posting to the server - * - * @param media media - * @param wikiText current WikiText from server - */ - override fun updateCategories( - media: Media, - wikiText: String, + /** + * Gets the selected categories and send them for posting to the server + * + * @param media media + * @param wikiText current WikiText from server + */ + override fun updateCategories( + media: Media, + wikiText: String, + ) { + // check if view.existingCategories is null + if (repository.selectedCategories.isNotEmpty() || + (view.existingCategories != null && repository.selectedExistingCategories.size != view.existingCategories.size) ) { - // check if view.existingCategories is null - if (repository.selectedCategories.isNotEmpty() || - (view.existingCategories != null && repository.selectedExistingCategories.size != view.existingCategories.size) - ) { - val selectedCategories: MutableList = - ( + val selectedCategories: MutableList = + ( repository.selectedCategories.map { it.name }.toMutableList() + - repository.selectedExistingCategories - ).toMutableList() + repository.selectedExistingCategories + ).toMutableList() - if (selectedCategories.isNotEmpty()) { - view.showProgressDialog() + if (selectedCategories.isNotEmpty()) { + view.showProgressDialog() - try { - compositeDisposable.add( - categoryEditHelper - .makeCategoryEdit( - view.fragmentContext, - media, - selectedCategories, - wikiText, - ).subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ - Timber.d("Categories are added.") - media.addedCategories = selectedCategories - repository.cleanup() - view.dismissProgressDialog() - view.refreshCategories() - view.goBackToPreviousScreen() - }, { - Timber.e( - "Failed to update categories", - ) - }), - ) - } catch (e: InvalidLoginTokenException) { - view.navigateToLoginScreen() - } + try { + compositeDisposable.add( + categoryEditHelper + .makeCategoryEdit( + view.fragmentContext, + media, + selectedCategories, + wikiText, + ).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + Timber.d("Categories are added.") + media.addedCategories = selectedCategories + repository.cleanup() + view.dismissProgressDialog() + view.refreshCategories() + view.goBackToPreviousScreen() + }, { + Timber.e( + "Failed to update categories", + ) + }), + ) + } catch (e: InvalidLoginTokenException) { + view.navigateToLoginScreen() } - } else { - repository.cleanup() - view.showNoCategorySelected() } + } else { + repository.cleanup() + view.showNoCategorySelected() } + } - /** - * Selects each [CategoryItem] in a given list as if they were clicked by the user by calling - * [onCategoryItemClicked] for each category and adding the category to [categoryList] - */ - private fun selectNewCategories(toSelect: List) { - toSelect.forEach { - it.isSelected = true - repository.onCategoryClicked(it, media) - } - - // Add the new selections to the list of category items so that the selections appear - // immediately (i.e. without any search term queries) - categoryList.value - ?.toMutableList() - ?.let { toSelect + it } - ?.distinctBy(CategoryItem::name) - ?.let { setCategoryListValue(it) } + /** + * Selects each [CategoryItem] in a given list as if they were clicked by the user by calling + * [onCategoryItemClicked] for each category and adding the category to [categoryList] + */ + private fun selectNewCategories(toSelect: List) { + toSelect.forEach { + it.isSelected = true + repository.onCategoryClicked(it, media) } - /** - * Livedata being used to observe category list inside - * @see UploadCategoriesFragment - * Any changes to category list reflect immediately to the adapter list - */ - override fun getCategories(): LiveData> = categoryList + // Add the new selections to the list of category items so that the selections appear + // immediately (i.e. without any search term queries) + categoryList.value + ?.toMutableList() + ?.let { toSelect + it } + ?.distinctBy(CategoryItem::name) + ?.let { setCategoryListValue(it) } + } - /** - * needed for tests - */ - fun setCategoryList(categoryList: MutableLiveData>) { - this.categoryList = categoryList - } + /** + * Livedata being used to observe category list inside + * @see UploadCategoriesFragment + * Any changes to category list reflect immediately to the adapter list + */ + override fun getCategories(): LiveData> = categoryList - /** - * needed for tests - */ - fun setCategoryListValue(categoryItems: List) { - categoryList.postValue(categoryItems) - } + /** + * needed for tests + */ + fun setCategoryList(categoryList: MutableLiveData>) { + this.categoryList = categoryList + } - override fun selectCategories() { - compositeDisposable.add( - repository.placeCategories - .subscribeOn(ioScheduler) - .observeOn(mainThreadScheduler) - .subscribe(::selectNewCategories), - ) - } + /** + * needed for tests + */ + fun setCategoryListValue(categoryItems: List) { + categoryList.postValue(categoryItems) + } + + override fun selectCategories() { + compositeDisposable.add( + repository.placeCategories + .subscribeOn(ioScheduler) + .observeOn(mainThreadScheduler) + .subscribe(::selectNewCategories), + ) } +} \ No newline at end of file From 75ec41bdb5a83b658db2bf4630ff234becd26c91 Mon Sep 17 00:00:00 2001 From: Zihan Pan Date: Sun, 20 Oct 2024 20:11:51 +1100 Subject: [PATCH 2/3] Fix space problem of categoriesPresenter.kt --- .../upload/categories/CategoriesPresenter.kt | 528 +++++++++--------- 1 file changed, 264 insertions(+), 264 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt index b57017a0ed..92063d7cc7 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt @@ -28,302 +28,302 @@ import javax.inject.Singleton */ @Singleton class CategoriesPresenter -@Inject -constructor( - private val repository: UploadRepository, - @param:Named(CommonsApplicationModule.IO_THREAD) private val ioScheduler: Scheduler, - @param:Named(CommonsApplicationModule.MAIN_THREAD) private val mainThreadScheduler: Scheduler, -) : CategoriesContract.UserActionListener { - companion object { - private val DUMMY: CategoriesContract.View = proxy() - } + @Inject + constructor( + private val repository: UploadRepository, + @param:Named(CommonsApplicationModule.IO_THREAD) private val ioScheduler: Scheduler, + @param:Named(CommonsApplicationModule.MAIN_THREAD) private val mainThreadScheduler: Scheduler, + ) : CategoriesContract.UserActionListener { + companion object { + private val DUMMY: CategoriesContract.View = proxy() + } - var view = DUMMY - private val compositeDisposable = CompositeDisposable() - private val searchTerms = PublishSubject.create() - private var categoryList: MutableLiveData> = MutableLiveData() + var view = DUMMY + private val compositeDisposable = CompositeDisposable() + private val searchTerms = PublishSubject.create() + private var categoryList: MutableLiveData> = MutableLiveData() - /** - * Current media - */ - private var media: Media? = null + /** + * Current media + */ + private var media: Media? = null - /** - * helper class for editing categories - */ - @Inject - lateinit var categoryEditHelper: CategoryEditHelper + /** + * helper class for editing categories + */ + @Inject + lateinit var categoryEditHelper: CategoryEditHelper - @SuppressLint("TimberArgCount") - override fun onAttachView(view: CategoriesContract.View) { - this.view = view - compositeDisposable.add( - searchTerms - .observeOn(mainThreadScheduler) - .doOnNext { - view.showProgress(true) - }.switchMap(::searchResults) - .map { repository.selectedCategories + it } - .map { it.distinctBy { categoryItem -> categoryItem.name } } - .observeOn(mainThreadScheduler) - .subscribe( - { - setCategoryListValue(it) - view.showProgress(false) - if (it.isEmpty() && !isInitialLoad) { + @SuppressLint("TimberArgCount") + override fun onAttachView(view: CategoriesContract.View) { + this.view = view + compositeDisposable.add( + searchTerms + .observeOn(mainThreadScheduler) + .doOnNext { + view.showProgress(true) + }.switchMap(::searchResults) + .map { repository.selectedCategories + it } + .map { it.distinctBy { categoryItem -> categoryItem.name } } + .observeOn(mainThreadScheduler) + .subscribe( + { + setCategoryListValue(it) + view.showProgress(false) + if (it.isEmpty() && !isInitialLoad) { + view.showError(R.string.no_categories_found) + } + }, + { t: Throwable? -> + view.showProgress(false) view.showError(R.string.no_categories_found) - } - }, - { t: Throwable? -> - view.showProgress(false) - view.showError(R.string.no_categories_found) - Timber.e(t) - }, - ), - ) + Timber.e(t) + }, + ), + ) - //isInitialLoad = false - } + //isInitialLoad = false + } - private var isInitialLoad = true //avoid initial empty content of edittext lead to showError + private var isInitialLoad = true //avoid initial empty content of edittext lead to showError - /** - * If media is null : Fetches categories from server according to the term - * Else : Fetches existing categories by their name, fetches categories from server according - * to the term and combines both in a list - */ - private fun searchResults(term: String): Observable>? { - if (media == null) { - return repository - .searchAll(term, getImageTitleList(), repository.selectedDepictions) - .subscribeOn(ioScheduler) - .map { - it.filter { categoryItem -> - !repository.isSpammyCategory(categoryItem.name) || - categoryItem.name == term - } - } - } else { - return Observable - .zip( - repository - .getCategories(repository.selectedExistingCategories) - .map { list -> - list.map { - CategoryItem(it.name, it.description, it.thumbnail, true) - } - }, - repository.searchAll(term, getImageTitleList(), repository.selectedDepictions), - ) { it1, it2 -> - it1 + it2 - }.subscribeOn(ioScheduler) - .map { - it.filter { categoryItem -> - !repository.isSpammyCategory(categoryItem.name) || - categoryItem.name == term + /** + * If media is null : Fetches categories from server according to the term + * Else : Fetches existing categories by their name, fetches categories from server according + * to the term and combines both in a list + */ + private fun searchResults(term: String): Observable>? { + if (media == null) { + return repository + .searchAll(term, getImageTitleList(), repository.selectedDepictions) + .subscribeOn(ioScheduler) + .map { + it.filter { categoryItem -> + !repository.isSpammyCategory(categoryItem.name) || + categoryItem.name == term + } } - }.map { it.filterNot { categoryItem -> categoryItem.thumbnail == "hidden" } } + } else { + return Observable + .zip( + repository + .getCategories(repository.selectedExistingCategories) + .map { list -> + list.map { + CategoryItem(it.name, it.description, it.thumbnail, true) + } + }, + repository.searchAll(term, getImageTitleList(), repository.selectedDepictions), + ) { it1, it2 -> + it1 + it2 + }.subscribeOn(ioScheduler) + .map { + it.filter { categoryItem -> + !repository.isSpammyCategory(categoryItem.name) || + categoryItem.name == term + } + }.map { it.filterNot { categoryItem -> categoryItem.thumbnail == "hidden" } } + } } - } - override fun onDetachView() { - view = DUMMY - compositeDisposable.clear() - isInitialLoad = true - } + override fun onDetachView() { + view = DUMMY + compositeDisposable.clear() + isInitialLoad = true + } - /** - * asks the repository to fetch categories for the query - * @param query - */ - override fun searchForCategories(query: String) { - if (query.isBlank()) { - if (!isInitialLoad) { - view.showError(R.string.no_categories_found) + /** + * asks the repository to fetch categories for the query + * @param query + */ + override fun searchForCategories(query: String) { + if (query.isBlank()) { + if (!isInitialLoad) { + view.showError(R.string.no_categories_found) + } + return } - return + isInitialLoad = false + searchTerms.onNext(query) } - isInitialLoad = false - searchTerms.onNext(query) - } - /** - * Returns image title list from UploadItem - * @return - */ - private fun getImageTitleList(): List = - repository.uploads - .map { it.uploadMediaDetails[0].captionText } - .filterNot { TextUtils.isEmpty(it) } + /** + * Returns image title list from UploadItem + * @return + */ + private fun getImageTitleList(): List = + repository.uploads + .map { it.uploadMediaDetails[0].captionText } + .filterNot { TextUtils.isEmpty(it) } - /** - * Verifies the number of categories selected, prompts the user if none selected - */ - override fun verifyCategories() { - val selectedCategories = repository.selectedCategories - if (selectedCategories.isNotEmpty()) { - repository.setSelectedCategories(selectedCategories.map { it.name }) - view.goToNextScreen() - } else { - view.showNoCategorySelected() + /** + * Verifies the number of categories selected, prompts the user if none selected + */ + override fun verifyCategories() { + val selectedCategories = repository.selectedCategories + if (selectedCategories.isNotEmpty()) { + repository.setSelectedCategories(selectedCategories.map { it.name }) + view.goToNextScreen() + } else { + view.showNoCategorySelected() + } } - } - /** - * ask repository to handle category clicked - * - * @param categoryItem - */ - override fun onCategoryItemClicked(categoryItem: CategoryItem) { - repository.onCategoryClicked(categoryItem, media) - } + /** + * ask repository to handle category clicked + * + * @param categoryItem + */ + override fun onCategoryItemClicked(categoryItem: CategoryItem) { + repository.onCategoryClicked(categoryItem, media) + } - /** - * Attaches view and media - */ - override fun onAttachViewWithMedia( - view: CategoriesContract.View, - media: Media, - ) { - this.view = view - this.media = media - repository.selectedExistingCategories = view.existingCategories - compositeDisposable.add( - searchTerms - .observeOn(mainThreadScheduler) - .doOnNext { - view.showProgress(true) - }.switchMap(::searchResults) - .map { repository.selectedCategories + it } - .map { it.distinctBy { categoryItem -> categoryItem.name } } - .observeOn(mainThreadScheduler) - .subscribe( - { - setCategoryListValue(it) - view.showProgress(false) - if (it.isEmpty() && !isInitialLoad) { + /** + * Attaches view and media + */ + override fun onAttachViewWithMedia( + view: CategoriesContract.View, + media: Media, + ) { + this.view = view + this.media = media + repository.selectedExistingCategories = view.existingCategories + compositeDisposable.add( + searchTerms + .observeOn(mainThreadScheduler) + .doOnNext { + view.showProgress(true) + }.switchMap(::searchResults) + .map { repository.selectedCategories + it } + .map { it.distinctBy { categoryItem -> categoryItem.name } } + .observeOn(mainThreadScheduler) + .subscribe( + { + setCategoryListValue(it) + view.showProgress(false) + if (it.isEmpty() && !isInitialLoad) { + view.showError(R.string.no_categories_found) + } + }, + { t: Throwable? -> + view.showProgress(false) view.showError(R.string.no_categories_found) - } - }, - { t: Throwable? -> - view.showProgress(false) - view.showError(R.string.no_categories_found) - Timber.e(t) - }, - ), - ) - } + Timber.e(t) + }, + ), + ) + } - /** - * Clears previous selections - */ - override fun clearPreviousSelection() { - repository.cleanup() - } + /** + * Clears previous selections + */ + override fun clearPreviousSelection() { + repository.cleanup() + } - /** - * Gets the selected categories and send them for posting to the server - * - * @param media media - * @param wikiText current WikiText from server - */ - override fun updateCategories( - media: Media, - wikiText: String, - ) { - // check if view.existingCategories is null - if (repository.selectedCategories.isNotEmpty() || - (view.existingCategories != null && repository.selectedExistingCategories.size != view.existingCategories.size) + /** + * Gets the selected categories and send them for posting to the server + * + * @param media media + * @param wikiText current WikiText from server + */ + override fun updateCategories( + media: Media, + wikiText: String, ) { - val selectedCategories: MutableList = - ( - repository.selectedCategories.map { it.name }.toMutableList() + - repository.selectedExistingCategories - ).toMutableList() + // check if view.existingCategories is null + if (repository.selectedCategories.isNotEmpty() || + (view.existingCategories != null && repository.selectedExistingCategories.size != view.existingCategories.size) + ) { + val selectedCategories: MutableList = + ( + repository.selectedCategories.map { it.name }.toMutableList() + + repository.selectedExistingCategories + ).toMutableList() - if (selectedCategories.isNotEmpty()) { - view.showProgressDialog() + if (selectedCategories.isNotEmpty()) { + view.showProgressDialog() - try { - compositeDisposable.add( - categoryEditHelper - .makeCategoryEdit( - view.fragmentContext, - media, - selectedCategories, - wikiText, - ).subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ - Timber.d("Categories are added.") - media.addedCategories = selectedCategories - repository.cleanup() - view.dismissProgressDialog() - view.refreshCategories() - view.goBackToPreviousScreen() - }, { - Timber.e( - "Failed to update categories", - ) - }), - ) - } catch (e: InvalidLoginTokenException) { - view.navigateToLoginScreen() + try { + compositeDisposable.add( + categoryEditHelper + .makeCategoryEdit( + view.fragmentContext, + media, + selectedCategories, + wikiText, + ).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + Timber.d("Categories are added.") + media.addedCategories = selectedCategories + repository.cleanup() + view.dismissProgressDialog() + view.refreshCategories() + view.goBackToPreviousScreen() + }, { + Timber.e( + "Failed to update categories", + ) + }), + ) + } catch (e: InvalidLoginTokenException) { + view.navigateToLoginScreen() + } } + } else { + repository.cleanup() + view.showNoCategorySelected() } - } else { - repository.cleanup() - view.showNoCategorySelected() } - } - /** - * Selects each [CategoryItem] in a given list as if they were clicked by the user by calling - * [onCategoryItemClicked] for each category and adding the category to [categoryList] - */ - private fun selectNewCategories(toSelect: List) { - toSelect.forEach { - it.isSelected = true - repository.onCategoryClicked(it, media) - } + /** + * Selects each [CategoryItem] in a given list as if they were clicked by the user by calling + * [onCategoryItemClicked] for each category and adding the category to [categoryList] + */ + private fun selectNewCategories(toSelect: List) { + toSelect.forEach { + it.isSelected = true + repository.onCategoryClicked(it, media) + } - // Add the new selections to the list of category items so that the selections appear - // immediately (i.e. without any search term queries) - categoryList.value - ?.toMutableList() - ?.let { toSelect + it } - ?.distinctBy(CategoryItem::name) - ?.let { setCategoryListValue(it) } - } + // Add the new selections to the list of category items so that the selections appear + // immediately (i.e. without any search term queries) + categoryList.value + ?.toMutableList() + ?.let { toSelect + it } + ?.distinctBy(CategoryItem::name) + ?.let { setCategoryListValue(it) } + } - /** - * Livedata being used to observe category list inside - * @see UploadCategoriesFragment - * Any changes to category list reflect immediately to the adapter list - */ - override fun getCategories(): LiveData> = categoryList + /** + * Livedata being used to observe category list inside + * @see UploadCategoriesFragment + * Any changes to category list reflect immediately to the adapter list + */ + override fun getCategories(): LiveData> = categoryList - /** - * needed for tests - */ - fun setCategoryList(categoryList: MutableLiveData>) { - this.categoryList = categoryList - } + /** + * needed for tests + */ + fun setCategoryList(categoryList: MutableLiveData>) { + this.categoryList = categoryList + } - /** - * needed for tests - */ - fun setCategoryListValue(categoryItems: List) { - categoryList.postValue(categoryItems) - } + /** + * needed for tests + */ + fun setCategoryListValue(categoryItems: List) { + categoryList.postValue(categoryItems) + } - override fun selectCategories() { - compositeDisposable.add( - repository.placeCategories - .subscribeOn(ioScheduler) - .observeOn(mainThreadScheduler) - .subscribe(::selectNewCategories), - ) - } -} \ No newline at end of file + override fun selectCategories() { + compositeDisposable.add( + repository.placeCategories + .subscribeOn(ioScheduler) + .observeOn(mainThreadScheduler) + .subscribe(::selectNewCategories), + ) + } + } \ No newline at end of file From 14eb8c63581a7d928424c40fd652d203d54f4ed5 Mon Sep 17 00:00:00 2001 From: Zihan Pan Date: Tue, 22 Oct 2024 12:51:33 +1100 Subject: [PATCH 3/3] Remove redundent lines --- .../free/nrw/commons/upload/categories/CategoriesPresenter.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt index 92063d7cc7..a0f5a51136 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/categories/CategoriesPresenter.kt @@ -81,8 +81,6 @@ class CategoriesPresenter }, ), ) - - //isInitialLoad = false } private var isInitialLoad = true //avoid initial empty content of edittext lead to showError @@ -326,4 +324,4 @@ class CategoriesPresenter .subscribe(::selectNewCategories), ) } - } \ No newline at end of file + }