支持自定义头衔
This commit is contained in:
@@ -296,6 +296,11 @@
|
|||||||
padding: .1em .5em;
|
padding: .1em .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box-header-name.author-title {
|
||||||
|
color: white;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
.root-dark-mode .box-header-cw {
|
.root-dark-mode .box-header-cw {
|
||||||
background-color: #00a;
|
background-color: #00a;
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/Flows.js
11
src/Flows.js
@@ -129,6 +129,9 @@ class Reply extends PureComponent {
|
|||||||
{(
|
{(
|
||||||
<span className="box-header-name">{info.name}</span>
|
<span className="box-header-name">{info.name}</span>
|
||||||
)}
|
)}
|
||||||
|
{info.author_title && (
|
||||||
|
<span className="box-header-name author-title">{`"${info.author_title}"`}</span>
|
||||||
|
)}
|
||||||
{!!do_delete && !!info.can_del && (
|
{!!do_delete && !!info.can_del && (
|
||||||
<span
|
<span
|
||||||
className="clickable"
|
className="clickable"
|
||||||
@@ -282,6 +285,10 @@ class FlowItem extends PureComponent {
|
|||||||
#{info.pid}
|
#{info.pid}
|
||||||
</a>
|
</a>
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
{info.author_title && (
|
||||||
|
<span className="box-header-name author-title">{`"${info.author_title}"`}</span>
|
||||||
|
)}
|
||||||
{!!do_delete && !!info.can_del && (
|
{!!do_delete && !!info.can_del && (
|
||||||
<span
|
<span
|
||||||
className="clickable"
|
className="clickable"
|
||||||
@@ -1098,6 +1105,9 @@ class FlowItemRow extends PureComponent {
|
|||||||
)}
|
)}
|
||||||
<code className="box-id">#{this.props.info.pid}</code>
|
<code className="box-id">#{this.props.info.pid}</code>
|
||||||
|
|
||||||
|
{this.props.info.author_title && (
|
||||||
|
<span className="box-header-name author-title">{`"${this.props.info.author_title}"`}</span>
|
||||||
|
)}
|
||||||
{this.props.info.cw !== null && (
|
{this.props.info.cw !== null && (
|
||||||
<span className="box-header-cw">{this.props.info.cw}</span>
|
<span className="box-header-cw">{this.props.info.cw}</span>
|
||||||
)}
|
)}
|
||||||
@@ -1360,6 +1370,7 @@ class SubFlow extends PureComponent {
|
|||||||
});
|
});
|
||||||
localStorage['_LATEST_POST_ID'] = '' + max_id;
|
localStorage['_LATEST_POST_ID'] = '' + max_id;
|
||||||
}
|
}
|
||||||
|
window.TITLE = json.custom_title;
|
||||||
json.data.forEach((x) => {
|
json.data.forEach((x) => {
|
||||||
if (x.comments) {
|
if (x.comments) {
|
||||||
let comment_json = {
|
let comment_json = {
|
||||||
|
|||||||
@@ -129,3 +129,17 @@
|
|||||||
.post-form-poll-options h6 {
|
.post-form-poll-options h6 {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-form-opt-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 0 0 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-form-opt-box > label {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-form-buttons {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|||||||
@@ -136,6 +136,27 @@ export function InfoSidebar(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class LoginForm extends Component {
|
export class LoginForm extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
'custom_title': window.TITLE || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_title(title, token) {
|
||||||
|
if (title === window.TITLE) {
|
||||||
|
alert('无变化');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
API.set_title(title, token)
|
||||||
|
.then((json) => {
|
||||||
|
if (json.code === 0) {
|
||||||
|
window.TITLE = title
|
||||||
|
alert('自定义头衔设置成功');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
copy_token(token) {
|
copy_token(token) {
|
||||||
if (copy(token)) alert('复制成功!\n请一定不要泄露哦');
|
if (copy(token)) alert('复制成功!\n请一定不要泄露哦');
|
||||||
}
|
}
|
||||||
@@ -175,7 +196,7 @@ export class LoginForm extends Component {
|
|||||||
查看系统日志
|
查看系统日志
|
||||||
</a>
|
</a>
|
||||||
<br />
|
<br />
|
||||||
举报记录、管理日志等都是公开的
|
举报记录、管理日志等都是公开的。
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a onClick={this.copy_token.bind(this, token.value)}>
|
<a onClick={this.copy_token.bind(this, token.value)}>
|
||||||
@@ -184,6 +205,22 @@ export class LoginForm extends Component {
|
|||||||
<br />
|
<br />
|
||||||
User Token仅用于开发bot,切勿告知他人。若怀疑被盗号请刷新Token(刷新功能即将上线)。
|
User Token仅用于开发bot,切勿告知他人。若怀疑被盗号请刷新Token(刷新功能即将上线)。
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
自定义头衔:
|
||||||
|
<input
|
||||||
|
value={this.state.custom_title}
|
||||||
|
onChange={(e) => {
|
||||||
|
this.setState({ custom_title: e.target.value})
|
||||||
|
}}
|
||||||
|
maxLength={10}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {this.update_title(this.state.custom_title, token.value)}}
|
||||||
|
>提交</button>
|
||||||
|
<br />
|
||||||
|
设置自定义头衔后,可在发言时选择使用。重置后需重新设置。临时用户如需保持头衔请使用相同后缀。
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<LoginPopup token_callback={token.set_value}>
|
<LoginPopup token_callback={token.set_value}>
|
||||||
@@ -220,8 +257,10 @@ export class ReplyForm extends Component {
|
|||||||
text: '',
|
text: '',
|
||||||
loading_status: 'done',
|
loading_status: 'done',
|
||||||
preview: false,
|
preview: false,
|
||||||
|
use_title: false,
|
||||||
};
|
};
|
||||||
this.on_change_bound = this.on_change.bind(this);
|
this.on_change_bound = this.on_change.bind(this);
|
||||||
|
this.on_use_title_change_bound = this.on_use_title_change.bind(this);
|
||||||
this.area_ref = this.props.area_ref || React.createRef();
|
this.area_ref = this.props.area_ref || React.createRef();
|
||||||
this.global_keypress_handler_bound = this.global_keypress_handler.bind(
|
this.global_keypress_handler_bound = this.global_keypress_handler.bind(
|
||||||
this,
|
this,
|
||||||
@@ -258,6 +297,12 @@ export class ReplyForm extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on_use_title_change(event) {
|
||||||
|
this.setState({
|
||||||
|
use_title: event.target.checked,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
on_submit(event) {
|
on_submit(event) {
|
||||||
if (event) event.preventDefault();
|
if (event) event.preventDefault();
|
||||||
if (this.state.loading_status === 'loading') return;
|
if (this.state.loading_status === 'loading') return;
|
||||||
@@ -266,10 +311,13 @@ export class ReplyForm extends Component {
|
|||||||
loading_status: 'loading',
|
loading_status: 'loading',
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = new URLSearchParams();
|
const { pid } = this.props;
|
||||||
let pid = this.props.pid;
|
const { text, use_title } = this.state;
|
||||||
data.append('pid', pid);
|
let data = new URLSearchParams({
|
||||||
data.append('text', this.state.text);
|
pid: pid,
|
||||||
|
text: text,
|
||||||
|
use_title: use_title ? '1' : '',
|
||||||
|
});
|
||||||
fetch(
|
fetch(
|
||||||
API_BASE + '/docomment',
|
API_BASE + '/docomment',
|
||||||
{
|
{
|
||||||
@@ -339,6 +387,8 @@ export class ReplyForm extends Component {
|
|||||||
on_submit={this.on_submit.bind(this)}
|
on_submit={this.on_submit.bind(this)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<div className="reply-form-opt-box">
|
||||||
|
<div className="reply-form-buttons">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -360,6 +410,18 @@ export class ReplyForm extends Component {
|
|||||||
<span className="icon icon-send" />
|
<span className="icon icon-send" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
{window.TITLE && (
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
onChange={this.on_use_title_change_bound}
|
||||||
|
checked={this.state.use_title}
|
||||||
|
/>
|
||||||
|
{' '}使用头衔
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -377,11 +439,13 @@ export class PostForm extends Component {
|
|||||||
preview: false,
|
preview: false,
|
||||||
has_poll: !!window.POLL_BACKUP,
|
has_poll: !!window.POLL_BACKUP,
|
||||||
poll_options: JSON.parse(window.POLL_BACKUP || '[""]'),
|
poll_options: JSON.parse(window.POLL_BACKUP || '[""]'),
|
||||||
|
use_title: false,
|
||||||
};
|
};
|
||||||
this.img_ref = React.createRef();
|
this.img_ref = React.createRef();
|
||||||
this.area_ref = React.createRef();
|
this.area_ref = React.createRef();
|
||||||
this.on_change_bound = this.on_change.bind(this);
|
this.on_change_bound = this.on_change.bind(this);
|
||||||
this.on_allow_search_change_bound = this.on_allow_search_change.bind(this);
|
this.on_allow_search_change_bound = this.on_allow_search_change.bind(this);
|
||||||
|
this.on_use_title_change_bound = this.on_use_title_change.bind(this);
|
||||||
this.on_cw_change_bound = this.on_cw_change.bind(this);
|
this.on_cw_change_bound = this.on_cw_change.bind(this);
|
||||||
this.on_poll_option_change_bound = this.on_poll_option_change.bind(this);
|
this.on_poll_option_change_bound = this.on_poll_option_change.bind(this);
|
||||||
this.on_img_change_bound = this.on_img_change.bind(this);
|
this.on_img_change_bound = this.on_img_change.bind(this);
|
||||||
@@ -406,6 +470,12 @@ export class PostForm extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on_use_title_change(event) {
|
||||||
|
this.setState({
|
||||||
|
use_title: event.target.checked,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
on_cw_change(event) {
|
on_cw_change(event) {
|
||||||
this.setState({
|
this.setState({
|
||||||
cw: event.target.value,
|
cw: event.target.value,
|
||||||
@@ -419,14 +489,14 @@ export class PostForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_post() {
|
do_post() {
|
||||||
let data = new URLSearchParams();
|
const { cw, text, allow_search, use_title, has_poll, poll_options } = this.state;
|
||||||
const { cw, text, allow_search, has_poll, poll_options } = this.state;
|
let data = new URLSearchParams({
|
||||||
data.append('cw', this.state.cw);
|
cw: cw,
|
||||||
data.append('text', this.state.text);
|
text: text,
|
||||||
data.append('allow_search', this.state.allow_search ? '1' : '');
|
allow_search: allow_search ? '1' : '',
|
||||||
//data.append('type', img ? 'image' : 'text');
|
use_title: use_title ? '1' : '',
|
||||||
//if (img) data.append('data', img);
|
type: 'text'
|
||||||
data.append('type', 'text')
|
});
|
||||||
if (has_poll) {
|
if (has_poll) {
|
||||||
poll_options.forEach((opt) => {
|
poll_options.forEach((opt) => {
|
||||||
if (opt)
|
if (opt)
|
||||||
@@ -676,8 +746,18 @@ export class PostForm extends Component {
|
|||||||
onChange={this.on_allow_search_change_bound}
|
onChange={this.on_allow_search_change_bound}
|
||||||
checked={this.state.allow_search}
|
checked={this.state.allow_search}
|
||||||
/>
|
/>
|
||||||
允许被搜索
|
{' '}允许搜索
|
||||||
</label>
|
</label>
|
||||||
|
{window.TITLE && (
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
onChange={this.on_use_title_change_bound}
|
||||||
|
checked={this.state.use_title}
|
||||||
|
/>
|
||||||
|
{' '}使用头衔
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{!!this.state.img_tip && (
|
{!!this.state.img_tip && (
|
||||||
|
|||||||
@@ -251,4 +251,22 @@ export const API = {
|
|||||||
);
|
);
|
||||||
return handle_response(response, true);
|
return handle_response(response, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return handle_response(response, true);
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user