自定义背景上传

This commit is contained in:
renhaoting 2025-11-05 17:24:02 +08:00
parent a1f5a40ba5
commit 8f171d3214
11 changed files with 132 additions and 115 deletions

View File

@ -55,6 +55,10 @@
</intent-filter>
</activity>
<activity
android:name=".widget.imagepicker.activity.multi.MultiImagePickerActivity"
android:exported="false" >
</activity>
<activity
android:name=".ui.main.MainActivity"

View File

@ -14,7 +14,7 @@ import com.remax.visualnovel.entity.request.SimpleDataDTO
import com.remax.visualnovel.entity.request.VoiceTTS
import com.remax.visualnovel.entity.response.Album
import com.remax.visualnovel.entity.response.Character
import com.remax.visualnovel.entity.response.ChatBackground
import com.remax.visualnovel.entity.response.ChatBackgroundBase
import com.remax.visualnovel.entity.response.ChatModel
import com.remax.visualnovel.entity.response.ChatSet
import com.remax.visualnovel.entity.response.ChatSound
@ -87,7 +87,7 @@ interface ChatService {
* 获取聊天背景列表
*/
@POST("/web/chat-background/list")
suspend fun getChatBackgroundList(@Body request: AIIDRequest): Response<List<ChatBackground>>
suspend fun getChatBackgroundList(@Body request: AIIDRequest): Response<List<ChatBackgroundBase.ChatBackground>>
/**
* 获取聊天设置

View File

@ -2,23 +2,23 @@ package com.remax.visualnovel.entity.response
data class ActorBean(
val id: Int,
val roleName: String,
val description: String,
val id: Int = 0,
val roleName: String = "",
val description: String = "",
var coverImage: String = "",
val sourceId: Int, //来源ID;所属书籍/漫剧
val sourceType: Int, //来源分类
val commonCount: Int, //评论数
val createTime: String,
val status: String,
val sourceId: Int = 0, //来源ID;所属书籍/漫剧
val sourceType: Int = 0, //来源分类
val commonCount: Int = 0, //评论数
val createTime: String = "",
val status: String = "",
// other needed
val avatarRes: Int,
val avatarRes: Int = 0,
val from: String = "from",
val rating: Float,
val characterName: String,
val age: Int,
val tags: List<String>,
val workTitle: String,
val imageRes: Int
val rating: Float = 0F,
val characterName: String = "",
val age: Int = 0,
val tags: List<String> = emptyList(),
val workTitle: String = "",
val imageRes: Int = 0
)

View File

@ -1,9 +1,9 @@
package com.remax.visualnovel.entity.response
import android.net.Uri
import com.remax.visualnovel.entity.model.base.BasePhoto
sealed class ChatBackgroundBase(val itemType: Int) {
data class ChatBackground(
var imageId: Long? = 0L,
var imageUrl: String? = "",
@ -12,4 +12,12 @@ data class ChatBackground(
var isDefault: Boolean = false,
var isSelected: Boolean = false,
var isCustomBg: Boolean = false,
) : ChatBackgroundBase()
) : ChatBackgroundBase(ITEM_TYPE_BACKGROUND)
object ChatBackgroundUpload : ChatBackgroundBase(ITEM_TYPE_UPLOAD)
}
const val ITEM_TYPE_BACKGROUND = 1
const val ITEM_TYPE_UPLOAD = 2

View File

@ -1,9 +0,0 @@
package com.remax.visualnovel.entity.response
import android.net.Uri
import com.remax.visualnovel.entity.model.base.BasePhoto
abstract class ChatBackgroundBase(
)

View File

@ -1,10 +0,0 @@
package com.remax.visualnovel.entity.response
import android.net.Uri
data class ChatBackgroundUpload(
var imageId: Long? = 0L,
var imageUrl: String? = "",
var localUri: Uri? = null,
) : ChatBackgroundBase()

View File

@ -10,8 +10,7 @@ import android.widget.LinearLayout
import androidx.core.graphics.toColorInt
import com.remax.visualnovel.R
import com.remax.visualnovel.databinding.LayoutChatMenuViewBinding
import com.remax.visualnovel.entity.response.ChatBackground
import com.remax.visualnovel.entity.response.ChatBackgroundUpload
import com.remax.visualnovel.entity.response.ChatBackgroundBase
import com.remax.visualnovel.entity.response.ChatBubble
import com.remax.visualnovel.entity.response.ChatHistory
import com.remax.visualnovel.entity.response.ChatMode
@ -291,31 +290,29 @@ class ChatSettingView @JvmOverloads constructor(
fun initBackgroundSelectView() {
val items = listOf(
ChatBackground(
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://vsn.s3.cn-north-1.amazonaws.com.cn/coverImage/fe8e3c7b-5b22-40f4-bacc-0183888c5149_test.png"
),
ChatBackground(
imageId = 1,
imageUrl = "https://cdhrss.chengdu.gov.cn/cdrsj/xhtml/images/2022_logo.png"
),
ChatBackground(
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://vsn.s3.cn-north-1.amazonaws.com.cn/coverImage/fe8e3c7b-5b22-40f4-bacc-0183888c5149_test.png"
),
ChatBackground(
imageId = 1,
imageUrl = "https://cdhrss.chengdu.gov.cn/cdrsj/xhtml/images/2022_logo.png"
),
ChatBackground(
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://vsn.s3.cn-north-1.amazonaws.com.cn/coverImage/fe8e3c7b-5b22-40f4-bacc-0183888c5149_test.png"
),
ChatBackground(
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://cdhrss.chengdu.gov.cn/cdrsj/xhtml/images/2022_logo.png"
),
ChatBackgroundUpload(
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://vsn.s3.cn-north-1.amazonaws.com.cn/coverImage/fe8e3c7b-5b22-40f4-bacc-0183888c5149_test.png"
),
ChatBackgroundBase.ChatBackground(
imageId = 1,
imageUrl = "https://cdhrss.chengdu.gov.cn/cdrsj/xhtml/images/2022_logo.png"
)
)

View File

@ -17,9 +17,7 @@ import com.drake.brv.utils.setup
import com.remax.visualnovel.R
import com.remax.visualnovel.databinding.LayoutItemSettingBackgroundBinding
import com.remax.visualnovel.databinding.LayoutSettingBgSubViewBinding
import com.remax.visualnovel.entity.response.ChatBackground
import com.remax.visualnovel.entity.response.ChatBackgroundBase
import com.remax.visualnovel.entity.response.ChatBackgroundUpload
import com.remax.visualnovel.extension.glide.load
import com.remax.visualnovel.extension.toast
import com.remax.visualnovel.utils.imagepick.EpalPickerPresenter
@ -39,7 +37,7 @@ class ExpandBackgroundSubView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
private lateinit var items: List<ChatBackgroundBase>
private var items = mutableListOf<ChatBackgroundBase>()
private var mBinding: LayoutSettingBgSubViewBinding
@ -57,41 +55,47 @@ class ExpandBackgroundSubView @JvmOverloads constructor(
setDivider(10, true)
orientation = DividerOrientation.VERTICAL
}.setup {
addType<ChatBackground>(R.layout.layout_item_setting_background)
addType<ChatBackgroundUpload>(R.layout.layout_item_setting_background_upload)
addType<ChatBackgroundBase.ChatBackground>(R.layout.layout_item_setting_background)
addType<ChatBackgroundBase.ChatBackgroundUpload>(R.layout.layout_item_setting_background_upload)
onClick(R.id.root) {
when (val item = getModel<Any>(it)) {
is ChatBackground -> {
val chatBackground = getModel<ChatBackground>()
/*when (val item = getModel<Any>(it)) {
is ChatBackgroundBase.ChatBackground -> {
val chatBackground = getModel<ChatBackgroundBase.ChatBackground>()
if (!chatBackground.isSelected) {
itemsRv.bindingAdapter.models?.filterIsInstance<ChatBackground>()?.forEach { item ->
itemsRv.bindingAdapter.models?.filterIsInstance<ChatBackgroundBase.ChatBackground>()?.forEach { item ->
item.isSelected = item == chatBackground
}
itemsRv.bindingAdapter.notifyDataSetChanged()
}
}
is ChatBackgroundUpload -> {
is ChatBackgroundBase.ChatBackgroundUpload -> {
selectCustomBg()
}
}
}*/
/*when (itemViewType) {
when (itemViewType) {
R.layout.layout_item_setting_background -> {
val chatBackground = getModel<ChatBackgroundBase.ChatBackground>()
if (!chatBackground.isSelected) {
itemsRv.bindingAdapter.models?.filterIsInstance<ChatBackgroundBase.ChatBackground>()?.forEach { item ->
item.isSelected = item == chatBackground
}
itemsRv.bindingAdapter.notifyDataSetChanged()
}
}
R.layout.layout_item_setting_background_upload -> {
selectCustomBg()
}
}*/
}
}
onBind {
when (itemViewType) {
R.layout.layout_item_setting_background -> {
val item = getModel<ChatBackground>()
val item = getModel<ChatBackgroundBase.ChatBackground>()
with(getBinding<LayoutItemSettingBackgroundBinding>()) {
if (!item.imageUrl.isNullOrEmpty()) {
ivBackgroundSrc.load(item.imageUrl)
@ -99,13 +103,13 @@ class ExpandBackgroundSubView @JvmOverloads constructor(
ivBackgroundSrc.load(item.localUri!!)
}
ivDel.visibility = if (item.isCustomBg) VISIBLE else GONE
ivBackgroundSrc.isVisible = item.isSelected
ivDel.isVisible = item.isCustomBg
selectBg.isVisible = item.isSelected
}
}
R.layout.layout_item_setting_background_upload -> {
val item = getModel<ChatBackgroundUpload>()
val item = getModel<ChatBackgroundBase.ChatBackgroundUpload>()
}
}
}
@ -113,7 +117,9 @@ class ExpandBackgroundSubView @JvmOverloads constructor(
}
fun setItems(newItems: List<ChatBackgroundBase>) {
items = newItems
items.clear()
items.addAll(newItems)
items.add(ChatBackgroundBase.ChatBackgroundUpload)
mBinding.itemsRv.models = items
}
@ -141,15 +147,22 @@ class ExpandBackgroundSubView @JvmOverloads constructor(
})
}
private fun appendCustomBg(items: ArrayList<ImageItem>?) {
val customBgList = items?.map { imageItem ->
ChatBackground(
private fun appendCustomBg(uploadedItems: ArrayList<ImageItem>?) {
val customBgList = uploadedItems?.map { imageItem ->
ChatBackgroundBase.ChatBackground(
imageId = imageItem.id,
imageUrl = imageItem.path,
localUri = imageItem.uri
localUri = imageItem.uri,
isCustomBg = true
)
}
mBinding.itemsRv.addModels(customBgList)
if (!customBgList.isNullOrEmpty()) {
items.add(if (items.isNotEmpty()) items.size - 1 else 0, customBgList!!.get(0))
mBinding.itemsRv.models = items
}
//items.add((items.size - 1).takeIf { items.isNotEmpty() } ?: 0, customBgList!!.first())
}
private fun uploadImageAndRequest(items: ArrayList<ImageItem>?) {

View File

@ -28,7 +28,7 @@ import kotlin.math.max
@Route(path = Routers.ROUTE_FRAG_ACTORLIST)
class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
private lateinit var mActorAdapter: ActorsAdapter
private lateinit var mRvAdapter: ActorsAdapter
private val mActorsModel by viewModels<ActorsViewModel>()
private var mLoadedPageIndex = 0
private val mRequestParam by lazy { ParamActorList() }
@ -67,11 +67,10 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
mActorsRv.setHasFixedSize(true)
mActorsRv.itemAnimator = DefaultItemAnimator()
mActorAdapter = ActorsAdapter()
mActorsRv.adapter = mActorAdapter
val characterList = createSampleData()
with(mActorAdapter) {
setList(characterList)
mRvAdapter = ActorsAdapter()
mActorsRv.adapter = mRvAdapter
with(mRvAdapter) {
loadMoreModule.setOnLoadMoreListener {
getActorList(false, showLoading = false)
}
@ -116,20 +115,20 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
mActorsModel.getActorList(mRequestParam)
}, showLoading = showLoading) {
onSuccess = {
val data = it ?: emptyList()
with(mActorAdapter) {
var datas = it ?: emptyList()
with(mRvAdapter) {
if (isRefresh) {
setList(data)
setList(datas)
setMyEmptyView(R.string.no_character_yet, topMargin = 60)
} else {
addData(data)
addData(datas)
loadMoreModule.loadMoreComplete()
}
if (data.size < mRequestParam.limit) {
if (datas.size < mRequestParam.limit) {
loadMoreModule.loadMoreEnd()
}
}
if (data.isNotEmpty()) {
if (datas.isNotEmpty()) {
mLoadedPageIndex++
}
}
@ -139,6 +138,13 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
binding.refreshLayout.finishRefresh()
}
}
onFailed = { code, msg ->
// TODO - remove temp datas
with(mRvAdapter) {
setList(createSampleData())
}
}
}
}
@ -160,7 +166,14 @@ class ActorListFragment : BaseBindingFragment<FragmentMainActorBinding>() {
private fun createSampleData(): List<ActorBean> {
return listOf()
return listOf(
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
ActorBean(characterName = "testName-1", description = "Des-xxxxxxxxxxxxx"),
)
}

View File

@ -24,7 +24,7 @@ import com.remax.visualnovel.entity.imbean.raw.CustomAlbumData
import com.remax.visualnovel.entity.model.MyImgData
import com.remax.visualnovel.entity.response.Album
import com.remax.visualnovel.entity.response.AppearanceImage
import com.remax.visualnovel.entity.response.ChatBackground
import com.remax.visualnovel.entity.response.ChatBackgroundBase
import com.remax.visualnovel.extension.setOnClick
import com.remax.visualnovel.widget.dialoglib.ScreenUtils
import com.remax.visualnovel.widget.imageviewer.core.ImageLoader
@ -50,7 +50,7 @@ class MyImageLoader : ImageLoader {
data.imageUrl
}
is ChatBackground -> {
is ChatBackgroundBase.ChatBackground -> {
data.imageUrl
}

View File

@ -9,28 +9,36 @@
<com.remax.visualnovel.widget.roundedimageview.RoundedImageView
android:id="@+id/iv_background_src"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@mipmap/img_1"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="h,87:116"
app:riv_corner_radius="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@+id/selectBg"
app:layout_constraintEnd_toEndOf="@+id/selectBg"
app:layout_constraintStart_toStartOf="@+id/selectBg"
app:layout_constraintTop_toTopOf="@+id/selectBg" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.remax.visualnovel.widget.uitoken.view.UITokenFrameLayout
android:id="@+id/selectBg"
android:layout_width="match_parent"
android:layout_height="0dp"
app:backgroundColorToken="@string/color_surface_element_normal"
app:layout_constraintDimensionRatio="h,87:116"
app:layout_constraintTop_toTopOf="parent"
app:radiusToken="@string/radius_l"
app:advStrokeWidth="@dimen/dp_5"
app:advStrokeColor="@color/blue_6f"
app:advRadius="@dimen/dp_10"
app:advBgColor="@color/transparent"
app:advRadius="@dimen/dp_10">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/setting_bg_selected_indi"
android:layout_gravity="right|bottom"
/>
</com.remax.visualnovel.widget.uitoken.view.UITokenFrameLayout>
<com.remax.visualnovel.widget.uitoken.view.UITokenImageView
android:id="@+id/iv_del"
@ -46,14 +54,7 @@
/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_selected_indi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/setting_bg_selected_indi"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>