add notification

This commit is contained in:
2026-05-28 08:55:01 +07:00
parent a2a4433a9d
commit cab12da4a5
5 changed files with 67 additions and 17 deletions

View File

@@ -72,7 +72,7 @@ val LocalNavController = staticCompositionLocalOf<NavController> {
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
fun App() {
fun App(openRoomId: Long? = null) {
val context = LocalContext.current
val navController = rememberNavController()
val scope = rememberCoroutineScope()
@@ -101,6 +101,12 @@ fun App() {
}
}
LaunchedEffect(openRoomId) {
if (openRoomId != null) {
navController.navigate(Screen.Chat(openRoomId))
}
}
MaterialExpressiveTheme(
colorScheme = colorScheme,
typography = Typography(),

View File

@@ -23,8 +23,10 @@ class MainActivity : ComponentActivity() {
startService(intent)
}
val roomId = intent.getLongExtra("room_id", -1L)
setContent {
App()
App(openRoomId = if (roomId != -1L) roomId else null)
}
}
}

View File

@@ -3,6 +3,7 @@ package su.reya.coop
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
@@ -45,7 +46,7 @@ class NostrForegroundService : Service() {
// Handle notifications
nostr.handleLiteNotifications { event ->
if (!isUserInApp()) {
showNewMessageNotification(event.content())
showNewMessageNotification(event.roomId(), event.content())
}
}
} catch (e: Exception) {
@@ -76,12 +77,26 @@ class NostrForegroundService : Service() {
.build()
}
private fun showNewMessageNotification(message: String) {
private fun showNewMessageNotification(roomId: Long, message: String) {
val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
putExtra("room_id", roomId)
}
val pendingIntent = PendingIntent.getActivity(
this,
roomId.toInt(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, "nostr_service")
.setContentTitle("New Message")
.setContentTitle("You received a new message")
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build()
val manager = getSystemService(NotificationManager::class.java)
manager?.notify(System.currentTimeMillis().toInt(), notification)
}

View File

@@ -19,6 +19,8 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -37,6 +39,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -90,19 +93,16 @@ fun ChatScreen(
var text by remember { mutableStateOf("") }
var loading by remember { mutableStateOf(true) }
var newOtherMessages by remember { mutableIntStateOf(0) }
val messages = remember { mutableStateListOf<UnsignedEvent>() }
val groupedMessages = remember(messages.toList()) {
messages.groupBy { it.createdAt().formatAsGroupHeader() }
}
fun setLoading(value: Boolean) {
loading = value
}
LaunchedEffect(id) {
// Start loading spinner
setLoading(true)
loading = true
// Get messages
val initialMessages = viewModel.getChatRoomMessages(id)
@@ -122,7 +122,7 @@ fun ChatScreen(
}
// Stop loading spinner
setLoading(false)
loading = false
// Handle new messages
viewModel.newEvents.collect { event ->
@@ -130,6 +130,9 @@ fun ChatScreen(
if (event.id() !in messages.map { it.id() }) {
messages.add(0, event)
}
} else {
// If the event is not in the current room, it's a new message from another user
newOtherMessages++
}
}
}
@@ -173,12 +176,22 @@ fun ChatScreen(
}
},
navigationIcon = {
BadgedBox(
badge = {
if (newOtherMessages > 0) {
Badge {
Text(newOtherMessages.toString())
}
}
}
) {
IconButton(onClick = onBack) {
Icon(
painter = painterResource(Res.drawable.ic_arrow_back),
contentDescription = "Back"
)
}
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceContainer,

View File

@@ -109,13 +109,27 @@ class NostrViewModel(
},
onSubscriptionClose = {
getChatRooms()
if (!_isPartialProcessedGiftWrap.value) {
_isPartialProcessedGiftWrap.value = true
}
},
onNewMessage = { event ->
viewModelScope.launch {
val roomId = event.roomId()
val existingRoom = _chatRooms.value.firstOrNull { it.id == roomId }
if (existingRoom == null) {
val currentUser = nostr.signer.currentUser
if (currentUser != null) {
val newRoom = Room.new(event, currentUser)
_chatRooms.update { currentRooms ->
currentRooms + newRoom
}
}
} else {
updateRoomList(roomId, event)
}
_newEvents.emit(event)
}
},