mirror of
https://github.com/urbit/shrub.git
synced 2024-12-18 15:55:00 +03:00
publish: add nicknames and sigils to interface
This commit is contained in:
parent
ffff42d371
commit
e59b783337
@ -1,7 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import moment from 'moment';
|
||||
import { Sigil } from './icons/sigil';
|
||||
import { uxToHex } from '../../lib/util';
|
||||
|
||||
//TODO take props and render div
|
||||
export class CommentItem extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
@ -36,12 +37,31 @@ export class CommentItem extends Component {
|
||||
});
|
||||
let date = moment(commentData["date-created"]).fromNow();
|
||||
|
||||
let contact = !!(commentData.author.substr(1) in this.props.contacts)
|
||||
? this.props.contacts[commentData.author.substr(1)] : false;
|
||||
|
||||
let name = commentData.author;
|
||||
let color = "#000000";
|
||||
if (contact) {
|
||||
name = (contact.nickname.length > 0)
|
||||
? contact.nickname : commentData.author;
|
||||
color = `#${uxToHex(contact.color)}`;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex mv3">
|
||||
<div className="f9 mono mr2">{commentData.author}</div>
|
||||
<div className="f9 gray3">{date}</div>
|
||||
<Sigil
|
||||
ship={commentData.author}
|
||||
size={24}
|
||||
color={color}
|
||||
/>
|
||||
<div className={"f9 mh2 pt1" +
|
||||
((name === commentData.author) ? " mono" : "")}>
|
||||
{name}
|
||||
</div>
|
||||
<div className="f9 gray3 pt1">{date}</div>
|
||||
</div>
|
||||
<div className="f8 lh-solid mb8 mb2">
|
||||
{content}
|
||||
|
@ -34,7 +34,11 @@ export class Comments extends Component {
|
||||
render() {
|
||||
let commentArray = this.props.comments.map((com, i) => {
|
||||
return (
|
||||
<CommentItem comment={com} key={i}/>
|
||||
<CommentItem
|
||||
comment={com}
|
||||
key={i}
|
||||
contacts={this.props.contacts}
|
||||
/>
|
||||
);
|
||||
})
|
||||
|
||||
|
@ -1,18 +1,21 @@
|
||||
import React, { Component } from 'react';
|
||||
import { sigil, reactRenderer } from 'urbit-sigil-js';
|
||||
|
||||
|
||||
export class Sigil extends Component {
|
||||
render() {
|
||||
const { props } = this;
|
||||
|
||||
let classes = props.classes || "";
|
||||
|
||||
if (props.ship.length > 14) {
|
||||
return (
|
||||
<div className="bg-black flex-shrink-0" style={{width: props.size, height: props.size}}>
|
||||
<div className="bg-black dib" style={{ width: props.size, height: props.size }}>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="dib flex-shrink-0" style={{ flexBasis: 32, backgroundColor: props.color }}>
|
||||
<div className={"dib " + classes} style={{ flexBasis: props.size, backgroundColor: props.color }}>
|
||||
{sigil({
|
||||
patp: props.ship,
|
||||
renderer: reactRenderer,
|
||||
@ -24,3 +27,4 @@ export class Sigil extends Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,20 +89,30 @@ export class Note extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let notebook = this.props.notebooks[this.props.ship][this.props.book];
|
||||
let comments = notebook.notes[this.props.note].comments;
|
||||
let title = notebook.notes[this.props.note].title;
|
||||
let author = notebook.notes[this.props.note].author;
|
||||
let file = notebook.notes[this.props.note].file;
|
||||
let date = moment(notebook.notes[this.props.note]["date-created"]).fromNow();
|
||||
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 contact = !!(author.substr(1) in props.contacts)
|
||||
? props.contacts[author.substr(1)] : false;
|
||||
|
||||
let name = author;
|
||||
if (contact) {
|
||||
name = (contact.nickname.length > 0)
|
||||
? contact.nickname : author;
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let newfile = file.slice(file.indexOf(';>')+2);
|
||||
let prevId = notebook.notes[this.props.note]["prev-note"];
|
||||
let nextId = notebook.notes[this.props.note]["next-note"];
|
||||
let prevId = notebook.notes[props.note]["prev-note"];
|
||||
let nextId = notebook.notes[props.note]["next-note"];
|
||||
|
||||
let prev = (prevId === null)
|
||||
? null
|
||||
@ -129,7 +139,10 @@ export class Note extends Component {
|
||||
<div className="flex flex-column">
|
||||
<div className="f9 mb1">{title}</div>
|
||||
<div className="flex mb6">
|
||||
<div className="di f9 mono gray2 mr2">{author}</div>
|
||||
<div className={"di f9 gray2 mr2 " +
|
||||
((name === author) ? "mono" : "")}>
|
||||
{name}
|
||||
</div>
|
||||
<div className="di f9 gray2">{date}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -139,12 +152,14 @@ export class Note extends Component {
|
||||
<NoteNavigation
|
||||
prev={prev}
|
||||
next={next}
|
||||
ship={this.props.ship}
|
||||
book={this.props.book}/>
|
||||
<Comments ship={this.props.ship}
|
||||
book={this.props.book}
|
||||
note={this.props.note}
|
||||
comments={comments}/>
|
||||
ship={props.ship}
|
||||
book={props.book}/>
|
||||
<Comments ship={props.ship}
|
||||
book={props.book}
|
||||
note={props.note}
|
||||
comments={comments}
|
||||
contacts={props.contacts}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,12 +13,27 @@ export class NotebookItem extends Component {
|
||||
let unread = (props.unreadCount > 0)
|
||||
? `${props.unreadCount} unread` : "";
|
||||
|
||||
let notebookContacts = (props.contactsPath in props.contacts)
|
||||
? props.contacts[props.contactsPath] : {};
|
||||
let contact = !!(props.author.substr(1) in notebookContacts)
|
||||
? notebookContacts[props.author.substr(1)] : false;
|
||||
|
||||
let name = props.author;
|
||||
if (contact) {
|
||||
name = (contact.nickname.length > 0)
|
||||
? contact.nickname : props.author;
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={"/~publish/notebook/" + props.path}>
|
||||
<div className={"w-100 v-mid f9 pl4 bb " + selectedClass}>
|
||||
<p className="f9 pt1">{props.title}</p>
|
||||
<p className="f9 mono gray2">by {props.author}</p>
|
||||
<p className="f9 gray2">by
|
||||
<span className={"pl1 " + ((name === props.author) ? "mono" : "")}>
|
||||
{name}
|
||||
</span>
|
||||
</p>
|
||||
<p className="f9 pb1">
|
||||
{postCount}
|
||||
<span className="green2 ml3">
|
||||
|
@ -30,14 +30,24 @@ export class NotebookPosts extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props } = this;
|
||||
let notes = [];
|
||||
|
||||
for (var i=0; i<this.props.list.length; i++) {
|
||||
let noteId = this.props.list[i];
|
||||
let note = this.props.notes[noteId];
|
||||
for (var i=0; i<props.list.length; i++) {
|
||||
let noteId = props.list[i];
|
||||
let note = props.notes[noteId];
|
||||
if (!note) {
|
||||
break;
|
||||
}
|
||||
|
||||
let contact = !!(note.author.substr(1) in props.contacts)
|
||||
? props.contacts[note.author.substr(1)] : false;
|
||||
|
||||
let name = note.author;
|
||||
if (contact) {
|
||||
name = (contact.nickname.length > 0)
|
||||
? contact.nickname : note.author;
|
||||
}
|
||||
let comment = "No Comments";
|
||||
if (note["num-comments"] == 1) {
|
||||
comment = "1 Comment";
|
||||
@ -45,7 +55,7 @@ export class NotebookPosts extends Component {
|
||||
comment = `${note["num-comments"]} Comments`;
|
||||
}
|
||||
let date = moment(note["date-created"]).fromNow();
|
||||
let url = `/~publish/note/${this.props.host}/${this.props.notebookName}/${noteId}`
|
||||
let url = `/~publish/note/${props.host}/${props.notebookName}/${noteId}`
|
||||
|
||||
notes.push(
|
||||
<Link key={i} to={url}>
|
||||
@ -53,7 +63,8 @@ export class NotebookPosts extends Component {
|
||||
<div className="mb1">{note.title}</div>
|
||||
<p className="mb1">{note.snippet}</p>
|
||||
<div className="flex">
|
||||
<div className="mono gray2 mr3">{note.author}</div>
|
||||
<div className={((note.author === name) ? "mono" : "") +
|
||||
" gray2 mr3"}>{name}</div>
|
||||
<div className="gray2 mr3">{date}</div>
|
||||
<div className="gray2">{comment}</div>
|
||||
</div>
|
||||
|
@ -69,7 +69,9 @@ export class Notebook extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let notebook = this.props.notebooks[this.props.ship][this.props.book];
|
||||
const { props } = this;
|
||||
|
||||
let notebook = props.notebooks[props.ship][props.book];
|
||||
|
||||
let tabStyles = {
|
||||
posts: "bb b--gray4 gray2 pv4 ph2",
|
||||
@ -77,17 +79,19 @@ export class Notebook extends Component {
|
||||
// subscribers: "bb b--gray4 gray2 pv4 ph2",
|
||||
// settings: "bb b--gray4 pr2 gray2 pv4 ph2",
|
||||
};
|
||||
tabStyles[this.props.view] = "bb b--black black pv4 ph2";
|
||||
tabStyles[props.view] = "bb b--black black pv4 ph2";
|
||||
|
||||
let inner = null;
|
||||
switch (this.props.view) {
|
||||
switch (props.view) {
|
||||
case "posts":
|
||||
let notesList = notebook["notes-by-date"] || [];
|
||||
let notes = notebook.notes || null;
|
||||
inner = <NotebookPosts notes={notes}
|
||||
list={notesList}
|
||||
host={this.props.ship}
|
||||
notebookName={this.props.book}/>
|
||||
host={props.ship}
|
||||
notebookName={props.book}
|
||||
contacts={props.contacts}
|
||||
/>
|
||||
break;
|
||||
case "about":
|
||||
inner = <p className="f8 lh-solid">{notebook.about}</p>
|
||||
@ -102,16 +106,24 @@ export class Notebook extends Component {
|
||||
break;
|
||||
}
|
||||
|
||||
let base = `/~publish/notebook/${this.props.ship}/${this.props.book}`;
|
||||
let contact = !!(props.ship.substr(1) in props.contacts)
|
||||
? props.contacts[props.ship.substr(1)] : false;
|
||||
let name = props.ship;
|
||||
if (contact) {
|
||||
name = (contact.nickname.length > 0)
|
||||
? contact.nickname : props.ship;
|
||||
}
|
||||
|
||||
let base = `/~publish/notebook/${props.ship}/${props.book}`;
|
||||
let about = base + '/about';
|
||||
let subs = base + '/subscribers';
|
||||
let settings = base + '/settings';
|
||||
let newUrl = base + '/new';
|
||||
|
||||
let newPost = null;
|
||||
if (notebook["writers-group-path"] in this.props.groups){
|
||||
if (notebook["writers-group-path"] in props.groups){
|
||||
let writers = notebook["writers-group-path"];
|
||||
if (this.props.groups[writers].has(window.ship)) {
|
||||
if (props.groups[writers].has(window.ship)) {
|
||||
newPost =
|
||||
<Link to={newUrl} className="NotebookButton bg-light-green green2">
|
||||
New Post
|
||||
@ -119,7 +131,7 @@ export class Notebook extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
let unsub = (window.ship === this.props.ship.slice(1))
|
||||
let unsub = (window.ship === props.ship.slice(1))
|
||||
? null
|
||||
: <button onClick={this.unsubscribe}
|
||||
className="NotebookButton bg-white black ba b--black ml3">
|
||||
@ -143,7 +155,9 @@ export class Notebook extends Component {
|
||||
<div className="mb1">{notebook.title}</div>
|
||||
<span>
|
||||
<span className="gray3 mr1">by</span>
|
||||
<span className="mono">{this.props.ship}</span>
|
||||
<span className={(props.ship === name) ? "mono" : ""}>
|
||||
{name}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex">
|
||||
|
@ -126,6 +126,8 @@ export class Sidebar extends Component {
|
||||
key={book.title}
|
||||
title={book.title}
|
||||
author={author}
|
||||
contacts={props.contacts}
|
||||
contactsPath={book["subscribers-group-path"]}
|
||||
path={path}
|
||||
total={book["num-notes"]}
|
||||
unreadCount={book["num-unread"]}
|
||||
|
@ -21,6 +21,8 @@ export class Root extends Component {
|
||||
render() {
|
||||
const { props, state } = this;
|
||||
|
||||
let contacts = !!state.contacts ? state.contacts : {};
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Route exact path="/~publish"
|
||||
@ -32,7 +34,8 @@ export class Root extends Component {
|
||||
rightPanelHide={true}
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}>
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}>
|
||||
<div className={`h-100 w-100 overflow-x-hidden flex flex-column
|
||||
bg-white bg-gray0-d dn db-ns`}>
|
||||
<div className="pl3 pr3 pt2 dt pb3 w-100 h-100">
|
||||
@ -54,7 +57,8 @@ export class Root extends Component {
|
||||
rightPanelHide={false}
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}>
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}>
|
||||
<NewScreen
|
||||
notebooks={state.notebooks}
|
||||
groups={state.groups}
|
||||
@ -73,7 +77,8 @@ export class Root extends Component {
|
||||
rightPanelHide={false}
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}>
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}>
|
||||
<JoinScreen notebooks={state.notebooks} {...props} />
|
||||
</Skeleton>
|
||||
)
|
||||
@ -89,6 +94,11 @@ export class Root extends Component {
|
||||
|
||||
let path = `${ship}/${notebook}`;
|
||||
|
||||
let bookGroupPath =
|
||||
state.notebooks[ship][notebook]["subscribers-group-path"];
|
||||
let notebookContacts = (bookGroupPath in contacts)
|
||||
? contacts[bookGroupPath] : {};
|
||||
|
||||
if (view === "new") {
|
||||
return (
|
||||
<Skeleton
|
||||
@ -98,6 +108,7 @@ export class Root extends Component {
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}
|
||||
path={path}>
|
||||
<NewPost
|
||||
notebooks={state.notebooks}
|
||||
@ -117,6 +128,7 @@ export class Root extends Component {
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}
|
||||
path={path}>
|
||||
<Notebook
|
||||
notebooks={state.notebooks}
|
||||
@ -124,6 +136,7 @@ export class Root extends Component {
|
||||
ship={ship}
|
||||
book={notebook}
|
||||
groups={state.groups}
|
||||
contacts={notebookContacts}
|
||||
{...props}
|
||||
/>
|
||||
</Skeleton>
|
||||
@ -137,6 +150,11 @@ export class Root extends Component {
|
||||
let path = `${ship}/${notebook}`
|
||||
let note = props.match.params.note || "";
|
||||
|
||||
let bookGroupPath =
|
||||
state.notebooks[ship][notebook]["subscribers-group-path"];
|
||||
let notebookContacts = (bookGroupPath in state.contacts)
|
||||
? contacts[bookGroupPath] : {};
|
||||
|
||||
return (
|
||||
<Skeleton
|
||||
popout={false}
|
||||
@ -145,10 +163,12 @@ export class Root extends Component {
|
||||
sidebarShown={true}
|
||||
invites={state.invites}
|
||||
notebooks={state.notebooks}
|
||||
contacts={contacts}
|
||||
path={path}>
|
||||
<Note
|
||||
notebooks={state.notebooks}
|
||||
book={notebook}
|
||||
contacts={notebookContacts}
|
||||
ship={ship}
|
||||
note={note}
|
||||
/>
|
||||
|
@ -29,6 +29,7 @@ export class Skeleton extends Component {
|
||||
sidebarShown={props.sidebarShown}
|
||||
active={props.active}
|
||||
notebooks={props.notebooks}
|
||||
contacts={props.contacts}
|
||||
path={props.path}
|
||||
invites={props.invites}
|
||||
/>
|
||||
|
@ -36,3 +36,13 @@ export function dateToDa(d, mil) {
|
||||
`${mil ? "..0000" : ""}`
|
||||
);
|
||||
}
|
||||
|
||||
export function uxToHex(ux) {
|
||||
if (ux.length > 2 && ux.substr(0, 2) === '0x') {
|
||||
let value = ux.substr(2).replace('.', '').padStart(6, '0');
|
||||
return value;
|
||||
}
|
||||
|
||||
let value = ux.replace('.', '').padStart(6, '0');
|
||||
return value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user