0
0
Fork 0
mirror of https://github.com/YTVanced/VancedManager synced 2024-12-22 16:30:00 +00:00

feature/home-screen (Future functionality) Change realisation.

This commit is contained in:
HaliksaR 2020-11-28 22:58:02 +07:00
parent 8b8e260945
commit 19eb04f19a
35 changed files with 296 additions and 544 deletions

View file

@ -0,0 +1,15 @@
package com.vanced.manager.feature.home.data.api
import com.vanced.manager.feature.home.data.dto.AppInfoDto
import okhttp3.ResponseBody
import retrofit2.http.GET
import retrofit2.http.Url
interface AppsApi {
@GET
suspend fun getAppsInfo(@Url url: String): List<AppInfoDto>
@GET
suspend fun getIcon(@Url url: String): ResponseBody
}

View file

@ -1,14 +0,0 @@
package com.vanced.manager.feature.home.data.api
import com.vanced.manager.feature.home.data.dto.VancedAppsDto
import retrofit2.http.GET
interface GetAppInformationApi {
companion object {
const val URL = "/api/v1/latest.json"
}
@GET(URL)
suspend fun getAppInformation(): VancedAppsDto
}

View file

@ -0,0 +1,23 @@
package com.vanced.manager.feature.home.data.datasource
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.vanced.manager.feature.home.data.api.AppsApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
interface AppIconDataSource {
suspend fun getIcon(url: String): Bitmap
}
class AppIconDataSourceImpl(
private val api: AppsApi
) : AppIconDataSource {
override suspend fun getIcon(url: String): Bitmap =
withContext(Dispatchers.IO) {
val inputStream = api.getIcon(url).byteStream()
BitmapFactory.decodeStream(inputStream)
}
}

View file

@ -1,46 +0,0 @@
package com.vanced.manager.feature.home.data.datasource
import com.vanced.manager.feature.home.data.api.GetAppInformationApi
import com.vanced.manager.feature.home.data.dto.toEntity
import com.vanced.manager.feature.home.domain.entity.MicroGInfo
import com.vanced.manager.feature.home.domain.entity.VancedManagerInfo
import com.vanced.manager.feature.home.domain.entity.YouTubeMusicVancedInfo
import com.vanced.manager.feature.home.domain.entity.YouTubeVancedInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
interface AppInformationRemoteDataSource {
suspend fun getMicroGInformation(): MicroGInfo
suspend fun getVancedManagerInformation(): VancedManagerInfo
suspend fun getYouTubeMusicVancedInformation(): YouTubeMusicVancedInfo
suspend fun getYouTubeVancedInformation(): YouTubeVancedInfo
}
class AppInformationDataSourceImpl(
private val api: GetAppInformationApi
) : AppInformationRemoteDataSource {
override suspend fun getMicroGInformation(): MicroGInfo =
withContext(Dispatchers.IO) {
api.getAppInformation().microG.toEntity()
}
override suspend fun getVancedManagerInformation(): VancedManagerInfo =
withContext(Dispatchers.IO) {
api.getAppInformation().vancedManager.toEntity()
}
override suspend fun getYouTubeMusicVancedInformation(): YouTubeMusicVancedInfo =
withContext(Dispatchers.IO) {
api.getAppInformation().youTubeMusicVanced.toEntity()
}
override suspend fun getYouTubeVancedInformation(): YouTubeVancedInfo =
withContext(Dispatchers.IO) {
api.getAppInformation().youTubeVanced.toEntity()
}
}

View file

@ -0,0 +1,21 @@
package com.vanced.manager.feature.home.data.datasource
import com.vanced.manager.feature.home.data.api.AppsApi
import com.vanced.manager.feature.home.data.dto.AppInfoDto
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
interface AppsInfoDataSource {
suspend fun getAppsInfo(channel: String): List<AppInfoDto>
}
class AppsInfoDataSourceImpl(
private val api: AppsApi
) : AppsInfoDataSource {
override suspend fun getAppsInfo(channel: String): List<AppInfoDto> =
withContext(Dispatchers.IO) {
api.getAppsInfo(channel)
}
}

View file

@ -7,24 +7,30 @@ import kotlinx.coroutines.withContext
interface PkgInformationDataSource {
@Throws(PackageManager.NameNotFoundException::class)
suspend fun getVersionCode(packageName: String): Int
suspend fun getVersionCode(packageName: String): Int?
@Throws(PackageManager.NameNotFoundException::class)
suspend fun getVersionName(packageName: String): String
suspend fun getVersionName(packageName: String): String?
}
class PkgInformationDataSourceImpl(
private val pkgManager: PkgManager
) : PkgInformationDataSource {
override suspend fun getVersionCode(packageName: String): Int =
override suspend fun getVersionCode(packageName: String): Int? =
withContext(Dispatchers.IO) {
pkgManager.getVersionCode(packageName)
try {
pkgManager.getVersionCode(packageName)
} catch (exception: PackageManager.NameNotFoundException) {
null
}
}
override suspend fun getVersionName(packageName: String): String =
override suspend fun getVersionName(packageName: String): String? =
withContext(Dispatchers.IO) {
pkgManager.getVersionName(packageName)
try {
pkgManager.getVersionName(packageName)
} catch (exception: PackageManager.NameNotFoundException) {
null
}
}
}

View file

@ -0,0 +1,17 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class AppInfoDto(
@Json(name = "name") val name: String,
@Json(name = "iconUrl") val iconUrl: String,
@Json(name = "versionName") val versionName: String,
@Json(name = "versionCode") val versionCode: Int,
@Json(name = "pkgName") val pkgName: String,
@Json(name = "downloadUrl") val downloadUrl: String,
@Json(name = "changelog") val changelog: String,
@Json(name = "languages") val languages: List<String>?,
@Json(name = "themes") val themes: List<String>?,
)

View file

@ -1,19 +0,0 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.vanced.manager.feature.home.domain.entity.MicroGInfo
@JsonClass(generateAdapter = true)
data class MicroGDto(
@Json(name = "version") val version: String,
@Json(name = "versionCode") val versionCode: Int,
@Json(name = "url") val baseUrl: String,
@Json(name = "changelog") val changeLog: String
)
fun MicroGDto.toEntity() =
MicroGInfo(version, versionCode, baseUrl, changeLog)
fun MicroGInfo.toDto() =
MicroGDto(version, versionCode, baseUrl, changeLog)

View file

@ -1,12 +0,0 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VancedAppsDto(
@Json(name = "manager") val vancedManager: VancedManagerDto,
@Json(name = "vanced") val youTubeVanced: YouTubeVancedDto,
@Json(name = "music") val youTubeMusicVanced: YouTubeMusicVancedDto,
@Json(name = "microg") val microG: MicroGDto
)

View file

@ -1,19 +0,0 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.vanced.manager.feature.home.domain.entity.VancedManagerInfo
@JsonClass(generateAdapter = true)
data class VancedManagerDto(
@Json(name = "version") val version: String,
@Json(name = "versionCode") val versionCode: Int,
@Json(name = "url") val baseUrl: String,
@Json(name = "changelog") val changeLog: String
)
fun VancedManagerDto.toEntity() =
VancedManagerInfo(version, versionCode, baseUrl, changeLog)
fun VancedManagerInfo.toDto() =
VancedManagerDto(version, versionCode, baseUrl, changeLog)

View file

@ -1,19 +0,0 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.vanced.manager.feature.home.domain.entity.YouTubeMusicVancedInfo
@JsonClass(generateAdapter = true)
data class YouTubeMusicVancedDto(
@Json(name = "version") val version: String,
@Json(name = "versionCode") val versionCode: Int,
@Json(name = "url") val baseUrl: String,
@Json(name = "changelog") val changeLog: String
)
fun YouTubeMusicVancedDto.toEntity() =
YouTubeMusicVancedInfo(version, versionCode, baseUrl, changeLog)
fun YouTubeMusicVancedInfo.toDto() =
YouTubeMusicVancedDto(version, versionCode, baseUrl, changeLog)

View file

@ -1,21 +0,0 @@
package com.vanced.manager.feature.home.data.dto
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.vanced.manager.feature.home.domain.entity.YouTubeVancedInfo
@JsonClass(generateAdapter = true)
data class YouTubeVancedDto(
@Json(name = "version") val version: String,
@Json(name = "versionCode") val versionCode: Int,
@Json(name = "url") val baseUrl: String,
@Json(name = "changelog") val changeLog: String,
@Json(name = "themes") val themes: List<String>,
@Json(name = "langs") val langs: List<String>
)
fun YouTubeVancedDto.toEntity() =
YouTubeVancedInfo(version, versionCode, baseUrl, changeLog, themes, langs)
fun YouTubeVancedInfo.toDto() =
YouTubeVancedDto(version, versionCode, baseUrl, changeLog, themes, langs)

View file

@ -1,96 +0,0 @@
package com.vanced.manager.feature.home.data.repository
import android.content.pm.PackageManager
import com.vanced.manager.feature.home.data.datasource.AppInformationRemoteDataSource
import com.vanced.manager.feature.home.data.datasource.PkgInformationDataSource
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.entity.AppState
import com.vanced.manager.feature.home.domain.repository.AppRepository
class AppRepositoryImpl(
private val remoteDtaSource: AppInformationRemoteDataSource,
private val localDataSource: PkgInformationDataSource
) : AppRepository {
override suspend fun getMicroGInformation(
packageName: (App.MicroG.Companion) -> String
): App.MicroG {
val pkg = packageName(App.MicroG.Companion)
val remoteData = remoteDtaSource.getMicroGInformation()
val localCode = tryLocalCode(pkg)
return App.MicroG(
remoteInfo = remoteData,
localVersionCode = localCode,
localVersionName = tryLocalName(pkg),
state = compareCode(remoteData.versionCode, localCode)
)
}
override suspend fun getVancedManagerInformation(
packageName: (App.VancedManager.Companion) -> String
): App.VancedManager {
val pkg = packageName(App.VancedManager.Companion)
val remoteData = remoteDtaSource.getVancedManagerInformation()
val localCode = tryLocalCode(pkg)
return App.VancedManager(
remoteInfo = remoteData,
localVersionCode = localCode,
localVersionName = tryLocalName(pkg),
state = compareCode(remoteData.versionCode, localCode)
)
}
override suspend fun getYouTubeMusicVancedInformation(
packageName: (App.YouTubeMusicVanced.Companion) -> String
): App.YouTubeMusicVanced {
val pkg = packageName(App.YouTubeMusicVanced.Companion)
val remoteData = remoteDtaSource.getYouTubeMusicVancedInformation()
val localCode = tryLocalCode(pkg)
return App.YouTubeMusicVanced(
remoteInfo = remoteData,
localVersionCode = localCode,
localVersionName = tryLocalName(pkg),
state = compareCode(remoteData.versionCode, localCode)
)
}
override suspend fun getYouTubeVancedInformation(
packageName: (App.YouTubeVanced.Companion) -> String
): App.YouTubeVanced {
val pkg = packageName(App.YouTubeVanced.Companion)
val remoteData = remoteDtaSource.getYouTubeVancedInformation()
val localCode = tryLocalCode(pkg)
return App.YouTubeVanced(
remoteInfo = remoteData,
localVersionCode = localCode,
localVersionName = tryLocalName(pkg),
state = compareCode(remoteData.versionCode, localCode)
)
}
private fun compareCode(remote: Int, local: Int?): AppState =
if (local != null) {
when {
remote > local -> AppState.UPDATE
remote == local -> AppState.REINSTALL
remote < local -> AppState.REINSTALL
else -> throw IllegalArgumentException("Unknown versions")
}
} else {
AppState.INSTALL
}
private suspend fun tryLocalCode(packageName: String): Int? =
try {
localDataSource.getVersionCode(packageName)
} catch (exception: PackageManager.NameNotFoundException) {
null
}
private suspend fun tryLocalName(packageName: String): String? =
try {
localDataSource.getVersionName(packageName)
} catch (exception: PackageManager.NameNotFoundException) {
null
}
}

View file

@ -0,0 +1,54 @@
package com.vanced.manager.feature.home.data.repository
import com.vanced.manager.feature.home.data.datasource.AppIconDataSource
import com.vanced.manager.feature.home.data.datasource.AppsInfoDataSource
import com.vanced.manager.feature.home.data.datasource.PkgInformationDataSource
import com.vanced.manager.feature.home.data.dto.AppInfoDto
import com.vanced.manager.feature.home.domain.entity.AppInfo
import com.vanced.manager.feature.home.domain.entity.AppState
import com.vanced.manager.feature.home.domain.repository.AppsRepository
class AppsRepositoryImpl(
private val appsInfoDataSource: AppsInfoDataSource,
private val appIconDataSource: AppIconDataSource,
private val pkgInformationDataSource: PkgInformationDataSource,
private val channel: String //TODO experiment
) : AppsRepository {
// TODO switch content OR send toggles to build retrofit and change channel get json
override suspend fun getAppsInfo(): List<AppInfo> =
appsInfoDataSource.getAppsInfo(channel)
.map { it.toEntity() }
private suspend fun AppInfoDto.toEntity(): AppInfo {
val localVersionName = pkgInformationDataSource.getVersionName(pkgName)
val localVersionCode = pkgInformationDataSource.getVersionCode(pkgName)
return AppInfo(
name = name,
icon = appIconDataSource.getIcon(iconUrl),
versionName = versionName,
versionCode = versionCode,
pkgName = pkgName,
downloadUrl = downloadUrl,
changelog = changelog,
languages = languages,
themes = themes,
localVersionName = localVersionName,
localVersionCode = localVersionCode,
state = compareCode(versionCode, localVersionCode)
)
}
private fun compareCode(remote: Int, local: Int?): AppState =
if (local != null) {
when {
remote > local -> AppState.UPDATE
remote == local -> AppState.REINSTALL
remote < local -> AppState.REINSTALL
else -> throw IllegalArgumentException("Unknown versions")
}
} else {
AppState.INSTALL
}
}

View file

@ -1,26 +1,24 @@
package com.vanced.manager.feature.home.di
import com.vanced.manager.feature.home.data.api.GetAppInformationApi
import com.vanced.manager.feature.home.data.datasource.AppInformationDataSourceImpl
import com.vanced.manager.feature.home.data.datasource.AppInformationRemoteDataSource
import com.vanced.manager.feature.home.data.api.AppsApi
import com.vanced.manager.feature.home.data.datasource.AppsInfoDataSource
import com.vanced.manager.feature.home.data.datasource.AppsInfoDataSourceImpl
import com.vanced.manager.feature.home.data.datasource.PkgInformationDataSource
import com.vanced.manager.feature.home.data.datasource.PkgInformationDataSourceImpl
import com.vanced.manager.feature.home.data.pkg.PkgManager
import com.vanced.manager.feature.home.data.pkg.PkgManagerImpl
import com.vanced.manager.feature.home.data.repository.AppRepositoryImpl
import com.vanced.manager.feature.home.domain.repository.AppRepository
import com.vanced.manager.feature.home.domain.usecase.GetMicroGInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetVancedManagerInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetYouTubeMusicVancedInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetYouTubeVancedInformationUseCase
import com.vanced.manager.feature.home.data.repository.AppsRepositoryImpl
import com.vanced.manager.feature.home.domain.repository.AppsRepository
import com.vanced.manager.feature.home.domain.usecase.GetAppsInfoUseCase
import com.vanced.manager.feature.home.presentation.HomeViewModel
import com.vanced.manager.library.network.service.createRetrofitService
import org.koin.android.ext.koin.androidContext
import org.koin.android.viewmodel.dsl.viewModel
import org.koin.core.qualifier.named
import org.koin.dsl.module
internal val retrofitModule = module {
single<GetAppInformationApi> { createRetrofitService(get()) }
single<AppsApi> { createRetrofitService(get()) }
}
internal val pkgManagerModule = module {
@ -28,39 +26,43 @@ internal val pkgManagerModule = module {
}
internal val dataSourceModule = module {
single<AppInformationRemoteDataSource> { AppInformationDataSourceImpl(api = get()) }
single<AppsInfoDataSource> { AppsInfoDataSourceImpl(api = get()) }
single<PkgInformationDataSource> { PkgInformationDataSourceImpl(pkgManager = get()) }
}
internal val channelModule = module {
factory(named("channel")) {
listOf(
"https://vancedapp.com/api/v1/latest.json",
"https://vancedapp.com/api/v1/latest_root.json",
"https://vancedapp.custom.com/api/v1/latest.json",
"https://vancedapp.custom.com/api/v1/latest_root.json"
).random()
}
}
internal val repositoryModule = module {
single<AppRepository> {
AppRepositoryImpl(
remoteDtaSource = get(),
localDataSource = get()
factory<AppsRepository> {
AppsRepositoryImpl(
appsInfoDataSource = get(),
appIconDataSource = get(),
pkgInformationDataSource = get(),
channel = get(named("channel")) //TODO experiment
)
}
}
internal val useCaseModule = module {
single { GetMicroGInformationUseCase(repository = get()) }
single { GetVancedManagerInformationUseCase(repository = get()) }
single { GetYouTubeMusicVancedInformationUseCase(repository = get()) }
single { GetYouTubeVancedInformationUseCase(repository = get()) }
single { GetAppsInfoUseCase(repository = get()) }
}
internal val viewModelModule = module {
viewModel {
HomeViewModel(
getMicroGInformationUseCase = get(),
getVancedManagerInformationUseCase = get(),
getYouTubeMusicVancedInformationUseCase = get(),
getYouTubeVancedInformationUseCase = get()
)
}
viewModel { HomeViewModel(getAppsInfoUseCase = get()) }
}
val FeatureHomeModules = listOf(
channelModule, //TODO experiment
retrofitModule,
pkgManagerModule,
dataSourceModule,

View file

@ -1,55 +0,0 @@
package com.vanced.manager.feature.home.domain.entity
sealed class App<R>(
open val remoteInfo: R,
open val localVersionCode: Int?,
open val localVersionName: String?,
open val state: AppState
) {
data class MicroG(
override val remoteInfo: MicroGInfo,
override val localVersionCode: Int?,
override val localVersionName: String?,
override val state: AppState
) : App<MicroGInfo>(remoteInfo, localVersionCode, localVersionName, state) {
companion object {
const val PKG_NAME = "com.mgoogle.android.gms"
}
}
data class VancedManager(
override val remoteInfo: VancedManagerInfo,
override val localVersionCode: Int?,
override val localVersionName: String?,
override val state: AppState
) : App<VancedManagerInfo>(remoteInfo, localVersionCode, localVersionName, state) {
companion object {
const val PKG_NAME = "com.vanced.manager" // TODO replace
}
}
data class YouTubeMusicVanced(
override val remoteInfo: YouTubeMusicVancedInfo,
override val localVersionCode: Int?,
override val localVersionName: String?,
override val state: AppState
) : App<YouTubeMusicVancedInfo>(remoteInfo, localVersionCode, localVersionName, state) {
companion object {
const val PKG_NAME = "com.vanced.android.apps.youtube.music"
const val PKG_NAME_ROOT = "com.google.android.apps.youtube.music"
}
}
data class YouTubeVanced(
override val remoteInfo: YouTubeVancedInfo,
override val localVersionCode: Int?,
override val localVersionName: String?,
override val state: AppState
) : App<YouTubeVancedInfo>(remoteInfo, localVersionCode, localVersionName, state) {
companion object {
const val PKG_NAME = "com.vanced.android.youtube"
const val PKG_NAME_ROOT = "com.google.android.youtube"
}
}
}

View file

@ -0,0 +1,18 @@
package com.vanced.manager.feature.home.domain.entity
import android.graphics.Bitmap
data class AppInfo(
val name: String,
val icon: Bitmap,
val versionName: String,
val versionCode: Int,
val pkgName: String,
val downloadUrl: String,
val changelog: String,
val languages: List<String>?,
val themes: List<String>?,
val localVersionName: String?,
val localVersionCode: Int?,
val state: AppState,
)

View file

@ -1,8 +0,0 @@
package com.vanced.manager.feature.home.domain.entity
data class MicroGInfo(
val version: String,
val versionCode: Int,
val baseUrl: String,
val changeLog: String
)

View file

@ -1,8 +0,0 @@
package com.vanced.manager.feature.home.domain.entity
data class VancedManagerInfo(
val version: String,
val versionCode: Int,
val baseUrl: String,
val changeLog: String
)

View file

@ -1,8 +0,0 @@
package com.vanced.manager.feature.home.domain.entity
data class YouTubeMusicVancedInfo(
val version: String,
val versionCode: Int,
val baseUrl: String,
val changeLog: String
)

View file

@ -1,10 +0,0 @@
package com.vanced.manager.feature.home.domain.entity
data class YouTubeVancedInfo(
val version: String,
val versionCode: Int,
val baseUrl: String,
val changeLog: String,
val themes: List<String>,
val langs: List<String>
)

View file

@ -0,0 +1,60 @@
[
{
"name": "manager",
"iconUrl": "https://github.com/YTVanced/VancedManager/icon.png",
"versionName": "2.0.1",
"versionCode": 201,
"pkgName": "com.vanced.manager",
"downloadUrl": "https://github.com/YTVanced/VancedManager/releases/latest/download",
"changelog": "- Fixed issues with Android 5 and 6\n- Fixed various crashes\n- Improved performance"
},
{
"name": "vanced",
"iconUrl": "https://github.com/YTVanced/icon.png",
"versionName": "15.43.32",
"versionCode": 1515701696,
"pkgName": "com.vanced.android.youtube",
"downloadUrl": "https://github.com/YTVanced/releases/latest/download",
"changelog": "- Added toggle to revert to ExoPlayer V1\\r\\n- Added toggle to hide the new big Create button\\r\\n- A lot of fixes to old features",
"languages": [
"af",
"am",
"ar",
"az",
"be",
"bg",
"bn",
"bs",
"ca",
"cs",
"da",
"de",
"el",
"en"
],
// may be null,
"themes": [
"dark",
"black"
]
// may be null
},
{
"name": "music",
"iconUrl": "https://github.com/YTMVanced/icon.png",
"versionName": "4.04.52",
"versionCode": 40452240,
"pkgName": "com.vanced.android.apps.youtube.music",
"downloadUrl": "https://github.com/YTMVanced/releases/latest/download",
"changelog": "- Added a toggle switch for outline icons\\n- Toolbar premium button has been removed"
},
{
"name": "microg",
"iconUrl": "https://github.com/microg/icon.png",
"versionName": "0.2.14.204215",
"versionCode": 204215001,
"pkgName": "com.vanced.android.apps.youtube.music",
"downloadUrl": "https://github.com/microg/releases/latest/download",
"changelog": "- Updated to upstream sources\\n- Fixed video uploading"
}
]

View file

@ -1,22 +0,0 @@
package com.vanced.manager.feature.home.domain.repository
import com.vanced.manager.feature.home.domain.entity.App
interface AppRepository {
suspend fun getMicroGInformation(
packageName: (App.MicroG.Companion) -> String
): App.MicroG
suspend fun getVancedManagerInformation(
packageName: (App.VancedManager.Companion) -> String
): App.VancedManager
suspend fun getYouTubeMusicVancedInformation(
packageName: (App.YouTubeMusicVanced.Companion) -> String
): App.YouTubeMusicVanced
suspend fun getYouTubeVancedInformation(
packageName: (App.YouTubeVanced.Companion) -> String
): App.YouTubeVanced
}

View file

@ -0,0 +1,8 @@
package com.vanced.manager.feature.home.domain.repository
import com.vanced.manager.feature.home.domain.entity.AppInfo
interface AppsRepository {
suspend fun getAppsInfo(): List<AppInfo>
}

View file

@ -0,0 +1,12 @@
package com.vanced.manager.feature.home.domain.usecase
import com.vanced.manager.feature.home.domain.entity.AppInfo
import com.vanced.manager.feature.home.domain.repository.AppsRepository
class GetAppsInfoUseCase(
private val repository: AppsRepository
) {
suspend operator fun invoke(): List<AppInfo> =
repository.getAppsInfo()
}

View file

@ -1,13 +0,0 @@
package com.vanced.manager.feature.home.domain.usecase
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.repository.AppRepository
class GetMicroGInformationUseCase(
private val repository: AppRepository
) {
suspend operator fun invoke(
packageName: (App.MicroG.Companion) -> String
): App.MicroG = repository.getMicroGInformation(packageName)
}

View file

@ -1,13 +0,0 @@
package com.vanced.manager.feature.home.domain.usecase
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.repository.AppRepository
class GetVancedManagerInformationUseCase(
private val repository: AppRepository
) {
suspend operator fun invoke(
packageName: (App.VancedManager.Companion) -> String
): App.VancedManager = repository.getVancedManagerInformation(packageName)
}

View file

@ -1,13 +0,0 @@
package com.vanced.manager.feature.home.domain.usecase
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.repository.AppRepository
class GetYouTubeMusicVancedInformationUseCase(
private val repository: AppRepository
) {
suspend operator fun invoke(
packageName: (App.YouTubeMusicVanced.Companion) -> String
): App.YouTubeMusicVanced = repository.getYouTubeMusicVancedInformation(packageName)
}

View file

@ -1,13 +0,0 @@
package com.vanced.manager.feature.home.domain.usecase
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.repository.AppRepository
class GetYouTubeVancedInformationUseCase(
private val repository: AppRepository
) {
suspend operator fun invoke(
packageName: (App.YouTubeVanced.Companion) -> String
): App.YouTubeVanced = repository.getYouTubeVancedInformation(packageName)
}

View file

@ -2,57 +2,27 @@ package com.vanced.manager.feature.home.presentation
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.vanced.manager.feature.home.domain.entity.App
import com.vanced.manager.feature.home.domain.usecase.GetMicroGInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetVancedManagerInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetYouTubeMusicVancedInformationUseCase
import com.vanced.manager.feature.home.domain.usecase.GetYouTubeVancedInformationUseCase
import com.vanced.manager.feature.home.domain.entity.AppInfo
import com.vanced.manager.feature.home.domain.usecase.GetAppsInfoUseCase
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import retrofit2.HttpException
class HomeViewModel(
private val getMicroGInformationUseCase: GetMicroGInformationUseCase,
private val getVancedManagerInformationUseCase: GetVancedManagerInformationUseCase,
private val getYouTubeMusicVancedInformationUseCase: GetYouTubeMusicVancedInformationUseCase,
private val getYouTubeVancedInformationUseCase: GetYouTubeVancedInformationUseCase
private val getAppsInfoUseCase: GetAppsInfoUseCase
) : ViewModel() {
private val _microG = MutableSharedFlow<App.MicroG>()
val microG: SharedFlow<App.MicroG> =
_microG.asSharedFlow()
private val _appsList = MutableSharedFlow<List<AppInfo>>()
val appsList: SharedFlow<List<AppInfo>> =
_appsList.asSharedFlow()
private val _vancedManager = MutableSharedFlow<App.VancedManager>()
val vancedManager: SharedFlow<App.VancedManager> =
_vancedManager.asSharedFlow()
private val _youTubeVanced = MutableSharedFlow<App.YouTubeVanced>()
val youTubeVanced: SharedFlow<App.YouTubeVanced> =
_youTubeVanced.asSharedFlow()
private val _youTubeVancedRoot = MutableSharedFlow<App.YouTubeVanced>()
val youTubeVancedRoot: SharedFlow<App.YouTubeVanced> =
_youTubeVancedRoot.asSharedFlow()
private val _youTubeMusicVanced = MutableSharedFlow<App.YouTubeMusicVanced>()
val youTubeMusicVanced: SharedFlow<App.YouTubeMusicVanced> =
_youTubeMusicVanced.asSharedFlow()
private val _youTubeMusicVancedRoot = MutableSharedFlow<App.YouTubeMusicVanced>()
val youTubeMusicVancedRoot: SharedFlow<App.YouTubeMusicVanced> =
_youTubeMusicVancedRoot.asSharedFlow()
fun fetchAppInformation() {
fun fetchAppsInfo() {
viewModelScope.launch {
try {
_microG.emit(getMicroGInformationUseCase { it.PKG_NAME })
_vancedManager.emit(getVancedManagerInformationUseCase { it.PKG_NAME })
_youTubeVanced.emit(getYouTubeVancedInformationUseCase { it.PKG_NAME })
_youTubeVancedRoot.emit(getYouTubeVancedInformationUseCase { it.PKG_NAME_ROOT })
_youTubeMusicVanced.emit(getYouTubeMusicVancedInformationUseCase { it.PKG_NAME })
_youTubeMusicVancedRoot.emit(getYouTubeMusicVancedInformationUseCase { it.PKG_NAME_ROOT })
} catch (exception: Exception) {
_appsList.emit(getAppsInfoUseCase())
} catch (exception: HttpException) {
//TODO state
}
}

View file

@ -6,6 +6,7 @@ import android.view.ViewGroup
import com.vanced.manager.core.ui.base.BindingFragment
import com.vanced.manager.feature.home.databinding.FragmentHomeBinding
import com.vanced.manager.feature.home.presentation.HomeViewModel
import com.vanced.manager.feature.home.ui.bind.bindData
import org.koin.android.viewmodel.ext.android.viewModel
class HomeFragment : BindingFragment<FragmentHomeBinding>() {
@ -18,4 +19,7 @@ class HomeFragment : BindingFragment<FragmentHomeBinding>() {
savedInstanceState: Bundle?
) = FragmentHomeBinding.inflate(inflater, container, false)
override fun otherSetups() {
bindData(binding, viewModel)
}
}

View file

@ -1,53 +1,18 @@
package com.vanced.manager.feature.home.ui.bind
import android.util.Log
import androidx.lifecycle.coroutineScope
import com.vanced.manager.feature.home.databinding.FragmentHomeBinding
import com.vanced.manager.feature.home.presentation.HomeViewModel
import com.vanced.manager.feature.home.ui.HomeFragment
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
internal fun HomeFragment.bindData(
binding: FragmentHomeBinding,
viewModel: HomeViewModel
) {
/* requireActivity().title = getString(R.string.title_home)
setHasOptionsMenu(true)
with(binding) {
homeRefresh.setOnRefreshListener { viewModel.fetchData() }
tooltip = ViewTooltip
.on(recyclerAppList)
.position(ViewTooltip.Position.TOP)
.autoHide(false, 0)
.color(ResourcesCompat.getColor(requireActivity().resources, R.color.Twitter, null))
.withShadow(false)
.corner(25)
.onHide {
prefs.edit { putBoolean("show_changelog_tooltip", false) }
}
.text(requireActivity().getString(R.string.app_changelog_tooltip))
if (prefs.getBoolean("show_changelog_tooltip", true)) {
tooltip.show()
}
recyclerAppList.apply {
layoutManager = LinearLayoutManager(requireActivity())
adapter = AppListAdapter(requireActivity(), viewModel, viewLifecycleOwner, tooltip)
setHasFixedSize(true)
}
recyclerSponsors.apply {
val lm = FlexboxLayoutManager(requireActivity())
lm.justifyContent = JustifyContent.SPACE_EVENLY
layoutManager = lm
setHasFixedSize(true)
adapter = SponsorAdapter(requireActivity(), viewModel)
}
recyclerLinks.apply {
val lm = FlexboxLayoutManager(requireActivity())
lm.justifyContent = JustifyContent.SPACE_EVENLY
layoutManager = lm
setHasFixedSize(true)
adapter = LinkAdapter(requireActivity(), viewModel)
}
}*/
viewModel.appsList.onEach {
Log.d("apps", it.toString())
}.launchIn(viewLifecycleOwner.lifecycle.coroutineScope)
}

View file

@ -1,15 +1,6 @@
package com.vanced.manager.feature.home.data.datasource
import com.vanced.manager.feature.home.data.api.GetAppInformationApi
import com.vanced.manager.feature.home.data.dto.*
import com.vanced.manager.feature.home.domain.entity.MicroGInfo
import com.vanced.manager.feature.home.domain.entity.VancedManagerInfo
import com.vanced.manager.feature.home.domain.entity.YouTubeMusicVancedInfo
import com.vanced.manager.feature.home.domain.entity.YouTubeVancedInfo
import io.kotest.core.spec.style.ShouldSpec
import io.kotest.matchers.shouldBe
import io.mockk.coEvery
import io.mockk.mockk
/*
internal class AppInformationDataSourceImplTest : ShouldSpec() {
@ -74,4 +65,4 @@ internal class AppInformationDataSourceImplTest : ShouldSpec() {
}
}
}
}
}*/

View file

@ -1,11 +1,6 @@
package com.vanced.manager.feature.home.data.datasource
import com.vanced.manager.feature.home.data.pkg.PkgManager
import io.kotest.core.spec.style.ShouldSpec
import io.kotest.matchers.shouldBe
import io.mockk.coEvery
import io.mockk.mockk
/*
internal class PkgInformationDataSourceImplTest : ShouldSpec() {
private val pkgManager: PkgManager = mockk()
@ -26,4 +21,4 @@ internal class PkgInformationDataSourceImplTest : ShouldSpec() {
dataSource.getVersionName(testPackageName) shouldBe expectation
}
}
}
}*/