react twilio video: first joiner screen black on participant join - reactjs

i have made a twillio video app.i can show local video on Laptop website but when i join from another chrome tab or mobile phone chrome browser the video on laptop goes black and only one video is showing whereas both videos should show properly.i am following this tutorial
https://www.twilio.com/blog/build-a-custom-video-chat-app-with-react-and-twilio-programmable-video
here is my code
App.js
import './App.scss';
import React, {Component} from 'react';
import Room from './Components/Room';
const { connect } = require('twilio-video');
const Token = {"identity":"Jose Corkery","token":"...sioAMt4..."}
class App extends Component {
constructor(props) {
super(props)
this.state = {
identity: '',
room: null
}
this.inputRef = React.createRef();
this.joinRoom = this.joinRoom.bind(this);
this.returnToLobby = this.returnToLobby.bind(this);
this.updateIdentity = this.updateIdentity.bind(this);
this.removePlaceholderText = this.removePlaceholderText.bind(this)
}
async joinRoom() {
try {
// const response = Token
// const data = await response.json();
const room = await connect(Token.token, {
name: 'cool-room',
audio: true,
video: true
});
// alert(room)
this.setState({ room: room });
} catch(err) {
alert(err);
}
}
updateIdentity(event) {
this.setState({
identity: event.target.value
});
}
returnToLobby() {
this.setState({ room: null });
}
removePlaceholderText() {
this.inputRef.current.placeholder = '';
}
render() {
const disabled = this.state.identity === '' ? true : false;
return (
<div className="app">
{
this.state.room === null
? <div className="lobby">
<input
ref={this.inputRef}
onClick={this.removePlaceholderText}
placeholder="What's your name?"
onChange={this.updateIdentity}
/>
<button disabled = {disabled} onClick={this.joinRoom}>Join Room</button>
</div>
: <Room returnToLobby={this.returnToLobby} room={this.state.room} />
}
</div>
);
}
}
export default App;
Room.jsx
import React, { Component } from 'react';
import Participant from './Participant';
const { connect } = require('twilio-video');
class Room extends Component {
componentDidMount() {
this.props.room.on('participantConnected', participant => this.addParticipant(participant));
this.props.room.on('participantDisconnected', participant => this.removeParticipant(participant));
window.addEventListener("beforeunload", this.leaveRoom);
}
componentWillUnmount() {
this.leaveRoom();
}
addParticipant(participant) {
console.log(`${participant.identity} has joined the room.`);
alert(`+ Participant : ${participant.identity}`)
this.setState({
remoteParticipants: [...this.state.remoteParticipants, participant]
})
}
removeParticipant(participant) {
alert(`Leaving : ${participant.identity}`)
console.log(`${participant.identity} has left the room`);
this.setState({
remoteParticipants: this.state.remoteParticipants.filter(p => p.identity !== participant.identity)
});
}
leaveRoom() {
this.props.room.disconnect();
this.props.returnToLobby();
}
constructor(props) {
super(props)
this.state = {
remoteParticipants: Array.from(this.props.room.participants.values())
}
this.leaveRoom = this.leaveRoom.bind(this);
}
render() {
return (
<div className="room">
<div className="participants">
<Participant
key={this.props.room.localParticipant.identity}
localParticipant="true"
participant={this.props.room.localParticipant} />
{
this.state.remoteParticipants.map(participant =>
<Participant key={participant.identity} participant={participant} />
)
}
</div>
<button id="leaveRoom" onClick={this.leaveRoom}>Leave Room</button>
</div>
);
}
}
export default Room
Participant.jsx
import React, { Component } from 'react';
import Track from './Track';
const { connect } = require('twilio-video');
class Participant extends Component {
componentDidMount() {
if (!this.props.localParticipant) {
this.props.participant.on('trackSubscribed', track => this.addTrack(track));
}
}
constructor(props) {
super(props);
const existingPublications = Array.from(this.props.participant.tracks.values());
const existingTracks = existingPublications.map(publication => publication.track);
const nonNullTracks = existingTracks.filter(track => track !== null)
this.state = {
tracks: nonNullTracks
}
}
addTrack(track) {
this.setState({
tracks: [...this.state.tracks, track]
});
}
render() {
return (
<div className="participant" id={this.props.participant.identity}>
<div className="identity">{this.props.participant.identity}</div>
{
this.state.tracks.map(track =>
<Track key={track} filter={this.state.filter} track={track}/>)
}
</div>
);
}
}
export default Participant
Track.jsx
import React, { Component } from 'react';
class Track extends Component {
componentDidMount() {
if (this.props.track !== null) {
const child = this.props.track.attach();
this.ref.current.classList.add(this.props.track.kind);
this.ref.current.appendChild(child)
}
}
constructor(props) {
super(props)
this.ref = React.createRef();
}
render() {
return (
<div className="track" ref={this.ref}>
</div>
)
}
}
export default Track
demo:https://android-anime.web.app
i have only two video events onJoin and onLeave do i need additional events ?
what is the solution? if your solution works i will award you best answer.Thanks !!

Related

Play songs one after another with Howler and NextJS

I have a list of songs on github, the goal is to play all songs one by one and post messages in console. But I faced a problem, how to find if the song is finished? Otherwise my code tries to play all songs without waiting the song's end.
import { Howl } from 'howler'
import { useState } from 'react'
export default function PlaySound() {
let [initSong, updatedSong] = useState(0)
const songs = [
'https://raw.githubusercontent.com/Sound/master/play1.mp3',
'https://raw.githubusercontent.com/Sound/master/play2.mp3',
'https://raw.githubusercontent.com/Sound/master/play3.mp3',
'https://raw.githubusercontent.com/Sound/master/play4.mp3',
'https://raw.githubusercontent.com/Sound/master/play5.mp3',
]
var sound = new Howl({
src: songs[initSong],
})
function postAMessage() {
for (let i = 0; i < songs.length; i++) {
if (initSong >= songs.length) return
console.log('New song ' + i)
sound.play()
updatedSong(initSong++)
i++
}
}
return (
<div>
<button onClick={postAMessage}>Play</button>
</div>
)
}
can you try react-Howler
import React from "react";
import ReactHowler from "react-howler";
import Button from "../components/Button";
class OnlyPlayPauseButton extends React.Component {
constructor(props) {
super(props);
this.state = {
playing: false
};
this.handlePlay = this.handlePlay.bind(this);
this.handlePause = this.handlePause.bind(this);
}
handlePlay() {
this.setState({
playing: true
});
}
handlePause() {
this.setState({
playing: false
});
}
render() {
return (
<div>
<ReactHowler
src={["sound.ogg", "sound.mp3"]}
playing={this.state.playing}
/>
<Button onClick={this.handlePlay}>Play</Button>
<Button onClick={this.handlePause}>Pause</Button>
</div>
);
}
}
export default OnlyPlayPauseButton;
refer: https://www.npmjs.com/package/react-howler

condition componentWillUnmount() in reactjs

When clicking on button, quote should unmount using componentwillunmount() but I checked by logging to console, unmount not at all running.
import React from "react";
import "./App.css";
class App extends React.Component {
constructor() {
super();
this.state = {
quote: ""
};
}
handleAction = () => {
this._isRemoved = true;
console.log("Clicked");
};
componentDidMount() {
this._isRemoved = false;
if (!this._isRemoved) {
this.setState({ quote: "Something" });
console.log("Mounted");
}
}
componentWillUnmount() {
this._isRemoved = true;
console.log("Unmount");
}
render() {
return (
<div className="App">
<div>
<q>{this.state.quote}</q>
<br />
<button onClick={this.handleAction}>Click Here</button>
</div>
</div>
);
}
}
export default App;
The unmount it's called when you change the page or somthing that the whole component will disappear .
you can simply hide or show your element like this example :
import React from "react";
import "./App.css";
class App extends React.Component {
constructor() {
super();
this.state = {
quote: "",
_isRemoved :false
};
}
handleAction = () => {
this.setState({
_isRemoved : true
})
console.log("Clicked");
};
showAction = () => {
this.setState({
_isRemoved : false
})
console.log("Clicked");
};
componentDidMount() {
this.setState({ quote: "Something" });
console.log("Mounted");
}
componentWillUnmount() {
this._isRemoved = true;
console.log("Unmount");
}
render() {
return (
<div className="App">
<div>
{!this.state._isRemoved &&
<q>{this.state.quote}</q>
}
<br />
<button onClick={this.handleAction}>Hide</button>
<button onClick={this.showAction}>Show</button>
</div>
</div>
);
}
}
export default App;

ReactJS -- Unable to find latest title from an api causing error

I have a Landing component and a NewsLatest component. I am hitting on an api and trying to find the article with the latest timestamp but iam unable to get it done in reactJS.I checked the js code its working fine but in react it is not rendering. Kindly suggest something.
import React, { Component } from 'react'
import NewsSearch from '../NewsSearch/NewsSearch';
import NewsLatest from '../NewsLatest/NewsLatest';
import './Landing.css';
import axios from 'axios';
class Landing extends Component {
state={
newsList: []
}
componentDidMount(){
axios.get(`https://api.nytimes.com/svc/topstories/v2/home.json?api-key=7cK9FpOnC3zgoboP2CPGR3FcznEaYCJv`)
.then(res=> {
this.setState({newsList: res.data.results});
});
}
render() {
// console.log(this.state.newsList);
return (
<div className="landing text-center text-white">
<h1>News Portal</h1>
<div className="news-search">
<NewsSearch />
</div>
<div className="news-latest">
<NewsLatest newsList={this.state.newsList}/>
</div>
</div>
)
}
}
export default Landing;
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
class NewsLatest extends Component {
constructor(props){
super(props);
this.state = {
newsTitle:'',
abstract:'',
newsUrl:'',
}
// this.newsLatest = this.newsLatest.bind(this);
}
newsLatest = (e)=>{
// e.preventDefault();
const {newsList} = this.props;
let maxTime = newsList.map(function(o) {
return new Date(o.updated_date);
});
let maximumValue = Math.max(...maxTime);
let latestnews = newsList.filter(function (el) {
return maximumValue === new Date(el.updated_date).getTime();
})[0];
if(latestnews){
this.setState({newsTitle: latestnews.title});
return (<h4>{this.state.newsTitle}</h4>);
}
}
newsTitle = () => (
this.props.newsList.map(item => (<h2 key={item.title}>{item.title}</h2>))
)
render() {
console.log(this.props.newsList);
return (
<div>
<h2>News Latest....</h2>
{this.newsLatest()}
</div>
);
}
}
export default NewsLatest;
There is some issue in rendering in NewsLatest component. KIndly suggest something.
Try this:
You must probably be getting a maximum depth error, use a lifecycle method instead like componentDidUpdate. Update your component state only if the previous props are different from the newer ones.
Read more here: https://reactjs.org/docs/react-component.html
import React, { Component } from "react";
// import PropTypes from 'prop-types';
class NewsLatest extends Component {
constructor(props) {
super(props);
this.state = {
newsTitle: "",
abstract: "",
newsUrl: ""
};
// this.newsLatest = this.newsLatest.bind(this);
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.newsList !== this.props.newsList) {
const { newsList } = this.props;
let maxTime = newsList.map(function(o) {
return new Date(o.updated_date);
});
let maximumValue = Math.max(...maxTime);
let latestnews = newsList.filter(function(el) {
return maximumValue === new Date(el.updated_date).getTime();
})[0];
this.setState({ newsTitle: latestnews.title });
}
}
// newsLatest = e => {
// // e.preventDefault();
// const { newsList } = this.props;
// let maxTime = newsList.map(function(o) {
// return new Date(o.updated_date);
// });
// let maximumValue = Math.max(...maxTime);
// let latestnews = newsList.filter(function(el) {
// return maximumValue === new Date(el.updated_date).getTime();
// })[0];
// console.log(latestnews)
// if (latestnews && latestnews.hasOwnProperty('length') && latestnews.length>0) {
// return <h4>{this.state.newsTitle}</h4>;
// }
// };
newsTitle = () =>
this.props.newsList.map(item => <h2 key={item.title}>{item.title}</h2>);
render() {
console.log(this.props.newsList);
return (
<div>
<h2>News Latest....</h2>
<h4>{this.state.newsTitle}</h4>
</div>
);
}
}
export default NewsLatest;
Also, a sandbox: https://codesandbox.io/s/hungry-frog-z37y0?fontsize=14

Error: Super expression must either be null or a function

Problem
So as the title said i've this issue in a todoapp. i checked if i had some typo like react instead of React and it seems to be alright.
Before post something i checked:
First post stackoverflow
Second post stackoverflow
but i cannot find a solution
Code
App.js
import React, {Component} from 'react';
import Form from './Components/Form';
import Footer from './Components/Footer';
import Header from './Components/Header';
class App extends React{
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
handleChange = (event) => {
this.setState({
todoValue: event.target.value,
})
}
handleClick = (event) => {
event.preventDefault();
if (this.state.todoValue !== "") {
const todo = {
id: Date.now(),
text: this.state.todoValue,
done: false,
}
this.setState({
todoValue: "",
todos: [todo, ...this.state.todos],
})
}
}
handleToggle = (id) => {
this.setState((prevState) => {
return {
todos: prevState.todos.map((item, i) => {
if (item.id === id) {
return {
...item,
done: !prevState.todos[i].done,
}
}
return item;
})
}
})
}
handleDelete = (id) => {
this.setState({
todos: this.state.todos.filter(item => item.id !== id)
})
}
deleteCompleted = () => {
this.setState({
todos: this.state.todos.filter(item => !item.done)
})
}
getVisibleTodos = () => {
const filterType = this.state.filterType;
let filterState = null;
switch (filterType) {
case "Completed":
return filterState = this.state.todos.filter(item => item.done);
case "Active":
return filterState = this.state.todos.filter(item => !item.done);
case "Originals":
return filterState = this.state.todos.filter(item => !item.done);
case "New":
return filterState = this.state.todos.filter(item => !item.done);
default:
return filterState = this.state.todos;
}
}
setActiveFilter = (text) => {
this.setState({
filterType: text,
})
}
render() {
return (
<div className="container">
<Header countTodo={this.state.todos.length}/>
<Form handleDelete={this.handleDelete}
handleToggle={this.handleToggle}
handleClick={this.handleClick}
handleChange={this.handleChange}
todoValue={this.state.todoValue}
todos={this.getVisibleTodos()}/>
<Footer setActiveFilter={this.setActiveFilter}
deleteCompleted={this.deleteCompleted}
filter={this.state.filterType}/>
</div>
)
}
}
export default App;
Header.js
import React from 'react';
class Header extends React.Component {
render() {
return (
<header className="header">
<h3>All To-Do {this.props.countTodo}</h3>
</header>
)
}
}
export default Header;
Form.js
import React, {Component} from'react';
import Todo from './Todo';
class Form extends React {
render() {
return (
<form className="form">
<input type="text"
className="form__input"
placeholder="Items"
onChange={this.props.handleChange}
value={this.props.todoValue}
/>
<button
className="form__button"
type="submit"
onClick={this.props.handleClick}>╋</button>
<Todo
todos={this.props.todos}
handleToggle={this.props.handleToggle}
handleDelete={this.props.handleDelete}
/>
</form>
)
}
}
export default Form;
and the last modul is Todo.js
import React, {Component} from 'react';
class Todo extends React{
render() {
return (
<ul className="todos-list">
{
this.props.todos.map((item) => {
return (
<li className="todo-item"
key={item.id} onClick={() => this.props.handleToggle(item.id)}>
<span
className={item.done ? "todo-item__name disabled" : "todo-item__name"}>
{item.text}
</span>
<span
className="todo-item__delete-button"
onClick={() => this.props.handleDelete(item.id)}>
×
</span>
</li>
)
})
}
</ul>
)
}
}
export default Todo;
You class should extend from Component that you're importing from react library.
It should be either
class App extends Component{}
or if you didn't import Component then
class App extends React.Component{}
You haven't extended your App component correctly
class App extends React{ // error here
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
Extend it from React.Component
class App extends React.Component {
constructor(props) {
super(props); // use super here
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}

How to send automatic constant message in web app based on reactjs?

This is my App.js and i have set my database in firebase. All the messages which i enter all display in database also.But i need to automatically send message back to me . so any one knows how to do that please help. Thank you.
import React, { Component } from 'react';
import MessagePane from './MessagePane';
import ChannelList from './ChannelList';
import { getMessages, getChannels, saveMessage, onNewMessage } from './remote_storage1';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
messages: [],
channels: [],
selected_channel_id: null
};
this.onSendMessage = this.onSendMessage.bind(this);
this.onChannelSelect = this.onChannelSelect.bind(this);
this.filteredMessages = this.filteredMessages.bind(this);
}
componentDidMount() {
getMessages().then(messages => this.setState({messages}));
getChannels().then(channels => this.setState({channels, selected_channel_id: channels[0].id}));
onNewMessage(new_message => {
const messages = [...this.state.messages, new_message];
this.setState({messages});
});
}
onSendMessage(author, text) {
const new_message = {
id: this.state.messages[this.state.messages.length - 1].id + 1,
author,
text,
channel_id: this.state.selected_channel_id
};
saveMessage(new_message);
const messages = [...this.state.messages, new_message];
this.setState({messages});
}
onChannelSelect(id) {
this.setState({ selected_channel_id: id });
}
filteredMessages() {
return this.state.messages.filter(({channel_id}) => channel_id === this.state.selected_channel_id);
}
render() {
return (
<div className="App">
<ChannelList
channels={this.state.channels}
selectedChannelId={this.state.selected_channel_id}
onSelect={this.onChannelSelect}
/>
<MessagePane messages={this.filteredMessages()} onSendMessage={this.onSendMessage} />
</div>
);
}
}
export default App;

Resources