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