diff --git a/VisualNovel/app/build.gradle.kts b/VisualNovel/app/build.gradle.kts index d574124..0c9f7b1 100644 --- a/VisualNovel/app/build.gradle.kts +++ b/VisualNovel/app/build.gradle.kts @@ -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") } } } diff --git a/VisualNovel/app/src/main/AndroidManifest.xml b/VisualNovel/app/src/main/AndroidManifest.xml index d694bf8..fb73b13 100644 --- a/VisualNovel/app/src/main/AndroidManifest.xml +++ b/VisualNovel/app/src/main/AndroidManifest.xml @@ -31,6 +31,7 @@ + + android:theme="@style/AppTheme" + + android:usesCleartextTraffic="true" + android:networkSecurityConfig="@xml/network_security_config" + > > + + @POST(BuildConfig.API_BASE + "/character/select/list") + suspend fun requestActorList(@Body param: ParamActorList): ResponseNew> + + /*@GET(BuildConfig.API_BASE + "/character/select/roleInfo/{roleId}") + suspend fun requestActorInfo(): ResponseNew*/ + + +} \ No newline at end of file diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/app/di/ApiServiceModule.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/app/di/ApiServiceModule.kt index b9c116d..7833166 100644 --- a/VisualNovel/app/src/main/java/com/remax/visualnovel/app/di/ApiServiceModule.kt +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/app/di/ApiServiceModule.kt @@ -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 create(): T { return ServiceFactory.createService() } + + @Singleton + @Provides + fun actorsService() = create() + + } \ No newline at end of file diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/request/ParamActorList.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/request/ParamActorList.kt new file mode 100644 index 0000000..6ca95d6 --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/request/ParamActorList.kt @@ -0,0 +1,8 @@ +package com.remax.visualnovel.entity.request + + +data class ParamActorList( + var index: Int = 0, + var limit: Int = 2, + var tagIds: List = listOf(), +) diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorBean.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorBean.kt new file mode 100644 index 0000000..c95ed12 --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorBean.kt @@ -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 +) diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorTag.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorTag.kt new file mode 100644 index 0000000..4aad76b --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/ActorTag.kt @@ -0,0 +1,7 @@ +package com.remax.visualnovel.entity.response + + +data class ActorTag( + val tagName: String, + val tagId: Long +) diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseData.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseData.kt new file mode 100644 index 0000000..2f1f71d --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseData.kt @@ -0,0 +1,10 @@ +package com.remax.visualnovel.entity.response.basenew + + + +class ResponseData { + val total = 0 + val index = 0 + val limit = 0 + val rows: T? = null +} diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseNew.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseNew.kt new file mode 100644 index 0000000..fdfefcd --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/entity/response/basenew/ResponseNew.kt @@ -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( + @SerializedName(value = "data") + val data: ResponseData? = null, + open val code: Int = -1, + open val message: String = "", +) { + + companion object { + const val SuccessCode = 200 + + /** + * zip打包的错误error封装 + * new + */ + inline fun createZipFailResponse(vararg data: ResponseNew<*>): ApiFailedResponse { + val failedResponse = ApiFailedResponse() + 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) -> Unit) = {}): ResponseNew { + if (isApiSuccess) { + apiSuccessCallback.invoke(data?.rows) + } else { + apiFailedCallback.invoke(this) + } + return this + } +} + +inline fun ResponseNew.parseData(listenerBuilder: (ResultBuilder.() -> Unit), showToast: Boolean = false) { + val listener = ResultBuilder().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 { + var onSuccess: (data: T?) -> Unit = {} + var onFailed: (errorCode: Int, errorMsg: String) -> Unit = { _, _ -> + } + var onFailedWithData: (errorData: T?) -> Unit = {} + var onComplete: () -> Unit = {} +} + +data class ApiSuccessResponse(val response: ResponseData? = null) : ResponseNew(data = response) + +class ApiEmptyResponse : ResponseNew() + +data class ApiFailedResponse(override var code: Int = -1, override var message: String = "") : + ResponseNew(code = code, message = message) + diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/extension/FlowKtx2.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/extension/FlowKtx2.kt new file mode 100644 index 0000000..36d2bc3 --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/extension/FlowKtx2.kt @@ -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 launchFlow2( + crossinline requestBlock: suspend () -> ResponseNew, + noinline startCallback: (() -> Unit)? = null, + noinline completeCallback: (() -> Unit)? = null, +): Flow> { + 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 AbsView.launchAndCollect2( + crossinline requestBlock: suspend () -> ResponseNew, + showLoading: Boolean = false, + showToast: Boolean = true, + crossinline listenerBuilder: (ResultBuilder.() -> Unit) = {} +) { + lifecycleScope.launch { + launchFlow2(requestBlock, { if (showLoading) showLoading() }) { if (showLoading) hideLoading() }.collect { response -> + response.parseData(listenerBuilder, showToast) + } + } +} + +inline fun AbsView.launchAndLoadingCollect2( + crossinline requestBlock: suspend () -> ResponseNew, showToast: Boolean = true, crossinline listenerBuilder: (ResultBuilder.() -> Unit) = {} +) { + launchAndCollect2(requestBlock, showLoading = true, showToast = showToast, listenerBuilder = listenerBuilder) +} + +/** + * 简单flow流订阅 生命周期安全 + */ +inline fun Flow.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 Flow.flowWithLifecycle2(lifecycle: Lifecycle, minActiveState: Lifecycle.State = Lifecycle.State.STARTED): Flow = callbackFlow { + lifecycle.repeatOnLifecycle(minActiveState) { + this@flowWithLifecycle2.collect { + send(it) + } + } + close() +} + +/** + * response liveData监听 + */ +inline fun LiveData>.observeIn2( + lifecycleOwner: LifecycleOwner, showToast: Boolean = true, crossinline listenerBuilder: ResultBuilder.() -> 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 Flow>.collectIn2( + lifecycleOwner: LifecycleOwner, + minActiveState: Lifecycle.State = Lifecycle.State.STARTED, + showToast: Boolean = true, + crossinline listenerBuilder: ResultBuilder.() -> Unit +): Job { + return lifecycleOwner.lifecycleScope.launch { + flowWithLifecycle2(lifecycleOwner.lifecycle, minActiveState).collect { + it.parseData(listenerBuilder, showToast) + } + } +} + + + + + diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/ActorsRepository.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/ActorsRepository.kt index f2496b8..917ca56 100644 --- a/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/ActorsRepository.kt +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/ActorsRepository.kt @@ -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 { - 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) + } + } \ No newline at end of file diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/base/BaseRepositoryNew.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/base/BaseRepositoryNew.kt new file mode 100644 index 0000000..11b9a10 --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/repository/api/base/BaseRepositoryNew.kt @@ -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 executeHttp(checkLogin: Boolean = true, block: suspend () -> ResponseNew): ResponseNew { + return if (!checkLogin) { + if (LoginManager.isLogin) { + execute(block) + } else { + ApiSuccessResponse() + } + } else { + execute(block) + } + } + + private suspend fun execute(block: suspend () -> ResponseNew): ResponseNew { + return try { + val data = block.invoke() + handleHttpOk(data) + } catch (e: Exception) { + handleHttpError(e) + } + } + + /** + * 非后台返回错误,捕获到的异常 + */ + private fun handleHttpError(e: Throwable): ApiFailedResponse { + 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 handleHttpOk(response: ResponseNew): ResponseNew { + 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 getHttpSuccessResponse(response: ResponseNew): ResponseNew { + val data = response.data + return if (data == null) { + ApiEmptyResponse() + } else { + ApiSuccessResponse(data) + } + } + +} \ No newline at end of file diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListFragment.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListFragment.kt index 551ec95..ab1384a 100644 --- a/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListFragment.kt +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListFragment.kt @@ -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() { private lateinit var mActorAdapter: ActorsAdapter - private val actorsViewModel by viewModels() + private val mActorsModel by viewModels() + private var mLoadedPageIndex = 0 + private val mRequestParam by lazy { ParamActorList() } + override fun onCreated(bundle: Bundle?) { setUI() @@ -36,6 +42,10 @@ class ActorListFragment : BaseBindingFragment() { return BgColorType.TRANSPARENT } + override fun lazyInit() { + getActorList(true, showLoading = false) + } + private fun setUI() { with(binding.root) { setPadding( @@ -59,11 +69,22 @@ class ActorListFragment : BaseBindingFragment() { 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() { } } + + 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 { return listOf( ActorItem( diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListViewModel.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListViewModel.kt deleted file mode 100644 index d1f5fd8..0000000 --- a/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorListViewModel.kt +++ /dev/null @@ -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>() - val msgStatFlow = _msgStatFlow.asSharedFlow() - - suspend fun getMessageStat() { - _msgStatFlow.emit(chatRepository.getBooks()) - } - -} diff --git a/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorsViewModel.kt b/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorsViewModel.kt new file mode 100644 index 0000000..b9fb8fb --- /dev/null +++ b/VisualNovel/app/src/main/java/com/remax/visualnovel/ui/main/actor/ActorsViewModel.kt @@ -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>>() + val actorsStatFlow = _actorsStatFlow.asSharedFlow() + + suspend fun getActorList(param: ParamActorList) = mActorsRepository.getActorList(param) + +} diff --git a/VisualNovel/app/src/main/res/layout/fragment_main_actor.xml b/VisualNovel/app/src/main/res/layout/fragment_main_actor.xml index 6d1078b..194bcf7 100644 --- a/VisualNovel/app/src/main/res/layout/fragment_main_actor.xml +++ b/VisualNovel/app/src/main/res/layout/fragment_main_actor.xml @@ -1,5 +1,5 @@ - - + android:layout_height="match_parent" + android:layout_marginTop="@dimen/dp_4"> + + - + + diff --git a/VisualNovel/app/src/main/res/xml/network_security_config.xml b/VisualNovel/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..7ed0cd4 --- /dev/null +++ b/VisualNovel/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,6 @@ + + + + 54.223.196.180 + +