diff --git a/public/index.html b/public/index.html index 49eabdb..e133c73 100644 --- a/public/index.html +++ b/public/index.html @@ -3,19 +3,19 @@ - + - + - + @@ -23,7 +23,7 @@ - P大树洞 + T大树洞
diff --git a/public/static/bg/cyberpunk.jpg b/public/static/bg/cyberpunk.jpg new file mode 100644 index 0000000..d93a1fb Binary files /dev/null and b/public/static/bg/cyberpunk.jpg differ diff --git a/public/static/favicon/180.png b/public/static/favicon/180.png index c289745..b08e109 100644 Binary files a/public/static/favicon/180.png and b/public/static/favicon/180.png differ diff --git a/public/static/favicon/192.png b/public/static/favicon/192.png index 658e5cb..ed4f0c8 100644 Binary files a/public/static/favicon/192.png and b/public/static/favicon/192.png differ diff --git a/public/static/favicon/256.png b/public/static/favicon/256.png deleted file mode 100644 index c06dacf..0000000 Binary files a/public/static/favicon/256.png and /dev/null differ diff --git a/public/static/favicon/512.png b/public/static/favicon/512.png new file mode 100644 index 0000000..0ac9fec Binary files /dev/null and b/public/static/favicon/512.png differ diff --git a/public/static/manifest.json b/public/static/manifest.json index b41136c..355d8b8 100644 --- a/public/static/manifest.json +++ b/public/static/manifest.json @@ -1,10 +1,10 @@ { "short_name": "树洞", - "name": "P大树洞", + "name": "T大树洞", "icons": [ { - "src": "favicon/256.png", - "sizes": "256x256", + "src": "favicon/512.png", + "sizes": "512x512", "type": "image/png" }, { diff --git a/public/stats.js b/public/stats.js index cdfe677..6284982 100644 --- a/public/stats.js +++ b/public/stats.js @@ -1,25 +1,25 @@ -var _czc=_czc||[]; -_czc.push(["_setAccount","1274501752"]); -_czc.push(["_setCustomVar","has_token",localStorage['TOKEN']?'yes':'no',1]); -_czc.push(["_setCustomVar","standalone",((window.matchMedia('(display-mode: standalone)').matches) || (window.navigator.standalone))?'yes':'no',1]); -_czc.push(["_setCustomVar","build_info","%REACT_APP_BUILD_INFO%"||'---']); -var cr_version=/Chrome\/(\d+)/.exec(navigator.userAgent); -_czc.push(["_setCustomVar","cr_version_test",cr_version?cr_version[1]:'[null]',2]); -/* -// track config -try { - var config=JSON.parse(localStorage['hole_config']||'{}'); - for(var key in config) - if(config.hasOwnProperty(key)) - _czc.push(["_trackEvent",'config',key,encodeURIComponent(JSON.stringify(config[key])),0,'']); - //_czc.push(["_setCustomVar","config_"+key,encodeURIComponent(JSON.stringify(config[key])),0]); -} catch(e) { - console.trace(e); -} -*/ -var cnzz_s_tag = document.createElement('script'); -cnzz_s_tag.type = 'text/javascript'; -cnzz_s_tag.async = true; -cnzz_s_tag.charset = "utf-8"; -cnzz_s_tag.src = "https://w.cnzz.com/c.php?id=1274501752&async=1"; -document.head.appendChild(cnzz_s_tag); \ No newline at end of file +// var _czc=_czc||[]; +// _czc.push(["_setAccount","1274501752"]); +// _czc.push(["_setCustomVar","has_token",localStorage['TOKEN']?'yes':'no',1]); +// _czc.push(["_setCustomVar","standalone",((window.matchMedia('(display-mode: standalone)').matches) || (window.navigator.standalone))?'yes':'no',1]); +// _czc.push(["_setCustomVar","build_info","%REACT_APP_BUILD_INFO%"||'---']); +// var cr_version=/Chrome\/(\d+)/.exec(navigator.userAgent); +// _czc.push(["_setCustomVar","cr_version_test",cr_version?cr_version[1]:'[null]',2]); +// /* +// // track config +// try { +// var config=JSON.parse(localStorage['hole_config']||'{}'); +// for(var key in config) +// if(config.hasOwnProperty(key)) +// _czc.push(["_trackEvent",'config',key,encodeURIComponent(JSON.stringify(config[key])),0,'']); +// //_czc.push(["_setCustomVar","config_"+key,encodeURIComponent(JSON.stringify(config[key])),0]); +// } catch(e) { +// console.trace(e); +// } +// */ +// var cnzz_s_tag = document.createElement('script'); +// cnzz_s_tag.type = 'text/javascript'; +// cnzz_s_tag.async = true; +// cnzz_s_tag.charset = "utf-8"; +// cnzz_s_tag.src = "https://w.cnzz.com/c.php?id=1274501752&async=1"; +// document.head.appendChild(cnzz_s_tag); \ No newline at end of file diff --git a/src/App.js b/src/App.js index 85f3035..12d0481 100644 --- a/src/App.js +++ b/src/App.js @@ -106,14 +106,14 @@ class App extends Component { {(do_popup)=>( -  登录到 PKU Helper +  登录到 T大树洞 )}

} - {this.inpku_flag||token.value ? + {this.inpku_flag||token.value||true ? : diff --git a/src/Common.js b/src/Common.js index 81171d8..3a2d07a 100644 --- a/src/Common.js +++ b/src/Common.js @@ -1,12 +1,12 @@ import React, {Component, PureComponent} from 'react'; import {format_time,Time,TitleLine} from './infrastructure/widgets'; -import {PKUHELPER_ROOT} from './flows_api'; +import {THUHOLE_API_ROOT} from './flows_api'; import './Common.css'; export {format_time,Time,TitleLine}; -export const API_BASE=PKUHELPER_ROOT+'services/pkuhole'; +export const API_BASE=THUHOLE_API_ROOT+'services/thuhole'; // https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex function escape_regex(string) { @@ -37,9 +37,9 @@ export class HighlightedText extends PureComponent { let [rule,p]=part; return ( { - rule==='url_pid' ? /hole/## : + rule==='url_pid' ? /## : rule==='url' ? {p} : - rule==='pid' ? {e.preventDefault(); this.props.show_pid(p);}}>{p} : + rule==='pid' ? {e.preventDefault(); this.props.show_pid(p.substring(1));}}>{p} : rule==='nickname' ? {p} : rule==='search' ? {p} : p diff --git a/src/Config.js b/src/Config.js index cf5cb9f..3546a92 100644 --- a/src/Config.js +++ b/src/Config.js @@ -7,6 +7,7 @@ const BUILTIN_IMGS={ 'static/bg/eriri.jpg': '平成著名画师', 'static/bg/yurucamp.jpg': '露营天下第一', 'static/bg/minecraft.jpg': '麦恩·库拉夫特', + 'static/bg/cyberpunk.jpg': '赛博城市', 'static/bg/sif.jpg': '梦开始的地方', }; @@ -238,7 +239,7 @@ export class ConfigUI extends PureComponent {

新功能建议或问题反馈请在  - GitHub + GitHub  提出。

diff --git a/src/Flows.js b/src/Flows.js index 3d093cf..8148ec3 100644 --- a/src/Flows.js +++ b/src/Flows.js @@ -8,14 +8,15 @@ import LazyLoad from './react-lazyload/src'; import {AudioWidget} from './AudioWidget'; import {TokenCtx, ReplyForm} from './UserAction'; -import {API, PKUHELPER_ROOT} from './flows_api'; +import {API, THUHOLE_API_ROOT} from './flows_api'; -const IMAGE_BASE=PKUHELPER_ROOT+'services/pkuhole/images/'; -const AUDIO_BASE=PKUHELPER_ROOT+'services/pkuhole/audios/'; +const IMAGE_BASE=THUHOLE_API_ROOT+'services/thuhole/images/'; +const AUDIO_BASE=THUHOLE_API_ROOT+'services/thuhole/audios/'; const CLICKABLE_TAGS={a: true, audio: true}; const PREVIEW_REPLY_COUNT=10; -const QUOTE_BLACKLIST=['23333','233333','66666','666666','10086','10000','100000','99999','999999','55555','555555']; +// const QUOTE_BLACKLIST=['23333','233333','66666','666666','10086','10000','100000','99999','999999','55555','555555']; +const QUOTE_BLACKLIST=[]; window.LATEST_POST_ID=parseInt(localStorage['_LATEST_POST_ID'],10)||0; @@ -521,7 +522,8 @@ class FlowItemRow extends PureComponent { let quote_id=null; if(!this.props.is_quote) - for(let [mode,content] of parts) + for(let [mode,content] of parts) { + content = content.length > 0 ? content.substring(1) : content if(mode==='pid' && QUOTE_BLACKLIST.indexOf(content)===-1 && parseInt(content){ @@ -809,7 +812,7 @@ export class Flow extends PureComponent {  Loading... : - '© xmcp' + '© thuhole' } /> ); diff --git a/src/Message.js b/src/Message.js index da6b16d..a9d7501 100644 --- a/src/Message.js +++ b/src/Message.js @@ -1,5 +1,5 @@ import React, {Component, PureComponent} from 'react'; -import {PKUHELPER_ROOT, get_json, API_VERSION_PARAM} from './flows_api'; +import {THUHOLE_API_ROOT, get_json, API_VERSION_PARAM} from './flows_api'; import {Time} from './Common'; export class MessageViewer extends PureComponent { @@ -20,7 +20,7 @@ export class MessageViewer extends PureComponent { this.setState({ loading_status: 'loading', },()=>{ - fetch(PKUHELPER_ROOT+'api_xmcp/hole/system_msg?user_token='+encodeURIComponent(this.props.token)+API_VERSION_PARAM()) + fetch(THUHOLE_API_ROOT+'api_xmcp/hole/system_msg?user_token='+encodeURIComponent(this.props.token)+API_VERSION_PARAM()) .then(get_json) .then((json)=>{ if(json.error) diff --git a/src/Title.js b/src/Title.js index f9af391..9ec71da 100644 --- a/src/Title.js +++ b/src/Title.js @@ -1,5 +1,5 @@ import React, {Component, PureComponent} from 'react'; -import {AppSwitcher} from './infrastructure/widgets'; +// import {AppSwitcher} from './infrastructure/widgets'; import {InfoSidebar, PostForm} from './UserAction'; import {TokenCtx} from './UserAction'; @@ -94,7 +94,7 @@ class ControlBar extends PureComponent { /> { this.props.show_sidebar( - 'P大树洞', + 'T大树洞', ) }}> @@ -124,15 +124,15 @@ class ControlBar extends PureComponent { export function Title(props) { return (
- + {/* */}

props.show_sidebar( - 'P大树洞', + 'T大树洞', )}> - P大树洞 + T大树洞

diff --git a/src/UserAction.js b/src/UserAction.js index 7b311fa..9203c03 100644 --- a/src/UserAction.js +++ b/src/UserAction.js @@ -6,7 +6,7 @@ import {ConfigUI} from './Config'; import fixOrientation from 'fix-orientation'; import copy from 'copy-to-clipboard'; import {cache} from './cache'; -import {API_VERSION_PARAM, PKUHELPER_ROOT, API, get_json, token_param} from './flows_api'; +import {API_VERSION_PARAM, THUHOLE_API_ROOT, API, get_json, token_param} from './flows_api'; import './UserAction.css'; @@ -20,179 +20,179 @@ export const TokenCtx=React.createContext({ set_value: ()=>{}, }); -class LifeInfoBox extends Component { - constructor(props) { - super(props); - if(!window._life_info_cache) - window._life_info_cache={}; - this.CACHE_TIMEOUT_S=15; - this.state={ - today_info: this.cache_get('today_info'), - card_balance: this.cache_get('card_balance'), - net_balance: this.cache_get('net_balance'), - mail_count: this.cache_get('mail_count'), - }; - this.INTERNAL_NETWORK_FAILURE='_network_failure'; - this.API_NAME={ - today_info: 'hole/today_info', - card_balance: 'isop/card_balance', - net_balance: 'isop/net_balance', - mail_count: 'isop/mail_count', - }; - } - - cache_get(key) { - let cache_item=window._life_info_cache[key]; - if(!cache_item || (+new Date())-cache_item[0]>1000*this.CACHE_TIMEOUT_S) - return null; - else - return cache_item[1]; - } - cache_set(key,value) { - if(!window._life_info_cache[key] || window._life_info_cache[key][1]!==value) - window._life_info_cache[key]=[+new Date(),value]; - } - - load(state_key) { - this.setState({ - [state_key]: null, - },()=>{ - fetch( - PKUHELPER_ROOT+'api_xmcp/'+this.API_NAME[state_key] - +'?user_token='+encodeURIComponent(this.props.token) - +API_VERSION_PARAM() - ) - .then(get_json) - .then((json)=>{ - //console.log(json); - this.setState({ - [state_key]: json, - }); - }) - .catch((e)=>{ - this.setState({ - [state_key]: { - errMsg: '网络错误 '+e, - errCode: this.INTERNAL_NETWORK_FAILURE, - success: false, - } - }); - }) - }); - } - - componentDidMount() { - ['today_info','card_balance','net_balance','mail_count'].forEach((k)=>{ - if(!this.state[k]) - this.load(k); - }); - } - - reload_all() { - ['today_info','card_balance','net_balance','mail_count'].forEach((k)=>{ - this.load(k); - }); - } - - render_line(state_key,title,value_fn,action,url_fn,do_login) { - let s=this.state[state_key]; - if(!s) - return ( - - {title} - 加载中…… - - - ); - else if(!s.success) { - let type='加载失败'; - if(s.errCode===this.INTERNAL_NETWORK_FAILURE) - type='网络错误'; - else if(['E01','E02','E03'].indexOf(s.errCode)!==-1) - type='授权失效'; - - let details=JSON.stringify(s); - if(s.errMsg) - details=s.errMsg; - else if(s.error) - details=s.error; - - return ( - - {title} - -
alert(details)}>{type} - - - {type==='授权失效' ? - -  重新登录 - : - this.load(state_key)}> -  重试 - - } - - - ) - } - else { - this.cache_set(state_key,s); - - return ( - - {title} - {value_fn(s)} - - -  {action} - - - - ); - } - } - - render() { - return ( - { - this.props.set_token(t); - this.reload_all(); - }}>{(do_login)=>( -
- - - {this.render_line( - 'today_info', - '今日',(s)=>s.info, - '校历',(s)=>s.schedule_url, - do_login, - )} - {this.render_line( - 'card_balance', - '校园卡',(s)=>`余额¥${s.balance.toFixed(2)}`, - '充值',()=>'https://virtualprod.alipay.com/educate/educatePcRecharge.htm?schoolCode=PKU&schoolName=', - do_login, - )} - {this.render_line( - 'net_balance', - '网费',(s)=>`余额¥${s.balance.toFixed(2)}`, - '充值',()=>'https://its.pku.edu.cn/epay.jsp', - do_login, - )} - {this.render_line( - 'mail_count', - '邮件',(s)=>`未读 ${s.count} 封`, - '查看',()=>'https://mail.pku.edu.cn/', - do_login, - )} - -
-
- )}
- ) - } -} +// class LifeInfoBox extends Component { +// constructor(props) { +// super(props); +// if(!window._life_info_cache) +// window._life_info_cache={}; +// this.CACHE_TIMEOUT_S=15; +// this.state={ +// today_info: this.cache_get('today_info'), +// card_balance: this.cache_get('card_balance'), +// net_balance: this.cache_get('net_balance'), +// mail_count: this.cache_get('mail_count'), +// }; +// this.INTERNAL_NETWORK_FAILURE='_network_failure'; +// this.API_NAME={ +// today_info: 'hole/today_info', +// card_balance: 'isop/card_balance', +// net_balance: 'isop/net_balance', +// mail_count: 'isop/mail_count', +// }; +// } +// +// cache_get(key) { +// let cache_item=window._life_info_cache[key]; +// if(!cache_item || (+new Date())-cache_item[0]>1000*this.CACHE_TIMEOUT_S) +// return null; +// else +// return cache_item[1]; +// } +// cache_set(key,value) { +// if(!window._life_info_cache[key] || window._life_info_cache[key][1]!==value) +// window._life_info_cache[key]=[+new Date(),value]; +// } +// +// load(state_key) { +// this.setState({ +// [state_key]: null, +// },()=>{ +// fetch( +// PKUHELPER_ROOT+'api_xmcp/'+this.API_NAME[state_key] +// +'?user_token='+encodeURIComponent(this.props.token) +// +API_VERSION_PARAM() +// ) +// .then(get_json) +// .then((json)=>{ +// //console.log(json); +// this.setState({ +// [state_key]: json, +// }); +// }) +// .catch((e)=>{ +// this.setState({ +// [state_key]: { +// errMsg: '网络错误 '+e, +// errCode: this.INTERNAL_NETWORK_FAILURE, +// success: false, +// } +// }); +// }) +// }); +// } +// +// componentDidMount() { +// ['today_info','card_balance','net_balance','mail_count'].forEach((k)=>{ +// if(!this.state[k]) +// this.load(k); +// }); +// } +// +// reload_all() { +// ['today_info','card_balance','net_balance','mail_count'].forEach((k)=>{ +// this.load(k); +// }); +// } +// +// render_line(state_key,title,value_fn,action,url_fn,do_login) { +// let s=this.state[state_key]; +// if(!s) +// return ( +// +// {title} +// 加载中…… +// +// +// ); +// else if(!s.success) { +// let type='加载失败'; +// if(s.errCode===this.INTERNAL_NETWORK_FAILURE) +// type='网络错误'; +// else if(['E01','E02','E03'].indexOf(s.errCode)!==-1) +// type='授权失效'; +// +// let details=JSON.stringify(s); +// if(s.errMsg) +// details=s.errMsg; +// else if(s.error) +// details=s.error; +// +// return ( +// +// {title} +// +// alert(details)}>{type} +// +// +// {type==='授权失效' ? +// +//  重新登录 +// : +// this.load(state_key)}> +//  重试 +// +// } +// +// +// ) +// } +// else { +// this.cache_set(state_key,s); +// +// return ( +// +// {title} +// {value_fn(s)} +// +// +//  {action} +// +// +// +// ); +// } +// } +// +// render() { +// return ( +// { +// this.props.set_token(t); +// this.reload_all(); +// }}>{(do_login)=>( +//
+// +// +// {this.render_line( +// 'today_info', +// '今日',(s)=>s.info, +// '校历',(s)=>s.schedule_url, +// do_login, +// )} +// {this.render_line( +// 'card_balance', +// '校园卡',(s)=>`余额¥${s.balance.toFixed(2)}`, +// '充值',()=>'https://virtualprod.alipay.com/educate/educatePcRecharge.htm?schoolCode=PKU&schoolName=', +// do_login, +// )} +// {this.render_line( +// 'net_balance', +// '网费',(s)=>`余额¥${s.balance.toFixed(2)}`, +// '充值',()=>'https://its.pku.edu.cn/epay.jsp', +// do_login, +// )} +// {this.render_line( +// 'mail_count', +// '邮件',(s)=>`未读 ${s.count} 封`, +// '查看',()=>'https://mail.pku.edu.cn/', +// do_login, +// )} +// +//
+//
+// )}
+// ) +// } +// } export function InfoSidebar(props) { return ( @@ -207,23 +207,25 @@ export function InfoSidebar(props) {    - - - -    - + {/**/} + {/* */} + {/**/} + {/*  */} +

- PKUHelper 网页版树洞 by @xmcp, + T大树洞 网页版 by @thuhole, 基于  GPLv3 -  协议在 GitHub 开源 +  协议在 GitHub 开源

- PKUHelper 网页版的诞生离不开  + T大树洞 网页版的诞生离不开  + P大树洞 + 、 ReactIcoMoon @@ -280,7 +282,7 @@ class ResetUsertokenWidget extends Component { this.setState({ loading_status: 'loading', },()=>{ - fetch(PKUHELPER_ROOT+'api_xmcp/hole/reset_usertoken', { + fetch(THUHOLE_API_ROOT+'api_xmcp/hole/reset_usertoken', { method: 'post', headers: { 'Content-Type': 'application/json', @@ -329,9 +331,9 @@ export class LoginForm extends Component { return ( {(token)=>

- {!!token.value && - - } + {/*{!!token.value &&*/} + {/* */} + {/*}*/}
{token.value ?
@@ -354,7 +356,7 @@ export class LoginForm extends Component {

复制 User Token
- User Token 用于迁移登录状态,切勿告知他人,若怀疑被盗号请尽快 + User Token 用于迁移登录状态,切勿告知他人{/*,若怀疑被盗号请尽快 */}

: {(do_popup)=>( @@ -366,7 +368,7 @@ export class LoginForm extends Component {

- PKU Helper 面向北京大学学生,通过 ISOP(北京大学数据共享开放服务平台)验证您的身份并提供服务。 + T大树洞 面向清华大学学生,通过清华邮箱验证您的身份并提供服务。

)} diff --git a/src/flows_api.js b/src/flows_api.js index 4ed5384..f897d64 100644 --- a/src/flows_api.js +++ b/src/flows_api.js @@ -1,9 +1,9 @@ import {get_json, API_VERSION_PARAM} from './infrastructure/functions'; -import {PKUHELPER_ROOT} from './infrastructure/const'; +import {THUHOLE_API_ROOT} from './infrastructure/const'; import {API_BASE} from './Common'; import {cache} from './cache'; -export {PKUHELPER_ROOT, API_VERSION_PARAM}; +export {THUHOLE_API_ROOT, API_VERSION_PARAM}; export function token_param(token) { return API_VERSION_PARAM()+(token ? ('&user_token='+token) : ''); diff --git a/src/infrastructure b/src/infrastructure index 9901aa8..e24cf98 160000 --- a/src/infrastructure +++ b/src/infrastructure @@ -1 +1 @@ -Subproject commit 9901aa83dfa8ee01da9e9480cc9524b18e29c40c +Subproject commit e24cf980948f63cc1535a6d2eb69319c5b3b055e diff --git a/src/text_splitter.js b/src/text_splitter.js index 02f1b16..713bdb2 100644 --- a/src/text_splitter.js +++ b/src/text_splitter.js @@ -1,6 +1,9 @@ // regexp should match the WHOLE segmented part -export const PID_RE=/(^|[^\d\u20e3\ufe0e\ufe0f])([2-9]\d{4,5}|1\d{4,6})(?![\d\u20e3\ufe0e\ufe0f])/g; -export const URL_PID_RE=/((?:https?:\/\/)?pkuhelper\.pku\.edu\.cn\/hole\/?#(?:#|%23)([2-9]\d{4,5}|1\d{4,6}))(?!\d|\u20e3|\ufe0e|\ufe0f)/g; +// export const PID_RE=/(^|[^\d\u20e3\ufe0e\ufe0f])([2-9]\d{4,5}|1\d{4,6})(?![\d\u20e3\ufe0e\ufe0f])/g; +export const PID_RE=/(^|[^\d\u20e3\ufe0e\ufe0f])(#\d{1,7})(?![\d\u20e3\ufe0e\ufe0f])/g; +// TODO: fix this re +// export const URL_PID_RE=/((?:https?:\/\/)?thuhole\.tech\/?#(?:#|%23)([2-9]\d{4,5}|1\d{4,6}))(?!\d|\u20e3|\ufe0e|\ufe0f)/g; +export const URL_PID_RE=/((?:https?:\/\/)?thuhole\.tech\/?#(?:#|%23)(\d{1,7}))(?!\d|\u20e3|\ufe0e|\ufe0f)/g; export const NICKNAME_RE=/(^|[^A-Za-z])((?:(?:Angry|Baby|Crazy|Diligent|Excited|Fat|Greedy|Hungry|Interesting|Jolly|Kind|Little|Magic|Naïve|Old|Powerful|Quiet|Rich|Superman|THU|Undefined|Valuable|Wifeless|Xiangbuchulai|Young|Zombie)\s)?(?: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)|You Win(?: \d+)?|洞主)(?![A-Za-z])/gi; export const URL_RE=/(^|[^.@a-zA-Z0-9_])((?:https?:\/\/)?(?:(?:[\w-]+\.)+[a-zA-Z]{2,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d{1,5})?(?:\/[\w~!@#$%^&*()\-_=+[\]{};:,./?|]*)?)(?![a-zA-Z0-9])/gi;