1
0
mirror of https://github.com/byulmaru/quesdon synced 2024-11-30 15:58:01 +09:00

[WIP]クライアントの通信エラー処理

This commit is contained in:
rinsuki 2018-05-23 09:58:50 +09:00
parent b517c608b9
commit 74449ba242
6 changed files with 231 additions and 47 deletions

View File

@ -9,6 +9,7 @@ import { Loading } from "../loading";
interface State {
questions: APIQuestion[]
loading: boolean
loadFailed?: number
loadTimer?: number
}
@ -17,14 +18,24 @@ export class PageLatest extends React.Component<{},State> {
super(props)
this.state = {
questions: [],
loading: true
loading: true,
}
}
render() {
const {
loading,
loadFailed,
questions,
} = this.state
return <div>
<Title> - Quesdon</Title>
<h2> <Button color="white" onClick={this.load.bind(this)} disabled={this.state.loading}></Button></h2>
{this.state.loading ? <Loading/> : this.state.questions.map(question => <Question {...question} />)}
<h2> <Button color="white" onClick={this.load.bind(this)} disabled={loading}></Button></h2>
{ loading
? <Loading/>
: loadFailed
? <span>({loadFailed < 0 ? loadFailed : "HTTP-"+loadFailed})</span>
: questions.map(question => <Question {...question} />)
}
</div>
}
@ -44,12 +55,33 @@ export class PageLatest extends React.Component<{},State> {
}
}
load() {
async load() {
this.setState({loading: true})
apiFetch("/api/web/questions/latest")
.then(r => r.json())
.then(questions => {
this.setState({questions, loading: false})
const req = await apiFetch("/api/web/questions/latest").catch(err => {
this.setState({
loading: false,
loadFailed: -1
})
})
if (!req) return
if (!req.ok) {
this.setState({
loading: false,
loadFailed: req.status,
})
}
const questions = await req.json().catch(err => {
this.setState({
loading: false,
loadFailed: -2,
})
})
if (!questions) return
this.setState({
loading: false,
loadFailed: undefined,
questions,
})
}
}

View File

@ -4,8 +4,20 @@ import majorInstances from "../../major-instances"
import { apiFetch } from "../../api-fetch"
import { Title } from "../common/title";
export class PageLogin extends React.Component {
interface State {
loading: boolean
}
export class PageLogin extends React.Component<{}, State> {
constructor(props: {}) {
super(props)
this.state = {
loading: false,
}
}
render() {
const { loading } = this.state
return <div>
<Title></Title>
<h1></h1>
@ -17,9 +29,11 @@ export class PageLogin extends React.Component {
{majorInstances.map(instance => <option value={instance} />)}
</datalist>
</FormGroup>
<Button type="submit" color="primary"></Button>
<Button type="submit" color="primary" disabled={loading}>{ loading ? "読み込み中" : "ログイン" }</Button>
<span>&nbsp;&nbsp;</span>
<Button type="button" color="secondary" onClick={this.twitterLogin.bind(this)}>Twitterでログイン</Button>
<Button type="button" color="secondary" disabled={loading} onClick={this.twitterLogin.bind(this)}>
{ loading ? "読み込み中" : "Twitterでログイン" }
</Button>
</form>
</div>
}
@ -28,15 +42,38 @@ export class PageLogin extends React.Component {
const form = new FormData(e.target)
this.callApi(form)
}
callApi(form: FormData) {
apiFetch("/api/web/oauth/get_url", {
async callApi(form: FormData) {
this.setState({
loading: true
})
function errorMsg(code: number | string) {
return "ログインに失敗しました。入力内容をご確認の上、再度お試しください ("+code+")"
}
const req = await apiFetch("/api/web/oauth/get_url", {
method: "POST",
body: form,
})
.then(r =>r.json())
.then(r => {
location.href = r.url
}).catch(e => {
alert(errorMsg(-1))
this.setState({
loading: false
})
})
if (!req) return
if (!req.ok) {
alert(errorMsg("HTTP-"+req.status))
this.setState({
loading: false
})
return
}
const urlRes = await req.json().catch(e => {
alert(errorMsg(-2))
this.setState({
loading: false
})
})
if (!urlRes) return
location.href = urlRes.url
}
twitterLogin() {

View File

@ -39,16 +39,37 @@ export class PageMyFollowers extends React.Component<{}, State> {
this.readMore()
}
readMore() {
async readMore() {
function errorMsg(code: number | string) {
return "読み込みに失敗しました。再度お試しください ("+code+")"
}
this.setState({loading: true})
apiFetch("/api/web/accounts/followers" + (this.state.maxId ? "?max_id="+this.state.maxId : ""))
.then(r => r.json())
.then(r => {
const req = await apiFetch("/api/web/accounts/followers" + (this.state.maxId ? "?max_id="+this.state.maxId : ""))
.catch(e => {
alert(errorMsg(-1))
this.setState({
accounts: this.state.accounts.concat(r.accounts),
maxId: r.max_id,
loading: false,
})
})
if (!req) return
if (!req.ok) {
alert(errorMsg("HTTP-"+req.status))
this.setState({
loading: false,
})
return
}
const res = await req.json().catch(e => {
alert(errorMsg(-2))
this.setState({
loading: false,
})
})
if (!res) return
this.setState({
accounts: this.state.accounts.concat(res.accounts),
maxId: res.max_id,
loading: false,
})
}
}

View File

@ -10,6 +10,7 @@ import { Loading } from "../../loading";
interface State {
questions: APIQuestion[]
loading: boolean
loadFailed?: number
}
export class PageMyQuestions extends React.Component<{},State> {
constructor(props: {}) {
@ -20,21 +21,61 @@ export class PageMyQuestions extends React.Component<{},State> {
}
}
render() {
const {
loading,
loadFailed,
questions
} = this.state
return <div>
<Title> - </Title>
<h1></h1>
<Link to="/my"></Link>
<div className="mt-3">
{this.state.loading ? <Loading/> : this.state.questions.map(q => <Question {...q} hideAnswerUser key={q._id}/>)}
{loading
? <Loading/>
: loadFailed
? <span>({ loadFailed < 0 ? loadFailed : "HTTP-"+loadFailed })<a href="javascript://" onClick={this.load.bind(this)}></a></span>
: questions.map(q => <Question {...q} hideAnswerUser key={q._id}/>)
}
</div>
<Button href={this.getShareUrl()} color="secondary" target="_blank"><wbr />()</Button>
</div>
}
componentDidMount() {
apiFetch("/api/web/questions").then(r => r.json()).then(questions => {
this.setState({questions, loading: false})
this.load()
}
async load() {
this.setState({
loading: true,
loadFailed: undefined,
})
const req = await apiFetch("/api/web/questions").catch(e => {
this.setState({
loading: false,
loadFailed: -1,
})
return
})
if (!req) return
if (!req.ok) {
this.setState({
loading: false,
loadFailed: req.status,
})
return
}
const questions = await req.json().catch(e => {
this.setState({
loading: false,
loadFailed: -2
})
return
})
if (!questions) return
this.setState({questions, loading: false})
}
getShareUrl() {
const user = (window as any).USER as APIUser

View File

@ -90,45 +90,95 @@ export class PageMySettings extends React.Component<{},State> {
})
}
pushbulletDisconnect() {
apiFetch("/api/web/accounts/pushbullet/disconnect", {
async pushbulletDisconnect() {
function errorMsg(code: number | string) {
return "通信に失敗しました。再度お試しください ("+code+")"
}
const req = await apiFetch("/api/web/accounts/pushbullet/disconnect", {
method: "POST"
}).catch(e => {
alert(errorMsg(-1))
})
.then(r => r.json())
.then(r => {
alert("切断しました。")
location.reload()
})
if (!req) return
if (!req.ok) {
alert(errorMsg("HTTP-"+req.status))
return
}
const res = await req.json().catch(e => {
alert(errorMsg(-2))
})
if (!res) return
alert("切断しました。")
location.reload()
}
allDeleteQuestions() {
async allDeleteQuestions() {
function errorMsg(code: number | string) {
return "通信に失敗しました。再度お試しください ("+code+")"
}
if (!me) return
const rand = Math.floor(Math.random() * 9) + 1
if (prompt(`あなた(@${me.acctDisplay})あてに来た質問を「回答済みのものも含めて全て」削除します。
${rand}()`, "") != rand.toString()) return
apiFetch("/api/web/questions/all_delete", {
const req = await apiFetch("/api/web/questions/all_delete", {
method: "POST"
}).catch(e => {
alert(errorMsg(-1))
})
.then(r => r.json())
.then(r => {
alert("削除しました。")
location.reload()
})
if (!req) return
if (!req.ok) {
alert(errorMsg("HTTP-"+req.status))
return
}
const res = await req.json().catch(e => {
alert(errorMsg(-2))
return
})
if (!res) return
alert("削除しました。")
location.reload()
}
onSubmit(e: any) {
async onSubmit(e: any) {
function errorMsg(code: number | string) {
return "通信に失敗しました。再度お試しください ("+code+")"
}
this.setState({saving: true})
const form = new FormData(e.target)
apiFetch("/api/web/accounts/update", {
const req = await apiFetch("/api/web/accounts/update", {
method: "POST",
body: form
})
.then(r => r.json())
.then(r => {
alert("更新しました!")
location.reload()
}).catch(e => {
alert(errorMsg(-1))
this.setState({
saving: false
})
})
if (!req) return
if (!req.ok) {
alert(errorMsg("HTTP-"+req.status))
this.setState({
saving: false
})
return
}
const res = req.json().catch(e => {
alert(errorMsg(-2))
this.setState({
saving: false
})
})
if (!res) return
alert("更新しました!")
location.reload()
}
}

View File

@ -93,6 +93,9 @@ export class PageUserIndex extends React.Component<Props,State> {
.then(questions => this.setState({questions}))
}
async fetchUserInfo() {
}
questionSubmit(e: any) {
if (!this.state.user) return
this.setState({questionNow: true})