diff --git a/example/src/App.tsx b/example/src/App.tsx index b23a56d..2e772f1 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -24,7 +24,6 @@ import Advanced from './advanced'; import Basic from './basic'; import Client from './components/Client'; const RootStack = createStackNavigator(); -// setDebuggable(!isDebuggable()); const DATA = [Basic, Advanced]; export default function App() { @@ -70,7 +69,9 @@ export default function App() { onPress={() => { setDebuggable(!isDebuggable()); }} - /> + > + Powered by Agora RTM SDK + ); diff --git a/example/src/advanced/ChannelMetadata/index.tsx b/example/src/advanced/ChannelMetadata/index.tsx index c693b62..a1d474e 100644 --- a/example/src/advanced/ChannelMetadata/index.tsx +++ b/example/src/advanced/ChannelMetadata/index.tsx @@ -1,6 +1,4 @@ import { - IStreamChannel, - JoinChannelOptions, MetadataItem, MetadataOptions, RTM_CHANNEL_TYPE, @@ -22,8 +20,7 @@ import * as log from '../../utils/log'; export default function ChannelMetadata() { const [loginSuccess, setLoginSuccess] = useState(false); - const [joinSuccess, setJoinSuccess] = useState(false); - const [streamChannel, setStreamChannel] = useState(); + const [subscribeSuccess, setSubscribeSuccess] = useState(false); const [cName, setCName] = useState(Config.channelName); const getChannelMetadataRequestId = useRef(); const setChannelMetadataRequestId = useRef(); @@ -41,25 +38,18 @@ export default function ChannelMetadata() { }) ); - const onJoinResult = useCallback( - ( - requestId: number, - channelName: string, - userId: string, - errorCode: RTM_ERROR_CODE - ) => { - log.info( - 'onJoinResult', + const onSubscribeResult = useCallback( + (requestId: number, channelName: string, errorCode: RTM_ERROR_CODE) => { + log.log( + 'onSubscribeResult', 'requestId', requestId, 'channelName', channelName, - 'userId', - userId, 'errorCode', errorCode ); - setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + setSubscribeSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); }, [] ); @@ -196,47 +186,24 @@ export default function ChannelMetadata() { const client = useRtmClient(); /** - * Step 1-1 : createStreamChannel - */ - const createStreamChannel = () => { - if (joinSuccess) { - log.error('already joined channel'); - return; - } - let result = client.createStreamChannel(cName); - setStreamChannel(result); - }; - - /** - * Step 1-2 : join message channel + * Step 1-1(optional) : subscribe message channel */ - const join = () => { - if (!streamChannel) { - log.error('please create streamChannel first'); - return; - } - streamChannel.join( - new JoinChannelOptions({ token: Config.appId, withMetadata: true }) - ); + const subscribe = () => { + client.subscribe(Config.channelName, { + withMessage: true, + withMetadata: true, + withPresence: true, + }); }; /** - * Step 1-3 : leave message channel + * Step 1-2 : unsubscribe message channel */ - const leave = () => { - if (streamChannel) { - streamChannel.leave(0); - } + const unsubscribe = () => { + client.unsubscribe(Config.channelName); + setSubscribeSuccess(false); }; - /** - * Step 1-4 : destroyStreamChannel - */ - const destroyStreamChannel = useCallback(() => { - streamChannel?.release(); - setStreamChannel(undefined); - }, [streamChannel]); - /** * Step 2 : setChannelMetadata */ @@ -316,7 +283,7 @@ export default function ChannelMetadata() { }; useEffect(() => { - client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener('onSubscribeResult', onSubscribeResult); client.addEventListener( 'onSetChannelMetadataResult', onSetChannelMetadataResult @@ -336,7 +303,7 @@ export default function ChannelMetadata() { client?.addEventListener('onStorageEvent', onStorageEvent); return () => { - client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener('onSubscribeResult', onSubscribeResult); client.removeEventListener( 'onSetChannelMetadataResult', onSetChannelMetadataResult @@ -358,7 +325,7 @@ export default function ChannelMetadata() { }, [ client, uid, - onJoinResult, + onSubscribeResult, onSetChannelMetadataResult, onGetChannelMetadataResult, onRemoveChannelMetadataResult, @@ -391,13 +358,12 @@ export default function ChannelMetadata() { RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT ) { setLoginSuccess(false); - destroyStreamChannel(); } - setJoinSuccess(false); + setSubscribeSuccess(false); break; } }, - [destroyStreamChannel] + [] ); useEffect(() => { client?.addEventListener( @@ -422,18 +388,9 @@ export default function ChannelMetadata() { /> { - streamChannel ? destroyStreamChannel() : createStreamChannel(); - }} - /> - { - joinSuccess ? leave() : join(); + subscribeSuccess ? unsubscribe() : subscribe(); }} /> (); + const [subscribeSuccess, setSubscribeSuccess] = useState(false); const [cName, setCName] = useState(Config.channelName); const acquireLockRequestId = useRef(); const setLockRequestId = useRef(); @@ -39,25 +36,18 @@ export default function Lock() { const [lockName, setLockName] = useState('lock-test'); const [ttl, setTtl] = useState(10); - const onJoinResult = useCallback( - ( - requestId: number, - channelName: string, - userId: string, - errorCode: RTM_ERROR_CODE - ) => { - log.info( - 'onJoinResult', + const onSubscribeResult = useCallback( + (requestId: number, channelName: string, errorCode: RTM_ERROR_CODE) => { + log.log( + 'onSubscribeResult', 'requestId', requestId, 'channelName', channelName, - 'userId', - userId, 'errorCode', errorCode ); - setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + setSubscribeSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); }, [] ); @@ -87,7 +77,7 @@ export default function Lock() { errorDetails ); if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { - log.error(`acquire lock failed`, `errorCode: ${errorCode}`); + log.error(`acquire lock failed: errorCode: ${errorCode}`); } }, [] @@ -141,7 +131,7 @@ export default function Lock() { errorCode ); if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { - log.error(`setLock failed`, `errorCode: ${errorCode}`); + log.error(`setLock failed: errorCode: ${errorCode}`); } }, [] @@ -169,7 +159,7 @@ export default function Lock() { errorCode ); if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { - log.error(`revokeLock failed`, `errorCode: ${errorCode}`); + log.error(`revokeLock failed: errorCode: ${errorCode}`); } }, [] @@ -197,7 +187,7 @@ export default function Lock() { errorCode ); if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { - log.error(`removeLock failed`, `errorCode: ${errorCode}`); + log.error(`removeLock failed: errorCode: ${errorCode}`); } }, [] @@ -243,49 +233,26 @@ export default function Lock() { const client = useRtmClient(); /** - * Step 1-1 : createStreamChannel - */ - const createStreamChannel = () => { - if (joinSuccess) { - log.error('already joined channel'); - return; - } - let result = client.createStreamChannel(cName); - setStreamChannel(result); - }; - - /** - * Step 1-2 : join message channel + * Step 1-1(optional) : subscribe message channel */ - const join = () => { - if (!streamChannel) { - log.error('please create streamChannel first'); - return; - } - streamChannel.join( - new JoinChannelOptions({ token: Config.appId, withMetadata: true }) - ); + const subscribe = () => { + client.subscribe(Config.channelName, { + withMessage: true, + withMetadata: true, + withPresence: true, + }); }; /** - * Step 1-3 : leave message channel + * Step 1-2 : unsubscribe message channel */ - const leave = () => { - if (streamChannel) { - streamChannel.leave(0); - } + const unsubscribe = () => { + client.unsubscribe(Config.channelName); + setSubscribeSuccess(false); }; /** - * Step 1-4 : destroyStreamChannel - */ - const destroyStreamChannel = useCallback(() => { - streamChannel?.release(); - setStreamChannel(undefined); - }, [streamChannel]); - - /** - * Step 1-4 : getLocks + * Step 1-3 : getLocks */ const getLocks = () => { getLocksRequestId.current = client @@ -349,7 +316,7 @@ export default function Lock() { }; useEffect(() => { - client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener('onSubscribeResult', onSubscribeResult); client.addEventListener('onSetLockResult', onSetLockResult); client?.addEventListener('onAcquireLockResult', onAcquireLockResult); client?.addEventListener('onReleaseLockResult', onReleaseLockResult); @@ -358,7 +325,7 @@ export default function Lock() { client?.addEventListener('onGetLocksResult', onGetLocksResult); return () => { - client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener('onSubscribeResult', onSubscribeResult); client.removeEventListener('onSetLockResult', onSetLockResult); client?.removeEventListener('onAcquireLockResult', onAcquireLockResult); client?.removeEventListener('onReleaseLockResult', onReleaseLockResult); @@ -369,7 +336,7 @@ export default function Lock() { }, [ client, uid, - onJoinResult, + onSubscribeResult, onSetLockResult, onAcquireLockResult, onReleaseLockResult, @@ -403,13 +370,12 @@ export default function Lock() { RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT ) { setLoginSuccess(false); - destroyStreamChannel(); } - setJoinSuccess(false); + setSubscribeSuccess(false); break; } }, - [destroyStreamChannel] + [] ); useEffect(() => { client?.addEventListener( @@ -434,18 +400,9 @@ export default function Lock() { /> { - streamChannel ? destroyStreamChannel() : createStreamChannel(); - }} - /> - { - joinSuccess ? leave() : join(); + subscribeSuccess ? unsubscribe() : subscribe(); }} /> (Config.channelName); const [uid, setUid] = useState(Config.uid); const [searchUid, setSearchUid] = useState(Config.uid); - const [feeling, setFeeling] = useState('happy'); - const [location, setLocation] = useState('tokyo'); + const [stateKey, setStateKey] = useState('test state'); + const [stateValue, setStateValue] = useState('test state value'); const onSubscribeResult = useCallback( (requestId: number, channelName: string, errorCode: RTM_ERROR_CODE) => { @@ -309,17 +303,15 @@ export default function Presence() { * Step 4 : setState */ const setState = () => { - setStateRequestId.current = client - .getPresence() - .setState( - cName, - RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_MESSAGE, - [ - new StateItem({ key: 'feeling', value: feeling }), - new StateItem({ key: 'location', value: location }), - ], - 1 - ); + setStateRequestId.current = client.getPresence().setState( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_MESSAGE, + [ + new StateItem({ key: stateKey, value: stateValue }), + // new StateItem({ key: 'location', value: location }), + ], + 1 + ); }; /** @@ -496,21 +488,19 @@ export default function Presence() { }} /> - { - setLocation(value); + { + setStateKey(text); }} /> { - setFeeling(text); + setStateValue(text); }} - label="How do you feel now?" - value={feeling} + label="input state value" + value={stateValue} /> (); + const [cName, setCName] = useState(Config.channelName); + const getChannelMetadataRequestId = useRef(); + const setChannelMetadataRequestId = useRef(); + const removeChannelMetadataRequestId = useRef(); + const updateChannelMetadataRequestId = useRef(); + const [uid, setUid] = useState(Config.uid); + const [metadataKey, setMetadataKey] = useState('channel notice'); + const [metadataValue, setMetadataValue] = useState('rtm test'); + + const metadata = useRef( + new RtmMetadata({ + majorRevision: -1, + metadataItems: [], + metadataItemsSize: 0, + }) + ); + + const onJoinResult = useCallback( + ( + requestId: number, + channelName: string, + userId: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onJoinResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'userId', + userId, + 'errorCode', + errorCode + ); + setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + }, + [] + ); + + const onGetChannelMetadataResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + data: RtmMetadata, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onGetChannelMetadataResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'data', + data, + 'errorCode', + errorCode + ); + if ( + requestId === getChannelMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`${channelName} metadata:`, `${JSON.stringify(data)}`); + metadata.current = data; + } + }, + [] + ); + + const onSetChannelMetadataResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onSetChannelMetadataResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'errorCode', + errorCode + ); + if ( + requestId === setChannelMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`setChannelMetadata success`, `channelName: ${channelName}`); + } + }, + [] + ); + + const onRemoveChannelMetadataResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onRemoveChannelMetadataResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'errorCode', + errorCode + ); + if ( + requestId === removeChannelMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert( + `removeChannelMetadata success`, + `channelName: ${channelName}` + ); + } + }, + [] + ); + + const onUpdateChannelMetadataResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onUpdateChannelMetadataResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'errorCode', + errorCode + ); + if ( + requestId === updateChannelMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert( + `updateChannelMetadata success`, + `channelName: ${channelName}` + ); + } + }, + [] + ); + + const onStorageEvent = useCallback((event: StorageEvent) => { + log.log('onStorageEvent', 'event', event); + }, []); + + /** + * Step 1: getRtmClient and initialize rtm client from BaseComponent + */ + const client = useRtmClient(); + + /** + * Step 1-1 : createStreamChannel + */ + const createStreamChannel = () => { + if (joinSuccess) { + log.error('already joined channel'); + return; + } + let result = client.createStreamChannel(cName); + setStreamChannel(result); + }; + + /** + * Step 1-2 : join message channel + */ + const join = () => { + if (!streamChannel) { + log.error('please create streamChannel first'); + return; + } + streamChannel.join( + new JoinChannelOptions({ token: Config.appId, withMetadata: true }) + ); + }; + + /** + * Step 1-3 : leave message channel + */ + const leave = () => { + if (streamChannel) { + streamChannel.leave(0); + } + }; + + /** + * Step 1-4 : destroyStreamChannel + */ + const destroyStreamChannel = useCallback(() => { + streamChannel?.release(); + setStreamChannel(undefined); + }, [streamChannel]); + + /** + * Step 2 : setChannelMetadata + */ + const setChannelMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + setChannelMetadataRequestId.current = client + .getStorage() + .setChannelMetadata( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, + metadata.current, + new MetadataOptions({ recordUserId: true }), + '' + ); + }; + + /** + * Step 3 : getChannelMetadata + */ + const getChannelMetadata = () => { + getChannelMetadataRequestId.current = client + .getStorage() + .getChannelMetadata(cName, RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM); + }; + + /** + * Step 4 : updateChannelMetadata + */ + const updateChannelMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + updateChannelMetadataRequestId.current = client + .getStorage() + .updateChannelMetadata( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, + metadata.current, + new MetadataOptions({ recordUserId: true }), + '' + ); + }; + + /** + * Step 5 : removeChannelMetadata + */ + const removeChannelMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + removeChannelMetadataRequestId.current = client + .getStorage() + .removeChannelMetadata( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, + metadata.current, + new MetadataOptions({ recordUserId: true }), + '' + ); + }; + + useEffect(() => { + client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener( + 'onSetChannelMetadataResult', + onSetChannelMetadataResult + ); + client?.addEventListener( + 'onGetChannelMetadataResult', + onGetChannelMetadataResult + ); + client?.addEventListener( + 'onRemoveChannelMetadataResult', + onRemoveChannelMetadataResult + ); + client?.addEventListener( + 'onUpdateChannelMetadataResult', + onUpdateChannelMetadataResult + ); + client?.addEventListener('onStorageEvent', onStorageEvent); + + return () => { + client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener( + 'onSetChannelMetadataResult', + onSetChannelMetadataResult + ); + client?.removeEventListener( + 'onGetChannelMetadataResult', + onGetChannelMetadataResult + ); + client?.removeEventListener( + 'onRemoveChannelMetadataResult', + onRemoveChannelMetadataResult + ); + client?.removeEventListener( + 'onUpdateChannelMetadataResult', + onUpdateChannelMetadataResult + ); + client?.removeEventListener('onStorageEvent', onStorageEvent); + }; + }, [ + client, + uid, + onJoinResult, + onSetChannelMetadataResult, + onGetChannelMetadataResult, + onRemoveChannelMetadataResult, + onUpdateChannelMetadataResult, + onStorageEvent, + ]); + + const onConnectionStateChanged = useCallback( + ( + channelName: string, + state: RTM_CONNECTION_STATE, + reason: RTM_CONNECTION_CHANGE_REASON + ) => { + log.log( + 'onConnectionStateChanged', + 'channelName', + channelName, + 'state', + state, + 'reason', + reason + ); + switch (state) { + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_CONNECTED: + setLoginSuccess(true); + break; + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_DISCONNECTED: + if ( + reason === + RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT + ) { + setLoginSuccess(false); + destroyStreamChannel(); + } + setJoinSuccess(false); + break; + } + }, + [destroyStreamChannel] + ); + useEffect(() => { + client?.addEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + + return () => { + client?.removeEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + }; + }, [client, uid, onConnectionStateChanged]); + + return ( + <> + + setCName(v)} + onUidChanged={(v) => setUid(v)} + /> + { + streamChannel ? destroyStreamChannel() : createStreamChannel(); + }} + /> + { + joinSuccess ? leave() : join(); + }} + /> + { + setMetadataKey(text); + }} + label="metadata key" + value={metadataKey} + /> + { + setMetadataValue(text); + }} + label="metadata value" + value={metadataValue} + /> + { + setChannelMetadata(); + }} + /> + { + getChannelMetadata(); + }} + /> + { + updateChannelMetadata(); + }} + /> + { + removeChannelMetadata(); + }} + /> + + + ); +} diff --git a/example/src/advanced/StreamChannelLock/index.tsx b/example/src/advanced/StreamChannelLock/index.tsx new file mode 100644 index 0000000..dbd7764 --- /dev/null +++ b/example/src/advanced/StreamChannelLock/index.tsx @@ -0,0 +1,520 @@ +import { + IStreamChannel, + JoinChannelOptions, + LockDetail, + RTM_CHANNEL_TYPE, + RTM_CONNECTION_CHANGE_REASON, + RTM_CONNECTION_STATE, + RTM_ERROR_CODE, +} from 'agora-react-native-rtm'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; + +import { ScrollView } from 'react-native'; + +import BaseComponent from '../../components/BaseComponent'; +import { + AgoraButton, + AgoraStyle, + AgoraText, + AgoraTextInput, +} from '../../components/ui'; +import Config from '../../config/agora.config'; +import { useRtmClient } from '../../hooks/useRtmClient'; +import * as log from '../../utils/log'; + +export default function StreamChannelLock() { + const [loginSuccess, setLoginSuccess] = useState(false); + const [joinSuccess, setJoinSuccess] = useState(false); + const [streamChannel, setStreamChannel] = useState(); + const [cName, setCName] = useState(Config.channelName); + const acquireLockRequestId = useRef(); + const setLockRequestId = useRef(); + const getLocksRequestId = useRef(); + const releaseLockRequestId = useRef(); + const revokeLockRequestId = useRef(); + const removeLockRequestId = useRef(); + const [uid, setUid] = useState(Config.uid); + const [lockDetailList, setLockDetailList] = useState([]); + + const [lockName, setLockName] = useState('lock-test'); + const [ttl, setTtl] = useState(10); + + const onJoinResult = useCallback( + ( + requestId: number, + channelName: string, + userId: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onJoinResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'userId', + userId, + 'errorCode', + errorCode + ); + setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + }, + [] + ); + + const onAcquireLockResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockName: string, + errorCode: RTM_ERROR_CODE, + errorDetails: string + ) => { + log.info( + 'onAcquireLockResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'lockName', + _lockName, + 'errorCode', + errorCode, + 'errorDetails', + errorDetails + ); + if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { + log.error(`acquire lock failed: errorCode: ${errorCode}`); + } + }, + [] + ); + + const onReleaseLockResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockName: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onAcquireLockResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'lockName', + _lockName, + 'errorCode', + errorCode + ); + }, + [] + ); + + const onSetLockResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockName: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onSetLockResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'errorCode', + 'lockName', + _lockName, + 'errorCode', + errorCode + ); + if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { + log.error(`setLock failed: errorCode: ${errorCode}`); + } + }, + [] + ); + + const onRevokeLockResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockName: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onRevokeLockResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'lockName', + _lockName, + 'errorCode', + errorCode + ); + if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { + log.error(`revokeLock failed: errorCode: ${errorCode}`); + } + }, + [] + ); + + const onRemoveLockResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockName: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onRemoveLockResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'lockName', + _lockName, + 'errorCode', + errorCode + ); + if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { + log.error(`removeLock failed: errorCode: ${errorCode}`); + } + }, + [] + ); + + const onGetLocksResult = useCallback( + ( + requestId: number, + channelName: string, + channelType: RTM_CHANNEL_TYPE, + _lockDetailList: LockDetail[], + count: number, + errorCode: RTM_ERROR_CODE + ) => { + log.log( + 'onGetLocksResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'channelType', + channelType, + 'lockDetailList', + _lockDetailList, + 'count', + count, + 'errorCode', + errorCode + ); + if ( + requestId === getLocksRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + setLockDetailList(_lockDetailList); + } + }, + [] + ); + + /** + * Step 1: getRtmClient and initialize rtm client from BaseComponent + */ + const client = useRtmClient(); + + /** + * Step 1-1 : createStreamChannel + */ + const createStreamChannel = () => { + if (joinSuccess) { + log.error('already joined channel'); + return; + } + let result = client.createStreamChannel(cName); + setStreamChannel(result); + }; + + /** + * Step 1-2 : join message channel + */ + const join = () => { + if (!streamChannel) { + log.error('please create streamChannel first'); + return; + } + streamChannel.join( + new JoinChannelOptions({ token: Config.appId, withMetadata: true }) + ); + }; + + /** + * Step 1-3 : leave message channel + */ + const leave = () => { + if (streamChannel) { + streamChannel.leave(0); + } + }; + + /** + * Step 1-4 : destroyStreamChannel + */ + const destroyStreamChannel = useCallback(() => { + streamChannel?.release(); + setStreamChannel(undefined); + }, [streamChannel]); + + /** + * Step 1-4 : getLocks + */ + const getLocks = () => { + getLocksRequestId.current = client + .getLock() + .getLocks(cName, RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM); + }; + + /** + * Step 2 : setLock + */ + const setLock = () => { + setLockRequestId.current = client + .getLock() + .setLock(cName, RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, lockName, ttl); + }; + + /** + * Step 3 : acquireLock + */ + const acquireLock = () => { + acquireLockRequestId.current = client + .getLock() + .acquireLock( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, + lockName, + false + ); + }; + + /** + * Step 4 : releaseLock + */ + const releaseLock = () => { + releaseLockRequestId.current = client + .getLock() + .releaseLock(cName, RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, lockName); + }; + + /** + * Step 5 : revokeLock + */ + const revokeLock = () => { + revokeLockRequestId.current = client + .getLock() + .revokeLock( + cName, + RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, + lockName, + Config.uid + ); + }; + + /** + * Step 5 : removeLock + */ + const removeLock = () => { + removeLockRequestId.current = client + .getLock() + .removeLock(cName, RTM_CHANNEL_TYPE.RTM_CHANNEL_TYPE_STREAM, lockName); + }; + + useEffect(() => { + client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener('onSetLockResult', onSetLockResult); + client?.addEventListener('onAcquireLockResult', onAcquireLockResult); + client?.addEventListener('onReleaseLockResult', onReleaseLockResult); + client?.addEventListener('onRevokeLockResult', onRevokeLockResult); + client?.addEventListener('onRemoveLockResult', onRemoveLockResult); + client?.addEventListener('onGetLocksResult', onGetLocksResult); + + return () => { + client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener('onSetLockResult', onSetLockResult); + client?.removeEventListener('onAcquireLockResult', onAcquireLockResult); + client?.removeEventListener('onReleaseLockResult', onReleaseLockResult); + client?.removeEventListener('onRevokeLockResult', onRevokeLockResult); + client?.removeEventListener('onRemoveLockResult', onRemoveLockResult); + client?.removeEventListener('onGetLocksResult', onGetLocksResult); + }; + }, [ + client, + uid, + onJoinResult, + onSetLockResult, + onAcquireLockResult, + onReleaseLockResult, + onRevokeLockResult, + onRemoveLockResult, + onGetLocksResult, + ]); + + const onConnectionStateChanged = useCallback( + ( + channelName: string, + state: RTM_CONNECTION_STATE, + reason: RTM_CONNECTION_CHANGE_REASON + ) => { + log.log( + 'onConnectionStateChanged', + 'channelName', + channelName, + 'state', + state, + 'reason', + reason + ); + switch (state) { + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_CONNECTED: + setLoginSuccess(true); + break; + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_DISCONNECTED: + if ( + reason === + RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT + ) { + setLoginSuccess(false); + destroyStreamChannel(); + } + setJoinSuccess(false); + break; + } + }, + [destroyStreamChannel] + ); + useEffect(() => { + client?.addEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + + return () => { + client?.removeEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + }; + }, [client, uid, onConnectionStateChanged]); + + return ( + <> + + setCName(v)} + onUidChanged={(v) => setUid(v)} + /> + { + streamChannel ? destroyStreamChannel() : createStreamChannel(); + }} + /> + { + joinSuccess ? leave() : join(); + }} + /> + { + setLockName(text); + }} + label="lock name" + value={lockName} + /> + { + if (!text) return; + setTtl(parseInt(text, 10)); + }} + numberKeyboard + label="ttl" + value={ttl.toString()} + /> + { + setLock(); + }} + /> + { + acquireLock(); + }} + /> + { + releaseLock(); + }} + /> + { + revokeLock(); + }} + /> + { + removeLock(); + }} + /> + { + getLocks(); + }} + /> + lockDetailList: + {lockDetailList.map((item) => { + return ( + {`${JSON.stringify( + item + )}`} + ); + })} + + + ); +} diff --git a/example/src/advanced/StreamChannelUserMetadata/index.tsx b/example/src/advanced/StreamChannelUserMetadata/index.tsx new file mode 100644 index 0000000..685770d --- /dev/null +++ b/example/src/advanced/StreamChannelUserMetadata/index.tsx @@ -0,0 +1,519 @@ +import { + IStreamChannel, + JoinChannelOptions, + MetadataItem, + MetadataOptions, + RTM_CONNECTION_CHANGE_REASON, + RTM_CONNECTION_STATE, + RTM_ERROR_CODE, + RtmMetadata, + StorageEvent, +} from 'agora-react-native-rtm'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; + +import { ScrollView } from 'react-native'; + +import BaseComponent from '../../components/BaseComponent'; +import { AgoraButton, AgoraStyle, AgoraTextInput } from '../../components/ui'; +import Config from '../../config/agora.config'; +import { useRtmClient } from '../../hooks/useRtmClient'; +import * as log from '../../utils/log'; + +export default function StreamChannelUserMetadata() { + const [loginSuccess, setLoginSuccess] = useState(false); + const [joinSuccess, setJoinSuccess] = useState(false); + const [subscribeSuccess, setSubscribeSuccess] = useState(false); + const [streamChannel, setStreamChannel] = useState(); + const [cName, setCName] = useState(Config.channelName); + const getUserMetadataRequestId = useRef(); + const setUserMetadataRequestId = useRef(); + const removeUserMetadataRequestId = useRef(); + const updateUserMetadataRequestId = useRef(); + const subscribeUserMetadataRequestId = useRef(); + const [uid, setUid] = useState(Config.uid); + const [subscribeUid, setSubscribeUid] = useState('123'); + const [metadataKey, setMetadataKey] = useState('profile'); + const [metadataValue, setMetadataValue] = useState('I am a student'); + + const metadata = useRef( + new RtmMetadata({ + majorRevision: -1, + metadataItems: [], + metadataItemsSize: 0, + }) + ); + + const onJoinResult = useCallback( + ( + requestId: number, + channelName: string, + userId: string, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onJoinResult', + 'requestId', + requestId, + 'channelName', + channelName, + 'userId', + userId, + 'errorCode', + errorCode + ); + setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + }, + [] + ); + + const onGetUserMetadataResult = useCallback( + ( + requestId: number, + userId: string, + data: RtmMetadata, + errorCode: RTM_ERROR_CODE + ) => { + log.info( + 'onGetUserMetadataResult', + 'requestId', + requestId, + 'userId', + userId, + 'data', + data, + 'errorCode', + errorCode + ); + if ( + requestId === getUserMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`${userId} metadata:`, `${JSON.stringify(data)}`); + metadata.current = data; + } + }, + [] + ); + + const onSetUserMetadataResult = useCallback( + (requestId: number, userId: string, errorCode: RTM_ERROR_CODE) => { + log.info( + 'onSetUserMetadataResult', + 'requestId', + requestId, + 'userId', + userId, + 'errorCode', + errorCode + ); + if ( + requestId === setUserMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`setUserMetadata success`, `userId: ${userId}`); + } + }, + [] + ); + + const onRemoveUserMetadataResult = useCallback( + (requestId: number, userId: string, errorCode: RTM_ERROR_CODE) => { + log.info( + 'onRemoveUserMetadataResult', + 'requestId', + requestId, + 'userId', + userId, + 'errorCode', + errorCode + ); + if ( + requestId === removeUserMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`removeUserMetadata success`, `userId: ${userId}`); + } + }, + [] + ); + + const onUpdateUserMetadataResult = useCallback( + (requestId: number, userId: string, errorCode: RTM_ERROR_CODE) => { + log.info( + 'onUpdateUserMetadataResult', + 'requestId', + requestId, + 'userId', + userId, + 'errorCode', + errorCode + ); + if ( + requestId === updateUserMetadataRequestId.current && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + log.alert(`updateUserMetadata success`, `userId: ${userId}`); + } + }, + [] + ); + + const onStorageEvent = useCallback((event: StorageEvent) => { + log.log('onStorageEvent', 'event', event); + }, []); + + const onSubscribeUserMetadataResult = useCallback( + (requestId: number, userId: string, errorCode: RTM_ERROR_CODE) => { + log.log( + 'onSubscribeUserMetadataResult', + 'requestId', + requestId, + 'userId', + userId, + 'errorCode', + errorCode + ); + if ( + subscribeUserMetadataRequestId.current === requestId && + errorCode === RTM_ERROR_CODE.RTM_ERROR_OK + ) { + setSubscribeSuccess(true); + } + }, + [] + ); + + /** + * Step 1: getRtmClient and initialize rtm client from BaseComponent + */ + const client = useRtmClient(); + + /** + * Step 1-1 : createStreamChannel + */ + const createStreamChannel = () => { + if (joinSuccess) { + log.error('already joined channel'); + return; + } + let result = client.createStreamChannel(cName); + setStreamChannel(result); + }; + + /** + * Step 1-2 : join message channel + */ + const join = () => { + if (!streamChannel) { + log.error('please create streamChannel first'); + return; + } + streamChannel.join( + new JoinChannelOptions({ token: Config.appId, withMetadata: true }) + ); + }; + + /** + * Step 1-3 : leave message channel + */ + const leave = () => { + if (streamChannel) { + streamChannel.leave(0); + } + }; + + /** + * Step 1-4 : destroyStreamChannel + */ + const destroyStreamChannel = useCallback(() => { + streamChannel?.release(); + setStreamChannel(undefined); + }, [streamChannel]); + + /** + * Step 2 : setUserMetadata + */ + const setUserMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + setUserMetadataRequestId.current = client + .getStorage() + .setUserMetadata( + Config.uid, + metadata.current, + new MetadataOptions({ recordUserId: true }) + ); + }; + + /** + * Step 3 : getUserMetadata + */ + const getUserMetadata = () => { + getUserMetadataRequestId.current = client + .getStorage() + .getUserMetadata(Config.uid); + }; + + /** + * Step 4 : updateUserMetadata + */ + const updateUserMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + updateUserMetadataRequestId.current = client + .getStorage() + .updateUserMetadata( + Config.uid, + metadata.current, + new MetadataOptions({ recordUserId: true }) + ); + }; + + /** + * Step 5 : removeUserMetadata + */ + const removeUserMetadata = () => { + metadata.current.metadataItems = [ + new MetadataItem({ + key: metadataKey, + value: metadataValue, + authorUserId: Config.uid, + }), + ]; + metadata.current.metadataItemsSize = 1; + removeUserMetadataRequestId.current = client + .getStorage() + .removeUserMetadata( + Config.uid, + metadata.current, + new MetadataOptions({ recordUserId: true }) + ); + }; + + /** + * Step 6 : subscribeUserMetadata + */ + const subscribeUserMetadata = () => { + subscribeUserMetadataRequestId.current = client + .getStorage() + .subscribeUserMetadata(subscribeUid); + }; + + /** + * Step 7 : unsubscribeUserMetadata + */ + const unsubscribeUserMetadata = () => { + let result = client.getStorage().unsubscribeUserMetadata(subscribeUid); + if (result === RTM_ERROR_CODE.RTM_ERROR_OK) { + setSubscribeSuccess(false); + } + }; + + useEffect(() => { + client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener('onSetUserMetadataResult', onSetUserMetadataResult); + client?.addEventListener( + 'onGetUserMetadataResult', + onGetUserMetadataResult + ); + client?.addEventListener( + 'onRemoveUserMetadataResult', + onRemoveUserMetadataResult + ); + client?.addEventListener( + 'onUpdateUserMetadataResult', + onUpdateUserMetadataResult + ); + client?.addEventListener('onStorageEvent', onStorageEvent); + client?.addEventListener( + 'onSubscribeUserMetadataResult', + onSubscribeUserMetadataResult + ); + + return () => { + client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener( + 'onSetUserMetadataResult', + onSetUserMetadataResult + ); + client?.removeEventListener( + 'onGetUserMetadataResult', + onGetUserMetadataResult + ); + client?.removeEventListener( + 'onRemoveUserMetadataResult', + onRemoveUserMetadataResult + ); + client?.removeEventListener( + 'onUpdateUserMetadataResult', + onUpdateUserMetadataResult + ); + client.removeEventListener('onStorageEvent', onStorageEvent); + client.removeEventListener( + 'onSubscribeUserMetadataResult', + onSubscribeUserMetadataResult + ); + }; + }, [ + client, + uid, + onJoinResult, + onSetUserMetadataResult, + onGetUserMetadataResult, + onRemoveUserMetadataResult, + onUpdateUserMetadataResult, + onStorageEvent, + onSubscribeUserMetadataResult, + ]); + + const onConnectionStateChanged = useCallback( + ( + channelName: string, + state: RTM_CONNECTION_STATE, + reason: RTM_CONNECTION_CHANGE_REASON + ) => { + log.log( + 'onConnectionStateChanged', + 'channelName', + channelName, + 'state', + state, + 'reason', + reason + ); + switch (state) { + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_CONNECTED: + setLoginSuccess(true); + break; + case RTM_CONNECTION_STATE.RTM_CONNECTION_STATE_DISCONNECTED: + if ( + reason === + RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT + ) { + setLoginSuccess(false); + setSubscribeSuccess(false); + destroyStreamChannel(); + } + setJoinSuccess(false); + break; + } + }, + [destroyStreamChannel] + ); + useEffect(() => { + client?.addEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + + return () => { + client?.removeEventListener( + 'onConnectionStateChanged', + onConnectionStateChanged + ); + }; + }, [client, uid, onConnectionStateChanged]); + + return ( + <> + + setCName(v)} + onUidChanged={(v) => setUid(v)} + /> + { + streamChannel ? destroyStreamChannel() : createStreamChannel(); + }} + /> + { + joinSuccess ? leave() : join(); + }} + /> + { + setMetadataKey(text); + }} + label="metadata key" + value={metadataKey} + /> + { + setMetadataValue(text); + }} + label="metadata value" + value={metadataValue} + /> + { + setUserMetadata(); + }} + /> + { + getUserMetadata(); + }} + /> + { + updateUserMetadata(); + }} + /> + { + removeUserMetadata(); + }} + /> + { + setSubscribeUid(text); + }} + placeholder="input uid you want to subscribe" + label="subscribeUid" + value={subscribeUid} + disabled={subscribeSuccess} + /> + { + subscribeSuccess + ? unsubscribeUserMetadata() + : subscribeUserMetadata(); + }} + /> + + + ); +} diff --git a/example/src/advanced/UserMetadata/index.tsx b/example/src/advanced/UserMetadata/index.tsx index 4a84897..9d184a5 100644 --- a/example/src/advanced/UserMetadata/index.tsx +++ b/example/src/advanced/UserMetadata/index.tsx @@ -1,6 +1,4 @@ import { - IStreamChannel, - JoinChannelOptions, MetadataItem, MetadataOptions, RTM_CONNECTION_CHANGE_REASON, @@ -21,9 +19,9 @@ import * as log from '../../utils/log'; export default function UserMetadata() { const [loginSuccess, setLoginSuccess] = useState(false); - const [joinSuccess, setJoinSuccess] = useState(false); + const [subscribeUserMetadataSuccess, setSubscribeUserMetadataSuccess] = + useState(false); const [subscribeSuccess, setSubscribeSuccess] = useState(false); - const [streamChannel, setStreamChannel] = useState(); const [cName, setCName] = useState(Config.channelName); const getUserMetadataRequestId = useRef(); const setUserMetadataRequestId = useRef(); @@ -43,25 +41,18 @@ export default function UserMetadata() { }) ); - const onJoinResult = useCallback( - ( - requestId: number, - channelName: string, - userId: string, - errorCode: RTM_ERROR_CODE - ) => { - log.info( - 'onJoinResult', + const onSubscribeResult = useCallback( + (requestId: number, channelName: string, errorCode: RTM_ERROR_CODE) => { + log.log( + 'onSubscribeResult', 'requestId', requestId, 'channelName', channelName, - 'userId', - userId, 'errorCode', errorCode ); - setJoinSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); + setSubscribeSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); }, [] ); @@ -177,7 +168,7 @@ export default function UserMetadata() { subscribeUserMetadataRequestId.current === requestId && errorCode === RTM_ERROR_CODE.RTM_ERROR_OK ) { - setSubscribeSuccess(true); + setSubscribeUserMetadataSuccess(true); } }, [] @@ -189,47 +180,24 @@ export default function UserMetadata() { const client = useRtmClient(); /** - * Step 1-1 : createStreamChannel - */ - const createStreamChannel = () => { - if (joinSuccess) { - log.error('already joined channel'); - return; - } - let result = client.createStreamChannel(cName); - setStreamChannel(result); - }; - - /** - * Step 1-2 : join message channel + * Step 1-1(optional) : subscribe message channel */ - const join = () => { - if (!streamChannel) { - log.error('please create streamChannel first'); - return; - } - streamChannel.join( - new JoinChannelOptions({ token: Config.appId, withMetadata: true }) - ); + const subscribe = () => { + client.subscribe(Config.channelName, { + withMessage: true, + withMetadata: true, + withPresence: true, + }); }; /** - * Step 1-3 : leave message channel + * Step 1-2 : unsubscribe message channel */ - const leave = () => { - if (streamChannel) { - streamChannel.leave(0); - } + const unsubscribe = () => { + client.unsubscribe(Config.channelName); + setSubscribeSuccess(false); }; - /** - * Step 1-4 : destroyStreamChannel - */ - const destroyStreamChannel = useCallback(() => { - streamChannel?.release(); - setStreamChannel(undefined); - }, [streamChannel]); - /** * Step 2 : setUserMetadata */ @@ -317,12 +285,12 @@ export default function UserMetadata() { const unsubscribeUserMetadata = () => { let result = client.getStorage().unsubscribeUserMetadata(subscribeUid); if (result === RTM_ERROR_CODE.RTM_ERROR_OK) { - setSubscribeSuccess(false); + setSubscribeUserMetadataSuccess(false); } }; useEffect(() => { - client.addEventListener('onJoinResult', onJoinResult); + client.addEventListener('onSubscribeResult', onSubscribeResult); client.addEventListener('onSetUserMetadataResult', onSetUserMetadataResult); client?.addEventListener( 'onGetUserMetadataResult', @@ -343,7 +311,7 @@ export default function UserMetadata() { ); return () => { - client.removeEventListener('onJoinResult', onJoinResult); + client.removeEventListener('onSubscribeResult', onSubscribeResult); client.removeEventListener( 'onSetUserMetadataResult', onSetUserMetadataResult @@ -369,7 +337,7 @@ export default function UserMetadata() { }, [ client, uid, - onJoinResult, + onSubscribeResult, onSetUserMetadataResult, onGetUserMetadataResult, onRemoveUserMetadataResult, @@ -403,14 +371,13 @@ export default function UserMetadata() { RTM_CONNECTION_CHANGE_REASON.RTM_CONNECTION_CHANGED_LOGOUT ) { setLoginSuccess(false); - setSubscribeSuccess(false); - destroyStreamChannel(); } - setJoinSuccess(false); + setSubscribeUserMetadataSuccess(false); + setSubscribeSuccess(false); break; } }, - [destroyStreamChannel] + [] ); useEffect(() => { client?.addEventListener( @@ -435,18 +402,9 @@ export default function UserMetadata() { /> { - streamChannel ? destroyStreamChannel() : createStreamChannel(); - }} - /> - { - joinSuccess ? leave() : join(); + subscribeSuccess ? unsubscribe() : subscribe(); }} /> { - subscribeSuccess + subscribeUserMetadataSuccess ? unsubscribeUserMetadata() : subscribeUserMetadata(); }} diff --git a/example/src/advanced/index.ts b/example/src/advanced/index.ts index 838ae07..5e13348 100644 --- a/example/src/advanced/index.ts +++ b/example/src/advanced/index.ts @@ -1,6 +1,9 @@ import ChannelMetadata from './ChannelMetadata'; import Lock from './Lock'; import Presence from './Presence'; +import StreamChannelChannelMetadata from './StreamChannelChannelMetadata'; +import StreamChannelLock from './StreamChannelLock'; +import StreamChannelUserMetadata from './StreamChannelUserMetadata'; import UserMetadata from './UserMetadata'; import PublishMessage from './publishMessage'; import PublishTopicMessage from './publishTopicMessage'; @@ -32,6 +35,18 @@ const Advanced = { name: 'Lock', component: Lock, }, + { + name: 'StreamChannelChannelMetadata', + component: StreamChannelChannelMetadata, + }, + { + name: 'StreamChannelUserMetadata', + component: StreamChannelUserMetadata, + }, + { + name: 'StreamChannelLock', + component: StreamChannelLock, + }, ], }; export default Advanced; diff --git a/example/src/advanced/publishMessage/index.tsx b/example/src/advanced/publishMessage/index.tsx index 2e3bc1c..9a5079e 100644 --- a/example/src/advanced/publishMessage/index.tsx +++ b/example/src/advanced/publishMessage/index.tsx @@ -62,7 +62,7 @@ export default function PublishMessage() { errorCode ); if (errorCode !== RTM_ERROR_CODE.RTM_ERROR_OK) { - log.error('CHANNEL_INVALID_MESSAGE', errorCode); + log.error(`CHANNEL_INVALID_MESSAGE: ${errorCode}`); } else { messages.map((message) => { if (message.requestId === requestId) { diff --git a/example/src/components/BaseComponent.tsx b/example/src/components/BaseComponent.tsx index 355600b..85f6897 100644 --- a/example/src/components/BaseComponent.tsx +++ b/example/src/components/BaseComponent.tsx @@ -1,3 +1,4 @@ +import { useNavigation } from '@react-navigation/native'; import { RTM_ERROR_CODE, RtmConfig } from 'agora-react-native-rtm'; import React, { useCallback, useEffect, useState } from 'react'; @@ -5,6 +6,7 @@ import Config from '../config/agora.config'; import { useRtmClient } from '../hooks/useRtmClient'; import * as log from '../utils/log'; +import { LogSink } from './LogSink'; import { AgoraButton, AgoraStyle, AgoraTextInput, AgoraView } from './ui'; interface Props { @@ -12,6 +14,25 @@ interface Props { onChannelNameChanged?: (value: string) => void; } +const Header = ({ getData }: { getData: () => Array }) => { + const [visible, setVisible] = useState(false); + + const toggleOverlay = () => { + setVisible(!visible); + }; + + return ( + <> + + + + ); +}; + export default function BaseComponent({ onUidChanged, onChannelNameChanged, @@ -20,12 +41,24 @@ export default function BaseComponent({ const [initResult, setInitResult] = useState(0); const [cName, setCName] = useState(Config.channelName); const [uid, setUid] = useState(Config.uid); + const navigation = useNavigation(); const onLoginResult = useCallback((errorCode: RTM_ERROR_CODE) => { log.log('onLoginResult', 'errorCode', errorCode); setLoginSuccess(errorCode === RTM_ERROR_CODE.RTM_ERROR_OK); }, []); + useEffect(() => { + const headerRight = () =>
log.logSink._data} />; + navigation.setOptions({ headerRight }); + }, [navigation]); + + useEffect(() => { + return () => { + log.logSink.clearData(); + }; + }, []); + /** * Step 1: getRtmClient */ diff --git a/example/src/components/LogSink.tsx b/example/src/components/LogSink.tsx index 5594a2e..3ba0e73 100644 --- a/example/src/components/LogSink.tsx +++ b/example/src/components/LogSink.tsx @@ -22,6 +22,7 @@ export const LogSink = ({ visible, data, onBackdropPress }: Props) => { index.toString()} renderItem={({ item }) => {item}} /> diff --git a/example/src/utils/log.ts b/example/src/utils/log.ts index b61b0cc..6dcb3e6 100644 --- a/example/src/utils/log.ts +++ b/example/src/utils/log.ts @@ -1,37 +1,48 @@ import { Alert } from 'react-native'; -export const _logSink = ( - level: 'debug' | 'log' | 'info' | 'warn' | 'error', - message?: any, - ...optionalParams: any[] -): string => { - if (level === 'error' && !__DEV__) { - alert(message); - } else { - console[level](message, ...optionalParams); +class LogSink { + _data: Array = []; + + sink( + level: 'debug' | 'log' | 'info' | 'warn' | 'error', + message?: any, + ...optionalParams: any[] + ): string { + if (level === 'error' && !__DEV__) { + alert(message); + } else { + console[level](message, ...optionalParams); + } + const content = `${optionalParams.map((v) => JSON.stringify(v))}`; + this._data.splice(0, 0, `[${level}] ${message} ${content}`); + return content; } - const content = `${optionalParams.map((v) => JSON.stringify(v))}`; - return content; -}; + + clearData() { + this._data = []; + } +} + +export const logSink = new LogSink(); export const debug = (message?: any, ...optionalParams: any[]): void => { - alert(message, _logSink('debug', message, optionalParams)); + alert(message, logSink.sink('debug', message, optionalParams)); }; export const log = (message?: any, ...optionalParams: any[]): void => { - _logSink('log', message, optionalParams); + logSink.sink('log', message, optionalParams); }; export const info = (message?: any, ...optionalParams: any[]): void => { - _logSink('info', message, optionalParams); + logSink.sink('info', message, optionalParams); }; export const warn = (message?: any, ...optionalParams: any[]): void => { - _logSink('warn', message, optionalParams); + logSink.sink('warn', message, optionalParams); }; export const error = (message?: any, ...optionalParams: any[]): void => { - _logSink('error', message, optionalParams); + logSink.sink('error', message, optionalParams); }; export const alert = (title: string, message?: string): void => {