mirror of
https://github.com/byulmaru/quesdon
synced 2024-11-27 14:28:04 +09:00
[WIP]クライアントの通信エラー処理
This commit is contained in:
parent
b517c608b9
commit
74449ba242
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
@ -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> もしくは </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() {
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
@ -92,6 +92,9 @@ export class PageUserIndex extends React.Component<Props,State> {
|
||||
.then(r => r.json())
|
||||
.then(questions => this.setState({questions}))
|
||||
}
|
||||
|
||||
async fetchUserInfo() {
|
||||
}
|
||||
|
||||
questionSubmit(e: any) {
|
||||
if (!this.state.user) return
|
||||
|
Loading…
Reference in New Issue
Block a user