/// import * as React from 'react'; import { connect } from 'react-redux'; import { reduxify } from './core'; import 'jquery'; import 'ss-utils'; declare var EventSource: ssutils.IEventSourceStatic; export default class Connect extends React.Component { constructor(props?, context?) { super(props, context); this.state = { channels: ["home"], currentUser: null, users: [], connectedToUserId: null, connectedUserActions: [], connectedStateIndex: -1 }; var source = new EventSource("/event-stream?channels=home"); $(source).handleServerEvents({ handlers: { onConnect: (currentUser) => { currentUser.usersChannel = userChannel(currentUser.userId); this.setState({ currentUser, users: filterUsers(this.state.users, currentUser.userId) }); this.props.onConnect(currentUser); }, onJoin: () => this.refreshUsers(), onLeave: () => this.refreshUsers(), onUpdate: (user) => this.setState({ users: this.state.users.map(x => x.userId === user.userId ? user : x) }), getState: (json, e) => { var o = JSON.parse(json); var index = o.stateIndex || this.props.history.stateIndex; var state = this.props.history.states[index]; $.ss.postJSON(`/send-user/${o.replyTo}?selector=cmd.onState`, state); }, onState: (json, e) => { this.props.store.dispatch({ type: 'LOAD', state: json ? JSON.parse(json) : this.props.defaultState }); }, publishAction: (json, e) => { var action = JSON.parse(json); this.props.store.dispatch(action); } } }); } render() { if (this.state.currentUser == null) return null; return (
{this.renderUser(this.state.currentUser) }
{this.state.users.length} users online:
{ this.state.users.map(u => this.renderUser(u)) }
{ this.state.connectedToUserId ? : null}
); } renderUser(u) { return (
this.connectToUser(u.userId) } style={{ cursor: "pointer", padding: "4px", background: u.userId === this.state.connectedToUserId ? "#ffc" : "" }}> {u.displayName} {u.userId === this.state.currentUser.userId ? " (me)" : ""}
); } connectToUser(userId) { if (userId === this.state.currentUser.userId) return; this.requestUsersState(userId); var connectedChannels = this.state.channels.filter(x => x !== "home"); $.ss.updateSubscriber({ SubscribeChannels: userChannel(userId), UnsubscribeChannels: connectedChannels.join(',') }, r => { this.setState({ channels: r.channels, connectedToUserId: userId }); }); } disconnect() { $.ss.unsubscribeFromChannels([userChannel(this.state.connectedToUserId)]); this.setState({ connectedToUserId: null }); } requestUsersState(userId) { return $.ss.postJSON(`/send-user/${userId}?selector=cmd.getState`, { replyTo: this.state.currentUser.userId }); } refreshUsers() { $.getJSON("/event-subscribers?channels=home", users => { this.setState({ users: filterUsers(users, this.state.currentUser.userId) }); }); } } const userChannel = (userId) => "u_" + userId; const filterUsers = (users, userId) => users.filter(x => x.userId !== userId).sort((x, y) => x.userId.localeCompare(y.userId));