Merge pull request #2430 from urbit/mp/os1/bug-bashing-vol-1

os1: bug bashing, volume 1
This commit is contained in:
ixv 2020-03-10 20:57:26 -07:00 committed by GitHub
commit 0dc65c1995
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 106 additions and 63 deletions

View File

@ -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>
);
}
}
}

View File

@ -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

View File

@ -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);
});;
};

View File

@ -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

View File

@ -147,6 +147,7 @@ export class Root extends Component {
selected={resourcePath}
rightPanelHide={true}
sidebarShown={state.sidebarShown}
popout={popout}
links={links}>
<SettingsScreen
sidebarShown={state.sidebarShown}

View File

@ -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>

View File

@ -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>

View File

@ -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}

View File

@ -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);
});
});
}

View File

@ -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"

View File

@ -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

View File

@ -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}

View File

@ -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)}
},

View File

@ -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);
});;
};