Browse Source

add post form

dev
xmcp 7 years ago
parent
commit
94251b394b
  1. 2
      public/index.html
  2. 18
      public/static/fonts_1/icomoon.svg
  3. BIN
      public/static/fonts_1/icomoon.ttf
  4. BIN
      public/static/fonts_1/icomoon.woff
  5. 24
      public/static/fonts_2/icomoon.css
  6. 21
      public/static/fonts_2/icomoon.svg
  7. BIN
      public/static/fonts_2/icomoon.ttf
  8. BIN
      public/static/fonts_2/icomoon.woff
  9. 19
      src/Flows.js
  10. 1
      src/Sidebar.js
  11. 41
      src/Title.js
  12. 26
      src/UserAction.css
  13. 204
      src/UserAction.js

2
public/index.html

@ -6,7 +6,7 @@
<link rel="icon" href="%PUBLIC_URL%/static/favicon/256.png">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="%PUBLIC_URL%/static/fonts_1/icomoon.css" />
<link rel="stylesheet" href="%PUBLIC_URL%/static/fonts_2/icomoon.css" />
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon/256.png">

18
public/static/fonts_1/icomoon.svg

@ -1,18 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe96b;" glyph-name="reply" d="M512 896c282.77 0 512-186.25 512-416 0-229.752-229.23-416-512-416-27.156 0-53.81 1.734-79.824 5.044-109.978-109.978-241.25-129.7-368.176-132.596v26.916c68.536 33.578 128 94.74 128 164.636 0 9.754-0.758 19.33-2.164 28.696-115.796 76.264-189.836 192.754-189.836 323.304 0 229.75 229.23 416 512 416z" />
<glyph unicode="&#xe975;" glyph-name="login-ok" d="M960 352l-288-288-96 96-64-64 160-160 352 352zM448 192h320v115.128c-67.22 39.2-156.308 66.11-256 74.26v52.78c70.498 39.728 128 138.772 128 237.832 0 159.058 0 288-192 288s-192-128.942-192-288c0-99.060 57.502-198.104 128-237.832v-52.78c-217.102-17.748-384-124.42-384-253.388h448v64z" />
<glyph unicode="&#xe98d;" glyph-name="login" d="M704 960c-176.73 0-320-143.268-320-320 0-20.026 1.858-39.616 5.376-58.624l-389.376-389.376v-192c0-35.346 28.654-64 64-64h64v64h128v128h128v128h128l83.042 83.042c34.010-12.316 70.696-19.042 108.958-19.042 176.73 0 320 143.268 320 320s-143.27 320-320 320zM799.874 639.874c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96z" />
<glyph unicode="&#xe9d3;" glyph-name="attention" d="M256 832v-896l320 320 320-320v896zM768 960h-640v-896l64 64v768h576z" />
<glyph unicode="&#xe9d7;" glyph-name="star" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
<glyph unicode="&#xe9d9;" glyph-name="star-ok" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538z" />
<glyph unicode="&#xea09;" glyph-name="help" d="M448 256h128v-128h-128zM704 704c35.346 0 64-28.654 64-64v-192l-192-128h-128v64l192 128v64h-320v128h384zM512 864c-111.118 0-215.584-43.272-294.156-121.844s-121.844-183.038-121.844-294.156c0-111.118 43.272-215.584 121.844-294.156s183.038-121.844 294.156-121.844c111.118 0 215.584 43.272 294.156 121.844s121.844 183.038 121.844 294.156c0 111.118-43.272 215.584-121.844 294.156s-183.038 121.844-294.156 121.844zM512 960v0c282.77 0 512-229.23 512-512s-229.23-512-512-512c-282.77 0-512 229.23-512 512s229.23 512 512 512z" />
<glyph unicode="&#xea2e;" glyph-name="refresh" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

BIN
public/static/fonts_1/icomoon.ttf

Binary file not shown.

BIN
public/static/fonts_1/icomoon.woff

Binary file not shown.

24
public/static/fonts_1/icomoon.css → public/static/fonts_2/icomoon.css

@ -1,9 +1,9 @@
@font-face {
font-family: 'icomoon';
src:
url('icomoon.ttf?4yzqd4') format('truetype'),
url('icomoon.woff?4yzqd4') format('woff'),
url('icomoon.svg?4yzqd4#icomoon') format('svg');
url('icomoon.ttf?y01gys') format('truetype'),
url('icomoon.woff?y01gys') format('woff'),
url('icomoon.svg?y01gys#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
@ -17,17 +17,21 @@
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-send:before {
content: "\e900";
}
.icon-reply:before {
content: "\e96b";
}
.icon-login-ok:before {
content: "\e975";
.icon-loading:before {
content: "\e979";
}
.icon-login:before {
content: "\e98d";
@ -41,9 +45,15 @@
.icon-star-ok:before {
content: "\e9d9";
}
.icon-help:before {
content: "\ea09";
.icon-plus:before {
content: "\ea0a";
}
.icon-about:before {
content: "\ea0c";
}
.icon-refresh:before {
content: "\ea2e";
}
.icon-github:before {
content: "\eab0";
}

21
public/static/fonts_2/icomoon.svg

@ -0,0 +1,21 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="send" horiz-adv-x="1025" d="M1008 944.571c12-8.571 17.714-22.286 15.429-36.571l-146.286-877.714c-1.714-10.857-8.571-20-18.286-25.714-5.143-2.857-11.429-4.571-17.714-4.571-4.571 0-9.143 1.143-13.714 2.857l-258.857 105.714-138.286-168.571c-6.857-8.571-17.143-13.143-28-13.143-4 0-8.571 0.571-12.571 2.286-14.286 5.143-24 18.857-24 34.286v199.429l493.714 605.143-610.857-528.571-225.714 92.571c-13.143 5.143-21.714 17.143-22.857 31.429-0.571 13.714 6.286 26.857 18.286 33.714l950.857 548.571c5.714 3.429 12 5.143 18.286 5.143 7.429 0 14.857-2.286 20.571-6.286z" />
<glyph unicode="&#xe96b;" glyph-name="reply" d="M512 896c282.77 0 512-186.25 512-416 0-229.752-229.23-416-512-416-27.156 0-53.81 1.734-79.824 5.044-109.978-109.978-241.25-129.7-368.176-132.596v26.916c68.536 33.578 128 94.74 128 164.636 0 9.754-0.758 19.33-2.164 28.696-115.796 76.264-189.836 192.754-189.836 323.304 0 229.75 229.23 416 512 416z" />
<glyph unicode="&#xe979;" glyph-name="loading" d="M728.992 448c137.754 87.334 231.008 255.208 231.008 448 0 21.676-1.192 43.034-3.478 64h-889.042c-2.29-20.968-3.48-42.326-3.48-64 0-192.792 93.254-360.666 231.006-448-137.752-87.334-231.006-255.208-231.006-448 0-21.676 1.19-43.034 3.478-64h889.042c2.288 20.966 3.478 42.324 3.478 64 0.002 192.792-93.252 360.666-231.006 448zM160 0c0 186.912 80.162 345.414 224 397.708v100.586c-143.838 52.29-224 210.792-224 397.706v0h704c0-186.914-80.162-345.416-224-397.706v-100.586c143.838-52.294 224-210.796 224-397.708h-704zM619.626 290.406c-71.654 40.644-75.608 93.368-75.626 125.366v64.228c0 31.994 3.804 84.914 75.744 125.664 38.504 22.364 71.808 56.348 97.048 98.336h-409.582c25.266-42.032 58.612-76.042 97.166-98.406 71.654-40.644 75.606-93.366 75.626-125.366v-64.228c0-31.992-3.804-84.914-75.744-125.664-72.622-42.18-126.738-125.684-143.090-226.336h501.67c-16.364 100.708-70.53 184.248-143.212 226.406z" />
<glyph unicode="&#xe98d;" glyph-name="login" d="M704 960c-176.73 0-320-143.268-320-320 0-20.026 1.858-39.616 5.376-58.624l-389.376-389.376v-192c0-35.346 28.654-64 64-64h64v64h128v128h128v128h128l83.042 83.042c34.010-12.316 70.696-19.042 108.958-19.042 176.73 0 320 143.268 320 320s-143.27 320-320 320zM799.874 639.874c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96z" />
<glyph unicode="&#xe9d3;" glyph-name="attention" d="M256 832v-896l320 320 320-320v896zM768 960h-640v-896l64 64v768h576z" />
<glyph unicode="&#xe9d7;" glyph-name="star" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
<glyph unicode="&#xe9d9;" glyph-name="star-ok" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538z" />
<glyph unicode="&#xea0a;" glyph-name="plus" d="M992 576h-352v352c0 17.672-14.328 32-32 32h-192c-17.672 0-32-14.328-32-32v-352h-352c-17.672 0-32-14.328-32-32v-192c0-17.672 14.328-32 32-32h352v-352c0-17.672 14.328-32 32-32h192c17.672 0 32 14.328 32 32v352h352c17.672 0 32 14.328 32 32v192c0 17.672-14.328 32-32 32z" />
<glyph unicode="&#xea0c;" glyph-name="about" d="M448 656c0 26.4 21.6 48 48 48h32c26.4 0 48-21.6 48-48v-32c0-26.4-21.6-48-48-48h-32c-26.4 0-48 21.6-48 48v32zM640 192h-256v64h64v192h-64v64h192v-256h64zM512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416z" />
<glyph unicode="&#xea2e;" glyph-name="refresh" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
<glyph unicode="&#xeab0;" glyph-name="github" d="M512.008 947.358c-282.738 0-512.008-229.218-512.008-511.998 0-226.214 146.704-418.132 350.136-485.836 25.586-4.738 34.992 11.11 34.992 24.632 0 12.204-0.48 52.542-0.696 95.324-142.448-30.976-172.504 60.41-172.504 60.41-23.282 59.176-56.848 74.916-56.848 74.916-46.452 31.778 3.51 31.124 3.51 31.124 51.4-3.61 78.476-52.766 78.476-52.766 45.672-78.27 119.776-55.64 149.004-42.558 4.588 33.086 17.852 55.68 32.506 68.464-113.73 12.942-233.276 56.85-233.276 253.032 0 55.898 20.004 101.574 52.76 137.428-5.316 12.9-22.854 64.972 4.952 135.5 0 0 43.006 13.752 140.84-52.49 40.836 11.348 84.636 17.036 128.154 17.234 43.502-0.198 87.336-5.886 128.256-17.234 97.734 66.244 140.656 52.49 140.656 52.49 27.872-70.528 10.35-122.6 5.036-135.5 32.82-35.856 52.694-81.532 52.694-137.428 0-196.654-119.778-239.95-233.79-252.624 18.364-15.89 34.724-47.046 34.724-94.812 0-68.508-0.596-123.644-0.596-140.508 0-13.628 9.222-29.594 35.172-24.566 203.322 67.776 349.842 259.626 349.842 485.768 0 282.78-229.234 511.998-511.992 511.998z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
public/static/fonts_2/icomoon.ttf

Binary file not shown.

BIN
public/static/fonts_2/icomoon.woff

Binary file not shown.

19
src/Flows.js

@ -131,8 +131,13 @@ class FlowItemRow extends PureComponent {
})
.then((res)=>res.json())
.then((json)=>{
if(json.code!==0 && (!json.msg || json.msg!=='已经关注过辣'))
throw new Error(json);
if(json.code!==0) {
if(json.msg && json.msg==='已经关注过辣') {}
else {
if(json.msg) alert(json.msg);
throw new Error(json);
}
}
this.setState({
attention: next_attention,
@ -164,8 +169,8 @@ class FlowItemRow extends PureComponent {
this.toggle_attention(this.show_sidebar.bind(this));
}}>
{this.state.attention ?
<span><span className="icon icon-star-ok" />已关注</span> :
<span><span className="icon icon-star" />未关注</span>
<span><span className="icon icon-star-ok" />&nbsp;已关注</span> :
<span><span className="icon icon-star" />&nbsp;未关注</span>
}
</a>
</span>
@ -382,7 +387,11 @@ export class Flow extends PureComponent {
<a onClick={()=>{this.load_page(this.state.loaded_pages+1)}}>重新加载</a>
</div>
}
<TitleLine text={this.state.loading_status==='loading' ? 'Loading...' : '© xmcp'} />
<TitleLine text={
this.state.loading_status==='loading' ?
<span><span className="icon icon-loading" />&nbsp;Loading...</span> :
'© xmcp'
} />
</div>
);
}

1
src/Sidebar.js

@ -10,7 +10,6 @@ export function Sidebar(props) {
<a onClick={props.do_close}>×</a>
&nbsp;{props.title}
</p>
<br />
{props.content}
</div>
</div>

41
src/Title.js

@ -1,5 +1,5 @@
import React, {Component, PureComponent} from 'react';
import {LoginForm} from './UserAction';
import {LoginForm, PostForm} from './UserAction';
import {TokenCtx} from './UserAction';
import './Title.css';
@ -112,15 +112,30 @@ class ControlBar extends PureComponent {
<input value={this.state.search_text} placeholder="搜索 或 #PID"
onChange={this.on_change_bound} onKeyPress={this.on_keypress_bound}
/>
<a className="control-btn" onClick={()=>{this.props.show_sidebar('登录',<LoginForm />)}}>
<span className={'icon icon-'+(token ? 'login-ok' : 'login')} />
</a>
<a className="control-btn" onClick={()=>{this.props.show_sidebar(
'关于 P大树洞(非官方) 网页版',
HELP_TEXT
)}}>
<span className="icon icon-help" />
<a className="control-btn" onClick={()=>{
this.props.show_sidebar(
'P大树洞(非官方)网页版',
<div>
<LoginForm />
{HELP_TEXT}
</div>
)
}}>
<span className={'icon icon-'+(token ? 'about' : 'login')} />
</a>
{!!token &&
<a className="control-btn" onClick={()=>{
this.props.show_sidebar(
'发表树洞',
<PostForm token={token} on_complete={()=>{
this.props.show_sidebar('',null);
this.do_refresh();
}} />
)
}}>
<span className="icon icon-plus" />
</a>
}
</div>
)}</TokenCtx.Consumer>
)
@ -131,7 +146,13 @@ export function Title(props) {
return (
<div className="title-bar">
<div className="aux-margin">
<p className="title centered-line">P大树洞</p>
<p className="title centered-line">
P大树洞
&nbsp;
<a href="https://github.com/xmcp/ashole" target="_blank">
<span className="icon icon-github" />
</a>
</p>
<ControlBar show_sidebar={props.show_sidebar} set_mode={props.set_mode} />
</div>
</div>

26
src/UserAction.css

@ -2,11 +2,9 @@
margin: 1em 0;
text-align: center;
}
.login-form button {
min-width: 100px;
}
.reply-form {
display: flex;
}
@ -17,5 +15,27 @@
height: 5em;
}
.reply-form button {
flex: 0 0 50px;
flex: 0 0 3em;
}
.post-form-bar {
line-height: 2em;
display: flex;
}
.post-form-bar label {
flex: 1;
}
@media screen and (max-width: 600px) {
.post-form-bar input[type=file] {
width: 150px;
}
}
.post-form-bar button {
flex: 0 0 8em;
}
.post-form textarea {
resize: vertical;
width: 100%;
min-height: 5em;
height: 20em;
}

204
src/UserAction.js

@ -5,6 +5,8 @@ import './UserAction.css';
import {API_BASE} from './Common';
const LOGIN_BASE=window.location.protocol==='https:' ? '/login_proxy' : 'http://www.pkuhelper.com/services/login';
const MAX_IMG_PX=1000;
const MAX_IMG_FILESIZE=100000;
export const TokenCtx=React.createContext({
value: null,
@ -42,8 +44,10 @@ export class LoginForm extends Component {
})
.then((res)=>res.json())
.then((json)=>{
if(json.code!==0)
if(json.code!==0) {
if(json.msg) alert(json.msg);
throw new Error(json);
}
set_token(json.token);
alert(`成功以 ${json.name} 的身份登录`);
@ -63,8 +67,8 @@ export class LoginForm extends Component {
render() {
return (
<TokenCtx.Consumer>{(token)=>
<div className="login-form">
<form onSubmit={(e)=>this.do_login(e,token.set_value)} className="box">
<div className="login-form box">
<form onSubmit={(e)=>this.do_login(e,token.set_value)}>
<p>{token.value ?
<span><b>您已登录</b>Token: <code>{token.value||'(null)'}</code></span> :
'登录后可以使用关注、回复等功能'
@ -83,19 +87,23 @@ export class LoginForm extends Component {
</p>
<p>
{this.state.loading_status==='loading' ?
<button disabled="disbled">正在登录</button> :
<button type="submit">登录</button>
<button disabled="disbled">
<span className="icon icon-loading" />
&nbsp;正在登录
</button> :
<button type="submit">
<span className="icon icon-login" />
&nbsp;登录
</button>
}
<button type="button" onClick={()=>{token.set_value(null);}}>退出</button>
</p>
</form>
<div className="box">
<ul>
<li>我们不会记录您的密码和个人信息</li>
<li><b>请勿泄露 Token</b></li>
<li>如果您不愿输入密码可以直接修改 <code>localStorage['TOKEN']</code></li>
</ul>
</div>
</form>
</div>
}</TokenCtx.Consumer>
)
@ -121,7 +129,6 @@ export class ReplyForm extends Component {
on_submit(event) {
event.preventDefault();
if(this.state.loading_status==='loading')
return;
this.setState({
@ -142,8 +149,10 @@ export class ReplyForm extends Component {
})
.then((res)=>res.json())
.then((json)=>{
if(json.code!==0)
if(json.code!==0) {
if(json.msg) alert(json.msg);
throw new Error(json);
}
this.setState({
loading_status: 'done',
@ -163,16 +172,175 @@ export class ReplyForm extends Component {
render() {
return (
<div className="box">
<form onSubmit={this.on_submit.bind(this)} className="reply-form">
<SafeTextarea ref={this.area_ref} id={this.props.pid} on_change={this.on_change_bound} />
{this.state.loading_status==='loading' ?
<button disabled="disabled">正在回复</button> :
<button type="submit">回复</button>
<form onSubmit={this.on_submit.bind(this)} className="reply-form box">
<SafeTextarea ref={this.area_ref} id={this.props.pid} on_change={this.on_change_bound} />
{this.state.loading_status==='loading' ?
<button disabled="disabled">
<span className="icon icon-loading" />
</button> :
<button type="submit">
<span className="icon icon-send" />
</button>
}
</form>
)
}
}
export class PostForm extends Component {
constructor(props) {
super(props);
this.state={
text: '',
loading_status: 'done',
};
this.img_ref=React.createRef();
this.area_ref=React.createRef();
this.on_change_bound=this.on_change.bind(this);
}
on_change(value) {
this.setState({
text: value,
});
}
do_post(text,img) {
let data=new URLSearchParams();
data.append('action','dopost');
data.append('text',this.state.text);
data.append('type',img ? 'image' : 'text');
data.append('token',this.props.token);
if(img)
data.append('data',img);
fetch(API_BASE+'/api.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: data,
})
.then((res)=>res.json())
.then((json)=>{
if(json.code!==0) {
if(json.msg) alert(json.msg);
throw new Error(json);
}
this.setState({
loading_status: 'done',
text: '',
});
this.area_ref.current.clear();
this.props.on_complete();
})
.catch((e)=>{
console.trace(e);
alert('发表失败');
this.setState({
loading_status: 'done',
});
});
}
proc_img(file) { // http://pkuhole.chenpong.com/
return new Promise((resolve,reject)=>{
function return_url(url) {
const idx=url.indexOf(';base64,');
if(idx===-1)
throw new Error('img not base64 encoded');
resolve(url.substr(idx+8));
}
let reader=new FileReader();
reader.onload=((event)=>{ // check size
const url=event.target.result;
const image = new Image();
image.src=url;
image.onload=(()=>{
let width=image.width;
let height=image.height;
if(width>MAX_IMG_PX) {
height=height*MAX_IMG_PX/width;
width=MAX_IMG_PX;
}
if(height>MAX_IMG_PX) {
width=width*MAX_IMG_PX/height;
height=MAX_IMG_PX;
}
</form>
</div>
let canvas=document.createElement('canvas');
let ctx=canvas.getContext('2d');
canvas.width=width;
canvas.height=height;
ctx.drawImage(image,0,0,width,height);
for(let quality=.9;quality>0;quality-=0.1) {
const url=canvas.toDataURL('image/jpeg',quality);
console.log('quality',quality,'size',url.length);
if(url.length<=MAX_IMG_FILESIZE) {
console.log('chosen img quality',quality);
return return_url(url);
}
}
// else
alert('图片过大,无法上传');
reject('img too large');
});
});
reader.readAsDataURL(file);
});
}
on_submit(event) {
event.preventDefault();
if(this.state.loading_status==='loading')
return;
if(this.img_ref.current.files.length) {
this.setState({
loading_status: 'processing',
});
this.proc_img(this.img_ref.current.files[0])
.then((img)=>{
this.setState({
loading_status: 'loading',
});
this.do_post(this.state.text,img);
})
} else {
this.setState({
loading_status: 'loading',
});
this.do_post(this.state.text,null);
}
}
render() {
return (
<form onSubmit={this.on_submit.bind(this)} className="post-form box">
<div className="post-form-bar">
<label>
图片
<input ref={this.img_ref} type="file" accept="image/*"
{...this.state.loading_status!=='done' ? {disabled: true} : {}} />
</label>
{this.state.loading_status!=='done' ?
<button disabled="disabled">
<span className="icon icon-loading" />
&nbsp;正在{this.state.loading_status==='processing' ? '处理' : '上传'}
</button> :
<button type="submit">
<span className="icon icon-send" />
&nbsp;发表
</button>
}
</div>
<br />
<SafeTextarea ref={this.area_ref} id="new_post" on_change={this.on_change_bound} />
</form>
)
}
}
Loading…
Cancel
Save