mirror of
https://github.com/Sevichecc/raycast-akkoma-extension.git
synced 2025-04-30 14:49:29 +08:00
refactor: merge states
This commit is contained in:
parent
5be7228b38
commit
ef3368abb1
2 changed files with 61 additions and 45 deletions
10
src/oauth.ts
10
src/oauth.ts
|
@ -1,4 +1,4 @@
|
|||
import { LocalStorage, OAuth, getPreferenceValues } from "@raycast/api";
|
||||
import { LocalStorage, OAuth, getPreferenceValues,Cache } from "@raycast/api";
|
||||
import { Preference } from "./types";
|
||||
import apiServer from "./api";
|
||||
|
||||
|
@ -44,13 +44,12 @@ const refreshToken = async (
|
|||
return tokenResponse;
|
||||
};
|
||||
|
||||
export const authorize = async (): Promise<void> => {
|
||||
export const authorize = async (cache: Cache): Promise<void> => {
|
||||
const { instance } = getPreferenceValues<Preference>();
|
||||
const tokenSet = await client.getTokens();
|
||||
|
||||
if (tokenSet?.accessToken) {
|
||||
if (tokenSet.refreshToken && tokenSet.isExpired()) {
|
||||
LocalStorage.clear();
|
||||
const { client_id, client_secret } = await apiServer.createApp();
|
||||
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);
|
||||
await client.setTokens(await requestAccessToken(client_id, client_secret, authRequest, authorizationCode));
|
||||
|
||||
const { fqn, avatar_static } = await apiServer.fetchAccountInfo();
|
||||
await LocalStorage.setItem("account-fqn", fqn);
|
||||
await LocalStorage.setItem("account-avator", avatar_static);
|
||||
const { fqn } = await apiServer.fetchAccountInfo();
|
||||
cache.set("account-fqn", fqn);
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
Toast,
|
||||
Cache,
|
||||
Icon,
|
||||
LocalStorage,
|
||||
getPreferenceValues,
|
||||
LaunchProps,
|
||||
} from "@raycast/api";
|
||||
|
@ -30,68 +29,12 @@ interface StatusForm extends Status {
|
|||
description?: string;
|
||||
}
|
||||
|
||||
export default function SimpleCommand(props: CommandProps) {
|
||||
const { instance } = getPreferenceValues<Preference>();
|
||||
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 [statusInfo, setStatusInfo] = useState<StatusResponse>(cached ? JSON.parse(cached) : null);
|
||||
|
||||
const cwRef = useRef<Form.TextField>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
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 init = async (cache: Cache, setFqn: (fqn: string) => void) => {
|
||||
try {
|
||||
if (!status && !files) throw new Error("You might forget the content, right ? |・ω・)");
|
||||
|
||||
showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ");
|
||||
|
||||
const mediaIds = await Promise.all(
|
||||
files?.map(async (file) => {
|
||||
const { id } = await apiServer.uploadAttachment({ file, description });
|
||||
return id;
|
||||
})
|
||||
);
|
||||
|
||||
const newStatus: Partial<Status> = {
|
||||
spoiler_text,
|
||||
status,
|
||||
scheduled_at,
|
||||
visibility,
|
||||
content_type: isMarkdown ? "text/markdown" : "text/plain",
|
||||
media_ids: mediaIds,
|
||||
sensitive,
|
||||
};
|
||||
|
||||
const response = await apiServer.postNewStatus(newStatus);
|
||||
|
||||
if (scheduled_at) {
|
||||
showToast(Toast.Style.Success, "Scheduled", labelText(scheduled_at));
|
||||
} else {
|
||||
showToast(Toast.Style.Success, "Status has been published (≧∇≦)/ ! ");
|
||||
}
|
||||
|
||||
setStatusInfo(response);
|
||||
setOpenActionText("View the status in Browser");
|
||||
cache.set("latest_published_status", JSON.stringify(response));
|
||||
setCw("");
|
||||
setTimeout(() => popToRoot, 2000);
|
||||
await authorize(cache);
|
||||
setFqn(cache.get("account-fqn") ?? "");
|
||||
} catch (error) {
|
||||
const requestErr = error as AkkomaError;
|
||||
showToast(Toast.Style.Failure, "Error", requestErr.message);
|
||||
console.error("Error during authorization or fetching account-fqn:", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -106,8 +49,76 @@ export default function SimpleCommand(props: CommandProps) {
|
|||
}).format(time);
|
||||
};
|
||||
|
||||
export default function SimpleCommand(props: CommandProps) {
|
||||
const { instance } = getPreferenceValues<Preference>();
|
||||
const { draftValues } = props;
|
||||
|
||||
const [state, setState] = useState({
|
||||
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);
|
||||
|
||||
useEffect(() => {
|
||||
init(cache, (fqn) => setState((prevState) => ({ ...prevState, fqn })));
|
||||
}, []);
|
||||
|
||||
const handleSubmit = async ({ spoiler_text, status, scheduled_at, visibility, files, description }: StatusForm) => {
|
||||
try {
|
||||
if (!status && !files) throw new Error("You might forget the content, right ? |・ω・)");
|
||||
showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ");
|
||||
|
||||
const mediaIds = await Promise.all(
|
||||
files?.map(async (file) => {
|
||||
const { id } = await apiServer.uploadAttachment({ file, description });
|
||||
return id;
|
||||
})
|
||||
);
|
||||
|
||||
const newStatus: Partial<Status> = {
|
||||
spoiler_text,
|
||||
status,
|
||||
scheduled_at,
|
||||
visibility,
|
||||
content_type: state.isMarkdown ? "text/markdown" : "text/plain",
|
||||
media_ids: mediaIds,
|
||||
sensitive: state.sensitive,
|
||||
};
|
||||
|
||||
const response = await apiServer.postNewStatus(newStatus);
|
||||
|
||||
if (scheduled_at) {
|
||||
showToast(Toast.Style.Success, "Scheduled", labelText(scheduled_at));
|
||||
} else {
|
||||
showToast(Toast.Style.Success, "Status has been published (≧∇≦)/ ! ");
|
||||
}
|
||||
|
||||
setStatusInfo(response);
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
openActionText: "View the status in Browser",
|
||||
cw: "",
|
||||
}));
|
||||
cache.set("latest_published_status", JSON.stringify(response));
|
||||
setTimeout(() => popToRoot, 2000);
|
||||
} catch (error) {
|
||||
const requestErr = error as AkkomaError;
|
||||
showToast(Toast.Style.Failure, "Error", requestErr.message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCw = (value: boolean) => {
|
||||
setSensitive(value);
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
sensitive: value,
|
||||
}));
|
||||
cwRef.current?.focus();
|
||||
};
|
||||
|
||||
|
@ -117,27 +128,34 @@ export default function SimpleCommand(props: CommandProps) {
|
|||
actions={
|
||||
<ActionPanel>
|
||||
<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" />
|
||||
</ActionPanel>
|
||||
}
|
||||
>
|
||||
<Form.Description title="Account" text={fqn} />
|
||||
{sensitive && (
|
||||
<Form.Description title="Account" text={state.fqn} />
|
||||
{state.sensitive && (
|
||||
<Form.TextField
|
||||
id="spoiler_text"
|
||||
title="CW"
|
||||
placeholder={"content warning"}
|
||||
value={cw}
|
||||
onChange={setCw}
|
||||
value={state.cw}
|
||||
onChange={(value) => setState((prevState) => ({ ...prevState, cw: value }))}
|
||||
ref={cwRef}
|
||||
/>
|
||||
)}
|
||||
<StatusContent isMarkdown={isMarkdown} draftStatus={draftValues?.status} />
|
||||
<StatusContent isMarkdown={state.isMarkdown} draftStatus={draftValues?.status} />
|
||||
{!props.children && <VisibilityDropdown />}
|
||||
{props.children}
|
||||
<Form.Checkbox id="markdown" title="Markdown" label="" value={isMarkdown} onChange={setIsMarkdown} storeValue />
|
||||
<Form.Checkbox id="sensitive" title="Sensitive" label="" value={sensitive} onChange={handleCw} storeValue />
|
||||
<Form.Checkbox
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue