diff --git a/src/App.js b/src/App.js index aa0c5bf..a87c97f 100644 --- a/src/App.js +++ b/src/App.js @@ -2,7 +2,6 @@ import React, {Component} from 'react'; import {Flow} from './Flows'; import {Title} from './Title'; import {Sidebar} from './Sidebar'; -import {ControlBar} from './ControlBar'; class App extends Component { constructor(props) { @@ -33,9 +32,8 @@ class App extends Component { return (
- + <Title callback={this.show_sidebar.bind(this)} set_search_text={this.set_search_text.bind(this)} /> <div className="left-container"> - <ControlBar set_search_text={this.set_search_text.bind(this)} /> <Flow key={this.state.flow_render_key} callback={this.show_sidebar.bind(this)} search_text={this.state.search_text} /> diff --git a/src/Common.css b/src/Common.css index 821c97a..73a1c80 100644 --- a/src/Common.css +++ b/src/Common.css @@ -1,13 +1,11 @@ .centered-line { overflow: hidden; text-align: center; - color: #fff; - margin-top: 1em; } .centered-line::before, .centered-line::after { - background-color: #fff; + background-color: #000; content: ""; display: inline-block; height: 1px; @@ -26,6 +24,15 @@ margin-right: -50%; } +.title-line { + color: #fff; + margin-top: 1em; +} +.title-line::before, +.title-line::after { + background-color: #fff; +} + .bg-img { position: fixed; z-index: -1; diff --git a/src/Common.js b/src/Common.js index 37ce576..42a72d0 100644 --- a/src/Common.js +++ b/src/Common.js @@ -22,9 +22,9 @@ export function Time(props) { ); } -export function CenteredLine(props) { +export function TitleLine(props) { return ( - <p className="centered-line aux-margin"> + <p className="centered-line title-line aux-margin"> <span>{props.text}</span> </p> ) diff --git a/src/ControlBar.css b/src/ControlBar.css deleted file mode 100644 index 33ad1a9..0000000 --- a/src/ControlBar.css +++ /dev/null @@ -1,17 +0,0 @@ -.control-bar { - display: flex; - line-height: 2em; -} - -.control-bar .refresh-btn { - flex: 0 0 100px; - color: black; - background-color: rgba(255,255,255,.9); - border-radius: 5px; - text-align: center; -} -.control-bar input { - flex: auto; - color: black; - background-color: rgba(255,255,255,.9); -} \ No newline at end of file diff --git a/src/ControlBar.js b/src/ControlBar.js deleted file mode 100644 index 9347d7c..0000000 --- a/src/ControlBar.js +++ /dev/null @@ -1,42 +0,0 @@ -import React, {Component} from 'react'; -import './ControlBar.css'; - -export class ControlBar extends Component { - constructor(props) { - super(props); - this.state={ - search_text: '', - }; - this.set_search_text=props.set_search_text; - } - - on_change(event) { - this.setState({ - search_text: event.target.value, - }); - } - - on_keypress(event) { - if(event.key==='Enter') - this.set_search_text(this.state.search_text); - } - - do_refresh() { - this.setState({ - search_text: '', - }); - this.set_search_text(null); - } - - render() { - return ( - <div className="control-bar aux-margin"> - <a className="refresh-btn" onClick={this.do_refresh.bind(this)}>最新树洞</a> -   - <input value={this.state.search_text} placeholder="搜索" - onChange={this.on_change.bind(this)} onKeyPress={this.on_keypress.bind(this)} - /> - </div> - ) - } -} \ No newline at end of file diff --git a/src/Flows.css b/src/Flows.css index e14ea11..bea850c 100644 --- a/src/Flows.css +++ b/src/Flows.css @@ -16,20 +16,20 @@ overflow-y: hidden; } -.left-container .aux-margin, +.aux-margin, .left-container .flow-item { margin-left: 50px; } -.left-container .aux-margin { +.aux-margin { width: calc(100% - 2 * 50px); } @media screen and (max-width: 1200px) { - .left-container .aux-margin, + .aux-margin, .left-container .flow-item { margin-left: 10px; } - .left-container .aux-margin { + .aux-margin { width: calc(100% - 2 * 10px); } } diff --git a/src/Flows.js b/src/Flows.js index 35f4ed2..1086261 100644 --- a/src/Flows.js +++ b/src/Flows.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {Time, CenteredLine} from './Common.js'; +import {Time, TitleLine} from './Common.js'; import './Flows.css'; import LazyLoad from 'react-lazyload'; @@ -97,7 +97,7 @@ class FlowItemRow extends Component { function FlowChunk(props) { return ( <div className="flow-chunk"> - <CenteredLine text={props.title} /> + <TitleLine text={props.title} /> {props.list.map((info)=>( <LazyLoad key={info.pid} offset={500} height="15em"> <FlowItemRow info={info} callback={props.callback} /> @@ -111,7 +111,11 @@ export class Flow extends Component { constructor(props) { super(props); this.state={ - mode: props.search_text===null ? 'list' : 'search', + mode: ( + props.search_text===null ? 'list' : + props.search_text.charAt(0)==='#' ? 'single' : + 'search' + ), search_param: props.search_text, loaded_pages: 0, chunks: [], @@ -154,15 +158,42 @@ export class Flow extends Component { if(json.code!==0) throw new Error(json.code); const finished=json.data.length<SEARCH_PAGESIZE; - this.setState((prev,props)=>({ + this.setState({ chunks: [{ title: 'Result for "'+this.state.search_param+'"', data: json.data, mode: finished ? 'search_finished' : 'search', }], loading: false, - })); + }); + }) + .catch((err)=>{ + console.trace(err); + alert('load failed'); + }); + } else if(this.state.mode==='single') { + const pid=parseInt(this.state.search_param.substr(1),10); + fetch( + 'http://www.pkuhelper.com:10301/services/pkuhole/api.php?action=getone'+ + '&pid='+pid + ) + .then((res)=>res.json()) + .then((json)=>{ + if(json.code!==0) + throw new Error(json.code); + this.setState({ + chunks: [{ + title: 'PID = '+pid, + data: [json.data], + mode: 'single_finished', + }], + loading: false, + }); }) + .catch((err)=>{ + console.trace(err); + alert('load failed'); + }); } this.setState((prev,props)=>({ loaded_pages: prev.loaded_pages+1, @@ -195,7 +226,7 @@ export class Flow extends Component { {this.state.chunks.map((chunk)=>( <FlowChunk title={chunk.title} list={chunk.data} key={chunk.title} callback={this.props.callback} /> ))} - <CenteredLine text={this.state.loading ? 'Loading...' : '© xmcp'} /> + <TitleLine text={this.state.loading ? 'Loading...' : '© xmcp'} /> </div> ); } diff --git a/src/Title.css b/src/Title.css index e60a5f2..69eb092 100644 --- a/src/Title.css +++ b/src/Title.css @@ -1,19 +1,37 @@ -.title { +.title-bar { z-index: 1; position: sticky; - top: 0; + top: -6em; left: 0; width: 100%; - height: 2em; - line-height: 2em; - font-size: 1.5em; + height: 9em; background-color: rgba(255,255,255,.8); - padding: 0 50px; box-shadow: 0 0 25px #999; margin-bottom: 1em; } -.title-links { - float: right; - display: inline-block; - font-size: .7em; + +.title { + font-size: 2em; + line-height: 3em; + text-align: center; +} + +.control-bar { + display: flex; + margin-top: .5em; + line-height: 2em; +} + +.control-bar .refresh-btn { + flex: 0 0 100px; + color: black; + background-color: rgba(255,255,255,.5); + border-radius: 5px; + text-align: center; + border: 1px solid black; +} +.control-bar input { + flex: auto; + color: black; + background-color: rgba(255,255,255,.5); } \ No newline at end of file diff --git a/src/Title.js b/src/Title.js index 91ce8e2..22a1df7 100644 --- a/src/Title.js +++ b/src/Title.js @@ -1,44 +1,93 @@ import React, {Component} from 'react'; import './Title.css'; -export function Title(props) { - return ( - <div className="title"> - <div className="title-links"> - <a onClick={()=>{props.callback( +const HELP_TEXT=( + <div className="box"> + <p>使用提示:</p> + <ul> + <li>为保证使用体验,请使用 Chrome 浏览器 stable 分支最新版</li> + <li>在列表中点击帖子可以显示全部回复</li> + <li>搜索框输入 #472865 等可以查看指定 ID 的树洞</li> + </ul> + <p>使用本网站时,您需要了解并同意:</p> + <ul> + <li>所有数据来自 PKU Helper,本站不对其内容负责</li> + <li>不接受关于修改 UI 的建议</li> + <li>英梨梨是我的,你们都不要抢</li> + </ul> + <p>By @xmcp</p> + <br /> + <p> + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + </p> + <br /> + <p> + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + </p> + </div> +); + +class ControlBar extends Component { + constructor(props) { + super(props); + this.state={ + search_text: '', + }; + this.set_search_text=props.set_search_text; + } + + on_change(event) { + this.setState({ + search_text: event.target.value, + }); + } + + on_keypress(event) { + if(event.key==='Enter') + this.set_search_text(this.state.search_text); + } + + do_refresh() { + window.scrollTo(0,0); + this.setState({ + search_text: '', + }); + this.set_search_text(null); + + } + + render() { + return ( + <div className="control-bar"> + <a className="refresh-btn" onClick={this.do_refresh.bind(this)}>最新树洞</a> +   + <input value={this.state.search_text} placeholder="搜索 或 #PID" + onChange={this.on_change.bind(this)} onKeyPress={this.on_keypress.bind(this)} + /> +   + <a onClick={()=>{this.props.callback( '关于 P大树洞(非官方) 网页版', - <div class="box"> - <p>使用提示:</p> - <ul> - <li>为保证使用体验,请使用 Chrome 浏览器 stable 分支最新版</li> - <li>在列表中点击帖子可以显示全部回复</li> - </ul> - <p>使用本网站时,您需要了解并同意:</p> - <ul> - <li>所有数据来自 PKU Helper,本站不对其内容负责</li> - <li>不接受关于修改 UI 的建议</li> - <li>英梨梨是我的,你们都不要抢</li> - </ul> - <p>By @xmcp</p> - <br /> - <p> - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - </p> - <br /> - <p> - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - </p> - </div> + HELP_TEXT )}}>Help</a> <a href="https://github.com/xmcp/ashole" target="_blank">GitHub</a> </div> - P大树洞(非官方) + ) + } +} + +export function Title(props) { + return ( + <div className="title-bar"> + <div className="aux-margin"> + <p className="title centered-line">P大树洞</p> + <ControlBar callback={props.callback} set_search_text={props.set_search_text} /> + </div> </div> ) } \ No newline at end of file