I need to give option to one attendee to mute all other attendee in amazon chime.I am using amazon-chime-sdk-js.
Currently, there is no for mute/unmute Remote Attendee or mute all/unmute all option available in Amazon Chime SDK But yes we can use real-time messaging to achive this
Add realtimeSubscribeToReceiveDataMessage on {channel-name} so when the user joins the meeting then it will get the message on this channel.
Like mentioned in the below code snip
const realtimeSubscribeToReceiveGeneralDataMessage = async () => {
chime.audioVideo &&
(await chime.audioVideo.realtimeSubscribeToReceiveDataMessage(MessageTopic.GeneralDataMessage, async (data) => {
const receivedData = (data && data.json()) || {};
const { type, attendeeId } = receivedData || {};
if (attendeeId !== chime.attendeeId && type === 'MUTEALL') {
chime.audioVideo && (await chime.audioVideo.realtimeMuteLocalAudio());
} else if (attendeeId !== chime.attendeeId && type === 'STOPALLVIDEO') {
chime.audioVideo && (await chime.audioVideo.stopLocalVideoTile());
}
}));
Where chime.attendeeId is your attendeId and GeneralDataMessage is channel name And you need to add a button for mute all and stop all video
<Button
type="button"
onClick={() => {
chime.sendMessage(MessageTopic.GeneralDataMessage, {
type: 'MUTEALL',
});
}}
>
{'Mute All'}
</Button>
<Button
type="button"
onClick={() => {
chime.sendMessage(MessageTopic.GeneralDataMessage, {
type: 'STOPALLVIDEO',
});
}}
>
{'Stop All Video'}
</Button>
Here is the method to send messages to all remote attendees through the channel
sendMessage = (data) => {
new AsyncScheduler().start(() => {
const payload = {
...data,
attendeeId: this.attendeeId || '',
name: this.rosterName || '',
};
this.audioVideo &&
this.audioVideo.realtimeSendDataMessage(MessageTopic.GeneralDataMessage, payload, ChimeSdkWrapper.DATA_MESSAGE_LIFETIME_MS);
this.publishMessageUpdate(
new DataMessage(
Date.now(),
MessageTopic.GeneralDataMessage,
new TextEncoder().encode(payload),
this.meetingSession.configuration.credentials.attendeeId || '',
this.meetingSession.configuration.credentials.externalUserId || '',
),
);
});
Here is the refrence question : click here
Related
I want to get AutoComplete onChange data. I got data from onChange((e,value) => console.log(value).
But how to put data on State .
This AutoComplete component behaviour is (Creatable and selectable) . I got all data on onChange but on in the state, If I set the data on State , selectOnFocus is not working.
How to get rid of that?
Thank you
`
<Autocomplete
multiple
limitTags={5}
onChange={(event, newValue) => {
setToEmails(newValue);
}}
filterOptions={(options, params) => {
const filtered = filter(options, params);
if (params.inputValue !== "") {
filtered.push({
inputValue: params.inputValue,
label: `Add "${params.inputValue}"`,
value: nanoid(7),
});
}
return filtered;
}}
selectOnFocus
blurOnSelect
clearOnBlur
handleHomeEndKeys
id="free-solo-with-text-demo"
options={toBlockers}
getOptionLabel={(option) => {
if (typeof option === "string") {
return option;
}
if (option.inputValue) {
return option.inputValue;
}
return option.label;
}}
renderOption={(option) => option.label}
freeSolo
renderInput={(params) => (
<TextField {...params} label="Blockers" variant="outlined" />
)}
/>
`
If I use this , Selectable is not working.
Later on I got solved by myself . This took about 3 days ,
here is full example of Creatable with selectable with formData thing.
const [toEmails, setToEmails] = useState([]);
//if you want to post this data on formData , you have structured this way
const appendedObject = [
{ label: "_creative", value: "node_process_Lh1L8RsafJbUas" },
{ label: "Azim__bro", value: "node_process_LhL1s8RaafJbUas" },
];
const finalBlockers = [...appendedObject, ...toEmails];
formData.append("attachmentList", []);
console.log({ toEmails, finalBlockers });
if (finalBlockers) {
for (const blocker of finalBlockers) {
console.log({ blocker });
formData.append("blockers", JSON.stringify(blocker));
}
}
<Autocomplete
multiple
limitTags={5}
getOptionSelected={(option, value) => {
const optionTitle =
typeof option === "string" ? option : option.value;
const valueTitle =
typeof value === "string" ? value : value.value;
return optionTitle === valueTitle;
}}
onChange={(event, newValue) => {
if (Array.isArray(newValue)) {
const updatedArrayValue = newValue.filter((e) =>
typeof e === "string" ? e.trim() : e
);
const newArrayValue = [...updatedArrayValue];
const updatedArray = newArrayValue.map((item) => {
if (typeof item === "string") {
const newItem = {};
newItem.label = item;
newItem.value = nanoid(12);
newItem.type = "created";
return newItem;
}
return item;
});
setToEmails(updatedArray);
}
}}
filterOptions={(options, params) => {
const filtered = filter(options, params);
if (params.inputValue !== "") {
filtered.push({
inputValue: params.inputValue,
title: `Add "${params.inputValue}"`,
value: nanoid(12),
type: "created",
});
}
return filtered;
}}
selectOnFocus
clearOnBlur
handleHomeEndKeys
id="free-solo-with-text-demo"
options={toBlockers}
filterSelectedOptions
getOptionLabel={(option) => {
// Value selected with enter, right from the input
if (typeof option === "string") {
return option;
}
// Add "xxx" option created dynamically
if (option.inputValue) {
return option.inputValue;
}
// Regular option
return option.label;
}}
renderOption={(option) => option.label}
freeSolo
renderInput={(params) => (
<TextField {...params} label="Blockers" variant="outlined" />
)}
/>
I want to upload image by Vue 3 and Axios with state. But error is: array to string. I don't know what to do know. Please help me. Thank so much.
HTML:
<input
type='file'
class="hidden"
name="avatar"
id="avatar"
#change="updatePreview"
style="display: none;"
/>
Define State
const state = reactive({
user: {},
updateMovie: {
id: '',
name: '',
image: '',
}
Take file image:
function updatePreview(e) {
if (e.target.files.length === 0) {
return
}
console.log(e)
imageFile.value = e.target.files[0]
state.updateMovie.image = e.target.files[0]
}
const submitModal = (type) => {
if (type === 'edit') {
const form = {
image: state.updateMovie.image,
}
const id = state.updateMovie.id
console.log("form: ", form)
console.log(typeof form.image)
axios.post(`movie/update/${id}`, form)
.then((res) => {
if (res.status === 200) {
const data = res.data.data.movie
})
}
})
}
}
That's all. Now i don't know what to do to send data to axios.
I'm making a poll app, and one of my routes is a GET request to get all the polls.
All i want to do is pass the polls to my dashboard view, and if there are no polls I want to pass the error to the dashboard view also.
I think my current implementation is wrong because if there are no polls the dashboard view receives an empty array not the errors.
I was curious what the best approach would be in this situation.
Thanks
router.get('/dashboard', isAuth, async (req, res) => {
try {
const polls = await Poll.find().populate('user', ['name', 'id']);
res.render('dashboard', {
polls
});
} catch(err) {
res.status(400);
res.render('dashboard', {
error: 'Could not find any polls'
});
}
});
You can throw error if polls is falsy/empty. Like this this:
const getType = element => Object.prototype.toString.call(element);
// Put this function in a helper file and use it throughout the source code
const isEmpty = element => {
if (
// undefined
typeof element === 'undefined' ||
// string
(typeof element === 'string' && element.trim().length == 0) ||
// null
getType(element) === '[object Null]' ||
// object
(getType(element) === '[object Object]' && !Object.keys(element).length) ||
// array
(getType(element) === '[object Array]' && !element.length)
) {
return true;
}
return false;
}
router.get('/dashboard', isAuth, async (req, res) => {
try {
const polls = await Poll.find().populate('user', ['name', 'id']);
if (isEmpty(polls)) {
throw new Error("Could not find any polls");
}
res.render('dashboard', {
polls
});
} catch (err) {
res.status(400);
res.render('dashboard', {
error: 'Could not find any polls'
});
}
});
I am new to react native. I have created a form from where I am sending some data to server. Now I want that to disabled submit button after user click on submit . once user submit data then after He unable to send data. means I want to avoid duplicate entry. please help. thanks. if possible also tell how to do it with functional component too.
here is my code
export default function Add(props) {
const { navigation } = props
const offset = (Platform.OS === 'android') ? -200 : 0;
const [AmazonError, setAmazonError] = useState([]);
const [Amazon, setAmazon] = useState('');
const [AmazonCNError, setAmazonCNError] = useState([]);
const [AmazonCN, setAmazonCN] = useState('');
const [AEPSError, setAEPSError] = useState([]);
const [AEPS, setAEPS] = useState('');
const [DMTError, setDMTError] = useState([]);
const [DMT, setDMT] = useState('');
const [BBPSError, setBBPSError] = useState([]);
const [BBPS, setBBPS] = useState('');
const [leadTagNumber, setLeadTagNumber] = useState([]);
const validateInputs = () => {
if (!Amazon.trim()) {
setAmazonError('Please Fill The Input')
return;
}
if (!AmazonCN.trim()) {
setAmazonCNError('Please Fill The Input')
return;
}
if (!AEPS.trim()) {
setAEPSError('Please Fill The Input')
return;
}
if (!DMT.trim()) {
setDMTError('Please Fill The Input')
return;
}
if (!BBPS.trim()) {
setBBPSError('Please Fill The Input')
return;
}
else
{
//+++++++++++++++++++++++++++++++++=submitting form data to api start+++++++++++++++++++++++++++++++++++
{
const leadTagNumber = props.route.params.leadTagNumber
AsyncStorage.multiGet(["application_id", "created_by",'leadTagNumber']).then(response => {
// console.log(response[0][0]) // Key1
console.log(response[0][1]) // Value1
// console.log(response[1][0]) // Key2
console.log(response[1][1]) // Value2
console.log(leadTagNumber)
fetch('https://xyxtech/Android_API_CI/uploaddata/tbservice_details', {
method: 'POST',
headers: {'Accept': 'application/json, text/plain, */*', "Content-Type": "application/json" },
// We convert the React state to JSON and send it as the POST body
body: JSON.stringify([{ data}])
})
.then((returnValue) => returnValue.json())
.then(function(response) {
console.log(response)
Alert.alert("File uploaded");
return response.json();
});
});
// event.preventDefault();
}
//+++++++++++++++++++++++++++++++++submitting form data to api end++++++++++++++++++++++++++++++++++++++
Alert.alert("success")
return;
//}
}
};
const handleAmazon = (text) => {
setAmazonError('')
setAmazon(text)
}
const handleAmazonCN= (text) => {
setAmazonCNError('')
setAmazonCN(text)
}
const handleAEPS= (text) => {
setAEPSError('')
setAEPS(text)
}
const handleDMT = (text) => {
setDMTError('')
setDMT(text)
}
const handleBBPS = (text) => {
setBBPSError('')
setBBPS(text)
}
return (
<View style={{flex: 1}}>
<ScrollView style={{flex: 1,}} showsVerticalScrollIndicator={false}>
<TextInput
maxLength={30}
placeholder="AEPS (Adhar enabled payment system) *"
style={styles.inputStyle}
onChangeText={(text)=>handleAEPS(text)}
defaultValue={AEPS}
value = {AEPS} />
<Text>{AEPSError}</Text>
</ScrollView>
<Button
style={styles.inputStyleB}
title="Submit"
color="#FF8C00"
onPress={() => validateInputs()}
/>
</View>
)
}
Set new state property to enable/disable button
const [disableButton, setDisableButton] = useState(false);
Now in your button component, add disabled property with disableButton state.
<Button
style={styles.inputStyleB}
title="Submit"
color="#FF8C00"
onPress={() => validateInputs()}
disabled={disableButton}
/>
Disable you button before fetching data
setDisableButton(true) //Add this
const leadTagNumber = props.route.params.leadTagNumber
Incase of fetch error or after fetching is complete, enable button again
setDisabledButton(false)
How we can build Mute/UmMute Remote Attendee in Amazon Chime Sdk with the help of
(https://aws.github.io/amazon-chime-sdk-js/modules/apioverview.html#9-send-and-receive-data-messages-optional ) web sockets to broadcast a message in a meeting.
Currently, there is no option to mute/unmute Remote Attendee in Amazon Chime SDK
But yes we can use real-time messaging for that
Add `realtimeSubscribeToReceiveDataMessage` on attndeeId so when the user joins meeting then it will get the message on this channel.
like mentioned in the below code snip
import { Button } from 'react-bootstrap';
import React, { useContext, useEffect, useState } from 'react';
import getChimeContext from '../context/getChimeContext';
import useRoster from '../hooks/useRoster';
export default function RosterCompoment(props) {
const { realTimeRequestAttendees, leaveMeeting } = props;
const chime = useContext(getChimeContext());
const roster = useRoster();
const [videoAttendees, setVideoAttendees] = useState(new Set());
const [isVideo, setIsVideo] = useState(false);
const realtimeSubscribeToReceiveDataMessage = async () => {
chime.audioVideo &&
(await chime.audioVideo.realtimeSubscribeToReceiveDataMessage(chime.attendeeId, async (data) => {
const receivedData = (data && data.json()) || {};
const { type, name } = receivedData || {};
if ((type === 'UNMUTE' || type === 'VIDEO-ENABLE')) {
return;
}
if (type === 'UNMUTE') {
chime.audioVideo && (await chime.audioVideo.realtimeUnmuteLocalAudio());
} else if (type === 'MUTE') {
chime.audioVideo && (await chime.audioVideo.realtimeMuteLocalAudio());
} else if (type === 'KICK') {
await new Promise((resolve) => setTimeout(resolve, 200));
await chime.chooseVideoInputDevice(null);
chime.audioVideo && (await chime.audioVideo.stopContentShare());
chime.audioVideo && (await chime.audioVideo.stop());
if (leaveMeeting) leaveMeeting(); // You can call leave meeting function here to kick any user
} else if (type === 'VIDEO-DISABLE') {
chime.audioVideo && (await chime.audioVideo.stopLocalVideoTile());
} else if (type === 'VIDEO-ENABLE') {
await chime.chooseVideoInputDevice(chime.currentVideoInputDevice);
chime.audioVideo && (await chime.audioVideo.startLocalVideoTile());
}
}));
};
useEffect(() => {
realtimeSubscribeToReceiveDataMessage();
const tileIds = {};
const realTimeVideoAttendees = new Set();
const removeTileId = (tileId) => {
const removedAttendeeId = tileIds[tileId];
delete tileIds[tileId];
realTimeVideoAttendees.delete(removedAttendeeId);
setVideoAttendees(new Set(realTimeVideoAttendees));
};
chime.audioVideo &&
chime.audioVideo.addObserver({
videoTileDidUpdate: (tileState) => {
if (!tileState.boundAttendeeId || tileState.isContent || !tileState.tileId) {
return;
}
if (tileState.active) {
tileIds[tileState.tileId] = tileState.boundAttendeeId;
realTimeVideoAttendees.add(tileState.boundAttendeeId);
setVideoAttendees(new Set(realTimeVideoAttendees));
} else {
removeTileId(tileState.tileId);
}
},
videoTileWasRemoved: (tileId) => {
removeTileId(tileId);
},
});
}, []);
let attendeeIds;
if (chime.meetingSession && roster) {
attendeeIds = Object.keys(roster).filter((attendeeId) => !!roster[attendeeId].name);
}
return (
<div>
<div className="roster">
{attendeeIds &&
attendeeIds.map((attendeeId) => {
const rosterAttendee = roster[attendeeId];
return (
<div key={attendeeId} className="attendee">
<div className="name">{rosterAttendee.name}</div>
{ realTimeRequestAttendees && realTimeRequestAttendees.has(attendeeId) && (
<div className="">
<a
className="cursor"
onClick={() => {
realTimeRequestAttendees.delete(attendeeId);
chime.sendMessage(attendeeId, {
type: 'ADMIT',
});
}}
>
Answer
</a>
</div>
)}
<a
className="cursor"
onClick={() => {
chime.sendMessage(attendeeId, {
type: 'KICK',
});
}}
>
Remove
</a>
{videoAttendees && (
<div className="video">
<a
className="cursor"
onClick={() => {
chime.sendMessage(attendeeId, {
type: videoAttendees.has(attendeeId) ? 'VIDEO-DISABLE' : 'VIDEO-ENABLE',
});
}
}}
>
{videoAttendees.has(attendeeId) ? (
<i className="fa fa-video-camera" />
) : (
<i className="camera-icon-muted" />
)}
</a>
</div>
)}
{typeof rosterAttendee.muted === 'boolean' && (
<div className="muted">
<a
className="cursor"
onClick={() => {
chime.sendMessage(attendeeId, {
type: rosterAttendee.muted ? 'UNMUTE' : 'MUTE',
});
}}
>
{rosterAttendee.muted ? (
<i className="fa fa-microphone-slash" />
) : (
<i
className={cx(
'fa fa-microphone',
{ 'active-speaker': rosterAttendee.active },
{
'weak-signal': rosterAttendee.signalStrength && rosterAttendee.signalStrength < 50,
},
)}
/>
)}
</a>
</div>
)}
</div>
);
})}
</div>
</div>
);
}
Here is the method to send messages to remote attendees through his/her attndeeId.
sendMessage = (topic, data) => {
new AsyncScheduler().start(() => {
const payload = {
...data,
attendeeId: this.attendeeId || '',
name: this.rosterName || '',
};
this.audioVideo &&
this.audioVideo.realtimeSendDataMessage(topic, payload, ChimeSdkWrapper.DATA_MESSAGE_LIFETIME_MS);
this.publishMessageUpdate(
new DataMessage(
Date.now(),
topic,
new TextEncoder().encode(payload),
this.meetingSession.configuration.credentials.attendeeId || '',
this.meetingSession.configuration.credentials.externalUserId || '',
),
);
});
};```