mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-15 10:02:47 +03:00
dont send invite on unban
split dropdown component out from api actions in subscribers
This commit is contained in:
parent
56807dd52f
commit
ac620baadb
@ -722,6 +722,8 @@
|
|||||||
|= who=@p
|
|= who=@p
|
||||||
?. (allowed who %read u.book)
|
?. (allowed who %read u.book)
|
||||||
[%give %kick [/notebook/[u.book]]~ `who]~
|
[%give %kick [/notebook/[u.book]]~ `who]~
|
||||||
|
?: ?=(%remove -.upd)
|
||||||
|
~
|
||||||
=/ uid (sham %publish who u.book eny.bol)
|
=/ uid (sham %publish who u.book eny.bol)
|
||||||
=/ inv=invite
|
=/ inv=invite
|
||||||
:* our.bol %publish /notebook/[u.book] who
|
:* our.bol %publish /notebook/[u.book] who
|
||||||
|
73
pkg/interface/publish/src/js/components/lib/dropdown.js
Normal file
73
pkg/interface/publish/src/js/components/lib/dropdown.js
Normal 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
|
@ -89,8 +89,6 @@ export class NewPost extends Component {
|
|||||||
|
|
||||||
let hiddenOnPopout = (props.popout)
|
let hiddenOnPopout = (props.popout)
|
||||||
? "" : "dib-m dib-l dib-xl";
|
? "" : "dib-m dib-l dib-xl";
|
||||||
let submitButtonPadding = (props.sidebarShown && !props.popout)
|
|
||||||
? " pl8" : " pl4";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="f9 h-100 relative">
|
<div className="f9 h-100 relative">
|
||||||
@ -100,7 +98,7 @@ export class NewPost extends Component {
|
|||||||
popout={props.popout}
|
popout={props.popout}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
className={"v-mid w-100 mw7 tl h1"+submitButtonPadding}
|
className={"v-mid w-100 mw7 tl h1 pl4"}
|
||||||
disabled={!state.submit}
|
disabled={!state.submit}
|
||||||
style={submitStyle}
|
style={submitStyle}
|
||||||
onClick={this.postSubmit}>
|
onClick={this.postSubmit}>
|
||||||
|
@ -22,7 +22,7 @@ export class Settings extends Component {
|
|||||||
<div className="flex-column">
|
<div className="flex-column">
|
||||||
<p className="f9 mt3 lh-copy db">Delete Notebook</p>
|
<p className="f9 mt3 lh-copy db">Delete Notebook</p>
|
||||||
<p className="f9 gray2 db mb4">
|
<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>
|
</p>
|
||||||
<button className="b--red2 red2 pointer dib f9 ba pa2"
|
<button className="b--red2 red2 pointer dib f9 ba pa2"
|
||||||
onClick={this.deleteNotebook}>
|
onClick={this.deleteNotebook}>
|
||||||
|
@ -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
|
|
@ -1,9 +1,36 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { SubscriberItem } from './subscriber-item';
|
import { Dropdown } from './dropdown';
|
||||||
|
|
||||||
export class Subscribers extends Component {
|
export class Subscribers extends Component {
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(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() {
|
render() {
|
||||||
@ -21,15 +48,33 @@ export class Subscribers extends Component {
|
|||||||
let withoutUs = new Set(writePerms.who)
|
let withoutUs = new Set(writePerms.who)
|
||||||
withoutUs.delete(window.ship);
|
withoutUs.delete(window.ship);
|
||||||
writers = Array.from(withoutUs).map((who, i) => {
|
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 (
|
return (
|
||||||
<SubscriberItem key={i}
|
<div className="flex justify-between" key={i}>
|
||||||
readPath={readPath}
|
<div className="f9 mono mr2">{`~${who}`}</div>
|
||||||
writePath={writePath}
|
<Dropdown
|
||||||
who={`~${who}`}
|
options={options}
|
||||||
readPerms={readPerms}
|
width={width}
|
||||||
writePerms={writePerms}
|
buttonText={"Options"}
|
||||||
section='participants'
|
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -43,32 +88,28 @@ export class Subscribers extends Component {
|
|||||||
|
|
||||||
let subscribers = null;
|
let subscribers = null;
|
||||||
if (readPath !== writePath) {
|
if (readPath !== writePath) {
|
||||||
if (readPerms && readPerms.kind === 'white') {
|
if (this.props.notebook.subscribers){
|
||||||
let withoutUs = new Set(readPerms.who)
|
let width = 162;
|
||||||
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){
|
|
||||||
subscribers = this.props.notebook.subscribers.map((who, i) => {
|
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 (
|
return (
|
||||||
<SubscriberItem key={i}
|
<div className="flex justify-between" key={i}>
|
||||||
readPath={readPath}
|
<div className="f9 mono mr2">{who}</div>
|
||||||
writePath={writePath}
|
<Dropdown
|
||||||
who={who}
|
options={options}
|
||||||
readPerms={readPerms}
|
width={width}
|
||||||
writePerms={writePerms}
|
buttonText={"Options"}
|
||||||
section='subscribers'
|
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -90,16 +131,22 @@ export class Subscribers extends Component {
|
|||||||
|
|
||||||
let bannedContainer = null;
|
let bannedContainer = null;
|
||||||
if (readPerms && readPerms.kind === 'black') {
|
if (readPerms && readPerms.kind === 'black') {
|
||||||
|
let width = 72;
|
||||||
let banned = Array.from(readPerms.who).map((who, i) => {
|
let banned = Array.from(readPerms.who).map((who, i) => {
|
||||||
|
let options = [{
|
||||||
|
cls: "tl red2 pointer",
|
||||||
|
txt: "Unban",
|
||||||
|
action: () => {this.removeUser(`~${who}`, readPath)}
|
||||||
|
}];
|
||||||
return (
|
return (
|
||||||
<SubscriberItem key={i}
|
<div className="flex justify-between" key={i}>
|
||||||
readPath={readPath}
|
<div className="f9 mono mr2">{`~${who}`}</div>
|
||||||
writePath={writePath}
|
<Dropdown
|
||||||
who={`~${who}`}
|
options={options}
|
||||||
readPerms={readPerms}
|
width={width}
|
||||||
writePerms={writePerms}
|
buttonText={"Options"}
|
||||||
section='banned'
|
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
if (banned.length === 0) {
|
if (banned.length === 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user