mirror of
https://github.com/urbit/shrub.git
synced 2024-12-11 11:02:25 +03:00
Merge pull request #2430 from urbit/mp/os1/bug-bashing-vol-1
os1: bug bashing, volume 1
This commit is contained in:
commit
0dc65c1995
@ -124,29 +124,12 @@ export class Message extends Component {
|
||||
</p>
|
||||
);
|
||||
} else {
|
||||
let chatroom = letter.text.match(
|
||||
/([~][/])?(~[a-z]{3,6})(-[a-z]{6})?([/])(([a-z])+([/-])?)+/
|
||||
);
|
||||
if ((chatroom !== null) // matched possible chatroom
|
||||
&& (chatroom[2].length > 2) // possible ship?
|
||||
&& (urbitOb.isValidPatp(chatroom[2]) // valid patp?
|
||||
&& (chatroom[0] === letter.text))) { // entire message is room name?
|
||||
return (
|
||||
<Link
|
||||
className="bb b--black b--white-d f7 mono lh-copy v-top"
|
||||
to={"/~chat/join/" + chatroom.input}>
|
||||
{letter.text}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
else {
|
||||
let text = letter.text.split ('\n').map ((item, i) => <p className='f7 lh-copy v-top' key={i}>{item}</p>);
|
||||
return (
|
||||
<section>
|
||||
{text}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { deSig, uxToHex } from '/lib/util';
|
||||
import { deSig, uxToHex, writeText } from '/lib/util';
|
||||
import { Route, Link } from "react-router-dom";
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ export class SettingsScreen extends Component {
|
||||
|
||||
let chatOwner = (deSig(props.match.params.ship) === window.ship);
|
||||
|
||||
let deleteButtonClasses = (chatOwner) ? 'b--red2 red2 pointer bg-gray0-d' : 'b--grey3 grey3 bg-gray0-d c-default';
|
||||
let deleteButtonClasses = (chatOwner) ? 'b--red2 red2 pointer bg-gray0-d' : 'b--gray3 gray3 bg-gray0-d c-default';
|
||||
let leaveButtonClasses = (!chatOwner) ? "pointer" : "c-default";
|
||||
|
||||
return (
|
||||
@ -94,7 +94,7 @@ export class SettingsScreen extends Component {
|
||||
<p className="f8 mt3 lh-copy db">Leave Chat</p>
|
||||
<p className="f9 gray2 db mb4">Remove this chat from your chat list. You will need to request for access again.</p>
|
||||
<a onClick={(!chatOwner) ? this.deleteChat.bind(this) : null}
|
||||
className={"dib f9 black gray4-d bg-gray0-d ba pa2 b--black b--gray0-d " + leaveButtonClasses}>Leave this chat</a>
|
||||
className={"dib f9 black gray4-d bg-gray0-d ba pa2 b--black b--gray1-d " + leaveButtonClasses}>Leave this chat</a>
|
||||
</div>
|
||||
<div className={"w-100 fl mt3 " + ((!chatOwner) ? 'o-30' : '')}>
|
||||
<p className="f8 mt3 lh-copy db">Delete Chat</p>
|
||||
@ -333,7 +333,7 @@ export class SettingsScreen extends Component {
|
||||
style={{right: 12, top: 1}}
|
||||
ref="copy"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(props.station.substr(1));
|
||||
writeText(props.station.substr(1));
|
||||
this.refs.copy.innerText = "Copied";
|
||||
}}>
|
||||
Copy
|
||||
|
@ -67,7 +67,32 @@ export function uxToHex(ux) {
|
||||
let value = ux.substr(2).replace('.', '').padStart(6, '0');
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
let value = ux.replace('.', '').padStart(6, '0');
|
||||
return value;
|
||||
}
|
||||
|
||||
export function writeText(str) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(document.body);
|
||||
document.getSelection().addRange(range);
|
||||
|
||||
var success = false;
|
||||
function listener(e) {
|
||||
e.clipboardData.setData("text/plain", str);
|
||||
e.preventDefault();
|
||||
success = true;
|
||||
}
|
||||
document.addEventListener("copy", listener);
|
||||
document.execCommand("copy");
|
||||
document.removeEventListener("copy", listener);
|
||||
|
||||
document.getSelection().removeAllRanges();
|
||||
|
||||
success ? resolve() : reject();
|
||||
}).catch(function (error) {
|
||||
console.error(error);
|
||||
});;
|
||||
};
|
@ -23,15 +23,17 @@ if (dark.matches) {
|
||||
background = "#333";
|
||||
}
|
||||
|
||||
dark.addEventListener("change", (e) => {
|
||||
if (e.matches) {
|
||||
function darkColors(dark) {
|
||||
if (dark.matches) {
|
||||
text = "#7f7f7f";
|
||||
background = "#333";
|
||||
} else {
|
||||
text = "#000000";
|
||||
background = "#ffffff"
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
dark.addListener(darkColors);
|
||||
|
||||
|
||||
const toRelativeTime = (date, referenceTime, unit) => moment(date)
|
||||
@ -202,7 +204,7 @@ class Clock extends Component {
|
||||
ctr,
|
||||
-1,
|
||||
2 * Math.PI,
|
||||
'rgba(0,0,0,0)'
|
||||
background
|
||||
)
|
||||
|
||||
// Day
|
||||
|
@ -147,6 +147,7 @@ export class Root extends Component {
|
||||
selected={resourcePath}
|
||||
rightPanelHide={true}
|
||||
sidebarShown={state.sidebarShown}
|
||||
popout={popout}
|
||||
links={links}>
|
||||
<SettingsScreen
|
||||
sidebarShown={state.sidebarShown}
|
||||
|
@ -27,7 +27,7 @@ export class SettingsScreen extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.resource) {
|
||||
if ((this.props.resource) && ("metadata" in this.props.resource)) {
|
||||
this.setState({
|
||||
title: this.props.resource.metadata.title,
|
||||
description: this.props.resource.metadata.description,
|
||||
@ -47,7 +47,8 @@ export class SettingsScreen extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
if (props.resource && (prevProps !== props)) {
|
||||
if (((this.props.resource) && ("metadata" in this.props.resource))
|
||||
&& (prevProps !== props)) {
|
||||
this.setState({
|
||||
title: props.resource.metadata.title,
|
||||
description: props.resource.metadata.description,
|
||||
@ -84,10 +85,7 @@ export class SettingsScreen extends Component {
|
||||
|
||||
const isManaged = ('/~/' !== props.groupPath.slice(0,3));
|
||||
|
||||
let deleteButtonClasses = (props.amOwner) ? 'b--red2 red2 pointer bg-gray0-d' : 'b--grey3 grey3 bg-gray0-d c-default';
|
||||
let leaveButtonClasses = (!props.amOwner) ? "pointer" : "c-default";
|
||||
|
||||
let deleteClasses = 'dib f9 black gray4-d bg-gray0-d ba pa2 b--black b--gray0-d pointer';
|
||||
let deleteClasses = 'dib f9 black gray4-d bg-gray0-d ba pa2 b--black b--gray1-d pointer';
|
||||
let deleteText = 'Remove this collection from your collection list.';
|
||||
let deleteAction = 'Remove';
|
||||
if (props.amOwner && isManaged) {
|
||||
@ -110,6 +108,10 @@ export class SettingsScreen extends Component {
|
||||
const { props, state } = this;
|
||||
const { resource } = props;
|
||||
|
||||
if (!("metadata" in resource)) {
|
||||
resource.metadata = {};
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div className={"w-100 pb6 fl mt3 " + ((props.amOwner) ? '' : 'o-30')}>
|
||||
@ -135,9 +137,9 @@ export class SettingsScreen extends Component {
|
||||
props.resourcePath,
|
||||
props.groupPath,
|
||||
state.title,
|
||||
props.resource.metadata.description,
|
||||
props.resource.metadata['date-created'],
|
||||
uxToHex(props.resource.metadata.color)
|
||||
resource.metadata.description,
|
||||
resource.metadata['date-created'],
|
||||
uxToHex(resource.metadata.color)
|
||||
).then(() => {
|
||||
api.setSpinner(false);
|
||||
this.refs.rename.innerText = "Saved";
|
||||
@ -170,10 +172,10 @@ export class SettingsScreen extends Component {
|
||||
api.metadataAdd(
|
||||
props.resourcePath,
|
||||
props.groupPath,
|
||||
props.resource.metadata.title,
|
||||
resource.metadata.title,
|
||||
state.description,
|
||||
props.resource['date-created'],
|
||||
uxToHex(props.resource.color)
|
||||
resource['date-created'],
|
||||
uxToHex(resource.color)
|
||||
).then(() => {
|
||||
api.setSpinner(false);
|
||||
this.refs.description.innerText = "Saved";
|
||||
@ -204,9 +206,9 @@ export class SettingsScreen extends Component {
|
||||
api.metadataAdd(
|
||||
props.resourcePath,
|
||||
props.groupPath,
|
||||
props.resource.metadata.title,
|
||||
props.resource.metadata.description,
|
||||
props.resource.metadata['date-created'],
|
||||
resource.metadata.title,
|
||||
resource.metadata.description,
|
||||
resource.metadata['date-created'],
|
||||
state.color
|
||||
).then(() => {
|
||||
api.setSpinner(false);
|
||||
@ -281,7 +283,7 @@ export class SettingsScreen extends Component {
|
||||
<Link to={makeRoutePath(props.resourcePath, props.popout)}
|
||||
className="pt2">
|
||||
<h2
|
||||
className="dib f9 fw4 v-top"
|
||||
className="dib f9 fw4 lh-solid v-top"
|
||||
style={{ width: "max-content" }}>
|
||||
{props.resource.metadata.title}
|
||||
</h2>
|
||||
|
@ -65,9 +65,10 @@ export class Comments extends Component {
|
||||
id="comment"
|
||||
name="comment"
|
||||
placeholder="Leave a comment here"
|
||||
className={"f9 db border-box w-100 ba b--gray3 pt3 ph3 pb8 br1 " +
|
||||
className={"f9 db border-box w-100 ba b--gray3 pt3 ph3 br1 " +
|
||||
"b--gray2-d mb2 focus-b--black focus-b--white-d white-d bg-gray0-d"}
|
||||
aria-describedby="comment-desc"
|
||||
style={{height: "4rem"}}
|
||||
onChange={this.commentChange}>
|
||||
</textarea>
|
||||
</div>
|
||||
|
@ -14,6 +14,7 @@ export class NewPost extends Component {
|
||||
title: '',
|
||||
submit: false,
|
||||
awaiting: null,
|
||||
disabled: false
|
||||
}
|
||||
|
||||
this.postSubmit = this.postSubmit.bind(this);
|
||||
@ -33,13 +34,14 @@ export class NewPost extends Component {
|
||||
}
|
||||
|
||||
window.api.setSpinner(true);
|
||||
this.setState({ disabled: true });
|
||||
window.api.action("publish", "publish-action", newNote).then(() =>{
|
||||
this.setState({ awaiting: newNote["new-note"].note });
|
||||
this.setState({ awaiting: newNote["new-note"].note, disabled: false });
|
||||
}).catch((err) => {
|
||||
if (err.includes("note already exists")) {
|
||||
let timestamp = Math.floor(Date.now() / 1000);
|
||||
newNote["new-note"].note += "-" + timestamp;
|
||||
this.setState({awaiting: newNote["new-note"].note});
|
||||
this.setState({awaiting: newNote["new-note"].note, disabled: false});
|
||||
window.api.action("publish", "publish-action", newNote);
|
||||
}
|
||||
});
|
||||
@ -86,7 +88,7 @@ export class NewPost extends Component {
|
||||
|
||||
let date = dateToDa(new Date()).slice(1, -10);
|
||||
|
||||
let submitStyle = (state.submit)
|
||||
let submitStyle = ((!state.disabled && state.submit) && (state.awaiting === null))
|
||||
? { color: '#2AA779', cursor: "pointer" }
|
||||
: { color: '#B1B2B3', cursor: "auto" };
|
||||
|
||||
@ -106,7 +108,7 @@ export class NewPost extends Component {
|
||||
/>
|
||||
<button
|
||||
className={"bg-transparent v-mid w-100 mw6 tl h1 pl4"}
|
||||
disabled={!state.submit}
|
||||
disabled={(!state.submit && state.disabled) || (state.awaiting !== null)}
|
||||
style={submitStyle}
|
||||
onClick={this.postSubmit}>
|
||||
Publish To {notebook.title}
|
||||
|
@ -93,10 +93,11 @@ export class NewScreen extends Component {
|
||||
group: groupInfo
|
||||
}
|
||||
}
|
||||
|
||||
props.api.setSpinner(true);
|
||||
this.setState({awaiting: bookId, disabled: true}, () => {
|
||||
props.api.setSpinner(true);
|
||||
props.api.action("publish", "publish-action", action);
|
||||
props.api.action("publish", "publish-action", action).then(() => {
|
||||
props.api.setSpinner(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -109,12 +109,12 @@ export class Note extends Component {
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
let notebook = props.notebooks[props.ship][props.book];
|
||||
let comments = notebook.notes[props.note].comments;
|
||||
let title = notebook.notes[props.note].title;
|
||||
let author = notebook.notes[props.note].author;
|
||||
let file = notebook.notes[props.note].file;
|
||||
let date = moment(notebook.notes[props.note]["date-created"]).fromNow();
|
||||
let notebook = props.notebooks[props.ship][props.book] || {};
|
||||
let comments = notebook.notes[props.note].comments || false;
|
||||
let title = notebook.notes[props.note].title || "";
|
||||
let author = notebook.notes[props.note].author || "";
|
||||
let file = notebook.notes[props.note].file || "";
|
||||
let date = moment(notebook.notes[props.note]["date-created"]).fromNow() || 0;
|
||||
|
||||
let contact = !!(author.substr(1) in props.contacts)
|
||||
? props.contacts[author.substr(1)] : false;
|
||||
@ -130,8 +130,8 @@ export class Note extends Component {
|
||||
}
|
||||
|
||||
let newfile = file.slice(file.indexOf(';>')+2);
|
||||
let prevId = notebook.notes[props.note]["prev-note"];
|
||||
let nextId = notebook.notes[props.note]["next-note"];
|
||||
let prevId = notebook.notes[props.note]["prev-note"] || null;
|
||||
let nextId = notebook.notes[props.note]["next-note"] || null;
|
||||
|
||||
let prev = (prevId === null)
|
||||
? null
|
||||
@ -202,7 +202,7 @@ export class Note extends Component {
|
||||
{name}
|
||||
</div>
|
||||
<div className="di">
|
||||
<span className="f9 gray2">{date}</span><span className="ml2">{editPost}</span></div>
|
||||
<span className="f9 gray2 dib">{date}</span><span className="ml2 dib">{editPost}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md"
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { writeText } from '../../lib/util';
|
||||
|
||||
export class Settings extends Component {
|
||||
constructor(props){
|
||||
@ -96,7 +97,7 @@ export class Settings extends Component {
|
||||
style={{ right: 12, top: 1 }}
|
||||
ref="copy"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(`${this.props.host}/${this.props.book}`);
|
||||
writeText(`${this.props.host}/${this.props.book}`);
|
||||
this.refs.copy.innerText = "Copied"
|
||||
}}>
|
||||
Copy
|
||||
|
@ -28,7 +28,7 @@ export class SidebarInvite extends Component {
|
||||
const { props } = this;
|
||||
|
||||
return (
|
||||
<div className='pa3 bb b--gray4'>
|
||||
<div className='pa3 bb b--gray4 b--gray2-d'>
|
||||
<div className='w-100 v-mid'>
|
||||
<p className="dib f9 mono gray4-d">
|
||||
{props.invite.text}
|
||||
|
@ -92,11 +92,11 @@ export class Subscribers extends Component {
|
||||
let width = 162;
|
||||
subscribers = this.props.notebook.subscribers.map((who, i) => {
|
||||
let options = [
|
||||
{ cls: "tl pointer w-100 db hover-bg-gray4 ph2 pv3",
|
||||
{ cls: "white-d tl pointer w-100 db hover-bg-gray4 hover-bg-gray1-d bg-transparent ph2 pv3",
|
||||
txt: "Promote to participant",
|
||||
action: () => {this.addUser(who, writePath)}
|
||||
},
|
||||
{ cls: "tl red2 pointer w-100 db hover-bg-gray4 ph2 pv3",
|
||||
{ cls: "tl red2 pointer w-100 db hover-bg-gray4 hover-bg-gray1-d bg-transparent ph2 pv3",
|
||||
txt: "Ban",
|
||||
action: () => {this.addUser(who, readPath)}
|
||||
},
|
||||
|
@ -46,3 +46,28 @@ export function uxToHex(ux) {
|
||||
let value = ux.replace('.', '').padStart(6, '0');
|
||||
return value;
|
||||
}
|
||||
|
||||
export function writeText(str) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(document.body);
|
||||
document.getSelection().addRange(range);
|
||||
|
||||
var success = false;
|
||||
function listener(e) {
|
||||
e.clipboardData.setData("text/plain", str);
|
||||
e.preventDefault();
|
||||
success = true;
|
||||
}
|
||||
document.addEventListener("copy", listener);
|
||||
document.execCommand("copy");
|
||||
document.removeEventListener("copy", listener);
|
||||
|
||||
document.getSelection().removeAllRanges();
|
||||
|
||||
success ? resolve() : reject();
|
||||
}).catch(function (error) {
|
||||
console.error(error);
|
||||
});;
|
||||
};
|
Loading…
Reference in New Issue
Block a user