dont send invite on unban

split dropdown component out from api actions in subscribers
This commit is contained in:
Isaac Visintainer 2020-02-14 13:55:55 -08:00
parent 56807dd52f
commit ac620baadb
6 changed files with 165 additions and 197 deletions

View File

@ -722,6 +722,8 @@
|= who=@p
?. (allowed who %read u.book)
[%give %kick [/notebook/[u.book]]~ `who]~
?: ?=(%remove -.upd)
~
=/ uid (sham %publish who u.book eny.bol)
=/ inv=invite
:* our.bol %publish /notebook/[u.book] who

View File

@ -0,0 +1,73 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
export class Dropdown extends Component {
constructor(props) {
super(props);
this.toggleDropdown = this.toggleDropdown.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this.collapseAndDispatch = this.collapseAndDispatch.bind(this);
this.state = {
open: false
}
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside);
}
handleClickOutside(evt) {
if (this.optsList && !this.optsList.contains(evt.target) &&
this.optsButton && !this.optsButton.contains(evt.target)) {
this.setState({open: false});
}
}
toggleDropdown() {
this.setState({open: !this.state.open});
}
collapseAndDispatch(action){
this.setState({open: false}, action);
}
render() {
let display = (this.state.open)
? "block" : "none";
let optionsColor = (this.state.open)
? '#e6e6e6' : 'white';
let optionsList = this.props.options.map((val, i) => {
return (
<button key={i} className={val.cls}
onClick={() => this.collapseAndDispatch(val.action)}>
{val.txt}
</button>
);
});
return (
<div className="options relative dib"
ref={(el) => {this.optsButton = el}}>
<button className="pr3 mb1 pointer br2 pa2 pr4"
style={{backgroundColor: optionsColor}}
onClick={this.toggleDropdown}>
{this.props.buttonText}
</button>
<div className="absolute flex flex-column pa4 ba b--gray4 br2 z-1 bg-white"
ref={(el) => {this.optsList = el}}
style={{right:0, width:this.props.width, display: display}}>
{optionsList}
</div>
</div>
)
}
}
export default Dropdown

View File

@ -89,8 +89,6 @@ export class NewPost extends Component {
let hiddenOnPopout = (props.popout)
? "" : "dib-m dib-l dib-xl";
let submitButtonPadding = (props.sidebarShown && !props.popout)
? " pl8" : " pl4";
return (
<div className="f9 h-100 relative">
@ -100,7 +98,7 @@ export class NewPost extends Component {
popout={props.popout}
/>
<button
className={"v-mid w-100 mw7 tl h1"+submitButtonPadding}
className={"v-mid w-100 mw7 tl h1 pl4"}
disabled={!state.submit}
style={submitStyle}
onClick={this.postSubmit}>

View File

@ -22,7 +22,7 @@ export class Settings extends Component {
<div className="flex-column">
<p className="f9 mt3 lh-copy db">Delete Notebook</p>
<p className="f9 gray2 db mb4">
Permenantly delete this notebook. (All current members will no longer see this notebook)
Permanently delete this notebook. (All current members will no longer see this notebook)
</p>
<button className="b--red2 red2 pointer dib f9 ba pa2"
onClick={this.deleteNotebook}>

View File

@ -1,152 +0,0 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
export class SubscriberItem extends Component {
constructor(props) {
super(props);
this.toggleOptions = this.toggleOptions.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this.ban = this.ban.bind(this);
this.unban = this.unban.bind(this);
this.removeWriter = this.removeWriter.bind(this);
this.addWriter = this.addWriter.bind(this);
this.state = {
optionsSelected: false
}
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside);
}
handleClickOutside(evt) {
if (this.optsList && !this.optsList.contains(evt.target) &&
this.optsButton && !this.optsButton.contains(evt.target)) {
this.setState({optionsSelected: false});
}
}
ban() {
let action = {
add: {
members: [this.props.who],
path: this.props.readPath,
}
}
this.setState({optionsSelected: false}, () => {
window.api.action("group-store", "group-action", action);
});
}
unban() {
let action = {
remove: {
members: [this.props.who],
path: this.props.readPath,
}
}
this.setState({optionsSelected: false}, () => {
window.api.action("group-store", "group-action", action);
});
}
removeWriter() {
let action = {
remove: {
members: [this.props.who],
path: this.props.writePath,
}
}
this.setState({optionsSelected: false}, () => {
window.api.action("group-store", "group-action", action);
});
}
addWriter() {
let action = {
add: {
members: [this.props.who],
path: this.props.writePath,
}
}
this.setState({optionsSelected: false}, () => {
window.api.action("group-store", "group-action", action);
});
}
toggleOptions() {
this.setState({optionsSelected: !this.state.optionsSelected});
}
render() {
let display = (this.state.optionsSelected)
? "block" : "none";
let width = 0;
let options = [];
if (this.props.section === 'participants') {
if (this.props.readPath === this.props.writePath) {
width = 258;
let url = `/~contacts${this.props.writePath}`;
options = [
<a key={0} className="tl pointer" href={url}>
Manage this group in the contacts view
</a>
];
} else {
width = 157;
options = [
<button key={0} className="tl pointer" onClick={this.removeWriter}>
Demote to subscriber
</button>
];
}
} else if (this.props.section === 'subscribers') {
width = 162;
options = [
<button key={0} className="tl mb2 pointer" onClick={this.addWriter}>
Promote to participant
</button>,
<button key={1} className="tl red2 pointer" onClick={this.ban}>
Ban
</button>
];
} else if (this.props.section === 'banned') {
width = 72;
options = [
<button key={0} className="tl red2 pointer" onClick={this.unban}>
Unban
</button>
];
}
let optionsColor = (this.state.optionsSelected)
? '#e6e6e6' : 'white';
return (
<div className="flex justify-between">
<div className="f9 mono mr2">{this.props.who}</div>
<div className="options relative dib"
ref={(el) => {this.optsButton = el}}>
<button className="pr3 mb1 pointer br2 pa2 pr4"
style={{backgroundColor: optionsColor}}
onClick={this.toggleOptions}>
Options
</button>
<div className="absolute flex flex-column pa4 ba b--gray4 br2 z-1 bg-white"
ref={(el) => {this.optsList = el}}
style={{right:0, width:width, display: display}}>
{options}
</div>
</div>
</div>
)
}
}
export default SubscriberItem

View File

@ -1,9 +1,36 @@
import React, { Component } from 'react';
import { SubscriberItem } from './subscriber-item';
import { Dropdown } from './dropdown';
export class Subscribers extends Component {
constructor(props){
super(props);
this.redirect = this.redirect.bind(this);
this.addUser = this.addUser.bind(this);
this.removeUser = this.removeUser.bind(this);
}
addUser(who, path) {
let action = {
add: {
members: [who],
path: path,
}
}
window.api.action("group-store", "group-action", action);
}
removeUser(who, path) {
let action = {
remove: {
members: [who],
path: path,
}
}
window.api.action("group-store", "group-action", action);
}
redirect(url) {
window.location.href = url;
}
render() {
@ -21,15 +48,33 @@ export class Subscribers extends Component {
let withoutUs = new Set(writePerms.who)
withoutUs.delete(window.ship);
writers = Array.from(withoutUs).map((who, i) => {
let width = 0;
let options = [];
if (readPath === writePath) {
width = 258;
let url = `/~contacts${writePath}`;
options = [{
cls: "tl pointer",
txt: "Manage this group in the contacts view",
action: () => {this.redirect(url)}
}];
} else {
width = 157;
options = [{
cls: "tl pointer",
txt: "Demote to subscriber",
action: () => {this.removeUser(`~${who}`, writePath)}
}];
}
return (
<SubscriberItem key={i}
readPath={readPath}
writePath={writePath}
who={`~${who}`}
readPerms={readPerms}
writePerms={writePerms}
section='participants'
/>
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{`~${who}`}</div>
<Dropdown
options={options}
width={width}
buttonText={"Options"}
/>
</div>
)
});
}
@ -43,32 +88,28 @@ export class Subscribers extends Component {
let subscribers = null;
if (readPath !== writePath) {
if (readPerms && readPerms.kind === 'white') {
let withoutUs = new Set(readPerms.who)
withoutUs.delete(window.ship);
subscribers = Array.from(withoutUs).map((who, i) => {
return (
<SubscriberItem key={i}
readPath={readPath}
writePath={writePath}
who={`~${who}`}
readPerms={readPerms}
writePerms={writePerms}
section='subscribers'
/>
)
});
} else if (this.props.notebook.subscribers){
if (this.props.notebook.subscribers){
let width = 162;
subscribers = this.props.notebook.subscribers.map((who, i) => {
let options = [
{ cls: "tl mb2 pointer",
txt: "Promote to participant",
action: () => {this.addUser(who, writePath)}
},
{ cls: "tl red2 pointer",
txt: "Ban",
action: () => {this.addUser(who, readPath)}
},
];
return (
<SubscriberItem key={i}
readPath={readPath}
writePath={writePath}
who={who}
readPerms={readPerms}
writePerms={writePerms}
section='subscribers'
/>
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{who}</div>
<Dropdown
options={options}
width={width}
buttonText={"Options"}
/>
</div>
)
});
}
@ -90,16 +131,22 @@ export class Subscribers extends Component {
let bannedContainer = null;
if (readPerms && readPerms.kind === 'black') {
let width = 72;
let banned = Array.from(readPerms.who).map((who, i) => {
let options = [{
cls: "tl red2 pointer",
txt: "Unban",
action: () => {this.removeUser(`~${who}`, readPath)}
}];
return (
<SubscriberItem key={i}
readPath={readPath}
writePath={writePath}
who={`~${who}`}
readPerms={readPerms}
writePerms={writePerms}
section='banned'
/>
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{`~${who}`}</div>
<Dropdown
options={options}
width={width}
buttonText={"Options"}
/>
</div>
)
});
if (banned.length === 0) {