@cometchat/skills 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/install.js +298 -41
- package/package.json +1 -1
- package/skills/cometchat/SKILL.md +146 -27
- package/skills/cometchat-a11y/SKILL.md +476 -0
- package/skills/cometchat-android-v5/SKILL.md +1 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +413 -0
- package/skills/cometchat-android-v5-calls/references/README.md +53 -0
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +195 -0
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +91 -0
- package/skills/cometchat-android-v5-calls/references/background-handling.md +168 -0
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +123 -0
- package/skills/cometchat-android-v5-calls/references/call-logs.md +113 -0
- package/skills/cometchat-android-v5-calls/references/call-session.md +274 -0
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +150 -0
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +123 -0
- package/skills/cometchat-android-v5-calls/references/group-calls.md +205 -0
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +111 -0
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +134 -0
- package/skills/cometchat-android-v5-calls/references/join-session.md +120 -0
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +206 -0
- package/skills/cometchat-android-v5-calls/references/participant-management.md +110 -0
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +106 -0
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +242 -0
- package/skills/cometchat-android-v5-calls/references/recording.md +101 -0
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +152 -0
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +82 -0
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +215 -0
- package/skills/cometchat-android-v5-calls/references/session-settings.md +121 -0
- package/skills/cometchat-android-v5-calls/references/setup.md +137 -0
- package/skills/cometchat-android-v5-calls/references/share-invite.md +151 -0
- package/skills/cometchat-android-v5-calls/references/video-controls.md +87 -0
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +526 -0
- package/skills/cometchat-android-v5-components/SKILL.md +1 -1
- package/skills/cometchat-android-v5-core/SKILL.md +1 -1
- package/skills/cometchat-android-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v5-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v5-features/SKILL.md +1 -1
- package/skills/cometchat-android-v5-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v5-production/SKILL.md +1 -1
- package/skills/cometchat-android-v5-push/SKILL.md +1 -1
- package/skills/cometchat-android-v5-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-android-v6/SKILL.md +1 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +1 -1
- package/skills/cometchat-android-v6-calls/SKILL.md +375 -0
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +97 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +91 -0
- package/skills/cometchat-android-v6-calls/references/call-session.md +163 -0
- package/skills/cometchat-android-v6-calls/references/device-management.md +171 -0
- package/skills/cometchat-android-v6-calls/references/group-calls.md +191 -0
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +107 -0
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +136 -0
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +186 -0
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +176 -0
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +127 -0
- package/skills/cometchat-android-v6-calls/references/share-invite.md +105 -0
- package/skills/cometchat-android-v6-compose-components/SKILL.md +2 -2
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-core/SKILL.md +1 -1
- package/skills/cometchat-android-v6-events/SKILL.md +1 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v6-features/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-migration/SKILL.md +398 -0
- package/skills/cometchat-android-v6-production/SKILL.md +1 -1
- package/skills/cometchat-android-v6-push/SKILL.md +1 -1
- package/skills/cometchat-android-v6-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-angular-calls/SKILL.md +511 -0
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +95 -0
- package/skills/cometchat-angular-calls/references/call-layouts.md +106 -0
- package/skills/cometchat-angular-calls/references/call-session.md +167 -0
- package/skills/cometchat-angular-calls/references/custom-ui.md +231 -0
- package/skills/cometchat-angular-calls/references/device-management.md +135 -0
- package/skills/cometchat-angular-calls/references/group-calls.md +412 -0
- package/skills/cometchat-angular-calls/references/idle-timeout.md +145 -0
- package/skills/cometchat-angular-calls/references/in-call-chat.md +148 -0
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +205 -0
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +53 -0
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +183 -0
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +285 -0
- package/skills/cometchat-angular-calls/references/raise-hand.md +167 -0
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +267 -0
- package/skills/cometchat-angular-calls/references/ringing-integration.md +131 -0
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +100 -0
- package/skills/cometchat-angular-calls/references/share-invite.md +116 -0
- package/skills/cometchat-angular-components/SKILL.md +1 -1
- package/skills/cometchat-angular-core/SKILL.md +1 -1
- package/skills/cometchat-angular-customization/SKILL.md +1 -1
- package/skills/cometchat-angular-features/SKILL.md +1 -1
- package/skills/cometchat-angular-patterns/SKILL.md +1 -1
- package/skills/cometchat-angular-placement/SKILL.md +1 -1
- package/skills/cometchat-angular-production/SKILL.md +1 -1
- package/skills/cometchat-angular-push/SKILL.md +403 -0
- package/skills/cometchat-angular-testing/SKILL.md +333 -0
- package/skills/cometchat-angular-theming/SKILL.md +1 -1
- package/skills/cometchat-angular-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-astro-patterns/SKILL.md +1 -1
- package/skills/cometchat-calls/SKILL.md +358 -0
- package/skills/cometchat-calls/references/use-case-broadcast.md +194 -0
- package/skills/cometchat-calls/references/use-case-marketplace.md +158 -0
- package/skills/cometchat-calls/references/use-case-support.md +190 -0
- package/skills/cometchat-calls/references/use-case-team.md +169 -0
- package/skills/cometchat-calls/references/use-case-telehealth.md +154 -0
- package/skills/cometchat-components/SKILL.md +1 -1
- package/skills/cometchat-core/SKILL.md +1 -1
- package/skills/cometchat-customization/SKILL.md +2 -2
- package/skills/cometchat-features/SKILL.md +2 -2
- package/skills/cometchat-flutter-v5/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-calls/SKILL.md +325 -94
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +169 -0
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +98 -0
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +330 -0
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +120 -0
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +187 -0
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +97 -0
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +132 -0
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +160 -0
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +244 -0
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +193 -0
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +101 -0
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +142 -0
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-push/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +390 -0
- package/skills/cometchat-flutter-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-calls/SKILL.md +308 -243
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +134 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +102 -0
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +229 -0
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +99 -0
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +190 -0
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +80 -0
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +122 -0
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +268 -0
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +171 -0
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +93 -0
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +102 -0
- package/skills/cometchat-flutter-v6-components/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-features/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-migration/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-placement/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-push/SKILL.md +452 -0
- package/skills/cometchat-flutter-v6-testing/SKILL.md +319 -0
- package/skills/cometchat-flutter-v6-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +1 -1
- package/skills/cometchat-i18n/SKILL.md +358 -0
- package/skills/cometchat-ios/SKILL.md +5 -5
- package/skills/cometchat-ios-calls/SKILL.md +409 -0
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +172 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +189 -0
- package/skills/cometchat-ios-calls/references/call-layouts.md +136 -0
- package/skills/cometchat-ios-calls/references/call-session.md +221 -0
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +353 -0
- package/skills/cometchat-ios-calls/references/custom-ui.md +322 -0
- package/skills/cometchat-ios-calls/references/device-management.md +171 -0
- package/skills/cometchat-ios-calls/references/group-calls.md +396 -0
- package/skills/cometchat-ios-calls/references/idle-timeout.md +185 -0
- package/skills/cometchat-ios-calls/references/in-call-chat.md +183 -0
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +138 -0
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +246 -0
- package/skills/cometchat-ios-calls/references/raise-hand.md +239 -0
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +339 -0
- package/skills/cometchat-ios-calls/references/ringing-integration.md +142 -0
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +267 -0
- package/skills/cometchat-ios-calls/references/share-invite.md +152 -0
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +246 -0
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +166 -0
- package/skills/cometchat-ios-components/SKILL.md +1 -1
- package/skills/cometchat-ios-core/SKILL.md +1 -1
- package/skills/cometchat-ios-customization/SKILL.md +1 -1
- package/skills/cometchat-ios-features/SKILL.md +1 -1
- package/skills/cometchat-ios-placement/SKILL.md +1 -1
- package/skills/cometchat-ios-production/SKILL.md +1 -1
- package/skills/cometchat-ios-push/SKILL.md +1 -1
- package/skills/cometchat-ios-testing/SKILL.md +371 -0
- package/skills/cometchat-ios-theming/SKILL.md +1 -1
- package/skills/cometchat-ios-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-native-bare-patterns/SKILL.md +45 -3
- package/skills/cometchat-native-calls/SKILL.md +599 -0
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +203 -0
- package/skills/cometchat-native-calls/references/call-layouts.md +124 -0
- package/skills/cometchat-native-calls/references/call-session.md +182 -0
- package/skills/cometchat-native-calls/references/custom-ui.md +250 -0
- package/skills/cometchat-native-calls/references/device-management.md +135 -0
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +179 -0
- package/skills/cometchat-native-calls/references/group-calls.md +291 -0
- package/skills/cometchat-native-calls/references/idle-timeout.md +128 -0
- package/skills/cometchat-native-calls/references/in-call-chat.md +143 -0
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +72 -0
- package/skills/cometchat-native-calls/references/picture-in-picture.md +276 -0
- package/skills/cometchat-native-calls/references/raise-hand.md +203 -0
- package/skills/cometchat-native-calls/references/recording-screen-share.md +290 -0
- package/skills/cometchat-native-calls/references/ringing-integration.md +118 -0
- package/skills/cometchat-native-calls/references/server-push-bridge.md +135 -0
- package/skills/cometchat-native-calls/references/server-push-payloads.md +193 -0
- package/skills/cometchat-native-calls/references/share-invite.md +144 -0
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +317 -0
- package/skills/cometchat-native-components/SKILL.md +1 -1
- package/skills/cometchat-native-core/SKILL.md +1 -1
- package/skills/cometchat-native-customization/SKILL.md +1 -1
- package/skills/cometchat-native-expo-patterns/SKILL.md +18 -1
- package/skills/cometchat-native-features/SKILL.md +1 -1
- package/skills/cometchat-native-placement/SKILL.md +1 -1
- package/skills/cometchat-native-production/SKILL.md +1 -1
- package/skills/cometchat-native-push/SKILL.md +1 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -1
- package/skills/cometchat-native-theming/SKILL.md +1 -1
- package/skills/cometchat-native-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-nextjs-patterns/SKILL.md +1 -1
- package/skills/cometchat-placement/SKILL.md +1 -1
- package/skills/cometchat-production/SKILL.md +1 -1
- package/skills/cometchat-react-calls/SKILL.md +539 -0
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +145 -0
- package/skills/cometchat-react-calls/references/call-layouts.md +161 -0
- package/skills/cometchat-react-calls/references/call-session.md +235 -0
- package/skills/cometchat-react-calls/references/custom-ui.md +201 -0
- package/skills/cometchat-react-calls/references/device-management.md +206 -0
- package/skills/cometchat-react-calls/references/group-calls.md +262 -0
- package/skills/cometchat-react-calls/references/idle-timeout.md +175 -0
- package/skills/cometchat-react-calls/references/in-call-chat.md +212 -0
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +172 -0
- package/skills/cometchat-react-calls/references/picture-in-picture.md +245 -0
- package/skills/cometchat-react-calls/references/raise-hand.md +238 -0
- package/skills/cometchat-react-calls/references/recording-screen-share.md +143 -0
- package/skills/cometchat-react-calls/references/ringing-integration.md +255 -0
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +241 -0
- package/skills/cometchat-react-calls/references/share-invite.md +176 -0
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +198 -0
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +165 -0
- package/skills/cometchat-react-patterns/SKILL.md +1 -1
- package/skills/cometchat-react-push/SKILL.md +448 -0
- package/skills/cometchat-react-router-patterns/SKILL.md +1 -1
- package/skills/cometchat-react-testing/SKILL.md +404 -0
- package/skills/cometchat-theming/SKILL.md +3 -3
- package/skills/cometchat-troubleshooting/SKILL.md +2 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# In-call chat on Android V6
|
|
2
|
+
|
|
3
|
+
V5 has detailed in-call-chat reference; V6 adds Compose-specific UI patterns. The SDK API + group-as-session architecture is unchanged.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://www.cometchat.com/docs/calls/android/in-call-chat
|
|
6
|
+
**Read first:** `cometchat-android-v5-calls/references/in-call-chat.md` — full Kotlin Views + Java SDK patterns + group setup.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Compose ModalBottomSheet for in-call chat
|
|
11
|
+
|
|
12
|
+
```kotlin
|
|
13
|
+
@OptIn(ExperimentalMaterial3Api::class)
|
|
14
|
+
@Composable
|
|
15
|
+
fun InCallChatSheet(
|
|
16
|
+
sessionId: String,
|
|
17
|
+
viewModel: InCallChatViewModel = viewModel(),
|
|
18
|
+
) {
|
|
19
|
+
val state by viewModel.state.collectAsStateWithLifecycle()
|
|
20
|
+
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = false)
|
|
21
|
+
|
|
22
|
+
if (state.open && state.group != null) {
|
|
23
|
+
ModalBottomSheet(
|
|
24
|
+
onDismissRequest = { viewModel.close() },
|
|
25
|
+
sheetState = sheetState,
|
|
26
|
+
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
|
27
|
+
) {
|
|
28
|
+
Column(modifier = Modifier
|
|
29
|
+
.fillMaxWidth()
|
|
30
|
+
.heightIn(min = 400.dp)
|
|
31
|
+
.padding(16.dp)) {
|
|
32
|
+
Text("Chat", style = MaterialTheme.typography.titleMedium)
|
|
33
|
+
Spacer(modifier = Modifier.height(8.dp))
|
|
34
|
+
// Compose call's CometChatMessageList composable
|
|
35
|
+
CometChatMessageList(
|
|
36
|
+
group = state.group,
|
|
37
|
+
modifier = Modifier.weight(1f),
|
|
38
|
+
)
|
|
39
|
+
CometChatMessageComposer(group = state.group)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`Modifier.weight(1f)` makes the message list expand; composer pinned at bottom. Same minHeight:0 idea but Compose-flavored.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ViewModel
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
data class InCallChatState(
|
|
54
|
+
val open: Boolean = false,
|
|
55
|
+
val unread: Int = 0,
|
|
56
|
+
val group: Group? = null,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
class InCallChatViewModel : ViewModel(), MessageListener {
|
|
60
|
+
private val _state = MutableStateFlow(InCallChatState())
|
|
61
|
+
val state: StateFlow<InCallChatState> = _state
|
|
62
|
+
|
|
63
|
+
fun init(sessionId: String) {
|
|
64
|
+
viewModelScope.launch {
|
|
65
|
+
val group = ensureGroup(sessionId)
|
|
66
|
+
_state.update { it.copy(group = group) }
|
|
67
|
+
CometChat.addMessageListener("in-call-chat-$sessionId", this@InCallChatViewModel)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
override fun onTextMessageReceived(message: TextMessage) {
|
|
72
|
+
if (_state.value.open) return
|
|
73
|
+
if (message.receiverType != CometChatConstants.RECEIVER_TYPE_GROUP) return
|
|
74
|
+
if (message.receiverUid != _state.value.group?.guid) return
|
|
75
|
+
_state.update { it.copy(unread = it.unread + 1) }
|
|
76
|
+
CometChatCalls.setChatButtonUnreadCount(_state.value.unread)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fun open() {
|
|
80
|
+
_state.update { it.copy(open = true, unread = 0) }
|
|
81
|
+
CometChatCalls.setChatButtonUnreadCount(0)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fun close() {
|
|
85
|
+
_state.update { it.copy(open = false) }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun onCleared() {
|
|
89
|
+
CometChat.removeMessageListener("in-call-chat-${_state.value.group?.guid}")
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Triggering from SDK event
|
|
97
|
+
|
|
98
|
+
In your `CometChatCallsEventsListener` impl:
|
|
99
|
+
|
|
100
|
+
```kotlin
|
|
101
|
+
override fun onChatButtonClicked() {
|
|
102
|
+
// Listener is on background thread — dispatch to UI
|
|
103
|
+
Handler(Looper.getMainLooper()).post {
|
|
104
|
+
inCallChatViewModel.open()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Anti-patterns
|
|
112
|
+
|
|
113
|
+
V5 sister rules apply, plus Compose-specific:
|
|
114
|
+
|
|
115
|
+
1. **`collectAsState()` instead of `collectAsStateWithLifecycle()`.** State updates while paused.
|
|
116
|
+
2. **No `Modifier.weight(1f)` on the message list.** Composer pushes off bottom (same flex-shrink trap).
|
|
117
|
+
3. **`ModalBottomSheet` without `skipPartiallyExpanded = false`.** Defaults to half-screen only; user can't drag to full.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Verification checklist
|
|
122
|
+
|
|
123
|
+
- [ ] InCallChatViewModel uses StateFlow + collectAsStateWithLifecycle
|
|
124
|
+
- [ ] Message list has `Modifier.weight(1f)`
|
|
125
|
+
- [ ] ModalBottomSheet `skipPartiallyExpanded = false`
|
|
126
|
+
- [ ] Listener cleanup in `onCleared`
|
|
127
|
+
- [ ] Real-device smoke: 2 phones in call, message → badge → tap → see message
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Pointers
|
|
132
|
+
|
|
133
|
+
- `cometchat-android-v5-calls/references/in-call-chat.md` — V5 sister (Kotlin Views patterns)
|
|
134
|
+
- `cometchat-android-v6-calls` SKILL.md
|
|
135
|
+
- `cometchat-android-v6-calls/references/raise-hand.md` — Compose pattern sibling
|
|
136
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/android/in-call-chat
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Raise hand on Android V6 (Compose + Kotlin Views)
|
|
2
|
+
|
|
3
|
+
V6 ships the same SDK API as V5 with two key delta: (1) Compose-first surface for new code, Kotlin Views still supported; (2) ViewModel + `collectAsStateWithLifecycle` is the canonical state-binding shape rather than manual `repeatOnLifecycle`.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://www.cometchat.com/docs/calls/android/raise-hand
|
|
6
|
+
**Read first:** `cometchat-android-v5-calls/references/raise-hand.md` — the SDK API + ViewModel pattern is shared; this reference covers V6's Compose layer.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## SDK API (same as V5)
|
|
11
|
+
|
|
12
|
+
```kotlin
|
|
13
|
+
import com.cometchat.calls.core.CometChatCalls
|
|
14
|
+
import com.cometchat.calls.listeners.CometChatCallsEventsListener
|
|
15
|
+
import com.cometchat.calls.model.Participant
|
|
16
|
+
|
|
17
|
+
CometChatCalls.raiseHand()
|
|
18
|
+
CometChatCalls.lowerHand()
|
|
19
|
+
|
|
20
|
+
val settings = SessionSettingsBuilder(context, callContainer)
|
|
21
|
+
.setSessionType(SessionType.VIDEO)
|
|
22
|
+
.hideRaiseHandButton(true)
|
|
23
|
+
.build()
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
ViewModel + `StateFlow` pattern is identical to V5 (cf. sister reference). The Compose-specific delta is the UI layer.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Compose toggle button
|
|
31
|
+
|
|
32
|
+
```kotlin
|
|
33
|
+
@Composable
|
|
34
|
+
fun RaiseHandButton(viewModel: RaiseHandViewModel = viewModel()) {
|
|
35
|
+
val state by viewModel.state.collectAsStateWithLifecycle()
|
|
36
|
+
val context = LocalContext.current
|
|
37
|
+
|
|
38
|
+
// Announce a11y on state change
|
|
39
|
+
LaunchedEffect(state.localRaised) {
|
|
40
|
+
val accessibilityManager = context.getSystemService(Context.ACCESSIBILITY_SERVICE)
|
|
41
|
+
as AccessibilityManager
|
|
42
|
+
if (accessibilityManager.isEnabled) {
|
|
43
|
+
val announcement = if (state.localRaised) "Hand raised" else "Hand lowered"
|
|
44
|
+
val event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT)
|
|
45
|
+
event.text.add(announcement)
|
|
46
|
+
accessibilityManager.sendAccessibilityEvent(event)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
IconButton(
|
|
51
|
+
onClick = { viewModel.toggle() },
|
|
52
|
+
modifier = Modifier
|
|
53
|
+
.semantics {
|
|
54
|
+
role = Role.Button
|
|
55
|
+
selected = state.localRaised
|
|
56
|
+
contentDescription = if (state.localRaised) "Lower hand" else "Raise hand"
|
|
57
|
+
}
|
|
58
|
+
.background(
|
|
59
|
+
color = if (state.localRaised) Color(0xFFFFD60A) else Color.White.copy(alpha = 0.2f),
|
|
60
|
+
shape = CircleShape,
|
|
61
|
+
)
|
|
62
|
+
.padding(12.dp),
|
|
63
|
+
) {
|
|
64
|
+
Icon(
|
|
65
|
+
imageVector = if (state.localRaised) Icons.Filled.PanTool else Icons.Outlined.PanTool,
|
|
66
|
+
contentDescription = null,
|
|
67
|
+
tint = if (state.localRaised) Color.Black else Color.White,
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`collectAsStateWithLifecycle()` (from `androidx.lifecycle.compose:lifecycle-viewmodel-compose`) is the replacement for V5's manual `repeatOnLifecycle` — it pauses collection automatically when the Composable's lifecycle drops below STARTED.
|
|
74
|
+
|
|
75
|
+
`semantics { ... }` is Compose's accessibility primitive — `role`, `selected`, `contentDescription` map to Android's TalkBack model.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Compose raised-hands sheet
|
|
80
|
+
|
|
81
|
+
```kotlin
|
|
82
|
+
@OptIn(ExperimentalMaterial3Api::class)
|
|
83
|
+
@Composable
|
|
84
|
+
fun RaisedHandsSheet(viewModel: RaiseHandViewModel = viewModel()) {
|
|
85
|
+
val state by viewModel.state.collectAsStateWithLifecycle()
|
|
86
|
+
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = false)
|
|
87
|
+
|
|
88
|
+
if (state.raised.isNotEmpty()) {
|
|
89
|
+
ModalBottomSheet(
|
|
90
|
+
onDismissRequest = { /* host control */ },
|
|
91
|
+
sheetState = sheetState,
|
|
92
|
+
) {
|
|
93
|
+
Column(modifier = Modifier.padding(16.dp)) {
|
|
94
|
+
Text(
|
|
95
|
+
text = "Raised hands (${state.raised.size})",
|
|
96
|
+
style = MaterialTheme.typography.titleMedium,
|
|
97
|
+
)
|
|
98
|
+
Spacer(modifier = Modifier.height(8.dp))
|
|
99
|
+
LazyColumn {
|
|
100
|
+
items(state.raised, key = { it.uid }) { p ->
|
|
101
|
+
ListItem(
|
|
102
|
+
leadingContent = { Text("✋", fontSize = 20.sp) },
|
|
103
|
+
headlineContent = { Text(p.name) },
|
|
104
|
+
supportingContent = {
|
|
105
|
+
Text(
|
|
106
|
+
"${(System.currentTimeMillis() - p.raisedAt) / 1000}s ago",
|
|
107
|
+
style = MaterialTheme.typography.bodySmall,
|
|
108
|
+
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
109
|
+
)
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`ModalBottomSheet` is Material 3 — the V6 default. `key = { it.uid }` on `LazyColumn.items` is critical (same as `trackBy` on the web/Angular side) — without it, every state change re-renders every item from scratch.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Wiring inside a CometChat call screen
|
|
125
|
+
|
|
126
|
+
Whether the project uses Compose or Kotlin Views for the call surface affects where the button + sheet land. V6 supports both surfaces (cf. `cometchat-android-v6-calls` SKILL.md).
|
|
127
|
+
|
|
128
|
+
**Compose surface:**
|
|
129
|
+
|
|
130
|
+
```kotlin
|
|
131
|
+
@Composable
|
|
132
|
+
fun CallScreen() {
|
|
133
|
+
Box(modifier = Modifier.fillMaxSize()) {
|
|
134
|
+
// CometChat call surface (composable from chatuikit-compose-android)
|
|
135
|
+
CometChatOngoingCall(modifier = Modifier.fillMaxSize())
|
|
136
|
+
|
|
137
|
+
// Custom raise-hand overlay
|
|
138
|
+
Box(modifier = Modifier
|
|
139
|
+
.align(Alignment.BottomEnd)
|
|
140
|
+
.padding(20.dp)
|
|
141
|
+
) {
|
|
142
|
+
RaiseHandButton()
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
RaisedHandsSheet()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Kotlin Views surface (XML layouts):** use the V5 `MaterialButton`-based pattern from the sister reference. The ViewModel + StateFlow plumbing is identical.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Anti-patterns
|
|
155
|
+
|
|
156
|
+
V5 sister reference rules apply, plus V6 Compose-specific:
|
|
157
|
+
|
|
158
|
+
1. **Forgetting `key = { it.uid }` on `LazyColumn.items`.** Without it, scrolling becomes jittery as items re-mount.
|
|
159
|
+
2. **Using `collectAsState()` instead of `collectAsStateWithLifecycle()`.** The former doesn't pause on lifecycle pause; burns CPU during background.
|
|
160
|
+
3. **`LaunchedEffect(state.localRaised)` firing the announcement on initial composition.** First render counts as a state change; if you don't want an announcement on screen open, gate on `if (state.localRaised) ... else ...` semantics with prior tracking.
|
|
161
|
+
4. **Mixing Compose state (`mutableStateOf`) with StateFlow.** Pick one source of truth — StateFlow with `collectAsStateWithLifecycle` is the V6 recommended path.
|
|
162
|
+
5. **Custom raise-hand button without the `semantics { selected = ... }`.** TalkBack reads "button" but doesn't announce selection state.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Verification checklist
|
|
167
|
+
|
|
168
|
+
- [ ] `RaiseHandViewModel` uses `StateFlow` for state
|
|
169
|
+
- [ ] Compose components use `collectAsStateWithLifecycle()` (not `collectAsState()`)
|
|
170
|
+
- [ ] `LazyColumn.items` uses `key = { it.uid }`
|
|
171
|
+
- [ ] Toggle has `semantics { role, selected, contentDescription }`
|
|
172
|
+
- [ ] Accessibility announcement on state change via AccessibilityManager
|
|
173
|
+
- [ ] `hideRaiseHandButton(true)` in SessionSettingsBuilder if custom UI
|
|
174
|
+
- [ ] Compose surface: button mounted via `Box.align` overlay, doesn't shift CometChat call view
|
|
175
|
+
- [ ] Real-device smoke: 3 Android phones, 2 raise → host's sheet shows both, sorted by time
|
|
176
|
+
- [ ] TalkBack smoke: announces "Hand raised" / "Hand lowered" on toggle
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Pointers
|
|
181
|
+
|
|
182
|
+
- `cometchat-android-v5-calls/references/raise-hand.md` — V5 sister reference (Kotlin Views + StateFlow)
|
|
183
|
+
- `cometchat-android-v6-calls` SKILL.md — V6 hard rules + Compose vs Views split
|
|
184
|
+
- `cometchat-android-v6-calls/references/group-calls.md` (when authored) — group call composition patterns
|
|
185
|
+
- `cometchat-a11y` — Android Compose semantics + TalkBack
|
|
186
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/android/raise-hand
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Ringing — call signaling with custom UI (Android V6 / Compose)
|
|
2
|
+
|
|
3
|
+
V5 has the canonical Android ringing reference. V6 keeps the same SDK API; only the UI layer changes (Compose vs XML Views).
|
|
4
|
+
|
|
5
|
+
**Read first:**
|
|
6
|
+
- `cometchat-android-v5-calls/references/ringing-integration.md` — canonical Android (full SDK flow)
|
|
7
|
+
- `cometchat-react-calls/references/ringing-integration.md` — architecture + hard rules
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## ViewModel
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
data class CallSignalingState(
|
|
15
|
+
val incoming: Call? = null,
|
|
16
|
+
val outgoing: Call? = null,
|
|
17
|
+
val activeSessionId: String? = null,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
class CallSignalingViewModel : ViewModel(), CometChat.CallListener {
|
|
21
|
+
private val _state = MutableStateFlow(CallSignalingState())
|
|
22
|
+
val state: StateFlow<CallSignalingState> = _state
|
|
23
|
+
|
|
24
|
+
init {
|
|
25
|
+
CometChat.addCallListener("app", this)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun onIncomingCallReceived(call: Call) {
|
|
29
|
+
Handler(Looper.getMainLooper()).post {
|
|
30
|
+
_state.update { it.copy(incoming = call) }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
override fun onOutgoingCallAccepted(call: Call) {
|
|
35
|
+
Handler(Looper.getMainLooper()).post {
|
|
36
|
+
_state.update { it.copy(outgoing = null, activeSessionId = call.sessionId) }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override fun onOutgoingCallRejected(call: Call) {
|
|
41
|
+
Handler(Looper.getMainLooper()).post {
|
|
42
|
+
_state.update { it.copy(outgoing = null) }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun onIncomingCallCancelled(call: Call) {
|
|
47
|
+
Handler(Looper.getMainLooper()).post {
|
|
48
|
+
_state.update { it.copy(incoming = null) }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun onCallEndedMessageReceived(call: Call) {
|
|
53
|
+
Handler(Looper.getMainLooper()).post {
|
|
54
|
+
_state.update { CallSignalingState() }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fun initiate(receiverUid: String, type: String) {
|
|
59
|
+
val call = Call(receiverUid, type, CometChatConstants.RECEIVER_TYPE_USER)
|
|
60
|
+
CometChat.initiateCall(call, object : CometChat.CallbackListener<Call>() {
|
|
61
|
+
override fun onSuccess(outgoing: Call) {
|
|
62
|
+
_state.update { it.copy(outgoing = outgoing) }
|
|
63
|
+
}
|
|
64
|
+
override fun onError(e: CometChatException) { Log.e("App", "Initiate failed", e) }
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fun accept(call: Call) {
|
|
69
|
+
CometChat.acceptCall(call.sessionId, object : CometChat.CallbackListener<Call>() {
|
|
70
|
+
override fun onSuccess(accepted: Call) {
|
|
71
|
+
_state.update { it.copy(incoming = null, activeSessionId = accepted.sessionId) }
|
|
72
|
+
}
|
|
73
|
+
override fun onError(e: CometChatException) {}
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fun reject(call: Call) {
|
|
78
|
+
CometChat.rejectCall(call.sessionId, CometChatConstants.CALL_STATUS_REJECTED, null)
|
|
79
|
+
_state.update { it.copy(incoming = null) }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
override fun onCleared() {
|
|
83
|
+
CometChat.removeCallListener("app")
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Compose incoming-call overlay
|
|
91
|
+
|
|
92
|
+
```kotlin
|
|
93
|
+
@Composable
|
|
94
|
+
fun CallSignalingOverlay(viewModel: CallSignalingViewModel = viewModel()) {
|
|
95
|
+
val state by viewModel.state.collectAsStateWithLifecycle()
|
|
96
|
+
|
|
97
|
+
state.incoming?.let { call ->
|
|
98
|
+
Dialog(onDismissRequest = { viewModel.reject(call) }) {
|
|
99
|
+
Surface(
|
|
100
|
+
modifier = Modifier.fillMaxSize(),
|
|
101
|
+
color = Color.Black.copy(alpha = 0.85f),
|
|
102
|
+
) {
|
|
103
|
+
Column(
|
|
104
|
+
modifier = Modifier.fillMaxSize(),
|
|
105
|
+
horizontalAlignment = Alignment.CenterHorizontally,
|
|
106
|
+
verticalArrangement = Arrangement.Center,
|
|
107
|
+
) {
|
|
108
|
+
AsyncImage(
|
|
109
|
+
model = call.callInitiator?.avatar,
|
|
110
|
+
contentDescription = null,
|
|
111
|
+
modifier = Modifier.size(120.dp).clip(CircleShape),
|
|
112
|
+
)
|
|
113
|
+
Spacer(Modifier.height(16.dp))
|
|
114
|
+
Text(
|
|
115
|
+
call.callInitiator?.name ?: "Unknown",
|
|
116
|
+
style = MaterialTheme.typography.titleLarge,
|
|
117
|
+
color = Color.White,
|
|
118
|
+
)
|
|
119
|
+
Text("Incoming ${call.type} call", color = Color.White.copy(alpha = 0.7f))
|
|
120
|
+
Spacer(Modifier.height(32.dp))
|
|
121
|
+
Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
|
|
122
|
+
FloatingActionButton(
|
|
123
|
+
onClick = { viewModel.reject(call) },
|
|
124
|
+
containerColor = Color.Red,
|
|
125
|
+
modifier = Modifier.semantics { contentDescription = "Decline call" },
|
|
126
|
+
) { Icon(Icons.Default.CallEnd, contentDescription = null, tint = Color.White) }
|
|
127
|
+
FloatingActionButton(
|
|
128
|
+
onClick = { viewModel.accept(call) },
|
|
129
|
+
containerColor = Color.Green,
|
|
130
|
+
modifier = Modifier.semantics { contentDescription = "Accept call" },
|
|
131
|
+
) { Icon(Icons.Default.Call, contentDescription = null, tint = Color.White) }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Mount above your nav graph in `MainActivity.setContent` so it surfaces over any screen.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Backgrounded ring — ConnectionService + FCM (mandatory)
|
|
145
|
+
|
|
146
|
+
The Compose overlay only fires when the app is foreground. For backgrounded/killed-app ring delivery, FCM data-message → ConnectionService → OS-level UI. See `cometchat-android-v6-calls/references/server-fcm-voip.md`.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Anti-patterns
|
|
151
|
+
|
|
152
|
+
V5 sister rules apply, plus V6-specific:
|
|
153
|
+
|
|
154
|
+
1. **`collectAsState()` instead of `collectAsStateWithLifecycle()`.** State updates while paused.
|
|
155
|
+
2. **Listener registered in a Composable.** Disposes on recomposition; use a ViewModel or Application-scoped class.
|
|
156
|
+
3. **Forgetting `Handler(Looper.getMainLooper()).post`.** SDK fires off main thread; StateFlow updates from background are fine but Compose recompositions need main.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Verification checklist
|
|
161
|
+
|
|
162
|
+
- [ ] ViewModel implements `CometChat.CallListener` and registers in init
|
|
163
|
+
- [ ] `onCleared` calls `removeCallListener`
|
|
164
|
+
- [ ] All state updates dispatched to main thread
|
|
165
|
+
- [ ] `Dialog`-based overlay mounts above nav graph in MainActivity
|
|
166
|
+
- [ ] FCM + ConnectionService handles backgrounded ring (V5 sister)
|
|
167
|
+
- [ ] Real-device smoke: foreground + backgrounded + killed-app ring
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Pointers
|
|
172
|
+
|
|
173
|
+
- `cometchat-android-v5-calls/references/ringing-integration.md` — canonical Android (V5 Views patterns)
|
|
174
|
+
- `cometchat-android-v6-calls/SKILL.md` — V6 architecture
|
|
175
|
+
- `cometchat-android-v6-calls/references/server-fcm-voip.md` — Compose IncomingCallActivity for backgrounded ring
|
|
176
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/android/ringing
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Server-side FCM HTTP v1 for Android V6 VoIP push
|
|
2
|
+
|
|
3
|
+
V5 has the canonical server template; V6 adds Compose-specific receiver patterns. The FCM payload + HTTP v1 API are unchanged from V5.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://firebase.google.com/docs/cloud-messaging/migrate-v1
|
|
6
|
+
**Read first:** `cometchat-android-v5-calls/references/server-fcm-voip.md` — full Node + Python templates, hard rules, webhook shape.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## V6 receiver-side delta
|
|
11
|
+
|
|
12
|
+
V5 patterns work on V6 (Compose calls bundle into chatuikit-{compose,kotlin}-android, but the FCM data-message reception is in a regular Service so Compose doesn't change anything there). One V6 nicety: surface the incoming-call UI through a Compose Activity that's launched in the foreground.
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
class VoipMessagingService : FirebaseMessagingService() {
|
|
16
|
+
override fun onMessageReceived(message: RemoteMessage) {
|
|
17
|
+
val data = message.data
|
|
18
|
+
if (data["type"] != "incoming_call") return
|
|
19
|
+
|
|
20
|
+
// V6: launch IncomingCallActivity (a Compose Activity) directly when the
|
|
21
|
+
// app is in the foreground; otherwise route through ConnectionService
|
|
22
|
+
// for the OS-level UI.
|
|
23
|
+
val isAppInForeground = ProcessLifecycleOwner.get().lifecycle.currentState
|
|
24
|
+
.isAtLeast(Lifecycle.State.STARTED)
|
|
25
|
+
|
|
26
|
+
if (isAppInForeground) {
|
|
27
|
+
val intent = Intent(this, IncomingCallActivity::class.java).apply {
|
|
28
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
|
29
|
+
putExtra("sessionId", data["sessionId"])
|
|
30
|
+
putExtra("callerName", data["callerName"])
|
|
31
|
+
putExtra("callType", data["callType"])
|
|
32
|
+
}
|
|
33
|
+
startActivity(intent)
|
|
34
|
+
} else {
|
|
35
|
+
// V5 ConnectionService path — see V5 sister doc
|
|
36
|
+
val telecom = getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
37
|
+
// ... addNewIncomingCall flow
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Compose IncomingCallActivity (V6 specific)
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
class IncomingCallActivity : ComponentActivity() {
|
|
49
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
50
|
+
super.onCreate(savedInstanceState)
|
|
51
|
+
|
|
52
|
+
// Allow showing over lock screen
|
|
53
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
54
|
+
setShowWhenLocked(true)
|
|
55
|
+
setTurnScreenOn(true)
|
|
56
|
+
val keyguard = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
|
|
57
|
+
keyguard.requestDismissKeyguard(this, null)
|
|
58
|
+
} else {
|
|
59
|
+
window.addFlags(
|
|
60
|
+
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
61
|
+
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
|
|
62
|
+
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
val sessionId = intent.getStringExtra("sessionId") ?: return finish()
|
|
67
|
+
val callerName = intent.getStringExtra("callerName") ?: ""
|
|
68
|
+
val callType = intent.getStringExtra("callType") ?: "audio"
|
|
69
|
+
|
|
70
|
+
setContent {
|
|
71
|
+
AppTheme {
|
|
72
|
+
IncomingCallScreen(
|
|
73
|
+
callerName = callerName,
|
|
74
|
+
callType = callType,
|
|
75
|
+
onAccept = {
|
|
76
|
+
// Hand off to the kit's call surface
|
|
77
|
+
val callIntent = Intent(this, ActiveCallActivity::class.java).apply {
|
|
78
|
+
putExtra("sessionId", sessionId)
|
|
79
|
+
}
|
|
80
|
+
startActivity(callIntent)
|
|
81
|
+
finish()
|
|
82
|
+
},
|
|
83
|
+
onReject = {
|
|
84
|
+
// Notify CometChat backend
|
|
85
|
+
CometChat.rejectCall(sessionId, ...)
|
|
86
|
+
finish()
|
|
87
|
+
},
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Key V6 deltas vs V5:
|
|
96
|
+
- `setShowWhenLocked(true)` instead of `FLAG_SHOW_WHEN_LOCKED` (V5 uses the deprecated flag)
|
|
97
|
+
- `setContent { ... }` for Compose UI vs XML layout
|
|
98
|
+
- Compose Activity transitions are smoother — no XML inflation lag
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Anti-patterns
|
|
103
|
+
|
|
104
|
+
V5 sister rules apply, plus V6-specific:
|
|
105
|
+
|
|
106
|
+
1. **Calling `setContent` before `setShowWhenLocked`.** UI flashes briefly before the keyguard layer applies.
|
|
107
|
+
2. **Forgetting `requestDismissKeyguard`.** Lock screen still shows behind your call UI.
|
|
108
|
+
3. **Mixing `IncomingCallActivity` (foreground path) and `ConnectionService` (background path).** Pick the right one based on app state — V6 still benefits from V5's ConnectionService path for true background.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Verification checklist
|
|
113
|
+
|
|
114
|
+
- [ ] V5 server template (Node/Python) — see V5 sister
|
|
115
|
+
- [ ] FCM data message lands at `VoipMessagingService.onMessageReceived` regardless of app state
|
|
116
|
+
- [ ] Foreground: `IncomingCallActivity` launches with show-when-locked
|
|
117
|
+
- [ ] Background/killed: ConnectionService path surfaces OS-level UI
|
|
118
|
+
- [ ] Real-device smoke: 3 cohorts (foreground, backgrounded, killed) all ring
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Pointers
|
|
123
|
+
|
|
124
|
+
- `cometchat-android-v5-calls/references/server-fcm-voip.md` — V5 sister (canonical server template)
|
|
125
|
+
- `cometchat-android-v6-calls/SKILL.md` — V6 architecture
|
|
126
|
+
- `cometchat-android-v6-calls/references/incoming-call-overlay.md` — Compose overlay patterns
|
|
127
|
+
- FCM HTTP v1: https://firebase.google.com/docs/cloud-messaging/migrate-v1
|