From c93750f4a430151f661ba539c1f22195aeacab31 Mon Sep 17 00:00:00 2001 From: sevichecc <91365763+Sevichecc@users.noreply.github.com> Date: Sat, 15 Apr 2023 03:38:56 +0800 Subject: [PATCH] feat: add fqn id and open in akkoma action --- src/api.ts | 31 ++++++++++++++++++++++--------- src/oauth.ts | 13 ++++++++----- src/simple-status.tsx | 41 +++++++++++++++++++++++++++++++---------- src/types.ts | 9 +++++++++ 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/src/api.ts b/src/api.ts index fd223b1..819b94e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,6 +1,6 @@ import fetch from "node-fetch"; import { OAuth, getPreferenceValues } from "@raycast/api"; -import { Credentials, Preference, Status, StatusResponse } from "./types"; +import { Credentials, Preference, Status, StatusResponse, Account } from "./types"; import { client } from "./oauth"; export const fetchToken = async (params: URLSearchParams, errorMessage: string): Promise => { @@ -11,13 +11,11 @@ export const fetchToken = async (params: URLSearchParams, errorMessage: string): body: params, }); - if (!response.ok) { - throw new Error(errorMessage); - } - + if (!response.ok) throw new Error(errorMessage); return (await response.json()) as OAuth.TokenResponse; }; + export const createApp = async (): Promise => { const { instance } = getPreferenceValues(); @@ -39,6 +37,7 @@ export const createApp = async (): Promise => { return (await response.json()) as Credentials; }; + export const postNewStatus = async ({ status, visibility, @@ -66,10 +65,24 @@ export const postNewStatus = async ({ }), }); - if (!response.ok) { - throw new Error("Failed to pulish :("); - } - + if (!response.ok) throw new Error("Failed to pulish :("); return (await response.json()) as StatusResponse; }; + + +export const fetchAccountInfo = async (): Promise => { + const { instance } = getPreferenceValues(); + const tokenSet = await client.getTokens(); + + const response = await fetch(`https://${instance}/api/v1/accounts/verify_credentials`, { + method: "GET", + headers: { + "Authorization": "Bearer " + tokenSet?.accessToken, + }, + }); + + if (!response.ok) throw new Error("Failed to fetch account's info :("); + + return (await response.json()) as Account; +}; diff --git a/src/oauth.ts b/src/oauth.ts index 40a6cd2..73f8b5c 100644 --- a/src/oauth.ts +++ b/src/oauth.ts @@ -1,6 +1,6 @@ -import { OAuth, getPreferenceValues } from "@raycast/api"; +import { LocalStorage, OAuth, getPreferenceValues } from "@raycast/api"; import { Preference } from "./types"; -import { fetchToken,createApp} from "./api"; +import { fetchToken, createApp, fetchAccountInfo } from "./api"; export const client = new OAuth.PKCEClient({ redirectMethod: OAuth.RedirectMethod.Web, @@ -16,7 +16,6 @@ const requestAccessToken = async ( authRequest: OAuth.AuthorizationRequest, authCode: string ): Promise => { - const params = new URLSearchParams(); params.append("client_id", clientId); params.append("client_secret", clientSecret); @@ -33,7 +32,6 @@ const refreshToken = async ( clientSecret: string, refreshToken: string ): Promise => { - const params = new URLSearchParams(); params.append("client_id", clientId); params.append("client_secret", clientSecret); @@ -52,6 +50,7 @@ export const authorize = async (): Promise => { if (tokenSet?.accessToken) { if (tokenSet.refreshToken && tokenSet.isExpired()) { + LocalStorage.clear() const { client_id, client_secret } = await createApp(); await client.setTokens(await refreshToken(client_id, client_secret, tokenSet.refreshToken)); } @@ -64,7 +63,11 @@ export const authorize = async (): Promise => { clientId: client_id, scope: "read write", }); - + const { authorizationCode } = await client.authorize(authRequest); await client.setTokens(await requestAccessToken(client_id, client_secret, authRequest, authorizationCode)); + + const { fqn, avatar_static } = await fetchAccountInfo(); + await LocalStorage.setItem("account-fqn", fqn); + await LocalStorage.setItem("account-avator", avatar_static); }; diff --git a/src/simple-status.tsx b/src/simple-status.tsx index 93f6745..ba40b09 100644 --- a/src/simple-status.tsx +++ b/src/simple-status.tsx @@ -1,7 +1,19 @@ import { useEffect, useState } from "react"; -import { Form, ActionPanel, Action, showToast, popToRoot, LaunchProps, Toast, Cache ,Icon} from "@raycast/api"; +import { + Form, + ActionPanel, + Action, + showToast, + popToRoot, + LaunchProps, + Toast, + Cache, + Icon, + LocalStorage, + getPreferenceValues, +} from "@raycast/api"; import { postNewStatus } from "./api"; -import { Status, AkkomaError, StatusResponse } from "./types"; +import { Status, AkkomaError, StatusResponse, Preference } from "./types"; import { authorize } from "./oauth"; import VisibilityDropdown from "./components/VisibilityDropdown"; @@ -10,20 +22,27 @@ import StatusContent from "./components/statusContent"; const cache = new Cache(); export default function Command(props: LaunchProps<{ draftValues: Partial }>) { + const { instance } = getPreferenceValues(); const { draftValues } = props; const [cw, setCw] = useState(draftValues?.spoiler_text || ""); - const [isMarkdown, setIsMarkdown] = useState(true); + const [isMarkdown, setIsMarkdown] = useState(true); + const [openActionText, setOpenActionText] = useState("Open the last published status"); + const [fqn, setFqn] = useState(""); const cached = cache.get("latest_published_status"); - const [statusInfo, setStatusInfo] = useState(cached ? JSON.parse(cached) : null); - const [openActionText, setOpenActionText] = useState("Open the last published status"); - + useEffect(() => { - authorize(); + const init = async () => { + authorize(); + const newFqn = await LocalStorage.getItem("account-fqn"); + if (newFqn) setFqn(newFqn); + }; + + init(); }, []); - const handleSubmit = async (values: Partial) => { + const handleSubmit = async (values: Pick) => { try { if (!values.status) throw new Error("You might forget the content, right ? |・ω・)"); showToast(Toast.Style.Animated, "Publishing to the Fediverse ... ᕕ( ᐛ )ᕗ"); @@ -51,11 +70,13 @@ export default function Command(props: LaunchProps<{ draftValues: Partial - - { statusInfo && } + + {statusInfo && } + } > + {fqn && } diff --git a/src/types.ts b/src/types.ts index d500c71..4dfdac3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -63,6 +63,8 @@ export interface Status { visibility: VisibilityScope; } + + export interface StatusResponse { id: string; create_at: Date; @@ -70,3 +72,10 @@ export interface StatusResponse { application: Application; url: string; } + +export interface Account { + acct: string; + display_name: string; + fqn: string; + avatar_static: string; +} \ No newline at end of file