refactor: 优化部分代码
This commit is contained in:
parent
da1fc07599
commit
2e9e115c7e
1
.idea/.name
Normal file
1
.idea/.name
Normal file
@ -0,0 +1 @@
|
||||
KChat-Android
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="17" />
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
@ -4,6 +4,7 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
@ -5,8 +5,12 @@
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
|
@ -20,15 +20,15 @@
|
||||
- [x] **搜索功能**:支持通过关键词在聊天记录中搜索消息,同时支持按文件类型筛选。
|
||||
- [x] **修改个人信息**:用户可以修改昵称、头像、个性签名等个人信息,提升个性化体验。
|
||||
- [x] **修改用户密码**:用户可以更新自己的密码。
|
||||
- [x] **离线消息**:即使用户离线,服务器也会缓存消息,并在用户上线后自动同步到设备。
|
||||
- [ ] **查看好友动态**:支持查看好友分享的动态内容,形式包括文字、图片和视频,用户可以点赞或评论。
|
||||
- [ ] **支持多媒体消息**:支持发送音频、视频、文件等多种格式,满足用户不同的交流需求。
|
||||
- [ ] **群聊支持**:用户可以创建群组,与多人实时互动,并支持群管理功能(如设置群管理员、踢人)。
|
||||
- [ ] **消息通知**:支持推送通知,提醒用户有新的消息,未读消息可在通知栏中展示摘要。
|
||||
- [ ] **离线消息**:即使用户离线,服务器也会缓存消息,并在用户上线后自动同步到设备。
|
||||
|
||||
### 其他特性
|
||||
|
||||
- [ ] **消息加密**:所有用户消息在传输过程中都进行端到端加密,确保通信安全,防止信息泄露。
|
||||
- [x] **消息加密**:所有用户消息在传输过程中都进行端到端加密,确保通信安全,防止信息泄露。
|
||||
- [ ] **个性化设置**:支持用户自定义头像、昵称、聊天背景,提供多种预设主题和自定义选项。
|
||||
- [ ] **深色/浅色模式**:支持自动或手动切换界面主题,适配不同的光线环境和用户偏好。
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.kaixed.kchat.extensions
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Parcelable
|
||||
|
||||
/**
|
||||
* @Author: kaixed
|
||||
* @Date: 2025/1/26 19:41
|
||||
*/
|
||||
// 扩展函数,用于兼容不同版本的 Intent.getParcelableExtra 方法
|
||||
inline fun <reified T : Parcelable> Intent.getParcelableExtraCompat(key: String): T? {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
getParcelableExtra(key, T::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
getParcelableExtra(key)
|
||||
}
|
||||
}
|
@ -13,22 +13,43 @@ object NetworkInterface {
|
||||
const val SERVER_URL = "http://$URL"
|
||||
const val WEBSOCKET_SERVER_URL = "ws://$URL"
|
||||
const val WEBSOCKET = "/websocket/single/"
|
||||
const val USER_INFO = "/users/info/"
|
||||
const val USER_LOGIN_BY_USERNAME = "/users/login/username"
|
||||
const val USER_LOGIN_BY_TELEPHONE = "/users/login/telephone"
|
||||
const val USER_REGISTER = "/users/register"
|
||||
|
||||
const val USER_MESSAGES_COUNT = "/users/%s/%s/msgCounts"
|
||||
const val USER_MESSAGES = "/users/%s/%s/messages"
|
||||
const val MESSAGE_WITHDRAW = "/messages/"
|
||||
// 获取access-token
|
||||
const val ACCESS_TOKEN = "auth/access-token"
|
||||
// 获取refresh-token
|
||||
const val REFRESH_TOKEN = "auth/refresh-token"
|
||||
// 登录接口(根据用户名登录)
|
||||
const val LOGIN_BY_USERNAME = "auth/login/username"
|
||||
// 登录接口(根据电话登录)
|
||||
const val LOGIN_BY_TELEPHONE = "auth/login/telephone"
|
||||
// 注册接口
|
||||
const val REGISTER = "auth/register"
|
||||
|
||||
const val USER_LIST = "/users/list/"
|
||||
// 上传文件
|
||||
const val UPLOAD_FILE = "file/upload"
|
||||
|
||||
const val ADD_FRIEND = "/friend/request"
|
||||
const val FRIEND_LIST = "/friend/list"
|
||||
const val FRIEND_REQUEST_LIST = "/friend/request/list"
|
||||
const val ACCEPT_CONTACT_REQUEST = "/friend/accept"
|
||||
// 更新用户密码
|
||||
const val UPDATE_PASSWORD = "user/password/update"
|
||||
// 获取用户信息
|
||||
const val GET_USER_INFO = "user/info/fetch"
|
||||
// 更新用户信息
|
||||
const val UPDATE_USER_INFO = "user/info/update"
|
||||
// 上传用户头像
|
||||
const val UPLOAD_AVATAR = "user/upload-avatar"
|
||||
|
||||
const val UPDATE_USER_INFO = "/users/info"
|
||||
const val UPLOAD_AVATAR = "/users/avatar"
|
||||
// 发送好友请求
|
||||
const val SEND_FRIEND_REQUEST = "friends/requests/send"
|
||||
// 接受好友请求
|
||||
const val ACCEPT_FRIEND_REQUEST = "friends/requests/accept"
|
||||
// 获取好友列表
|
||||
const val GET_FRIENDS = "friends/list"
|
||||
// 获取好友请求列表
|
||||
const val GET_FRIEND_LIST = "friends/requests/fetch"
|
||||
// 删除好友
|
||||
const val DELETE_FRIEND = "friends/delete-friend"
|
||||
// 设置好友备注
|
||||
const val SET_FRIEND_REMARK = "friends/set-remark"
|
||||
|
||||
//撤回消息
|
||||
const val RECALL_MESSAGE = "message/withdraw"
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ import com.kaixed.kchat.data.local.entity.UserInfo
|
||||
import com.kaixed.kchat.data.model.request.RegisterRequest
|
||||
import com.kaixed.kchat.data.model.response.register.Register
|
||||
import com.kaixed.kchat.network.ApiResponse
|
||||
import com.kaixed.kchat.network.NetworkInterface.ACCESS_TOKEN
|
||||
import com.kaixed.kchat.network.NetworkInterface.LOGIN_BY_TELEPHONE
|
||||
import com.kaixed.kchat.network.NetworkInterface.LOGIN_BY_USERNAME
|
||||
import com.kaixed.kchat.network.NetworkInterface.REFRESH_TOKEN
|
||||
import com.kaixed.kchat.network.NetworkInterface.REGISTER
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
@ -15,32 +20,32 @@ import retrofit2.http.Query
|
||||
*/
|
||||
interface AuthApiService {
|
||||
|
||||
@POST("auth/access-token")
|
||||
@POST(ACCESS_TOKEN)
|
||||
suspend fun auth(
|
||||
@Header("Authorization") token: String,
|
||||
@Query("username") username: String
|
||||
): ApiResponse<String>
|
||||
|
||||
@POST("auth/refresh-token")
|
||||
@POST(REFRESH_TOKEN)
|
||||
suspend fun refresh(
|
||||
@Header("Authorization") token: String,
|
||||
@Query("username") username: String
|
||||
): ApiResponse<String>
|
||||
|
||||
// 登录接口(根据用户名登录)
|
||||
@POST("auth/login/username")
|
||||
@POST(LOGIN_BY_USERNAME)
|
||||
suspend fun loginByUsername(
|
||||
@Body requestParams: Map<String, String>,
|
||||
): ApiResponse<UserInfo?>
|
||||
|
||||
// 登录接口(根据电话登录)
|
||||
@POST("auth/login/telephone")
|
||||
@POST(LOGIN_BY_TELEPHONE)
|
||||
suspend fun loginByTelephone(
|
||||
@Body requestParams: Map<String, String>,
|
||||
): ApiResponse<UserInfo>
|
||||
|
||||
// 注册接口
|
||||
@POST("auth/register")
|
||||
@POST(REGISTER)
|
||||
suspend fun register(
|
||||
@Body registerRequest: RegisterRequest
|
||||
): ApiResponse<Register>
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.kaixed.kchat.network.service
|
||||
|
||||
import com.kaixed.kchat.network.ApiResponse
|
||||
import com.kaixed.kchat.network.NetworkInterface.UPLOAD_FILE
|
||||
import okhttp3.MultipartBody
|
||||
import retrofit2.http.Multipart
|
||||
import retrofit2.http.POST
|
||||
@ -13,7 +14,7 @@ import retrofit2.http.Part
|
||||
interface FileApiService {
|
||||
|
||||
@Multipart
|
||||
@POST("file/upload")
|
||||
@POST(UPLOAD_FILE)
|
||||
suspend fun uploadFile(
|
||||
@Part file: MultipartBody.Part
|
||||
): ApiResponse<String>
|
||||
|
@ -4,6 +4,11 @@ import com.kaixed.kchat.data.local.entity.Contact
|
||||
import com.kaixed.kchat.data.model.friend.FriendRequestItem
|
||||
import com.kaixed.kchat.data.model.search.SearchUser
|
||||
import com.kaixed.kchat.network.ApiResponse
|
||||
import com.kaixed.kchat.network.NetworkInterface.ACCEPT_FRIEND_REQUEST
|
||||
import com.kaixed.kchat.network.NetworkInterface.DELETE_FRIEND
|
||||
import com.kaixed.kchat.network.NetworkInterface.GET_FRIEND_LIST
|
||||
import com.kaixed.kchat.network.NetworkInterface.SEND_FRIEND_REQUEST
|
||||
import com.kaixed.kchat.network.NetworkInterface.SET_FRIEND_REMARK
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
@ -16,16 +21,16 @@ import retrofit2.http.Path
|
||||
* @Date: 2025/1/25 16:38
|
||||
*/
|
||||
interface FriendApiService {
|
||||
// 获取联系人请求列表
|
||||
// 获取好友请求列表
|
||||
@FormUrlEncoded
|
||||
@POST("friend/request/list")
|
||||
@POST(GET_FRIEND_LIST)
|
||||
suspend fun getContactRequestList(
|
||||
@Field("userId") username: String
|
||||
): ApiResponse<List<FriendRequestItem>?>
|
||||
|
||||
// 接受联系人请求
|
||||
// 接受好友请求
|
||||
@FormUrlEncoded
|
||||
@POST("friend/accept")
|
||||
@POST(ACCEPT_FRIEND_REQUEST)
|
||||
suspend fun acceptContactRequest(
|
||||
@Field("requestId") contactId: String,
|
||||
@Field("receiverId") username: String,
|
||||
@ -34,7 +39,7 @@ interface FriendApiService {
|
||||
|
||||
// 添加联系人
|
||||
@FormUrlEncoded
|
||||
@POST("friend/request")
|
||||
@POST(SEND_FRIEND_REQUEST)
|
||||
suspend fun addContact(
|
||||
@Field("senderId") senderId: String,
|
||||
@Field("receiverId") receiverId: String,
|
||||
@ -54,7 +59,7 @@ interface FriendApiService {
|
||||
): ApiResponse<List<Contact>?>
|
||||
|
||||
// 删除联系人
|
||||
@POST("friends/delete")
|
||||
@POST(DELETE_FRIEND)
|
||||
suspend fun deleteContact(
|
||||
@Field("userId") username: String,
|
||||
@Field("contactId") contactId: String,
|
||||
@ -62,7 +67,7 @@ interface FriendApiService {
|
||||
|
||||
// 设置好友备注
|
||||
@FormUrlEncoded
|
||||
@POST("friend/remark")
|
||||
@POST(SET_FRIEND_REMARK)
|
||||
suspend fun setRemark(
|
||||
@Field("userId") userId: String,
|
||||
@Field("contactId") contactId: String,
|
||||
|
@ -5,6 +5,11 @@ import com.kaixed.kchat.data.model.request.UserRequest
|
||||
import com.kaixed.kchat.data.model.response.search.User
|
||||
import com.kaixed.kchat.data.model.search.SearchUser
|
||||
import com.kaixed.kchat.network.ApiResponse
|
||||
import com.kaixed.kchat.network.NetworkInterface.GET_FRIENDS
|
||||
import com.kaixed.kchat.network.NetworkInterface.GET_USER_INFO
|
||||
import com.kaixed.kchat.network.NetworkInterface.UPDATE_PASSWORD
|
||||
import com.kaixed.kchat.network.NetworkInterface.UPDATE_USER_INFO
|
||||
import com.kaixed.kchat.network.NetworkInterface.UPLOAD_AVATAR
|
||||
import okhttp3.MultipartBody
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Multipart
|
||||
@ -18,33 +23,33 @@ import retrofit2.http.Part
|
||||
interface UserApiService {
|
||||
|
||||
// 获取用户列表
|
||||
@POST("friends/list")
|
||||
@POST(GET_FRIENDS)
|
||||
suspend fun fetchUserList(
|
||||
@Body requestParams: Map<String, String>
|
||||
): ApiResponse<List<User>>
|
||||
|
||||
// 获取用户信息
|
||||
@POST("users/info/fetch")
|
||||
@POST(GET_USER_INFO)
|
||||
suspend fun getUserInfo(
|
||||
@Body requestParams: Map<String, String>
|
||||
): ApiResponse<SearchUser>
|
||||
|
||||
// 更改昵称接口
|
||||
@POST("users/info")
|
||||
@POST(UPDATE_USER_INFO)
|
||||
suspend fun changeNickname(
|
||||
@Body userRequest: UserRequest
|
||||
): ApiResponse<Boolean?>
|
||||
|
||||
// 上传头像接口
|
||||
@Multipart
|
||||
@POST("users/avatar")
|
||||
@POST(UPLOAD_AVATAR)
|
||||
suspend fun uploadAvatar(
|
||||
@Part("username") username: String,
|
||||
@Part file: MultipartBody.Part
|
||||
): ApiResponse<String>
|
||||
|
||||
// 更改密码
|
||||
@POST("users/password")
|
||||
@POST(UPDATE_PASSWORD)
|
||||
suspend fun updatePassword(
|
||||
@Body updatePasswordRequest: UpdatePasswordRequest
|
||||
): ApiResponse<String>
|
||||
|
@ -7,6 +7,13 @@ import androidx.activity.enableEdgeToEdge
|
||||
import com.kaixed.kchat.databinding.ActivityAddFriendsBinding
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
|
||||
/**
|
||||
* 该文件包含用于兼容不同 Android 版本的 Intent 获取 Parcelable 数据的扩展函数。
|
||||
* 通过扩展函数 getParcelableExtraCompat 解决了低版本和高版本 Android 系统间的差异。
|
||||
*
|
||||
* @author kaixed
|
||||
* @since 2025年1月26日
|
||||
*/
|
||||
class AddFriendsActivity : BaseActivity<ActivityAddFriendsBinding>() {
|
||||
|
||||
private val context: Context by lazy { this }
|
||||
@ -18,15 +25,21 @@ class AddFriendsActivity : BaseActivity<ActivityAddFriendsBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
initView()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
override fun observeData() {
|
||||
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
@ -21,11 +21,13 @@ class ApplyAddFriendActivity : BaseActivity<ActivityApplyAddFriendBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setListener()
|
||||
observeData()
|
||||
}
|
||||
|
||||
private fun observeData() {
|
||||
override fun initView() {
|
||||
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
contactViewModel.addContactResult
|
||||
.observe(this) { result ->
|
||||
result.onSuccess {
|
||||
@ -36,7 +38,7 @@ class ApplyAddFriendActivity : BaseActivity<ActivityApplyAddFriendBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
override fun setupListeners() {
|
||||
binding.tvSendApply.setOnClickListener {
|
||||
sendContactRequest(contactId)
|
||||
}
|
||||
|
@ -12,26 +12,14 @@ import com.kaixed.kchat.ui.base.BaseActivity
|
||||
|
||||
class ApplyFriendsDetailActivity : BaseActivity<ActivityApplyFriendsDetailBinding>() {
|
||||
|
||||
override fun inflateBinding(): ActivityApplyFriendsDetailBinding {
|
||||
return ActivityApplyFriendsDetailBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
private var user: SearchUser? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
setContent()
|
||||
setOnClick()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
override fun initData() {
|
||||
user = intent.getParcelableExtra("user", SearchUser::class.java)
|
||||
}
|
||||
|
||||
private fun setContent() {
|
||||
override fun initView() {
|
||||
val nickname = user?.nickname
|
||||
val signature = user?.signature
|
||||
val avatarUrl = user?.avatarUrl
|
||||
@ -43,7 +31,12 @@ class ApplyFriendsDetailActivity : BaseActivity<ActivityApplyFriendsDetailBindin
|
||||
Glide.with(this).load(avatarUrl).into(binding.ifvAvatar)
|
||||
}
|
||||
|
||||
private fun setOnClick() {
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
override fun initData() {
|
||||
user = intent.getParcelableExtra("user", SearchUser::class.java)
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.tvAddContact.setOnClickListener {
|
||||
val contactId = user?.username
|
||||
contactId?.let {
|
||||
@ -60,4 +53,12 @@ class ApplyFriendsDetailActivity : BaseActivity<ActivityApplyFriendsDetailBindin
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
|
||||
}
|
||||
|
||||
override fun inflateBinding(): ActivityApplyFriendsDetailBinding {
|
||||
return ActivityApplyFriendsDetailBinding.inflate(layoutInflater)
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,6 @@ class ApproveContactRequestActivity : BaseActivity<ActivityApproveContactRequest
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
|
||||
setContent()
|
||||
|
||||
setOnClickListener()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
@ -41,18 +36,22 @@ class ApproveContactRequestActivity : BaseActivity<ActivityApproveContactRequest
|
||||
contactId = intent.getStringExtra("contactId").toString()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun setContent() {
|
||||
binding.etRemark.setText(nickname)
|
||||
binding.tvMessage.text = "‘$message’"
|
||||
override fun observeData() {
|
||||
|
||||
}
|
||||
|
||||
private fun setOnClickListener() {
|
||||
override fun setupListeners() {
|
||||
binding.tvFinish.setOnClickListener {
|
||||
acceptContactRequest(contactId!!, nickname!!)
|
||||
acceptContactRequest(contactId, nickname)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun initView() {
|
||||
binding.etRemark.setText(nickname)
|
||||
binding.tvMessage.text = "‘$message’"
|
||||
}
|
||||
|
||||
private fun acceptContactRequest(contactId: String, nickname: String) {
|
||||
contactViewModel.acceptContactRequestResult
|
||||
.observe(this) { result ->
|
||||
|
@ -1,63 +1,45 @@
|
||||
package com.kaixed.kchat.ui.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.bumptech.glide.Glide
|
||||
import com.kaixed.kchat.databinding.ActivityApproveDetailBinding
|
||||
import com.kaixed.kchat.data.model.friend.FriendRequestItem
|
||||
import com.kaixed.kchat.databinding.ActivityApproveDetailBinding
|
||||
import com.kaixed.kchat.extensions.getParcelableExtraCompat
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
|
||||
class ApproveDetailActivity : BaseActivity<ActivityApproveDetailBinding>() {
|
||||
|
||||
private var request: FriendRequestItem? = null
|
||||
|
||||
override fun inflateBinding(): ActivityApproveDetailBinding {
|
||||
return ActivityApproveDetailBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
handleIntent(intent)
|
||||
|
||||
setContent()
|
||||
|
||||
setOnClick()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
request = intent.getParcelableExtraCompat("request")
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent) {
|
||||
request = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getParcelableExtra("request", FriendRequestItem::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
intent.getParcelableExtra("request") as? FriendRequestItem
|
||||
override fun initView() {
|
||||
request?.let {
|
||||
val nickname = it.nickname
|
||||
val signature = it.signature
|
||||
val avatarUrl = it.avatarUrl
|
||||
|
||||
binding.tvContactName.text = nickname
|
||||
binding.tvContactSignature.text = signature
|
||||
binding.tvSignatureContent.text = signature
|
||||
Glide.with(this).load(avatarUrl).into(binding.ifvAvatar)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setContent() {
|
||||
if (request == null) {
|
||||
return
|
||||
}
|
||||
val nickname = request?.nickname
|
||||
val signature = request?.signature
|
||||
val avatarUrl = request?.avatarUrl
|
||||
|
||||
binding.tvContactName.text = nickname
|
||||
binding.tvContactSignature.text = signature
|
||||
binding.tvSignatureContent.text = signature
|
||||
Glide.with(this).load(avatarUrl).into(binding.ifvAvatar)
|
||||
}
|
||||
|
||||
private fun setOnClick() {
|
||||
override fun setupListeners() {
|
||||
binding.ctl.setOnSettingClickListener {
|
||||
val intent = Intent(this, DataSettingActivity::class.java)
|
||||
startActivity(intent)
|
||||
@ -73,4 +55,8 @@ class ApproveDetailActivity : BaseActivity<ActivityApproveDetailBinding>() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun inflateBinding(): ActivityApproveDetailBinding {
|
||||
return ActivityApproveDetailBinding.inflate(layoutInflater)
|
||||
}
|
||||
}
|
||||
|
@ -116,13 +116,9 @@ class ChatActivity : BaseActivity<ActivityChatBinding>(), OnItemClickListener,
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
EventBus.getDefault().register(this)
|
||||
observeLiveData()
|
||||
firstLoadData()
|
||||
initView()
|
||||
setListener()
|
||||
bindWebSocketService()
|
||||
setPanelChange()
|
||||
observeStateFlow()
|
||||
if (isSearchHistory) {
|
||||
val size = MessagesManager.queryHistory(msgLocalId)
|
||||
binding.recycleChatList.smoothScrollToPosition(size - 1)
|
||||
@ -136,17 +132,6 @@ class ChatActivity : BaseActivity<ActivityChatBinding>(), OnItemClickListener,
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeStateFlow() {
|
||||
lifecycleScope.launch {
|
||||
MessagesManager.messages.collect {
|
||||
chatAdapter?.submitList(it)
|
||||
binding.recycleChatList.post {
|
||||
binding.recycleChatList.smoothScrollToPosition(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val connection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
val binder = service as LocalBinder
|
||||
@ -266,7 +251,114 @@ class ChatActivity : BaseActivity<ActivityChatBinding>(), OnItemClickListener,
|
||||
}
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
private fun setupFunctionPanel() {
|
||||
strings?.add("[委屈]")
|
||||
val mEmojiAdapter = EmojiAdapter(strings)
|
||||
mEmojiAdapter.setOnItemClickListener(this)
|
||||
binding.rvEmoji.adapter = mEmojiAdapter
|
||||
|
||||
val gridLayoutManager = GridLayoutManager(this, 7)
|
||||
binding.rvEmoji.layoutManager = gridLayoutManager
|
||||
|
||||
val map: MutableMap<String, Int> = mutableMapOf()
|
||||
|
||||
map["相册"] = R.drawable.ic_filled_picture
|
||||
map["拍摄"] = R.drawable.ic_filled_camera
|
||||
map["位置"] = R.drawable.ic_filled_location
|
||||
map["名片"] = R.drawable.ic_filled_personal
|
||||
map["转账"] = R.drawable.ic_filled_transfer
|
||||
map["文件"] = R.drawable.ic_folder_filled
|
||||
map["语音输入"] = R.drawable.ic_filled_voiceinput
|
||||
map["我的收藏"] = R.drawable.ic_filled_favorites
|
||||
|
||||
val functionItems = mutableListOf<FunctionItem>()
|
||||
for (i in map.keys) {
|
||||
functionItems.add(FunctionItem(i, map[i]!!))
|
||||
}
|
||||
|
||||
val functionPanelAdapter = FunctionPanelAdapter(functionItems, this)
|
||||
functionPanelAdapter.setOnItemClickListener(this)
|
||||
binding.gvFunctionPanel.adapter = functionPanelAdapter
|
||||
}
|
||||
|
||||
override fun onItemClick(position: Int) {
|
||||
runOnUiThread {
|
||||
val editable = binding.etInput.text
|
||||
// 获取当前光标位置
|
||||
val index = binding.etInput.selectionStart
|
||||
// 获取将要插入的表情符号
|
||||
val emoji = strings!![position]
|
||||
// 使用 ImageSpanUtil 插入表情符号
|
||||
insertEmoji(
|
||||
context, editable, binding.etInput.textSize.toInt(), emoji, index
|
||||
)
|
||||
// 设置新的光标位置
|
||||
binding.etInput.setSelection(index + emoji.length)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.ctb.setUnReadCount(ConversationManager.unReadMsgCount)
|
||||
setupFunctionPanel()
|
||||
setRecycleView()
|
||||
contactNickname?.let {
|
||||
binding.ctb.setTitleName(contactNickname!!)
|
||||
}
|
||||
setPanel()
|
||||
}
|
||||
|
||||
private fun setPanel() {
|
||||
val layoutParams = binding.clBottomPanel.layoutParams
|
||||
layoutParams.height = softKeyboardHeight
|
||||
binding.clBottomPanel.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
contactId = intent.getStringExtra("contactId").toString()
|
||||
contactNickname = intent.getStringExtra("contactNickname")
|
||||
isSearchHistory = intent.getBooleanExtra("isSearchHistory", false) == true
|
||||
msgLocalId = intent.getLongExtra("msgLocalId", 0)
|
||||
|
||||
binding.ctb.setTitleName(contactNickname!!)
|
||||
|
||||
softKeyboardHeight = getKeyboardHeight()
|
||||
mmkv.putString(CURRENT_CONTACT_ID, contactId)
|
||||
}
|
||||
|
||||
private fun setRecycleView() {
|
||||
val layoutManager = LinearLayoutManager(this)
|
||||
layoutManager.reverseLayout = true
|
||||
binding.recycleChatList.layoutManager = layoutManager
|
||||
chatAdapter = ChatAdapter(this)
|
||||
binding.recycleChatList.adapter = chatAdapter
|
||||
}
|
||||
|
||||
private fun firstLoadData() {
|
||||
MessagesManager.setContactId(contactId)
|
||||
MessagesManager.firstLoadMessages()
|
||||
}
|
||||
|
||||
private fun loadMoreMessages() {
|
||||
MessagesManager.loadMoreMessages()
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
webSocketService!!.messageLivedata.observe(this) {
|
||||
it?.let {
|
||||
handleMsg(it)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
MessagesManager.messages.collect {
|
||||
chatAdapter?.submitList(it)
|
||||
binding.recycleChatList.post {
|
||||
binding.recycleChatList.smoothScrollToPosition(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.etInput.setOnClickListener {
|
||||
if (hasSoftInput()){
|
||||
MMKV.defaultMMKV().encode(KEYBOARD_HEIGHT, max(getSoftInputHeight(), 300))
|
||||
@ -324,108 +416,6 @@ class ChatActivity : BaseActivity<ActivityChatBinding>(), OnItemClickListener,
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupFunctionPanel() {
|
||||
strings?.add("[委屈]")
|
||||
val mEmojiAdapter = EmojiAdapter(strings)
|
||||
mEmojiAdapter.setOnItemClickListener(this)
|
||||
binding.rvEmoji.adapter = mEmojiAdapter
|
||||
|
||||
val gridLayoutManager = GridLayoutManager(this, 7)
|
||||
binding.rvEmoji.layoutManager = gridLayoutManager
|
||||
|
||||
val map: MutableMap<String, Int> = mutableMapOf()
|
||||
|
||||
map["相册"] = R.drawable.ic_filled_picture
|
||||
map["拍摄"] = R.drawable.ic_filled_camera
|
||||
map["位置"] = R.drawable.ic_filled_location
|
||||
map["名片"] = R.drawable.ic_filled_personal
|
||||
map["转账"] = R.drawable.ic_filled_transfer
|
||||
map["文件"] = R.drawable.ic_folder_filled
|
||||
map["语音输入"] = R.drawable.ic_filled_voiceinput
|
||||
map["我的收藏"] = R.drawable.ic_filled_favorites
|
||||
|
||||
val functionItems = mutableListOf<FunctionItem>()
|
||||
for (i in map.keys) {
|
||||
functionItems.add(FunctionItem(i, map[i]!!))
|
||||
}
|
||||
|
||||
val functionPanelAdapter = FunctionPanelAdapter(functionItems, this)
|
||||
functionPanelAdapter.setOnItemClickListener(this)
|
||||
binding.gvFunctionPanel.adapter = functionPanelAdapter
|
||||
}
|
||||
|
||||
override fun onItemClick(position: Int) {
|
||||
runOnUiThread {
|
||||
val editable = binding.etInput.text
|
||||
// 获取当前光标位置
|
||||
val index = binding.etInput.selectionStart
|
||||
// 获取将要插入的表情符号
|
||||
val emoji = strings!![position]
|
||||
// 使用 ImageSpanUtil 插入表情符号
|
||||
insertEmoji(
|
||||
context, editable, binding.etInput.textSize.toInt(), emoji, index
|
||||
)
|
||||
// 设置新的光标位置
|
||||
binding.etInput.setSelection(index + emoji.length)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.ctb.setUnReadCount(ConversationManager.unReadMsgCount)
|
||||
setupFunctionPanel()
|
||||
setRecycleView()
|
||||
contactNickname?.let {
|
||||
binding.ctb.setTitleName(contactNickname!!)
|
||||
}
|
||||
setPanel()
|
||||
}
|
||||
|
||||
private fun setPanel() {
|
||||
val layoutParams = binding.clBottomPanel.layoutParams
|
||||
layoutParams.height = softKeyboardHeight
|
||||
binding.clBottomPanel.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
contactId = intent.getStringExtra("contactId").toString()
|
||||
contactNickname = intent.getStringExtra("contactNickname")
|
||||
isSearchHistory = intent.getBooleanExtra("isSearchHistory", false) == true
|
||||
msgLocalId = intent.getLongExtra("msgLocalId", 0)
|
||||
|
||||
binding.ctb.setTitleName(contactNickname!!)
|
||||
|
||||
softKeyboardHeight = getKeyboardHeight()
|
||||
mmkv.putString(CURRENT_CONTACT_ID, contactId)
|
||||
}
|
||||
|
||||
private fun setRecycleView() {
|
||||
val layoutManager = LinearLayoutManager(this)
|
||||
layoutManager.reverseLayout = true
|
||||
binding.recycleChatList.layoutManager = layoutManager
|
||||
chatAdapter = ChatAdapter(this)
|
||||
binding.recycleChatList.adapter = chatAdapter
|
||||
}
|
||||
|
||||
private fun firstLoadData() {
|
||||
MessagesManager.setContactId(contactId)
|
||||
MessagesManager.firstLoadMessages()
|
||||
}
|
||||
|
||||
private fun loadMoreMessages() {
|
||||
MessagesManager.loadMoreMessages()
|
||||
}
|
||||
|
||||
private fun observeLiveData() {
|
||||
if (webSocketService == null) {
|
||||
return
|
||||
}
|
||||
webSocketService!!.messageLivedata.observe(this) {
|
||||
it?.let {
|
||||
handleMsg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMsg(messages: Messages) {
|
||||
MessagesManager.receiveMessage(messages)
|
||||
binding.recycleChatList.smoothScrollToPosition(0)
|
||||
|
@ -25,13 +25,9 @@ class ChatDetailActivity : BaseActivity<ActivityChatDetailBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
initView()
|
||||
|
||||
setListener()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
Glide.with(this).load(contact?.avatarUrl).into(binding.ifvAvatar)
|
||||
binding.tvContactName.text = contact?.remark ?: contact?.nickname
|
||||
}
|
||||
@ -41,7 +37,11 @@ class ChatDetailActivity : BaseActivity<ActivityChatDetailBinding>() {
|
||||
binding.ciSetDisturb.setSwitchChecked(contact?.doNotDisturb ?: false)
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
override fun observeData() {
|
||||
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.ciSetDisturb.sbSwitch.setOnCheckedChangeListener(object :
|
||||
SwitchButton.OnCheckedChangeListener {
|
||||
override fun onCheckedChanged(button: SwitchButton, isChecked: Boolean) {
|
||||
|
@ -21,7 +21,14 @@ class ContactPermissionActivity : BaseActivity<ActivityContactPermissionBinding>
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.ciChat.setYesSelected(false)
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ import com.kaixed.kchat.viewmodel.ContactViewModel
|
||||
|
||||
class ContactRequestListActivity : BaseActivity<ActivityContactRequestListBinding>() {
|
||||
|
||||
|
||||
private var items = mutableListOf<FriendRequestItem>()
|
||||
|
||||
private val contactViewModel: ContactViewModel by viewModels()
|
||||
@ -38,10 +37,19 @@ class ContactRequestListActivity : BaseActivity<ActivityContactRequestListBindin
|
||||
binding.recycleFriendRequestList.adapter = contactRequestListAdapter
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
private fun getItems() {
|
||||
contactViewModel.contactRequestListResult
|
||||
.observe(this) { result ->
|
||||
|
@ -5,17 +5,18 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import com.kaixed.kchat.databinding.ActivityContactUpdatesBinding
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
import com.kaixed.kchat.utils.ScreenUtils
|
||||
|
||||
class ContactUpdatesActivity : AppCompatActivity() {
|
||||
class ContactUpdatesActivity : BaseActivity<ActivityContactUpdatesBinding>() {
|
||||
|
||||
private lateinit var binding: ActivityContactUpdatesBinding
|
||||
override fun inflateBinding(): ActivityContactUpdatesBinding {
|
||||
return ActivityContactUpdatesBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = ActivityContactUpdatesBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
val constraintSet = ConstraintSet()
|
||||
constraintSet.clone(binding.main)
|
||||
@ -37,4 +38,16 @@ class ContactUpdatesActivity : AppCompatActivity() {
|
||||
)
|
||||
constraintSet.applyTo(binding.main)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
}
|
||||
|
@ -36,16 +36,49 @@ class ContactsDetailActivity : BaseActivity<ActivityContactsDetailBinding>() {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
setOnListener()
|
||||
|
||||
updateContent()
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
contactId = intent.getStringExtra("contactId")
|
||||
isMine = intent.getBooleanExtra("isMine", false)
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.tvSendMessage.setOnClickListener {
|
||||
startActivity(Intent(this, ChatActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
putExtra("contactNickname", contactId)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ciSetRemarkAndLabel.setOnClickListener {
|
||||
startActivity(Intent(this, SetRemarkAndLabelActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
putExtra("contactNickname", contactNickname)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ctb.setOnSettingClickListener {
|
||||
startActivity(Intent(this, DataSettingActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ciPermission.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(this, ContactPermissionActivity::class.java)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun updateContent() {
|
||||
if (isMine) {
|
||||
@ -83,34 +116,6 @@ class ContactsDetailActivity : BaseActivity<ActivityContactsDetailBinding>() {
|
||||
updateContent()
|
||||
}
|
||||
|
||||
private fun setOnListener() {
|
||||
binding.tvSendMessage.setOnClickListener {
|
||||
startActivity(Intent(this, ChatActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
putExtra("contactNickname", contactId)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ciSetRemarkAndLabel.setOnClickListener {
|
||||
startActivity(Intent(this, SetRemarkAndLabelActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
putExtra("contactNickname", contactNickname)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ctb.setOnSettingClickListener {
|
||||
startActivity(Intent(this, DataSettingActivity::class.java).apply {
|
||||
putExtra("contactId", contactId)
|
||||
})
|
||||
}
|
||||
|
||||
binding.ciPermission.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(this, ContactPermissionActivity::class.java)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getContactInfo(contactId: String): Contact {
|
||||
return DataBase.contactBox
|
||||
.query(Contact_.username.equal(contactId))
|
||||
|
@ -33,10 +33,20 @@ class DataSettingActivity : BaseActivity<ActivityDataSettingBinding>(),
|
||||
handleIntent(intent)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent) {
|
||||
contactId = intent.getStringExtra("contactId") ?: ""
|
||||
}
|
||||
|
@ -38,21 +38,21 @@ class FriendCircleActivity : BaseActivity<ActivityFriendCircleBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
initView()
|
||||
setListener()
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
getItems()
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getItems() {
|
||||
val img = listOf(
|
||||
R.drawable.ic_1,
|
||||
@ -90,7 +90,7 @@ class FriendCircleActivity : BaseActivity<ActivityFriendCircleBinding>() {
|
||||
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
setContent()
|
||||
binding.clTool.apply {
|
||||
updateLayoutParams {
|
||||
|
@ -35,10 +35,19 @@ class LaunchActivity : BaseActivity<ActivityLaunchBinding>() {
|
||||
setOnClickListener()
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
@SuppressLint("DiscouragedApi", "InternalInsetResource")
|
||||
private fun getStatusBarHeight(): Int {
|
||||
var result = 0
|
||||
|
@ -58,7 +58,7 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
setupLoginView()
|
||||
}
|
||||
|
||||
@ -210,6 +210,11 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>() {
|
||||
}
|
||||
|
||||
override fun initData() {}
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun inflateBinding(): ActivityLoginBinding {
|
||||
return ActivityLoginBinding.inflate(layoutInflater)
|
||||
|
@ -180,6 +180,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onMessageEvent(unreadEvent: UnreadEvent) {
|
||||
val unreadCount = unreadEvent.unreadCount
|
||||
@ -191,7 +197,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
|
||||
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
navItems.forEachIndexed { index, navItem ->
|
||||
navItem.container.setOnClickListener {
|
||||
updateSelection(index)
|
||||
|
@ -65,6 +65,9 @@ class ProfileDetailActivity : BaseActivity<ActivityProfileDetailBinding>() {
|
||||
updateContent(username)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
getImageLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
@ -79,6 +82,12 @@ class ProfileDetailActivity : BaseActivity<ActivityProfileDetailBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
private fun updateAvatar(uri: Uri) {
|
||||
val filePath = getPathFromUri(uri)
|
||||
|
||||
|
@ -31,6 +31,9 @@ class QrCodeActivity : BaseActivity<ActivityQrCodeBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
setupQrcode()
|
||||
binding.tvNickname.text = getNickName()
|
||||
@ -38,6 +41,12 @@ class QrCodeActivity : BaseActivity<ActivityQrCodeBinding>() {
|
||||
.into(binding.ifvAvatar)
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
private fun setupQrcode() {
|
||||
val content = "kchat@${getUsername()}"
|
||||
val type = HmsScan.QRCODE_SCAN_TYPE
|
||||
|
@ -33,10 +33,6 @@ class RegisterActivity : BaseActivity<ActivityRegisterBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
initView()
|
||||
|
||||
setOnClickListener()
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
@ -53,7 +49,10 @@ class RegisterActivity : BaseActivity<ActivityRegisterBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setOnClickListener() {
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.ivClose.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
@ -95,7 +94,7 @@ class RegisterActivity : BaseActivity<ActivityRegisterBinding>() {
|
||||
}
|
||||
|
||||
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
setupTip()
|
||||
setOnEtChangeListener()
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import androidx.activity.viewModels
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import com.kaixed.kchat.data.local.box.ObjectBox.getBoxStore
|
||||
import com.kaixed.kchat.data.local.entity.UserInfo
|
||||
import com.kaixed.kchat.databinding.ActivityRenameBinding
|
||||
import com.kaixed.kchat.data.model.request.UserRequest
|
||||
import com.kaixed.kchat.databinding.ActivityRenameBinding
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
import com.kaixed.kchat.ui.widget.LoadingDialogFragment
|
||||
import com.kaixed.kchat.utils.ConstantsUtils.getNickName
|
||||
@ -19,8 +19,6 @@ import io.objectbox.Box
|
||||
|
||||
class RenameActivity : BaseActivity<ActivityRenameBinding>() {
|
||||
|
||||
private val userInfoBox: Box<UserInfo> by lazy { getBoxStore().boxFor(UserInfo::class.java) }
|
||||
|
||||
private val userViewModel: UserViewModel by viewModels()
|
||||
|
||||
private var oldNickname: String = ""
|
||||
@ -56,10 +54,19 @@ class RenameActivity : BaseActivity<ActivityRenameBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
oldNickname = getNickName()
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
private fun updateNicknamesByCondition(newNickname: String, username: String) {
|
||||
binding.ctb.setBtnEnable(false)
|
||||
val dialog: LoadingDialogFragment = LoadingDialogFragment.newInstance("正在保存")
|
||||
|
@ -86,6 +86,15 @@ class ScanActivity : BaseActivity<ActivityScanBinding>() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
private fun initPermission() {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
|
@ -40,13 +40,22 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
private fun setupViewVisibility(length: Int) {
|
||||
binding.rvSearchResult.visibility = if (length > 0) View.VISIBLE else View.INVISIBLE
|
||||
binding.tvPageSetting.visibility = if (length > 0) View.INVISIBLE else View.VISIBLE
|
||||
}
|
||||
|
||||
private fun setupRecycleView() {
|
||||
binding!!.rvSearchResult.edgeEffectFactory = object : EdgeEffectFactory() {
|
||||
binding.rvSearchResult.edgeEffectFactory = object : EdgeEffectFactory() {
|
||||
override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect {
|
||||
return object : EdgeEffect(view.context) {
|
||||
override fun onPull(deltaDistance: Float, displacement: Float) {
|
||||
|
@ -140,4 +140,13 @@ class SearchChatHistory : BaseActivity<ActivitySearchChatHistoryBinding>() {
|
||||
contactAvatarUrl = intent?.getStringExtra("contactAvatarUrl") ?: ""
|
||||
contactId = intent?.getStringExtra("contactId") ?: ""
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +132,17 @@ class SearchFriendsActivity : BaseActivity<ActivitySearchFriendsBinding>() {
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
override fun initView() {
|
||||
binding.clFriends.visibility = View.INVISIBLE
|
||||
binding.tvTitle.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
private fun searchUser(username: String) {
|
||||
contactViewModel.searchContact(username)
|
||||
}
|
||||
|
@ -4,13 +4,28 @@ import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.kaixed.kchat.databinding.ActivityServiceDetailBinding
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
|
||||
class ServiceDetailActivity : BaseActivity<ActivityServiceDetailBinding>() {
|
||||
|
||||
class ServiceDetailActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityServiceDetailBinding
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = ActivityServiceDetailBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun inflateBinding(): ActivityServiceDetailBinding {
|
||||
return ActivityServiceDetailBinding.inflate(layoutInflater)
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,28 @@ import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.kaixed.kchat.databinding.ActivitySetRemarkBinding
|
||||
import com.kaixed.kchat.ui.base.BaseActivity
|
||||
|
||||
class SetRemarkActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivitySetRemarkBinding
|
||||
class SetRemarkActivity : BaseActivity<ActivitySetRemarkBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = ActivitySetRemarkBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
setOnClickListener()
|
||||
}
|
||||
|
||||
private fun setOnClickListener() {
|
||||
override fun initData() {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.ivBack.setOnClickListener { finish() }
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun inflateBinding(): ActivitySetRemarkBinding {
|
||||
return ActivitySetRemarkBinding.inflate(layoutInflater)
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,6 @@ import kotlinx.coroutines.launch
|
||||
|
||||
class SetRemarkAndLabelActivity : BaseActivity<ActivitySetRemarkAndLabelBinding>() {
|
||||
|
||||
private val contactBox by lazy {
|
||||
getBoxStore().boxFor(Contact::class.java)
|
||||
}
|
||||
|
||||
private var contactId: String? = null
|
||||
|
||||
private var hasFocus = false
|
||||
@ -59,6 +55,15 @@ class SetRemarkAndLabelActivity : BaseActivity<ActivitySetRemarkAndLabelBinding>
|
||||
remark = contact?.remark ?: contact?.nickname ?: ""
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateContent()
|
||||
|
@ -140,4 +140,13 @@ class SettingsActivity : BaseActivity<ActivitySettingBinding>(), View.OnClickLis
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
}
|
@ -4,14 +4,8 @@ import android.os.Bundle
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.util.Linkify
|
||||
import android.util.Patterns
|
||||
import android.view.View
|
||||
import android.webkit.WebChromeClient
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import com.kaixed.kchat.databinding.ActivityTestBinding
|
||||
@ -70,4 +64,13 @@ class TestActivity : BaseActivity<ActivityTestBinding>() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
}
|
@ -57,6 +57,15 @@ class WebViewActivity : BaseActivity<ActivityWebViewBinding>() {
|
||||
url = intent.getStringExtra("url") ?: ""
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
private fun setupWebView() {
|
||||
// 启用 JavaScript
|
||||
webView.settings.javaScriptEnabled = true
|
||||
|
@ -28,4 +28,13 @@ class AboutActivity : BaseActivity<ActivityAboutBinding>() {
|
||||
loadingDialog.showLoading(supportFragmentManager)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
}
|
@ -16,16 +16,6 @@ class AccountSecurityActivity : BaseActivity<ActivityAccountSecurityBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
|
||||
setListener()
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
binding.ciUpdatePassword.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(this, UpdatePasswordActivity::class.java)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
@ -36,4 +26,18 @@ class AccountSecurityActivity : BaseActivity<ActivityAccountSecurityBinding>() {
|
||||
binding.ciTelephone.setItemDesc(telephone)
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
binding.ciUpdatePassword.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(this, UpdatePasswordActivity::class.java)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
}
|
@ -17,10 +17,18 @@ class UpdateKidActivity : BaseActivity<ActivityUpdateKidBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_update_kid)
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
}
|
@ -83,6 +83,15 @@ class UpdatePasswordActivity : BaseActivity<ActivityUpdatePasswordBinding>() {
|
||||
addEdittextFilter()
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
}
|
||||
|
||||
private val textWatch = object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
}
|
||||
|
@ -22,4 +22,16 @@ class UpdateTelephoneActivity : BaseActivity<ActivityUpdateTelephoneBinding>() {
|
||||
override fun initData() {
|
||||
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun setupListeners() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun observeData() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
@ -14,13 +14,13 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
|
||||
protected lateinit var binding: VB
|
||||
|
||||
abstract fun inflateBinding(): VB
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = inflateBinding()
|
||||
setContentView(binding.root)
|
||||
initData()
|
||||
initView()
|
||||
setupListeners()
|
||||
AppManager.instance.addActivity(this)
|
||||
}
|
||||
|
||||
@ -31,6 +31,12 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
|
||||
abstract fun initData()
|
||||
|
||||
abstract fun initView()
|
||||
|
||||
abstract fun setupListeners()
|
||||
|
||||
abstract fun observeData()
|
||||
|
||||
fun toast(msg: String) {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
@ -38,4 +44,6 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
fun toast() {
|
||||
Toast.makeText(this, "暂未开发", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
abstract fun inflateBinding(): VB
|
||||
}
|
@ -10,6 +10,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.bumptech.glide.Glide
|
||||
import com.kaixed.kchat.R
|
||||
import com.kaixed.kchat.databinding.ItemCustomBinding
|
||||
import com.kaixed.kchat.utils.ImageLoader
|
||||
|
||||
/**
|
||||
* @Author: kaixed
|
||||
@ -123,8 +124,7 @@ class CustomItem @JvmOverloads constructor(
|
||||
|
||||
if (itemIconRound > 0) {
|
||||
binding.ivItemIcon.roundPercent = itemIconRound
|
||||
Glide.with(context).load(itemIcon)
|
||||
.into(binding.ivItemIcon)
|
||||
ImageLoader.loadImage(context, itemIcon, binding.ivItemIcon)
|
||||
}
|
||||
} else {
|
||||
binding.ivItemIcon.visibility = View.GONE
|
||||
|
54
app/src/main/kotlin/com/kaixed/kchat/utils/ImageLoader.kt
Normal file
54
app/src/main/kotlin/com/kaixed/kchat/utils/ImageLoader.kt
Normal file
@ -0,0 +1,54 @@
|
||||
package com.kaixed.kchat.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
|
||||
object ImageLoader {
|
||||
|
||||
fun loadImage(context: Context, url: String, imageView: ImageView) {
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
fun loadImage(context: Context, image: Int, imageView: ImageView) {
|
||||
Glide.with(context)
|
||||
.load(image)
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
fun loadImageWithPlaceholder(context: Context, url: String, imageView: ImageView, placeholderResId: Int) {
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.apply(getDefaultOptions().placeholder(placeholderResId))
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
fun loadImageWithError(context: Context, url: String, imageView: ImageView, errorResId: Int) {
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.apply(getDefaultOptions().error(errorResId))
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
fun loadImageCircle(context: Context, url: String, imageView: ImageView) {
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.apply(getCircleCropOptions())
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
private fun getDefaultOptions(): RequestOptions {
|
||||
return RequestOptions()
|
||||
.centerCrop() // 默认居中裁剪
|
||||
.dontAnimate() // 禁止动画(如果不需要)
|
||||
}
|
||||
|
||||
private fun getCircleCropOptions(): RequestOptions {
|
||||
return RequestOptions()
|
||||
.circleCrop() // 圆形裁剪
|
||||
.dontAnimate() // 禁止动画
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user