@cometchat/skills 4.4.2 → 5.0.1
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 +44 -0
- package/LICENSE +21 -0
- package/MIGRATING.md +187 -0
- package/README.md +52 -156
- package/RULES.md +125 -0
- package/bin/cometchat-skills.mjs +1280 -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 +156 -74
- package/peers.yaml +355 -0
- package/registry/README.md +31 -0
- package/registry/android-calls-v5.json +94 -0
- package/registry/android-v6.json +177 -0
- package/registry/angular-v5.json +154 -0
- package/registry/flutter-calls-v5.json +94 -0
- package/registry/flutter-v6.json +159 -0
- package/registry/ios-calls-v5.json +99 -0
- package/registry/ios-v5.json +152 -0
- package/registry/rn-calls-v5.json +99 -0
- package/registry/rn-v5.json +169 -0
- package/registry/sdk-android-v5.json +93 -0
- package/registry/sdk-jsv4.json +93 -0
- package/registry/web-calls-v5.json +94 -0
- package/registry/web-v7.json +154 -0
- package/skills/cometchat/SKILL.md +47 -2096
- package/skills/cometchat-a11y/SKILL.md +44 -472
- package/skills/cometchat-analytics/SKILL.md +61 -0
- 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 +41 -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 +102 -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-audit/SKILL.md +61 -0
- package/skills/cometchat-compliance/SKILL.md +63 -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 +132 -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 +59 -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-i18n/SKILL.md +35 -404
- 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 +182 -1068
- package/skills/cometchat-ios-core/references/anti-patterns.md +113 -0
- package/skills/cometchat-ios-core/references/docs-map.md +124 -0
- package/skills/cometchat-ios-core/references/install.md +23 -0
- package/skills/cometchat-ios-core/references/layout.md +219 -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-production/SKILL.md +67 -723
- package/skills/cometchat-ios-push/SKILL.md +24 -602
- package/skills/cometchat-ios-testing/SKILL.md +36 -355
- package/skills/cometchat-ios-troubleshooting/SKILL.md +31 -989
- 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-migrate-from-getstream/SKILL.md +65 -0
- package/skills/cometchat-migrate-from-getstream/references/concept-map.md +98 -0
- package/skills/cometchat-migrate-from-getstream/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-getstream/references/feature-map.md +108 -0
- package/skills/cometchat-migrate-from-getstream/references/inventory.md +82 -0
- package/skills/cometchat-migrate-from-getstream/references/native-build.md +9 -0
- package/skills/cometchat-migrate-from-getstream/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-sendbird/SKILL.md +64 -0
- package/skills/cometchat-migrate-from-sendbird/references/concept-map.md +99 -0
- package/skills/cometchat-migrate-from-sendbird/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-sendbird/references/feature-map.md +104 -0
- package/skills/cometchat-migrate-from-sendbird/references/inventory.md +86 -0
- package/skills/cometchat-migrate-from-sendbird/references/native-build.md +10 -0
- package/skills/cometchat-migrate-from-sendbird/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-twilio/SKILL.md +52 -0
- package/skills/cometchat-migrate-from-twilio/references/concept-map.md +49 -0
- package/skills/cometchat-migrate-from-twilio/references/data-migration.md +50 -0
- package/skills/cometchat-migrate-from-twilio/references/feature-map.md +27 -0
- package/skills/cometchat-migrate-from-twilio/references/inventory.md +53 -0
- package/skills/cometchat-migrate-from-twilio/references/report-template.md +52 -0
- package/skills/cometchat-moderation/SKILL.md +58 -0
- package/skills/cometchat-onboarding/SKILL.md +92 -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 +105 -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 +335 -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 +127 -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 +79 -0
- package/skills/cometchat-react-native-push/SKILL.md +88 -0
- package/skills/cometchat-react-native-sdk/SKILL.md +133 -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 +174 -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/layout.md +150 -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-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-production/SKILL.md +84 -0
- package/skills/cometchat-react-v7-push/SKILL.md +53 -0
- package/skills/cometchat-react-v7-testing/SKILL.md +60 -0
- package/skills/cometchat-react-v7-troubleshooting/SKILL.md +47 -0
- package/skills/cometchat-security/SKILL.md +80 -0
- package/skills/cometchat-self-host/SKILL.md +56 -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 +932 -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 +134 -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-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-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-theming/SKILL.md +0 -667
- 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
|
@@ -1,991 +1,56 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cometchat-ios-customization
|
|
3
|
-
description: "
|
|
3
|
+
description: "Brand and restyle the CometChat iOS UI Kit — theme colours, typography, per-component styles, localisation and sounds. Use for any 'make it match our brand' or 'change how it looks' request. Triggers: 'change cometchat colors ios', 'brand the chat ui swift', 'dark mode cometchat ios', 'custom font chat kit', 'localize cometchat ios'."
|
|
4
4
|
license: "MIT"
|
|
5
|
-
compatibility: "CometChatUIKitSwift
|
|
5
|
+
compatibility: "CometChatUIKitSwift 5.1.22 · iOS 15.1+"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "CometChat"
|
|
8
|
-
version: "
|
|
9
|
-
tags: "
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat ios theming customization branding swift v5"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Companion skills (read first)
|
|
13
|
+
- `cometchat-ios-core` owns setup and the golden path. This skill ADDS appearance. Exact token lists live in the docs — fetch via `cometchat-ios-core/references/docs-map.md` (`theme-introduction`, `color-resources`, `component-styling`, `message-bubble-styling`).
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Use this skill when
|
|
16
|
+
"match our brand", "change the accent colour", "use our font", "dark mode", "restyle the bubbles", "translate the UI".
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
## Three levels — go global first, per-component only when you must
|
|
19
|
+
**1. Global theme (start here).** `CometChatTheme` exposes **static** colour vars — `primaryColor`, `extendedPrimaryColor50…900`, `neutralColor50…`, `white`, `black`. Set them once at startup, before rendering, and every component follows. This is the branding lever: one primary colour usually does the whole job.
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## 1. Custom Views in CometChatConversations
|
|
21
|
-
|
|
22
|
-
### Custom List Item View
|
|
23
|
-
|
|
24
|
-
Replace the entire list item with a custom view:
|
|
25
|
-
|
|
26
|
-
```swift
|
|
27
|
-
let conversations = CometChatConversations()
|
|
28
|
-
|
|
29
|
-
conversations.set(listItemView: { (conversation: Conversation) -> UIView in
|
|
30
|
-
let customView = UIView()
|
|
31
|
-
customView.backgroundColor = .secondarySystemBackground
|
|
32
|
-
|
|
33
|
-
let nameLabel = UILabel()
|
|
34
|
-
nameLabel.font = .boldSystemFont(ofSize: 16)
|
|
35
|
-
|
|
36
|
-
if let user = conversation.conversationWith as? User {
|
|
37
|
-
nameLabel.text = user.name
|
|
38
|
-
} else if let group = conversation.conversationWith as? Group {
|
|
39
|
-
nameLabel.text = group.name
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
customView.addSubview(nameLabel)
|
|
43
|
-
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
44
|
-
NSLayoutConstraint.activate([
|
|
45
|
-
nameLabel.leadingAnchor.constraint(equalTo: customView.leadingAnchor, constant: 16),
|
|
46
|
-
nameLabel.centerYAnchor.constraint(equalTo: customView.centerYAnchor)
|
|
47
|
-
])
|
|
48
|
-
|
|
49
|
-
return customView
|
|
50
|
-
})
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Custom Leading View (Avatar Area)
|
|
54
|
-
|
|
55
|
-
```swift
|
|
56
|
-
conversations.set(leadingView: { (conversation: Conversation) -> UIView in
|
|
57
|
-
let avatarView = UIView()
|
|
58
|
-
avatarView.backgroundColor = .systemBlue
|
|
59
|
-
avatarView.layer.cornerRadius = 24
|
|
60
|
-
|
|
61
|
-
let initialsLabel = UILabel()
|
|
62
|
-
initialsLabel.textColor = .white
|
|
63
|
-
initialsLabel.font = .boldSystemFont(ofSize: 14)
|
|
64
|
-
initialsLabel.textAlignment = .center
|
|
65
|
-
|
|
66
|
-
if let user = conversation.conversationWith as? User {
|
|
67
|
-
initialsLabel.text = String(user.name?.prefix(2).uppercased() ?? "")
|
|
68
|
-
} else if let group = conversation.conversationWith as? Group {
|
|
69
|
-
initialsLabel.text = String(group.name?.prefix(2).uppercased() ?? "")
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
avatarView.addSubview(initialsLabel)
|
|
73
|
-
initialsLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
74
|
-
NSLayoutConstraint.activate([
|
|
75
|
-
initialsLabel.centerXAnchor.constraint(equalTo: avatarView.centerXAnchor),
|
|
76
|
-
initialsLabel.centerYAnchor.constraint(equalTo: avatarView.centerYAnchor),
|
|
77
|
-
avatarView.widthAnchor.constraint(equalToConstant: 48),
|
|
78
|
-
avatarView.heightAnchor.constraint(equalToConstant: 48)
|
|
79
|
-
])
|
|
80
|
-
|
|
81
|
-
return avatarView
|
|
82
|
-
})
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Custom Title View
|
|
86
|
-
|
|
87
|
-
```swift
|
|
88
|
-
conversations.set(titleView: { (conversation: Conversation) -> UIView in
|
|
89
|
-
let stackView = UIStackView()
|
|
90
|
-
stackView.axis = .horizontal
|
|
91
|
-
stackView.spacing = 8
|
|
92
|
-
|
|
93
|
-
let nameLabel = UILabel()
|
|
94
|
-
nameLabel.font = .boldSystemFont(ofSize: 16)
|
|
95
|
-
|
|
96
|
-
let verifiedBadge = UIImageView(image: UIImage(systemName: "checkmark.seal.fill"))
|
|
97
|
-
verifiedBadge.tintColor = .systemBlue
|
|
98
|
-
verifiedBadge.isHidden = true
|
|
99
|
-
|
|
100
|
-
if let user = conversation.conversationWith as? User {
|
|
101
|
-
nameLabel.text = user.name
|
|
102
|
-
// Show badge for verified users (custom metadata)
|
|
103
|
-
if let metadata = user.metadata, metadata["verified"] as? Bool == true {
|
|
104
|
-
verifiedBadge.isHidden = false
|
|
105
|
-
}
|
|
106
|
-
} else if let group = conversation.conversationWith as? Group {
|
|
107
|
-
nameLabel.text = group.name
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
stackView.addArrangedSubview(nameLabel)
|
|
111
|
-
stackView.addArrangedSubview(verifiedBadge)
|
|
112
|
-
|
|
113
|
-
return stackView
|
|
114
|
-
})
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Custom Subtitle View
|
|
118
|
-
|
|
119
|
-
```swift
|
|
120
|
-
conversations.set(subtitleView: { (conversation: Conversation) -> UIView in
|
|
121
|
-
let label = UILabel()
|
|
122
|
-
label.font = .systemFont(ofSize: 14)
|
|
123
|
-
label.textColor = .secondaryLabel
|
|
124
|
-
|
|
125
|
-
if let lastMessage = conversation.lastMessage as? TextMessage {
|
|
126
|
-
label.text = lastMessage.text
|
|
127
|
-
} else if let lastMessage = conversation.lastMessage as? MediaMessage {
|
|
128
|
-
switch lastMessage.messageType {
|
|
129
|
-
case .image:
|
|
130
|
-
label.text = "📷 Photo"
|
|
131
|
-
case .video:
|
|
132
|
-
label.text = "🎥 Video"
|
|
133
|
-
case .audio:
|
|
134
|
-
label.text = "🎵 Audio"
|
|
135
|
-
case .file:
|
|
136
|
-
label.text = "📎 File"
|
|
137
|
-
default:
|
|
138
|
-
label.text = "Attachment"
|
|
139
|
-
}
|
|
140
|
-
} else {
|
|
141
|
-
label.text = "No messages yet"
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return label
|
|
145
|
-
})
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Custom Tail View
|
|
149
|
-
|
|
150
|
-
```swift
|
|
151
|
-
conversations.set(trailView: { (conversation: Conversation) -> UIView in
|
|
152
|
-
let stackView = UIStackView()
|
|
153
|
-
stackView.axis = .vertical
|
|
154
|
-
stackView.alignment = .trailing
|
|
155
|
-
stackView.spacing = 4
|
|
156
|
-
|
|
157
|
-
// Time label
|
|
158
|
-
let timeLabel = UILabel()
|
|
159
|
-
timeLabel.font = .systemFont(ofSize: 12)
|
|
160
|
-
timeLabel.textColor = .tertiaryLabel
|
|
161
|
-
|
|
162
|
-
if let timestamp = conversation.lastMessage?.sentAt {
|
|
163
|
-
let date = Date(timeIntervalSince1970: TimeInterval(timestamp))
|
|
164
|
-
let formatter = DateFormatter()
|
|
165
|
-
formatter.dateFormat = "h:mm a"
|
|
166
|
-
timeLabel.text = formatter.string(from: date)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Unread badge
|
|
170
|
-
let badge = UILabel()
|
|
171
|
-
badge.font = .boldSystemFont(ofSize: 12)
|
|
172
|
-
badge.textColor = .white
|
|
173
|
-
badge.backgroundColor = .systemBlue
|
|
174
|
-
badge.textAlignment = .center
|
|
175
|
-
badge.layer.cornerRadius = 10
|
|
176
|
-
badge.clipsToBounds = true
|
|
177
|
-
|
|
178
|
-
let unreadCount = conversation.unreadMessageCount
|
|
179
|
-
badge.isHidden = unreadCount == 0
|
|
180
|
-
badge.text = unreadCount > 99 ? "99+" : "\(unreadCount)"
|
|
181
|
-
|
|
182
|
-
stackView.addArrangedSubview(timeLabel)
|
|
183
|
-
stackView.addArrangedSubview(badge)
|
|
184
|
-
|
|
185
|
-
NSLayoutConstraint.activate([
|
|
186
|
-
badge.widthAnchor.constraint(greaterThanOrEqualToConstant: 20),
|
|
187
|
-
badge.heightAnchor.constraint(equalToConstant: 20)
|
|
188
|
-
])
|
|
189
|
-
|
|
190
|
-
return stackView
|
|
191
|
-
})
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 2. Custom Swipe Actions
|
|
197
|
-
|
|
198
|
-
### Custom Options
|
|
199
|
-
|
|
200
|
-
```swift
|
|
201
|
-
conversations.set(options: { (conversation: Conversation?) -> [CometChatConversationOption] in
|
|
202
|
-
guard let conversation = conversation else { return [] }
|
|
203
|
-
var options: [CometChatConversationOption] = []
|
|
204
|
-
|
|
205
|
-
// CometChatConversationOption.init takes NO `id`; the click handler is the
|
|
206
|
-
// `onClick` initializer parameter (not a settable property) and its closure is
|
|
207
|
-
// (User?, Int, CometChatConversationOption, UIViewController?) -> Void.
|
|
208
|
-
// Pin conversation
|
|
209
|
-
let pinOption = CometChatConversationOption(
|
|
210
|
-
title: "Pin",
|
|
211
|
-
titleColor: nil,
|
|
212
|
-
icon: UIImage(systemName: "pin.fill"),
|
|
213
|
-
titleFont: nil,
|
|
214
|
-
iconTint: .white,
|
|
215
|
-
backgroundColor: .systemYellow,
|
|
216
|
-
onClick: { user, index, option, controller in
|
|
217
|
-
print("Pin conversation")
|
|
218
|
-
}
|
|
219
|
-
)
|
|
220
|
-
options.append(pinOption)
|
|
221
|
-
|
|
222
|
-
// Mute conversation
|
|
223
|
-
let muteOption = CometChatConversationOption(
|
|
224
|
-
title: "Mute",
|
|
225
|
-
titleColor: nil,
|
|
226
|
-
icon: UIImage(systemName: "bell.slash.fill"),
|
|
227
|
-
titleFont: nil,
|
|
228
|
-
iconTint: .white,
|
|
229
|
-
backgroundColor: .systemGray,
|
|
230
|
-
onClick: { user, index, option, controller in
|
|
231
|
-
print("Mute conversation")
|
|
232
|
-
}
|
|
233
|
-
)
|
|
234
|
-
options.append(muteOption)
|
|
235
|
-
|
|
236
|
-
// Delete conversation
|
|
237
|
-
let deleteOption = CometChatConversationOption(
|
|
238
|
-
title: "Delete",
|
|
239
|
-
titleColor: nil,
|
|
240
|
-
icon: UIImage(systemName: "trash.fill"),
|
|
241
|
-
titleFont: nil,
|
|
242
|
-
iconTint: .white,
|
|
243
|
-
backgroundColor: .systemRed,
|
|
244
|
-
onClick: { user, index, option, controller in
|
|
245
|
-
print("Delete conversation")
|
|
246
|
-
}
|
|
247
|
-
)
|
|
248
|
-
options.append(deleteOption)
|
|
249
|
-
|
|
250
|
-
return options
|
|
251
|
-
})
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Add Options (Keep Default + Add Custom)
|
|
255
|
-
|
|
256
|
-
```swift
|
|
257
|
-
conversations.add(options: { (conversation: Conversation?) -> [CometChatConversationOption] in
|
|
258
|
-
let archiveOption = CometChatConversationOption(
|
|
259
|
-
title: "Archive",
|
|
260
|
-
titleColor: nil,
|
|
261
|
-
icon: UIImage(systemName: "archivebox.fill"),
|
|
262
|
-
titleFont: nil,
|
|
263
|
-
iconTint: .white,
|
|
264
|
-
backgroundColor: .systemPurple,
|
|
265
|
-
onClick: { user, index, option, controller in
|
|
266
|
-
print("Archive conversation")
|
|
267
|
-
}
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
return [archiveOption]
|
|
271
|
-
})
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## 3. Custom Message Templates
|
|
277
|
-
|
|
278
|
-
### Creating a Custom Message Template
|
|
279
|
-
|
|
280
|
-
> ⚠️ **`CometChatMessageTemplate` is a `struct` with ONE memberwise initializer** — there is NO `CometChatMessageTemplate(type:category:)` convenience init, and the label order is **`category` first, then `type`**. The init requires ALL of these labels: `category:type:contentView:bubbleView:headerView:footerView:bottomView:options:` (the trailing `statusInfoView:` / `replyView:` default to `nil`). Pass `nil` for any view closure you don't need — you cannot omit the label. Verified: `CometChatMessageTemplate.swift:25-47`.
|
|
281
|
-
|
|
282
|
-
```swift
|
|
283
|
-
let messageList = CometChatMessageList()
|
|
284
|
-
|
|
285
|
-
// Get default templates — the argument is required (pass nil for defaults).
|
|
286
|
-
// Starting from this list (not []) keeps every built-in bubble.
|
|
287
|
-
// CometChatUIKit.getDataSource() → CometChatUIKit.swift:287; getAllMessageTemplates(additionalConfiguration:) → DataSource.swift:63
|
|
288
|
-
var templates = CometChatUIKit.getDataSource().getAllMessageTemplates(additionalConfiguration: nil)
|
|
289
|
-
|
|
290
|
-
// Create custom template for a specific message type.
|
|
291
|
-
// ALL labels below are required by the only initializer (CometChatMessageTemplate.swift:25).
|
|
292
|
-
// `category` comes BEFORE `type`. Each view closure is (BaseMessage?, MessageBubbleAlignment, UIViewController?) -> UIView?.
|
|
293
|
-
let customTemplate = CometChatMessageTemplate(
|
|
294
|
-
category: "custom",
|
|
295
|
-
type: "custom_poll",
|
|
296
|
-
|
|
297
|
-
// Custom content view — the inner bubble content
|
|
298
|
-
contentView: { message, alignment, controller in
|
|
299
|
-
guard let customMessage = message as? CustomMessage,
|
|
300
|
-
let data = customMessage.customData else {
|
|
301
|
-
return UIView()
|
|
302
|
-
}
|
|
303
|
-
let pollView = PollBubbleView()
|
|
304
|
-
pollView.configure(with: data)
|
|
305
|
-
return pollView
|
|
306
|
-
},
|
|
307
|
-
|
|
308
|
-
// Custom bubble view (wraps content). alignment is MessageBubbleAlignment (.left/.right/.center — UIKitConstants.swift:85).
|
|
309
|
-
bubbleView: { message, alignment, controller in
|
|
310
|
-
let bubble = UIView()
|
|
311
|
-
bubble.backgroundColor = alignment == .right
|
|
312
|
-
? CometChatTheme.primaryColor.withAlphaComponent(0.1)
|
|
313
|
-
: UIColor.secondarySystemBackground
|
|
314
|
-
bubble.layer.cornerRadius = 12
|
|
315
|
-
return bubble
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
// Custom header view (above the bubble)
|
|
319
|
-
headerView: { message, alignment, controller in
|
|
320
|
-
let label = UILabel()
|
|
321
|
-
label.text = "📊 Poll"
|
|
322
|
-
label.font = .boldSystemFont(ofSize: 12)
|
|
323
|
-
label.textColor = .secondaryLabel
|
|
324
|
-
return label
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
// Custom footer view (below the bubble)
|
|
328
|
-
footerView: { message, alignment, controller in
|
|
329
|
-
let label = UILabel()
|
|
330
|
-
label.text = "Tap to vote"
|
|
331
|
-
label.font = .systemFont(ofSize: 11)
|
|
332
|
-
label.textColor = .tertiaryLabel
|
|
333
|
-
return label
|
|
334
|
-
},
|
|
335
|
-
|
|
336
|
-
// bottomView — pass nil if unused (label still required)
|
|
337
|
-
bottomView: nil,
|
|
338
|
-
|
|
339
|
-
// Custom options (long press menu). Closure is (BaseMessage?, Group?, UIViewController?) -> [CometChatMessageOption]?
|
|
340
|
-
options: { message, group, controller in
|
|
341
|
-
let viewResultsOption = CometChatMessageOption(
|
|
342
|
-
id: "view_results",
|
|
343
|
-
title: "View Results",
|
|
344
|
-
icon: UIImage(systemName: "chart.bar.fill"),
|
|
345
|
-
onItemClick: { message in
|
|
346
|
-
// Show poll results — closure receives the BaseMessage? only
|
|
347
|
-
}
|
|
348
|
-
)
|
|
349
|
-
return [viewResultsOption]
|
|
350
|
-
}
|
|
351
|
-
)
|
|
352
|
-
|
|
353
|
-
// APPEND to the default templates (do NOT start from []) so every built-in bubble survives.
|
|
354
|
-
templates.append(customTemplate)
|
|
355
|
-
|
|
356
|
-
// set(templates:) → CometChatMessageList + Properties.swift:54 (replaces the list, so we passed the merged array).
|
|
357
|
-
// add(templates:) (line 63) merges into the existing list if you prefer.
|
|
358
|
-
messageList.set(templates: templates)
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Custom Poll Bubble View Example
|
|
362
|
-
|
|
363
|
-
```swift
|
|
364
|
-
class PollBubbleView: UIView {
|
|
365
|
-
|
|
366
|
-
private let questionLabel = UILabel()
|
|
367
|
-
private let optionsStack = UIStackView()
|
|
368
|
-
|
|
369
|
-
override init(frame: CGRect) {
|
|
370
|
-
super.init(frame: frame)
|
|
371
|
-
setupUI()
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
required init?(coder: NSCoder) {
|
|
375
|
-
super.init(coder: coder)
|
|
376
|
-
setupUI()
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
private func setupUI() {
|
|
380
|
-
questionLabel.font = .boldSystemFont(ofSize: 16)
|
|
381
|
-
questionLabel.numberOfLines = 0
|
|
382
|
-
|
|
383
|
-
optionsStack.axis = .vertical
|
|
384
|
-
optionsStack.spacing = 8
|
|
385
|
-
|
|
386
|
-
addSubview(questionLabel)
|
|
387
|
-
addSubview(optionsStack)
|
|
388
|
-
|
|
389
|
-
questionLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
390
|
-
optionsStack.translatesAutoresizingMaskIntoConstraints = false
|
|
391
|
-
|
|
392
|
-
NSLayoutConstraint.activate([
|
|
393
|
-
questionLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
|
|
394
|
-
questionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
|
|
395
|
-
questionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
|
|
396
|
-
|
|
397
|
-
optionsStack.topAnchor.constraint(equalTo: questionLabel.bottomAnchor, constant: 12),
|
|
398
|
-
optionsStack.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
|
|
399
|
-
optionsStack.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
|
|
400
|
-
optionsStack.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
|
|
401
|
-
])
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
func configure(with data: [String: Any]) {
|
|
405
|
-
questionLabel.text = data["question"] as? String
|
|
406
|
-
|
|
407
|
-
optionsStack.arrangedSubviews.forEach { $0.removeFromSuperview() }
|
|
408
|
-
|
|
409
|
-
if let options = data["options"] as? [String] {
|
|
410
|
-
for option in options {
|
|
411
|
-
let button = UIButton(type: .system)
|
|
412
|
-
button.setTitle(option, for: .normal)
|
|
413
|
-
button.backgroundColor = .systemGray5
|
|
414
|
-
button.layer.cornerRadius = 8
|
|
415
|
-
button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 12, bottom: 8, right: 12)
|
|
416
|
-
optionsStack.addArrangedSubview(button)
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
---
|
|
424
|
-
|
|
425
|
-
## 4. Text Formatters
|
|
426
|
-
|
|
427
|
-
### Creating a Custom Text Formatter
|
|
428
|
-
|
|
429
|
-
```swift
|
|
430
|
-
class HashtagFormatter: CometChatTextFormatter {
|
|
431
|
-
|
|
432
|
-
override func getRegex() -> String {
|
|
433
|
-
return "#[a-zA-Z0-9_]+"
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
override func prepareMessageString(
|
|
437
|
-
baseMessage: BaseMessage,
|
|
438
|
-
regexString: String,
|
|
439
|
-
alignment: MessageBubbleAlignment,
|
|
440
|
-
formattingType: FormattingType
|
|
441
|
-
) -> NSAttributedString {
|
|
442
|
-
|
|
443
|
-
guard let textMessage = baseMessage as? TextMessage,
|
|
444
|
-
let text = textMessage.text else {
|
|
445
|
-
return NSAttributedString()
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
let attributedString = NSMutableAttributedString(string: text)
|
|
449
|
-
|
|
450
|
-
// Default text attributes
|
|
451
|
-
let defaultAttributes: [NSAttributedString.Key: Any] = [
|
|
452
|
-
.font: CometChatTypography.Body.regular,
|
|
453
|
-
.foregroundColor: alignment == .right ? UIColor.white : UIColor.label
|
|
454
|
-
]
|
|
455
|
-
attributedString.addAttributes(defaultAttributes, range: NSRange(location: 0, length: text.count))
|
|
456
|
-
|
|
457
|
-
// Highlight hashtags
|
|
458
|
-
let regex = try? NSRegularExpression(pattern: regexString, options: [])
|
|
459
|
-
let matches = regex?.matches(in: text, options: [], range: NSRange(location: 0, length: text.count)) ?? []
|
|
460
|
-
|
|
461
|
-
for match in matches {
|
|
462
|
-
let hashtagAttributes: [NSAttributedString.Key: Any] = [
|
|
463
|
-
.foregroundColor: UIColor.systemBlue,
|
|
464
|
-
.font: CometChatTypography.Body.medium
|
|
465
|
-
]
|
|
466
|
-
attributedString.addAttributes(hashtagAttributes, range: match.range)
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return attributedString
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
override func onTextTapped(
|
|
473
|
-
baseMessage: BaseMessage,
|
|
474
|
-
tappedText: String,
|
|
475
|
-
controller: UIViewController?
|
|
476
|
-
) {
|
|
477
|
-
// Handle hashtag tap
|
|
478
|
-
print("Hashtag tapped: \(tappedText)")
|
|
479
|
-
// Navigate to hashtag search, etc.
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Usage
|
|
484
|
-
let messageList = CometChatMessageList()
|
|
485
|
-
messageList.textFormatter = [
|
|
486
|
-
CometChatMentionsFormatter(), // Built-in mentions
|
|
487
|
-
HashtagFormatter() // Custom hashtags
|
|
488
|
-
]
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
### URL Formatter with Custom Preview
|
|
492
|
-
|
|
493
|
-
```swift
|
|
494
|
-
class CustomURLFormatter: CometChatTextFormatter {
|
|
495
|
-
|
|
496
|
-
override func getRegex() -> String {
|
|
497
|
-
return "https?://[^\\s]+"
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
override func prepareMessageString(
|
|
501
|
-
baseMessage: BaseMessage,
|
|
502
|
-
regexString: String,
|
|
503
|
-
alignment: MessageBubbleAlignment,
|
|
504
|
-
formattingType: FormattingType
|
|
505
|
-
) -> NSAttributedString {
|
|
506
|
-
|
|
507
|
-
guard let textMessage = baseMessage as? TextMessage,
|
|
508
|
-
let text = textMessage.text else {
|
|
509
|
-
return NSAttributedString()
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
let attributedString = NSMutableAttributedString(string: text)
|
|
513
|
-
|
|
514
|
-
let regex = try? NSRegularExpression(pattern: regexString, options: [])
|
|
515
|
-
let matches = regex?.matches(in: text, options: [], range: NSRange(location: 0, length: text.count)) ?? []
|
|
516
|
-
|
|
517
|
-
for match in matches {
|
|
518
|
-
let urlAttributes: [NSAttributedString.Key: Any] = [
|
|
519
|
-
.foregroundColor: UIColor.systemBlue,
|
|
520
|
-
.underlineStyle: NSUnderlineStyle.single.rawValue
|
|
521
|
-
]
|
|
522
|
-
attributedString.addAttributes(urlAttributes, range: match.range)
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
return attributedString
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
override func onTextTapped(
|
|
529
|
-
baseMessage: BaseMessage,
|
|
530
|
-
tappedText: String,
|
|
531
|
-
controller: UIViewController?
|
|
532
|
-
) {
|
|
533
|
-
if let url = URL(string: tappedText) {
|
|
534
|
-
UIApplication.shared.open(url)
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
---
|
|
541
|
-
|
|
542
|
-
## 5. Event Listeners
|
|
543
|
-
|
|
544
|
-
### Message Events
|
|
545
|
-
|
|
546
|
-
```swift
|
|
547
|
-
import CometChatSDK
|
|
21
|
+
**2. Typography.** `CometChatTypography.setFont(name:)` swaps the family app-wide. Do this alongside the theme, not per component.
|
|
548
22
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
func ccMessageSent(message: BaseMessage, status: MessageStatus) {
|
|
552
|
-
switch status {
|
|
553
|
-
case .inProgress:
|
|
554
|
-
print("Message sending...")
|
|
555
|
-
case .success:
|
|
556
|
-
print("Message sent successfully")
|
|
557
|
-
case .error:
|
|
558
|
-
print("Message failed to send")
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
func ccMessageEdited(message: BaseMessage, status: MessageStatus) {
|
|
563
|
-
print("Message edited: \(message.id)")
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
func ccMessageDeleted(message: BaseMessage) {
|
|
567
|
-
print("Message deleted: \(message.id)")
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
func ccMessageRead(message: BaseMessage) {
|
|
571
|
-
print("Message read: \(message.id)")
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
func ccLiveReaction(reaction: TransientMessage) {
|
|
575
|
-
print("Live reaction received")
|
|
576
|
-
}
|
|
577
|
-
}
|
|
23
|
+
**3. Per-component styles.** Each component takes a style object — `ConversationsStyle`, `SearchStyle`, `AvatarStyle`, `BadgeStyle`, `ReceiptStyle`, `StatusIndicatorStyle`, `TypingIndicatorStyle`, `DateStyle` and the per-bubble styles (`TextBubbleStyle`, `AudioBubbleStyle`, `CallBubbleStyle`, `BaseMessageBubbleStyle`, …). **These are assigned as properties, not passed through setters**: `conversations.avatarStyle = style`, `conversations.style = ConversationsStyle()`. Reach for these only when the global theme cannot express what you need.
|
|
578
24
|
|
|
579
|
-
|
|
580
|
-
let listener = MessageEventListener()
|
|
581
|
-
CometChatMessageEvents.addListener("message-listener", listener)
|
|
25
|
+
> Style type names are **mostly un-prefixed** — it is `ConversationsStyle`, `AvatarStyle`, `DateStyle`, with no `CometChat` prefix on any of them. 491 of the kit's 638 public types are un-prefixed, so prefixing a style name is the most common way to invent a type that does not exist. Check `catalogs/ios-v5.json` before writing one.
|
|
582
26
|
|
|
583
|
-
|
|
584
|
-
CometChatMessageEvents.removeListener("message-listener")
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### User Events
|
|
588
|
-
|
|
589
|
-
```swift
|
|
590
|
-
class UserEventListener: CometChatUserEventListener {
|
|
591
|
-
|
|
592
|
-
func ccUserBlocked(user: User) {
|
|
593
|
-
print("User blocked: \(user.name ?? "")")
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
func ccUserUnblocked(user: User) {
|
|
597
|
-
print("User unblocked: \(user.name ?? "")")
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Register
|
|
602
|
-
CometChatUserEvents.addListener("user-listener", UserEventListener())
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
### Group Events
|
|
606
|
-
|
|
607
|
-
```swift
|
|
608
|
-
class GroupEventListener: CometChatGroupEventListener {
|
|
609
|
-
|
|
610
|
-
func ccGroupCreated(group: Group) {
|
|
611
|
-
print("Group created: \(group.name ?? "")")
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
func ccGroupDeleted(group: Group) {
|
|
615
|
-
print("Group deleted: \(group.name ?? "")")
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
func ccGroupMemberAdded(messages: [ActionMessage], usersAdded: [User], groupAddedIn: Group, addedBy: User) {
|
|
619
|
-
print("Members added to group")
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
func ccGroupMemberKicked(action: ActionMessage, kickedUser: User, kickedBy: User, kickedFrom: Group) {
|
|
623
|
-
print("Member kicked from group")
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
func ccGroupMemberBanned(action: ActionMessage, bannedUser: User, bannedBy: User, bannedFrom: Group) {
|
|
627
|
-
print("Member banned from group")
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
func ccOwnershipChanged(group: Group, newOwner: GroupMember) {
|
|
631
|
-
print("Group ownership changed")
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
// Register
|
|
636
|
-
CometChatGroupEvents.addListener("group-listener", GroupEventListener())
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
### Call Events
|
|
640
|
-
|
|
641
|
-
```swift
|
|
642
|
-
class CallEventListener: CometChatCallEventListener {
|
|
643
|
-
|
|
644
|
-
func ccCallAccepted(call: Call) {
|
|
645
|
-
print("Call accepted")
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
func ccCallRejected(call: Call) {
|
|
649
|
-
print("Call rejected")
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
func ccCallEnded(call: Call) {
|
|
653
|
-
print("Call ended")
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
func ccOutgoingCall(call: Call) {
|
|
657
|
-
print("Outgoing call initiated")
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
func onCallInitiated(call: Call) { // CometChatCallEventListener has onCallInitiated, not ccCallInitiated
|
|
661
|
-
print("Call initiated")
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// Register
|
|
666
|
-
CometChatCallEvents.addListener("call-listener", CallEventListener())
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
---
|
|
670
|
-
|
|
671
|
-
## 6. Request Builder Filters
|
|
27
|
+
## Dark mode — the kit already does it
|
|
672
28
|
|
|
673
|
-
|
|
29
|
+
**Do NOT write trait-collection observers or reassign theme values on appearance changes.** The iOS
|
|
30
|
+
kit follows the OS light/dark setting by ITSELF: its components override `traitCollectionDidChange`
|
|
31
|
+
and its palette is built from dynamic colours. Flipping the simulator (or the device) between light
|
|
32
|
+
and dark repaints the whole surface with **zero theming code** in the host app.
|
|
674
33
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
// Only show user conversations (no groups)
|
|
679
|
-
// ConversationRequestBuilder exposes setConversationType(conversationType:), not set(conversationType:)
|
|
680
|
-
conversations.set(conversationsRequestBuilder: ConversationRequest.ConversationRequestBuilder()
|
|
681
|
-
.setConversationType(conversationType: .user)
|
|
682
|
-
.set(limit: 30)
|
|
683
|
-
)
|
|
684
|
-
```
|
|
34
|
+
This is the opposite of the web kit, where `theme="system"` does not exist and the core must sync
|
|
35
|
+
`theme` ↔ `prefers-color-scheme` (AUDIT-004). Do not carry that habit across — on iOS the work is
|
|
36
|
+
already done, and an observer you add is redundant at best.
|
|
685
37
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
### Filter Messages
|
|
38
|
+
For BRAND colours that must differ per appearance, build them with the kit's helper rather than
|
|
39
|
+
branching on the current style yourself:
|
|
689
40
|
|
|
690
41
|
```swift
|
|
691
|
-
let
|
|
692
|
-
|
|
693
|
-
// Only show text and image messages
|
|
694
|
-
messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
695
|
-
.set(uid: user.uid ?? "")
|
|
696
|
-
.set(types: [MessageTypeConstants.text, MessageTypeConstants.image])
|
|
697
|
-
.set(limit: 30)
|
|
698
|
-
)
|
|
699
|
-
|
|
700
|
-
// Only show messages from a specific time range
|
|
701
|
-
let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
|
|
702
|
-
messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
703
|
-
.set(uid: user.uid ?? "")
|
|
704
|
-
.set(timeStamp: Int(startDate.timeIntervalSince1970))
|
|
705
|
-
.set(limit: 50)
|
|
706
|
-
)
|
|
707
|
-
|
|
708
|
-
// Hide deleted messages
|
|
709
|
-
messageList.set(messagesRequestBuilder: MessagesRequest.MessageRequestBuilder()
|
|
710
|
-
.set(uid: user.uid ?? "")
|
|
711
|
-
.hideDeletedMessages(hide: true)
|
|
712
|
-
.set(limit: 30)
|
|
713
|
-
)
|
|
42
|
+
let brand = UIColor.dynamicColor(lightModeColor: .systemIndigo, darkModeColor: .systemTeal)
|
|
714
43
|
```
|
|
715
44
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
```swift
|
|
719
|
-
let users = CometChatUsers()
|
|
720
|
-
|
|
721
|
-
// Only show users with specific role
|
|
722
|
-
users.set(usersRequestBuilder: UsersRequest.UsersRequestBuilder()
|
|
723
|
-
.set(roles: ["admin", "moderator"])
|
|
724
|
-
.set(limit: 30)
|
|
725
|
-
)
|
|
726
|
-
|
|
727
|
-
// Only show friends
|
|
728
|
-
users.set(usersRequestBuilder: UsersRequest.UsersRequestBuilder()
|
|
729
|
-
.friendsOnly(true)
|
|
730
|
-
.set(limit: 30)
|
|
731
|
-
)
|
|
732
|
-
|
|
733
|
-
// Search users
|
|
734
|
-
users.set(usersRequestBuilder: UsersRequest.UsersRequestBuilder()
|
|
735
|
-
.set(searchKeyword: "john")
|
|
736
|
-
.set(limit: 30)
|
|
737
|
-
)
|
|
738
|
-
```
|
|
739
|
-
|
|
740
|
-
### Filter Groups
|
|
741
|
-
|
|
742
|
-
```swift
|
|
743
|
-
let groups = CometChatGroups()
|
|
744
|
-
|
|
745
|
-
// Only show joined groups
|
|
746
|
-
groups.set(groupsRequestBuilder: GroupsRequest.GroupsRequestBuilder()
|
|
747
|
-
.set(joinedOnly: true)
|
|
748
|
-
.set(limit: 30)
|
|
749
|
-
)
|
|
750
|
-
|
|
751
|
-
// Only show public groups
|
|
752
|
-
groups.set(groupsRequestBuilder: GroupsRequest.GroupsRequestBuilder()
|
|
753
|
-
.set(groupType: .public)
|
|
754
|
-
.set(limit: 30)
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
// Search groups
|
|
758
|
-
groups.set(groupsRequestBuilder: GroupsRequest.GroupsRequestBuilder()
|
|
759
|
-
.set(searchKeyWord: "team")
|
|
760
|
-
.set(limit: 30)
|
|
761
|
-
)
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
---
|
|
765
|
-
|
|
766
|
-
## 7. DataSource Decorator Pattern
|
|
767
|
-
|
|
768
|
-
> ⚠️ **REGISTRATION IS THE CATCH.** `DataSourceDecorator` is public (DataSourceDecorator.swift:12), but the only mechanism that installs a decorator — `ChatConfigurator.enable { ... }` — is **internal to CometChatUIKitSwift**. `ChatConfigurator` shows up in the public module interface (`uikit.swiftinterface:8591`) as a class with **no public members** (only `deinit`); its `enable`/`getDataSource` statics are NOT public. The kit's own extensions (Polls/Stickers/etc.) call `ChatConfigurator.enable` from *inside* the module via `ExtensionDataSource.addExtension()`, but **app code cannot call it**. So a hand-rolled `DataSourceDecorator` subclass compiles but **has no public way to be registered** in this kit version.
|
|
769
|
-
>
|
|
770
|
-
> **Use the public component-level setters instead** for the common cases:
|
|
771
|
-
> - **Attachment options** → `CometChatMessageComposer.set(attachmentOptions:)` (§7a below). Public. Verified `CometChatMessageComposer + Properties.swift:44`.
|
|
772
|
-
> - **Custom message type / override a built-in bubble / per-type long-press options** → build a `CometChatMessageTemplate` and apply it with `CometChatMessageList.set(templates:)` / `add(templates:)` (§3 and §7b). Public. Verified `CometChatMessageList + Properties.swift:54,63`.
|
|
773
|
-
> - **Message long-press options**: there is **NO** `set(options:)`/`add(options:)` for *message* options on `CometChatMessageList` (only Conversations/Users/Groups/GroupMembers/CallLogs expose those). Message options are customized **only through a template's `options` closure** (§7b).
|
|
774
|
-
>
|
|
775
|
-
> The decorator subclass below is documented for completeness / for code that lives inside a kit fork — its method signatures are the source of truth for the protocol — but prefer the component setters above for app integration.
|
|
776
|
-
|
|
777
|
-
### 7a. Add a composer attachment option (public path)
|
|
778
|
-
|
|
779
|
-
`set(attachmentOptions:)` REPLACES the attachment list with whatever the closure returns — there is no public "super" list at the composer level, so to keep the built-in photo/video/file actions you must construct them yourself or accept that only your returned actions show. The closure is `(User?, Group?, UIViewController?) -> [CometChatMessageComposerAction]`.
|
|
780
|
-
|
|
781
|
-
```swift
|
|
782
|
-
let composer = CometChatMessageComposer()
|
|
783
|
-
|
|
784
|
-
composer.set(attachmentOptions: { user, group, controller in
|
|
785
|
-
// NOTE: returning ONLY this array hides the default attachments.
|
|
786
|
-
// Re-add any defaults you still want here.
|
|
787
|
-
let location = CometChatMessageComposerAction(
|
|
788
|
-
id: "location",
|
|
789
|
-
text: "Send Location",
|
|
790
|
-
startIcon: UIImage(systemName: "location.fill"),
|
|
791
|
-
startIconTint: CometChatTheme.iconColorPrimary,
|
|
792
|
-
textColor: CometChatTheme.textColorPrimary,
|
|
793
|
-
textFont: CometChatTypography.Body.regular,
|
|
794
|
-
onActionClick: { /* present location picker, then send (see §8) */ }
|
|
795
|
-
)
|
|
796
|
-
return [location]
|
|
797
|
-
})
|
|
798
|
-
```
|
|
799
|
-
|
|
800
|
-
### 7b. Override a built-in type's bubble / add per-type options (public path)
|
|
801
|
-
|
|
802
|
-
To replace the content view of a built-in type (e.g. text) — or attach a custom long-press option to it — start from the default template for that type, rebuild it with your closures, and apply via `add(templates:)`. `CometChatMessageTemplate` is a struct, so you create a NEW one (you cannot mutate a `let` from `getAllMessageTemplates`); copy `category`/`type` from the default and supply the closures you want.
|
|
803
|
-
|
|
804
|
-
```swift
|
|
805
|
-
let messageList = CometChatMessageList()
|
|
806
|
-
|
|
807
|
-
// Built-in text type identifiers (CometChatSDK constants):
|
|
808
|
-
// category = "message", type = "text" (matches MessagesDataSource.getTextMessageTemplate → "message"/"text")
|
|
809
|
-
let overriddenText = CometChatMessageTemplate(
|
|
810
|
-
category: "message",
|
|
811
|
-
type: "text",
|
|
812
|
-
contentView: { message, alignment, controller in // ← override the bubble content
|
|
813
|
-
let label = UILabel()
|
|
814
|
-
label.numberOfLines = 0
|
|
815
|
-
label.text = (message as? TextMessage)?.text
|
|
816
|
-
label.textColor = alignment == .right ? .white : .label
|
|
817
|
-
return label
|
|
818
|
-
},
|
|
819
|
-
bubbleView: nil, headerView: nil, footerView: nil, bottomView: nil,
|
|
820
|
-
options: { message, group, controller in // ← add a long-press option to text bubbles
|
|
821
|
-
let star = CometChatMessageOption(
|
|
822
|
-
id: "star",
|
|
823
|
-
title: "Star",
|
|
824
|
-
icon: UIImage(systemName: "star.fill"),
|
|
825
|
-
onItemClick: { msg in print("starred \(msg?.id ?? 0)") }
|
|
826
|
-
)
|
|
827
|
-
return [star]
|
|
828
|
-
}
|
|
829
|
-
)
|
|
830
|
-
|
|
831
|
-
// add(templates:) MERGES by "category_type" key — it overwrites the default text template
|
|
832
|
-
// with ours and leaves every OTHER built-in bubble intact (CometChatMessageList + Properties.swift:63).
|
|
833
|
-
messageList.add(templates: [overriddenText])
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
### 7c. Decorator signatures (reference — registration is internal)
|
|
837
|
-
|
|
838
|
-
```swift
|
|
839
|
-
class CustomDataSource: DataSourceDecorator {
|
|
840
|
-
|
|
841
|
-
// ⚠️ Signature MUST match the protocol exactly — it takes `additionalConfiguration:`.
|
|
842
|
-
// Omitting the parameter does NOT override the kit method; your templates never appear.
|
|
843
|
-
override func getAllMessageTemplates(
|
|
844
|
-
additionalConfiguration: AdditionalConfiguration?
|
|
845
|
-
) -> [CometChatMessageTemplate] {
|
|
846
|
-
// Call super to KEEP every default template (text/image/video/file/…).
|
|
847
|
-
var templates = super.getAllMessageTemplates(additionalConfiguration: additionalConfiguration)
|
|
848
|
-
|
|
849
|
-
// Append — never replace the array, or all default bubbles disappear.
|
|
850
|
-
// ⚠️ Same init rule as §3: `category` first, then `type`, and ALL view-closure labels
|
|
851
|
-
// are required (pass nil). NO `CometChatMessageTemplate(type:category:)` shorthand exists.
|
|
852
|
-
let customTemplate = CometChatMessageTemplate(
|
|
853
|
-
category: "custom",
|
|
854
|
-
type: "custom_type",
|
|
855
|
-
contentView: { message, alignment, controller in UIView() },
|
|
856
|
-
bubbleView: nil, headerView: nil, footerView: nil, bottomView: nil, options: nil
|
|
857
|
-
)
|
|
858
|
-
templates.append(customTemplate)
|
|
859
|
-
|
|
860
|
-
return templates
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
// Add a composer attachment option WITHOUT wiping the defaults (photo/video/file/…).
|
|
864
|
-
// Same rule: start from super's list, then append.
|
|
865
|
-
// ⚠️ `additionalConfiguration: AdditionalConfiguration` is REQUIRED with NO default value
|
|
866
|
-
// in the protocol (DataSource.swift:74) and the decorator (DataSourceDecorator.swift:24).
|
|
867
|
-
// Do NOT add `= AdditionalConfiguration()` here — match the signature exactly.
|
|
868
|
-
override func getAttachmentOptions(
|
|
869
|
-
controller: UIViewController,
|
|
870
|
-
user: User?,
|
|
871
|
-
group: Group?,
|
|
872
|
-
id: [String: Any]?,
|
|
873
|
-
additionalConfiguration: AdditionalConfiguration
|
|
874
|
-
) -> [CometChatMessageComposerAction]? {
|
|
875
|
-
var options = super.getAttachmentOptions(
|
|
876
|
-
controller: controller, user: user, group: group,
|
|
877
|
-
id: id, additionalConfiguration: additionalConfiguration
|
|
878
|
-
) ?? []
|
|
879
|
-
// ⚠️ There is NO zero-arg `CometChatMessageComposerAction()` init. The only
|
|
880
|
-
// initializer requires id/text/startIcon/startIconTint/textColor/textFont
|
|
881
|
-
// (endIcon, tints, colors, border, onActionClick all default).
|
|
882
|
-
// Verified: CometChatMessageComposerAction.swift:28-56.
|
|
883
|
-
let location = CometChatMessageComposerAction(
|
|
884
|
-
id: "location",
|
|
885
|
-
text: "Send Location",
|
|
886
|
-
startIcon: UIImage(systemName: "location.fill"),
|
|
887
|
-
startIconTint: CometChatTheme.iconColorPrimary,
|
|
888
|
-
textColor: CometChatTheme.textColorPrimary,
|
|
889
|
-
textFont: CometChatTypography.Body.regular,
|
|
890
|
-
onActionClick: { /* present location picker, then send (see §8) */ }
|
|
891
|
-
)
|
|
892
|
-
options.append(location)
|
|
893
|
-
return options
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
override func getAllMessageTypes() -> [String]? {
|
|
897
|
-
var types = super.getAllMessageTypes() ?? []
|
|
898
|
-
types.append("custom_type")
|
|
899
|
-
return types
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
override func getAllMessageCategories() -> [String]? {
|
|
903
|
-
var categories = super.getAllMessageCategories() ?? []
|
|
904
|
-
categories.append("custom")
|
|
905
|
-
return categories
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
// ⚠️ `additionalConfiguration: AdditionalConfiguration` is REQUIRED (no default) on this
|
|
909
|
-
// method too — omitting it means you DON'T override the protocol method and your option
|
|
910
|
-
// never appears. Verified: DataSource.swift:67, DataSourceDecorator.swift:36.
|
|
911
|
-
override func getMessageOptions(
|
|
912
|
-
loggedInUser: User,
|
|
913
|
-
messageObject: BaseMessage,
|
|
914
|
-
controller: UIViewController?,
|
|
915
|
-
group: Group?,
|
|
916
|
-
additionalConfiguration: AdditionalConfiguration
|
|
917
|
-
) -> [CometChatMessageOption]? {
|
|
918
|
-
var options = super.getMessageOptions(
|
|
919
|
-
loggedInUser: loggedInUser,
|
|
920
|
-
messageObject: messageObject,
|
|
921
|
-
controller: controller,
|
|
922
|
-
group: group,
|
|
923
|
-
additionalConfiguration: additionalConfiguration
|
|
924
|
-
) ?? []
|
|
925
|
-
|
|
926
|
-
// Add custom option. ⚠️ The click handler is `onItemClick: (BaseMessage?) -> Void`
|
|
927
|
-
// — there is NO `onClick` property and NO 4-arg closure. Set it via the initializer
|
|
928
|
-
// (it's a struct; `onItemClick` is the only callback). Verified: CometChatMessageOption.swift:30,33-45.
|
|
929
|
-
let customOption = CometChatMessageOption(
|
|
930
|
-
id: "custom_action",
|
|
931
|
-
title: "Custom Action",
|
|
932
|
-
icon: UIImage(systemName: "star.fill"),
|
|
933
|
-
onItemClick: { message in
|
|
934
|
-
print("Custom action triggered for \(message?.id ?? 0)")
|
|
935
|
-
}
|
|
936
|
-
)
|
|
937
|
-
options.append(customOption)
|
|
938
|
-
|
|
939
|
-
return options
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
// ⚠️ NO PUBLIC REGISTRATION. The only installer, `ChatConfigurator.enable { dataSource in
|
|
944
|
-
// return CustomDataSource(dataSource: dataSource) }`, is INTERNAL to CometChatUIKitSwift
|
|
945
|
-
// and does NOT compile from app code (ChatConfigurator exposes no public members —
|
|
946
|
-
// uikit.swiftinterface:8591). Subclassing `ExtensionDataSource` does not help either: its
|
|
947
|
-
// base `addExtension()` is empty and the only way to make it do anything is to call the same
|
|
948
|
-
// internal `ChatConfigurator.enable` from inside it.
|
|
949
|
-
// → For app integration, use the public component setters in §7a / §7b instead.
|
|
950
|
-
// (This decorator block stands only as the authoritative signature reference, and works
|
|
951
|
-
// for code compiled INSIDE a kit fork.)
|
|
952
|
-
```
|
|
953
|
-
|
|
954
|
-
---
|
|
955
|
-
|
|
956
|
-
## 8. Sending a Custom Message — use the UIKit path, not the raw SDK
|
|
957
|
-
|
|
958
|
-
A custom `contentView`/template only renders messages of that `type`; you still have to **send** one. Use **`CometChatUIKit.sendCustomMessage(message:)`**, not `CometChat.sendCustomMessage(...)`. The UIKit wrapper stamps `muid` + sender and fires the `ccMessageSent` event, which is what makes the new bubble **append** to the open list. The raw SDK call skips those, giving the two classic failures: a "cannot determine recipient" state and the realtime message **replacing** an existing bubble instead of appending (no `muid` for dedup).
|
|
959
|
-
|
|
960
|
-
```swift
|
|
961
|
-
// Build with the receiver set — receiverUid + .user (or a guid + .group)
|
|
962
|
-
let custom = CustomMessage(
|
|
963
|
-
receiverUid: selectedUser.uid,
|
|
964
|
-
receiverType: .user, // CometChat.ReceiverType
|
|
965
|
-
customData: ["question": "Lunch?", "options": ["Yes", "No"]],
|
|
966
|
-
type: "custom_poll" // MUST match the template/contentView type
|
|
967
|
-
)
|
|
968
|
-
|
|
969
|
-
// ✅ kit path — sets muid + sender, emits ccMessageSent → list appends
|
|
970
|
-
CometChatUIKit.sendCustomMessage(message: custom)
|
|
971
|
-
|
|
972
|
-
// ❌ raw SDK — no muid/sender/event → recipient error + realtime replace
|
|
973
|
-
// CometChat.sendCustomMessage(message: custom, onSuccess: { _ in }, onError: { _ in })
|
|
974
|
-
```
|
|
975
|
-
|
|
976
|
-
Verified: `CustomMessage(receiverUid:receiverType:customData:type:)` (CometChatSDK) and static `CometChatUIKit.sendCustomMessage(message:)` (CometChatUIKitSwift).
|
|
977
|
-
|
|
978
|
-
---
|
|
979
|
-
|
|
980
|
-
## Best Practices
|
|
45
|
+
It resolves per trait collection automatically, so it keeps working when the OS setting changes.
|
|
981
46
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
3. **Handle all message types** — Don't forget edge cases
|
|
985
|
-
4. **Test with real data** — Use actual conversations for testing
|
|
986
|
-
5. **Clean up listeners** — Remove event listeners when views are deallocated
|
|
987
|
-
6. **Use weak references** — Avoid retain cycles in closures
|
|
47
|
+
## Localisation & sounds
|
|
48
|
+
`CometChatLocalize` for strings, `CometChatSoundManager` for the audio cues; per-component overrides via `set(customSoundForMessages:)`. **Never render a raw localisation key** — the kit's keys are SCREAMING_SNAKE (`TYPE_A_MESSAGE`, `CHATS`); if one appears on screen it means a missing or wrong key, not a label.
|
|
988
49
|
|
|
989
|
-
##
|
|
50
|
+
## Gotchas
|
|
51
|
+
- **Set the theme BEFORE the first render.** Restyling after components are on screen does not retroactively repaint them.
|
|
52
|
+
- **Styles are properties.** `component.set(avatarStyle:)` does not exist on the list components; assignment does.
|
|
53
|
+
- **Don't restyle what the theme already covers** — a per-component style that hardcodes a colour will drift from the brand the moment the theme changes.
|
|
990
54
|
|
|
991
|
-
|
|
55
|
+
## Verify it works
|
|
56
|
+
The brand colour appears on send buttons, badges and highlights without per-component work; the font applies across every screen; dark mode flips cleanly; no SCREAMING_SNAKE keys are visible anywhere.
|