diff --git a/src/App.js b/src/App.js index 6f7c880..8ddf87c 100644 --- a/src/App.js +++ b/src/App.js @@ -100,9 +100,12 @@ class App extends Component { } componentDidMount() { - if (window.location.protocol === 'http:' && - window.location.hostname !== '127.0.0.1' && !window.location.hostname.endsWith('localhost')) { - window.location.protocol = 'https:'; // 因为CDN的原因先在前端做下https跳转 + if ( + window.location.protocol === 'http:' && + window.location.hostname !== '127.0.0.1' && + !window.location.hostname.endsWith('localhost') + ) { + window.location.protocol = 'https:'; // 因为CDN的原因先在前端做下https跳转 return; } let arg = window.location.search; @@ -110,7 +113,10 @@ class App extends Component { if (arg.startsWith('?token=')) { let token = arg.substr(7); if (token.endsWith(encodeURI('_任意自定义后缀'))) { - let tmp_token_suf = localStorage['TOKEN_SUF'] || prompt('设置一个你专属的临时token后缀吧') || Math.random(); + let tmp_token_suf = + localStorage['TOKEN_SUF'] || + prompt('设置一个你专属的临时token后缀吧') || + Math.random(); localStorage['TOKEN_SUF'] = tmp_token_suf; token = `${token.split('_')[0]}_${tmp_token_suf}`; } diff --git a/src/Attention.js b/src/Attention.js index 73f291c..e9ae4fe 100644 --- a/src/Attention.js +++ b/src/Attention.js @@ -1,5 +1,7 @@ export function load_attentions() { - window.saved_attentions = JSON.parse(localStorage['saved_attentions'] || '[]'); + window.saved_attentions = JSON.parse( + localStorage['saved_attentions'] || '[]', + ); } export function save_attentions() { diff --git a/src/Common.css b/src/Common.css index ce10dd9..08bbf0a 100644 --- a/src/Common.css +++ b/src/Common.css @@ -1,65 +1,64 @@ .clickable { - cursor: pointer; + cursor: pointer; } .bg-img { - position: fixed; - z-index: -1; - top: 0; - left: 0; - width: 100%; - height: 100%; + position: fixed; + z-index: -1; + top: 0; + left: 0; + width: 100%; + height: 100%; } .root-dark-mode .bg-img { - opacity: .65; + opacity: 0.65; } .black-outline { - text-shadow: /* also change .flow-item-row-with-prompt:hover::before */ - -1px -1px 0 rgba(0,0,0,.6), - 0 -1px 0 rgba(0,0,0,.6), - 1px -1px 0 rgba(0,0,0,.6), - -1px 1px 0 rgba(0,0,0,.6), - 0 1px 0 rgba(0,0,0,.6), - 1px 1px 0 rgba(0,0,0,.6); + text-shadow: /* also change .flow-item-row-with-prompt:hover::before */ -1px -1px + 0 rgba(0, 0, 0, 0.6), + 0 -1px 0 rgba(0, 0, 0, 0.6), 1px -1px 0 rgba(0, 0, 0, 0.6), + -1px 1px 0 rgba(0, 0, 0, 0.6), 0 1px 0 rgba(0, 0, 0, 0.6), + 1px 1px 0 rgba(0, 0, 0, 0.6); } .search-query-highlight { - border-bottom: 1px solid black; - font-weight: bold; + border-bottom: 1px solid black; + font-weight: bold; } .root-dark-mode .search-query-highlight { - border-bottom: 1px solid white; + border-bottom: 1px solid white; } .url-pid-link { - opacity: .6; + opacity: 0.6; } :root { - --coloredspan-bgcolor-light: white; - --coloredspan-bgcolor-dark: black; + --coloredspan-bgcolor-light: white; + --coloredspan-bgcolor-dark: black; } .colored-span { - background-color: var(--coloredspan-bgcolor-light); + background-color: var(--coloredspan-bgcolor-light); } .root-dark-mode .colored-span { - background-color: var(--coloredspan-bgcolor-dark); + background-color: var(--coloredspan-bgcolor-dark); } -.icon+label { - font-size: .9em; - vertical-align: .05em; - cursor: inherit; - padding: 0 .1rem; - margin-left: .15rem; +.icon + label { + font-size: 0.9em; + vertical-align: 0.05em; + cursor: inherit; + padding: 0 0.1rem; + margin-left: 0.15rem; } -.ext-img, .ext-video { +.ext-img, +.ext-video { max-width: 100%; max-height: 2000px; display: block; @@ -71,7 +70,7 @@ } blockquote { - margin-left: 8px; + margin-left: 8px; padding-left: 5px; - border-left: 3px solid #cbcbcb; + border-left: 3px solid #cbcbcb; } diff --git a/src/Common.js b/src/Common.js index 2730707..5ef41e1 100644 --- a/src/Common.js +++ b/src/Common.js @@ -138,13 +138,18 @@ export class HighlightedMarkdown extends Component { ['url', URL_RE], ['pid', PID_RE], ['nickname', NICKNAME_RE], - ['tag', TAG_RE] + ['tag', TAG_RE], ]; if (props.search_param) { - let search_kws = props.search_param.split(' ').filter(s => !!s); + let search_kws = props.search_param.split(' ').filter((s) => !!s); rules.push([ 'search', - new RegExp(`(${search_kws.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join("|")})`, "g") + new RegExp( + `(${search_kws + .map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) + .join('|')})`, + 'g', + ), ]); } const splitted = split_text(originalText, rules); @@ -170,7 +175,7 @@ export class HighlightedMarkdown extends Component { {is_video(p) && ( - )}   - {( - {info.name} - )} + {{info.name}} {info.author_title && ( {`"${info.author_title}"`} )} @@ -138,21 +142,21 @@ class Reply extends PureComponent { onClick={() => { do_delete('cid', info.cid); }} - > 🗑️ + > + {' '} + 🗑️{' '} + )} {!!do_block && ( - 🚫 + + {' '} + 🚫{' '} + )} {!!do_report && ( <>   - +   @@ -219,9 +223,21 @@ class FlowItem extends PureComponent { render() { const { - info, is_quote, cached, attention, can_del, do_filter_name, do_delete, - do_edit_cw, timestamp, img_clickable, color_picker, - show_pid, do_vote, do_block, search_param + info, + is_quote, + cached, + attention, + can_del, + do_filter_name, + do_delete, + do_edit_cw, + timestamp, + img_clickable, + color_picker, + show_pid, + do_vote, + do_block, + search_param, } = this.props; const { cw } = this.state; return ( @@ -241,9 +257,7 @@ class FlowItem extends PureComponent { parseInt(info.pid, 10) > window.LATEST_POST_ID && (
)} - {!!attention && !cached && ( -
- )} + {!!attention && !cached &&
}
{!!do_filter_name && ( {info.likenum}  )} @@ -272,10 +284,7 @@ class FlowItem extends PureComponent { )} - + #{info.pid} @@ -283,22 +292,23 @@ class FlowItem extends PureComponent { {info.author_title && ( {`"${info.author_title}"`} )} - {info.is_reported && ( - R - )} + {info.is_reported && R } {!!do_delete && !!info.can_del && ( { do_delete('pid', info.pid); }} - > 🗑️ + > + {' '} + 🗑️{' '} + )} {!!do_block && ( - 🚫 + + {' '} + 🚫{' '} + )} {info.dangerous_user && ( {info.dangerous_user} @@ -306,30 +316,24 @@ class FlowItem extends PureComponent { {info.blocked_count && ( {info.blocked_count} )} - {info.cw !== null && - (!do_edit_cw || !info.can_del) && ( - {info.cw} + {info.cw !== null && (!do_edit_cw || !info.can_del) && ( + {info.cw} )} - { - !!do_edit_cw && !!info.can_del && ( -
- - -
- ) - } - { - info.allow_search && 📢 - } + {!!do_edit_cw && !!info.can_del && ( +
+ + +
+ )} + {info.allow_search && 📢 }
{!!info.hot_score && ( @@ -343,14 +347,14 @@ class FlowItem extends PureComponent { search_param={search_param} />
- { info.poll && ( -
+ {info.poll && ( +
{})} - customStyles={{'theme': 'cyan'}} + customStyles={{ theme: 'cyan' }} noStorage={true} vote={localStorage['VOTE_RECORD:' + info.pid] || info.poll.vote} /> @@ -358,8 +362,7 @@ class FlowItem extends PureComponent { )} {!!(attention && info.variant.latest_reply) && (

- 最新回复{' '} -

)}
@@ -432,7 +435,7 @@ class FlowSidebar extends PureComponent { info: update_count ? Object.assign({}, prev.info, { reply: '' + json.data.length, - likenum: ''+json.likenum, + likenum: '' + json.likenum, }) : prev.info, attention: !!json.attention, @@ -473,16 +476,16 @@ class FlowSidebar extends PureComponent { this.setState({ attention: json.attention, info: Object.assign({}, prev_info, { - likenum: ''+json.likenum, - }), + likenum: '' + json.likenum, + }), }); let saved_attentions = window.saved_attentions; if (json.attention && !saved_attentions.includes(pid)) { - saved_attentions.unshift(pid) + saved_attentions.unshift(pid); } else if (!json.attention && saved_attentions.includes(pid)) { const idx = saved_attentions.indexOf(pid); - saved_attentions.splice(idx, 1) + saved_attentions.splice(idx, 1); } window.saved_attentions = saved_attentions; save_attentions(); @@ -490,8 +493,8 @@ class FlowSidebar extends PureComponent { this.syncState({ attention: json.attention, info: Object.assign({}, prev_info, { - likenum: ''+json.likenum, - }), + likenum: '' + json.likenum, + }), }); }) .catch((e) => { @@ -551,15 +554,15 @@ class FlowSidebar extends PureComponent { block(name, type, id, on_complete) { if (confirm(`确定拉黑${name}吗?后续将不会收到其发布的任何内容`)) { API.block(type, id, this.props.token) - .then((json) => { - let data = json.data; - alert(`操作成功,其成为危险用户进度 ${data.curr}/${data.threshold}`) - !!on_complete && on_complete(); - }) - .catch((e) => { - alert('拉黑失败\n' + e); - console.error(e) - }); + .then((json) => { + let data = json.data; + alert(`操作成功,其成为危险用户进度 ${data.curr}/${data.threshold}`); + !!on_complete && on_complete(); + }) + .catch((e) => { + alert('拉黑失败\n' + e); + console.error(e); + }); } } @@ -590,7 +593,7 @@ class FlowSidebar extends PureComponent { } } - make_do_delete(token, on_complete=null) { + make_do_delete(token, on_complete = null) { const do_delete = (type, id) => { let note = prompt(`将删除${type}=${id}, 备注:`, '(无)'); if (note !== null) { @@ -604,27 +607,29 @@ class FlowSidebar extends PureComponent { console.error(e); }); } - } + }; return do_delete; } do_edit_cw(cw, id) { - API.update_cw(cw, id, this.props.token) - .then((json) => { - this.setState({ - info: Object.assign({}, this.state.info, { cw: cw }), + API.update_cw(cw, id, this.props.token) + .then((json) => { + this.setState( + { + info: Object.assign({}, this.state.info, { cw: cw }), }, () => { this.syncState({ info: this.state.info, }); - }); - alert('已更新'); - }) - .catch((e) => { - alert('更新失败\n' + e); - console.error(e); - }); + }, + ); + alert('已更新'); + }) + .catch((e) => { + alert('更新失败\n' + e); + console.error(e); + }); } render() { @@ -671,12 +676,16 @@ class FlowSidebar extends PureComponent { do_filter_name={ replies_cnt[DZ_NAME] > 1 ? this.set_filter_name.bind(this) : null } - do_delete={this.make_do_delete(this.props.token, ()=>{window.location.reload();})} + do_delete={this.make_do_delete(this.props.token, () => { + window.location.reload(); + })} do_edit_cw={this.do_edit_cw.bind(this)} do_vote={this.do_vote.bind(this)} - do_block={() => {this.block( - '洞主', 'post', this.state.info.pid, () => {window.location.reload();} - )}} + do_block={() => { + this.block('洞主', 'post', this.state.info.pid, () => { + window.location.reload(); + }); + }} /> ); @@ -766,41 +775,57 @@ class FlowSidebar extends PureComponent { 条回复被删除
)} - {replies_to_show.map((reply, i) => !reply.blocked && ( - - { - this.show_reply_bar(reply.name, e); - }} - > - { - this.set_variant(reply.cid, variant); - }} - do_filter_name={ - replies_cnt[reply.name] > 1 - ? this.set_filter_name.bind(this) - : null - } - do_delete={this.make_do_delete(this.props.token, this.load_replies.bind(this))} - do_block={() => {this.block( - reply.name, 'comment', reply.cid, this.load_replies.bind(this) - )}} - do_report={(e) => {this.report(e, `评论区${reply.name},评论id ${reply.cid}`)}} - /> - - - ))} + {replies_to_show.map( + (reply, i) => + !reply.blocked && ( + + { + this.show_reply_bar(reply.name, e); + }} + > + { + this.set_variant(reply.cid, variant); + }} + do_filter_name={ + replies_cnt[reply.name] > 1 + ? this.set_filter_name.bind(this) + : null + } + do_delete={this.make_do_delete( + this.props.token, + this.load_replies.bind(this), + )} + do_block={() => { + this.block( + reply.name, + 'comment', + reply.cid, + this.load_replies.bind(this), + ); + }} + do_report={(e) => { + this.report( + e, + `评论区${reply.name},评论id ${reply.cid}`, + ); + }} + /> + + + ), + )} {this.state.rev && main_thread_elem} {this.props.token ? ( + hidden: + (window.config.block_words_v2.some((word) => props.info.text.includes(word), - ) && !props.info.can_del || this.needFold, + ) && + !props.info.can_del) || + this.needFold, attention: props.info.attention, cached: true, // default no display anything }; @@ -841,7 +874,7 @@ class FlowItemRow extends PureComponent { componentDidMount() { // cache from getlist, so always to this to update attention if (!this.props.info.comments) { - //if (true || parseInt(this.state.info.reply, 10)) { + //if (true || parseInt(this.state.info.reply, 10)) { this.load_replies(null, /*update_count=*/ false); } } @@ -918,14 +951,10 @@ class FlowItemRow extends PureComponent { } render() { - const {show_sidebar, token, search_param, is_quote } = this.props; - let show_pid = load_single_meta(show_sidebar, token, [ - this.state.info.pid, - ]); + const { show_sidebar, token, search_param, is_quote } = this.props; + let show_pid = load_single_meta(show_sidebar, token, [this.state.info.pid]); - let hl_rules = [ - ['pid', PID_RE], - ]; + let hl_rules = [['pid', PID_RE]]; let parts = split_text(this.state.info.text, hl_rules); //console.log('hl:', parts,this.state.info.pid); @@ -939,12 +968,11 @@ class FlowItemRow extends PureComponent { QUOTE_BLACKLIST.indexOf(content) === -1 && parseInt(content) < parseInt(this.state.info.pid) ) { - if (quote_id === null) - quote_id = parseInt(content); - else { - quote_id = null; - break; - } + if (quote_id === null) quote_id = parseInt(content); + else { + quote_id = null; + break; + } } } @@ -988,15 +1016,20 @@ class FlowItemRow extends PureComponent {

{this.state.reply_error}

)} - {this.state.replies.slice(0, PREVIEW_REPLY_COUNT).map((reply) => !reply.blocked && ( - - ))} + {this.state.replies + .slice(0, PREVIEW_REPLY_COUNT) + .map( + (reply) => + !reply.blocked && ( + + ), + )} {this.state.replies.length > PREVIEW_REPLY_COUNT && (
还有 {this.state.replies.length - PREVIEW_REPLY_COUNT} 条 @@ -1007,58 +1040,60 @@ class FlowItemRow extends PureComponent { ); if (this.state.hidden) { - return this.needFold && ( -
{ - if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()]) - this.show_sidebar(); - }} - > + return ( + this.needFold && (
{ + if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()]) + this.show_sidebar(); + }} > - {!!this.props.is_quote && ( -
-
- +
+ {!!this.props.is_quote && ( +
+
+ +
+ {/*
*/} + {/* 提到*/} + {/*
*/}
- {/*
*/} - {/* 提到*/} - {/*
*/} -
- )} -
-
- {!!this.props.do_filter_name && ( - { - this.props.do_filter_name(DZ_NAME); - }} - > - + )} +
+
+ {!!this.props.do_filter_name && ( + { + this.props.do_filter_name(DZ_NAME); + }} + > + + + )} + #{this.props.info.pid} +   + {this.props.info.author_title && ( + {`"${this.props.info.author_title}"`} + )} + {this.props.info.cw !== null && ( + {this.props.info.cw} + )} +
-
+ ) ); } @@ -1163,37 +1198,40 @@ function FlowChunk(props) { {({ value: token }) => (
{!!props.title && } - {props.list.map((info, ind) => !info.blocked && ( - -
- {!!( - props.deletion_detect && - props.mode === 'list' && - ind && - props.list[ind - 1].pid - info.pid > 1 - ) && ( -
-
- {props.list[ind - 1].pid - info.pid - 1} 条被删除 -
+ {props.list.map( + (info, ind) => + !info.blocked && ( + +
+ {!!( + props.deletion_detect && + props.mode === 'list' && + ind && + props.list[ind - 1].pid - info.pid > 1 + ) && ( +
+
+ {props.list[ind - 1].pid - info.pid - 1} 条被删除 +
+
+ )} +
- )} - -
- - ))} + + ), + )}
)} @@ -1205,23 +1243,23 @@ export class Flow extends PureComponent { super(props); let submode = window[props.mode.toUpperCase() + '_SUBMODE_BACKUP']; if (submode === undefined) { - submode = props.mode === 'list' ? (window.config.by_c ? 1 : 0) : 0; + submode = props.mode === 'list' ? (window.config.by_c ? 1 : 0) : 0; } this.state = { submode: submode, - } + }; } get_submode_names(mode) { - switch(mode) { - case('list'): + switch (mode) { + case 'list': return ['最新', '最近回复', '近期热门', '随机']; - case('attention'): + case 'attention': return ['线上关注', '本地收藏']; - case('search'): - return ['Tag搜索', '全文搜索', '头衔'] + case 'search': + return ['Tag搜索', '全文搜索', '头衔']; } - return [] + return []; } set_submode(submode) { @@ -1233,7 +1271,7 @@ export class Flow extends PureComponent { render() { const { submode } = this.state; - const submode_names = this.get_submode_names(this.props.mode) + const submode_names = this.get_submode_names(this.props.mode); return ( <>
@@ -1257,11 +1295,10 @@ export class Flow extends PureComponent { token={this.props.token} /> - ) + ); } } - class SubFlow extends PureComponent { constructor(props) { super(props); @@ -1406,11 +1443,13 @@ class SubFlow extends PureComponent { ? json.data : !use_regex ? json.data.filter((post) => { - return this.state.search_param - .split(' ') - .every((keyword) => post.text.includes(keyword)); + return this.state.search_param + .split(' ') + .every((keyword) => post.text.includes(keyword)); }) // Not using regex - : json.data.filter((post) => !!post.text.match(regex_search)), // Using regex + : json.data.filter( + (post) => !!post.text.match(regex_search), + ), // Using regex }, mode: 'attention_finished', loading_status: 'done', @@ -1419,18 +1458,18 @@ class SubFlow extends PureComponent { window.saved_attentions = Array.from( new Set([ ...window.saved_attentions, - ...json.data.map(post => post.pid) - ]) - ).sort((a, b) => (b - a)); + ...json.data.map((post) => post.pid), + ]), + ).sort((a, b) => b - a); save_attentions(); } }) .catch(failed); } else if (this.props.submode === 1) { const PERPAGE = 50; - let pids = window.saved_attentions.sort( - (a, b) => (b - a) - ).slice((page - 1) * PERPAGE, page * PERPAGE); + let pids = window.saved_attentions + .sort((a, b) => b - a) + .slice((page - 1) * PERPAGE, page * PERPAGE); if (pids.length) { API.get_multi(pids, this.props.token) .then((json) => { @@ -1458,7 +1497,7 @@ class SubFlow extends PureComponent { console.log('local attention finished'); this.setState({ loading_status: 'done', - mode: 'attention_finished' + mode: 'attention_finished', }); return; } @@ -1496,18 +1535,23 @@ class SubFlow extends PureComponent { } trunc_string(s, max_len) { - return s.substr(0, max_len) + ( - s.length > max_len ? '...' : '' - ) + return s.substr(0, max_len) + (s.length > max_len ? '...' : ''); } gen_export() { this.setState({ can_export: false, - export_text: "以下是你关注的洞及摘要,复制保存到本地吧。\n\n" + this.state.chunks.data.map( - p => `#${p.pid}: ${ - this.trunc_string(p.text.replaceAll('\n', ' '), 50) - }`).join('\n\n') + export_text: + '以下是你关注的洞及摘要,复制保存到本地吧。\n\n' + + this.state.chunks.data + .map( + (p) => + `#${p.pid}: ${this.trunc_string( + p.text.replaceAll('\n', ' '), + 50, + )}`, + ) + .join('\n\n'), }); } @@ -1515,9 +1559,14 @@ class SubFlow extends PureComponent { const should_deletion_detect = localStorage['DELETION_DETECT'] === 'on'; return (
- {this.state.mode === 'attention_finished' && this.props.submode == 0 && ( - + )} {this.state.export_text && ( diff --git a/src/Markdown.css b/src/Markdown.css index 5739246..095606e 100644 --- a/src/Markdown.css +++ b/src/Markdown.css @@ -1,3 +1,3 @@ .hljs { white-space: pre-wrap; -} \ No newline at end of file +} diff --git a/src/Message.css b/src/Message.css index 4277fe9..aaefc14 100644 --- a/src/Message.css +++ b/src/Message.css @@ -16,4 +16,3 @@ vertical-align: top; padding: 3px; } - diff --git a/src/Message.js b/src/Message.js index 8474f6a..3b9be21 100644 --- a/src/Message.js +++ b/src/Message.js @@ -11,7 +11,7 @@ export class MessageViewer extends PureComponent { loading_status: 'idle', msg: [], }; - this.input_suf_ref=React.createRef(); + this.input_suf_ref = React.createRef(); } componentDidMount() { @@ -25,12 +25,9 @@ export class MessageViewer extends PureComponent { loading_status: 'loading', }, () => { - fetch( - API_BASE + '/systemlog', - { - headers: {'User-Token': this.props.token}, - } - ) + fetch(API_BASE + '/systemlog', { + headers: { 'User-Token': this.props.token }, + }) .then(get_json) .then((json) => { this.setState({ @@ -53,10 +50,9 @@ export class MessageViewer extends PureComponent { } do_set_token() { - if (this.state.loading_status==='loading') - return; + if (this.state.loading_status === 'loading') return; if (!this.input_suf_ref.current.value) { - alert("不建议后缀为空"); + alert('不建议后缀为空'); return; } let tt = this.state.tmp_token + '_' + this.input_suf_ref.current.value; @@ -65,7 +61,7 @@ export class MessageViewer extends PureComponent { alert('已登录为临时用户,过期后需注销重新登陆'); window.location.reload(); } - + render() { if (this.state.loading_status === 'loading') return

加载中……

; @@ -84,20 +80,29 @@ export class MessageViewer extends PureComponent { else if (this.state.loading_status === 'done') return ( <> -
+

最近一次重置

随机盐 {this.state.salt}

-
-
-

15分钟临时token:

+
+
+

15分钟临时token:

{this.state.tmp_token}_
- -
@@ -105,8 +110,7 @@ export class MessageViewer extends PureComponent {
- ))} + ))} - ) + ); else return null; } } diff --git a/src/PressureHelper.css b/src/PressureHelper.css index fa66f32..e1da473 100644 --- a/src/PressureHelper.css +++ b/src/PressureHelper.css @@ -1,16 +1,16 @@ .pressure-box { - border: 500px /* also change js! */ solid orange; - position: fixed; - margin: auto; - z-index: 100; - pointer-events: none; + border: 500px /* also change js! */ solid orange; + position: fixed; + margin: auto; + z-index: 100; + pointer-events: none; } .pressure-box-empty { - visibility: hidden; + visibility: hidden; } .pressure-box-fired { - border-color: orangered; - pointer-events: initial !important; -} \ No newline at end of file + border-color: orangered; + pointer-events: initial !important; +} diff --git a/src/Sidebar.css b/src/Sidebar.css index 409e575..4a48456 100644 --- a/src/Sidebar.css +++ b/src/Sidebar.css @@ -1,183 +1,193 @@ .sidebar-shadow { - will-change: opacity; - opacity: 0; - background-color: black; - pointer-events: none; - transition: opacity 150ms ease-out; - position: fixed; - left: 0; - top: 0; - height: 100%; - width: 100%; - z-index: 20; + will-change: opacity; + opacity: 0; + background-color: black; + pointer-events: none; + transition: opacity 150ms ease-out; + position: fixed; + left: 0; + top: 0; + height: 100%; + width: 100%; + z-index: 20; } .sidebar-on .sidebar-shadow { - opacity: .3; - pointer-events: initial; + opacity: 0.3; + pointer-events: initial; } .sidebar-on .sidebar-shadow:active { - opacity: .5; - transition: unset; + opacity: 0.5; + transition: unset; } .root-dark-mode .sidebar-on .sidebar-shadow { - opacity: .65; + opacity: 0.65; } .root-dark-mode .sidebar-on .sidebar-shadow:active { - opacity: .8; + opacity: 0.8; } .sidebar { - user-select: text; - position: fixed; - top: 0; - /* think twice before you use 100vh + user-select: text; + position: fixed; + top: 0; + /* think twice before you use 100vh https://dev.to/peiche/100vh-behavior-on-chrome-2hm8 */ - height: 100%; - background-color: rgba(255,255,255,.7); - overflow-y: auto; - padding-top: 3em; - /* padding-bottom: 1em; */ /* move to sidebar-content */ - backdrop-filter: blur(5px); + height: 100%; + background-color: rgba(255, 255, 255, 0.7); + overflow-y: auto; + padding-top: 3em; + /* padding-bottom: 1em; */ /* move to sidebar-content */ + backdrop-filter: blur(5px); } .sidebar-content { - backdrop-filter: blur(0px); /* fix scroll performance issues */ + backdrop-filter: blur(0px); /* fix scroll performance issues */ } .root-dark-mode .sidebar { - background-color: hsla(0,0%,5%,.4); + background-color: hsla(0, 0%, 5%, 0.4); } -.sidebar, .sidebar-title { - left: 700px; - will-change: opacity, transform; - z-index: 21; - width: calc(100% - 700px); +.sidebar, +.sidebar-title { + left: 700px; + will-change: opacity, transform; + z-index: 21; + width: calc(100% - 700px); } -.sidebar-on .sidebar, .sidebar-on .sidebar-title { - animation: sidebar-fadein .15s cubic-bezier(0.15, 0.4, 0.6, 1); +.sidebar-on .sidebar, +.sidebar-on .sidebar-title { + animation: sidebar-fadein 0.15s cubic-bezier(0.15, 0.4, 0.6, 1); } -.sidebar-off .sidebar, .sidebar-off .sidebar-title { - visibility: hidden; - pointer-events: none; - backdrop-filter: none; - animation: sidebar-fadeout .2s cubic-bezier(0.15, 0.4, 0.6, 1); +.sidebar-off .sidebar, +.sidebar-off .sidebar-title { + visibility: hidden; + pointer-events: none; + backdrop-filter: none; + animation: sidebar-fadeout 0.2s cubic-bezier(0.15, 0.4, 0.6, 1); } .sidebar-container { - animation: sidebar-initial .25s linear; /* skip initial animation */ + animation: sidebar-initial 0.25s linear; /* skip initial animation */ } @keyframes sidebar-fadeout { - from { - visibility: visible; - opacity: 1; - transform: none; - backdrop-filter: none; - } - to { - visibility: visible; - opacity: 0; - transform: translateX(40vw); - backdrop-filter: none; - } + from { + visibility: visible; + opacity: 1; + transform: none; + backdrop-filter: none; + } + to { + visibility: visible; + opacity: 0; + transform: translateX(40vw); + backdrop-filter: none; + } } @keyframes sidebar-fadein { - from { - opacity: 0; - transform: translateX(40vw); - backdrop-filter: none; - } - to { - opacity: 1; - transform: none; - backdrop-filter: none; - } + from { + opacity: 0; + transform: translateX(40vw); + backdrop-filter: none; + } + to { + opacity: 1; + transform: none; + backdrop-filter: none; + } } @keyframes sidebar-initial { - from {opacity: 0;} - to {opacity: 0;} + from { + opacity: 0; + } + to { + opacity: 0; + } } .sidebar-title { - text-shadow: 0 0 3px white; - font-weight: bold; - position: fixed; - width: 100%; - top: 0; - line-height: 3em; - padding-left: .5em; - background-color: rgba(255,255,255,.6); - pointer-events: none; - backdrop-filter: blur(5px); - box-shadow: 0 3px 5px rgba(0,0,0,.2); + text-shadow: 0 0 3px white; + font-weight: bold; + position: fixed; + width: 100%; + top: 0; + line-height: 3em; + padding-left: 0.5em; + background-color: rgba(255, 255, 255, 0.6); + pointer-events: none; + backdrop-filter: blur(5px); + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); } .root-dark-mode .sidebar-title { - background-color: hsla(0,0%,18%,.6); - color: var(--foreground-dark); - text-shadow: 0 0 3px black; + background-color: hsla(0, 0%, 18%, 0.6); + color: var(--foreground-dark); + text-shadow: 0 0 3px black; } .sidebar-title a { - pointer-events: initial; + pointer-events: initial; } - /* move all padding to sidebar-content - the scrolling div (overflow-y: auto) */ /* .sidebar, */ .sidebar-content, .sidebar-title { - padding-left: 1em; - padding-right: 1em; + padding-left: 1em; + padding-right: 1em; } .sidebar-content { - padding-bottom: 1em; + padding-bottom: 1em; } @media screen and (max-width: 1300px) { - .sidebar, .sidebar-title { - left: calc(100% - 550px); - width: 550px;/* + .sidebar, + .sidebar-title { + left: calc(100% - 550px); + width: 550px; /* padding-left: .5em; padding-right: .5em; */ - } - .sidebar-content, .sidebar-title { - padding-left: .5em; - padding-right: .5em; - } + } + .sidebar-content, + .sidebar-title { + padding-left: 0.5em; + padding-right: 0.5em; + } } @media screen and (max-width: 580px) { - .sidebar, .sidebar-title { - left: 27px; - width: calc(100% - 27px); - /* padding-left: .25em; + .sidebar, + .sidebar-title { + left: 27px; + width: calc(100% - 27px); + /* padding-left: .25em; padding-right: .25em; */ - } - .sidebar-content, .sidebar-title { - padding-left: .25em; - padding-right: .25em; - } + } + .sidebar-content, + .sidebar-title { + padding-left: 0.25em; + padding-right: 0.25em; + } } .sidebar-flow-item { - display: block; + display: block; } .sidebar-flow-item .box { - width: 100%; + width: 100%; } .sidebar-content-show { - height: 100%; - overflow-y: auto; + height: 100%; + overflow-y: auto; } -.sidebar-content-hide{ - /* will make lazyload working correctly */ - height: 0; - padding: 0; - overflow-y: scroll; +.sidebar-content-hide { + /* will make lazyload working correctly */ + height: 0; + padding: 0; + overflow-y: scroll; } diff --git a/src/Title.css b/src/Title.css index 40719dd..e6d6689 100644 --- a/src/Title.css +++ b/src/Title.css @@ -1,88 +1,88 @@ .title-bar { - z-index: 10; - position: sticky; - top: -4em; - left: 0; - width: 100%; - height: 7em; - background-color: rgba(255,255,255,.8); - box-shadow: 0 0 25px rgba(0,0,0,.4); - margin-bottom: 1em; - backdrop-filter: blur(5px); + z-index: 10; + position: sticky; + top: -4em; + left: 0; + width: 100%; + height: 7em; + background-color: rgba(255, 255, 255, 0.8); + box-shadow: 0 0 25px rgba(0, 0, 0, 0.4); + margin-bottom: 1em; + backdrop-filter: blur(5px); } .root-dark-mode .title-bar { - background-color: hsla(0,0%,12%,.8); - box-shadow: 0 0 5px rgba(255,255,255,.1); + background-color: hsla(0, 0%, 12%, 0.8); + box-shadow: 0 0 5px rgba(255, 255, 255, 0.1); } .control-bar { - display: flex; - margin-top: .5em; - line-height: 2em; + display: flex; + margin-top: 0.5em; + line-height: 2em; } .control-btn { - flex: 0 0 4.5em; - text-align: center; - color: black; - border-radius: 5px; + flex: 0 0 4.5em; + text-align: center; + color: black; + border-radius: 5px; } .control-btn:hover { - background-color: #666666; - color: white; + background-color: #666666; + color: white; } .control-btn-label { - margin-left: .25rem; - font-size: .9em; - vertical-align: .05em; + margin-left: 0.25rem; + font-size: 0.9em; + vertical-align: 0.05em; } @media screen and (max-width: 900px) { - .control-btn { - flex: 0 0 2.5em; - } - .control-btn-label { - display: none; - } - .control-search { - padding: 0 .5em; - } + .control-btn { + flex: 0 0 2.5em; + } + .control-btn-label { + display: none; + } + .control-search { + padding: 0 0.5em; + } } .root-dark-mode .control-btn { - color: var(--foreground-dark); - opacity: .9; + color: var(--foreground-dark); + opacity: 0.9; } .root-dark-mode .control-btn:hover { - color: var(--foreground-dark); - opacity: 1; + color: var(--foreground-dark); + opacity: 1; } .control-search { - flex: auto; - color: black; - background-color: rgba(255,255,255,.3) !important; - margin: 0 .5em; - min-width: 8em; + flex: auto; + color: black; + background-color: rgba(255, 255, 255, 0.3) !important; + margin: 0 0.5em; + min-width: 8em; } .control-search:focus { - background-color: white !important; + background-color: white !important; } .root-dark-mode .control-search { - background-color: hsla(0,0%,35%,.6) !important; - color: var(--foreground-dark); + background-color: hsla(0, 0%, 35%, 0.6) !important; + color: var(--foreground-dark); } .root-dark-mode .control-search:focus { - background-color: hsl(0,0%,80%) !important; - color: black !important; + background-color: hsl(0, 0%, 80%) !important; + color: black !important; } .list-menu { - text-align: center; + text-align: center; } .help-desc-box p { - margin: .5em; -} \ No newline at end of file + margin: 0.5em; +} diff --git a/src/Title.js b/src/Title.js index 90f4865..8daf134 100644 --- a/src/Title.js +++ b/src/Title.js @@ -36,10 +36,11 @@ class ControlBar extends PureComponent { ); } - window.addEventListener("hashchange", + window.addEventListener( + 'hashchange', () => { let text = decodeURIComponent(window.location.hash).substr(1); - if(text && text[0]!='#') { + if (text && text[0] != '#') { console.log('search', text); this.setState( { @@ -51,7 +52,7 @@ class ControlBar extends PureComponent { ); } }, - false + false, ); } @@ -136,7 +137,10 @@ class ControlBar extends PureComponent { className="control-search" value={this.state.search_text} placeholder={ - this.props.mode === 'attention' ? '在关注列表中搜索' : '关键词 / tag / #树洞号'} + this.props.mode === 'attention' + ? '在关注列表中搜索' + : '关键词 / tag / #树洞号' + } onChange={this.on_change_bound} onKeyPress={this.on_keypress_bound} /> diff --git a/src/UserAction.css b/src/UserAction.css index 97f8360..99b6e53 100644 --- a/src/UserAction.css +++ b/src/UserAction.css @@ -1,120 +1,119 @@ .login-form p { - margin: 1em 0; - text-align: center; + margin: 1em 0; + text-align: center; } .login-form button { - min-width: 6rem; + min-width: 6rem; } .reply-form { - display: flex; + display: flex; } .reply-sticky { - position: sticky; - bottom: 0; + position: sticky; + bottom: 0; } .reply-form textarea { - resize: vertical; - flex: 1; - min-height: 2em; - height: 4em; + resize: vertical; + flex: 1; + min-height: 2em; + height: 4em; } .reply-form button { - flex: 0 0 3em; - margin-right: 0; + flex: 0 0 3em; + margin-right: 0; } .reply-preview { - flex: 1; - min-height: 2em; + flex: 1; + min-height: 2em; } - .post-form-bar { - line-height: 2em; - display: flex; - flex-wrap: wrap; - margin-bottom: .5em; + line-height: 2em; + display: flex; + flex-wrap: wrap; + margin-bottom: 0.5em; } .post-form-bar .checkbox-bar { - display: flex; - flex-wrap: wrap; + display: flex; + flex-wrap: wrap; } .post-form-bar .checkbox-bar label { - flex: 0 0 auto; - margin: 0 0.5rem; + flex: 0 0 auto; + margin: 0 0.5rem; } -.post-form-bar input[type=file] { - border: 0; - padding: 0 0 0 .5em; +.post-form-bar input[type='file'] { + border: 0; + padding: 0 0 0 0.5em; } @media screen and (max-width: 580px) { - .post-form-bar input[type=file] { - width: 120px; - } + .post-form-bar input[type='file'] { + width: 120px; + } } @media screen and (max-width: 320px) { - .post-form-bar input[type=file] { - width: 100px; - } + .post-form-bar input[type='file'] { + width: 100px; + } } .post-form-bar button { - flex: 0 0 6em; - margin-right: 0; + flex: 0 0 6em; + margin-right: 0; } @media screen and (max-width: 580px) { - .post-form-bar button { - flex: 0 0 4.5em; - margin-right: 0; - } + .post-form-bar button { + flex: 0 0 4.5em; + margin-right: 0; + } } .post-form-img-tip { - font-size: small; - margin-top: -.5em; - margin-bottom: .5em; + font-size: small; + margin-top: -0.5em; + margin-bottom: 0.5em; } .post-form textarea { - resize: vertical; - width: 100%; - min-height: 5em; - height: 20em; + resize: vertical; + width: 100%; + min-height: 5em; + height: 20em; } .post-preview { - width: 100%; - min-height: 5em; + width: 100%; + min-height: 5em; } .life-info-table { - width: 100%; - margin: auto; + width: 100%; + margin: auto; } @media screen and (min-width: 375px) { - .life-info-table { - width: 315px; - } + .life-info-table { + width: 315px; + } } .life-info-table td { - padding: .25em; + padding: 0.25em; } .life-info-table td:nth-child(1) { - font-weight: bold; - text-align: right; + font-weight: bold; + text-align: right; } .life-info-error a { - --var-link-color: hsl(25,100%,45%); + --var-link-color: hsl(25, 100%, 45%); } .spoiler-input { diff --git a/src/UserAction.js b/src/UserAction.js index 176d0d6..d98fa70 100644 --- a/src/UserAction.js +++ b/src/UserAction.js @@ -12,11 +12,8 @@ import { ConfigUI } from './Config'; import fixOrientation from 'fix-orientation'; import copy from 'copy-to-clipboard'; import { cache } from './cache'; -import { - API, - get_json, -} from './flows_api'; -import { save_attentions } from './Attention' +import { API, get_json } from './flows_api'; +import { save_attentions } from './Attention'; import './UserAction.css'; @@ -57,7 +54,9 @@ export function InfoSidebar(props) { -

强烈建议开始使用前先看一遍所有设置选项

+

+ 强烈建议开始使用前先看一遍所有设置选项 +

@@ -87,15 +86,18 @@ export function InfoSidebar(props) {

意见反馈请加tag #意见反馈 或到github后端的issue区。

-

新T树洞强烈期待有其他更多树洞的出现,一起分布式互联,构建清华树洞族。详情见 关于 中的描述。

-

联系我们:{EMAIL}

+

+ 新T树洞强烈期待有其他更多树洞的出现,一起分布式互联,构建清华树洞族。详情见 + 关于 中的描述。 +

+

+ 联系我们:{EMAIL} 。 +

新T树洞 网页版 by @hole_thu,基于 - + AGPLv3 协议在{' '} @@ -121,7 +123,8 @@ export function InfoSidebar(props) { > T大树洞网页版 by @thuhole - 、 + 、{' '} + React 、 @@ -139,8 +142,8 @@ export class LoginForm extends Component { constructor(props) { super(props); this.state = { - 'custom_title': window.TITLE || '' - } + custom_title: window.TITLE || '', + }; } update_title(title, token) { @@ -151,10 +154,11 @@ export class LoginForm extends Component { API.set_title(title, token) .then((json) => { if (json.code === 0) { - window.TITLE = title + window.TITLE = title; alert('专属头衔设置成功'); } - }).catch(err => alert("设置头衔出错了:\n"+ err)); + }) + .catch((err) => alert('设置头衔出错了:\n' + err)); } copy_token(token) { @@ -203,22 +207,27 @@ export class LoginForm extends Component { 复制 User Token
- User Token仅用于开发bot,切勿告知他人。若怀疑被盗号请刷新Token(刷新功能即将上线)。 + User + Token仅用于开发bot,切勿告知他人。若怀疑被盗号请刷新Token(刷新功能即将上线)。

- 专属头衔: + 专属头衔: { - this.setState({ custom_title: e.target.value}) + this.setState({ custom_title: e.target.value }); }} maxLength={10} /> + onClick={(e) => { + this.update_title(this.state.custom_title, token.value); + }} + > + 提交 +
设置专属头衔后,可在发言时选择使用。重置后需重新设置。临时用户如需保持头衔请使用相同后缀。

@@ -319,17 +328,14 @@ export class ReplyForm extends Component { text: text, use_title: use_title ? '1' : '', }); - fetch( - API_BASE + '/docomment', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': this.props.token, - }, - body: data, + fetch(API_BASE + '/docomment', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': this.props.token, }, - ) + body: data, + }) .then(get_json) .then((json) => { if (json.code !== 0) { @@ -338,7 +344,7 @@ export class ReplyForm extends Component { let saved_attentions = window.saved_attentions; if (!saved_attentions.includes(pid)) { - saved_attentions.unshift(pid) + saved_attentions.unshift(pid); window.saved_attentions = saved_attentions; save_attentions(); } @@ -393,7 +399,7 @@ export class ReplyForm extends Component {
@@ -490,18 +496,24 @@ export class PostForm extends Component { } do_post() { - const { cw, text, allow_search, use_title, has_poll, poll_options } = this.state; + const { + cw, + text, + allow_search, + use_title, + has_poll, + poll_options, + } = this.state; let data = new URLSearchParams({ cw: cw, text: text, allow_search: allow_search ? '1' : '', use_title: use_title ? '1' : '', - type: 'text' + type: 'text', }); if (has_poll) { poll_options.forEach((opt) => { - if (opt) - data.append('poll_options', opt); + if (opt) data.append('poll_options', opt); }); } @@ -692,15 +704,14 @@ export class PostForm extends Component { let text = event.target.value; poll_options[idx] = text; if (!text && poll_options.length > 1) { - poll_options.splice(idx, 1) + poll_options.splice(idx, 1); } if (poll_options[poll_options.length - 1] && poll_options.length < 8) { - poll_options.push('') + poll_options.push(''); } this.setState({ poll_options: poll_options }); } - render() { const { has_poll, poll_options, preview, loading_status } = this.state; return ( @@ -748,8 +759,8 @@ export class PostForm extends Component { type="checkbox" onChange={this.on_allow_search_change_bound} checked={this.state.allow_search} - /> - {' '}允许搜索 + />{' '} + 允许搜索 {window.TITLE && ( )}
@@ -815,7 +826,7 @@ export class PostForm extends Component { {has_poll && (
投票选项
- {poll_options.map( (option, idx) => ( + {poll_options.map((option, idx) => ( )} -


+
+
+

请遵守 @@ -839,7 +852,8 @@ export class PostForm extends Component {

- 插入图片请使用图片外链,Markdown格式 ![](图片链接), 支持动图,支持多图。推荐的图床: + 插入图片请使用图片外链,Markdown格式 ![](图片链接), + 支持动图,支持多图。推荐的图床: 路过图床 @@ -848,7 +862,10 @@ export class PostForm extends Component { sm.ms 、 - + 未名BBS 、 diff --git a/src/flows_api.js b/src/flows_api.js index 5e7271d..c7b0781 100644 --- a/src/flows_api.js +++ b/src/flows_api.js @@ -1,4 +1,4 @@ -import { get_json, gen_name} from './infrastructure/functions'; +import { get_json, gen_name } from './infrastructure/functions'; import { API_BASE } from './Common'; import { cache } from './cache'; @@ -35,14 +35,11 @@ export const parse_replies = (replies, color_picker) => export const API = { load_replies: async (pid, token, color_picker, cache_version) => { pid = parseInt(pid); - let response = await fetch( - API_BASE + '/getcomment?pid=' + pid , - { - headers: { - 'User-Token': token, - } - } - ); + let response = await fetch(API_BASE + '/getcomment?pid=' + pid, { + headers: { + 'User-Token': token, + }, + }); let json = await handle_response(response); // Why delete then put ?? //console.log('Put cache', json, pid, cache_version); @@ -70,17 +67,14 @@ export const API = { let data = new URLSearchParams(); data.append('pid', pid); data.append('switch', attention ? '1' : '0'); - let response = await fetch( - API_BASE + '/attention', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/attention', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); // Delete cache to update `attention` on next reload cache().delete(pid); return handle_response(response, false); @@ -90,55 +84,46 @@ export const API = { let data = new URLSearchParams(); data.append('pid', pid); data.append('reason', reason); - let response = await fetch( - API_BASE + '/report', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/report', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, false); }, block: async (type, id, token) => { let data = new URLSearchParams([ - ['type', type], ['id', id] + ['type', type], + ['id', id], ]); - let response = await fetch( - API_BASE + '/block', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/block', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, false); }, - del: async (type, id, note, token) => { let data = new URLSearchParams(); data.append('type', type); data.append('id', id); data.append('note', note); - let response = await fetch( - API_BASE + '/delete', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/delete', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, false); }, @@ -146,17 +131,14 @@ export const API = { let data = new URLSearchParams(); data.append('cw', cw); data.append('pid', id); - let response = await fetch( - API_BASE + '/editcw', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/editcw', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, false); }, @@ -166,7 +148,7 @@ export const API = { window.config.no_c_post ? '&no_cw' : '' }&order_mode=${submode}`, { - headers: {'User-Token': token}, + headers: { 'User-Token': token }, }, ); return handle_response(response); @@ -174,58 +156,49 @@ export const API = { get_search: async (page, keyword, token, submode) => { let response = await fetch( - `${API_BASE}/search?search_mode=${submode}&page=${page}&keywords=${ - encodeURIComponent(keyword) - }&pagesize=${SEARCH_PAGESIZE}`, + `${API_BASE}/search?search_mode=${submode}&page=${page}&keywords=${encodeURIComponent( + keyword, + )}&pagesize=${SEARCH_PAGESIZE}`, { - headers: {'User-Token': token}, - } + headers: { 'User-Token': token }, + }, ); return handle_response(response); }, get_single: async (pid, token) => { - let response = await fetch( - API_BASE + '/getone?pid=' + pid, - { - headers: {'User-Token': token}, - } - ); + let response = await fetch(API_BASE + '/getone?pid=' + pid, { + headers: { 'User-Token': token }, + }); return handle_response(response); }, get_attention: async (token) => { - let response = await fetch( - API_BASE + '/getattention', - { - headers: {'User-Token': token}, - } - ); + let response = await fetch(API_BASE + '/getattention', { + headers: { 'User-Token': token }, + }); return handle_response(response); }, add_vote: async (vote, pid, token) => { let data = new URLSearchParams([ ['vote', vote], - ['pid', pid] + ['pid', pid], ]); - let response = await fetch( - API_BASE + '/vote', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/vote', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, true); }, get_multi: async (pids, token) => { let response = await fetch( - API_BASE + '/getmulti?' + pids.map(pid => `pids=${pid}`).join('&'), + API_BASE + '/getmulti?' + pids.map((pid) => `pids=${pid}`).join('&'), { headers: { 'User-Token': token, @@ -238,18 +211,14 @@ export const API = { set_title: async (title, token) => { console.log('title: ', title); let data = new URLSearchParams([['title', title]]); - let response = await fetch( - API_BASE + '/title', - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'User-Token': token, - }, - body: data, + let response = await fetch(API_BASE + '/title', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'User-Token': token, }, - ); + body: data, + }); return handle_response(response, true); }, - }; diff --git a/src/fonts_7/icomoon.css b/src/fonts_7/icomoon.css index 49071f0..70d7e3e 100644 --- a/src/fonts_7/icomoon.css +++ b/src/fonts_7/icomoon.css @@ -1,7 +1,6 @@ @font-face { font-family: 'icomoon'; - src: - url('icomoon.ttf?8qh3rt') format('truetype'), + src: url('icomoon.ttf?8qh3rt') format('truetype'), url('icomoon.woff?8qh3rt') format('woff'), url('icomoon.svg?8qh3rt#icomoon') format('svg'); font-weight: normal; @@ -19,7 +18,7 @@ font-variant: normal; text-transform: none; line-height: 1; - vertical-align: -.0625em; + vertical-align: -0.0625em; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; @@ -27,84 +26,84 @@ } .icon-send:before { - content: "\e900"; + content: '\e900'; } .icon-textfile:before { - content: "\e926"; + content: '\e926'; } .icon-history:before { - content: "\e94d"; + content: '\e94d'; } .icon-reply:before { - content: "\e96b"; + content: '\e96b'; } .icon-quote:before { - content: "\e977"; + content: '\e977'; } .icon-loading:before { - content: "\e979"; + content: '\e979'; } .icon-login:before { - content: "\e98d"; + content: '\e98d'; } .icon-settings:before { - content: "\e994"; + content: '\e994'; } .icon-stats:before { - content: "\e99b"; + content: '\e99b'; } .icon-locate:before { - content: "\e9b3"; + content: '\e9b3'; } .icon-upload:before { - content: "\e9c3"; + content: '\e9c3'; } .icon-flag:before { - content: "\e9cc"; + content: '\e9cc'; } .icon-attention:before { - content: "\e9d3"; + content: '\e9d3'; } .icon-star:before { - content: "\e9d7"; + content: '\e9d7'; } .icon-star-ok:before { - content: "\e9d9"; + content: '\e9d9'; } .icon-plus:before { - content: "\ea0a"; + content: '\ea0a'; } .icon-about:before { - content: "\ea0c"; + content: '\ea0c'; } .icon-close:before { - content: "\ea0d"; + content: '\ea0d'; } .icon-logout:before { - content: "\ea14"; + content: '\ea14'; } .icon-refresh:before { - content: "\ea2e"; + content: '\ea2e'; } .icon-forward:before { - content: "\ea42"; + content: '\ea42'; } .icon-back:before { - content: "\ea44"; + content: '\ea44'; } .icon-order-rev:before { - content: "\ea46"; + content: '\ea46'; font-size: 1.2em; } .icon-github:before { - content: "\eab0"; + content: '\eab0'; } .icon-new-tab:before { - content: "\ea7e"; + content: '\ea7e'; } .icon-eye:before { - content: "\e9ce"; + content: '\e9ce'; } .icon-eye-blocked:before { - content: "\e9d1"; + content: '\e9d1'; } diff --git a/src/index.css b/src/index.css index c0da48c..737977e 100644 --- a/src/index.css +++ b/src/index.css @@ -1,87 +1,98 @@ body { - background-size: cover; - user-select: none; - background-color: #333; + background-size: cover; + user-select: none; + background-color: #333; } body.root-dark-mode { - background-color: black; + background-color: black; } html::-webkit-scrollbar { - display: none; + display: none; } html { - scrollbar-width: none; - -ms-overflow-style: none; + scrollbar-width: none; + -ms-overflow-style: none; } :root { - --var-link-color: #00c; + --var-link-color: #00c; } -.root-dark-mode .left-container, .root-dark-mode .sidebar, .root-dark-mode .sidebar-title, .root-dark-mode .balance-popover { - --var-link-color: #9bf; +.root-dark-mode .left-container, +.root-dark-mode .sidebar, +.root-dark-mode .sidebar-title, +.root-dark-mode .balance-popover { + --var-link-color: #9bf; } a { - color: var(--var-link-color); + color: var(--var-link-color); } a:not(.no-underline):hover { - border-bottom: 1px solid var(--var-link-color); - margin-bottom: -1px; + border-bottom: 1px solid var(--var-link-color); + margin-bottom: -1px; } -input, textarea { - border-radius: 5px; - border: 1px solid black; - outline: none; - margin: 0; +input, +textarea { + border-radius: 5px; + border: 1px solid black; + outline: none; + margin: 0; } input { - padding: 0 1em; - line-height: 2em; + padding: 0 1em; + line-height: 2em; } audio { - vertical-align: middle; + vertical-align: middle; } -button, .button { - color: black; - background-color: rgba(235,235,235,.5); - border-radius: 5px; - text-align: center; - border: 1px solid black; - line-height: 2em; - margin: 0 .5rem; +button, +.button { + color: black; + background-color: rgba(235, 235, 235, 0.5); + border-radius: 5px; + text-align: center; + border: 1px solid black; + line-height: 2em; + margin: 0 0.5rem; } -.root-dark-mode button, .root-dark-mode .button { - background-color: hsl(0,0%,30%); - color: var(--foreground-dark); +.root-dark-mode button, +.root-dark-mode .button { + background-color: hsl(0, 0%, 30%); + color: var(--foreground-dark); } -button:hover, .button:hover { - background-color: rgba(255,255,255,.7); +button:hover, +.button:hover { + background-color: rgba(255, 255, 255, 0.7); } -.root-dark-mode button:hover, .root-dark-mode .button:hover { - background-color: hsl(0,0%,40%); +.root-dark-mode button:hover, +.root-dark-mode .button:hover { + background-color: hsl(0, 0%, 40%); } -button:disabled, .button:disabled { - background-color: rgba(128,128,128,.5); +button:disabled, +.button:disabled { + background-color: rgba(128, 128, 128, 0.5); } -.root-dark-mode button:disabled, .root-dark-mode .button:disabled { - background-color: hsl(0,0%,20%); - color: hsl(0,0%,60%); +.root-dark-mode button:disabled, +.root-dark-mode .button:disabled { + background-color: hsl(0, 0%, 20%); + color: hsl(0, 0%, 60%); } -.root-dark-mode input:not([type=file]), .root-dark-mode textarea { - background-color: hsl(0,0%,30%); - color: var(--foreground-dark); +.root-dark-mode input:not([type='file']), +.root-dark-mode textarea { + background-color: hsl(0, 0%, 30%); + color: var(--foreground-dark); +} +.root-dark-mode input:not([type='file'])::placeholder { + color: var(--foreground-dark); } -.root-dark-mode input:not([type=file])::placeholder { - color: var(--foreground-dark); -} \ No newline at end of file diff --git a/src/index.js b/src/index.js index f44e849..7f2172c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; -import './fonts_7/icomoon.css' +import './fonts_7/icomoon.css'; import App from './App'; //import {elevate} from './infrastructure/elevator'; import registerServiceWorker from './registerServiceWorker'; diff --git a/src/infrastructure/functions.js b/src/infrastructure/functions.js index 2bfca57..688489a 100644 --- a/src/infrastructure/functions.js +++ b/src/infrastructure/functions.js @@ -1,75 +1,72 @@ export function get_json(res) { - if(!res.ok) { - return ( - res.text().then((t) => { - console.log('error:', res); - t = t.length < 100 ? t : ''; - throw Error(`${res.status} ${res.statusText} ${t}`); - }) - ); + if (!res.ok) { + return res.text().then((t) => { + console.log('error:', res); + t = t.length < 100 ? t : ''; + throw Error(`${res.status} ${res.statusText} ${t}`); + }); + } + return res.text().then((t) => { + try { + return JSON.parse(t); + } catch (e) { + console.error('json parse error'); + console.trace(e); + console.log(t); + throw new SyntaxError('JSON Parse Error ' + t.substr(0, 50)); } - return ( - res - .text() - .then((t)=>{ - try { - return JSON.parse(t); - } catch(e) { - console.error('json parse error'); - console.trace(e); - console.log(t); - throw new SyntaxError('JSON Parse Error '+t.substr(0,50)); - } - }) - ); + }); } -export function listen_darkmode(override) { // override: true/false/undefined - function update_color_scheme() { - if(override===undefined ? window.matchMedia('(prefers-color-scheme: dark)').matches : override) - document.body.classList.add('root-dark-mode'); - else - document.body.classList.remove('root-dark-mode'); - } +export function listen_darkmode(override) { + // override: true/false/undefined + function update_color_scheme() { + if ( + override === undefined + ? window.matchMedia('(prefers-color-scheme: dark)').matches + : override + ) + document.body.classList.add('root-dark-mode'); + else document.body.classList.remove('root-dark-mode'); + } + update_color_scheme(); + window.matchMedia('(prefers-color-scheme: dark)').addListener(() => { update_color_scheme(); - window.matchMedia('(prefers-color-scheme: dark)').addListener(()=>{ - update_color_scheme(); - }); + }); } const NAMES = [ -'Alice', -'Bob', -'Carol', -'Dave', -'Eve', -'Francis', -'Grace', -'Hans', -'Isabella', -'Jason', -'Kate', -'Louis', -'Margaret', -'Nathan', -'Olivia', -'Paul', -'Queen', -'Richard', -'Susan', -'Thomas', -'Uma', -'Vivian', -'Winnie', -'Xander', -'Yasmine', -'Zach' -] + 'Alice', + 'Bob', + 'Carol', + 'Dave', + 'Eve', + 'Francis', + 'Grace', + 'Hans', + 'Isabella', + 'Jason', + 'Kate', + 'Louis', + 'Margaret', + 'Nathan', + 'Olivia', + 'Paul', + 'Queen', + 'Richard', + 'Susan', + 'Thomas', + 'Uma', + 'Vivian', + 'Winnie', + 'Xander', + 'Yasmine', + 'Zach', +]; export function gen_name(name_id) { - if (name_id == 0) - return '洞主'; + if (name_id == 0) return '洞主'; let r = name_id; let name = ''; @@ -81,4 +78,3 @@ export function gen_name(name_id) { return name.substr(1); } - diff --git a/src/infrastructure/global.css b/src/infrastructure/global.css index 6be140f..153d8e6 100644 --- a/src/infrastructure/global.css +++ b/src/infrastructure/global.css @@ -1,37 +1,40 @@ :root { - --foreground-dark: hsl(0,0%,93%); + --foreground-dark: hsl(0, 0%, 93%); } body { - margin: 0; - padding: 0; - overflow-x: hidden; - text-size-adjust: 100%; + margin: 0; + padding: 0; + overflow-x: hidden; + text-size-adjust: 100%; } -body, textarea, pre { - font-family: 'Segoe UI', '微软雅黑', 'Microsoft YaHei', sans-serif; +body, +textarea, +pre { + font-family: 'Segoe UI', '微软雅黑', 'Microsoft YaHei', sans-serif; } * { - box-sizing: border-box; - word-wrap: break-word; - -webkit-overflow-scrolling: touch; + box-sizing: border-box; + word-wrap: break-word; + -webkit-overflow-scrolling: touch; } -p, pre { - margin: 0; +p, +pre { + margin: 0; } a { - text-decoration: none; - cursor: pointer; + text-decoration: none; + cursor: pointer; } pre { - white-space: pre-line; + white-space: pre-line; } code { - font-family: Consolas, Courier, monospace; -} \ No newline at end of file + font-family: Consolas, Courier, monospace; +} diff --git a/src/infrastructure/widgets.css b/src/infrastructure/widgets.css index 4edfcc2..3d66b1c 100644 --- a/src/infrastructure/widgets.css +++ b/src/infrastructure/widgets.css @@ -1,312 +1,322 @@ .centered-line { - overflow: hidden; - text-align: center; + overflow: hidden; + text-align: center; } .centered-line::before, .centered-line::after { - background-color: #000; - content: ""; - display: inline-block; - height: 1px; - position: relative; - vertical-align: middle; - width: 50%; + background-color: #000; + content: ''; + display: inline-block; + height: 1px; + position: relative; + vertical-align: middle; + width: 50%; } .root-dark-mode .centered-line { - color: var(--foreground-dark); + color: var(--foreground-dark); } -.root-dark-mode .centered-line::before, .root-dark-mode .centered-line::after { - background-color: var(--foreground-dark); +.root-dark-mode .centered-line::before, +.root-dark-mode .centered-line::after { + background-color: var(--foreground-dark); } .centered-line::before { - right: 1em; - margin-left: -50%; + right: 1em; + margin-left: -50%; } .centered-line::after { - left: 1em; - margin-right: -50%; + left: 1em; + margin-right: -50%; } .title-line { - color: #fff; - margin-top: 1em; + color: #fff; + margin-top: 1em; } .title-line::before, .title-line::after { - background-color: #fff; - box-shadow: 0 1px 1px #000; + background-color: #fff; + box-shadow: 0 1px 1px #000; } .root-dark-mode .title-line { - color: var(--foreground-dark); + color: var(--foreground-dark); } -.root-dark-mode .title-line::before, .root-dark-mode .title-line::after { - background-color: var(--foreground-dark); +.root-dark-mode .title-line::before, +.root-dark-mode .title-line::after { + background-color: var(--foreground-dark); } .app-switcher { - display: flex; - height: 2em; - text-align: center; - margin: 0 .1em; - user-select: none; + display: flex; + height: 2em; + text-align: center; + margin: 0 0.1em; + user-select: none; } .app-switcher-desc { - margin: 0 .5em; - flex: 1 1 0; - opacity: .5; - height: 2em; - line-height: 2rem; - font-size: .8em; + margin: 0 0.5em; + flex: 1 1 0; + opacity: 0.5; + height: 2em; + line-height: 2rem; + font-size: 0.8em; } .root-dark-mode .app-switcher-desc { - color: var(--foreground-dark); + color: var(--foreground-dark); } @media screen and (max-width: 570px) { - .app-switcher-desc { - flex: 1 1 0; - display: none; - } - .app-switcher-item { - flex: 1 1 0 !important; - padding: 0 !important; - } - .app-switcher-dropdown-title { - padding-left: 0 !important; - padding-right: 0 !important; - text-align: center !important; - } - .app-switcher-dropdown-item { - margin-left: -2em !important; - margin-right: 0 !important; - } + .app-switcher-desc { + flex: 1 1 0; + display: none; + } + .app-switcher-item { + flex: 1 1 0 !important; + padding: 0 !important; + } + .app-switcher-dropdown-title { + padding-left: 0 !important; + padding-right: 0 !important; + text-align: center !important; + } + .app-switcher-dropdown-item { + margin-left: -2em !important; + margin-right: 0 !important; + } } -.app-switcher a:hover { /* reset underline from /hole style */ - border-bottom: unset; - margin-bottom: unset; +.app-switcher a:hover { + /* reset underline from /hole style */ + border-bottom: unset; + margin-bottom: unset; } .app-switcher-desc a { - color: unset; + color: unset; } .app-switcher-left { - text-align: right; + text-align: right; } .app-switcher-right { - text-align: left; + text-align: left; } .app-switcher-item { - flex: 0 0 auto; - border-radius: 3px; - height: 1.6em; - line-height: 1.6em; - margin: .2em .1em; - padding: 0 .45em; -} -a.app-switcher-item, .app-switcher-item a { - transition: unset; /* override ant design */ - color: black; + flex: 0 0 auto; + border-radius: 3px; + height: 1.6em; + line-height: 1.6em; + margin: 0.2em 0.1em; + padding: 0 0.45em; +} +a.app-switcher-item, +.app-switcher-item a { + transition: unset; /* override ant design */ + color: black; } .app-switcher-item img { - width: 1.2rem; - height: 1.2rem; - position: relative; - top: .2rem; - vertical-align: unset; /* override ant design */ + width: 1.2rem; + height: 1.2rem; + position: relative; + top: 0.2rem; + vertical-align: unset; /* override ant design */ } .app-switcher-item span:not(:empty) { - margin-left: .2rem; + margin-left: 0.2rem; } .app-switcher-logo-hover { - margin-left: -1.2rem; + margin-left: -1.2rem; } .app-switcher-item:hover { - background-color: black; - color: white !important; + background-color: black; + color: white !important; } .app-switcher-item:hover a { - color: white !important; + color: white !important; } .app-switcher-item-current { - background-color: rgba(0,0,0,.4); - text-shadow: 0 0 5px rgba(0,0,0,.5); - color: white !important; + background-color: rgba(0, 0, 0, 0.4); + text-shadow: 0 0 5px rgba(0, 0, 0, 0.5); + color: white !important; } .app-switcher-item-current a { - color: white !important; + color: white !important; } -.root-dark-mode .app-switcher-item, .root-dark-mode .app-switcher-dropdown-title a { - color: var(--foreground-dark); +.root-dark-mode .app-switcher-item, +.root-dark-mode .app-switcher-dropdown-title a { + color: var(--foreground-dark); } -.root-dark-mode .app-switcher-item:hover, .root-dark-mode .app-switcher-item-current, .root-dark-mode .app-switcher-dropdown-title:hover a { - background-color: #555; - color: var(--foreground-dark); +.root-dark-mode .app-switcher-item:hover, +.root-dark-mode .app-switcher-item-current, +.root-dark-mode .app-switcher-dropdown-title:hover a { + background-color: #555; + color: var(--foreground-dark); } -.app-switcher-item:hover .app-switcher-logo-normal, .app-switcher-item-current .app-switcher-logo-normal { - opacity: 0; +.app-switcher-item:hover .app-switcher-logo-normal, +.app-switcher-item-current .app-switcher-logo-normal { + opacity: 0; } -.app-switcher-item:not(.app-switcher-item-current):not(:hover) .app-switcher-logo-hover { - opacity: 0; +.app-switcher-item:not(.app-switcher-item-current):not(:hover) + .app-switcher-logo-hover { + opacity: 0; } .root-dark-mode .app-switcher-logo-normal { - opacity: 0 !important; + opacity: 0 !important; } .root-dark-mode .app-switcher-logo-hover { - opacity: 1 !important; + opacity: 1 !important; } .app-switcher-dropdown { - padding: 0; - text-align: left; + padding: 0; + text-align: left; } .app-switcher-dropdown:not(:hover) { - max-height: 1.6rem; - overflow: hidden; + max-height: 1.6rem; + overflow: hidden; } .app-switcher-dropdown-item { - background-color: hsla(0,0%,35%,.9); - padding: .125em .25em; - margin-left: -.75em; - margin-right: -.75em; - position: relative; - z-index: 10; - cursor: pointer; + background-color: hsla(0, 0%, 35%, 0.9); + padding: 0.125em 0.25em; + margin-left: -0.75em; + margin-right: -0.75em; + position: relative; + z-index: 10; + cursor: pointer; } .app-switcher-dropdown-item:hover { - background-color: rgba(0,0,0,.9); + background-color: rgba(0, 0, 0, 0.9); } .app-switcher-dropdown-item:nth-child(2) { - border-top-left-radius: 3px; - border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } .app-switcher-dropdown-item:last-child { - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; } .app-switcher-dropdown-title { - padding-bottom: .2em; - padding-left: .5em; - padding-right: .25em; + padding-bottom: 0.2em; + padding-left: 0.5em; + padding-right: 0.25em; } .app-switcher-dropdown-title a { - cursor: unset; + cursor: unset; } .thuhole-login-popup { - font-size: 1rem; - background-color: #f7f7f7; - color: black; - position: fixed; - left: 50%; - top: 50%; - width: 320px; - z-index: 114515; - transform: translateX(-50%) translateY(-50%); - border-radius: 5px; + font-size: 1rem; + background-color: #f7f7f7; + color: black; + position: fixed; + left: 50%; + top: 50%; + width: 320px; + z-index: 114515; + transform: translateX(-50%) translateY(-50%); + border-radius: 5px; } .thuhole-login-popup a { - color: #00c; + color: #00c; } .thuhole-login-popup p { - margin: 1.25em 0; - text-align: center; + margin: 1.25em 0; + text-align: center; } .thuhole-login-popup-info p { - margin: .25em 1em; - text-align: left; + margin: 0.25em 1em; + text-align: left; } .thuhole-login-popup-info ul { - margin: .75em 1em; - text-align: left; - font-size: 75%; + margin: 0.75em 1em; + text-align: left; + font-size: 75%; } /* override ant design */ -.thuhole-login-popup input, .thuhole-login-popup button { - font-size: .85em; - vertical-align: middle; -} -.thuhole-login-popup input:not([type="checkbox"]) { - width: 8rem; - border-radius: 5px; - border: 1px solid black; - outline: none; - margin: 0; - padding: 0 .5em; - line-height: 2em; +.thuhole-login-popup input, +.thuhole-login-popup button { + font-size: 0.85em; + vertical-align: middle; +} +.thuhole-login-popup input:not([type='checkbox']) { + width: 8rem; + border-radius: 5px; + border: 1px solid black; + outline: none; + margin: 0; + padding: 0 0.5em; + line-height: 2em; } .thuhole-login-popup button { - min-width: 6rem; - color: black; - background-color: rgba(235,235,235,.5); - border-radius: 5px; - text-align: center; - border: 1px solid black; - line-height: 2em; - margin: 0 .5rem; + min-width: 6rem; + color: black; + background-color: rgba(235, 235, 235, 0.5); + border-radius: 5px; + text-align: center; + border: 1px solid black; + line-height: 2em; + margin: 0 0.5rem; } .thuhole-login-popup button:hover { - background-color: rgba(255,255,255,.7); + background-color: rgba(255, 255, 255, 0.7); } .thuhole-login-popup button:disabled { - background-color: rgba(128,128,128,.5); + background-color: rgba(128, 128, 128, 0.5); } .thuhole-login-type { - display: inline-block; - width: 6rem; - margin: 0 .5rem; + display: inline-block; + width: 6rem; + margin: 0 0.5rem; } .thuhole-login-popup-shadow { - opacity: .5; - background-color: black; - position: fixed; - left: 0; - top: 0; - height: 100%; - width: 100%; - z-index: 114514; + opacity: 0.5; + background-color: black; + position: fixed; + left: 0; + top: 0; + height: 100%; + width: 100%; + z-index: 114514; } .thuhole-login-popup label.perm-item { - font-size: .8em; - vertical-align: .1rem; - margin-left: .5rem; + font-size: 0.8em; + vertical-align: 0.1rem; + margin-left: 0.5rem; } .aux-margin { - width: calc(100% - 2 * 50px); - margin: 0 50px; + width: calc(100% - 2 * 50px); + margin: 0 50px; } @media screen and (max-width: 1300px) { - .aux-margin { - width: calc(100% - 2 * 10px); - margin: 0 10px; - } + .aux-margin { + width: calc(100% - 2 * 10px); + margin: 0 10px; + } } .title { - font-size: 1.5em; - height: 4rem; - padding-top: 1rem; - text-align: center; + font-size: 1.5em; + height: 4rem; + padding-top: 1rem; + text-align: center; } .time-str { - color: #999999; + color: #999999; } a.button { diff --git a/src/infrastructure/widgets.js b/src/infrastructure/widgets.js index aaba2ce..0507b20 100644 --- a/src/infrastructure/widgets.js +++ b/src/infrastructure/widgets.js @@ -1,4 +1,4 @@ -import React, {Component, PureComponent} from 'react'; +import React, { Component, PureComponent } from 'react'; import ReactDOM from 'react-dom'; import TimeAgo from 'react-timeago'; @@ -8,57 +8,63 @@ import buildFormatter from 'react-timeago/lib/formatters/buildFormatter'; import './global.css'; import './widgets.css'; -import {get_json, API_VERSION_PARAM} from './functions'; +import { get_json, API_VERSION_PARAM } from './functions'; function pad2(x) { - return x<10 ? '0'+x : ''+x; + return x < 10 ? '0' + x : '' + x; } export function format_time(time) { - return `${time.getMonth()+1}-${pad2(time.getDate())} ${time.getHours()}:${pad2(time.getMinutes())}:${pad2(time.getSeconds())}`; + return `${time.getMonth() + 1}-${pad2( + time.getDate(), + )} ${time.getHours()}:${pad2(time.getMinutes())}:${pad2(time.getSeconds())}`; } -const chinese_format=buildFormatter(chineseStrings); +const chinese_format = buildFormatter(chineseStrings); export function Time(props) { - const time=new Date(props.stamp*1000); - return ( - - -   - {!props.short ? format_time(time) : null} - - ); + const time = new Date(props.stamp * 1000); + return ( + + +   + {!props.short ? format_time(time) : null} + + ); } export function TitleLine(props) { - return ( -

- {props.text} -

- ) + return ( +

+ {props.text} +

+ ); } export function GlobalTitle(props) { - return ( -
-
-

{props.text}

-
-
- ); + return ( +
+
+

{props.text}

+
+
+ ); } class LoginPopupSelf extends Component { - constructor(props) { - super(props); - this.state={ - loading_status: 'idle', - } + constructor(props) { + super(props); + this.state = { + loading_status: 'idle', + }; + + this.input_token_ref = React.createRef(); + } - this.input_token_ref=React.createRef(); - }; - setThuhole(e, tar, ref) { console.log(tar); e.preventDefault(); @@ -67,105 +73,111 @@ class LoginPopupSelf extends Component { alert('T大树洞已经没有啦😭'); } - render() { - - return ( -
-
-
-

- 通过第三方验证登陆新T树洞 -

-

- - -  闭社 - -

-

- -
- {this.setThuhole(e, e.target, this.input_token_ref)}} - > - -  T大树洞 - -

-

- 前往Telegram群查询15分钟临时token -
- - -  清华大水群 - -

-

- -

-

- -

-
-

- -

-
-
-

提醒: -

-
    -
  • 无论采用哪种方式注册,你后台记录的用户名都是本质实名的(除临时token),因为闭社/T大树洞的管理员可以根据你的闭社id/树洞评论区代号查到邮箱。但是这不影响新T树洞的安全性。新T树洞的匿名性来自隔离用户名与发布的内容,而非试图隔离用户名与真实身份。
  • -
  • 由于T大树洞仍未提供授权接口,使用T大树洞方式登陆需要用你的token在特定洞发布一段随机内容以确定身份。这是否违反用户条例由T大树洞管理员决定,需自行承担相关风险。完成登陆后建议立即重置T大树洞token。
  • -
  • 目前一个人可能有两个帐号。
  • -
-
-
-
- ); - } + render() { + return ( +
+
+
+

+ 通过第三方验证登陆新T树洞 +

+

+ + +  闭社 + +

+

+ +
+ { + this.setThuhole(e, e.target, this.input_token_ref); + }} + > + +  T大树洞 + +

+

+ 前往Telegram群查询15分钟临时token +
+ + +  清华大水群 + +

+

+ +

+

+ +

+
+

+ +

+
+
+

提醒:

+
    +
  • + {' '} + 无论采用哪种方式注册,你后台记录的用户名都是本质实名的(除临时token),因为闭社/T大树洞的管理员可以根据你的闭社id/树洞评论区代号查到邮箱。但是这不影响新T树洞的安全性。新T树洞的匿名性来自隔离用户名与发布的内容,而非试图隔离用户名与真实身份。 +
  • +
  • + {' '} + 由于T大树洞仍未提供授权接口,使用T大树洞方式登陆需要用你的token在特定洞发布一段随机内容以确定身份。这是否违反用户条例由T大树洞管理员决定,需自行承担相关风险。完成登陆后建议立即重置T大树洞token。{' '} +
  • +
  • 目前一个人可能有两个帐号。
  • +
+
+
+
+ ); + } } export class LoginPopup extends Component { - constructor(props) { - super(props); - this.state={ - popup_show: false, - }; - this.on_popup_bound=this.on_popup.bind(this); - this.on_close_bound=this.on_close.bind(this); - } + constructor(props) { + super(props); + this.state = { + popup_show: false, + }; + this.on_popup_bound = this.on_popup.bind(this); + this.on_close_bound = this.on_close.bind(this); + } - on_popup() { - this.setState({ - popup_show: true, - }); - } - on_close() { - this.setState({ - popup_show: false, - }); - } + on_popup() { + this.setState({ + popup_show: true, + }); + } + on_close() { + this.setState({ + popup_show: false, + }); + } - render() { - return ( - <> - {this.props.children(this.on_popup_bound)} - {this.state.popup_show && - - } - - ); - } + render() { + return ( + <> + {this.props.children(this.on_popup_bound)} + {this.state.popup_show && ( + + )} + + ); + } }