chat: integrate invite search on members page

This commit is contained in:
Matilde Park 2020-02-28 00:15:55 -05:00
parent 34b5d5702f
commit 2c301c0b80
4 changed files with 35 additions and 63 deletions

View File

@ -78,11 +78,11 @@ class UrbitApi {
}
groupsAction(data) {
this.action("group-store", "group-action", data);
return this.action("group-store", "group-action", data);
}
groupAdd(members, path) {
this.groupsAction({
return this.groupsAction({
add: {
members, path
}
@ -147,7 +147,7 @@ class UrbitApi {
chatViewJoin(ship, path, askHistory) {
this.chatViewAction({
join: {
ship,
ship,
'app-path': path,
'ask-history': askHistory
}

View File

@ -1,40 +1,25 @@
import React, { Component } from 'react';
import classnames from 'classnames';
import { Sigil } from '/components/lib/icons/sigil';
import { deSig } from '/lib/util';
import urbitOb from 'urbit-ob';
import { InviteSearch } from './invite-search';
export class InviteElement extends Component {
constructor(props) {
super(props);
this.state = {
members: '',
members: [],
error: false,
success: false
};
this.setInvite = this.setInvite.bind(this);
}
modifyMembers() {
const { props, state } = this;
let aud = [];
let isValid = true;
if (state.members.length > 2) {
aud = state.members
.split(',')
.map((mem) => `~${deSig(mem.trim())}`);
let aud = state.members.map(mem => `~${mem}`);
aud.forEach((mem) => {
if (!urbitOb.isValidPatp(mem)) {
isValid = false;
}
});
}
if (!isValid || (state.members.length > 0 && state.members.length < 3)) {
if (state.members.length === 0) {
this.setState({
error: true,
success: false
@ -42,40 +27,27 @@ export class InviteElement extends Component {
return;
}
if (this.textarea) {
this.textarea.value = '';
}
props.api.setSpinner(true);
this.setState({
error: false,
success: true,
members: ''
members: []
}, () => {
props.api.groups.add(aud, props.path);
props.api.groups.add(aud, props.path).then(() => {
props.api.setSpinner(false);
});
});
}
modifyMembersChange(e) {
this.setState({
members: e.target.value
});
setInvite(invite) {
this.setState({members: invite.ships});
}
render() {
const { props, state} = this;
let errorElem = !!state.error ? (
<p className="pt2 red2 f8">Invalid ship name.</p>
) : (
<div></div>
);
const { props, state } = this;
let successElem = !!state.success ? (
<p className="pt2 green2 f8">Success!</p>
) : (
<div></div>
);
let modifyButtonClasses = "db f9 ba pa2 white-d bg-gray0-d b--black b--gray2-d pointer";
let modifyButtonClasses = "mt4 db f9 ba pa2 white-d bg-gray0-d b--black b--gray2-d pointer";
if (state.error) {
modifyButtonClasses = modifyButtonClasses + ' gray3';
}
@ -89,23 +61,21 @@ export class InviteElement extends Component {
return (
<div>
<textarea
ref={ e => { this.textarea = e; } }
className="f7 mono ba b--gray3 bg-gray0-d white-d pa3 mb4 db w-100"
style={{
resize: 'none',
height: 50
}}
spellCheck="false"
placeholder="~zod, ~bus"
onChange={this.modifyMembersChange.bind(this)}></textarea>
<InviteSearch
groups={{}}
contacts={props.contacts}
groupResults={false}
invites={{
groups: [],
ships: this.state.members
}}
setInvite={this.setInvite}
/>
<button
onClick={this.modifyMembers.bind(this)}
className={modifyButtonClasses}>
{buttonText}
</button>
{errorElem}
{successElem}
</div>
);
}

View File

@ -29,9 +29,12 @@ export class MemberScreen extends Component {
modifyText = 'Invite someone to this chat.';
}
let contacts = (props.station in props.contacts)
? props.contacts[props.station] : {};
let members = perm.map((mem) => {
let contact = (mem in props.contacts)
? props.contacts[mem] : false;
let contact = (mem in contacts)
? contacts[mem] : false;
return (
<MemberElement
@ -55,7 +58,7 @@ export class MemberScreen extends Component {
<Link to="/~chat/">{"⟵ All Chats"}</Link>
</div>
<div
className={`pl4 pt2 bb b--gray4 b--gray1-d bg-gray0-d flex relative
className={`pl4 pt2 bb b--gray4 b--gray1-d bg-gray0-d flex relative
overflow-x-scroll overflow-x-auto-l overflow-x-auto-xl flex-shrink-0`}
style={{ height: 48 }}>
<SidebarSwitcher
@ -91,6 +94,7 @@ export class MemberScreen extends Component {
<InviteElement
path={props.station}
permissions={props.permission}
contacts={props.contacts}
api={props.api}
/>
) : null}

View File

@ -200,8 +200,6 @@ export class Root extends Component {
};
let popout = props.match.url.includes("/popout/");
let roomContacts = (station in contacts)
? contacts[station] : {};
return (
<Skeleton
@ -216,7 +214,7 @@ export class Root extends Component {
api={api}
station={station}
permission={permission}
contacts={roomContacts}
contacts={contacts}
permissions={state.permissions}
popout={popout}
sidebarShown={state.sidebarShown}