import React from 'react'; /* InfoView: panel with topic/user info */ export default class InfoView extends React.Component { constructor(props) { super(props); this.state = { topic: null, owner: false, admin: false, sharer: false, muted: false, address: null, groupTopic: undefined, fullName: undefined, avatar: null, private: null, selectedContact: null, access: null, modeGiven: null, modeWant: null, modeGiven2: null, // P2P topic, the other user mode given modeWant2: null, // P2P topic, the other user mode want auth: null, anon: null, contactList: [], tags: [], showMemberPanel: false, showPermissionEditorFor: undefined, moreInfoExpanded: false, previousMetaDesc: undefined, previousSubsUpdated: undefined, previousTagsUpdated: undefined }; this.resetSubs = this.resetSubs.bind(this); this.resetDesc = this.resetDesc.bind(this); this.onMetaDesc = this.onMetaDesc.bind(this); this.onSubsUpdated = this.onSubsUpdated.bind(this); this.onTagsUpdated = this.onTagsUpdated.bind(this); this.handleFullNameUpdate = this.handleFullNameUpdate.bind(this); this.handlePrivateUpdate = this.handlePrivateUpdate.bind(this); this.handleImageChanged = this.handleImageChanged.bind(this); this.handleMuted = this.handleMuted.bind(this); this.handlePermissionsChanged = this.handlePermissionsChanged.bind(this); this.handleLaunchPermissionsEditor = this.handleLaunchPermissionsEditor.bind(this); this.handleHidePermissionsEditor = this.handleHidePermissionsEditor.bind(this); this.handleShowAddMembers = this.handleShowAddMembers.bind(this); this.handleHideAddMembers = this.handleHideAddMembers.bind(this); this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this); this.handleLeave = this.handleLeave.bind(this); this.handleMemberSelected = this.handleMemberSelected.bind(this); this.handleMoreInfo = this.handleMoreInfo.bind(this); this.handleTagsUpdated = this.handleTagsUpdated.bind(this); this.handleContextMenu = this.handleContextMenu.bind(this); } // No need to separately handle component mount. UNSAFE_componentWillReceiveProps(props) { var topic = this.props.tinode.getTopic(props.topic); if (!topic) { return; } if (this.onMetaDesc != topic.onMetaDesc) { this.previousMetaDesc = topic.onMetaDesc; topic.onMetaDesc = this.onMetaDesc; this.previousSubsUpdated = topic.onSubsUpdated; topic.onSubsUpdated = this.onSubsUpdated; if (topic.getType() == 'grp') { this.previousTagsUpdated = topic.onTagsUpdated; topic.onTagsUpdated = this.onTagsUpdated; } else { this.previousTagsUpdated = undefined; } } if (this.state.topic != props.topic) { this.setState({topic: props.topic}); this.resetDesc(topic, props); this.resetSubs(topic, props); } } componentWillUnmount() { var topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.setState({topic: null}); topic.onMetaDesc = this.previousMetaDesc; topic.onSubsUpdated = this.previousSubsUpdated; topic.onTagsUpdated = this.previousTagsUpdated; } resetSubs(topic, props) { var newState = {contactList: []}; if (topic.getType() == 'p2p') { // Fetch the other party in the p2p conversation. // Topic may not be ready yet, so check if user is found. var user2 = topic.subscriber(props.topic); if (user2) { newState.modeGiven2 = user2.acs.getGiven(); newState.modeWant2 = user2.acs.getWant(); } } else { topic.subscribers(function(sub) { newState.contactList.push(sub); }, this); } this.setState(newState); } resetDesc(topic, props) { var defacs = topic.getDefaultAccess() || {}; var acs = topic.getAccessMode(); this.setState({ owner: acs && acs.isOwner(), admin: acs && acs.isAdmin(), sharer: acs && (acs.isAdmin() || acs.isSharer()), muted: acs && acs.isMuted(), fullName: topic.public ? topic.public.fn : undefined, avatar: makeImageUrl(topic.public ? topic.public.photo : null), private: topic.private ? topic.private.comment : null, address: topic.name, groupTopic: (topic.getType() == 'grp'), showMemberPanel: false, access: acs ? acs.getMode() : undefined, modeGiven: acs ? acs.getGiven() : undefined, modeWant: acs ? acs.getWant() : undefined, auth: defacs.auth, anon: defacs.anon }); if (topic.getType() == 'grp' && acs && acs.isOwner()) { // Requesting tags: owner is editing the topic. topic.getMeta(topic.startMetaQuery().withTags().build()); } } onMetaDesc(desc) { var topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.resetDesc(topic, this.props); if (this.previousMetaDesc && this.previousMetaDesc != this.onMetaDesc) { this.previousMetaDesc(desc); } } onSubsUpdated() { var topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } this.resetSubs(topic, this.props); if (this.previousSubsUpdated && this.previousSubsUpdated != this.onSubsUpdated) { this.previousSubsUpdated(); } } onTagsUpdated(tags) { this.setState({tags: tags}); if (this.previousTagsUpdated && this.previousTagsUpdated != this.onTagsUpdated) { this.previousTagsUpdated(); } } handleFullNameUpdate(fn) { if (this.state.fullName !== fn) { this.setState({fullName: fn}); this.props.onTopicDescUpdate(this.props.topic, vcard(fn, this.state.avatar), null); } } handlePrivateUpdate(priv) { if (this.state.priv !== priv) { this.setState({private: priv}); this.props.onTopicDescUpdate(this.props.topic, null, priv); } } handleImageChanged(img) { this.setState({avatar: img}); this.props.onTopicDescUpdate(this.props.topic, vcard(this.state.fullName, img), null); } handleMuted(ignored, checked) { this.setState({muted: checked}); this.props.onChangePermissions(this.props.topic, checked ? '-P' : '+P'); } handlePermissionsChanged(perm) { switch (this.state.showPermissionEditorFor) { case 'auth': this.props.onTopicDescUpdate(this.props.topic, null, null, {auth: perm}); break; case 'anon': this.props.onTopicDescUpdate(this.props.topic, null, null, {anon: perm}); break; case 'mode': case 'want': this.props.onChangePermissions(this.props.topic, perm); break; case 'given': this.props.onChangePermissions(this.props.topic, perm, this.props.topic); break; case 'user': this.props.onChangePermissions(this.props.topic, perm, this.state.userPermissionsEdited); break; } this.setState({showPermissionEditorFor: undefined}); } handleLaunchPermissionsEditor(which, uid) { let toEdit, toCompare, toSkip, titleEdit, titleCompare, userTitle, userAvatar; switch (which) { case 'mode': toEdit = this.state.access; break; case 'want': toEdit = this.state.modeWant; toCompare = this.state.modeGiven; toSkip = this.state.groupTopic ? 'O' : 'ASDO'; titleEdit = "Requested"; titleCompare = "Granted"; break; case 'given': toEdit = this.state.modeGiven2; toCompare = this.state.modeWant2; toSkip = this.state.groupTopic ? (this.state.owner ? '' : 'O') : 'ASDO'; titleEdit = "Granted"; titleCompare = "Requested"; break; case 'auth': toEdit = this.state.auth; toSkip = 'O'; break; case 'anon': toEdit = this.state.anon; toSkip = 'O'; break; case 'user': { let topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } var user = topic.subscriber(uid); if (!user || !user.acs) { return; } toEdit = user.acs.getGiven(); toCompare = user.acs.getWant(); toSkip = this.state.owner ? '' : 'O'; titleEdit = "Granted"; titleCompare = "Requested"; if (user.public) { userTitle = user.public.fn; userAvatar = user.public.photo; } break; } default: console.log("Unknown permission editing mode '" + which + "'"); break; } this.setState({ showPermissionEditorFor: which, userPermissionsEdited: uid, userPermissionsTitle: userTitle, userPermissionsAvatar: userAvatar, editedPermissions: toEdit, immutablePermissions: toCompare, editedPermissionsTitle: titleEdit, immutablePermissionsTitle: titleCompare, editedPermissionsSkipped: toSkip, }); } handleHidePermissionsEditor() { this.setState({showPermissionEditorFor: undefined}); } handleShowAddMembers() { this.props.onInitFind(); this.setState({showMemberPanel: true}); } handleHideAddMembers() { this.setState({showMemberPanel: false}); } handleMemberUpdateRequest(members, added, removed) { this.props.onMemberUpdateRequest(this.props.topic, added, removed); this.setState({showMemberPanel: false}); } handleLeave() { this.props.onLeaveTopic(this.props.topic); } handleMemberSelected(uid) { this.setState({selectedContact: uid}); } handleMoreInfo(open) { this.setState({moreInfoExpanded: open}); } handleTagsUpdated(tags) { if (!arrayEqual(this.state.tags.slice(0), tags.slice(0))) { this.props.onTopicTagsUpdate(this.props.topic, tags); } } handleContextMenu(params) { var instance = this; var topic = this.props.tinode.getTopic(this.props.topic); if (!topic) { return; } var user = topic.subscriber(params.topicName); if (!user || !user.acs) { return; } var menuItems = [ {title: "Edit permissions", handler: function() { instance.handleLaunchPermissionsEditor('user', params.topicName); }}, 'member_delete', user.acs.isMuted() ? 'member_unmute' : 'member_mute', user.acs.isJoiner() ? 'member_block' : 'member_unblock' ]; this.props.showContextMenu({ topicName: this.props.topic, x: params.x, y: params.y, user: params.topicName}, menuItems); } render() { return (
Info
{this.props.displayMobile ? : null} {this.state.showMemberPanel ? : this.state.showPermissionEditorFor ? :
Unknown} readOnly={!this.state.owner} value={this.state.fullName} onFinished={this.handleFullNameUpdate} />
{this.state.moreInfoExpanded ?
{this.state.address}
{this.state.groupTopic ?
{this.state.access}
:
Yours:   {this.state.access}
{this.state.fullName ? this.state.fullName : "Other"}′s:   {this.state.modeGiven2}
} {this.state.sharer && (this.state.auth || this.state.anon) ?
Auth: {this.state.admin ? {this.state.auth} : {this.state.auth} }
Anon: {this.state.admin ? {this.state.anon} : {this.state.anon} }
: null }
: null }
{this.state.owner ? : null } {this.state.owner ?
: null } {this.state.groupTopic ?
{this.state.sharer ? person_add Add members : null} {!this.state.owner ? exit_to_app Leave : null}
: }
}
); } };