refactor: merge states

This commit is contained in:
sevichecc 2023-04-16 19:02:41 +08:00
parent 5be7228b38
commit ef3368abb1
Signed by untrusted user who does not match committer: SevicheCC
GPG key ID: C577000000000000
2 changed files with 61 additions and 45 deletions

View file

@ -1,4 +1,4 @@
import { LocalStorage, OAuth, getPreferenceValues } from "@raycast/api"; import { LocalStorage, OAuth, getPreferenceValues,Cache } from "@raycast/api";
import { Preference } from "./types"; import { Preference } from "./types";
import apiServer from "./api"; import apiServer from "./api";
@ -44,13 +44,12 @@ const refreshToken = async (
return tokenResponse; return tokenResponse;
}; };
export const authorize = async (): Promise<void> => { export const authorize = async (cache: Cache): Promise<void> => {
const { instance } = getPreferenceValues<Preference>(); const { instance } = getPreferenceValues<Preference>();
const tokenSet = await client.getTokens(); const tokenSet = await client.getTokens();
if (tokenSet?.accessToken) { if (tokenSet?.accessToken) {
if (tokenSet.refreshToken && tokenSet.isExpired()) { if (tokenSet.refreshToken && tokenSet.isExpired()) {
LocalStorage.clear();
const { client_id, client_secret } = await apiServer.createApp(); const { client_id, client_secret } = await apiServer.createApp();
await client.setTokens(await refreshToken(client_id, client_secret, tokenSet.refreshToken)); await client.setTokens(await refreshToken(client_id, client_secret, tokenSet.refreshToken));
} }
@ -67,7 +66,6 @@ export const authorize = async (): Promise<void> => {
const { authorizationCode } = await client.authorize(authRequest); const { authorizationCode } = await client.authorize(authRequest);
await client.setTokens(await requestAccessToken(client_id, client_secret, authRequest, authorizationCode)); await client.setTokens(await requestAccessToken(client_id, client_secret, authRequest, authorizationCode));
const { fqn, avatar_static } = await apiServer.fetchAccountInfo(); const { fqn } = await apiServer.fetchAccountInfo();
await LocalStorage.setItem("account-fqn", fqn); cache.set("account-fqn", fqn);
await LocalStorage.setItem("account-avator", avatar_static);
}; };

View file

@ -8,7 +8,6 @@ import {
Toast, Toast,
Cache, Cache,
Icon, Icon,
LocalStorage,
getPreferenceValues, getPreferenceValues,
LaunchProps, LaunchProps,
} from "@raycast/api"; } from "@raycast/api";
@ -30,33 +29,50 @@ interface StatusForm extends Status {
description?: string; description?: string;
} }
const init = async (cache: Cache, setFqn: (fqn: string) => void) => {
try {
await authorize(cache);
setFqn(cache.get("account-fqn") ?? "");
} catch (error) {
console.error("Error during authorization or fetching account-fqn:", error);
}
};
const labelText = (time: Date) => {
return new Intl.DateTimeFormat("default", {
hour: "numeric",
minute: "numeric",
day: "numeric",
month: "long",
weekday: "long",
dayPeriod: "narrow",
}).format(time);
};
export default function SimpleCommand(props: CommandProps) { export default function SimpleCommand(props: CommandProps) {
const { instance } = getPreferenceValues<Preference>(); const { instance } = getPreferenceValues<Preference>();
const { draftValues } = props; const { draftValues } = props;
const [cw, setCw] = useState<string>(draftValues?.spoiler_text || "");
const [isMarkdown, setIsMarkdown] = useState(true);
const [sensitive, setSensitive] = useState(false);
const [openActionText, setOpenActionText] = useState("Open the last published status");
const [fqn, setFqn] = useState("");
const cached = cache.get("latest_published_status"); const [state, setState] = useState({
const [statusInfo, setStatusInfo] = useState<StatusResponse>(cached ? JSON.parse(cached) : null); cw: draftValues?.spoiler_text || "",
isMarkdown: true,
sensitive: false,
openActionText: "Open the last published status",
fqn: "",
});
const cachedInfo = cache.get("latest_published_status");
const [statusInfo, setStatusInfo] = useState<StatusResponse>(cachedInfo ? JSON.parse(cachedInfo) : null);
const cwRef = useRef<Form.TextField>(null); const cwRef = useRef<Form.TextField>(null);
useEffect(() => { useEffect(() => {
const init = async () => { init(cache, (fqn) => setState((prevState) => ({ ...prevState, fqn })));
authorize();
const newFqn = await LocalStorage.getItem<string>("account-fqn");
newFqn ? setFqn(newFqn) : setFqn("");
};
init();
}, []); }, []);
const handleSubmit = async ({ spoiler_text, status, scheduled_at, visibility, files, description }: StatusForm) => { const handleSubmit = async ({ spoiler_text, status, scheduled_at, visibility, files, description }: StatusForm) => {
try { try {
if (!status && !files) throw new Error("You might forget the content, right ? |・ω・)"); if (!status && !files) throw new Error("You might forget the content, right ? |・ω・)");
showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ"); showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ");
const mediaIds = await Promise.all( const mediaIds = await Promise.all(
@ -71,9 +87,9 @@ export default function SimpleCommand(props: CommandProps) {
status, status,
scheduled_at, scheduled_at,
visibility, visibility,
content_type: isMarkdown ? "text/markdown" : "text/plain", content_type: state.isMarkdown ? "text/markdown" : "text/plain",
media_ids: mediaIds, media_ids: mediaIds,
sensitive, sensitive: state.sensitive,
}; };
const response = await apiServer.postNewStatus(newStatus); const response = await apiServer.postNewStatus(newStatus);
@ -85,9 +101,12 @@ export default function SimpleCommand(props: CommandProps) {
} }
setStatusInfo(response); setStatusInfo(response);
setOpenActionText("View the status in Browser"); setState((prevState) => ({
...prevState,
openActionText: "View the status in Browser",
cw: "",
}));
cache.set("latest_published_status", JSON.stringify(response)); cache.set("latest_published_status", JSON.stringify(response));
setCw("");
setTimeout(() => popToRoot, 2000); setTimeout(() => popToRoot, 2000);
} catch (error) { } catch (error) {
const requestErr = error as AkkomaError; const requestErr = error as AkkomaError;
@ -95,19 +114,11 @@ export default function SimpleCommand(props: CommandProps) {
} }
}; };
const labelText = (time: Date) => {
return new Intl.DateTimeFormat("default", {
hour: "numeric",
minute: "numeric",
day: "numeric",
month: "long",
weekday: "long",
dayPeriod: "narrow",
}).format(time);
};
const handleCw = (value: boolean) => { const handleCw = (value: boolean) => {
setSensitive(value); setState((prevState) => ({
...prevState,
sensitive: value,
}));
cwRef.current?.focus(); cwRef.current?.focus();
}; };
@ -117,27 +128,34 @@ export default function SimpleCommand(props: CommandProps) {
actions={ actions={
<ActionPanel> <ActionPanel>
<Action.SubmitForm onSubmit={handleSubmit} title={"Publish"} icon={Icon.Upload} /> <Action.SubmitForm onSubmit={handleSubmit} title={"Publish"} icon={Icon.Upload} />
{statusInfo && <Action.OpenInBrowser url={statusInfo.url} title={openActionText} />} {statusInfo && <Action.OpenInBrowser url={statusInfo.url} title={state.openActionText} />}
<Action.OpenInBrowser url={`https://${instance}/main/friends/`} title="Open Akkoma in Browser" /> <Action.OpenInBrowser url={`https://${instance}/main/friends/`} title="Open Akkoma in Browser" />
</ActionPanel> </ActionPanel>
} }
> >
<Form.Description title="Account" text={fqn} /> <Form.Description title="Account" text={state.fqn} />
{sensitive && ( {state.sensitive && (
<Form.TextField <Form.TextField
id="spoiler_text" id="spoiler_text"
title="CW" title="CW"
placeholder={"content warning"} placeholder={"content warning"}
value={cw} value={state.cw}
onChange={setCw} onChange={(value) => setState((prevState) => ({ ...prevState, cw: value }))}
ref={cwRef} ref={cwRef}
/> />
)} )}
<StatusContent isMarkdown={isMarkdown} draftStatus={draftValues?.status} /> <StatusContent isMarkdown={state.isMarkdown} draftStatus={draftValues?.status} />
{!props.children && <VisibilityDropdown />} {!props.children && <VisibilityDropdown />}
{props.children} {props.children}
<Form.Checkbox id="markdown" title="Markdown" label="" value={isMarkdown} onChange={setIsMarkdown} storeValue /> <Form.Checkbox
<Form.Checkbox id="sensitive" title="Sensitive" label="" value={sensitive} onChange={handleCw} storeValue /> id="markdown"
title="Markdown"
label=""
value={state.isMarkdown}
onChange={(value) => setState((prevState) => ({ ...prevState, isMarkdown: value }))}
storeValue
/>
<Form.Checkbox id="sensitive" title="Sensitive" label="" value={state.sensitive} onChange={handleCw} storeValue />
</Form> </Form>
); );
} }