mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-09-20 15:08:34 +03:00
pass snippet and about field from backend
wire up routing for notebook page add infinite scroll and note fetching logic to notebook page
This commit is contained in:
parent
fe44b25f92
commit
919db6a3be
@ -628,10 +628,12 @@
|
||||
++ form-note
|
||||
|= [note-name=@tas udon=@t]
|
||||
^- note
|
||||
=/ build=(each manx tang)
|
||||
%- mule |.
|
||||
^- manx
|
||||
elm:(static:cram (ream udon))
|
||||
=/ body=tape (slag (add 3 (need (find ";>" (trip udon)))) (trip udon))
|
||||
=/ snippet=@t (of-wain:format (scag 1 (to-wain:format (crip body))))
|
||||
:: =/ build=(each manx tang)
|
||||
:: %- mule |.
|
||||
:: ^- manx
|
||||
:: elm:(static:cram (ream udon))
|
||||
::
|
||||
=/ meta=(each (map term knot) tang)
|
||||
%- mule |.
|
||||
@ -658,7 +660,7 @@
|
||||
now.bol
|
||||
%.n
|
||||
udon
|
||||
build
|
||||
snippet
|
||||
~
|
||||
==
|
||||
::
|
||||
@ -1284,7 +1286,7 @@
|
||||
=/ notebook-json (notebook-full-json host book-name u.book)
|
||||
?> ?=(%o -.notebook-json)
|
||||
=. p.notebook-json
|
||||
(~(uni by p.notebook-json) (notes-page notes.u.book 0 50))
|
||||
(~(uni by p.notebook-json) (notes-page notes.u.book 0 10))
|
||||
=. p.notebook-json
|
||||
(~(put by p.notebook-json) %subscribers (get-subscribers-json book-name))
|
||||
=/ notebooks-json (notebooks-map-json our.bol books subs)
|
||||
@ -1418,7 +1420,7 @@
|
||||
=/ notebook-json (notebook-full-json u.host book-name u.book)
|
||||
?> ?=(%o -.notebook-json)
|
||||
=. p.notebook-json
|
||||
(~(uni by p.notebook-json) (notes-page notes.u.book 0 50))
|
||||
(~(uni by p.notebook-json) (notes-page notes.u.book 0 10))
|
||||
=. p.notebook-json
|
||||
(~(put by p.notebook-json) %subscribers (get-subscribers-json book-name))
|
||||
=/ jon=json (pairs notebook+notebook-json ~)
|
||||
|
@ -103,6 +103,7 @@
|
||||
%- pairs
|
||||
:~ title+s+title.book
|
||||
date-created+(time date-created.book)
|
||||
about+s+description.book
|
||||
num-notes+(numb ~(wyt by notes.book))
|
||||
num-unread+(numb (count-unread notes.book))
|
||||
==
|
||||
@ -113,6 +114,7 @@
|
||||
=, enjs:format
|
||||
%- pairs
|
||||
:~ title+s+title.book
|
||||
about+s+description.book
|
||||
date-created+(time date-created.book)
|
||||
num-notes+(numb ~(wyt by notes.book))
|
||||
num-unread+(numb (count-unread notes.book))
|
||||
@ -160,10 +162,10 @@
|
||||
author+s+(scot %p author.note)
|
||||
title+s+title.note
|
||||
date-created+(time date-created.note)
|
||||
build+(note-build-to-json build.note)
|
||||
snippet+s+snippet.note
|
||||
file+s+file.note
|
||||
num-comments+(numb ~(wyt by comments.note))
|
||||
comments+(comments-page comments.note 0 50)
|
||||
comments+(comments-page comments.note 0 10)
|
||||
read+b+read.note
|
||||
==
|
||||
::
|
||||
@ -191,7 +193,7 @@
|
||||
date-created+(time date-created.note)
|
||||
num-comments+(numb ~(wyt by comments.note))
|
||||
read+b+read.note
|
||||
:: XX snippet
|
||||
snippet+s+snippet.note
|
||||
==
|
||||
::
|
||||
++ notes-page
|
||||
|
@ -40,7 +40,8 @@
|
||||
last-edit=@da
|
||||
read=?
|
||||
file=@t
|
||||
build=(each manx tang)
|
||||
snippet=@t
|
||||
:: build=(each manx tang)
|
||||
comments=(map @da comment)
|
||||
==
|
||||
::
|
||||
|
@ -166,3 +166,13 @@ a {
|
||||
[contenteditable]:focus {
|
||||
outline: 0px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export class All extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="mv6">
|
||||
<div className="mb1">Title</div>
|
||||
<p className="mb1">I dreamt of urbit hardware - stars and galaxies and planets had differing...</p>
|
||||
<div className="flex">
|
||||
<div className="mono gray2 mr3">~fabled-faster</div>
|
||||
<div className="gray2 mr3">1m ago</div>
|
||||
<div className="gray2">No Comments</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default All
|
@ -8,7 +8,7 @@ export class NewPost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
body: "# Hello",
|
||||
body: '',
|
||||
title: '',
|
||||
submit: false,
|
||||
awaiting: null,
|
||||
@ -81,7 +81,7 @@ export class NewPost extends Component {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<input type="text"
|
||||
<input autoFocus type="text"
|
||||
style={{paddingBottom: 8, paddingTop: 24}}
|
||||
className="w-100"
|
||||
onChange={this.titleChange}
|
||||
|
@ -0,0 +1,73 @@
|
||||
import React, { Component } from 'react';
|
||||
import moment from 'moment';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export class NotebookPosts extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
moment.updateLocale('en', {
|
||||
relativeTime: {
|
||||
past: function(input) {
|
||||
return input === 'just now'
|
||||
? input
|
||||
: input + ' ago'
|
||||
},
|
||||
s : 'just now',
|
||||
future : 'in %s',
|
||||
m : '1m',
|
||||
mm : '%dm',
|
||||
h : '1h',
|
||||
hh : '%dh',
|
||||
d : '1d',
|
||||
dd : '%dd',
|
||||
M : '1 month',
|
||||
MM : '%d months',
|
||||
y : '1 year',
|
||||
yy : '%d years',
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let notes = [];
|
||||
|
||||
for (var i=0; i<this.props.list.length; i++) {
|
||||
let noteId = this.props.list[i];
|
||||
let note = this.props.notes[noteId];
|
||||
if (!note) {
|
||||
break;
|
||||
}
|
||||
let comment = "No Comments";
|
||||
if (note["num-comments"] == 1) {
|
||||
comment = "1 Comment";
|
||||
} else if (note["num-comments"] > 1) {
|
||||
comment = `${note["num-comments"]} Comments`;
|
||||
}
|
||||
let date = moment(note["date-created"]).fromNow();
|
||||
let url = `/~publish/note/${this.props.host}/${this.props.notebookName}/${noteId}`
|
||||
|
||||
notes.push(
|
||||
<Link key={i} to={url}>
|
||||
<div className="mv6">
|
||||
<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="gray2 mr3">{date}</div>
|
||||
<div className="gray2">{comment}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex-col">
|
||||
{notes}
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default NotebookPosts
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link, Switch, Route } from 'react-router-dom';
|
||||
import { NoteList } from './note-list';
|
||||
import { All } from './all';
|
||||
import { NotebookPosts } from './notebook-posts';
|
||||
import { About } from './about';
|
||||
import { Subscribers } from './subscribers';
|
||||
import { Settings } from './settings';
|
||||
@ -23,22 +23,84 @@ import { Settings } from './settings';
|
||||
export class Notebook extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
console.log("props", this.props);
|
||||
this.state = {
|
||||
ours: (window.ship === this.props.ship.slice(1)),
|
||||
numNotes: 10,
|
||||
};
|
||||
|
||||
this.onScroll = this.onScroll.bind(this);
|
||||
|
||||
}
|
||||
|
||||
onScroll(e) {
|
||||
let scrollTop = this.scrollElement.scrollTop;
|
||||
let clientHeight = e.target.clientHeight;
|
||||
let scrollHeight = e.target.scrollHeight;
|
||||
|
||||
let atBottom = false;
|
||||
if (scrollHeight - scrollTop - clientHeight < 40) {
|
||||
atBottom = true;
|
||||
}
|
||||
let loadedNotes = Object.keys(this.props.notebook.notes).length;
|
||||
let allNotes = this.props.notebook["notes-by-date"].length;
|
||||
|
||||
let fullyLoaded = (loadedNotes === allNotes);
|
||||
|
||||
if (atBottom && !fullyLoaded) {
|
||||
window.api.fetchNotesPage(this.props.ship, this.props.notebookName, loadedNotes, 5);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillMount(){
|
||||
if (!this.props.notebook.notes) {
|
||||
window.api.fetchNotebook(this.props.ship, this.props.notebookName);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let tabStyles = {
|
||||
posts: "bb b--gray4 gray2 NotebookTab",
|
||||
about: "bb b--gray4 gray2 NotebookTab",
|
||||
subscribers: "bb b--gray4 gray2 NotebookTab",
|
||||
settings: "bb b--gray4 pr2 gray2 NotebookTab",
|
||||
// subscribers: "bb b--gray4 gray2 NotebookTab",
|
||||
// settings: "bb b--gray4 pr2 gray2 NotebookTab",
|
||||
}
|
||||
tabStyles[this.props.view] = "bb b--black black NotebookTab";
|
||||
|
||||
let inner = null;
|
||||
switch (this.props.view) {
|
||||
case "posts":
|
||||
let notesList = this.props.notebook["notes-by-date"] || [];
|
||||
let notes = this.props.notebook.notes || null;
|
||||
inner = <NotebookPosts notes={notes}
|
||||
list={notesList}
|
||||
host={this.props.ship}
|
||||
notebookName={this.props.notebookName}/>
|
||||
break;
|
||||
case "about":
|
||||
inner = <p className="f8 lh-solid">{this.props.notebook.about}</p>
|
||||
break;
|
||||
// case "subscribers":
|
||||
// inner = <Subscribers/>
|
||||
// break;
|
||||
// case "settings":
|
||||
// inner = <Settings/>
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
let base = `/~publish/notebook/${this.props.ship}/${this.props.notebookName}`;
|
||||
let about = base + '/about';
|
||||
let subs = base + '/subscribers';
|
||||
let settings = base + '/settings';
|
||||
let newUrl = base + '/new';
|
||||
|
||||
return (
|
||||
<div className="center mw6 f9 h-100"
|
||||
style={{paddingLeft:16, paddingRight:16}}>
|
||||
<div className="h-100 overflow-container">
|
||||
<div className="h-100 overflow-container no-scrollbar"
|
||||
onScroll={this.onScroll}
|
||||
ref={(el) => {this.scrollElement = el}}>
|
||||
<div className="flex justify-between"
|
||||
style={{marginTop: 56, marginBottom: 32}}>
|
||||
<div className="flex-col">
|
||||
@ -49,31 +111,24 @@ export class Notebook extends Component {
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<button className="NotebookButton bg-light-green green2">
|
||||
<Link to={newUrl} className="NotebookButton bg-light-green green2">
|
||||
New Post
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex" style={{marginBottom:24}}>
|
||||
<div className={tabStyles.posts}>
|
||||
<Link to={base} className={tabStyles.posts}>
|
||||
All Posts
|
||||
</Link>
|
||||
<Link to={about} className={tabStyles.about}>
|
||||
About
|
||||
</Link>
|
||||
<div className="bb b--gray4 gray2 NotebookTab" style={{flexGrow:1}}>
|
||||
</div>
|
||||
<div className={tabStyles.about}>
|
||||
About
|
||||
</div>
|
||||
<div className={tabStyles.subscribers}>
|
||||
Subscribers
|
||||
</div>
|
||||
<div className={tabStyles.settings}>
|
||||
Settings
|
||||
</div>
|
||||
<div className="bb b--gray4 gray2 NotebookTab" style={{flexGrow:1}}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{height:"calc(100% - 170px)"}} className="f9 lh-solid">
|
||||
<Settings />
|
||||
</div>
|
||||
|
||||
<div style={{height:"calc(100% - 188px)"}} className="f9 lh-solid">
|
||||
{inner}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,9 +41,9 @@ export class Sidebar extends Component {
|
||||
<a className="db dn-m dn-l dn-xl f8 pb3 pl3" href="/">⟵ Landscape</a>
|
||||
<div className="w-100 pa4">
|
||||
<Link
|
||||
to="/~publish/new"
|
||||
to="/~publish/notebook/~zod/foo"
|
||||
className="green2 mr4 f9">
|
||||
New
|
||||
zod/foo
|
||||
</Link>
|
||||
<Link
|
||||
to="/~publish/join"
|
||||
|
@ -2,7 +2,6 @@ import _ from 'lodash';
|
||||
|
||||
export class PrimaryReducer {
|
||||
reduce(json, state){
|
||||
console.log("primaryReducer", json);
|
||||
switch(Object.keys(json)[0]){
|
||||
case "add-book":
|
||||
this.addBook(json["add-book"], state);
|
||||
|
@ -2,7 +2,6 @@ import _ from 'lodash';
|
||||
|
||||
export class ResponseReducer {
|
||||
reduce(json, state) {
|
||||
console.log("responseReducer", json);
|
||||
switch(json.type) {
|
||||
case "notebooks":
|
||||
this.handleNotebooks(json, state);
|
||||
|
Loading…
Reference in New Issue
Block a user