Loading app/src/main/java/foundation/e/apps/data/search/PlayStoreAppMapperImpl.kt 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.data.search import android.content.Context import com.aurora.gplayapi.data.models.App import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.utils.toApplication import foundation.e.apps.domain.search.PlayStoreAppMapper import javax.inject.Inject import javax.inject.Singleton @Singleton class PlayStoreAppMapperImpl @Inject constructor( @ApplicationContext private val context: Context, ) : PlayStoreAppMapper { override fun map(app: App): Application { return app.toApplication(context) } } app/src/main/java/foundation/e/apps/di/SearchPagingModule.kt +8 −0 Original line number Diff line number Diff line Loading @@ -23,9 +23,11 @@ import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.data.search.CleanApkSearchPagingRepository import foundation.e.apps.data.search.PlayStoreAppMapperImpl import foundation.e.apps.data.search.PlayStoreWebSearch import foundation.e.apps.data.search.PlayStoreWebSearchImpl import foundation.e.apps.data.search.SearchPagingRepository import foundation.e.apps.domain.search.PlayStoreAppMapper import javax.inject.Singleton @Module Loading @@ -42,4 +44,10 @@ abstract class SearchPagingModule { abstract fun bindPlayStoreWebSearch( impl: PlayStoreWebSearchImpl ): PlayStoreWebSearch @Binds @Singleton abstract fun bindPlayStoreAppMapper( impl: PlayStoreAppMapperImpl ): PlayStoreAppMapper } app/src/main/java/foundation/e/apps/domain/search/CleanApkSearchPagingUseCase.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import androidx.paging.PagingData import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.search.CleanApkSearchParams import foundation.e.apps.data.search.SearchPagingRepository import foundation.e.apps.ui.search.v2.SearchTabType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest import javax.inject.Inject class CleanApkSearchPagingUseCase @Inject constructor( private val searchPagingRepository: SearchPagingRepository, ) { @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke( requests: Flow<SearchRequest?>, tab: SearchTabType, appSource: String, appType: String, ): Flow<PagingData<Application>> { return requests .filterNotNull() .mapLatest { request -> if (!request.visibleTabs.contains(tab) || request.query.isBlank()) { flowOf(PagingData.empty<Application>()) } else { searchPagingRepository.cleanApkSearch( CleanApkSearchParams( keyword = request.query, appSource = appSource, appType = appType, ) ) } } .flatMapLatest { it } } } app/src/main/java/foundation/e/apps/domain/search/PlayStoreAppMapper.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import com.aurora.gplayapi.data.models.App import foundation.e.apps.data.application.data.Application interface PlayStoreAppMapper { fun map(app: App): Application } app/src/main/java/foundation/e/apps/domain/search/PlayStoreSearchPagingUseCase.kt 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import androidx.paging.PagingData import androidx.paging.map import com.aurora.gplayapi.data.models.App import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.search.PlayStorePagingRepository import foundation.e.apps.ui.search.v2.SearchTabType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import javax.inject.Inject class PlayStoreSearchPagingUseCase @Inject constructor( private val playStorePagingRepository: PlayStorePagingRepository, private val playStoreAppMapper: PlayStoreAppMapper, ) { @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke( requests: Flow<SearchRequest?>, pageSize: Int, tab: SearchTabType = SearchTabType.COMMON_APPS, ): Flow<PagingData<Application>> { return requests .filterNotNull() .mapLatest { request -> if (!request.visibleTabs.contains(tab) || request.query.isBlank()) { flowOf(PagingData.empty<Application>()) } else { playStorePagingRepository.playStoreSearch( query = request.query, pageSize = pageSize, ).map { pagingData: PagingData<App> -> pagingData.map { app: App -> playStoreAppMapper.map(app) } } } } .flatMapLatest { it } } } Loading
app/src/main/java/foundation/e/apps/data/search/PlayStoreAppMapperImpl.kt 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.data.search import android.content.Context import com.aurora.gplayapi.data.models.App import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.application.utils.toApplication import foundation.e.apps.domain.search.PlayStoreAppMapper import javax.inject.Inject import javax.inject.Singleton @Singleton class PlayStoreAppMapperImpl @Inject constructor( @ApplicationContext private val context: Context, ) : PlayStoreAppMapper { override fun map(app: App): Application { return app.toApplication(context) } }
app/src/main/java/foundation/e/apps/di/SearchPagingModule.kt +8 −0 Original line number Diff line number Diff line Loading @@ -23,9 +23,11 @@ import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.data.search.CleanApkSearchPagingRepository import foundation.e.apps.data.search.PlayStoreAppMapperImpl import foundation.e.apps.data.search.PlayStoreWebSearch import foundation.e.apps.data.search.PlayStoreWebSearchImpl import foundation.e.apps.data.search.SearchPagingRepository import foundation.e.apps.domain.search.PlayStoreAppMapper import javax.inject.Singleton @Module Loading @@ -42,4 +44,10 @@ abstract class SearchPagingModule { abstract fun bindPlayStoreWebSearch( impl: PlayStoreWebSearchImpl ): PlayStoreWebSearch @Binds @Singleton abstract fun bindPlayStoreAppMapper( impl: PlayStoreAppMapperImpl ): PlayStoreAppMapper }
app/src/main/java/foundation/e/apps/domain/search/CleanApkSearchPagingUseCase.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import androidx.paging.PagingData import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.search.CleanApkSearchParams import foundation.e.apps.data.search.SearchPagingRepository import foundation.e.apps.ui.search.v2.SearchTabType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest import javax.inject.Inject class CleanApkSearchPagingUseCase @Inject constructor( private val searchPagingRepository: SearchPagingRepository, ) { @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke( requests: Flow<SearchRequest?>, tab: SearchTabType, appSource: String, appType: String, ): Flow<PagingData<Application>> { return requests .filterNotNull() .mapLatest { request -> if (!request.visibleTabs.contains(tab) || request.query.isBlank()) { flowOf(PagingData.empty<Application>()) } else { searchPagingRepository.cleanApkSearch( CleanApkSearchParams( keyword = request.query, appSource = appSource, appType = appType, ) ) } } .flatMapLatest { it } } }
app/src/main/java/foundation/e/apps/domain/search/PlayStoreAppMapper.kt 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import com.aurora.gplayapi.data.models.App import foundation.e.apps.data.application.data.Application interface PlayStoreAppMapper { fun map(app: App): Application }
app/src/main/java/foundation/e/apps/domain/search/PlayStoreSearchPagingUseCase.kt 0 → 100644 +64 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.domain.search import androidx.paging.PagingData import androidx.paging.map import com.aurora.gplayapi.data.models.App import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.search.PlayStorePagingRepository import foundation.e.apps.ui.search.v2.SearchTabType import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import javax.inject.Inject class PlayStoreSearchPagingUseCase @Inject constructor( private val playStorePagingRepository: PlayStorePagingRepository, private val playStoreAppMapper: PlayStoreAppMapper, ) { @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke( requests: Flow<SearchRequest?>, pageSize: Int, tab: SearchTabType = SearchTabType.COMMON_APPS, ): Flow<PagingData<Application>> { return requests .filterNotNull() .mapLatest { request -> if (!request.visibleTabs.contains(tab) || request.query.isBlank()) { flowOf(PagingData.empty<Application>()) } else { playStorePagingRepository.playStoreSearch( query = request.query, pageSize = pageSize, ).map { pagingData: PagingData<App> -> pagingData.map { app: App -> playStoreAppMapper.map(app) } } } } .flatMapLatest { it } } }