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