forked from tanner/qotnews
wip on other discussions ui.
This commit is contained in:
parent
32bc3b906b
commit
e1830a589b
|
@ -1,225 +1,231 @@
|
||||||
body {
|
body {
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
font: 1rem/1.3 sans-serif;
|
font: 1rem/1.3 sans-serif;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
margin-bottom: 100vh;
|
margin-bottom: 100vh;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
font-kerning: normal;
|
font-kerning: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
font-size: 1.05rem;
|
font-size: 1.05rem;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 1px solid #828282;
|
border: 1px solid #828282;
|
||||||
margin: 0.25rem;
|
margin: 0.25rem;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
margin: 1rem auto;
|
margin: 1rem auto;
|
||||||
max-width: 64rem;
|
max-width: 64rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slogan {
|
.slogan {
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme {
|
.theme {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
display: table;
|
display: table;
|
||||||
color: #828282;
|
color: #828282;
|
||||||
margin-bottom: 0.7rem;
|
margin-bottom: 0.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item .source-logo {
|
.item .source-logo {
|
||||||
width: 0.9rem;
|
width: 0.9rem;
|
||||||
height: 0.9rem;
|
height: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item a {
|
.item a {
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
.item a:hover {
|
.item a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item a.link {
|
.item a.link {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
.item a.link:visited {
|
.item a.link:visited {
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
.item a.link:hover {
|
.item a.link:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.source {
|
span.source {
|
||||||
margin-left: 0.4rem;
|
margin-left: 0.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item .info a.hot {
|
.item .info a.hot {
|
||||||
color: #444444;
|
color: #444444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article {
|
.article {
|
||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-container {
|
.article-container {
|
||||||
margin: 1rem auto;
|
margin: 1rem auto;
|
||||||
max-width: 38rem;
|
max-width: 38rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article a {
|
.article a {
|
||||||
border-bottom: 1px solid #222222;
|
border-bottom: 1px solid #222222;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article h1 {
|
.article h1 {
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article h2 {
|
.article h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article h3, .article h4 {
|
.article h3,
|
||||||
font-size: 1.3rem;
|
.article h4 {
|
||||||
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article img {
|
.article img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article figure, .article video {
|
.article figure,
|
||||||
width: 100%;
|
.article video {
|
||||||
height: auto;
|
width: 100%;
|
||||||
margin: 0;
|
height: auto;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article table {
|
.article table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article iframe {
|
.article iframe {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article u {
|
.article u {
|
||||||
border-bottom: 1px solid #222;
|
border-bottom: 1px solid #222;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article .info {
|
.article .info {
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article .info a {
|
.article .info a {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
.article .info a:hover {
|
.article .info a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.story-text {
|
.story-text {
|
||||||
font: 1.2rem/1.5 'Apparatus SIL', sans-serif;
|
font: 1.2rem/1.5 "Apparatus SIL", sans-serif;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments {
|
.comments {
|
||||||
margin-left: -1.25rem;
|
margin-left: -1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
padding-left: 1.25rem;
|
padding-left: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment.lined {
|
.comment.lined {
|
||||||
border-left: 1px solid #cccccc;
|
border-left: 1px solid #cccccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment .text {
|
.comment .text {
|
||||||
margin-top: -0.5rem;
|
margin-top: -0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment .text.hidden > p {
|
.comment .text.hidden > p {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: none;
|
display: none;
|
||||||
color: #828282;
|
color: #828282;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment .text.hidden > p:first-child {
|
.comment .text.hidden > p:first-child {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment .collapser {
|
.comment .collapser {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-right: 1.5rem;
|
padding-right: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment .pointer {
|
.comment .pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggleDot {
|
.toggleDot {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 1rem;
|
bottom: 1rem;
|
||||||
left: 1rem;
|
left: 1rem;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
background-color: #828282;
|
background-color: #828282;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggleDot .button {
|
.toggleDot .button {
|
||||||
font: 2rem/1 'icomoon';
|
font: 2rem/1 "icomoon";
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
left: 0.55rem;
|
left: 0.55rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.forwardDot {
|
.forwardDot {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 1rem;
|
bottom: 1rem;
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
background-color: #828282;
|
background-color: #828282;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.forwardDot .button {
|
.forwardDot .button {
|
||||||
font: 2.5rem/1 'icomoon';
|
font: 2.5rem/1 "icomoon";
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0.25rem;
|
top: 0.25rem;
|
||||||
left: 0.3rem;
|
left: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search form {
|
.search form {
|
||||||
display: inline;
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.indented {
|
||||||
|
padding: 0 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import localForage from 'localforage';
|
import localForage from 'localforage';
|
||||||
import { sourceLink, infoLine, ToggleDot } from '../utils.js';
|
import { sourceLink, infoLine, ToggleDot } from '../utils.js';
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
class Article extends React.Component {
|
class Article extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -14,6 +15,7 @@ class Article extends React.Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
story: cache[id] || false,
|
story: cache[id] || false,
|
||||||
|
related: [],
|
||||||
error: false,
|
error: false,
|
||||||
pConv: [],
|
pConv: [],
|
||||||
};
|
};
|
||||||
|
@ -35,7 +37,7 @@ class Article extends React.Component {
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(
|
.then(
|
||||||
(result) => {
|
(result) => {
|
||||||
this.setState({ story: result.story });
|
this.setState({ story: result.story, related: result.related });
|
||||||
localForage.setItem(id, result.story);
|
localForage.setItem(id, result.story);
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
@ -51,6 +53,7 @@ class Article extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const id = this.props.match ? this.props.match.params.id : 'CLOL';
|
const id = this.props.match ? this.props.match.params.id : 'CLOL';
|
||||||
const story = this.state.story;
|
const story = this.state.story;
|
||||||
|
const related = this.state.related;//.filter(r => r.id != id);
|
||||||
const error = this.state.error;
|
const error = this.state.error;
|
||||||
const pConv = this.state.pConv;
|
const pConv = this.state.pConv;
|
||||||
let nodes = null;
|
let nodes = null;
|
||||||
|
@ -78,6 +81,16 @@ class Article extends React.Component {
|
||||||
|
|
||||||
{infoLine(story)}
|
{infoLine(story)}
|
||||||
|
|
||||||
|
{related.length ? <div className='related indented info'>
|
||||||
|
<span>Other discussions: </span>
|
||||||
|
{related.map((r, i) =>
|
||||||
|
<>
|
||||||
|
{i !== 0 ? <> • </> : <></>}
|
||||||
|
<Link className='' to={"/" + r.id + "/c"}>{r.source}</Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div> : <></>}
|
||||||
|
|
||||||
{nodes ?
|
{nodes ?
|
||||||
<div className='story-text'>
|
<div className='story-text'>
|
||||||
{Object.entries(nodes).map(([k, v]) =>
|
{Object.entries(nodes).map(([k, v]) =>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import moment from 'moment';
|
||||||
import localForage from 'localforage';
|
import localForage from 'localforage';
|
||||||
import { infoLine, ToggleDot } from '../utils.js';
|
import { infoLine, ToggleDot } from '../utils.js';
|
||||||
|
|
||||||
class Article extends React.Component {
|
class Comments extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ class Article extends React.Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
story: cache[id] || false,
|
story: cache[id] || false,
|
||||||
|
related: [],
|
||||||
error: false,
|
error: false,
|
||||||
collapsed: [],
|
collapsed: [],
|
||||||
expanded: [],
|
expanded: [],
|
||||||
|
@ -37,7 +38,7 @@ class Article extends React.Component {
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(
|
.then(
|
||||||
(result) => {
|
(result) => {
|
||||||
this.setState({ story: result.story }, () => {
|
this.setState({ story: result.story, related: result.related }, () => {
|
||||||
const hash = window.location.hash.substring(1);
|
const hash = window.location.hash.substring(1);
|
||||||
if (hash) {
|
if (hash) {
|
||||||
document.getElementById(hash).scrollIntoView();
|
document.getElementById(hash).scrollIntoView();
|
||||||
|
@ -110,6 +111,7 @@ class Article extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const id = this.props.match.params.id;
|
const id = this.props.match.params.id;
|
||||||
const story = this.state.story;
|
const story = this.state.story;
|
||||||
|
const related = this.state.related;//.filter(r => r.id != id);
|
||||||
const error = this.state.error;
|
const error = this.state.error;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -129,6 +131,17 @@ class Article extends React.Component {
|
||||||
|
|
||||||
{infoLine(story)}
|
{infoLine(story)}
|
||||||
|
|
||||||
|
{related.length ? <div className='related indented info'>
|
||||||
|
<span>Other discussions: </span>
|
||||||
|
{related.map((r, i) =>
|
||||||
|
<>
|
||||||
|
{i !== 0 ? <> • </> : <></>}
|
||||||
|
<Link className='' to={"/" + r.id + "/c"}>{r.source}</Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div> : <></>}
|
||||||
|
|
||||||
|
|
||||||
<div className='comments'>
|
<div className='comments'>
|
||||||
{story.comments.map(c => this.displayComment(story, c, 0))}
|
{story.comments.map(c => this.displayComment(story, c, 0))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -142,4 +155,4 @@ class Article extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Article;
|
export default Comments;
|
||||||
|
|
5321
webclient/yarn.lock
5321
webclient/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user