From 81f90db1b10c1aaeb64018e14183346ee5d5e77f Mon Sep 17 00:00:00 2001 From: AllenTom Date: Fri, 11 Oct 2024 16:51:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=81=8A=E5=A4=A9=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 7 +- .../java/com/aiosman/riderpro/AppState.kt | 18 ++- .../java/com/aiosman/riderpro/ChatState.kt | 40 ++++++ .../java/com/aiosman/riderpro/MainActivity.kt | 23 +++- .../java/com/aiosman/riderpro/TrtcService.kt | 129 ++++++++++++++++++ .../com/aiosman/riderpro/data/ChatService.kt | 42 ++++++ .../aiosman/riderpro/data/api/RiderProAPI.kt | 47 +++---- .../java/com/aiosman/riderpro/entity/Chat.kt | 24 +++- .../aiosman/riderpro/ui/chat/ChatScreen.kt | 41 +++++- .../aiosman/riderpro/ui/chat/ChatViewModel.kt | 18 ++- .../index/tabs/profile/MyProfileViewModel.kt | 4 +- .../ui/index/tabs/profile/ProfileV3.kt | 99 +++++++------- .../ui/index/tabs/profile/ProfileWrap.kt | 17 +-- .../res/drawable/rider_pro_notice_active.xml | 5 + .../res/drawable/rider_pro_notice_mute.xml | 5 + 15 files changed, 414 insertions(+), 105 deletions(-) create mode 100644 app/src/main/java/com/aiosman/riderpro/ChatState.kt create mode 100644 app/src/main/java/com/aiosman/riderpro/TrtcService.kt create mode 100644 app/src/main/java/com/aiosman/riderpro/data/ChatService.kt create mode 100644 app/src/main/res/drawable/rider_pro_notice_active.xml create mode 100644 app/src/main/res/drawable/rider_pro_notice_mute.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b3eeeb9..76b5645 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -37,9 +37,9 @@ + android:theme="@style/Theme.RiderPro" + android:windowSoftInputMode="adjustResize"> @@ -69,6 +69,9 @@ + () + suspend fun getStrategyByTargetTrtcId(targetTrtcId: String): ChatNotification? { + // 先从缓存中查找 + if (chatNotificationList.isNotEmpty()) { + chatNotificationList.forEach { + if (it.targetTrtcId == targetTrtcId) { + return it + } + } + } + // 缓存中没有再从网络获取 + chatService.getChatNotifications(targetTrtcId)?.let { + chatNotificationList.add(it) + return it + } + // 存在未设置策略的情况 + return null + } + + suspend fun updateChatNotification(targetUserId: Int, strategy: String): ChatNotification { + val updatedData = chatService.updateChatNotification(targetUserId, strategy) + chatNotificationList = chatNotificationList.filter { + it.targetUserId != targetUserId + }.toMutableList().apply { + add(updatedData) + } + return updatedData + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/MainActivity.kt b/app/src/main/java/com/aiosman/riderpro/MainActivity.kt index ff6439e..b4e559c 100644 --- a/app/src/main/java/com/aiosman/riderpro/MainActivity.kt +++ b/app/src/main/java/com/aiosman/riderpro/MainActivity.kt @@ -26,6 +26,8 @@ import cn.jiguang.api.utils.JCollectionAuth import cn.jpush.android.api.JPushInterface import com.aiosman.riderpro.data.AccountService import com.aiosman.riderpro.data.AccountServiceImpl +import com.aiosman.riderpro.data.UserService +import com.aiosman.riderpro.data.UserServiceImpl import com.aiosman.riderpro.ui.Navigation import com.aiosman.riderpro.ui.NavigationRoute import com.aiosman.riderpro.ui.navigateToPost @@ -109,7 +111,7 @@ class MainActivity : ComponentActivity() { // 处理带有 postId 的通知点击 val postId = intent.getStringExtra("POST_ID") var commentId = intent.getStringExtra("COMMENT_ID") - var action = intent.getStringExtra("ACTION") + val action = intent.getStringExtra("ACTION") if (action == "newFollow") { navController.navigate(NavigationRoute.Followers.route) return@Navigation @@ -118,6 +120,25 @@ class MainActivity : ComponentActivity() { navController.navigate(NavigationRoute.Followers.route) return@Navigation } + if (action == "TRTC_NEW_MESSAGE") { + val userService:UserService = UserServiceImpl() + val sender = intent.getStringExtra("SENDER") + sender?.let { + scope.launch { + try { + val profile = userService.getUserProfileByTrtcUserId(it) + navController.navigate(NavigationRoute.Chat.route.replace( + "{id}", + profile.id.toString() + )) + }catch (e:Exception){ + e.printStackTrace() + } + } + } + return@Navigation + } + if (commentId == null) { commentId = "0" } diff --git a/app/src/main/java/com/aiosman/riderpro/TrtcService.kt b/app/src/main/java/com/aiosman/riderpro/TrtcService.kt new file mode 100644 index 0000000..cd14e56 --- /dev/null +++ b/app/src/main/java/com/aiosman/riderpro/TrtcService.kt @@ -0,0 +1,129 @@ +package com.aiosman.riderpro + +import android.Manifest +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.app.Service +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build +import android.os.IBinder +import android.util.Log +import androidx.core.app.ActivityCompat +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import com.aiosman.riderpro.entity.ChatItem +import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener +import com.tencent.imsdk.v2.V2TIMManager +import com.tencent.imsdk.v2.V2TIMMessage +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class TrtcService : Service() { + private var trtcMessageListener: V2TIMAdvancedMsgListener? = null + private val channelId = "chat_notification" + override fun onBind(intent: Intent?): IBinder? { + return null + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + Log.d("TrtcService", "onStartCommand") + createNotificationChannel() + CoroutineScope(Dispatchers.IO).launch { + registerMessageListener(applicationContext) + } + return START_STICKY; + } + + + override fun onDestroy() { + super.onDestroy() + Log.d("TrtcService", "onDestroy") + CoroutineScope(Dispatchers.IO).launch { + unRegisterMessageListener() + } + } + + private fun registerMessageListener(context: Context) { + val scope = CoroutineScope(Dispatchers.IO) + trtcMessageListener = object : V2TIMAdvancedMsgListener() { + override fun onRecvNewMessage(msg: V2TIMMessage?) { + super.onRecvNewMessage(msg) + msg?.let { + if (MainActivityLifecycle.isForeground) { + return + } + scope.launch { + // 先获取通知策略 + val notiStrategy = ChatState.getStrategyByTargetTrtcId(it.sender) + if (notiStrategy == null) { + // 未设置策略, 默认通知 + sendNotification(context, it) + return@launch + } + if (notiStrategy.strategy != "mute") { + sendNotification(context, it) + } + } + + } + } + } + V2TIMManager.getMessageManager().addAdvancedMsgListener(trtcMessageListener) + } + + private fun unRegisterMessageListener() { + V2TIMManager.getMessageManager().removeAdvancedMsgListener(trtcMessageListener) + } + + private fun createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val name = "Chat Notification" + val descriptionText = "Notification for chat message" + val importance = NotificationManager.IMPORTANCE_DEFAULT + val channel = NotificationChannel(channelId, name, importance).apply { + description = descriptionText + } + val notificationManager: NotificationManager = + getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(channel) + } + } + + private fun sendNotification(context: Context, message: V2TIMMessage) { + val intent = Intent(context, MainActivity::class.java).apply { + putExtra("ACTION", "TRTC_NEW_MESSAGE") + putExtra("SENDER", message.sender) + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + } + + val pendingIntent: PendingIntent = PendingIntent.getActivity( + context, + 0, + intent, + PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) + val chatItem = ChatItem.convertToChatItem(message, context) ?: return + val builder = NotificationCompat.Builder(context, channelId) + .setSmallIcon(R.mipmap.rider_pro_log_round) + .setContentTitle(chatItem.nickname) + .setContentText(chatItem.textDisplay) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + + with(NotificationManagerCompat.from(context)) { + if (ActivityCompat.checkSelfPermission( + context, + Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED + ) { + return + } + notify(message.msgID.hashCode(), builder.build()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/data/ChatService.kt b/app/src/main/java/com/aiosman/riderpro/data/ChatService.kt new file mode 100644 index 0000000..2a2751d --- /dev/null +++ b/app/src/main/java/com/aiosman/riderpro/data/ChatService.kt @@ -0,0 +1,42 @@ +package com.aiosman.riderpro.data + +import com.aiosman.riderpro.data.api.ApiClient +import com.aiosman.riderpro.data.api.UpdateChatNotificationRequestBody +import com.aiosman.riderpro.entity.ChatNotification + +interface ChatService { + suspend fun getChatNotifications( + targetTrtcId: String + ): ChatNotification? + + suspend fun updateChatNotification( + targetUserId: Int, + strategy: String + ): ChatNotification +} + +class ChatServiceImpl : ChatService { + override suspend fun getChatNotifications( + targetTrtcId: String + ): ChatNotification? { + val resp = ApiClient.api.getChatNotification(targetTrtcId) + if (resp.isSuccessful) { + return resp.body()?.data + } + return null + } + + override suspend fun updateChatNotification( + targetUserId: Int, + strategy: String + ): ChatNotification { + val resp = ApiClient.api.updateChatNotification(UpdateChatNotificationRequestBody( + targetUserId = targetUserId, + strategy = strategy + )) + if (resp.isSuccessful) { + return resp.body()?.data!! + } + throw Exception("update chat notification failed") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt b/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt index 2fdfa2e..97acccf 100644 --- a/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt +++ b/app/src/main/java/com/aiosman/riderpro/data/api/RiderProAPI.kt @@ -9,6 +9,7 @@ import com.aiosman.riderpro.data.Comment import com.aiosman.riderpro.data.DataContainer import com.aiosman.riderpro.data.ListContainer import com.aiosman.riderpro.data.Moment +import com.aiosman.riderpro.entity.ChatNotification import com.google.gson.annotations.SerializedName import okhttp3.MultipartBody import okhttp3.RequestBody @@ -154,31 +155,6 @@ data class GenerateLoginCaptchaRequestBody( @SerializedName("username") val username: String, ) -//{ -// "id":48, -// "dot": [ -// { -// "index": 0, -// "x": 76, -// "y": 165 -// }, -// { -// "index": 1, -// "x": 144, -// "y": 21 -// }, -// { -// "index": 2, -// "x": 220, -// "y": 42 -// }, -// { -// "index": 3, -// "x": 10, -// "y": 10 -// } -// ] -//} data class DotPosition( @SerializedName("index") val index: Int, @@ -193,6 +169,15 @@ data class CaptchaInfo( @SerializedName("dot") val dot: List ) + + +data class UpdateChatNotificationRequestBody( + @SerializedName("targetUserId") + val targetUserId: Int, + @SerializedName("strategy") + val strategy: String, +) + interface RiderProAPI { @POST("register") suspend fun register(@Body body: RegisterRequestBody): Response @@ -417,4 +402,14 @@ interface RiderProAPI { @Body body: GenerateLoginCaptchaRequestBody ): Response> -} \ No newline at end of file + @GET("chat/notification") + suspend fun getChatNotification( + @Query("targetTrtcId") targetTrtcId: String + ): Response> + + @POST("chat/notification") + suspend fun updateChatNotification( + @Body body: UpdateChatNotificationRequestBody + ): Response> +} + diff --git a/app/src/main/java/com/aiosman/riderpro/entity/Chat.kt b/app/src/main/java/com/aiosman/riderpro/entity/Chat.kt index 2dd0d82..6309b23 100644 --- a/app/src/main/java/com/aiosman/riderpro/entity/Chat.kt +++ b/app/src/main/java/com/aiosman/riderpro/entity/Chat.kt @@ -3,6 +3,7 @@ package com.aiosman.riderpro.entity import android.content.Context import android.icu.util.Calendar import com.aiosman.riderpro.exp.formatChatTime +import com.google.gson.annotations.SerializedName import com.tencent.imsdk.v2.V2TIMImageElem import com.tencent.imsdk.v2.V2TIMMessage @@ -15,11 +16,11 @@ data class ChatItem( val timeCategory: String = "", val timestamp: Long = 0, val imageList: MutableList = emptyList().toMutableList(), - val messageType : Int = 0, - val textDisplay : String = "", + val messageType: Int = 0, + val textDisplay: String = "", val msgId: String, // Add this property var showTimestamp: Boolean = false, - var showTimeDivider:Boolean = false + var showTimeDivider: Boolean = false ) { companion object { fun convertToChatItem(message: V2TIMMessage, context: Context): ChatItem? { @@ -36,7 +37,7 @@ data class ChatItem( val timestamp = message.timestamp val calendar = Calendar.getInstance() calendar.timeInMillis = timestamp * 1000 - val imageElm = message.imageElem?.imageList + val imageElm = message.imageElem?.imageList when (message.elemType) { V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE -> { val imageElm = message.imageElem?.imageList?.all { @@ -74,8 +75,8 @@ data class ChatItem( textDisplay = message.textElem?.text ?: "Unsupported message type", msgId = message.msgID // Add this line to include msgId ) - } + else -> { return null } @@ -85,3 +86,16 @@ data class ChatItem( } } + +data class ChatNotification( + @SerializedName("userId") + val userId: Int, + @SerializedName("userTrtcId") + val userTrtcId: String, + @SerializedName("targetUserId") + val targetUserId: Int, + @SerializedName("targetTrtcId") + val targetTrtcId: String, + @SerializedName("strategy") + val strategy: String +) \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatScreen.kt b/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatScreen.kt index 107c1d0..e01a56d 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatScreen.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatScreen.kt @@ -66,12 +66,15 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.viewModel import com.aiosman.riderpro.LocalNavController import com.aiosman.riderpro.R import com.aiosman.riderpro.entity.ChatItem import com.aiosman.riderpro.exp.formatChatTime import com.aiosman.riderpro.ui.composables.CustomAsyncImage +import com.aiosman.riderpro.ui.composables.DropdownMenu +import com.aiosman.riderpro.ui.composables.MenuItem import com.aiosman.riderpro.ui.composables.StatusBarSpacer import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.tencent.imsdk.v2.V2TIMMessage @@ -80,6 +83,7 @@ import kotlinx.coroutines.launch @Composable fun ChatScreen(userId: String) { + var isMenuExpanded by remember { mutableStateOf(false) } val navController = LocalNavController.current val context = LocalNavController.current.context val viewModel = viewModel( @@ -131,7 +135,7 @@ fun ChatScreen(userId: String) { Row( modifier = Modifier .fillMaxWidth() - .padding(vertical = 8.dp, horizontal = 16.dp), + .padding(vertical = 16.dp, horizontal = 16.dp), horizontalArrangement = Arrangement.Start, verticalAlignment = androidx.compose.ui.Alignment.CenterVertically ) { @@ -154,6 +158,41 @@ fun ChatScreen(userId: String) { fontWeight = androidx.compose.ui.text.font.FontWeight.Bold ) ) + Spacer(modifier = Modifier.weight(1f)) + Box { + Image( + painter = painterResource(R.drawable.rider_pro_more_horizon), + modifier = Modifier + .size(28.dp) + .noRippleClickable { + isMenuExpanded = true + }, + contentDescription = null + ) + DropdownMenu( + expanded = isMenuExpanded, + onDismissRequest = { + isMenuExpanded = false + }, + menuItems = listOf( + MenuItem( + title = if (viewModel.notificationStrategy == "mute") "Unmute" else "Mute", + icon = if (viewModel.notificationStrategy == "mute") R.drawable.rider_pro_notice_mute else R.drawable.rider_pro_notice_active, + ){ + + isMenuExpanded = false + viewModel.viewModelScope.launch { + if (viewModel.notificationStrategy == "mute") { + viewModel.updateNotificationStrategy("active") + } else { + viewModel.updateNotificationStrategy("mute") + } + } + } + ), + + ) + } } } }, diff --git a/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatViewModel.kt b/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatViewModel.kt index c772e88..66f0fec 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatViewModel.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/chat/ChatViewModel.kt @@ -1,7 +1,6 @@ package com.aiosman.riderpro.ui.chat import android.content.Context -import android.icu.util.Calendar import android.net.Uri import android.provider.MediaStore import android.util.Log @@ -11,16 +10,16 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.aiosman.riderpro.ChatState import com.aiosman.riderpro.data.AccountService import com.aiosman.riderpro.data.AccountServiceImpl import com.aiosman.riderpro.data.UserService import com.aiosman.riderpro.data.UserServiceImpl import com.aiosman.riderpro.entity.AccountProfileEntity import com.aiosman.riderpro.entity.ChatItem -import com.aiosman.riderpro.exp.formatChatTime +import com.aiosman.riderpro.entity.ChatNotification import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener import com.tencent.imsdk.v2.V2TIMCallback -import com.tencent.imsdk.v2.V2TIMImageElem import com.tencent.imsdk.v2.V2TIMManager import com.tencent.imsdk.v2.V2TIMMessage import com.tencent.imsdk.v2.V2TIMSendCallback @@ -44,6 +43,7 @@ class ChatViewModel( var isLoading by mutableStateOf(false) var lastMessage: V2TIMMessage? = null val showTimestampMap = mutableMapOf() // Add this map + var chatNotification by mutableStateOf(null) fun init(context: Context) { // 获取用户信息 viewModelScope.launch { @@ -53,6 +53,9 @@ class ChatViewModel( RegistListener(context) fetchHistoryMessage(context) + // 获取通知信息 + val notiStrategy = ChatState.getStrategyByTargetTrtcId(resp.trtcUserId) + chatNotification = notiStrategy } } @@ -243,4 +246,13 @@ class ChatViewModel( } return list } + + suspend fun updateNotificationStrategy(strategy: String) { + userProfile?.let { + val result = ChatState.updateChatNotification(it.id, strategy) + chatNotification = result + } + } + + val notificationStrategy get() = chatNotification?.strategy ?: "default" } \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/MyProfileViewModel.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/MyProfileViewModel.kt index dedbfc8..349fb19 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/MyProfileViewModel.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/MyProfileViewModel.kt @@ -73,13 +73,13 @@ object MyProfileViewModel : ViewModel() { } } - suspend fun logout() { + suspend fun logout(context: Context) { AppStore.apply { token = null rememberMe = false saveData() } - AppState.ReloadAppState() + AppState.ReloadAppState(context) } fun updateUserProfileBanner(bannerImageUrl: Uri?,file:File, context: Context) { diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileV3.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileV3.kt index 1d7bdbe..eccb8e8 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileV3.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileV3.kt @@ -378,62 +378,65 @@ fun ProfileV3( color = Color.Black ) Spacer(modifier = Modifier.weight(1f)) - Box( - modifier = Modifier - ) { + if (isSelf) { Box( modifier = Modifier - .padding(16.dp) ) { - Icon( - painter = painterResource(id = R.drawable.rider_pro_more_horizon), - contentDescription = "", - modifier = Modifier.noRippleClickable { - minibarExpanded = true - }, - tint = Color.Black - ) - } - DropdownMenu( - expanded = minibarExpanded, - onDismissRequest = { minibarExpanded = false }, - width = 250, - menuItems = listOf( - MenuItem( - stringResource(R.string.logout), - R.mipmap.rider_pro_logout - ) { - minibarExpanded = false - scope.launch { - onLogout() - navController.navigate(NavigationRoute.Login.route) { - popUpTo(NavigationRoute.Index.route) { - inclusive = true + Box( + modifier = Modifier + .padding(16.dp) + ) { + Icon( + painter = painterResource(id = R.drawable.rider_pro_more_horizon), + contentDescription = "", + modifier = Modifier.noRippleClickable { + minibarExpanded = true + }, + tint = Color.Black + ) + } + DropdownMenu( + expanded = minibarExpanded, + onDismissRequest = { minibarExpanded = false }, + width = 250, + menuItems = listOf( + MenuItem( + stringResource(R.string.logout), + R.mipmap.rider_pro_logout + ) { + minibarExpanded = false + scope.launch { + onLogout() + navController.navigate(NavigationRoute.Login.route) { + popUpTo(NavigationRoute.Index.route) { + inclusive = true + } } } + }, + MenuItem( + stringResource(R.string.change_password), + R.mipmap.rider_pro_change_password + ) { + minibarExpanded = false + scope.launch { + navController.navigate(NavigationRoute.ChangePasswordScreen.route) + } + }, + MenuItem( + stringResource(R.string.favourites), + R.drawable.rider_pro_favourite + ) { + minibarExpanded = false + scope.launch { + navController.navigate(NavigationRoute.FavouriteList.route) + } } - }, - MenuItem( - stringResource(R.string.change_password), - R.mipmap.rider_pro_change_password - ) { - minibarExpanded = false - scope.launch { - navController.navigate(NavigationRoute.ChangePasswordScreen.route) - } - }, - MenuItem( - stringResource(R.string.favourites), - R.drawable.rider_pro_favourite - ) { - minibarExpanded = false - scope.launch { - navController.navigate(NavigationRoute.FavouriteList.route) - } - } + ) ) - ) + } } + } Spacer(modifier = Modifier.height(8.dp)) } diff --git a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileWrap.kt b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileWrap.kt index 23db28f..e14508e 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileWrap.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/index/tabs/profile/ProfileWrap.kt @@ -2,6 +2,7 @@ package com.aiosman.riderpro.ui.index.tabs.profile import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch @@ -9,29 +10,17 @@ import kotlinx.coroutines.launch fun ProfileWrap( ) { + val context = LocalContext.current LaunchedEffect(Unit) { MyProfileViewModel.loadProfile() } -// ProfileV2( -// onUpdateBanner = { uri, context -> -// MyProfileViewModel.updateUserProfileBanner(uri, context) -// }, -// onLogout = { -// MyProfileViewModel.viewModelScope.launch { -// MyProfileViewModel.logout() -// } -// -// }, -// profile = MyProfileViewModel.profile, -// sharedFlow = MyProfileViewModel.sharedFlow -// ) ProfileV3( onUpdateBanner = { uri, file, context -> MyProfileViewModel.updateUserProfileBanner(uri, file, context) }, onLogout = { MyProfileViewModel.viewModelScope.launch { - MyProfileViewModel.logout() + MyProfileViewModel.logout(context) } }, diff --git a/app/src/main/res/drawable/rider_pro_notice_active.xml b/app/src/main/res/drawable/rider_pro_notice_active.xml new file mode 100644 index 0000000..09fde48 --- /dev/null +++ b/app/src/main/res/drawable/rider_pro_notice_active.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/rider_pro_notice_mute.xml b/app/src/main/res/drawable/rider_pro_notice_mute.xml new file mode 100644 index 0000000..bfbc214 --- /dev/null +++ b/app/src/main/res/drawable/rider_pro_notice_mute.xml @@ -0,0 +1,5 @@ + + + + +