From 23f4ce2a9a0f4478538f63f8b6334445736a9d8d Mon Sep 17 00:00:00 2001 From: dalechyn Date: Wed, 17 Jul 2024 21:37:40 +0300 Subject: [PATCH] refactor: drop `RouteOptions` for composer action, add state --- playground/src/composerAction.tsx | 72 +++-------------- src/components/Button.tsx | 27 ------- src/frog-base.tsx | 14 +--- src/types/composerAction.ts | 39 ++------- src/types/routes.ts | 110 +++++--------------------- src/utils/getComposerActionContext.ts | 3 + 6 files changed, 44 insertions(+), 221 deletions(-) diff --git a/playground/src/composerAction.tsx b/playground/src/composerAction.tsx index 07515e22..1c5a7484 100644 --- a/playground/src/composerAction.tsx +++ b/playground/src/composerAction.tsx @@ -1,67 +1,19 @@ -import { Button, Frog } from 'frog' +import { Frog } from 'frog' import { vars } from './ui.js' export const app = new Frog({ ui: { vars }, title: 'Composer Action', -}) - .frame('/', (c) => - c.res({ - image: ( -
-
- Add Composer Action -
-
- ), - intents: [ - - Add Action - , - ], - }), - ) - .composerAction( - '/action', - async (c) => { - console.log( - `Composer Action to ${JSON.stringify(c.actionData.castId)} from ${ - c.actionData.fid - }`, - ) - if (Math.random() > 0.5) return c.error({ message: 'Action failed :(' }) - return c.res({ - url: 'https://somewhere.com/some-form', - }) - }, - { - name: 'Super Form', - icon: 'log', - description: 'This composer action will do something with the cast!', - }, +}).composerAction('/', async (c) => { + console.log( + `Composer Action call ${JSON.stringify(c.actionData, null, 2)} from ${ + c.actionData.fid + }`, ) + if (Math.random() > 0.5) return c.error({ message: 'Action failed :(' }) + return c.res({ + title: 'Some Composer Action', + url: 'https://somewhere.com/some-form', + }) +}) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index fd2c6d46..fcb4ca68 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -68,32 +68,6 @@ export function ButtonAddCastAction({ ] as unknown as HtmlEscapedString } -export type ButtonAddComposerActionProps = ButtonProps & { - /** Action path */ - action: string -} - -ButtonAddComposerAction.__type = 'button' -export function ButtonAddComposerAction({ - action, - children, - // @ts-ignore - private - index = 1, -}: ButtonAddComposerActionProps) { - return [ - , - , - , - ] as unknown as HtmlEscapedString -} - export type ButtonLinkProps = ButtonProps & { href: string } @@ -239,7 +213,6 @@ export function ButtonSignature({ export const Button = Object.assign(ButtonRoot, { AddCastAction: ButtonAddCastAction, - AddComposerAction: ButtonAddComposerAction, Link: ButtonLink, Mint: ButtonMint, Redirect: ButtonRedirect, diff --git a/src/frog-base.tsx b/src/frog-base.tsx index cd1f1105..0443e1f9 100644 --- a/src/frog-base.tsx +++ b/src/frog-base.tsx @@ -209,19 +209,7 @@ export type RouteOptions< c: Context, ) => Promise | CastActionOptions } - : method extends 'composerAction' - ? - | ComposerActionOptions - | { - /** - * Custom handler for Composer Action `GET` response. - * One can use that if something needs to be derived from the `Context`. - */ - handler: ( - c: Context, - ) => Promise | ComposerActionOptions - } - : {}) + : {}) /** * A Frog instance. diff --git a/src/types/composerAction.ts b/src/types/composerAction.ts index a144782a..098e801a 100644 --- a/src/types/composerAction.ts +++ b/src/types/composerAction.ts @@ -1,38 +1,10 @@ -import type { Octicon } from './octicon.js' import type { TypedResponse } from './response.js' -export type ComposerActionOptions = { - /** - * An action name up to 30 characters. - * - * @example `'My action.'` - */ - name: string - /** - * An icon ID. - * - * @see https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa - * @example `'log'` - */ - icon: Octicon - /** - * A short description up to 80 characters. - * - * @example `'My awesome action description.'` - */ - description?: string +export type ComposerActionResponse = { /** - * Optional external link to an "about" page. - * You should only include this if you can't fully describe your - * action using the `description` field. - * Must be http or https protocol. - * - * @example `'My awesome action description.'` + * Title of the action. */ - aboutUrl?: string -} - -export type ComposerActionResponse = { + title: string /** * URL of the form. * @@ -53,6 +25,11 @@ export type ComposerActionData = { network: number timestamp: number url: string + state: { + parent?: string | undefined + text: string + embeds: string[] + } } export type TrustedData = { diff --git a/src/types/routes.ts b/src/types/routes.ts index 8e663622..54da18c4 100644 --- a/src/types/routes.ts +++ b/src/types/routes.ts @@ -142,15 +142,8 @@ export type HandlerInterface< >( path: P, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -171,15 +164,8 @@ export type HandlerInterface< path: P, middleware: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -204,15 +190,8 @@ export type HandlerInterface< middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -240,15 +219,8 @@ export type HandlerInterface< middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -279,15 +251,8 @@ export type HandlerInterface< middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -321,15 +286,8 @@ export type HandlerInterface< middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -366,15 +324,8 @@ export type HandlerInterface< middleware_5: MiddlewareHandler, middleware_6: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -414,15 +365,8 @@ export type HandlerInterface< middleware_6: MiddlewareHandler, middleware_7: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -465,15 +409,8 @@ export type HandlerInterface< middleware_7: MiddlewareHandler, middleware_8: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, @@ -521,15 +458,8 @@ export type HandlerInterface< middleware_8: MiddlewareHandler, middleware_9: MiddlewareHandler, handler: H, - ...rest: M extends 'castAction' | 'composerAction' - ? [ - options: RouteOptions< - 'castAction' | 'composerAction', - E2, - MergedPath, - I - >, - ] + ...rest: M extends 'castAction' + ? [options: RouteOptions<'castAction', E2, MergedPath, I>] : [options?: RouteOptions] ): FrogBase< E, diff --git a/src/utils/getComposerActionContext.ts b/src/utils/getComposerActionContext.ts index b64b1535..c482f733 100644 --- a/src/utils/getComposerActionContext.ts +++ b/src/utils/getComposerActionContext.ts @@ -30,6 +30,8 @@ export function getComposerActionContext< if (!frameData) throw new Error('Frame data must be present for action handlers.') + if (!frameData.state) + throw new Error('State must be present for composer action handler.') return { context: { @@ -40,6 +42,7 @@ export function getComposerActionContext< network: frameData.network, messageHash: frameData.messageHash, timestamp: frameData.timestamp, + state: JSON.parse(decodeURIComponent(frameData.state)), url: frameData.url, }, env,