refactor: more friendly error toast

This commit is contained in:
sevichecc 2023-04-15 00:07:59 +08:00
parent bca2f2e23a
commit e4663cd121
Signed by untrusted user who does not match committer: SevicheCC
GPG key ID: C577000000000000
4 changed files with 28 additions and 25 deletions

View file

@ -1,6 +1,6 @@
import fetch from "node-fetch"; import fetch from "node-fetch";
import { OAuth, getPreferenceValues } from "@raycast/api"; import { OAuth, getPreferenceValues } from "@raycast/api";
import { Credentials, Preference, Status ,StatusResponse} from "./types"; import { Credentials, Preference, Status, StatusResponse } from "./types";
import { client } from "./oauth"; import { client } from "./oauth";
export const fetchToken = async (params: URLSearchParams, errorMessage: string): Promise<OAuth.TokenResponse> => { export const fetchToken = async (params: URLSearchParams, errorMessage: string): Promise<OAuth.TokenResponse> => {
@ -12,8 +12,7 @@ export const fetchToken = async (params: URLSearchParams, errorMessage: string):
}); });
if (!response.ok) { if (!response.ok) {
console.error(errorMessage, await response.text()); throw new Error(errorMessage);
throw new Error(response.statusText);
} }
return (await response.json()) as OAuth.TokenResponse; return (await response.json()) as OAuth.TokenResponse;
@ -35,9 +34,7 @@ export const createApp = async (): Promise<Credentials> => {
}), }),
}); });
if (!response.ok) { if (!response.ok) throw new Error("Failed to create Akkoma app");
throw new Error("Failed to create Akkoma app");
}
return (await response.json()) as Credentials; return (await response.json()) as Credentials;
}; };
@ -70,8 +67,9 @@ export const postNewStatus = async ({
}); });
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to pulish new status!"); throw new Error("Failed to pulish :(");
} }
return (await response.json()) as StatusResponse; return (await response.json()) as StatusResponse;
}; };

View file

@ -15,15 +15,11 @@ const StatusContent = ({ isMarkdown, draftStatus }: statusProps) => {
<Form.TextArea <Form.TextArea
id="status" id="status"
title="Content" title="Content"
placeholder="Write something down" placeholder={`Write something down ${isMarkdown ? "with Markdown" : ""}`}
enableMarkdown={isMarkdown} enableMarkdown={isMarkdown}
autoFocus={true} autoFocus={true}
value={statusContent} value={statusContent}
error={error ? "Content should not be empty!" : ""}
onChange={setStatusContent} onChange={setStatusContent}
onBlur={() => {
setError(!statusContent.trim());
}}
/> />
</> </>
); );

View file

@ -1,8 +1,9 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Form, ActionPanel, Action, showToast, popToRoot, LaunchProps, Toast } from "@raycast/api"; import { Form, ActionPanel, Action, showToast, popToRoot, LaunchProps, Toast } from "@raycast/api";
import { postNewStatus } from "./api"; import { postNewStatus } from "./api";
import { Status } from "./types"; import { Status, AkkomaError } from "./types";
import { authorize } from "./oauth"; import { authorize } from "./oauth";
import VisibilityDropdown from "./components/VisibilityDropdown"; import VisibilityDropdown from "./components/VisibilityDropdown";
import StatusContent from "./components/statusContent"; import StatusContent from "./components/statusContent";
@ -17,17 +18,19 @@ export default function Command(props: LaunchProps<{ draftValues: Partial<Status
const handleSubmit = async (values: Partial<Status>) => { const handleSubmit = async (values: Partial<Status>) => {
try { try {
if (!values.status) throw new Error("You might forget the content, right ? |・ω・)");
showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ");
await postNewStatus({ await postNewStatus({
...values, ...values,
content_type: isMarkdown ? "text/markdown" : "text/plain", content_type: isMarkdown ? "text/markdown" : "text/plain",
}); })
setCw(""); showToast(Toast.Style.Success, "Status has been published (≧∇≦)/ ! ");
showToast({ title: "Success", message: "Status has been posted!" });
popToRoot(); popToRoot();
} catch (error) { } catch (error) {
console.error(error); const requestErr = error as AkkomaError;
showToast({ title: "Error", message: "Something went wrong!", style: Toast.Style.Failure }); showToast(Toast.Style.Failure, "Error", requestErr.message);
} }
}; };
@ -40,7 +43,7 @@ export default function Command(props: LaunchProps<{ draftValues: Partial<Status
</ActionPanel> </ActionPanel>
} }
> >
<Form.TextField id="spoiler_text" title="CW" placeholder="content warning" value={cw} onChange={setCw} /> <Form.TextField id="spoiler_text" title="CW" placeholder={"content warning"} value={cw} onChange={setCw} />
<StatusContent isMarkdown={isMarkdown} draftStatus={draftValues?.status} /> <StatusContent isMarkdown={isMarkdown} draftStatus={draftValues?.status} />
<VisibilityDropdown /> <VisibilityDropdown />
<Form.Checkbox <Form.Checkbox

View file

@ -1,4 +1,10 @@
import type {Icon} from '@raycast/api' import type { Icon } from "@raycast/api";
export interface AkkomaError {
code: string;
message: string;
}
export interface Preference { export interface Preference {
instance: string; instance: string;
defaultVisibility: VisibilityScope; defaultVisibility: VisibilityScope;
@ -9,7 +15,7 @@ export type VisibilityScope = "public" | "unlisted" | "direct" | "private" | "lo
export interface VisibilityOption { export interface VisibilityOption {
title: string; title: string;
value: VisibilityScope; value: VisibilityScope;
icon: Icon icon: Icon;
} }
interface Application { interface Application {
@ -61,5 +67,5 @@ export interface StatusResponse {
id: string; id: string;
create_at: Date; create_at: Date;
content: string; content: string;
application: Application application: Application;
} }