diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b78af99
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+KChat-Android
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b589d56..b86273d 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 0897082..7b3006b 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,6 +4,7 @@
diff --git a/README.md b/README.md
index a808eb0..59e3664 100644
--- a/README.md
+++ b/README.md
@@ -20,15 +20,15 @@
- [x] **搜索功能**:支持通过关键词在聊天记录中搜索消息,同时支持按文件类型筛选。
- [x] **修改个人信息**:用户可以修改昵称、头像、个性签名等个人信息,提升个性化体验。
- [x] **修改用户密码**:用户可以更新自己的密码。
+- [x] **离线消息**:即使用户离线,服务器也会缓存消息,并在用户上线后自动同步到设备。
- [ ] **查看好友动态**:支持查看好友分享的动态内容,形式包括文字、图片和视频,用户可以点赞或评论。
- [ ] **支持多媒体消息**:支持发送音频、视频、文件等多种格式,满足用户不同的交流需求。
- [ ] **群聊支持**:用户可以创建群组,与多人实时互动,并支持群管理功能(如设置群管理员、踢人)。
- [ ] **消息通知**:支持推送通知,提醒用户有新的消息,未读消息可在通知栏中展示摘要。
-- [ ] **离线消息**:即使用户离线,服务器也会缓存消息,并在用户上线后自动同步到设备。
### 其他特性
-- [ ] **消息加密**:所有用户消息在传输过程中都进行端到端加密,确保通信安全,防止信息泄露。
+- [x] **消息加密**:所有用户消息在传输过程中都进行端到端加密,确保通信安全,防止信息泄露。
- [ ] **个性化设置**:支持用户自定义头像、昵称、聊天背景,提供多种预设主题和自定义选项。
- [ ] **深色/浅色模式**:支持自动或手动切换界面主题,适配不同的光线环境和用户偏好。
diff --git a/app/src/main/kotlin/com/kaixed/kchat/extensions/CommonExtensions.kt b/app/src/main/kotlin/com/kaixed/kchat/extensions/CommonExtensions.kt
new file mode 100644
index 0000000..58cf6d1
--- /dev/null
+++ b/app/src/main/kotlin/com/kaixed/kchat/extensions/CommonExtensions.kt
@@ -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 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)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/network/NetworkInterface.kt b/app/src/main/kotlin/com/kaixed/kchat/network/NetworkInterface.kt
index 5c4a970..dc05114 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/network/NetworkInterface.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/network/NetworkInterface.kt
@@ -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"
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/network/service/AuthApiService.kt b/app/src/main/kotlin/com/kaixed/kchat/network/service/AuthApiService.kt
index 59a27ab..7cb9562 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/network/service/AuthApiService.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/network/service/AuthApiService.kt
@@ -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
- @POST("auth/refresh-token")
+ @POST(REFRESH_TOKEN)
suspend fun refresh(
@Header("Authorization") token: String,
@Query("username") username: String
): ApiResponse
// 登录接口(根据用户名登录)
- @POST("auth/login/username")
+ @POST(LOGIN_BY_USERNAME)
suspend fun loginByUsername(
@Body requestParams: Map,
): ApiResponse
// 登录接口(根据电话登录)
- @POST("auth/login/telephone")
+ @POST(LOGIN_BY_TELEPHONE)
suspend fun loginByTelephone(
@Body requestParams: Map,
): ApiResponse
// 注册接口
- @POST("auth/register")
+ @POST(REGISTER)
suspend fun register(
@Body registerRequest: RegisterRequest
): ApiResponse
diff --git a/app/src/main/kotlin/com/kaixed/kchat/network/service/FileApiService.kt b/app/src/main/kotlin/com/kaixed/kchat/network/service/FileApiService.kt
index 05b4d29..ed2c5bc 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/network/service/FileApiService.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/network/service/FileApiService.kt
@@ -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
diff --git a/app/src/main/kotlin/com/kaixed/kchat/network/service/FriendApiService.kt b/app/src/main/kotlin/com/kaixed/kchat/network/service/FriendApiService.kt
index ac3417a..6580d32 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/network/service/FriendApiService.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/network/service/FriendApiService.kt
@@ -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?>
- // 接受联系人请求
+ // 接受好友请求
@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?>
// 删除联系人
- @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,
diff --git a/app/src/main/kotlin/com/kaixed/kchat/network/service/UserApiService.kt b/app/src/main/kotlin/com/kaixed/kchat/network/service/UserApiService.kt
index 96c2bce..62ce088 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/network/service/UserApiService.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/network/service/UserApiService.kt
@@ -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
): ApiResponse>
// 获取用户信息
- @POST("users/info/fetch")
+ @POST(GET_USER_INFO)
suspend fun getUserInfo(
@Body requestParams: Map
): ApiResponse
// 更改昵称接口
- @POST("users/info")
+ @POST(UPDATE_USER_INFO)
suspend fun changeNickname(
@Body userRequest: UserRequest
): ApiResponse
// 上传头像接口
@Multipart
- @POST("users/avatar")
+ @POST(UPLOAD_AVATAR)
suspend fun uploadAvatar(
@Part("username") username: String,
@Part file: MultipartBody.Part
): ApiResponse
// 更改密码
- @POST("users/password")
+ @POST(UPDATE_PASSWORD)
suspend fun updatePassword(
@Body updatePasswordRequest: UpdatePasswordRequest
): ApiResponse
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/AddFriendsActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/AddFriendsActivity.kt
index 1835cd9..ce9ae5d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/AddFriendsActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/AddFriendsActivity.kt
@@ -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() {
private val context: Context by lazy { this }
@@ -18,15 +25,21 @@ class AddFriendsActivity : BaseActivity() {
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()
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyAddFriendActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyAddFriendActivity.kt
index 9b083d9..b2b119d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyAddFriendActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyAddFriendActivity.kt
@@ -21,11 +21,13 @@ class ApplyAddFriendActivity : BaseActivity() {
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() {
}
}
- private fun setListener() {
+ override fun setupListeners() {
binding.tvSendApply.setOnClickListener {
sendContactRequest(contactId)
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyFriendsDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyFriendsDetailActivity.kt
index 55e9895..e128ff4 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyFriendsDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApplyFriendsDetailActivity.kt
@@ -12,26 +12,14 @@ import com.kaixed.kchat.ui.base.BaseActivity
class ApplyFriendsDetailActivity : BaseActivity() {
- 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
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApproveDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApproveDetailActivity.kt
index 400b44e..01367f1 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApproveDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ApproveDetailActivity.kt
@@ -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() {
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() {
)
}
}
+
+ override fun inflateBinding(): ActivityApproveDetailBinding {
+ return ActivityApproveDetailBinding.inflate(layoutInflater)
+ }
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatActivity.kt
index bdec026..1f7cac3 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatActivity.kt
@@ -116,13 +116,9 @@ class ChatActivity : BaseActivity(), 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(), 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(), 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 = 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()
+ 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(), 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 = 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()
- 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)
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt
index 1907a3b..1a57d03 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ChatDetailActivity.kt
@@ -25,13 +25,9 @@ class ChatDetailActivity : BaseActivity() {
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() {
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) {
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactPermissionActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactPermissionActivity.kt
index 64d14e3..b28dc6c 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactPermissionActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactPermissionActivity.kt
@@ -21,7 +21,14 @@ class ContactPermissionActivity : BaseActivity
override fun initData() {
}
- private fun initView() {
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+
+ }
+
+ override fun initView() {
binding.ciChat.setYesSelected(false)
}
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactRequestListActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactRequestListActivity.kt
index 9594ec0..7211b0d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactRequestListActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactRequestListActivity.kt
@@ -13,7 +13,6 @@ import com.kaixed.kchat.viewmodel.ContactViewModel
class ContactRequestListActivity : BaseActivity() {
-
private var items = mutableListOf()
private val contactViewModel: ContactViewModel by viewModels()
@@ -38,10 +37,19 @@ class ContactRequestListActivity : BaseActivity
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactUpdatesActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactUpdatesActivity.kt
index 193585d..2083bee 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactUpdatesActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactUpdatesActivity.kt
@@ -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() {
- 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() {
+ }
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactsDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactsDetailActivity.kt
index 1ab2626..d439fb0 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactsDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ContactsDetailActivity.kt
@@ -36,16 +36,49 @@ class ContactsDetailActivity : BaseActivity() {
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() {
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))
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/DataSettingActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/DataSettingActivity.kt
index b478f0c..c5a2b54 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/DataSettingActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/DataSettingActivity.kt
@@ -33,10 +33,20 @@ class DataSettingActivity : BaseActivity(),
handleIntent(intent)
}
+ override fun initView() {
+
+ }
+
override fun initData() {
}
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+ }
+
private fun handleIntent(intent: Intent) {
contactId = intent.getStringExtra("contactId") ?: ""
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/FriendCircleActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/FriendCircleActivity.kt
index d7a5ae3..0763716 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/FriendCircleActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/FriendCircleActivity.kt
@@ -38,21 +38,21 @@ class FriendCircleActivity : BaseActivity() {
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() {
@SuppressLint("NewApi")
- private fun initView() {
+ override fun initView() {
setContent()
binding.clTool.apply {
updateLayoutParams {
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LaunchActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LaunchActivity.kt
index 2544b26..d9ef27f 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LaunchActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LaunchActivity.kt
@@ -35,10 +35,19 @@ class LaunchActivity : BaseActivity() {
setOnClickListener()
}
+ override fun initView() {
+ }
+
override fun initData() {
}
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+ }
+
@SuppressLint("DiscouragedApi", "InternalInsetResource")
private fun getStatusBarHeight(): Int {
var result = 0
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LoginActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LoginActivity.kt
index 76ad3fc..f5a28ca 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LoginActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/LoginActivity.kt
@@ -58,7 +58,7 @@ class LoginActivity : BaseActivity() {
}
}
- private fun initView() {
+ override fun initView() {
setupLoginView()
}
@@ -210,6 +210,11 @@ class LoginActivity : BaseActivity() {
}
override fun initData() {}
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+ }
override fun inflateBinding(): ActivityLoginBinding {
return ActivityLoginBinding.inflate(layoutInflater)
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/MainActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/MainActivity.kt
index 42e20af..b04d076 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/MainActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/MainActivity.kt
@@ -180,6 +180,12 @@ class MainActivity : BaseActivity() {
}
}
+ 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() {
}
- private fun initView() {
+ override fun initView() {
navItems.forEachIndexed { index, navItem ->
navItem.container.setOnClickListener {
updateSelection(index)
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ProfileDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ProfileDetailActivity.kt
index 22603df..7d1acfe 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ProfileDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ProfileDetailActivity.kt
@@ -65,6 +65,9 @@ class ProfileDetailActivity : BaseActivity() {
updateContent(username)
}
+ override fun initView() {
+ }
+
override fun initData() {
getImageLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
@@ -79,6 +82,12 @@ class ProfileDetailActivity : BaseActivity() {
}
}
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+ }
+
private fun updateAvatar(uri: Uri) {
val filePath = getPathFromUri(uri)
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/QrCodeActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/QrCodeActivity.kt
index e35cef0..81d1c72 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/QrCodeActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/QrCodeActivity.kt
@@ -31,6 +31,9 @@ class QrCodeActivity : BaseActivity() {
}
}
+ override fun initView() {
+ }
+
override fun initData() {
setupQrcode()
binding.tvNickname.text = getNickName()
@@ -38,6 +41,12 @@ class QrCodeActivity : BaseActivity() {
.into(binding.ifvAvatar)
}
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
+ }
+
private fun setupQrcode() {
val content = "kchat@${getUsername()}"
val type = HmsScan.QRCODE_SCAN_TYPE
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RegisterActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RegisterActivity.kt
index 771b509..2c9230f 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RegisterActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RegisterActivity.kt
@@ -33,10 +33,6 @@ class RegisterActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
-
- initView()
-
- setOnClickListener()
}
override fun initData() {
@@ -53,7 +49,10 @@ class RegisterActivity : BaseActivity() {
}
}
- private fun setOnClickListener() {
+ override fun observeData() {
+ }
+
+ override fun setupListeners() {
binding.ivClose.setOnClickListener {
finish()
}
@@ -95,7 +94,7 @@ class RegisterActivity : BaseActivity() {
}
- private fun initView() {
+ override fun initView() {
setupTip()
setOnEtChangeListener()
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RenameActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RenameActivity.kt
index ea0a00d..531ab92 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RenameActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/RenameActivity.kt
@@ -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() {
- private val userInfoBox: Box by lazy { getBoxStore().boxFor(UserInfo::class.java) }
-
private val userViewModel: UserViewModel by viewModels()
private var oldNickname: String = ""
@@ -56,10 +54,19 @@ class RenameActivity : BaseActivity() {
}
}
+ 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("正在保存")
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ScanActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ScanActivity.kt
index 2128830..7dafe8c 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ScanActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ScanActivity.kt
@@ -86,6 +86,15 @@ class ScanActivity : BaseActivity() {
}
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
+
private fun initPermission() {
ActivityCompat.requestPermissions(
this,
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchActivity.kt
index 3037f47..15dec21 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchActivity.kt
@@ -40,13 +40,22 @@ class SearchActivity : BaseActivity() {
}
+ 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) {
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchChatHistory.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchChatHistory.kt
index c9617de..ca6eece 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchChatHistory.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchChatHistory.kt
@@ -140,4 +140,13 @@ class SearchChatHistory : BaseActivity() {
contactAvatarUrl = intent?.getStringExtra("contactAvatarUrl") ?: ""
contactId = intent?.getStringExtra("contactId") ?: ""
}
+
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchFriendsActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchFriendsActivity.kt
index 7ce6bf8..007c814 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchFriendsActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SearchFriendsActivity.kt
@@ -132,11 +132,17 @@ class SearchFriendsActivity : BaseActivity() {
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)
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ServiceDetailActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ServiceDetailActivity.kt
index 1f91c60..58fc043 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ServiceDetailActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/ServiceDetailActivity.kt
@@ -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() {
-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)
}
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkActivity.kt
index 58a0aac..3746075 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkActivity.kt
@@ -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() {
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)
+ }
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkAndLabelActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkAndLabelActivity.kt
index d283af2..3abf441 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkAndLabelActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SetRemarkAndLabelActivity.kt
@@ -25,10 +25,6 @@ import kotlinx.coroutines.launch
class SetRemarkAndLabelActivity : BaseActivity() {
- 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
remark = contact?.remark ?: contact?.nickname ?: ""
}
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
+
override fun onResume() {
super.onResume()
updateContent()
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SettingsActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SettingsActivity.kt
index e0b456f..4d04c2d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/SettingsActivity.kt
@@ -140,4 +140,13 @@ class SettingsActivity : BaseActivity(), View.OnClickLis
override fun initData() {
}
+
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/TestActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/TestActivity.kt
index 3553000..04d5730 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/TestActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/TestActivity.kt
@@ -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() {
}
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/WebViewActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/WebViewActivity.kt
index 4d74e63..9d629e6 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/WebViewActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/WebViewActivity.kt
@@ -57,6 +57,15 @@ class WebViewActivity : BaseActivity() {
url = intent.getStringExtra("url") ?: ""
}
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
+
private fun setupWebView() {
// 启用 JavaScript
webView.settings.javaScriptEnabled = true
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt
index 48869f4..089d751 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AboutActivity.kt
@@ -28,4 +28,13 @@ class AboutActivity : BaseActivity() {
loadingDialog.showLoading(supportFragmentManager)
}
}
+
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ }
+
+ override fun observeData() {
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AccountSecurityActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AccountSecurityActivity.kt
index a9eb48d..1a53509 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AccountSecurityActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/AccountSecurityActivity.kt
@@ -16,16 +16,6 @@ class AccountSecurityActivity : BaseActivity() {
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() {
binding.ciTelephone.setItemDesc(telephone)
}
}
+
+ override fun initView() {
+ }
+
+ override fun setupListeners() {
+ binding.ciUpdatePassword.setOnClickListener {
+ startActivity(
+ Intent(this, UpdatePasswordActivity::class.java)
+ )
+ }
+ }
+
+ override fun observeData() {
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateKidActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateKidActivity.kt
index cdc9e22..2b30f0b 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateKidActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateKidActivity.kt
@@ -17,10 +17,18 @@ class UpdateKidActivity : BaseActivity() {
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() {
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdatePasswordActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdatePasswordActivity.kt
index 4017d72..a27d3dd 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdatePasswordActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdatePasswordActivity.kt
@@ -83,6 +83,15 @@ class UpdatePasswordActivity : BaseActivity() {
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) {
}
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateTelephoneActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateTelephoneActivity.kt
index 59ccbed..b07d54d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateTelephoneActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/activity/setting/UpdateTelephoneActivity.kt
@@ -22,4 +22,16 @@ class UpdateTelephoneActivity : BaseActivity() {
override fun initData() {
}
+
+ override fun initView() {
+ TODO("Not yet implemented")
+ }
+
+ override fun setupListeners() {
+ TODO("Not yet implemented")
+ }
+
+ override fun observeData() {
+ TODO("Not yet implemented")
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/base/BaseActivity.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/base/BaseActivity.kt
index 20e0a99..1302f2d 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/base/BaseActivity.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/base/BaseActivity.kt
@@ -14,13 +14,13 @@ abstract class BaseActivity : 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 : 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 : AppCompatActivity() {
fun toast() {
Toast.makeText(this, "暂未开发", Toast.LENGTH_SHORT).show()
}
+
+ abstract fun inflateBinding(): VB
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/kaixed/kchat/ui/widget/CustomItem.kt b/app/src/main/kotlin/com/kaixed/kchat/ui/widget/CustomItem.kt
index f9a9c11..72c8a09 100644
--- a/app/src/main/kotlin/com/kaixed/kchat/ui/widget/CustomItem.kt
+++ b/app/src/main/kotlin/com/kaixed/kchat/ui/widget/CustomItem.kt
@@ -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
diff --git a/app/src/main/kotlin/com/kaixed/kchat/utils/ImageLoader.kt b/app/src/main/kotlin/com/kaixed/kchat/utils/ImageLoader.kt
new file mode 100644
index 0000000..c169b13
--- /dev/null
+++ b/app/src/main/kotlin/com/kaixed/kchat/utils/ImageLoader.kt
@@ -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() // 禁止动画
+ }
+}