diff --git a/src/client/components/pages/latest.tsx b/src/client/components/pages/latest.tsx
index c65eb9a..5a02a0d 100644
--- a/src/client/components/pages/latest.tsx
+++ b/src/client/components/pages/latest.tsx
@@ -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
最近の回答 - Quesdon
- 最近の回答
- {this.state.loading ? : this.state.questions.map(question => )}
+ 最近の回答
+ { loading
+ ?
+ : loadFailed
+ ? 読み込みに失敗しました。上の再読み込みボタンを押して再度お試しください。({loadFailed < 0 ? loadFailed : "HTTP-"+loadFailed})
+ : questions.map(question => )
+ }
}
@@ -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,
+ })
}
}
\ No newline at end of file
diff --git a/src/client/components/pages/login.tsx b/src/client/components/pages/login.tsx
index 86b1029..c7c7f9b 100644
--- a/src/client/components/pages/login.tsx
+++ b/src/client/components/pages/login.tsx
@@ -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
ログイン
ログイン
@@ -17,9 +29,11 @@ export class PageLogin extends React.Component {
{majorInstances.map(instance => )}
-
+
もしくは
-
+
}
@@ -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() {
diff --git a/src/client/components/pages/my/followers.tsx b/src/client/components/pages/my/followers.tsx
index b68ec98..a865ae5 100644
--- a/src/client/components/pages/my/followers.tsx
+++ b/src/client/components/pages/my/followers.tsx
@@ -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,
+ })
}
}
\ No newline at end of file
diff --git a/src/client/components/pages/my/questions.tsx b/src/client/components/pages/my/questions.tsx
index 1257c49..d7ba488 100644
--- a/src/client/components/pages/my/questions.tsx
+++ b/src/client/components/pages/my/questions.tsx
@@ -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
質問一覧 - マイページ
質問一覧
マイページへ
- {this.state.loading ?
: this.state.questions.map(q =>
)}
+ {loading
+ ?
+ : loadFailed
+ ? 読み込みに失敗しました({ loadFailed < 0 ? loadFailed : "HTTP-"+loadFailed })。再度読み込む
+ : questions.map(q => )
+ }
}
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
diff --git a/src/client/components/pages/my/settings.tsx b/src/client/components/pages/my/settings.tsx
index 37044d1..1fb494b 100644
--- a/src/client/components/pages/my/settings.tsx
+++ b/src/client/components/pages/my/settings.tsx
@@ -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()
}
}
\ No newline at end of file
diff --git a/src/client/components/pages/user/index.tsx b/src/client/components/pages/user/index.tsx
index 2000094..73cd5ca 100644
--- a/src/client/components/pages/user/index.tsx
+++ b/src/client/components/pages/user/index.tsx
@@ -92,6 +92,9 @@ export class PageUserIndex extends React.Component {
.then(r => r.json())
.then(questions => this.setState({questions}))
}
+
+ async fetchUserInfo() {
+ }
questionSubmit(e: any) {
if (!this.state.user) return