角色相关接口
This commit is contained in:
parent
a792dddc7c
commit
48b23cbdd3
|
|
@ -129,8 +129,9 @@ android {
|
|||
buildConfigString("API_PIGEON", "https://test-pigeon.xxxx.ai")
|
||||
buildConfigString("API_LION", "https://test-lion.xxxx.ai")
|
||||
buildConfigString("RECHAEGE_SERVICES", "https://test.xxxxx.ai/policy/recharge")
|
||||
|
||||
buildConfigString("RTC_APP_ID", "689ade491323ae01797818e0-XXX-TODO")
|
||||
|
||||
buildConfigString("API_BASE", "http://54.223.196.180:9090")
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -147,8 +148,9 @@ android {
|
|||
buildConfigString("API_PIGEON", "https://test-pigeon.xxxx.ai")
|
||||
buildConfigString("API_LION", "https://test-lion.xxxx.ai")
|
||||
buildConfigString("RECHAEGE_SERVICES", "https://test.xxxxx.ai/policy/recharge")
|
||||
|
||||
buildConfigString("RTC_APP_ID", "689ade491323ae01797818e0-XXX-TODO")
|
||||
|
||||
buildConfigString("API_BASE", "http://54.223.196.180:9090")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
<!--TODO - remove usesCleartextTraffic below-->
|
||||
<application
|
||||
android:name=".configs.NovelApplication"
|
||||
android:allowBackup="true"
|
||||
|
|
@ -40,7 +41,11 @@
|
|||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
>
|
||||
<activity
|
||||
android:name=".ui.splash.SplashActivity"
|
||||
android:theme="@style/AppTheme.Launcher"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.remax.visualnovel.api.service
|
||||
|
||||
import com.remax.visualnovel.BuildConfig
|
||||
import com.remax.visualnovel.entity.response.basenew.ResponseNew
|
||||
import com.remax.visualnovel.entity.request.ParamActorList
|
||||
import com.remax.visualnovel.entity.response.ActorBean
|
||||
import com.remax.visualnovel.entity.response.ActorTag
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
|
||||
|
||||
interface ActorsService {
|
||||
@GET(BuildConfig.API_BASE + "/tag/getTags")
|
||||
suspend fun requestActorTags(): ResponseNew<List<ActorTag>>
|
||||
|
||||
@POST(BuildConfig.API_BASE + "/character/select/list")
|
||||
suspend fun requestActorList(@Body param: ParamActorList): ResponseNew<List<ActorBean>>
|
||||
|
||||
/*@GET(BuildConfig.API_BASE + "/character/select/roleInfo/{roleId}")
|
||||
suspend fun requestActorInfo(): ResponseNew<ActorTag>*/
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.remax.visualnovel.app.di
|
|||
|
||||
import com.remax.visualnovel.api.factory.ServiceFactory
|
||||
import com.remax.visualnovel.api.service.AIService
|
||||
import com.remax.visualnovel.api.service.ActorsService
|
||||
import com.remax.visualnovel.api.service.BookService
|
||||
import com.remax.visualnovel.api.service.ChatService
|
||||
import com.remax.visualnovel.api.service.DictService
|
||||
|
|
@ -64,4 +65,10 @@ object ApiServiceModule {
|
|||
private inline fun <reified T> create(): T {
|
||||
return ServiceFactory.createService()
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun actorsService() = create<ActorsService>()
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.remax.visualnovel.entity.request
|
||||
|
||||
|
||||
data class ParamActorList(
|
||||
var index: Int = 0,
|
||||
var limit: Int = 2,
|
||||
var tagIds: List<Long> = listOf<Long>(),
|
||||
)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.remax.visualnovel.entity.response
|
||||
|
||||
|
||||
data class ActorBean(
|
||||
val id: Long,
|
||||
val roleName: String,
|
||||
val description: String,
|
||||
val coverImageId: String,
|
||||
val sourceId: Int, //来源ID;所属书籍/漫剧
|
||||
val sourceType: Int, //来源分类
|
||||
val commonCount: Int, //评论数
|
||||
val createTime: String,
|
||||
val status: String
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.remax.visualnovel.entity.response
|
||||
|
||||
|
||||
data class ActorTag(
|
||||
val tagName: String,
|
||||
val tagId: Long
|
||||
)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.remax.visualnovel.entity.response.basenew
|
||||
|
||||
|
||||
|
||||
class ResponseData<T> {
|
||||
val total = 0
|
||||
val index = 0
|
||||
val limit = 0
|
||||
val rows: T? = null
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package com.remax.visualnovel.entity.response.basenew
|
||||
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.remax.visualnovel.app.base.app.CommonApplicationProxy
|
||||
import com.remax.visualnovel.extension.toast
|
||||
|
||||
|
||||
open class ResponseNew<T>(
|
||||
@SerializedName(value = "data")
|
||||
val data: ResponseData<T>? = null,
|
||||
open val code: Int = -1,
|
||||
open val message: String = "",
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val SuccessCode = 200
|
||||
|
||||
/**
|
||||
* zip打包的错误error封装
|
||||
* new
|
||||
*/
|
||||
inline fun <reified T> createZipFailResponse(vararg data: ResponseNew<*>): ApiFailedResponse<T> {
|
||||
val failedResponse = ApiFailedResponse<T>()
|
||||
for (t in data) {
|
||||
if (!t.isApiSuccess) {
|
||||
failedResponse.code = t.code
|
||||
failedResponse.message = t.message
|
||||
break
|
||||
}
|
||||
}
|
||||
return failedResponse
|
||||
}
|
||||
}
|
||||
|
||||
val isOk: Boolean
|
||||
get() = code == SuccessCode
|
||||
|
||||
val isApiSuccess: Boolean
|
||||
get() =
|
||||
this is ApiSuccessResponse || this is ApiEmptyResponse
|
||||
|
||||
/**
|
||||
* 将返回结果分为成功和失败2个高阶函数
|
||||
*
|
||||
* 使用inline修饰,使2个参数可以调用外部函数return
|
||||
*/
|
||||
inline fun transformResult(apiSuccessCallback: ((T?) -> Unit) = {}, apiFailedCallback: ((ResponseNew<T>) -> Unit) = {}): ResponseNew<T> {
|
||||
if (isApiSuccess) {
|
||||
apiSuccessCallback.invoke(data?.rows)
|
||||
} else {
|
||||
apiFailedCallback.invoke(this)
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> ResponseNew<T>.parseData(listenerBuilder: (ResultBuilder<T>.() -> Unit), showToast: Boolean = false) {
|
||||
val listener = ResultBuilder<T>().also(listenerBuilder)
|
||||
when (this) {
|
||||
is ApiSuccessResponse -> listener.onSuccess(response?.rows)
|
||||
is ApiEmptyResponse -> listener.onSuccess(null)
|
||||
is ApiFailedResponse -> {
|
||||
listener.onFailed(this.code, this.message)
|
||||
listener.onFailedWithData(data?.rows)
|
||||
if (showToast) {
|
||||
CommonApplicationProxy.application.toast(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
listener.onComplete()
|
||||
}
|
||||
|
||||
class ResultBuilder<T> {
|
||||
var onSuccess: (data: T?) -> Unit = {}
|
||||
var onFailed: (errorCode: Int, errorMsg: String) -> Unit = { _, _ ->
|
||||
}
|
||||
var onFailedWithData: (errorData: T?) -> Unit = {}
|
||||
var onComplete: () -> Unit = {}
|
||||
}
|
||||
|
||||
data class ApiSuccessResponse<T>(val response: ResponseData<T>? = null) : ResponseNew<T>(data = response)
|
||||
|
||||
class ApiEmptyResponse<T> : ResponseNew<T>()
|
||||
|
||||
data class ApiFailedResponse<T>(override var code: Int = -1, override var message: String = "") :
|
||||
ResponseNew<T>(code = code, message = message)
|
||||
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
package com.remax.visualnovel.extension
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.remax.visualnovel.app.AbsView
|
||||
import com.remax.visualnovel.entity.response.basenew.ResponseNew
|
||||
import com.remax.visualnovel.entity.response.basenew.ResultBuilder
|
||||
import com.remax.visualnovel.entity.response.basenew.parseData
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
inline fun <T> launchFlow2(
|
||||
crossinline requestBlock: suspend () -> ResponseNew<T>,
|
||||
noinline startCallback: (() -> Unit)? = null,
|
||||
noinline completeCallback: (() -> Unit)? = null,
|
||||
): Flow<ResponseNew<T>> {
|
||||
return flow {
|
||||
emit(requestBlock())
|
||||
}.onStart {
|
||||
startCallback?.invoke()
|
||||
}.onCompletion {
|
||||
completeCallback?.invoke()
|
||||
}.flowOn(Dispatchers.Main)
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单的请求,不返回任何实体类, 无loading和toast,数据可通过livedata/flow监听
|
||||
*/
|
||||
inline fun AbsView.launchWithRequest2(crossinline requestBlock: suspend () -> Unit, showLoading: Boolean = false) {
|
||||
lifecycleScope.launch {
|
||||
flow {
|
||||
emit(requestBlock())
|
||||
}.onStart {
|
||||
if (showLoading) showLoading()
|
||||
}.onCompletion {
|
||||
if (showLoading) hideLoading()
|
||||
}.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用上面的,默认loading
|
||||
*/
|
||||
inline fun AbsView.launchWithRequestLoading2(crossinline requestBlock: suspend () -> Unit) {
|
||||
launchWithRequest(requestBlock, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 链式调用,返回结果的处理都在一起,viewmodel中不需要创建一个livedata对象
|
||||
* 适用于不需要监听数据变化/一次性使用的场景,比如提交表单/登录
|
||||
* 屏幕旋转,Activity销毁重建,数据会消失
|
||||
*
|
||||
* 默认无toast,无loading
|
||||
*/
|
||||
inline fun <reified T> AbsView.launchAndCollect2(
|
||||
crossinline requestBlock: suspend () -> ResponseNew<T>,
|
||||
showLoading: Boolean = false,
|
||||
showToast: Boolean = true,
|
||||
crossinline listenerBuilder: (ResultBuilder<T>.() -> Unit) = {}
|
||||
) {
|
||||
lifecycleScope.launch {
|
||||
launchFlow2(requestBlock, { if (showLoading) showLoading() }) { if (showLoading) hideLoading() }.collect { response ->
|
||||
response.parseData(listenerBuilder, showToast)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> AbsView.launchAndLoadingCollect2(
|
||||
crossinline requestBlock: suspend () -> ResponseNew<T>, showToast: Boolean = true, crossinline listenerBuilder: (ResultBuilder<T>.() -> Unit) = {}
|
||||
) {
|
||||
launchAndCollect2(requestBlock, showLoading = true, showToast = showToast, listenerBuilder = listenerBuilder)
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单flow流订阅 生命周期安全
|
||||
*/
|
||||
inline fun <T> Flow<T?>.flowWithLaunch2(
|
||||
lifecycleOwner: LifecycleOwner, minActiveState: Lifecycle.State = Lifecycle.State.STARTED, crossinline resCallback: ((t: T?) -> Unit)
|
||||
) {
|
||||
lifecycleOwner.lifecycleScope.launch {
|
||||
flowWithLifecycle(lifecycleOwner.lifecycle, minActiveState).collect {
|
||||
resCallback.invoke(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun <T> Flow<T>.flowWithLifecycle2(lifecycle: Lifecycle, minActiveState: Lifecycle.State = Lifecycle.State.STARTED): Flow<T> = callbackFlow {
|
||||
lifecycle.repeatOnLifecycle(minActiveState) {
|
||||
this@flowWithLifecycle2.collect {
|
||||
send(it)
|
||||
}
|
||||
}
|
||||
close()
|
||||
}
|
||||
|
||||
/**
|
||||
* response liveData监听
|
||||
*/
|
||||
inline fun <reified T> LiveData<ResponseNew<T>>.observeIn2(
|
||||
lifecycleOwner: LifecycleOwner, showToast: Boolean = true, crossinline listenerBuilder: ResultBuilder<T>.() -> Unit
|
||||
) {
|
||||
this.observe(lifecycleOwner, Observer {
|
||||
it.parseData(listenerBuilder, showToast)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅UI上展示Flow数据流
|
||||
*
|
||||
* 状态(State)用 StateFlow,粘性的 ;事件(Event)用 SharedFlow 在其 replayCache 中保留特定数量的最新值
|
||||
* MutableSharedFlow :一次性事件,不需要重放的状态变更(例如 Toast)
|
||||
* MutableStateFlow : 页面需要的状态,比如UI的刷新,多次执行没有任何问题
|
||||
* collectLastValue = true时,stateFlow也不会发送未改变的value,就和sharedFlow一样的用法
|
||||
*/
|
||||
inline fun <reified T> Flow<ResponseNew<T>>.collectIn2(
|
||||
lifecycleOwner: LifecycleOwner,
|
||||
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
|
||||
showToast: Boolean = true,
|
||||
crossinline listenerBuilder: ResultBuilder<T>.() -> Unit
|
||||
): Job {
|
||||
return lifecycleOwner.lifecycleScope.launch {
|
||||
flowWithLifecycle2(lifecycleOwner.lifecycle, minActiveState).collect {
|
||||
it.parseData(listenerBuilder, showToast)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
package com.remax.visualnovel.repository.api
|
||||
|
||||
import com.remax.visualnovel.entity.response.Book
|
||||
import com.remax.visualnovel.repository.api.base.BaseRepository
|
||||
import com.remax.visualnovel.api.service.BookService
|
||||
import com.remax.visualnovel.entity.response.base.Response
|
||||
import com.remax.visualnovel.api.service.ActorsService
|
||||
import com.remax.visualnovel.entity.request.ParamActorList
|
||||
import com.remax.visualnovel.repository.api.base.BaseRepositoryNew
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class ActorsRepository @Inject constructor(private val bookService: BookService) : BaseRepository() {
|
||||
suspend fun getBooks(): Response<Book> {
|
||||
return bookService.getBooks()
|
||||
class ActorsRepository @Inject constructor(private val mActorsService: ActorsService) : BaseRepositoryNew() {
|
||||
suspend fun getActorTags() = executeHttp {
|
||||
mActorsService.requestActorTags()
|
||||
}
|
||||
|
||||
suspend fun getActorList(param: ParamActorList) = executeHttp {
|
||||
mActorsService.requestActorList(param)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.remax.visualnovel.repository.api.base
|
||||
|
||||
|
||||
import com.remax.visualnovel.R
|
||||
import com.remax.visualnovel.app.base.app.CommonApplicationProxy
|
||||
import com.remax.visualnovel.constant.StatusCode
|
||||
import com.remax.visualnovel.entity.response.basenew.ApiEmptyResponse
|
||||
import com.remax.visualnovel.entity.response.basenew.ApiFailedResponse
|
||||
import com.remax.visualnovel.entity.response.basenew.ApiSuccessResponse
|
||||
import com.remax.visualnovel.entity.response.basenew.ResponseNew
|
||||
import com.remax.visualnovel.extension.toast
|
||||
import com.remax.visualnovel.manager.login.LoginManager
|
||||
import timber.log.Timber
|
||||
|
||||
open class BaseRepositoryNew {
|
||||
|
||||
/**
|
||||
* 如果不需要检查登录,那么在未登录的情况下 直接返回Success
|
||||
* @param checkLogin 检查登录,默认都需要检查
|
||||
*/
|
||||
suspend fun <T> executeHttp(checkLogin: Boolean = true, block: suspend () -> ResponseNew<T>): ResponseNew<T> {
|
||||
return if (!checkLogin) {
|
||||
if (LoginManager.isLogin) {
|
||||
execute(block)
|
||||
} else {
|
||||
ApiSuccessResponse()
|
||||
}
|
||||
} else {
|
||||
execute(block)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> execute(block: suspend () -> ResponseNew<T>): ResponseNew<T> {
|
||||
return try {
|
||||
val data = block.invoke()
|
||||
handleHttpOk(data)
|
||||
} catch (e: Exception) {
|
||||
handleHttpError(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 非后台返回错误,捕获到的异常
|
||||
*/
|
||||
private fun <T> handleHttpError(e: Throwable): ApiFailedResponse<T> {
|
||||
Timber.e("responseAsync error -> ${e.localizedMessage}")
|
||||
val errorMsg = CommonApplicationProxy.application.getString(R.string.your_network_error)
|
||||
return ApiFailedResponse(message = errorMsg)
|
||||
}
|
||||
|
||||
/**
|
||||
* http返回200,还要判断后端业务层isSuccess
|
||||
*/
|
||||
private fun <T> handleHttpOk(response: ResponseNew<T>): ResponseNew<T> {
|
||||
return when {
|
||||
//后端业务正常
|
||||
response.isOk -> {
|
||||
getHttpSuccessResponse(response)
|
||||
}
|
||||
|
||||
//登录超时
|
||||
response.code == /*StatusCode.TOKEN_EXPIRED.code*/403 -> {
|
||||
CommonApplicationProxy.application.toast(response.message)
|
||||
LoginManager.logout()
|
||||
ApiFailedResponse(response.code, response.message)
|
||||
}
|
||||
|
||||
//余额不足
|
||||
response.code == /*StatusCode.INSUFFICIENT_BALANCE.code*/ 610 -> {
|
||||
/*WalletManager.refreshWallet()
|
||||
WalletManager.showChargeDialog()*/
|
||||
ApiFailedResponse(response.code, response.message)
|
||||
}
|
||||
|
||||
else -> {
|
||||
ApiFailedResponse(response.code, response.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功和数据为空的处理
|
||||
*/
|
||||
private fun <T> getHttpSuccessResponse(response: ResponseNew<T>): ResponseNew<T> {
|
||||
val data = response.data
|
||||
return if (data == null) {
|
||||
ApiEmptyResponse()
|
||||
} else {
|
||||
ApiSuccessResponse(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,11 +9,14 @@ import androidx.recyclerview.widget.DefaultItemAnimator
|
|||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.chad.library.adapter.base.loadmore.LoadMoreStatus
|
||||
import com.dylanc.loadingstateview.BgColorType
|
||||
import com.remax.visualnovel.R
|
||||
import com.remax.visualnovel.app.base.BaseBindingFragment
|
||||
import com.remax.visualnovel.configs.NovelApplication
|
||||
import com.remax.visualnovel.databinding.FragmentMainActorBinding
|
||||
import com.remax.visualnovel.entity.request.ParamActorList
|
||||
import com.remax.visualnovel.extension.launchAndCollect2
|
||||
import com.remax.visualnovel.utils.Routers
|
||||
import com.remax.visualnovel.utils.StatusBarUtil3
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
|
@ -26,7 +29,10 @@ import kotlin.math.max
|
|||
class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
|
||||
|
||||
private lateinit var mActorAdapter: ActorsAdapter
|
||||
private val actorsViewModel by viewModels<ActorListViewModel>()
|
||||
private val mActorsModel by viewModels<ActorsViewModel>()
|
||||
private var mLoadedPageIndex = 0
|
||||
private val mRequestParam by lazy { ParamActorList() }
|
||||
|
||||
|
||||
override fun onCreated(bundle: Bundle?) {
|
||||
setUI()
|
||||
|
|
@ -36,6 +42,10 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
|
|||
return BgColorType.TRANSPARENT
|
||||
}
|
||||
|
||||
override fun lazyInit() {
|
||||
getActorList(true, showLoading = false)
|
||||
}
|
||||
|
||||
private fun setUI() {
|
||||
with(binding.root) {
|
||||
setPadding(
|
||||
|
|
@ -59,11 +69,22 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
|
|||
mActorsRv.addItemDecoration(GridSpacingItemDecoration(16))
|
||||
mActorsRv.setHasFixedSize(true)
|
||||
mActorsRv.itemAnimator = DefaultItemAnimator()
|
||||
|
||||
mActorAdapter = ActorsAdapter()
|
||||
mActorsRv.adapter = mActorAdapter
|
||||
|
||||
val characterList = createSampleData()
|
||||
mActorAdapter.setList(characterList)
|
||||
with(mActorAdapter) {
|
||||
setList(characterList)
|
||||
loadMoreModule.setOnLoadMoreListener {
|
||||
getActorList(false, showLoading = false)
|
||||
}
|
||||
}
|
||||
|
||||
with(refreshLayout) {
|
||||
onRefresh {
|
||||
getActorList(true, showLoading = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +115,55 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getActorList(isRefresh: Boolean, showLoading: Boolean) {
|
||||
if (isRefresh) {
|
||||
mLoadedPageIndex = 0
|
||||
}
|
||||
mRequestParam.index = mLoadedPageIndex + 1
|
||||
|
||||
launchAndCollect2({
|
||||
mActorsModel.getActorList(mRequestParam)
|
||||
}, showLoading = showLoading) {
|
||||
onSuccess = {
|
||||
val data = it ?: emptyList()
|
||||
with(mActorAdapter) {
|
||||
/*if (isRefresh) {
|
||||
setList(data)
|
||||
setMyEmptyView(R.string.no_character_yet, topMargin = 60)
|
||||
} else {
|
||||
addData(data)
|
||||
loadMoreModule.loadMoreComplete()
|
||||
}
|
||||
if (data.size < PageQuery.DEFAULT_PAGE_SIZE) {
|
||||
loadMoreModule.loadMoreEnd()
|
||||
}*/
|
||||
}
|
||||
mLoadedPageIndex++
|
||||
}
|
||||
|
||||
onComplete = {
|
||||
binding.refreshLayout.finishRefresh()
|
||||
mActorAdapter.loadMoreModule.loadMoreComplete()
|
||||
}
|
||||
|
||||
onFailed = { errorCode, errorMsg ->
|
||||
var temp = 100
|
||||
}
|
||||
|
||||
onFailedWithData = {
|
||||
var temp = 100
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private fun createSampleData(): List<ActorItem> {
|
||||
return listOf(
|
||||
ActorItem(
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package com.remax.visualnovel.ui.main.actor
|
||||
|
||||
|
||||
import com.remax.visualnovel.entity.response.Book
|
||||
import com.remax.visualnovel.app.viewmodel.base.BaseViewModel
|
||||
import com.remax.visualnovel.entity.response.base.Response
|
||||
import com.remax.visualnovel.repository.api.ActorsRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class ActorListViewModel @Inject constructor(private val chatRepository: ActorsRepository) : BaseViewModel() {
|
||||
|
||||
private val _msgStatFlow = MutableSharedFlow<Response<Book>>()
|
||||
val msgStatFlow = _msgStatFlow.asSharedFlow()
|
||||
|
||||
suspend fun getMessageStat() {
|
||||
_msgStatFlow.emit(chatRepository.getBooks())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.remax.visualnovel.ui.main.actor
|
||||
|
||||
|
||||
import com.remax.visualnovel.app.viewmodel.base.BaseViewModel
|
||||
import com.remax.visualnovel.entity.request.ParamActorList
|
||||
import com.remax.visualnovel.entity.response.basenew.ResponseNew
|
||||
import com.remax.visualnovel.entity.response.ActorBean
|
||||
import com.remax.visualnovel.repository.api.ActorsRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class ActorsViewModel @Inject constructor(private val mActorsRepository: ActorsRepository) : BaseViewModel() {
|
||||
|
||||
private val _actorsStatFlow = MutableSharedFlow<ResponseNew<List<ActorBean>>>()
|
||||
val actorsStatFlow = _actorsStatFlow.asSharedFlow()
|
||||
|
||||
suspend fun getActorList(param: ParamActorList) = mActorsRepository.getActorList(param)
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
<com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -27,12 +27,17 @@
|
|||
app:tag_expand_drawable="@mipmap/tag_flow_expand"
|
||||
app:tag_shrink_drawable="@mipmap/tag_flow_shrink" />
|
||||
|
||||
<com.drake.brv.PageRefreshLayout
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/dp_4">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/m_actors_rv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="@dimen/dp_4"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</com.drake.brv.PageRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.remax.visualnovel.widget.uitoken.view.UITokenLinearLayout>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">54.223.196.180</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
Loading…
Reference in New Issue