Merge pull request #1615 from urbit/publish-fixes

Publish: various fixes and improvements
This commit is contained in:
ixv 2019-08-13 16:17:52 -07:00 committed by GitHub
commit 55d8fe978a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 242 additions and 130 deletions

View File

@ -1268,7 +1268,13 @@
:: ::
%read %read
=. unread.sat (~(del in unread.sat) who.act coll.act post.act) =. unread.sat (~(del in unread.sat) who.act coll.act post.act)
[make-tile-moves this] :_ this
%+ welp make-tile-moves
::
%+ turn (prey:pubsub:userlib /primary bol)
|= [b=bone *]
^- move
[b %diff %publish-update %unread %.n (sy [who.act coll.act post.act] ~)]
:: ::
== ==
:: ::

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -84,6 +84,11 @@
[%base %talk] [%base %talk]
[%base %dojo] [%base %dojo]
[%base %modulo] [%base %modulo]
[%home %launch]
[%home %chat]
[%home %publish]
[%home %clock]
[%home %weather]
== ==
:~ [%home %lens] :~ [%home %lens]
[%home %acme] [%home %acme]

View File

@ -47,7 +47,7 @@
:: ::
++ new-collection ++ new-collection
%- ot:dejs %- ot:dejs
:~ name+(su:dejs sym) :~ name+so:dejs
title+so:dejs title+so:dejs
comments+comment-config comments+comment-config
allow-edit+edit-config allow-edit+edit-config
@ -57,8 +57,8 @@
++ new-post ++ new-post
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
name+(su:dejs sym) name+so:dejs
title+so:dejs title+so:dejs
comments+comment-config comments+comment-config
perm+perm-config perm+perm-config
@ -68,40 +68,40 @@
++ new-comment ++ new-comment
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
name+(su:dejs sym) name+(su:dejs sym)
content+so:dejs content+so:dejs
== ==
:: ::
++ delete-collection ++ delete-collection
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
== ==
:: ::
++ delete-post ++ delete-post
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
post+(su:dejs sym) post+so:dejs
== ==
:: ::
++ delete-comment ++ delete-comment
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
post+(su:dejs sym) post+so:dejs
comment+(su:dejs sym) comment+so:dejs
== ==
:: ::
++ edit-collection ++ edit-collection
%- ot:dejs %- ot:dejs
:~ name+(su:dejs sym) :~ name+so:dejs
title+so:dejs title+so:dejs
== ==
:: ::
++ edit-post ++ edit-post
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
name+(su:dejs sym) name+so:dejs
title+so:dejs title+so:dejs
comments+comment-config comments+comment-config
perm+perm-config perm+perm-config
@ -110,9 +110,9 @@
:: ::
++ edit-comment ++ edit-comment
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
name+(su:dejs sym) name+so:dejs
id+(su:dejs sym) id+so:dejs
content+so:dejs content+so:dejs
== ==
:: ::
@ -147,7 +147,7 @@
:: ::
++ invite ++ invite
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
title+so:dejs title+so:dejs
who+(ar:dejs (su:dejs fed:ag)) who+(ar:dejs (su:dejs fed:ag))
== ==
@ -155,36 +155,36 @@
++ reject-invite ++ reject-invite
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
== ==
:: ::
++ serve ++ serve
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
== ==
:: ::
++ unserve ++ unserve
%- ot:dejs %- ot:dejs
:~ coll+(su:dejs sym) :~ coll+so:dejs
== ==
:: ::
++ subscribe ++ subscribe
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
== ==
:: ::
++ unsubscribe ++ unsubscribe
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
== ==
:: ::
++ read ++ read
%- ot:dejs %- ot:dejs
:~ who+(su:dejs fed:ag) :~ who+(su:dejs fed:ag)
coll+(su:dejs sym) coll+so:dejs
post+(su:dejs sym) post+so:dejs
== ==
:: ::
-- --

View File

@ -19,6 +19,21 @@
[%coll s+col.upd] [%coll s+col.upd]
[%title s+title.upd] [%title s+title.upd]
== ==
::
%unread
%- pairs
:~ [%add b+add.upd]
:+ %posts
%a
%+ turn ~(tap in keys.upd)
|= [who=@p coll=@tas post=@tas]
^- ^json
%- pairs
:~ [%who (ship who)]
[%coll s+coll]
[%post s+post]
==
==
:: ::
== ==
:: ::

View File

@ -108,5 +108,6 @@
:: ::
+$ update +$ update
$% [%invite add=? who=@p col=@tas title=@t] $% [%invite add=? who=@p col=@tas title=@t]
[%unread add=? keys=(set [who=@p coll=@tas post=@tas])]
== ==
-- --

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { PostPreview } from '/components/lib/post-preview';
import _ from 'lodash'; import _ from 'lodash';
import { PathControl } from '/components/lib/path-control'; import { PathControl } from '/components/lib/path-control';
import { BlogData } from '/components/lib/blog-data'; import { BlogData } from '/components/lib/blog-data';
@ -82,8 +81,8 @@ export class Blog extends Component {
let blogId = this.props.blogId; let blogId = this.props.blogId;
let blog = (ship === window.ship) let blog = (ship === window.ship)
? _.get(this.props, `pubs[${blogId}]`, false) ? _.get(this.props, `pubs["${blogId}"]`, false)
: _.get(this.props, `subs[${ship}][${blogId}]`, false); : _.get(this.props, `subs["${ship}"]["${blogId}"]`, false);
if (!(blog) && (ship === window.ship)) { if (!(blog) && (ship === window.ship)) {
@ -110,8 +109,8 @@ export class Blog extends Component {
let ship = this.props.ship; let ship = this.props.ship;
let blogId = this.props.blogId; let blogId = this.props.blogId;
let blog = (ship == window.ship) let blog = (ship == window.ship)
? _.get(this.props, `pubs[${blogId}]`, false) ? _.get(this.props, `pubs["${blogId}"]`, false)
: _.get(this.props, `subs[${ship}][${blogId}]`, false); : _.get(this.props, `subs["${ship}"]["${blogId}"]`, false);
if (!(blog) && (ship === window.ship)) { if (!(blog) && (ship === window.ship)) {
this.setState({notFound: true}); this.setState({notFound: true});
@ -158,6 +157,13 @@ export class Blog extends Component {
} }
buildPostPreviewProps(post, blog, pinned){ buildPostPreviewProps(post, blog, pinned){
let unread = (-1 === _.findIndex(this.props.unread, {
post: post.post.info.filename,
coll: blog.info.filename,
who: blog.info.owner.slice(1),
}))
? false: true;
return { return {
postTitle: post.post.info.title, postTitle: post.post.info.title,
postName: post.post.info.filename, postName: post.post.info.filename,
@ -169,13 +175,14 @@ export class Blog extends Component {
blogOwner: blog.info.owner, blogOwner: blog.info.owner,
date: post.post.info["date-created"], date: post.post.info["date-created"],
pinned: pinned, pinned: pinned,
unread: unread,
} }
} }
buildData(){ buildData(){
let blog = (this.props.ship == window.ship) let blog = (this.props.ship == window.ship)
? _.get(this.props, `pubs[${this.props.blogId}]`, false) ? _.get(this.props, `pubs["${this.props.blogId}"]`, false)
: _.get(this.props, `subs[${this.props.ship}][${this.props.blogId}]`, false); : _.get(this.props, `subs["${this.props.ship}"]["${this.props.blogId}"]`, false);
if (this.state.temporary) { if (this.state.temporary) {
return { return {
@ -228,17 +235,14 @@ export class Blog extends Component {
} }
viewSubs() { viewSubs() {
console.log("view subs");
this.setState({view: 'subs'}); this.setState({view: 'subs'});
} }
viewSettings() { viewSettings() {
console.log("view settings");
this.setState({view: 'settings'}); this.setState({view: 'settings'});
} }
viewNotes() { viewNotes() {
console.log("view notes");
this.setState({view: 'notes'}); this.setState({view: 'notes'});
} }
@ -259,7 +263,7 @@ export class Blog extends Component {
let subNum = _.get(data.blog, 'subscribers.length', 0); let subNum = _.get(data.blog, 'subscribers.length', 0);
let foreign = _.get(this.props, let foreign = _.get(this.props,
`subs[${this.props.ship}][${this.props.blogId}]`, false); `subs["${this.props.ship}"]["${this.props.blogId}"]`, false);
let actionType = false; let actionType = false;
if (this.state.temporary) { if (this.state.temporary) {

View File

@ -6,9 +6,6 @@ export class Sigil extends Component {
render() { render() {
const { props } = this; const { props } = this;
console.log("sigil ship", props.ship);
if (props.ship.length > 14) { if (props.ship.length > 14) {
return ( return (
<div className="bg-black" style={{width: 44, height: 44}}> <div className="bg-black" style={{width: 44, height: 44}}>

View File

@ -64,13 +64,14 @@ class Preview extends Component {
return ( return (
<div className="w-336"> <div className="w-336">
<Link className="ml2 mr2 gray-50 body-regular" to={prevUrl}> <Link className="ml2 mr2 gray-50 body-regular db mb3" to={prevUrl}>
{this.props.text} {this.props.text}
</Link> </Link>
<div className="w-336 relative" <div className="w-336 relative"
style={{height:195}}> style={{height:210}}>
<Link to={postLink}> <Link to={postLink} className="db">
<TitleSnippet title={previewProps.postTitle}/> <TitleSnippet badge={false} title={previewProps.postTitle} />
<div className="w-100" style={{height:16}}></div>
<PostSnippet <PostSnippet
body={previewProps.postBody} body={previewProps.postBody}
/> />

View File

@ -31,9 +31,9 @@ export class PathControl extends Component {
if ((last.lastMatch === '/~publish/:ship/:blog/:post') || if ((last.lastMatch === '/~publish/:ship/:blog/:post') ||
(last.lastMatch === '/~publish/:ship/:blog')){ (last.lastMatch === '/~publish/:ship/:blog')){
blog = (last.lastParams.ship.slice(1) == window.ship) blog = (last.lastParams.ship.slice(1) == window.ship)
? _.get(this.props, `pubs[${last.lastParams.blog}]`, false) ? _.get(this.props, `pubs["${last.lastParams.blog}"]`, false)
: _.get(this.props, : _.get(this.props,
`subs[${last.lastParams.ship.slice(1)}][${last.lastParams.blog}]`, false); `subs["${last.lastParams.ship.slice(1)}"]["${last.lastParams.blog}"]`, false);
} }
} }

View File

@ -59,6 +59,11 @@ export class PostBody extends Component {
return element; return element;
} }
renderHR(what, node, attr, parentNode) {
const element = React.createElement(node, attr);
return element;
}
renderDefault(what, node, attr, parentNode) { renderDefault(what, node, attr, parentNode) {
let dStyle = { let dStyle = {
wordWrap: "break-word", wordWrap: "break-word",
@ -84,6 +89,8 @@ export class PostBody extends Component {
return this.renderIMG(what, node, attr, parentNode); return this.renderIMG(what, node, attr, parentNode);
case "p": case "p":
return this.renderP(what, node, attr, parentNode); return this.renderP(what, node, attr, parentNode);
case "hr":
return this.renderHR(what, node, attr, parentNode);
default: default:
return this.renderDefault(what, node, attr, parentNode); return this.renderDefault(what, node, attr, parentNode);
} }

View File

@ -47,7 +47,7 @@ export class PostPreview extends Component {
<div className="w-336 relative" <div className="w-336 relative"
style={{height:195, marginBottom: 72, marginRight:16}}> style={{height:195, marginBottom: 72, marginRight:16}}>
<Link to={postLink}> <Link to={postLink}>
<TitleSnippet title={this.props.post.postTitle}/> <TitleSnippet badge={this.props.post.unread} title={this.props.post.postTitle}/>
<PostSnippet <PostSnippet
body={this.props.post.postBody} body={this.props.post.postBody}
/> />

View File

@ -47,7 +47,7 @@ export class RecentPreview extends Component {
<div className="w-336 relative" <div className="w-336 relative"
style={{height:240, marginBottom: 72, marginRight: 16}}> style={{height:240, marginBottom: 72, marginRight: 16}}>
<Link to={postLink}> <Link to={postLink}>
<TitleSnippet title={this.props.post.postTitle}/> <TitleSnippet badge={this.props.post.unread} title={this.props.post.postTitle}/>
<PostSnippet <PostSnippet
body={this.props.post.postBody} body={this.props.post.postBody}
/> />

View File

@ -7,6 +7,17 @@ export class TitleSnippet extends Component {
} }
render() { render() {
if (this.props.badge) {
return (
<div className="body-large two-lines b"
style={{WebkitBoxOrient: "vertical"}}>
<span className="h2 green-medium"></span>
<span>
{this.props.title}
</span>
</div>
);
} else {
return ( return (
<p className="body-large b two-lines" <p className="body-large b two-lines"
style={{WebkitBoxOrient: "vertical"}}> style={{WebkitBoxOrient: "vertical"}}>
@ -14,5 +25,6 @@ export class TitleSnippet extends Component {
</p> </p>
); );
} }
}
} }

View File

@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
import { PathControl } from '/components/lib/path-control'; import { PathControl } from '/components/lib/path-control';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import urbitOb from 'urbit-ob'; import urbitOb from 'urbit-ob';
import { stringToSymbol } from '/lib/util';
const PC = withRouter(PathControl); const PC = withRouter(PathControl);
@ -39,30 +40,14 @@ export class NewBlog extends Component {
this.returnHome = this.returnHome.bind(this); this.returnHome = this.returnHome.bind(this);
this.addInvites = this.addInvites.bind(this); this.addInvites = this.addInvites.bind(this);
this.blogSubmit = this.blogSubmit.bind(this); this.blogSubmit = this.blogSubmit.bind(this);
}
stringToSymbol(str){ this.titleHeight = 52;
let result = '';
for (var i=0; i<str.length; i++){
var n = str.charCodeAt(i);
if (( (n >= 97) && (n <= 122) ) ||
( (n >= 48) && (n <= 57) ))
{
result += str[i];
} else if ( (n >= 65) && (n <= 90) )
{
result += String.fromCharCode(n + 32);
} else {
result += '-';
}
}
return result.replace(/^\-+|\-+$/g, '');
} }
blogSubmit() { blogSubmit() {
let ship = window.ship; let ship = window.ship;
let blogTitle = this.state.title; let blogTitle = this.state.title;
let blogId = this.stringToSymbol(blogTitle); let blogId = stringToSymbol(blogTitle);
let permissions = { let permissions = {
read: { read: {
@ -126,6 +111,11 @@ export class NewBlog extends Component {
} }
titleChange(evt){ titleChange(evt){
this.titleInput.style.height = 'auto';
this.titleInput.style.height = (this.titleInput.scrollHeight < 52)
? 52 : this.titleInput.scrollHeight;
this.titleHeight = this.titleInput.style.height;
this.setState({title: evt.target.value}); this.setState({title: evt.target.value});
} }
@ -172,13 +162,16 @@ export class NewBlog extends Component {
style={{height: 'calc(100% - 124px)', top: 124}}> style={{height: 'calc(100% - 124px)', top: 124}}>
<div className="h-inner dt center mw-688 w-100"> <div className="h-inner dt center mw-688 w-100">
<div className="flex-col dtc v-mid"> <div className="flex-col dtc v-mid">
<input autoFocus <textarea autoFocus
className="header-2 b--none" ref={(el) => {this.titleInput = el}}
className="header-2 b--none w-100"
style={{resize:"none", height: this.titleHeight}}
rows={1}
type="text" type="text"
name="blogName" name="blogName"
placeholder="Add a Title" placeholder="Add a Title"
onChange={this.titleChange} onChange={this.titleChange}>
/> </textarea>
<hr className="gray-30" style={{marginTop:32, marginBottom: 32}}/> <hr className="gray-30" style={{marginTop:32, marginBottom: 32}}/>
@ -219,13 +212,16 @@ export class NewBlog extends Component {
style={{height: 'calc(100% - 124px)', top: 124}}> style={{height: 'calc(100% - 124px)', top: 124}}>
<div className="h-inner dt center mw-688 w-100"> <div className="h-inner dt center mw-688 w-100">
<div className="flex-col dtc v-mid"> <div className="flex-col dtc v-mid">
<input autoFocus <textarea autoFocus
className="header-2 b--none" ref={(el) => {this.titleInput = el}}
className="header-2 b--none w-100"
style={{resize:"none", height: this.titleHeight}}
rows={1}
type="text" type="text"
name="blogName" name="blogName"
placeholder="Add a Title" placeholder="Add a Title"
onChange={this.titleChange} onChange={this.titleChange}>
/> </textarea>
<p className="body-regular-400" style={{marginTop:25, marginBottom:27}}> <p className="body-regular-400" style={{marginTop:25, marginBottom:27}}>
Who is invited to read this notebook? Who is invited to read this notebook?

View File

@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
import _ from 'lodash'; import _ from 'lodash';
import { PathControl } from '/components/lib/path-control'; import { PathControl } from '/components/lib/path-control';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { stringToSymbol } from '/lib/util';
const PC = withRouter(PathControl); const PC = withRouter(PathControl);
@ -67,8 +68,6 @@ export class NewPost extends Component {
constructor(props){ constructor(props){
super(props); super(props);
console.log("props", this.props);
this.state = { this.state = {
title: "", title: "",
body: "", body: "",
@ -92,24 +91,6 @@ export class NewPost extends Component {
this.comments = false; this.comments = false;
} }
stringToSymbol(str){
let result = '';
for (var i=0; i<str.length; i++){
var n = str.charCodeAt(i);
if (( (n >= 97) && (n <= 122) ) ||
( (n >= 48) && (n <= 57) ))
{
result += str[i];
} else if ( (n >= 65) && (n <= 90) )
{
result += String.fromCharCode(n + 32);
} else {
result += '-';
}
}
return result.replace(/^\-+|\-+$/g, '');
}
postSubmit() { postSubmit() {
let last = _.get(this.props, 'location.state', false); let last = _.get(this.props, 'location.state', false);
let ship = window.ship; let ship = window.ship;
@ -121,7 +102,7 @@ export class NewPost extends Component {
} }
let postTitle = this.state.title; let postTitle = this.state.title;
let postId = this.stringToSymbol(postTitle); let postId = stringToSymbol(postTitle);
let awaiting = Object.assign({}, { let awaiting = Object.assign({}, {
ship: ship, ship: ship,
@ -202,17 +183,17 @@ export class NewPost extends Component {
if (ship == window.ship) { if (ship == window.ship) {
post = post =
_.get(this.props, _.get(this.props,
`pubs[${blogId}].posts[${postId}].post`, false) || false; `pubs["${blogId}"].posts["${postId}"].post`, false) || false;
comments = comments =
_.get(this.props, _.get(this.props,
`pubs[${blogId}].posts[${postId}].comments`, false) || false; `pubs["${blogId}"].posts["${postId}"].comments`, false) || false;
} else { } else {
post = post =
_.get(this.props, _.get(this.props,
`subs[${ship}][${blogId}].posts[${postId}].post`, false) || false; `subs["${ship}"]["${blogId}"].posts["${postId}"].post`, false) || false;
comments = comments =
_.get(this.props, _.get(this.props,
`subs[${ship}][${blogId}].posts[${postId}].comments`, false) || false; `subs["${ship}"]["${blogId}"].posts["${postId}"].comments`, false) || false;
} }
if (!_.isEqual(this.post, post)) { if (!_.isEqual(this.post, post)) {

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { PostPreview } from '/components/lib/post-preview';
import moment from 'moment'; import moment from 'moment';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { PostBody } from '/components/lib/post-body'; import { PostBody } from '/components/lib/post-body';
@ -159,11 +158,11 @@ export class Post extends Component {
if (ship !== window.ship) { if (ship !== window.ship) {
let blog = _.get(this.props, `subs[${ship}][${blogId}]`, false); let blog = _.get(this.props, `subs["${ship}"]["${blogId}"]`, false);
if (blog) { if (blog) {
let post = _.get(blog, `posts[${postId}].post`, false); let post = _.get(blog, `posts["${postId}"].post`, false);
let comments = _.get(blog, `posts[${postId}].comments`, false); let comments = _.get(blog, `posts["${postId}"].comments`, false);
let blogUrl = `/~publish/${blog.info.owner}/${blog.info.filename}`; let blogUrl = `/~publish/${blog.info.owner}/${blog.info.filename}`;
let postUrl = `${blogUrl}/${post.info.filename}`; let postUrl = `${blogUrl}/${post.info.filename}`;
@ -208,9 +207,9 @@ export class Post extends Component {
this.handleError.bind(this)); this.handleError.bind(this));
} }
} else { } else {
let blog = _.get(this.props, `pubs[${blogId}]`, false); let blog = _.get(this.props, `pubs["${blogId}"]`, false);
let post = _.get(blog, `posts[${postId}].post`, false); let post = _.get(blog, `posts["${postId}"].post`, false);
let comments = _.get(blog, `posts[${postId}].comments`, false); let comments = _.get(blog, `posts["${postId}"].comments`, false);
if (!blog || !post) { if (!blog || !post) {
this.setState({notFound: true}); this.setState({notFound: true});
@ -303,13 +302,13 @@ export class Post extends Component {
let blog; let blog;
if (ship === window.ship) { if (ship === window.ship) {
blog = _.get(this.props, `pubs[${blogId}]`, false); blog = _.get(this.props, `pubs["${blogId}"]`, false);
post = _.get(blog, `posts[${postId}].post`, false); post = _.get(blog, `posts["${postId}"].post`, false);
comments = _.get(blog, `posts[${postId}].comments`, false); comments = _.get(blog, `posts["${postId}"].comments`, false);
} else { } else {
blog = _.get(this.props, `subs[${ship}][${blogId}]`, false); blog = _.get(this.props, `subs["${ship}"]["${blogId}"]`, false);
post = _.get(blog, `posts[${postId}].post`, false); post = _.get(blog, `posts["${postId}"].post`, false);
comments = _.get(blog, `posts[${postId}].comments`, false); comments = _.get(blog, `posts["${postId}"].comments`, false);
} }
@ -329,6 +328,9 @@ export class Post extends Component {
((post.info.title != oldPost.info.title) || ((post.info.title != oldPost.info.title) ||
(post.raw != oldPost.raw))) { (post.raw != oldPost.raw))) {
let blogUrl = `/~publish/${blog.info.owner}/${blog.info.filename}`;
let postUrl = `${blogUrl}/${post.info.filename}`;
this.setState({ this.setState({
mode: 'view', mode: 'view',
titleOriginal: post.info.title, titleOriginal: post.info.title,
@ -337,18 +339,49 @@ export class Post extends Component {
body: post.raw, body: post.raw,
awaitingEdit: false, awaitingEdit: false,
post: post, post: post,
pathData: [
{ text: "Home", url: "/~publish/recent" },
{ text: blog.info.title, url: blogUrl },
{ text: post.info.title, url: postUrl },
],
}); });
this.props.setSpinner(false); this.props.setSpinner(false);
let read = {
read: {
who: ship,
coll: blogId,
post: postId,
}
};
this.props.api.action("publish", "publish-action", read);
} }
if (!this.state.temporary){ if (!this.state.temporary){
if (oldPost != post) { if (oldPost != post) {
let blogUrl = `/~publish/${blog.info.owner}/${blog.info.filename}`;
let postUrl = `${blogUrl}/${post.info.filename}`;
this.setState({ this.setState({
titleOriginal: post.info.title, titleOriginal: post.info.title,
bodyOriginal: post.raw, bodyOriginal: post.raw,
post: post, post: post,
pathData: [
{ text: "Home", url: "/~publish/recent" },
{ text: blog.info.title, url: blogUrl },
{ text: post.info.title, url: postUrl },
],
}); });
let read = {
read: {
who: ship,
coll: blogId,
post: postId,
}
};
this.props.api.action("publish", "publish-action", read);
} }
if (oldComments != comments) { if (oldComments != comments) {
this.setState({comments: comments}); this.setState({comments: comments});

View File

@ -51,6 +51,13 @@ export class Recent extends Component {
let col = this.retrieveColl(coll, who); let col = this.retrieveColl(coll, who);
let com = this.retrieveComments(post, coll, who); let com = this.retrieveComments(post, coll, who);
let unread = (-1 === _.findIndex(this.props.unread, {
post: post,
coll: coll,
who: who,
}))
? false: true;
return { return {
postTitle: pos.info.title, postTitle: pos.info.title,
postName: post, postName: post,
@ -60,7 +67,8 @@ export class Recent extends Component {
collectionName: coll, collectionName: coll,
author: pos.info.creator.slice(1), author: pos.info.creator.slice(1),
blogOwner: who, blogOwner: who,
date: pos.info["date-created"] date: pos.info["date-created"],
unread: unread,
} }
} }

View File

@ -1,9 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { BrowserRouter, Route } from "react-router-dom"; import { BrowserRouter, Route } from "react-router-dom";
import Mousetrap from 'mousetrap';
import classnames from 'classnames'; import classnames from 'classnames';
import _ from 'lodash';
import { api } from '/api'; import { api } from '/api';
import { store } from '/store'; import { store } from '/store';
import { Recent } from '/components/recent'; import { Recent } from '/components/recent';

View File

@ -0,0 +1,38 @@
export function stringToSymbol(str) {
let result = '';
for (var i=0; i<str.length; i++){
var n = str.charCodeAt(i);
if (( (n >= 97) && (n <= 122) ) ||
( (n >= 48) && (n <= 57) ))
{
result += str[i];
} else if ( (n >= 65) && (n <= 90) )
{
result += String.fromCharCode(n + 32);
} else {
result += '-';
}
}
result = result.replace(/^[\-\d]+|\-+/g, '-');
result = result.replace(/^\-+|\-+$/g, '');
if (result === ''){
return dateToDa(new Date());
}
return result;
}
export function dateToDa(d, mil) {
  var fil = function(n) {
    return n >= 10 ? n : "0" + n;
  };
  return (
    `~${d.getUTCFullYear()}.` +
    `${(d.getUTCMonth() + 1)}.` +
    `${fil(d.getUTCDate())}..` +
    `${fil(d.getUTCHours())}.` +
    `${fil(d.getUTCMinutes())}.` +
    `${fil(d.getUTCSeconds())}` +
`${mil ? "..0000" : ""}`
  );
}

View File

@ -3,22 +3,34 @@ import _ from 'lodash';
export class UpdateReducer { export class UpdateReducer {
reduce(json, state){ reduce(json, state){
if (json.invite) { if (json.invite) {
this.reduceInvite(json, state); this.reduceInvite(json.invite, state);
} else if (json.unread) {
this.reduceUnread(json.unread, state);
} }
} }
reduceInvite(json, state) { reduceInvite(json, state) {
let val = { let val = {
title: json.invite.title, title: json.title,
coll: json.invite.coll, coll: json.coll,
who: json.invite.who, who: json.who,
}; };
if (json.invite.add) { if (json.add) {
state.invites.push(val); state.invites.push(val);
} else { } else {
let idx = _.findIndex(state.invites, val) let idx = _.findIndex(state.invites, val)
_.pullAt(state.invites, [idx]); _.pullAt(state.invites, [idx]);
} }
}
reduceUnread(json, state) {
if (json.add) {
state.unread = _.uniq(state.unread.concat(json.posts));
} else {
let idx = json.posts.map((val) => {
return _.findIndex(state.unread, val);
});
_.pullAt(state.unread, idx);
}
} }
} }

View File

@ -1,5 +1,4 @@
import { api } from '/api'; import { api } from '/api';
import _ from 'lodash';
import { store } from '/store'; import { store } from '/store';