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:
parent
8b8e260945
commit
19eb04f19a
35 changed files with 296 additions and 544 deletions
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>?,
|
||||
)
|
|
@ -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)
|
|
@ -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
|
||||
)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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>
|
||||
)
|
|
@ -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"
|
||||
}
|
||||
]
|
|
@ -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
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
Loading…
Reference in a new issue