@cometchat/skills 4.4.2 → 5.0.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/.claude-plugin/marketplace.json +55 -0
- package/.claude-plugin/plugin.json +14 -0
- package/CHANGELOG.md +36 -0
- package/LICENSE +21 -0
- package/README.md +41 -163
- package/RULES.md +114 -0
- package/bin/cometchat-skills.mjs +1180 -0
- package/bin/legacy-skills.json +95 -0
- package/catalogs/android-v6.json +1646 -0
- package/catalogs/flutter-v6.json +651 -0
- package/catalogs/ios-v5.json +1383 -0
- package/catalogs/rn-calls-v5.json +134 -0
- package/catalogs/rn-calls-v5.symbols.txt +58 -0
- package/catalogs/rn-sdk-v4.json +672 -0
- package/catalogs/rn-v5.json +449 -0
- package/catalogs/rn-v5.symbols.txt +216 -0
- package/catalogs/sdk-android-v5.json +514 -0
- package/contracts.android-calls-v5.json +122 -0
- package/contracts.android-v6.json +135 -0
- package/contracts.angular-v5.json +694 -0
- package/contracts.flutter-calls-v5.json +77 -0
- package/contracts.flutter-v6.json +126 -0
- package/contracts.ios-calls-v5.json +67 -0
- package/contracts.ios-v5.json +436 -0
- package/contracts.json +82 -0
- package/contracts.rn-calls-v5.json +77 -0
- package/contracts.rn-v5.json +727 -0
- package/contracts.sdk-android-v5.json +15 -0
- package/contracts.web-calls-v5.json +45 -0
- package/features.android-calls-v5.json +246 -0
- package/features.android-v6.json +65 -0
- package/features.angular-v5.json +521 -0
- package/features.flutter-calls-v5.json +286 -0
- package/features.flutter-v6.json +484 -0
- package/features.ios-calls-v5.json +236 -0
- package/features.ios-v5.json +573 -0
- package/features.json +61 -0
- package/features.rn-calls-v5.json +187 -0
- package/features.rn-v5.json +614 -0
- package/features.sdk-android-v5.json +40 -0
- package/features.sdk-jsv4.json +24 -0
- package/features.web-calls-v5.json +108 -0
- package/package.json +151 -74
- package/peers.yaml +312 -0
- package/registry/README.md +31 -0
- package/registry/android-calls-v5.json +54 -0
- package/registry/android-v6.json +137 -0
- package/registry/angular-v5.json +114 -0
- package/registry/flutter-calls-v5.json +54 -0
- package/registry/flutter-v6.json +119 -0
- package/registry/ios-calls-v5.json +59 -0
- package/registry/ios-v5.json +97 -0
- package/registry/rn-calls-v5.json +59 -0
- package/registry/rn-v5.json +129 -0
- package/registry/sdk-android-v5.json +53 -0
- package/registry/sdk-jsv4.json +53 -0
- package/registry/web-calls-v5.json +54 -0
- package/registry/web-v7.json +99 -0
- package/skills/cometchat/SKILL.md +42 -2096
- package/skills/cometchat-android-v5-calls-sdk/SKILL.md +206 -0
- package/skills/cometchat-android-v5-calls-sdk/references/build-truth.md +63 -0
- package/skills/cometchat-android-v5-calls-sdk/references/docs-map.md +119 -0
- package/skills/cometchat-android-v5-calls-sdk/references/method-map.md +53 -0
- package/skills/cometchat-android-v5-calls-sdk/references/pitfalls.md +72 -0
- package/skills/cometchat-android-v5-calls-sdk/references/ringing.md +92 -0
- package/skills/cometchat-android-v5-calls-sdk/references/user-switch.md +90 -0
- package/skills/cometchat-android-v5-sdk/SKILL.md +127 -0
- package/skills/cometchat-android-v5-sdk/references/app-surface.md +88 -0
- package/skills/cometchat-android-v5-sdk/references/docs-map.md +91 -0
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +51 -137
- package/skills/cometchat-android-v6-calls/SKILL.md +128 -413
- package/skills/cometchat-android-v6-compose-components/SKILL.md +84 -194
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +66 -411
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +154 -237
- package/skills/cometchat-android-v6-core/SKILL.md +236 -672
- package/skills/cometchat-android-v6-core/references/anti-patterns.md +31 -0
- package/skills/cometchat-android-v6-core/references/component-props.md +168 -0
- package/skills/cometchat-android-v6-core/references/docs-map.md +153 -0
- package/skills/cometchat-android-v6-core/references/layout.md +112 -0
- package/skills/cometchat-android-v6-core/references/lifecycle.md +75 -0
- package/skills/cometchat-android-v6-core/references/setup-credentials.md +105 -0
- package/skills/cometchat-android-v6-core/references/troubleshooting.md +36 -0
- package/skills/cometchat-android-v6-events/SKILL.md +46 -184
- package/skills/cometchat-android-v6-extensions/SKILL.md +39 -179
- package/skills/cometchat-android-v6-features/SKILL.md +74 -143
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +75 -193
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +67 -419
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +77 -223
- package/skills/cometchat-android-v6-migration/SKILL.md +67 -378
- package/skills/cometchat-android-v6-production/SKILL.md +40 -179
- package/skills/cometchat-android-v6-push/SKILL.md +39 -289
- package/skills/cometchat-android-v6-testing/SKILL.md +50 -265
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +70 -254
- package/skills/cometchat-angular-v5-calls/SKILL.md +193 -0
- package/skills/cometchat-angular-v5-components/SKILL.md +131 -0
- package/skills/cometchat-angular-v5-components/references/catalog.md +111 -0
- package/skills/cometchat-angular-v5-components/references/host-composed.md +46 -0
- package/skills/cometchat-angular-v5-core/SKILL.md +300 -0
- package/skills/cometchat-angular-v5-core/references/anti-patterns.md +49 -0
- package/skills/cometchat-angular-v5-core/references/component-props.md +55 -0
- package/skills/cometchat-angular-v5-core/references/dependencies.md +66 -0
- package/skills/cometchat-angular-v5-core/references/docs-map.md +132 -0
- package/skills/cometchat-angular-v5-core/references/layout.md +64 -0
- package/skills/cometchat-angular-v5-core/references/lifecycle.md +202 -0
- package/skills/cometchat-angular-v5-core/references/setup-credentials.md +137 -0
- package/skills/cometchat-angular-v5-core/references/theming.md +70 -0
- package/skills/cometchat-angular-v5-core/references/troubleshooting.md +27 -0
- package/skills/cometchat-angular-v5-customization/SKILL.md +94 -0
- package/skills/cometchat-angular-v5-features/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-features/references/custom-messages.md +133 -0
- package/skills/cometchat-angular-v5-features/references/formatters.md +28 -0
- package/skills/cometchat-angular-v5-features/references/host-composed-extensions.md +85 -0
- package/skills/cometchat-angular-v5-migration/SKILL.md +40 -0
- package/skills/cometchat-angular-v5-migration/references/migration-guide.md +165 -0
- package/skills/cometchat-angular-v5-patterns/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-placement/SKILL.md +133 -0
- package/skills/cometchat-angular-v5-placement/references/combined-app.md +174 -0
- package/skills/cometchat-angular-v5-placement/references/core-surface.md +199 -0
- package/skills/cometchat-angular-v5-production/SKILL.md +101 -0
- package/skills/cometchat-angular-v5-push/SKILL.md +61 -0
- package/skills/cometchat-angular-v5-testing/SKILL.md +112 -0
- package/skills/cometchat-angular-v5-troubleshooting/SKILL.md +96 -0
- package/skills/cometchat-flutter-v5-sdk/SKILL.md +188 -0
- package/skills/cometchat-flutter-v5-sdk/references/doc-corrections.md +55 -0
- package/skills/cometchat-flutter-v5-sdk/references/docs-map.md +211 -0
- package/skills/cometchat-flutter-v5-sdk/references/platform-notes.md +48 -0
- package/skills/cometchat-flutter-v5-sdk/references/transcription.md +87 -0
- package/skills/cometchat-flutter-v6-calls/SKILL.md +75 -389
- package/skills/cometchat-flutter-v6-components/SKILL.md +88 -361
- package/skills/cometchat-flutter-v6-core/SKILL.md +154 -593
- package/skills/cometchat-flutter-v6-core/references/anti-patterns.md +55 -0
- package/skills/cometchat-flutter-v6-core/references/docs-map.md +143 -0
- package/skills/cometchat-flutter-v6-core/references/layout.md +45 -0
- package/skills/cometchat-flutter-v6-core/references/lifecycle.md +87 -0
- package/skills/cometchat-flutter-v6-core/references/setup-credentials.md +84 -0
- package/skills/cometchat-flutter-v6-core/references/troubleshooting.md +26 -0
- package/skills/cometchat-flutter-v6-customization/SKILL.md +70 -712
- package/skills/cometchat-flutter-v6-events/SKILL.md +79 -174
- package/skills/cometchat-flutter-v6-features/SKILL.md +55 -394
- package/skills/cometchat-flutter-v6-migration/SKILL.md +68 -367
- package/skills/cometchat-flutter-v6-migration/references/migration-guide.md +131 -0
- package/skills/cometchat-flutter-v6-patterns/SKILL.md +61 -0
- package/skills/cometchat-flutter-v6-placement/SKILL.md +94 -381
- package/skills/cometchat-flutter-v6-production/SKILL.md +58 -615
- package/skills/cometchat-flutter-v6-push/SKILL.md +46 -455
- package/skills/cometchat-flutter-v6-testing/SKILL.md +68 -299
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +54 -878
- package/skills/cometchat-ios-calls/SKILL.md +112 -563
- package/skills/cometchat-ios-components/SKILL.md +44 -834
- package/skills/cometchat-ios-core/SKILL.md +181 -1068
- package/skills/cometchat-ios-core/references/anti-patterns.md +80 -0
- package/skills/cometchat-ios-core/references/docs-map.md +123 -0
- package/skills/cometchat-ios-core/references/install.md +23 -0
- package/skills/cometchat-ios-core/references/layout.md +186 -0
- package/skills/cometchat-ios-core/references/setup-credentials.md +197 -0
- package/skills/cometchat-ios-core/references/swiftui.md +91 -0
- package/skills/cometchat-ios-core/references/troubleshooting.md +100 -0
- package/skills/cometchat-ios-customization/SKILL.md +33 -968
- package/skills/cometchat-ios-features/SKILL.md +29 -738
- package/skills/cometchat-ios-migration/SKILL.md +39 -0
- package/skills/cometchat-ios-placement/SKILL.md +51 -729
- package/skills/cometchat-ios-push/SKILL.md +24 -602
- package/skills/cometchat-ios-v5-sdk/SKILL.md +161 -0
- package/skills/cometchat-ios-v5-sdk/references/docs-map.md +326 -0
- package/skills/cometchat-js-v5-sdk/SKILL.md +95 -0
- package/skills/cometchat-js-v5-sdk/references/docs-map.md +114 -0
- package/skills/cometchat-onboarding/SKILL.md +89 -0
- package/skills/cometchat-onboarding/references/archetypes.md +51 -0
- package/skills/cometchat-onboarding/references/calling-first.md +77 -0
- package/skills/cometchat-onboarding/references/not-in-this-pack.md +8 -0
- package/skills/cometchat-onboarding/references/plan-artifact.md +133 -0
- package/skills/cometchat-onboarding/references/platforms.md +90 -0
- package/skills/cometchat-react-native-bare-patterns/SKILL.md +120 -0
- package/skills/cometchat-react-native-calls/SKILL.md +200 -0
- package/skills/cometchat-react-native-components/SKILL.md +142 -0
- package/skills/cometchat-react-native-core/SKILL.md +313 -0
- package/skills/cometchat-react-native-core/references/anti-patterns.md +79 -0
- package/skills/cometchat-react-native-core/references/component-props.md +105 -0
- package/skills/cometchat-react-native-core/references/dependencies.md +62 -0
- package/skills/cometchat-react-native-core/references/docs-map.md +126 -0
- package/skills/cometchat-react-native-core/references/layout.md +61 -0
- package/skills/cometchat-react-native-core/references/lifecycle.md +64 -0
- package/skills/cometchat-react-native-core/references/setup-credentials.md +39 -0
- package/skills/cometchat-react-native-customization/SKILL.md +198 -0
- package/skills/cometchat-react-native-expo-patterns/SKILL.md +116 -0
- package/skills/cometchat-react-native-features/SKILL.md +122 -0
- package/skills/cometchat-react-native-migration/SKILL.md +103 -0
- package/skills/cometchat-react-native-placement/SKILL.md +158 -0
- package/skills/cometchat-react-native-production/SKILL.md +78 -0
- package/skills/cometchat-react-native-push/SKILL.md +88 -0
- package/skills/cometchat-react-native-sdk/SKILL.md +126 -0
- package/skills/cometchat-react-native-sdk/references/method-map.md +239 -0
- package/skills/cometchat-react-native-sdk/references/page-map.md +96 -0
- package/skills/cometchat-react-native-testing/SKILL.md +94 -0
- package/skills/cometchat-react-native-troubleshooting/SKILL.md +116 -0
- package/skills/cometchat-react-native-v5-sdk/SKILL.md +150 -0
- package/skills/cometchat-react-native-v5-sdk/references/docs-map.md +127 -0
- package/skills/cometchat-react-native-v5-sdk/references/ringing-voip.md +369 -0
- package/skills/cometchat-react-v7-calls/SKILL.md +75 -0
- package/skills/cometchat-react-v7-components/SKILL.md +72 -0
- package/skills/cometchat-react-v7-core/SKILL.md +101 -0
- package/skills/cometchat-react-v7-core/references/anti-patterns.md +19 -0
- package/skills/cometchat-react-v7-core/references/component-props.md +82 -0
- package/skills/cometchat-react-v7-core/references/dependencies.md +23 -0
- package/skills/cometchat-react-v7-core/references/docs-map.md +117 -0
- package/skills/cometchat-react-v7-core/references/i18n-rtl-a11y.md +22 -0
- package/skills/cometchat-react-v7-core/references/layout.md +158 -0
- package/skills/cometchat-react-v7-core/references/lifecycle.md +74 -0
- package/skills/cometchat-react-v7-core/references/setup-credentials.md +58 -0
- package/skills/cometchat-react-v7-core/references/ssr.md +11 -0
- package/skills/cometchat-react-v7-core/references/theming.md +52 -0
- package/skills/cometchat-react-v7-core/references/troubleshooting.md +28 -0
- package/skills/cometchat-react-v7-customization/SKILL.md +84 -0
- package/skills/cometchat-react-v7-features/SKILL.md +92 -0
- package/skills/cometchat-react-v7-migration/SKILL.md +39 -0
- package/skills/cometchat-react-v7-migration/references/migration-guide.md +119 -0
- package/skills/cometchat-react-v7-patterns/SKILL.md +43 -0
- package/skills/cometchat-react-v7-placement/SKILL.md +106 -0
- package/skills/cometchat-react-v7-placement/references/recipes.md +354 -0
- package/skills/cometchat-react-v7-push/SKILL.md +53 -0
- package/test-suite/README.md +70 -0
- package/test-suite/catalogs/android-calls-v5.json +830 -0
- package/test-suite/catalogs/android-calls-v5.symbols.txt +499 -0
- package/test-suite/catalogs/android-v6.json +1646 -0
- package/test-suite/catalogs/android-v6.symbols.txt +298 -0
- package/test-suite/catalogs/angular-v5.json +7587 -0
- package/test-suite/catalogs/flutter-calls-v5.json +196 -0
- package/test-suite/catalogs/flutter-calls-v5.symbols.txt +59 -0
- package/test-suite/catalogs/flutter-v6.json +651 -0
- package/test-suite/catalogs/ios-calls-v5.json +158 -0
- package/test-suite/catalogs/ios-calls-v5.symbols.txt +70 -0
- package/test-suite/catalogs/ios-v5.json +1383 -0
- package/test-suite/catalogs/ios-v5.symbols.txt +699 -0
- package/test-suite/catalogs/rn-calls-v5.json +134 -0
- package/test-suite/catalogs/rn-sdk-v4.json +672 -0
- package/test-suite/catalogs/rn-v5.json +449 -0
- package/test-suite/catalogs/sdk-android-v5.json +514 -0
- package/test-suite/catalogs/sdk-android-v5.symbols.txt +254 -0
- package/test-suite/catalogs/sdk-jsv4.json +800 -0
- package/test-suite/catalogs/web-calls-v5.json +195 -0
- package/test-suite/catalogs/web-v7.json +1243 -0
- package/test-suite/scripts/build-registry.mjs +113 -0
- package/test-suite/scripts/catalog-refresh-dart.mjs +151 -0
- package/test-suite/scripts/catalog-refresh.mjs +100 -0
- package/test-suite/scripts/lint-skills.mjs +909 -0
- package/test-suite/scripts/measure-tokens.mjs +169 -0
- package/test-suite/scripts/typecheck-fences-dart.mjs +437 -0
- package/test-suite/scripts/typecheck-fences-kotlin.mjs +269 -0
- package/test-suite/scripts/typecheck-fences.mjs +206 -0
- package/test-suite/scripts/verify-catalog.mjs +242 -0
- package/test-suite/scripts/verify-contract-fences.mjs +94 -0
- package/test-suite/scripts/verify-detection.mjs +178 -0
- package/test-suite/scripts/verify-docs-base.mjs +91 -0
- package/test-suite/scripts/verify-family-agnostic.mjs +130 -0
- package/test-suite/scripts/verify-golden-path.mjs +138 -0
- package/test-suite/scripts/verify-oracle-components.mjs +133 -0
- package/test-suite/scripts/verify-template-bindings.mjs +148 -0
- package/test-suite/typecheck/angular-v5/package.json +21 -0
- package/test-suite/typecheck/angular-v5/tsconfig.json +21 -0
- package/test-suite/typecheck/flutter-v6/analysis_options.yaml +25 -0
- package/test-suite/typecheck/flutter-v6/pubspec.yaml +21 -0
- package/test-suite/typecheck/web-v7/package.json +18 -0
- package/test-suite/typecheck/web-v7/tsconfig.json +19 -0
- package/bin/install.js +0 -1003
- package/skills/.claude-plugin/marketplace.json +0 -86
- package/skills/cometchat/references/asking-questions.md +0 -48
- package/skills/cometchat-a11y/SKILL.md +0 -477
- package/skills/cometchat-android-v5/SKILL.md +0 -121
- package/skills/cometchat-android-v5-calls/SKILL.md +0 -429
- package/skills/cometchat-android-v5-calls/references/README.md +0 -53
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +0 -197
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +0 -91
- package/skills/cometchat-android-v5-calls/references/background-handling.md +0 -168
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +0 -131
- package/skills/cometchat-android-v5-calls/references/call-logs.md +0 -113
- package/skills/cometchat-android-v5-calls/references/call-session.md +0 -274
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +0 -150
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +0 -123
- package/skills/cometchat-android-v5-calls/references/group-calls.md +0 -205
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +0 -117
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +0 -134
- package/skills/cometchat-android-v5-calls/references/join-session.md +0 -120
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +0 -222
- package/skills/cometchat-android-v5-calls/references/participant-management.md +0 -110
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +0 -106
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +0 -248
- package/skills/cometchat-android-v5-calls/references/recording.md +0 -101
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +0 -152
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +0 -78
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +0 -215
- package/skills/cometchat-android-v5-calls/references/session-settings.md +0 -121
- package/skills/cometchat-android-v5-calls/references/setup.md +0 -137
- package/skills/cometchat-android-v5-calls/references/share-invite.md +0 -156
- package/skills/cometchat-android-v5-calls/references/video-controls.md +0 -87
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +0 -526
- package/skills/cometchat-android-v5-components/SKILL.md +0 -431
- package/skills/cometchat-android-v5-core/SKILL.md +0 -486
- package/skills/cometchat-android-v5-customization/SKILL.md +0 -469
- package/skills/cometchat-android-v5-extensions/SKILL.md +0 -127
- package/skills/cometchat-android-v5-features/SKILL.md +0 -131
- package/skills/cometchat-android-v5-placement/SKILL.md +0 -277
- package/skills/cometchat-android-v5-production/SKILL.md +0 -95
- package/skills/cometchat-android-v5-push/SKILL.md +0 -619
- package/skills/cometchat-android-v5-testing/SKILL.md +0 -188
- package/skills/cometchat-android-v5-theming/SKILL.md +0 -167
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +0 -74
- package/skills/cometchat-android-v6/SKILL.md +0 -108
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +0 -97
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +0 -87
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +0 -100
- package/skills/cometchat-android-v6-calls/references/call-session.md +0 -163
- package/skills/cometchat-android-v6-calls/references/device-management.md +0 -172
- package/skills/cometchat-android-v6-calls/references/group-calls.md +0 -191
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +0 -110
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +0 -141
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +0 -188
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +0 -176
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +0 -127
- package/skills/cometchat-android-v6-calls/references/share-invite.md +0 -105
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +0 -250
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +0 -233
- package/skills/cometchat-angular-calls/SKILL.md +0 -380
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +0 -96
- package/skills/cometchat-angular-calls/references/call-layouts.md +0 -123
- package/skills/cometchat-angular-calls/references/call-session.md +0 -167
- package/skills/cometchat-angular-calls/references/custom-ui.md +0 -239
- package/skills/cometchat-angular-calls/references/device-management.md +0 -154
- package/skills/cometchat-angular-calls/references/group-calls.md +0 -433
- package/skills/cometchat-angular-calls/references/idle-timeout.md +0 -161
- package/skills/cometchat-angular-calls/references/in-call-chat.md +0 -148
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +0 -205
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +0 -53
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +0 -184
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +0 -285
- package/skills/cometchat-angular-calls/references/raise-hand.md +0 -172
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +0 -260
- package/skills/cometchat-angular-calls/references/ringing-integration.md +0 -133
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +0 -100
- package/skills/cometchat-angular-calls/references/share-invite.md +0 -122
- package/skills/cometchat-angular-calls/references/virtual-background.md +0 -29
- package/skills/cometchat-angular-components/SKILL.md +0 -235
- package/skills/cometchat-angular-core/SKILL.md +0 -386
- package/skills/cometchat-angular-customization/SKILL.md +0 -616
- package/skills/cometchat-angular-features/SKILL.md +0 -329
- package/skills/cometchat-angular-patterns/SKILL.md +0 -256
- package/skills/cometchat-angular-placement/SKILL.md +0 -314
- package/skills/cometchat-angular-production/SKILL.md +0 -564
- package/skills/cometchat-angular-push/SKILL.md +0 -389
- package/skills/cometchat-angular-testing/SKILL.md +0 -605
- package/skills/cometchat-angular-theming/SKILL.md +0 -290
- package/skills/cometchat-angular-troubleshooting/SKILL.md +0 -364
- package/skills/cometchat-astro-patterns/SKILL.md +0 -708
- package/skills/cometchat-calls/SKILL.md +0 -364
- package/skills/cometchat-calls/references/use-case-broadcast.md +0 -199
- package/skills/cometchat-calls/references/use-case-marketplace.md +0 -157
- package/skills/cometchat-calls/references/use-case-support.md +0 -189
- package/skills/cometchat-calls/references/use-case-team.md +0 -180
- package/skills/cometchat-calls/references/use-case-telehealth.md +0 -153
- package/skills/cometchat-components/SKILL.md +0 -1142
- package/skills/cometchat-core/SKILL.md +0 -1048
- package/skills/cometchat-customization/SKILL.md +0 -580
- package/skills/cometchat-customization/references/component-catalog.md +0 -236
- package/skills/cometchat-features/SKILL.md +0 -861
- package/skills/cometchat-flutter-v5/SKILL.md +0 -173
- package/skills/cometchat-flutter-v5-calls/SKILL.md +0 -455
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +0 -193
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +0 -103
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +0 -285
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +0 -124
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +0 -181
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +0 -99
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +0 -135
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +0 -210
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +0 -255
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +0 -196
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +0 -101
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +0 -148
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +0 -118
- package/skills/cometchat-flutter-v5-core/SKILL.md +0 -239
- package/skills/cometchat-flutter-v5-customization/SKILL.md +0 -358
- package/skills/cometchat-flutter-v5-events/SKILL.md +0 -156
- package/skills/cometchat-flutter-v5-messages/SKILL.md +0 -259
- package/skills/cometchat-flutter-v5-production/SKILL.md +0 -216
- package/skills/cometchat-flutter-v5-push/SKILL.md +0 -285
- package/skills/cometchat-flutter-v5-testing/SKILL.md +0 -401
- package/skills/cometchat-flutter-v5-theming/SKILL.md +0 -161
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +0 -130
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +0 -152
- package/skills/cometchat-flutter-v6/SKILL.md +0 -446
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +0 -136
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +0 -89
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +0 -229
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +0 -190
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +0 -88
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +0 -125
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +0 -275
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +0 -171
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +0 -93
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +0 -102
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +0 -238
- package/skills/cometchat-flutter-v6-messages/SKILL.md +0 -384
- package/skills/cometchat-flutter-v6-theming/SKILL.md +0 -293
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +0 -224
- package/skills/cometchat-i18n/SKILL.md +0 -419
- package/skills/cometchat-ios/SKILL.md +0 -325
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +0 -181
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +0 -45
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +0 -188
- package/skills/cometchat-ios-calls/references/call-layouts.md +0 -76
- package/skills/cometchat-ios-calls/references/call-session.md +0 -218
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +0 -357
- package/skills/cometchat-ios-calls/references/custom-ui.md +0 -322
- package/skills/cometchat-ios-calls/references/device-management.md +0 -171
- package/skills/cometchat-ios-calls/references/group-calls.md +0 -359
- package/skills/cometchat-ios-calls/references/idle-timeout.md +0 -184
- package/skills/cometchat-ios-calls/references/in-call-chat.md +0 -179
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +0 -196
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +0 -246
- package/skills/cometchat-ios-calls/references/raise-hand.md +0 -26
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +0 -252
- package/skills/cometchat-ios-calls/references/ringing-integration.md +0 -143
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +0 -267
- package/skills/cometchat-ios-calls/references/share-invite.md +0 -148
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +0 -246
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +0 -166
- package/skills/cometchat-ios-production/SKILL.md +0 -738
- package/skills/cometchat-ios-testing/SKILL.md +0 -376
- package/skills/cometchat-ios-theming/SKILL.md +0 -667
- package/skills/cometchat-ios-troubleshooting/SKILL.md +0 -1003
- package/skills/cometchat-native-bare-patterns/SKILL.md +0 -550
- package/skills/cometchat-native-calls/SKILL.md +0 -671
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +0 -203
- package/skills/cometchat-native-calls/references/call-layouts.md +0 -125
- package/skills/cometchat-native-calls/references/call-session.md +0 -182
- package/skills/cometchat-native-calls/references/custom-ui.md +0 -254
- package/skills/cometchat-native-calls/references/device-management.md +0 -158
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +0 -179
- package/skills/cometchat-native-calls/references/group-calls.md +0 -296
- package/skills/cometchat-native-calls/references/idle-timeout.md +0 -128
- package/skills/cometchat-native-calls/references/in-call-chat.md +0 -145
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +0 -72
- package/skills/cometchat-native-calls/references/picture-in-picture.md +0 -276
- package/skills/cometchat-native-calls/references/raise-hand.md +0 -205
- package/skills/cometchat-native-calls/references/recording-screen-share.md +0 -169
- package/skills/cometchat-native-calls/references/ringing-integration.md +0 -118
- package/skills/cometchat-native-calls/references/server-push-bridge.md +0 -135
- package/skills/cometchat-native-calls/references/server-push-payloads.md +0 -193
- package/skills/cometchat-native-calls/references/share-invite.md +0 -146
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +0 -319
- package/skills/cometchat-native-components/SKILL.md +0 -628
- package/skills/cometchat-native-core/SKILL.md +0 -679
- package/skills/cometchat-native-customization/SKILL.md +0 -716
- package/skills/cometchat-native-expo-patterns/SKILL.md +0 -552
- package/skills/cometchat-native-features/SKILL.md +0 -638
- package/skills/cometchat-native-placement/SKILL.md +0 -509
- package/skills/cometchat-native-production/SKILL.md +0 -700
- package/skills/cometchat-native-push/SKILL.md +0 -594
- package/skills/cometchat-native-testing/SKILL.md +0 -582
- package/skills/cometchat-native-theming/SKILL.md +0 -681
- package/skills/cometchat-native-troubleshooting/SKILL.md +0 -501
- package/skills/cometchat-nextjs-patterns/SKILL.md +0 -899
- package/skills/cometchat-placement/SKILL.md +0 -1360
- package/skills/cometchat-production/SKILL.md +0 -1027
- package/skills/cometchat-react-calls/SKILL.md +0 -752
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +0 -146
- package/skills/cometchat-react-calls/references/call-layouts.md +0 -160
- package/skills/cometchat-react-calls/references/call-session.md +0 -235
- package/skills/cometchat-react-calls/references/custom-ui.md +0 -247
- package/skills/cometchat-react-calls/references/device-management.md +0 -210
- package/skills/cometchat-react-calls/references/group-calls.md +0 -257
- package/skills/cometchat-react-calls/references/idle-timeout.md +0 -188
- package/skills/cometchat-react-calls/references/in-call-chat.md +0 -212
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +0 -170
- package/skills/cometchat-react-calls/references/picture-in-picture.md +0 -245
- package/skills/cometchat-react-calls/references/raise-hand.md +0 -238
- package/skills/cometchat-react-calls/references/recording-screen-share.md +0 -144
- package/skills/cometchat-react-calls/references/ringing-integration.md +0 -255
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +0 -241
- package/skills/cometchat-react-calls/references/share-invite.md +0 -175
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +0 -216
- package/skills/cometchat-react-calls/references/virtual-background.md +0 -32
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +0 -165
- package/skills/cometchat-react-patterns/SKILL.md +0 -628
- package/skills/cometchat-react-push/SKILL.md +0 -634
- package/skills/cometchat-react-router-patterns/SKILL.md +0 -758
- package/skills/cometchat-react-testing/SKILL.md +0 -413
- package/skills/cometchat-theming/SKILL.md +0 -498
- package/skills/cometchat-troubleshooting/SKILL.md +0 -294
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Combined app — the grow target
|
|
2
|
+
|
|
3
|
+
Load this only when the user asks for the whole chat application: a tabbed selector (chats · users · groups · calls), the message pane, and details/thread panels.
|
|
4
|
+
|
|
5
|
+
Built on `core-surface.md` — the shell, `ChatStateService` wiring, teardown and responsive rules are identical. This adds the tab selector and the details panel.
|
|
6
|
+
|
|
7
|
+
> **Carry the whole core surface over, not just the shell.** `chat-experience`'s contract is a SUPERSET of `core-chat-surface`, so everything core-surface.md wires comes too — including **search** (`side-panel-or-column-search`: the toggle + `<cometchat-search>` in the list column) and the **thread panel**. Dropping search because this file does not repeat it is the easy mistake: this file shows only the DELTA.
|
|
8
|
+
|
|
9
|
+
## Tabs
|
|
10
|
+
```ts
|
|
11
|
+
type Tab = 'chats' | 'users' | 'groups' | 'calls';
|
|
12
|
+
|
|
13
|
+
export class ChatAppComponent {
|
|
14
|
+
readonly tab = signal<Tab>('chats');
|
|
15
|
+
readonly showDetails = signal(false);
|
|
16
|
+
|
|
17
|
+
// THREE handlers, not one. `(itemClick)` emits a different type per list:
|
|
18
|
+
// cometchat-conversations → Conversation (needs discriminating — see core-surface.md open())
|
|
19
|
+
// cometchat-users → User
|
|
20
|
+
// cometchat-groups → Group
|
|
21
|
+
// Routing users/groups through open() fails the build:
|
|
22
|
+
// TS2345: Argument of type 'User' is not assignable to parameter of type 'Conversation'.
|
|
23
|
+
openUser(user: CometChat.User) { this.chatState.setActiveUser(user); }
|
|
24
|
+
openGroup(group: CometChat.Group) { this.chatState.setActiveGroup(group); }
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
```html
|
|
28
|
+
<aside class="cc-side">
|
|
29
|
+
<nav class="cc-tabs">
|
|
30
|
+
<button (click)="tab.set('chats')" [class.active]="tab() === 'chats'">Chats</button>
|
|
31
|
+
<button (click)="tab.set('users')" [class.active]="tab() === 'users'">Users</button>
|
|
32
|
+
<button (click)="tab.set('groups')" [class.active]="tab() === 'groups'">Groups</button>
|
|
33
|
+
<button (click)="tab.set('calls')" [class.active]="tab() === 'calls'">Calls</button>
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<cometchat-conversations class="cc-fill" *ngIf="tab() === 'chats'" (itemClick)="open($event)"></cometchat-conversations>
|
|
37
|
+
<cometchat-users class="cc-fill" *ngIf="tab() === 'users'" (itemClick)="openUser($event)"></cometchat-users>
|
|
38
|
+
<cometchat-groups class="cc-fill" *ngIf="tab() === 'groups'" (itemClick)="openGroup($event)"></cometchat-groups>
|
|
39
|
+
<!-- Wire the calls tab too, or clicking a log dead-ends (RULES.md wire-or-hide). -->
|
|
40
|
+
<!-- ⚠️ GATE the call-logs surface on callsReady(): the kit's call-logs component NPEs
|
|
41
|
+
("Cannot read properties of null (reading 'CallLogRequestBuilder')") if it mounts before
|
|
42
|
+
the lazily-loaded Calls SDK populates CometChatUIKitCalls — its ngOnInit touches the builder
|
|
43
|
+
synchronously, and Retry does not recover. callsReady() awaits CometChatUIKit.callingReady
|
|
44
|
+
AND null-checks CometChatUIKitCalls (see cometchat-angular-v5-calls § Call history).
|
|
45
|
+
STOPGAP until the kit component awaits readiness itself. -->
|
|
46
|
+
<ng-container *ngIf="tab() === 'calls'">
|
|
47
|
+
<cometchat-call-logs class="cc-fill" *ngIf="callsReady(); else callsLoading" (itemClick)="openCallLog($event)"></cometchat-call-logs>
|
|
48
|
+
<ng-template #callsLoading><div class="cc-empty">Loading call history…</div></ng-template>
|
|
49
|
+
</ng-container>
|
|
50
|
+
</aside>
|
|
51
|
+
```
|
|
52
|
+
```css
|
|
53
|
+
/* .cc-side is already display:flex;flex-direction:column from core-surface.md. The tab
|
|
54
|
+
nav must not be squeezed, and whichever list is showing must be the ONE flex child
|
|
55
|
+
that fills the rest — see .cc-fill's comment in core-surface.md for why this is
|
|
56
|
+
required, not cosmetic: without it the list can't scroll, it gets clipped. */
|
|
57
|
+
.cc-tabs { flex-shrink: 0; }
|
|
58
|
+
```
|
|
59
|
+
The tab nav is yours — the kit ships no tab component. Every kit component used above must
|
|
60
|
+
be in this component's `imports: []`, or it renders **nothing, silently**:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { Component, inject, signal, computed } from '@angular/core';
|
|
64
|
+
import { CometChat } from '@cometchat/chat-sdk-javascript';
|
|
65
|
+
import { CommonModule } from '@angular/common';
|
|
66
|
+
import {
|
|
67
|
+
ChatStateService,
|
|
68
|
+
CometChatUIKit,
|
|
69
|
+
CometChatUIKitCalls,
|
|
70
|
+
CometChatConversationsComponent,
|
|
71
|
+
CometChatUsersComponent,
|
|
72
|
+
CometChatGroupsComponent,
|
|
73
|
+
CometChatCallLogsComponent,
|
|
74
|
+
CometChatGroupMembersComponent,
|
|
75
|
+
CometChatIncomingCallComponent,
|
|
76
|
+
} from '@cometchat/chat-uikit-angular';
|
|
77
|
+
|
|
78
|
+
@Component({
|
|
79
|
+
selector: 'app-chat-tabs',
|
|
80
|
+
standalone: true,
|
|
81
|
+
imports: [ // ← omit any of these and that tab renders blank
|
|
82
|
+
CommonModule,
|
|
83
|
+
CometChatConversationsComponent,
|
|
84
|
+
CometChatUsersComponent,
|
|
85
|
+
CometChatGroupsComponent,
|
|
86
|
+
CometChatCallLogsComponent,
|
|
87
|
+
// The Details panel and Incoming calls sections below use these two. Omitting them is
|
|
88
|
+
// NG8001 ("not a known element") plus NG8002 on [group] — this file's own #1 pitfall.
|
|
89
|
+
CometChatGroupMembersComponent,
|
|
90
|
+
CometChatIncomingCallComponent,
|
|
91
|
+
],
|
|
92
|
+
templateUrl: './chat-tabs.component.html',
|
|
93
|
+
})
|
|
94
|
+
export class ChatTabsComponent {
|
|
95
|
+
private readonly chatState = inject(ChatStateService);
|
|
96
|
+
readonly tab = signal<'chats' | 'users' | 'groups' | 'calls'>('chats');
|
|
97
|
+
|
|
98
|
+
// The template below binds these — declare them here or the build fails TS2339.
|
|
99
|
+
readonly activeUser = computed(() => this.chatState.activeUser() ?? undefined);
|
|
100
|
+
readonly activeGroup = computed(() => this.chatState.activeGroup() ?? undefined);
|
|
101
|
+
readonly activeConversation = computed(() => this.chatState.activeConversation() ?? undefined);
|
|
102
|
+
readonly showDetails = signal(false);
|
|
103
|
+
readonly threadParent = signal<any>(null);
|
|
104
|
+
|
|
105
|
+
// Gate the call-logs tab: <cometchat-call-logs> NPEs if it mounts before the lazily-loaded
|
|
106
|
+
// Calls SDK populates CometChatUIKitCalls. callingReady ALONE is not enough (it defaults to a
|
|
107
|
+
// pre-resolved Promise and the namespace can still be null) — also null-check CometChatUIKitCalls.
|
|
108
|
+
// STOPGAP (AUDIT-163, proven live).
|
|
109
|
+
readonly callsReady = signal(false);
|
|
110
|
+
constructor() {
|
|
111
|
+
CometChatUIKit.callingReady
|
|
112
|
+
.then(() => this.callsReady.set(!!CometChatUIKitCalls))
|
|
113
|
+
.catch(() => this.callsReady.set(false));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
open(conversation: CometChat.Conversation) { /* see core-surface.md open() */ }
|
|
117
|
+
openUser(user: CometChat.User) { this.chatState.setActiveUser(user); }
|
|
118
|
+
openGroup(group: CometChat.Group) { this.chatState.setActiveGroup(group); }
|
|
119
|
+
openCallLog(_log: any) { /* render your own detail pane — v5 ships none */ }
|
|
120
|
+
openDetails() { this.threadParent.set(null); this.showDetails.set(true); }
|
|
121
|
+
closeDetails() { this.showDetails.set(false); }
|
|
122
|
+
closeThread() { this.threadParent.set(null); }
|
|
123
|
+
openThread(m: any) { this.showDetails.set(false); this.threadParent.set(m); }
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Details panel
|
|
128
|
+
There is no single "details" component. Compose it: your own header plus `<cometchat-group-members>` for a group.
|
|
129
|
+
```html
|
|
130
|
+
<!-- The OPENER: the message header's own (itemClick) — clicking the avatar/name area.
|
|
131
|
+
Without it openDetails() is never called and the panel is unreachable. -->
|
|
132
|
+
<cometchat-message-header
|
|
133
|
+
[user]="activeUser()" [group]="activeGroup()"
|
|
134
|
+
(itemClick)="openDetails()">
|
|
135
|
+
</cometchat-message-header>
|
|
136
|
+
|
|
137
|
+
<aside class="cc-panel" *ngIf="showDetails()">
|
|
138
|
+
<header class="cc-panel-head">
|
|
139
|
+
<span>{{ activeGroup()?.getName() ?? activeUser()?.getName() }}</span>
|
|
140
|
+
<button (click)="showDetails.set(false)">Close</button>
|
|
141
|
+
</header>
|
|
142
|
+
<!-- `[group]` is REQUIRED (Group, not Group | undefined). `*ngIf="activeGroup()"` guards at
|
|
143
|
+
runtime but does NOT narrow the type: activeGroup() is a signal CALL, and Angular's
|
|
144
|
+
strict template checker cannot narrow a call expression across the binding. Written the
|
|
145
|
+
obvious way it fails the build with
|
|
146
|
+
TS2322: Type 'Group | undefined' is not assignable to type 'Group'.
|
|
147
|
+
Bind the `as` alias instead — that narrows, and the *ngIf still guards. -->
|
|
148
|
+
<ng-container *ngIf="activeGroup() as group">
|
|
149
|
+
<cometchat-group-members class="cc-fill" [group]="group"></cometchat-group-members>
|
|
150
|
+
</ng-container>
|
|
151
|
+
</aside>
|
|
152
|
+
```
|
|
153
|
+
Banned members and create-group have no component — see `cometchat-angular-v5-components/references/host-composed.md`.
|
|
154
|
+
|
|
155
|
+
## Incoming calls
|
|
156
|
+
Mount the listener **once at app root**, not inside the chat page, or it stops working the moment the user navigates away.
|
|
157
|
+
```html
|
|
158
|
+
<!-- app.component.html -->
|
|
159
|
+
<cometchat-incoming-call></cometchat-incoming-call>
|
|
160
|
+
<router-outlet></router-outlet>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Panel arbitration
|
|
164
|
+
Thread and details compete for the same column. Decide explicitly — opening one should close the other:
|
|
165
|
+
```ts
|
|
166
|
+
openThread(m: any) { this.showDetails.set(false); this.threadParent.set(m); }
|
|
167
|
+
openDetails() { this.threadParent.set(null); this.showDetails.set(true); }
|
|
168
|
+
// Call logs: v5 ships no detail component — render your own pane (cometchat-angular-v5-calls).
|
|
169
|
+
openCallLog(log: any) { this.selectedCallLog.set(log); }
|
|
170
|
+
```
|
|
171
|
+
Two panels open at once on a 1280px screen leaves the message pane unusably narrow.
|
|
172
|
+
|
|
173
|
+
## Verify
|
|
174
|
+
Every tab renders its list · switching tabs keeps the open conversation · details and thread never both open · incoming calls ring from any route · one pane on mobile.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Core surface — the default "add chat" layout
|
|
2
|
+
|
|
3
|
+
List + message pane, with thread and search as panels. Ships conversations, messages, threaded replies and search. This is the default for an unscoped request; grow to `combined-app.md` only when asked.
|
|
4
|
+
|
|
5
|
+
## Component
|
|
6
|
+
```ts
|
|
7
|
+
import { Component, inject, signal, computed, OnDestroy } from '@angular/core';
|
|
8
|
+
import { CommonModule } from '@angular/common';
|
|
9
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
10
|
+
import { CometChat } from '@cometchat/chat-sdk-javascript'; // Conversation / User / Group types
|
|
11
|
+
import {
|
|
12
|
+
ChatStateService, CometChatUIKitConstants,
|
|
13
|
+
CometChatConversationsComponent, CometChatMessageHeaderComponent,
|
|
14
|
+
CometChatMessageListComponent, CometChatMessageComposerComponent,
|
|
15
|
+
CometChatThreadHeaderComponent, CometChatErrorBoundaryComponent,
|
|
16
|
+
CometChatSearchComponent,
|
|
17
|
+
} from '@cometchat/chat-uikit-angular';
|
|
18
|
+
import type { SearchConversationClickEvent, SearchMessageClickEvent } from '@cometchat/chat-uikit-angular';
|
|
19
|
+
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'app-chat',
|
|
22
|
+
standalone: true,
|
|
23
|
+
imports: [
|
|
24
|
+
CommonModule,
|
|
25
|
+
CometChatErrorBoundaryComponent,
|
|
26
|
+
CometChatConversationsComponent,
|
|
27
|
+
CometChatMessageHeaderComponent,
|
|
28
|
+
CometChatMessageListComponent,
|
|
29
|
+
CometChatMessageComposerComponent,
|
|
30
|
+
CometChatThreadHeaderComponent,
|
|
31
|
+
CometChatSearchComponent,
|
|
32
|
+
],
|
|
33
|
+
templateUrl: './chat.component.html',
|
|
34
|
+
styleUrl: './chat.component.css',
|
|
35
|
+
})
|
|
36
|
+
export class ChatComponent implements OnDestroy {
|
|
37
|
+
private destroy$ = new Subject<void>();
|
|
38
|
+
readonly chatState = inject(ChatStateService);
|
|
39
|
+
|
|
40
|
+
// ChatStateService signals are `T | null`; the kit's inputs are OPTIONAL
|
|
41
|
+
// (`user?: CometChat.User`). Binding the raw signal fails Angular's strict
|
|
42
|
+
// template check with "Type 'User | null' is not assignable to 'User | undefined'".
|
|
43
|
+
// Normalise once here rather than writing `?? undefined` at every binding.
|
|
44
|
+
readonly activeUser = computed(() => this.chatState.activeUser() ?? undefined);
|
|
45
|
+
readonly activeGroup = computed(() => this.chatState.activeGroup() ?? undefined);
|
|
46
|
+
readonly activeConversation = computed(() => this.chatState.activeConversation() ?? undefined);
|
|
47
|
+
readonly hasActiveChat = computed(() => !!(this.activeUser() || this.activeGroup()));
|
|
48
|
+
|
|
49
|
+
readonly threadParent = signal<any>(null);
|
|
50
|
+
|
|
51
|
+
// `(itemClick)` emits a **Conversation**, never a User or a Group. Resolve the subject
|
|
52
|
+
// with getConversationWith() and branch on getConversationType() — a Conversation has
|
|
53
|
+
// no getGuid(), so sniffing for one silently sends every group into the user slot and
|
|
54
|
+
// the header/list/composer throw "getUid is not a function".
|
|
55
|
+
open(conversation: CometChat.Conversation) {
|
|
56
|
+
this.threadParent.set(null); // closing context when switching chats
|
|
57
|
+
const subject = conversation.getConversationWith();
|
|
58
|
+
if (conversation.getConversationType() === CometChatUIKitConstants.MessageReceiverType.group) {
|
|
59
|
+
this.chatState.setActiveGroup(subject as CometChat.Group);
|
|
60
|
+
} else {
|
|
61
|
+
this.chatState.setActiveUser(subject as CometChat.User);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
openThread(message: any) { this.threadParent.set(message); }
|
|
66
|
+
closeThread() { this.threadParent.set(null); }
|
|
67
|
+
back() { this.chatState.clearActiveChat(); }
|
|
68
|
+
|
|
69
|
+
// Search is part of the core surface, not an extra — `core-chat-surface` contracts
|
|
70
|
+
// both `global-conversation-search` and `in-chat-message-search-default`. It swaps
|
|
71
|
+
// INTO the side column rather than overlaying it, so nothing is covered up.
|
|
72
|
+
readonly searchOpen = signal(false);
|
|
73
|
+
openSearch() { this.searchOpen.set(true); }
|
|
74
|
+
closeSearch() { this.searchOpen.set(false); }
|
|
75
|
+
|
|
76
|
+
// A search hit must LAND somewhere — an unwired result list is a dead affordance.
|
|
77
|
+
// Both outputs emit a WRAPPER, not the domain object: `{ conversation, searchKeyword }`
|
|
78
|
+
// and `{ message, searchKeyword }`. Binding them as if they emitted a Conversation is a
|
|
79
|
+
// compile error, and `$event.conversation` is the field you actually want.
|
|
80
|
+
onSearchConversation(e: SearchConversationClickEvent) { this.open(e.conversation); this.closeSearch(); }
|
|
81
|
+
async onSearchMessage(e: SearchMessageClickEvent) {
|
|
82
|
+
// Reuse open() rather than hand-deriving the counterpart: the SDK converts a message
|
|
83
|
+
// back into its Conversation, which works for both 1:1 and group hits.
|
|
84
|
+
const conversation = await CometChat.CometChatHelper.getConversationFromMessage(e.message);
|
|
85
|
+
this.open(conversation);
|
|
86
|
+
this.closeSearch();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); }
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Template
|
|
94
|
+
```html
|
|
95
|
+
<cometchat-error-boundary>
|
|
96
|
+
<div class="cc-shell">
|
|
97
|
+
<aside class="cc-side">
|
|
98
|
+
<ng-container *ngIf="!searchOpen(); else searchPane">
|
|
99
|
+
<!-- Global search is ENTERED from the conversation list's OWN search bar, not a separate
|
|
100
|
+
button stacked above it: [showSearchBar] renders the built-in bar in the Conversations
|
|
101
|
+
header and (searchBarClick) opens the search pane. Do NOT hand-roll a search button. -->
|
|
102
|
+
<cometchat-conversations
|
|
103
|
+
class="cc-fill"
|
|
104
|
+
[showSearchBar]="true"
|
|
105
|
+
[activeConversation]="activeConversation()"
|
|
106
|
+
(searchBarClick)="openSearch()"
|
|
107
|
+
(itemClick)="open($event)">
|
|
108
|
+
</cometchat-conversations>
|
|
109
|
+
</ng-container>
|
|
110
|
+
<ng-template #searchPane>
|
|
111
|
+
<cometchat-search
|
|
112
|
+
class="cc-fill"
|
|
113
|
+
[uid]="activeUser()?.getUid()"
|
|
114
|
+
[guid]="activeGroup()?.getGuid()"
|
|
115
|
+
(conversationClick)="onSearchConversation($event)"
|
|
116
|
+
(messageClick)="onSearchMessage($event)"
|
|
117
|
+
(backClick)="closeSearch()">
|
|
118
|
+
</cometchat-search>
|
|
119
|
+
</ng-template>
|
|
120
|
+
</aside>
|
|
121
|
+
|
|
122
|
+
<main class="cc-main" *ngIf="hasActiveChat(); else empty">
|
|
123
|
+
<cometchat-message-header [user]="activeUser()" [group]="activeGroup()"></cometchat-message-header>
|
|
124
|
+
<cometchat-message-list
|
|
125
|
+
class="cc-fill"
|
|
126
|
+
[user]="activeUser()"
|
|
127
|
+
[group]="activeGroup()"
|
|
128
|
+
(threadRepliesClick)="openThread($event)">
|
|
129
|
+
</cometchat-message-list>
|
|
130
|
+
<cometchat-message-composer [user]="activeUser()" [group]="activeGroup()"></cometchat-message-composer>
|
|
131
|
+
</main>
|
|
132
|
+
<ng-template #empty><div class="cc-empty">Select a conversation</div></ng-template>
|
|
133
|
+
|
|
134
|
+
<aside class="cc-panel" *ngIf="threadParent()">
|
|
135
|
+
<cometchat-thread-header [parentMessage]="threadParent()" (closeClick)="closeThread()"></cometchat-thread-header>
|
|
136
|
+
<cometchat-message-list
|
|
137
|
+
class="cc-fill"
|
|
138
|
+
[user]="activeUser()"
|
|
139
|
+
[group]="activeGroup()"
|
|
140
|
+
[parentMessageId]="threadParent()?.getId()">
|
|
141
|
+
</cometchat-message-list>
|
|
142
|
+
<cometchat-message-composer
|
|
143
|
+
[user]="activeUser()"
|
|
144
|
+
[group]="activeGroup()"
|
|
145
|
+
[parentMessageId]="threadParent()?.getId()">
|
|
146
|
+
</cometchat-message-composer>
|
|
147
|
+
</aside>
|
|
148
|
+
</div>
|
|
149
|
+
</cometchat-error-boundary>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Styles
|
|
153
|
+
```css
|
|
154
|
+
/* <cometchat-error-boundary> ships NO :host rule (verified vs 5.1.0 — its styles array
|
|
155
|
+
only covers .cometchat-error-boundary__fallback). As the template ROOT it therefore
|
|
156
|
+
sits BETWEEN your sized ancestor and .cc-shell as an auto-height flex item, and a
|
|
157
|
+
`height: 100%` below it resolves against an indefinite height. Size it or the whole
|
|
158
|
+
surface balloons to content height and is clipped by the ancestor's overflow: hidden.
|
|
159
|
+
`height: 100dvh` on .cc-shell below happens to survive this (viewport-relative, so it
|
|
160
|
+
ignores the broken chain) — but the moment this recipe is ROUTED and .cc-shell becomes
|
|
161
|
+
`height: 100%` under a 100dvh outlet, the missing rule silently breaks every pane.
|
|
162
|
+
Field-proven: a real v4→v5 migration made exactly that (correct) routed adaptation and
|
|
163
|
+
measured 4120px of list inside an 827px viewport, unscrollable. */
|
|
164
|
+
cometchat-error-boundary { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; }
|
|
165
|
+
|
|
166
|
+
.cc-shell { display: flex; height: 100dvh; width: 100%; min-height: 0; overflow: hidden; }
|
|
167
|
+
.cc-side { width: 320px; min-height: 0; overflow: hidden; display: flex; flex-direction: column; border-right: 1px solid var(--cometchat-border-color-default); }
|
|
168
|
+
.cc-main { flex: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
|
|
169
|
+
.cc-panel { width: 360px; min-height: 0; overflow: hidden; display: flex; flex-direction: column; border-left: 1px solid var(--cometchat-border-color-default); }
|
|
170
|
+
|
|
171
|
+
/* The thread panel needs its own background so it reads as a distinct surface. Unlike
|
|
172
|
+
React — where the message list paints an OPAQUE token and a wrapper background never
|
|
173
|
+
shows (AUDIT-020/024) — Angular's `--cometchat-message-list-background` defaults to
|
|
174
|
+
**transparent** (verified in the shipped kit), so the wrapper's own background shows
|
|
175
|
+
through and is all you need. Do NOT copy React's `--cometchat-message-list-bg`
|
|
176
|
+
override: that token does not exist in this kit and the rule silently does nothing. */
|
|
177
|
+
.cc-panel { background: var(--cometchat-background-color-01); }
|
|
178
|
+
.cc-empty { flex: 1; display: grid; place-items: center; color: var(--cometchat-text-color-secondary); }
|
|
179
|
+
|
|
180
|
+
/* Every cometchat-conversations / -users / -groups / -call-logs / -search / -message-list
|
|
181
|
+
host resolves an internal `height: 100%` down to its OWN scroll region
|
|
182
|
+
(.cometchat-paginated-list { overflow-y: auto }) — it does not size itself. Left
|
|
183
|
+
unsized inside a flex column it defaults to min-height: auto (refuses to shrink below
|
|
184
|
+
its content), so the list balloons past the shell and gets hard-clipped by .cc-side's
|
|
185
|
+
overflow: hidden instead of scrolling. flex: 1 gives it the column's remaining space;
|
|
186
|
+
min-height: 0 lets it actually shrink to that space so overflow-y: auto can engage. */
|
|
187
|
+
.cc-fill { flex: 1; min-height: 0; overflow: hidden; }
|
|
188
|
+
|
|
189
|
+
@media (max-width: 768px) {
|
|
190
|
+
.cc-shell { flex-direction: column; }
|
|
191
|
+
.cc-side, .cc-panel { width: 100%; }
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
`html, body { height: 100%; margin: 0; }` in `styles.css` is required.
|
|
195
|
+
|
|
196
|
+
## Notes
|
|
197
|
+
- `[user]` and `[group]` are both bound and one is always undefined — the components accept that and it avoids branching the template twice. What they do **not** accept is the wrong kind in either slot: a `Group` in `[user]` throws `getUid is not a function`, which is why `open()` branches on `getConversationType()` rather than duck-typing the emitted object.
|
|
198
|
+
- Switching conversation clears the open thread; leaving it open would show a thread from the previous chat.
|
|
199
|
+
- Search is wired above, swapped into `.cc-side` behind a toggle — never overlaid. Binding `[uid]`/`[guid]` scopes it to the open chat (`in-chat-message-search-default`); with neither bound it searches everything (`global-conversation-search`). Both outputs are handled: an unwired result list is a dead affordance (`RULES.md` §12).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-angular-v5-production
|
|
3
|
+
description: "Ship a CometChat Angular integration safely — server-minted auth tokens instead of the Auth Key, environment file replacement, key hygiene, build config and a pre-launch checklist. Triggers: 'is this production ready', 'auth token instead of auth key angular', 'secure my cometchat setup', 'production build config', 'going live checklist'."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "@cometchat/chat-uikit-angular ^5 (5.1.0–5.2.0 verified); Angular 17-21"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "CometChat"
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat angular production v5 security auth-token hardening deployment"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-angular@5` (5.1.0–5.2.0 verified). The auth-token API is FETCHED from `{DOCS_BASE}/ui-kit/angular/methods.md` and `/integration.md` (base + paths in `cometchat-angular-v5-core/references/docs-map.md`). **The Angular UI Kit docs have no dedicated production-hardening page** — the checklist below is the pack's own guidance, derived from the credential rules in `RULES.md` §4 and what the kit ships; it is labelled as such rather than presented as documented. Treat that as a tracked DOCS GAP.
|
|
13
|
+
|
|
14
|
+
## Companion skills (read first)
|
|
15
|
+
- `cometchat-angular-v5-core` — `references/setup-credentials.md` covers the dev credential flow this replaces.
|
|
16
|
+
|
|
17
|
+
## Use this skill when
|
|
18
|
+
Moving off the development setup: going live, a security review, or "is this safe to ship".
|
|
19
|
+
|
|
20
|
+
## The one thing that matters
|
|
21
|
+
**Never ship the Auth Key in the browser bundle.**
|
|
22
|
+
|
|
23
|
+
The Auth Key can mint a session for **any user in your app**. Anything in `environment.ts` is compiled into JavaScript your users download, so an Auth Key there is public. Anyone can read it, log in as any UID, and read every conversation.
|
|
24
|
+
|
|
25
|
+
| | Development | Production |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| Login | `CometChatUIKit.login(uid)` | `CometChatUIKit.loginWithAuthToken(token)` |
|
|
28
|
+
| Auth Key | in `environment.ts` | **absent from the bundle** |
|
|
29
|
+
| Token source | n/a | your backend, per authenticated user |
|
|
30
|
+
| REST API Key | never client-side | server only |
|
|
31
|
+
|
|
32
|
+
## The production login flow
|
|
33
|
+
1. Your app authenticates the user (your own auth — CometChat is not an identity provider).
|
|
34
|
+
2. Your **server** calls CometChat's REST API with the **REST API Key** to mint an auth token for that user's UID.
|
|
35
|
+
3. The server returns the token to the browser over an authenticated request.
|
|
36
|
+
4. The app calls `loginWithAuthToken(token)`.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { inject } from '@angular/core';
|
|
40
|
+
import { HttpClient } from '@angular/common/http';
|
|
41
|
+
import { firstValueFrom } from 'rxjs';
|
|
42
|
+
import { CometChatUIKit } from '@cometchat/chat-uikit-angular';
|
|
43
|
+
|
|
44
|
+
const http = inject(HttpClient);
|
|
45
|
+
|
|
46
|
+
async function loginForCurrentUser() {
|
|
47
|
+
// your endpoint, protected by your own session
|
|
48
|
+
const { authToken } = await firstValueFrom(
|
|
49
|
+
http.get<{ authToken: string }>('/api/cometchat-token', { withCredentials: true }),
|
|
50
|
+
);
|
|
51
|
+
return CometChatUIKit.loginWithAuthToken(authToken);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The endpoint must derive the UID from the **server-side session**, never from a request parameter. Accepting `?uid=` lets any caller impersonate anyone.
|
|
56
|
+
|
|
57
|
+
## Environment files
|
|
58
|
+
```ts
|
|
59
|
+
// src/environments/environment.prod.ts
|
|
60
|
+
export const environment = {
|
|
61
|
+
production: true,
|
|
62
|
+
cometchat: { appId: 'APP_ID', region: 'REGION', authKey: '' }, // empty on purpose
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
App ID and Region are not secrets — they identify the app. The Auth Key is the secret, and it is empty here. Confirm `fileReplacements` is wired in the production configuration, then **grep the built bundle** for the key to be certain:
|
|
66
|
+
```bash
|
|
67
|
+
ng build --configuration production && grep -r "YOUR_AUTH_KEY" dist/ || echo "clean"
|
|
68
|
+
```
|
|
69
|
+
Run that in CI. A misconfigured `fileReplacements` fails silently and ships the dev file.
|
|
70
|
+
|
|
71
|
+
## Also before launch
|
|
72
|
+
- **Users are created server-side**, as part of your signup — not from the browser.
|
|
73
|
+
- **Log out properly**: `await CometChatUIKit.logout()`, then clear derived state and unregister push tokens (`cometchat-angular-v5-push`).
|
|
74
|
+
- **HTTPS everywhere** — required for calls (`getUserMedia`) and push.
|
|
75
|
+
- **Pin the kit** to an exact or `~` range so a minor cannot change component behaviour under you.
|
|
76
|
+
- **Set a log level**: `CometChatUIKit.setLogLevel(...)` — quieter in production.
|
|
77
|
+
- **Handle errors visibly**: every list EXCEPT `<cometchat-call-logs>` has an `(error)` output — verified vs 5.1.0, its only outputs are `itemClick` and `callButtonClicked`; it takes an `onError` INPUT callback instead, so `(error)` there binds a DOM listener that never fires. Conversations / Users / Groups / GroupMembers / MessageList all do have `(error)`; wrap the surface in `<cometchat-error-boundary>`.
|
|
78
|
+
- **Teardown** — `ngOnDestroy` on every subscription and listener; leaks are worse in a long-lived SPA.
|
|
79
|
+
- **Region must match** the dashboard app, in every configuration you build.
|
|
80
|
+
|
|
81
|
+
## Pre-launch checklist
|
|
82
|
+
- [ ] Auth Key absent from the production bundle (grep-verified in CI)
|
|
83
|
+
- [ ] `loginWithAuthToken` in production; UID from the server session
|
|
84
|
+
- [ ] REST API Key server-side only
|
|
85
|
+
- [ ] `fileReplacements` verified by building, not by reading config — note the production build FAILS on the default 1 MB budget until you raise it (`cometchat-angular-v5-core` Install); the grep below never runs otherwise
|
|
86
|
+
- [ ] HTTPS, valid certificate
|
|
87
|
+
- [ ] Logout clears session, state and push tokens
|
|
88
|
+
- [ ] Kit version pinned
|
|
89
|
+
- [ ] Error boundary + error outputs handled
|
|
90
|
+
- [ ] Dashboard extensions/AI enabled for the production app, not just dev
|
|
91
|
+
- [ ] Tested against the production app's credentials
|
|
92
|
+
|
|
93
|
+
## Common pitfalls
|
|
94
|
+
1. **Auth Key in the production bundle** — the critical one.
|
|
95
|
+
2. **Token endpoint trusting a client-supplied UID** — impersonation.
|
|
96
|
+
3. **`fileReplacements` assumed rather than verified** — dev config ships.
|
|
97
|
+
4. **Dashboard configured on the dev app only** — features silently missing in production.
|
|
98
|
+
5. **No logout teardown** — the next user inherits the session or the push token.
|
|
99
|
+
|
|
100
|
+
## Verify it works
|
|
101
|
+
Production build contains no Auth Key · login works via token · a tampered UID is rejected by the server · logout fully clears · calls and push work over HTTPS · features enabled on the production app.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-angular-v5-push
|
|
3
|
+
description: "Web push notifications for a CometChat Angular app — the Notifications product, FCM registration, the service worker, and token lifecycle. Docs-first: fetches the current notifications docs rather than baking a version-specific recipe. Triggers: 'add push notifications to my angular app', 'notify users when the app is closed', 'fcm setup', 'register push token'."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "@cometchat/chat-sdk-javascript ^4.1.13; Angular 17-21; requires the CometChat Notifications product"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "CometChat"
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat angular push v5 notifications fcm firebase service-worker"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Ground truth:** push is the CometChat **Notifications** product, not a UI Kit component — this skill is THIN and docs-first. Registration, payload shape and provider setup are FETCHED from the notifications docs via `cometchat-angular-v5-core/references/docs-map.md`; nothing about them is baked here. Live delivery cannot be auto-smoked — say so honestly rather than claiming verification.
|
|
13
|
+
|
|
14
|
+
## Companion skills (read first)
|
|
15
|
+
- `cometchat-angular-v5-core` — install, credentials, `init→login→render`. Assumed.
|
|
16
|
+
|
|
17
|
+
## Use this skill when
|
|
18
|
+
Delivering notifications while the app is closed or backgrounded.
|
|
19
|
+
|
|
20
|
+
## This skill is deliberately THIN — fetch the docs
|
|
21
|
+
Push spans a product (CometChat Notifications), a third-party provider (Firebase/FCM), a service worker, and browser permission rules. Every one of those changes independently, so a baked recipe goes stale fast.
|
|
22
|
+
|
|
23
|
+
**Start here:** `{SDK_DOCS_BASE}/notifications/overview.md`, then the web push integration page. Discover the current pages from the SDK index (`cometchat-angular-v5-core/references/docs-map.md`). Read before writing.
|
|
24
|
+
|
|
25
|
+
Angular's own docs cover push only inside `{DOCS_BASE}/ui-kit/angular/campaigns.md` — there is no dedicated Angular push page. That is a **known docs gap**; the product-level notifications docs are the source of truth.
|
|
26
|
+
|
|
27
|
+
## What is true regardless of version
|
|
28
|
+
**1. Push is a separate product.** It must be enabled and configured for the app in the dashboard, with provider credentials added there. No client code substitutes for that step.
|
|
29
|
+
|
|
30
|
+
**2. It is not the UI Kit.** Registration is SDK-level (`CometChatNotifications`), not a component. There is nothing to render.
|
|
31
|
+
|
|
32
|
+
**3. It needs a service worker at origin root.** `firebase-messaging-sw.js` must be served from `/`, not from a nested path. In Angular, add it to the app's `assets` in `angular.json` so it lands at the root of `dist/`, and confirm it is reachable at `/firebase-messaging-sw.js` after build — a 404 there is the single most common cause of "push does nothing".
|
|
33
|
+
|
|
34
|
+
**4. Permission requires a user gesture.** Call the permission request from a click. Browsers block it on load, and repeated silent blocks poison the origin.
|
|
35
|
+
|
|
36
|
+
**5. Token lifecycle is yours.** Register the FCM token after login; unregister on logout. Skipping the unregister sends the next user's notifications to the previous device.
|
|
37
|
+
|
|
38
|
+
**6. iOS Safari is PWA-only.** Web push on iOS requires the site installed to the home screen. Not a bug; set expectations.
|
|
39
|
+
|
|
40
|
+
## Angular specifics
|
|
41
|
+
- Register the token **after** `login()` resolves — see core's guarded-login pattern.
|
|
42
|
+
- Put registration in a service, not a component, so it does not re-run per route.
|
|
43
|
+
- If the app is SSR, guard all of it with `isPlatformBrowser` (`cometchat-angular-v5-patterns`).
|
|
44
|
+
- Unregister in the same place you call `CometChatUIKit.logout()`.
|
|
45
|
+
|
|
46
|
+
## Verify it works
|
|
47
|
+
Push cannot be verified in a headless browser: it needs a real device or browser profile, a live provider, and a backgrounded app. Expect to test by hand:
|
|
48
|
+
1. Load over HTTPS, grant permission from a click.
|
|
49
|
+
2. Confirm `/firebase-messaging-sw.js` returns 200.
|
|
50
|
+
3. Background the tab; send a message from a second account.
|
|
51
|
+
4. Notification arrives; tapping it focuses the app.
|
|
52
|
+
5. Log out; confirm notifications stop.
|
|
53
|
+
|
|
54
|
+
## Common pitfalls
|
|
55
|
+
1. **Notifications not enabled in the dashboard** — nothing works, no error.
|
|
56
|
+
2. **Service worker not at origin root** — silent failure.
|
|
57
|
+
3. **Permission requested on load** — blocked.
|
|
58
|
+
4. **Token registered before login** — no user to attach it to.
|
|
59
|
+
5. **No unregister on logout** — notifications follow the wrong user.
|
|
60
|
+
6. **Expecting iOS Safari to work outside a PWA.**
|
|
61
|
+
7. **Baking a recipe from memory** — fetch the docs; this area moves.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-angular-v5-testing
|
|
3
|
+
description: "Test an Angular app that embeds CometChat — what to mock vs exercise for real, TestBed setup for standalone kit components, avoiding real network in unit tests, and a two-account manual pass for realtime. Triggers: 'write tests for my chat', 'mock cometchat in jest', 'testbed cometchat', 'my tests hang', 'e2e test the chat'."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "@cometchat/chat-uikit-angular ^5 (5.1.0–5.2.0 verified); Angular 17-21; Jest / Karma / Vitest / Playwright"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "CometChat"
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat angular testing v5 testbed jest mock e2e playwright"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-angular@5` (5.1.0–5.2.0 verified). **The Angular UI Kit docs have no testing page** — the strategy here is the pack's own, and is labelled as such rather than presented as documented (a tracked DOCS GAP). Any kit symbol a test mocks must still exist in the `angular-v5` catalog, and its real shape comes from the component's `.md` twin via `cometchat-angular-v5-core/references/docs-map.md` — mock the API the kit actually exposes, never one invented to fit the test.
|
|
13
|
+
|
|
14
|
+
## Companion skills (read first)
|
|
15
|
+
- `cometchat-angular-v5-core` — init/login lifecycle, which is what makes tests hang if unmocked.
|
|
16
|
+
|
|
17
|
+
## Use this skill when
|
|
18
|
+
Writing tests for a component that renders kit components, or diagnosing tests that hang or fail on network.
|
|
19
|
+
|
|
20
|
+
## Decide what you are testing
|
|
21
|
+
| Testing | Approach |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| **Your** logic — selection, routing, state | Unit test with CometChat **mocked** |
|
|
24
|
+
| Kit component internals | Don't. It is a third-party dependency with its own tests |
|
|
25
|
+
| Your app's chat flow end-to-end | Playwright against a real dev app, two accounts |
|
|
26
|
+
| Realtime delivery | Manual, two browsers. Not automatable cheaply |
|
|
27
|
+
|
|
28
|
+
The common mistake is unit-testing kit internals. Test the seam: given a click, does your component set the right active chat?
|
|
29
|
+
|
|
30
|
+
## Mock CometChat in unit tests
|
|
31
|
+
Kit components open sockets and call the API at construction. Left real, tests hang, fail offline, and pollute a live app with test data.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// src/testing/cometchat.mock.ts
|
|
35
|
+
export const cometChatUIKitMock = {
|
|
36
|
+
initFromSettings: jest.fn().mockResolvedValue({}),
|
|
37
|
+
login: jest.fn().mockResolvedValue({ getUid: () => 'test-uid' }),
|
|
38
|
+
loginWithAuthToken: jest.fn().mockResolvedValue({ getUid: () => 'test-uid' }),
|
|
39
|
+
logout: jest.fn().mockResolvedValue(undefined),
|
|
40
|
+
getLoggedInUser: jest.fn().mockReturnValue({ getUid: () => 'test-uid' }),
|
|
41
|
+
isInitialized: jest.fn().mockReturnValue(true),
|
|
42
|
+
isCallingEnabled: jest.fn().mockReturnValue(false),
|
|
43
|
+
};
|
|
44
|
+
```
|
|
45
|
+
Point the module at it (Jest):
|
|
46
|
+
```ts
|
|
47
|
+
jest.mock('@cometchat/chat-uikit-angular', () => ({
|
|
48
|
+
...jest.requireActual('@cometchat/chat-uikit-angular'),
|
|
49
|
+
CometChatUIKit: cometChatUIKitMock,
|
|
50
|
+
}));
|
|
51
|
+
```
|
|
52
|
+
Keep `requireActual` so real component classes and `ChatStateService` still exist — you want your own wiring exercised, only the network faked.
|
|
53
|
+
|
|
54
|
+
## TestBed with standalone kit components
|
|
55
|
+
They are standalone, so they go in `imports`, exactly as in the app:
|
|
56
|
+
```ts
|
|
57
|
+
import { TestBed } from '@angular/core/testing';
|
|
58
|
+
import { ChatComponent } from './chat.component';
|
|
59
|
+
|
|
60
|
+
beforeEach(async () => {
|
|
61
|
+
await TestBed.configureTestingModule({ imports: [ChatComponent] }).compileComponents();
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
If a test fails with "is not a known element", the component under test is missing it from its own `imports` — a real bug the test just caught, not a test problem.
|
|
65
|
+
|
|
66
|
+
## Prefer testing ChatStateService over the DOM
|
|
67
|
+
Assert state, not kit markup. Kit internals change between releases; your wiring should not.
|
|
68
|
+
```ts
|
|
69
|
+
it('sets the active group when a group conversation is clicked', () => {
|
|
70
|
+
const fixture = TestBed.createComponent(ChatComponent);
|
|
71
|
+
const cmp = fixture.componentInstance;
|
|
72
|
+
|
|
73
|
+
// Mock the SHAPE the kit actually emits: a Conversation whose subject is a Group.
|
|
74
|
+
// Handing open() a bare { getGuid } instead lets a duck-typing bug pass the test
|
|
75
|
+
// while every group chat throws "getUid is not a function" in the browser.
|
|
76
|
+
const group = new CometChat.Group('g1', 'Team', CometChat.GROUP_TYPE.PUBLIC);
|
|
77
|
+
const conversation = { getConversationType: () => 'group', getConversationWith: () => group };
|
|
78
|
+
|
|
79
|
+
cmp.open(conversation as unknown as CometChat.Conversation);
|
|
80
|
+
expect(cmp.chatState.getActiveGroup()).toBeTruthy();
|
|
81
|
+
expect(cmp.chatState.getActiveUser()).toBeFalsy(); // the group must NOT land in the user slot
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
> **Mock the emitted shape, not the shape your code happens to check.** A mock built backwards from the implementation can only confirm the implementation — including its bugs. `(itemClick)` emits a `Conversation`; a test that passes anything else is not exercising the wiring.
|
|
85
|
+
|
|
86
|
+
## E2E with Playwright
|
|
87
|
+
Use a real dev app and two seeded users. What is worth asserting:
|
|
88
|
+
- The conversation list renders rows
|
|
89
|
+
- Clicking one opens header + list + composer
|
|
90
|
+
- Sending text makes it appear
|
|
91
|
+
- **No console errors** — the kit fails quietly, so this catches a lot
|
|
92
|
+
- **Nothing collapsed** — assert the message list's height is non-zero; a zero-height pane is the most common silent break
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const box = await page.locator('cometchat-message-list').boundingBox();
|
|
96
|
+
expect(box!.height).toBeGreaterThan(100);
|
|
97
|
+
```
|
|
98
|
+
Seed users and conversations through the REST API in setup, not the UI.
|
|
99
|
+
|
|
100
|
+
## Not worth automating
|
|
101
|
+
Realtime delivery between two clients, calls (needs media permissions and two peers), and push (needs a real device and a backgrounded app). Verify these manually and say so in the test plan rather than writing brittle automation.
|
|
102
|
+
|
|
103
|
+
## Common pitfalls
|
|
104
|
+
1. **Unmocked CometChat in unit tests** → hangs, flakes, offline failures.
|
|
105
|
+
2. **Mocking the whole module** without `requireActual` → your own wiring never runs.
|
|
106
|
+
3. **Asserting kit DOM internals** → breaks on every kit release.
|
|
107
|
+
4. **Tests against a production app** → real users, real data.
|
|
108
|
+
5. **No zero-height assertion in E2E** → the most common visual break goes unnoticed.
|
|
109
|
+
6. **No teardown in tests** → leaked listeners bleed across specs.
|
|
110
|
+
|
|
111
|
+
## Verify it works
|
|
112
|
+
Unit tests pass offline · no test opens a real socket · a missing `imports` entry fails a test · E2E asserts non-zero height and no console errors · manual checks are documented, not faked.
|