### Perform Tool Registration on App Start (Swift) Source: https://getstream.io/chat/docs/sdk/ios/ai-integrations/client-side-tools.md Example of how to initiate the tool registration process when your application starts. It retrieves the tool payloads from a client registry and calls the `registerTools` function. ```swift let tools = clientToolRegistry.registrationPayloads() try await registerTools(channelId: "your_channel_id", tools: tools) ``` -------------------------------- ### Configure Stream Video and Chat Clients Source: https://getstream.io/chat/docs/sdk/ios/guides/video-integration.md Example of initializing and connecting both Stream Video and Chat clients, ensuring they share the same API key and user token. This setup is facilitated by a StreamWrapper. ```swift let streamWrapper = StreamWrapper( apiKey: "YOUR_API_KEY", userCredentials: user, tokenProvider: { result in let token = \ Retrieve the token from your backend result(.success(token)) } ) ``` -------------------------------- ### Initialize StreamChat Context Provider Source: https://getstream.io/chat/docs/sdk/ios/swiftui/getting-started.md This is the minimal setup required for the context provider. It's recommended to perform this setup when the app starts and maintain a strong reference to the `StreamChat` instance. ```swift let apiKeyString = "your_api_key_string" let config = ChatClientConfig(apiKey: .init(apiKeyString)) let chatClient = ChatClient(config: config) let streamChat = StreamChat(chatClient: chatClient) ``` -------------------------------- ### Install Media Library for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install the expo-media-library package for Expo projects using npx. ```bash npx expo install expo-media-library ``` -------------------------------- ### Basic Usage of useCreateChatClient Source: https://getstream.io/chat/docs/sdk/react-native/hooks/chat/use-create-chat-client.md This example demonstrates the basic setup for the useCreateChatClient hook. It shows how to provide API key, user data, and token, and how to handle the loading state before rendering the Chat component. ```tsx import { Chat, OverlayProvider, useCreateChatClient, } from "stream-chat-react-native"; import { ActivityIndicator, View } from "react-native"; const App = () => { const chatClient = useCreateChatClient({ apiKey: "YOUR_API_KEY", userData: { id: "YOUR_USER_ID", name: "YOUR_USER_NAME", }, tokenOrProvider: "YOUR_TOKEN_OR_PROVIDER", }); if (!chatClient) { return ( ); } return ( {/** Your app components */} ); }; ``` -------------------------------- ### Client Setup: v7 with Config Source: https://getstream.io/chat/docs/sdk/android/migration-guides/migrating-from-v6-to-v7.md Shows the v7 client setup using the `config()` method with `ChatClientConfig`. ```kotlin val client = ChatClient.Builder(apiKey, context) .config(ChatClientConfig()) .build() ``` -------------------------------- ### Install @stream-io/chat-react-ai with NPM Source: https://getstream.io/chat/docs/sdk/react/guides/ai-integrations.md Install the AI SDK and its peer dependencies using NPM. ```bash npm i @stream-io/chat-react-ai ``` -------------------------------- ### Client Setup: v6 with Plugins Source: https://getstream.io/chat/docs/sdk/android/migration-guides/migrating-from-v6-to-v7.md Illustrates the client setup in v6 using `withPlugins` for offline and state management. ```kotlin val client = ChatClient.Builder(apiKey, context) .withPlugins( StreamOfflinePluginFactory(context), StreamStatePluginFactory(StatePluginConfig(), context), ) .build() ``` -------------------------------- ### Install @stream-io/chat-react-ai with PNPM Source: https://getstream.io/chat/docs/sdk/react/guides/ai-integrations.md Install the AI SDK and its peer dependencies using PNPM. ```bash pnpm add @stream-io/chat-react-ai ``` -------------------------------- ### Quick Start: Single Agent Deployment Source: https://getstream.io/chat/docs/sdk/android/ai-integrations/stream-chat-ai-sdk.md Instantiate and manage a single AI agent for chat interactions. Includes setup for server and client tools, and lifecycle management. ```typescript import { Agent, AgentPlatform, createDefaultTools, type ClientToolDefinition, } from "@stream-io/chat-ai-sdk"; const agent = new Agent({ userId: "ai-bot-weather", channelId: "support-room", channelType: "messaging", platform: AgentPlatform.OPENAI, model: "gpt-4o-mini", instructions: [ "Answer in a friendly, concise tone.", "Prefer Celsius unless the user specifies otherwise.", ], serverTools: createDefaultTools(), clientTools: [ { name: "openHelpCenter", description: "Open the help center in the web app", parameters: { type: "object", properties: { articleSlug: { type: "string" } }, required: ["articleSlug"], }, } satisfies ClientToolDefinition, ], mem0Context: { channelId: "support-room", appId: "stream-chat-support", }, }); await agent.start(); // Later... await agent.stop(); ``` -------------------------------- ### Install @stream-io/chat-react-ai with Yarn Source: https://getstream.io/chat/docs/sdk/react/guides/ai-integrations.md Install the AI SDK and its peer dependencies using Yarn. ```bash yarn add @stream-io/chat-react-ai ``` -------------------------------- ### Start Ionic Development Server Source: https://getstream.io/chat/docs/sdk/angular/code-examples/ionic-guide.md Starts the development server for the Ionic application, allowing for live preview and testing. ```bash npm start ``` -------------------------------- ### Start ChannelActivity with Java Source: https://getstream.io/chat/docs/sdk/android/ui/message-components/message-list-screen.md Use ChannelActivity.createIntent to start a fully functional chat screen. Requires a channel ID. ```java context.startActivity(ChannelActivity.createIntent(context, "messaging:123")); ``` -------------------------------- ### start Source: https://getstream.io/chat/docs/sdk/angular/services/AmplitudeRecorderService.md Starts amplitude recording for a given media stream. This method initializes the recording process. ```APIDOC ## start ### Description Start amplitude recording for the given media stream. ### Method POST ### Endpoint /start ### Parameters #### Request Body - **stream** (MediaStream) - Required - The media stream to record amplitudes from. ### Response #### Success Response (200) - **void** - Indicates successful start of the recording. #### Response Example null ``` -------------------------------- ### Basic ChannelList Usage Source: https://getstream.io/chat/docs/sdk/react/components/core-components/channel-list.md This example shows the basic setup for the ChannelList component within a Chat application. It includes essential props like filters, sort, and options for customizing the channel query. Ensure filters include the user ID to avoid querying all app channels. ```tsx const filters = { members: { $in: [ 'jimmy', 'buffet' ] } } const sort = { last_message_at: -1 }; const options = { limit: 10 } ``` -------------------------------- ### Install with npm Source: https://getstream.io/chat/docs/sdk/react/basics/installation.md Use npm to install the Stream Chat and Stream Chat React packages. Ensure both packages are installed to maintain version alignment. ```bash npm install stream-chat stream-chat-react@beta ``` -------------------------------- ### Example SDK String Resource Source: https://getstream.io/chat/docs/sdk/android/ui/guides/custom-translations.md This is an example of a default string resource provided by the Stream SDK, prefixed with `stream_ui_`. ```xml No messages ``` -------------------------------- ### Start ChannelActivity with Kotlin Source: https://getstream.io/chat/docs/sdk/android/ui/message-components/message-list-screen.md Use ChannelActivity.createIntent to start a fully functional chat screen. Requires a channel ID. ```kotlin context.startActivity(ChannelActivity.createIntent(context, cid = "messaging:123")) ``` -------------------------------- ### Install LameJS for MP3 Transcoding Source: https://getstream.io/chat/docs/sdk/angular/code-examples/voice-recordings.md Install the @breezystack/lamejs library to enable MP3 transcoding for audio recordings. ```bash npm install @breezystack/lamejs ``` -------------------------------- ### Install Emoji Mart Library Source: https://getstream.io/chat/docs/sdk/angular/code-examples/emoji-picker.md Install the @ctrl/ngx-emoji-mart package using npm. ```bash npm install @ctrl/ngx-emoji-mart ``` -------------------------------- ### Install Ionic CLI and Tooling Source: https://getstream.io/chat/docs/sdk/angular/code-examples/ionic-guide.md Installs the Ionic command-line interface and related tools for building and running Ionic applications. ```bash npm install -g @ionic/cli native-run cordova-res ``` -------------------------------- ### Install AI Components and Dependencies Source: https://getstream.io/chat/docs/sdk/react-native/guides/ai-integrations.md Install the AI components and their peer dependencies using Yarn. Ensure all listed packages are included for full functionality. ```bash yarn add @stream-io/chat-react-native-ai react-native-reanimated react-native-worklets react-native-gesture-handler react-native-svg victory-native @shopify/react-native-skia @babel/plugin-proposal-export-namespace-from ``` -------------------------------- ### Basic StreamMemberListView Example Source: https://getstream.io/chat/docs/sdk/flutter/stream-chat-flutter/member-list/stream-member-list-view.md This example demonstrates how to initialize and use StreamMemberListView with a StreamMemberListController. Ensure StreamChannel is available in the widget tree. ```dart class MemberListPage extends StatefulWidget { const MemberListPage({super.key}); @override State createState() => _MemberListPageState(); } class _MemberListPageState extends State { late final StreamMemberListController _memberListController = StreamMemberListController( channel: StreamChannel.of(context).channel, limit: 25, filter: Filter.and( [Filter.notEqual('id', StreamChat.of(context).currentUser!.id)], ), sort: [ const SortOption( 'name', direction: 1, ), ], ); @override Widget build(BuildContext context) { return RefreshIndicator( onRefresh: () => _memberListController.refresh(), child: StreamMemberListView( controller: _memberListController, ), ); } } ``` -------------------------------- ### Example: Subscribing to MessageNewEvent Source: https://getstream.io/chat/docs/sdk/ios/combine/events.md This example demonstrates how to subscribe to `MessageNewEvent` within a custom `ChatChannelListVC`. Ensure the `EventsController` is initialized and the subscription is stored in `cancellables`. ```swift class YourCustomChannelListVC: ChatChannelListVC { var eventsController: EventsController! var cancellables: Set = [] override func viewDidLoad() { super.viewDidLoad() eventsController = controller.client.eventsController() eventsController .eventPublisher(MessageNewEvent.self) .receive(on: RunLoop.main) .sink { messageNewEvent in // do what you need with the event print(messageNewEvent.message.id) } .store(in: &cancellables) } } ``` -------------------------------- ### Setup ChatClient Instance Source: https://getstream.io/chat/docs/sdk/ios/uikit/getting-started.md Instantiate the ChatClient using a singleton pattern. Ensure you replace the placeholder with your actual API Key. ```swift extension ChatClient { static let shared: ChatClient = { // You can grab your API Key from https://getstream.io/dashboard/ let config = ChatClientConfig(apiKeyString: "<# Your API Key Here #>") // Create an instance of the `ChatClient` with the given config let client = ChatClient(config: config) return client }() } ``` -------------------------------- ### GreetClientTool Implementation Source: https://getstream.io/chat/docs/sdk/ios/ai-integrations/client-side-tools.md An example implementation of the `ClientTool` protocol for a 'greet' tool. It defines the tool's schema, instructions, and handles invocation by presenting a greeting alert. ```swift @MainActor final class GreetClientTool: ClientTool { let toolDefinition: Tool = { let schema: Value = .object([ "type": .string("object"), "properties": .object([:]), "required": .array([]), "additionalProperties": .bool(false) ]) return Tool( name: "greetUser", description: "Display a native greeting to the user", inputSchema: schema, annotations: .init(title: "Greet user") ) }() let instructions = "Use the greetUser tool when the user asks to be greeted. The tool shows a greeting alert in the iOS app." let showExternalSourcesIndicator = false func handleInvocation(_ invocation: ClientToolInvocation) -> [ClientToolAction] { [ { ClientToolActionHandler.shared.presentAlert( ClientToolAlert( title: "Greetings!", message: "👋 Hello there! The assistant asked me to greet you." ) ) } ] } } ``` -------------------------------- ### Bind ChannelListHeaderViewModel with ChannelListHeaderView (Java) Source: https://getstream.io/chat/docs/sdk/android/ui/channel-components/channel-list-header.md Instantiate the ChannelListHeaderViewModel using ViewModelProvider and bind it with the ChannelListHeaderView. This Java example demonstrates the equivalent setup for Android development. ```java // Instantiate the ViewModel ChannelListHeaderViewModel viewModel = new ViewModelProvider(this).get(ChannelListHeaderViewModel.class); // Bind it with ChannelListHeaderView ChannelListHeaderViewModelBinding.bind(viewModel, channelListHeaderView, getViewLifecycleOwner()); ``` -------------------------------- ### Custom Channel Preview with Archiving Logic Source: https://getstream.io/chat/docs/sdk/react-native/guides/channel-pinning-and-archiving.md Implement custom UI for channel archiving and unarchiving. This example uses `useChannelMembershipState` to get the archived status and `channel.archive()` or `channel.unarchive()` to toggle the state. ```typescript import { Pressable } from "react-native"; import { Archive, Unarchive, useChannelMembershipState, } from "stream-chat-react-native"; const CustomChannelPreview = ({ channel }) => { const membership = useChannelMembershipState(channel); return ( { if (membership?.archived_at) { await channel.unarchive(); } else { await channel.archive(); } }} > {membership?.archived_at ? ( ) : ( )} ); }; ``` -------------------------------- ### Start ChannelListActivity Source: https://getstream.io/chat/docs/sdk/android/ui/channel-components/channel-list-screen.md Use this to launch the pre-built channel list screen activity. Ensure you have the necessary context available. ```kotlin context.startActivity(ChannelListActivity.createIntent(context)) ``` ```java context.startActivity(ChannelListActivity.createIntent(context)); ``` -------------------------------- ### Global Audio Player UI with useActiveAudioPlayer Source: https://getstream.io/chat/docs/sdk/react/guides/audio-playback.md Use `useActiveAudioPlayer` to get a reactive `AudioPlayer` instance for the currently active player. This example shows how to display a persistent player UI and hide it when playback ends. ```tsx import { useEffect, useState } from "react"; import { useActiveAudioPlayer } from "stream-chat-react"; import { AudioPlayerUI } from "./MyAudioPlayerUI"; const Player = () => { const activePlayer = useActiveAudioPlayer(); const [open, setOpen] = useState(!!activePlayer); useEffect(() => { setOpen(!!activePlayer); if (!activePlayer) return; const element = activePlayer?.elementRef; if (!element) return; const handleEnded = () => { setOpen(false); }; // optionally we can hide the player once the playback ended element.addEventListener("ended", handleEnded); return () => { element.removeEventListener("ended", handleEnded); }; }, [activePlayer]); if (!activePlayer || !open) return null; return (
); }; ``` -------------------------------- ### Firebase Cloud Functions for Stream Chat Source: https://getstream.io/chat/docs/sdk/flutter/guides/token-generation-with-firebase.md This is the complete example for setting up Firebase Cloud Functions to interact with Stream Chat. It includes functions for creating, getting, and revoking user tokens, as well as deleting users. ```javascript const StreamChat = require("stream-chat").StreamChat; const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); const serverClient = StreamChat.getInstance( functions.config().stream.key, functions.config().stream.secret, ); // When a user is deleted from Firebase their associated Stream account is also deleted. exports.deleteStreamUser = functions.auth.user().onDelete((user, context) => { return serverClient.deleteUser(user.uid); }); // Create a Stream user and return auth token. exports.createStreamUserAndGetToken = functions.https.onCall( async (data, context) => { // Checking that the user is authenticated. if (!context.auth) { // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "failed-precondition", "The function must be called " + "while authenticated.", ); } else { try { // Create user using the serverClient. await serverClient.upsertUser({ id: context.auth.uid, name: context.auth.token.name, email: context.auth.token.email, image: context.auth.token.image, }); /// Create and return user auth token. return serverClient.createToken(context.auth.uid); } catch (err) { console.error( `Unable to create user with ID ${context.auth.uid} on Stream. Error ${err}`, ); // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "aborted", "Could not create Stream user", ); } } }, ); // Get Stream user token. exports.getStreamUserToken = functions.https.onCall((data, context) => { // Checking that the user is authenticated. if (!context.auth) { // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "failed-precondition", "The function must be called " + "while authenticated.", ); } else { try { return serverClient.createToken(context.auth.uid); } catch (err) { console.error( `Unable to get user token with ID ${context.auth.uid} on Stream. Error ${err}`, ); // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "aborted", "Could not get Stream user", ); } } }); // Revoke the authenticated user's Stream chat token. exports.revokeStreamUserToken = functions.https.onCall((data, context) => { // Checking that the user is authenticated. if (!context.auth) { // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "failed-precondition", "The function must be called " + "while authenticated.", ); } else { try { return serverClient.revokeUserToken(context.auth.uid); } catch (err) { console.error( `Unable to revoke user token with ID ${context.auth.uid} on Stream. Error ${err}`, ); // Throwing an HttpsError so that the client gets the error details. throw new functions.https.HttpsError( "aborted", "Could not get Stream user", ); } } }); ``` -------------------------------- ### Using useSelectedChannelState to Get Member Count Source: https://getstream.io/chat/docs/sdk/react-native/hooks/channel-state/use-selected-channel-state.md This example demonstrates how to use the `useSelectedChannelState` hook to retrieve the member count of a channel. It specifies the channel, a selector function to extract `member_count`, and the event key 'channel.updated' to trigger re-renders when the channel is updated. ```tsx import { useSelectedChannelState } from "stream-chat-react-native"; const memberCount = useSelectedChannelState({ channel, selector: (channel) => channel.data?.member_count ?? 0, stateChangeEventKeys: ["channel.updated"], }); ``` -------------------------------- ### Provide Custom Audio Player Configuration Source: https://getstream.io/chat/docs/sdk/ios/uikit/components/voice-recording.md Example of providing a custom audio player with a custom audio session configuration. This allows for modifications like forcing audio playback through the speaker. ```swift final class CustomAudioPlayer: StreamAudioQueuePlayer { required convenience init() { self.init( assetPropertyLoader: StreamAssetPropertyLoader(), audioSessionConfigurator: CustomAudioSessionConfigurator() ) } } Components.default.audioPlayer = CustomAudioPlayer.self ``` -------------------------------- ### Create Custom Audio Player UI Source: https://getstream.io/chat/docs/sdk/react/guides/audio-playback.md Build a custom audio player component that requests an `AudioPlayer` instance using the `useAudioPlayer` hook. Ensure a stable `requester` ID (e.g., message ID) to get a persistent player instance. This example demonstrates requesting player state and controlling playback. ```tsx import type { AudioPlayer, AudioPlayerDescriptor, AudioPlayerState, } from "stream-chat-react"; import { FileSizeIndicator, PlayButton, PlaybackRateButton, useAudioPlayer, useStateStore, WaveProgressBar, } from "stream-chat-react"; // Provide a stable ID so you get a stable AudioPlayer instance // (for example: message ID + parent ID or any other stable key). import { useStableComponentId } from "./useStableComponentId"; import { FileIcon } from "stream-chat-react"; type AudioPlayerComponentProps = Omit & { playbackRates: number[]; }; const AudioPlayerComponent = (props: AudioPlayerComponentProps) => { const componentID = useStableComponentId(); // Retrieve the AudioPlayer instance. const audioPlayer = useAudioPlayer({ durationSeconds: props.durationSeconds, fileSize: props.fileSize, mimeType: props.mimeType, playbackRates: props.playbackRates, requester: componentID, src: props.src, title: props.title, waveformData: props.waveformData, }); return audioPlayer ? : null; }; type AudioPlayerUIProps = { audioPlayer: AudioPlayer; }; // Select the data you need from AudioPlayer state. const audioPlayerStateSelector = (state: AudioPlayerState) => ({ canPlayRecord: state.canPlayRecord, isPlaying: state.isPlaying, playbackRate: state.currentPlaybackRate, progress: state.progressPercent, secondsElapsed: state.secondsElapsed, }); const AudioPlayerUI = ({ audioPlayer }: AudioPlayerUIProps) => { // Subscribe to AudioPlayer state changes. const { canPlayRecord, isPlaying, playbackRate, progress, secondsElapsed } = useStateStore(audioPlayer.state, audioPlayerStateSelector); const displayedDuration = secondsElapsed || audioPlayer.durationSeconds; return (
{audioPlayer.title && (
{audioPlayer.title}
)} {typeof displayedDuration === "number" && (
{displayedDuration}
)} {typeof audioPlayer.fileSize !== "undefined" && ( )} {!!audioPlayer.waveformData && ( )} {isPlaying ? ( {playbackRate?.toFixed(1)}x ) : ( )}
); }; ``` -------------------------------- ### Example: Signed URLs with Authentication Headers Source: https://getstream.io/chat/docs/sdk/android/client/guides/custom-cdn.md An example implementation of the `CDN` interface that generates signed URLs and includes an Authorization header. Network calls should be wrapped in `withContext(Dispatchers.IO)`. ```kotlin val myCdn = object : CDN { override suspend fun imageRequest(url: String): CDNRequest = withContext(Dispatchers.IO) { val signedUrl = mySigningService.sign(url) CDNRequest( url = signedUrl, headers = mapOf("Authorization" to "Bearer ${getToken()}") ) } override suspend fun fileRequest(url: String): CDNRequest = withContext(Dispatchers.IO) { val signedUrl = mySigningService.sign(url) CDNRequest( url = signedUrl, headers = mapOf("Authorization" to "Bearer ${getToken()}") ) } } ChatClient.Builder("apiKey", context) .cdn(myCdn) .build() ``` -------------------------------- ### Install @op-engineering/op-sqlite dependency Source: https://getstream.io/chat/docs/sdk/react-native/basics/offline-support.md Install the necessary dependency for offline support and run pod install. Ensure version compatibility with your stream-chat-react-native version. ```bash yarn add @op-engineering/op-sqlite npx pod-install ``` -------------------------------- ### Install Emoji Dependencies Source: https://getstream.io/chat/docs/sdk/react-native/guides/emoji-suggestions.md Install the necessary packages for emoji data and suggestions. ```bash npm install @emoji-mart/data emoji-mart ``` -------------------------------- ### Initialize Chat and Video SDKs Source: https://getstream.io/chat/docs/sdk/android/client/guides/video-integration.md Initialize both the Chat and Video SDKs within your Application class. Ensure you use the same API key, user ID, and user token for both. ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() val apiKey = "your_api_key" val userId = "user_id" val userToken = "user_token" // Initialize Chat SDK initializeChatClient(apiKey, userId, userToken) // Initialize Video SDK initializeStreamVideo(apiKey, userId, userToken) } private fun initializeChatClient(apiKey: String, userId: String, token: String) { val chatClient = ChatClient.Builder(apiKey, this) .config(ChatClientConfig()) .build() val user = User(id = userId) chatClient.connectUser(user, token).enqueue() } private fun initializeStreamVideo(apiKey: String, userId: String, token: String) { val streamVideo = StreamVideoBuilder( context = this, apiKey = apiKey, user = io.getstream.video.android.model.User(id = userId), token = token, ).build() } } ``` -------------------------------- ### Initialize and Bind ViewModels in Java Source: https://getstream.io/chat/docs/sdk/android/ui/guides/building-message-list-screen.md Set up ViewModels for channel header, message list, and message composer using ViewModelProvider, then bind them to their respective views. Observe message list mode changes to update channel header and composer states for threads. ```java ViewModelProvider.Factory factory = new ChannelViewModelFactory.Builder(requireContext()) .cid("messaging:123") .build(); ViewModelProvider provider = new ViewModelProvider(this, factory); ChannelHeaderViewModel channelHeaderViewModel = provider.get(ChannelHeaderViewModel.class); MessageListViewModel messageListViewModel = provider.get(MessageListViewModel.class); MessageComposerViewModel messageComposerViewModel = provider.get(MessageComposerViewModel.class); ChannelHeaderViewModelBinding.bind(channelHeaderViewModel, channelHeaderView, getViewLifecycleOwner()); MessageListViewModelBinding.bind(messageListViewModel, messageListView, getViewLifecycleOwner()); MessageComposerViewModelBinder.with(messageComposerViewModel).bind(messageComposerView, getViewLifecycleOwner()); messageListViewModel.getMode().observe(getViewLifecycleOwner(), mode -> { if (mode instanceof MessageMode.MessageThread) { Message parentMessage = ((MessageMode.MessageThread) mode).getParentMessage(); channelHeaderViewModel.setActiveThread(parentMessage); messageComposerViewModel.setMessageMode(new MessageMode.MessageThread(parentMessage, null)); } else if (mode instanceof MessageMode.Normal) { channelHeaderViewModel.resetThread(); messageComposerViewModel.leaveThread(); } }); ``` -------------------------------- ### Basic MessageListCore Example Source: https://getstream.io/chat/docs/sdk/flutter/stream-chat-flutter-core/message-list-core.md Demonstrates how to use MessageListCore to fetch and display messages with custom UI builders for different states. Ensure a StreamChannel ancestor is present. ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ super.key, }); @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded( child: MessageListCore( emptyBuilder: (context) { return const Center( child: Text('Nothing here...'), ); }, loadingBuilder: (context) { return const Center( child: CircularProgressIndicator(), ); }, messageListBuilder: (context, list) { return MessagesPage(list); }, errorBuilder: (context, err) { return const Center( child: Text('Error'), ); }, ), ), ], ), ); } } ``` -------------------------------- ### Install OP SQLite for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install the @op-engineering/op-sqlite package for offline support in Expo projects. ```bash npx expo install @op-engineering/op-sqlite ``` -------------------------------- ### Complete Push Notification Configuration (Kotlin) Source: https://getstream.io/chat/docs/sdk/android/client/guides/push-notifications.md An example demonstrating the configuration of all push notification properties in Kotlin, including WebSocket behavior, runtime control, permission management, and advanced features. ```kotlin val notificationConfig = NotificationConfig( // WebSocket connection behavior ignorePushMessageWhenUserOnline = { type -> when (type) { ChatNotification.TYPE_MESSAGE_NEW -> true ChatNotification.TYPE_NOTIFICATION_REMINDER_DUE -> false else -> true } }, // Runtime notification control shouldShowNotificationOnPush = { val currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) currentHour in 8..22 }, // Permission management requestPermissionOnAppLaunch = { true }, // Advanced features autoTranslationEnabled = true, ) ChatClient.Builder("api-key", context) .notifications(notificationConfig, notificationHandler) .build() ``` -------------------------------- ### Initialize Audio Player with URL Source: https://getstream.io/chat/docs/sdk/react-native/guides/audio-playback.md Initialize the audio player by providing a URL to the audio source. This is the common method for web-based audio sources. ```typescript await audioPlayer.initPlayer({ url: "https://example.com/audio.mp3" }); ``` -------------------------------- ### Install expo-video for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency to enable video playing capabilities in your Expo application. ```bash npx expo install expo-video ``` -------------------------------- ### Install react-native-safe-area-context for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency if you are using React Navigation and need SafeAreaProvider and useSafeAreaInsets. ```bash npx expo install react-native-safe-area-context ``` -------------------------------- ### Get Channel Members with useChannelMembersState Source: https://getstream.io/chat/docs/sdk/react-native/hooks/channel-list/use-channel-members-state.md Import and use the useChannelMembersState hook to get the members of a channel. Calculate the member count by getting the length of the keys in the returned members object. Handle the case where members might be undefined. ```tsx import { useChannelMembersState } from "stream-chat-react-native"; const members = useChannelMembersState(channel); const memberCount = Object.keys(members ?? {}).length; ``` -------------------------------- ### Input Component Usage Source: https://getstream.io/chat/docs/sdk/react-native/ui-components/base-ui/input.md Demonstrates basic usage of the Input component with title, description, and placeholder. ```APIDOC ## Input Component ### Description The `Input` component is a theme-aware text input that supports titles, descriptions, helper text, validation states, and leading/trailing icons. It enhances React Native's `TextInput` with additional UI elements for forms. ### Usage Example ```tsx import { Input } from "stream-chat-react-native"; ; ``` ### Props `Input` extends `TextInputProps` from React Native. | Prop | Description | Type | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | | `variant` (required) | The visual variant of the input container. `'outline'`: input with a visible border, `'ghost'`: input with no border or background. | `'outline'` \| `'ghost'` | | `title` | Label text displayed above the input. | `string` | | `description` | Descriptive text displayed below the title and above the input field. | `string` | | `LeadingIcon` | A render function for the icon displayed on the leading side (left in LTR, right in RTL) of the input. | `(props: IconProps) => ReactNode` | | `TrailingIcon` | A render function for the icon displayed on the trailing side (right in LTR, left in RTL) of the input. | `(props: IconProps) => ReactNode` | | `state` | The current validation state of the input. Controls the visual styling and which helper message is displayed. Defaults to `'default'`. | `'default'` \| `'error'` \| `'success'` | | `helperText` | Whether to show the helper text area below the input. When `false`, the error/success/info messages are hidden. Defaults to `true`. | `boolean` | | `errorMessage` | Message displayed below the input when `state` is `'error'`. | `string` | | `successMessage` | Message displayed below the input when `state` is `'success'`. | `string` | | `infoText` | Message displayed below the input when `state` is `'default'`. | `string` | | `editable` | Whether the input is editable. Defaults to `true`. | `boolean` | | `containerStyle` | Additional style applied to the outermost container `View` wrapping the title, input, and helper text. | `StyleProp` | ``` -------------------------------- ### Install Expo Dependencies Source: https://getstream.io/chat/docs/sdk/react-native/guides/location-sharing.md Install the Expo location and maps libraries for React Native using Expo. ```bash yarn add expo-location yarn add react-native-maps ``` -------------------------------- ### Install react-native-safe-area-context for RN CLI Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency if you are using React Navigation and need SafeAreaProvider and useSafeAreaInsets. ```bash yarn add react-native-safe-area-context ``` -------------------------------- ### Complete Push Notification Configuration (Java) Source: https://getstream.io/chat/docs/sdk/android/client/guides/push-notifications.md An example demonstrating the configuration of all push notification properties in Java, including WebSocket behavior, runtime control, permission management, and advanced features. ```java NotificationConfig notificationConfig = new NotificationConfig( true, // pushNotificationsEnabled type -> { // ignorePushMessageWhenUserOnline switch (type) { case ChatNotification.TYPE_MESSAGE_NEW: return true; case ChatNotification.TYPE_NOTIFICATION_REMINDER_DUE: return false; default: return true; } }, Collections.singletonList(new FirebasePushDeviceGenerator()), // pushDeviceGenerators () -> { // shouldShowNotificationOnPush Calendar calendar = Calendar.getInstance(); int currentHour = calendar.get(Calendar.HOUR_OF_DAY); return currentHour >= 8 && currentHour <= 22; }, () -> true, // requestPermissionOnAppLaunch false // autoTranslationEnabled ); new ChatClient.Builder("api-key", context) .notifications(notificationConfig, notificationHandler) .build() ``` -------------------------------- ### Initialize and Bind ViewModels in Kotlin Source: https://getstream.io/chat/docs/sdk/android/ui/guides/building-message-list-screen.md Set up ViewModels for channel header, message list, and message composer, then bind them to their respective views. Observe message list mode changes to update channel header and composer states for threads. ```kotlin val factory = ChannelViewModelFactory(context = requireContext(), cid = "messaging:123") val channelHeaderViewModel: ChannelHeaderViewModel by viewModels { factory } val messageListViewModel: MessageListViewModel by viewModels { factory } val messageComposerViewModel: MessageComposerViewModel by viewModels { factory } channelHeaderViewModel.bindView(channelHeaderView, viewLifecycleOwner) messageListViewModel.bindView(messageListView, viewLifecycleOwner) messageComposerViewModel.bindView(messageComposerView, viewLifecycleOwner) messageListViewModel.mode.observe(viewLifecycleOwner) { when (it) { is MessageMode.MessageThread -> { channelHeaderViewModel.setActiveThread(it.parentMessage) messageComposerViewModel.setMessageMode(MessageMode.MessageThread(it.parentMessage)) } is MessageMode.Normal -> { channelHeaderViewModel.resetThread() messageComposerViewModel.leaveThread() } } } ``` -------------------------------- ### Install ngx-popperjs Dependencies Source: https://getstream.io/chat/docs/sdk/angular/code-examples/mention-actions.md Install the necessary dependencies for ngx-popperjs. This command should be run in your project's terminal. ```bash npm install @popperjs/core ngx-popperjs --save ``` -------------------------------- ### Old UserListView Example Source: https://getstream.io/chat/docs/sdk/flutter/v9/guides/migration-guide-4-0.md Demonstrates the previous method of displaying all users using UserListView and UsersBloc. ```dart class UsersExample extends StatelessWidget { const UsersExample({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return UsersBloc( child: UserListView( groupAlphabetically: true, onUserTap: (user, _) { /// Handle on tap }, limit: 25, filter: Filter.and([ Filter.autoComplete('name', 'some-name'), Filter.notEqual('id', StreamChat.of(context).currentUser!.id), ]), sort: const [ SortOption( 'name', direction: 1, ), ], ), ); } } ``` -------------------------------- ### Install Native CLI Dependencies Source: https://getstream.io/chat/docs/sdk/react-native/guides/location-sharing.md Install the geolocation and maps libraries for React Native using the Native CLI. ```bash yarn add @react-native-community/geolocation yarn add react-native-maps ``` -------------------------------- ### Querying Reaction List Source: https://getstream.io/chat/docs/sdk/ios/client/state-layer/state-layer-overview.md Demonstrates how to create a query for reaction lists, load reactions, and access them. ```swift let query = ReactionListQuery( messageId: messageId, filter: .equal(.reactionType, to: "like") ) let reactionList = chatClient.makeReactionList(with: query) // Load reactions for the query try await reactionList.get() // Load more reactions try await reactionList.loadMoreReactions() // All the loaded reactions let users = reactionList.state.reactions ``` -------------------------------- ### Install FlashList for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install the @shopify/flash-list package for your Expo project. This is recommended for optimizing large message lists. ```bash npx expo install @shopify\/flash-list ``` -------------------------------- ### Install attachment sharing dependency for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency for sharing attachments outside the app when using Expo. ```bash npx expo install expo-sharing ``` -------------------------------- ### Provide Custom Audio Recorder Configuration Source: https://getstream.io/chat/docs/sdk/ios/uikit/components/voice-recording.md Example of providing a custom audio recorder with a custom audio session configuration. This can be used to customize audio session behavior during recording. ```swift class CustomAudioRecorder: StreamAudioRecorder { required convenience init() { self.init( configuration: .default, audioSessionConfigurator: CustomAudioSessionConfigurator() ) } } Components.default.audioRecorder = CustomAudioRecorder.self ``` -------------------------------- ### Install expo-av for Expo Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency for microphone access for voice recording when using Expo and the expo-av library. ```bash npx expo install expo-av ``` -------------------------------- ### Define Command Display Info Source: https://getstream.io/chat/docs/sdk/ios/swiftui/chat-channel-components/composer-commands.md Use `CommandDisplayInfo` to set the display name, icon, format, and placeholder for a command. The description is shown in the suggestions list. ```swift let displayInfo = CommandDisplayInfo( displayName: "Pay", icon: UIImage(systemName: "creditcard")!, format: "/pay [@username]", isInstant: true, placeholder: "Enter amount", description: "Send a payment to a user" ) ``` -------------------------------- ### Install react-native-video for RN CLI Source: https://getstream.io/chat/docs/sdk/react-native/basics/installation.md Install this dependency to enable video playing capabilities in your React Native application. ```bash yarn add react-native-video ``` -------------------------------- ### Instantiate ChannelListHeaderViewModel and ChannelListViewModel (Java) Source: https://getstream.io/chat/docs/sdk/android/ui/guides/building-channel-list-screen.md Instantiate the ViewModels for the channel list header and channel list using Java. Configure the ChannelListViewModel with filters, sorting, and limits using the builder pattern. ```java ChannelListHeaderViewModel channelListHeaderViewModel = new ViewModelProvider(this).get(ChannelListHeaderViewModel.class); FilterObject filter = Filters.and( Filters.eq("type", "messaging"), Filters.in("members", Collections.singletonList(ChatClient.instance().getCurrentUser().getId())) ); ViewModelProvider.Factory factory = new ChannelListViewModelFactory.Builder() .filter(filter) .sort(QuerySortByField.descByName("last_updated")) .limit(30) .build(); ChannelListViewModel channelListViewModel = new ViewModelProvider(this, factory).get(ChannelListViewModel.class); ``` -------------------------------- ### Basic Usage Example Source: https://getstream.io/chat/docs/sdk/angular/components/MessageActionsBoxComponent.md Demonstrates how to integrate the `stream-message-actions-box` component into a custom message component. ```APIDOC ## Basic usage A typical use case for the `MessageActionsBox` component would be to use in your custom components that will completely override the message component. ```typescript @Component({ selector: "app-custom-message", template: `
{{ message.text }}
`, }) export class CustomMessageComponent { @Input() message: StreamMessage; @Input() enabledActions: string[]; } ``` ``` -------------------------------- ### Setup Command UI Middlewares Source: https://getstream.io/chat/docs/sdk/react-native/guides/handle-commands-ui.md Set up the necessary middlewares for the command UI in the MessageComposer. This should be done once during client setup. ```tsx import { useEffect } from "react"; import { setupCommandUIMiddlewares } from "stream-chat-react-native"; const App = () => { useEffect(() => { if (!chatClient) { return; } chatClient.setMessageComposerSetupFunction(({ composer }) => { setupCommandUIMiddlewares(composer); }); }, [chatClient]); }; ```