feat(ui): switch message actions to icon buttons
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, untrack } from "solid-js"
|
import { For, Match, Show, Switch, createEffect, createMemo, createSignal, untrack } from "solid-js"
|
||||||
import { FoldVertical } from "lucide-solid"
|
import { ExternalLink, FoldVertical, Trash2 } from "lucide-solid"
|
||||||
import MessageItem from "./message-item"
|
import MessageItem from "./message-item"
|
||||||
import ToolCall from "./tool-call"
|
import ToolCall from "./tool-call"
|
||||||
import type { InstanceMessageStore } from "../stores/message-v2/instance-store"
|
import type { InstanceMessageStore } from "../stores/message-v2/instance-store"
|
||||||
@@ -390,9 +390,10 @@ function ToolCallItem(props: ToolCallItemProps) {
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={!taskLocation()}
|
disabled={!taskLocation()}
|
||||||
onClick={handleGoToTaskSession}
|
onClick={handleGoToTaskSession}
|
||||||
title={!taskLocation() ? t("messageBlock.tool.goToSession.unavailableTitle") : t("messageBlock.tool.goToSession.title")}
|
title={t("messageBlock.tool.goToSession.label")}
|
||||||
|
aria-label={t("messageBlock.tool.goToSession.label")}
|
||||||
>
|
>
|
||||||
{t("messageBlock.tool.goToSession.label")}
|
<ExternalLink class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
@@ -401,9 +402,10 @@ function ToolCallItem(props: ToolCallItemProps) {
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={deleteDisabled()}
|
disabled={deleteDisabled()}
|
||||||
onClick={handleDeleteToolPart}
|
onClick={handleDeleteToolPart}
|
||||||
title={t("messageBlock.tool.deletePart.title")}
|
title={deleting() ? t("messageBlock.tool.deletePart.deleting") : t("messageBlock.tool.deletePart.label")}
|
||||||
|
aria-label={deleting() ? t("messageBlock.tool.deletePart.deleting") : t("messageBlock.tool.deletePart.label")}
|
||||||
>
|
>
|
||||||
{deleting() ? t("messageBlock.tool.deletePart.deleting") : t("messageBlock.tool.deletePart.label")}
|
<Trash2 class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { For, Show, createSignal } from "solid-js"
|
import { For, Show, createSignal } from "solid-js"
|
||||||
|
import { Copy, Split, Trash2, Undo } from "lucide-solid"
|
||||||
import type { MessageInfo, ClientPart } from "../types/message"
|
import type { MessageInfo, ClientPart } from "../types/message"
|
||||||
import { partHasRenderableText } from "../types/message"
|
import { partHasRenderableText } from "../types/message"
|
||||||
import type { MessageRecord } from "../stores/message-v2/types"
|
import type { MessageRecord } from "../stores/message-v2/types"
|
||||||
@@ -159,6 +160,8 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const copyLabel = () => (copied() ? t("messageItem.actions.copied") : t("messageItem.actions.copy"))
|
||||||
|
|
||||||
const getRawContent = () => {
|
const getRawContent = () => {
|
||||||
return props.parts
|
return props.parts
|
||||||
.filter(part => part.type === "text")
|
.filter(part => part.type === "text")
|
||||||
@@ -278,31 +281,29 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
<button
|
<button
|
||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={handleRevert}
|
onClick={handleRevert}
|
||||||
title={t("messageItem.actions.revertTitle")}
|
title={t("messageItem.actions.revert")}
|
||||||
aria-label={t("messageItem.actions.revertTitle")}
|
aria-label={t("messageItem.actions.revert")}
|
||||||
>
|
>
|
||||||
{t("messageItem.actions.revert")}
|
<Undo class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={props.onFork}>
|
<Show when={props.onFork}>
|
||||||
<button
|
<button
|
||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={() => props.onFork?.(props.record.id)}
|
onClick={() => props.onFork?.(props.record.id)}
|
||||||
title={t("messageItem.actions.forkTitle")}
|
title={t("messageItem.actions.fork")}
|
||||||
aria-label={t("messageItem.actions.forkTitle")}
|
aria-label={t("messageItem.actions.fork")}
|
||||||
>
|
>
|
||||||
{t("messageItem.actions.fork")}
|
<Split class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</Show>
|
</Show>
|
||||||
<button
|
<button
|
||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
title={t("messageItem.actions.copyTitle")}
|
title={copyLabel()}
|
||||||
aria-label={t("messageItem.actions.copyTitle")}
|
aria-label={copyLabel()}
|
||||||
>
|
>
|
||||||
<Show when={copied()} fallback={t("messageItem.actions.copy")}>
|
<Copy class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
{t("messageItem.actions.copied")}
|
|
||||||
</Show>
|
|
||||||
</button>
|
</button>
|
||||||
<Show when={deletableTextPartId()}>
|
<Show when={deletableTextPartId()}>
|
||||||
{(partId) => (
|
{(partId) => (
|
||||||
@@ -310,10 +311,10 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={() => void handleDeletePart(partId())}
|
onClick={() => void handleDeletePart(partId())}
|
||||||
disabled={isDeletingPart(partId())}
|
disabled={isDeletingPart(partId())}
|
||||||
title={t("messagePart.actions.deleteTitle")}
|
title={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
||||||
aria-label={t("messagePart.actions.deleteTitle")}
|
aria-label={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
||||||
>
|
>
|
||||||
{isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
<Trash2 class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</Show>
|
</Show>
|
||||||
@@ -324,12 +325,10 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
<button
|
<button
|
||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
title={t("messageItem.actions.copyTitle")}
|
title={copyLabel()}
|
||||||
aria-label={t("messageItem.actions.copyTitle")}
|
aria-label={copyLabel()}
|
||||||
>
|
>
|
||||||
<Show when={copied()} fallback={t("messageItem.actions.copy")}>
|
<Copy class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
{t("messageItem.actions.copied")}
|
|
||||||
</Show>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Show when={deletableTextPartId()}>
|
<Show when={deletableTextPartId()}>
|
||||||
@@ -338,10 +337,10 @@ export default function MessageItem(props: MessageItemProps) {
|
|||||||
class="message-action-button"
|
class="message-action-button"
|
||||||
onClick={() => void handleDeletePart(partId())}
|
onClick={() => void handleDeletePart(partId())}
|
||||||
disabled={isDeletingPart(partId())}
|
disabled={isDeletingPart(partId())}
|
||||||
title={t("messagePart.actions.deleteTitle")}
|
title={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
||||||
aria-label={t("messagePart.actions.deleteTitle")}
|
aria-label={isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
||||||
>
|
>
|
||||||
{isDeletingPart(partId()) ? t("messagePart.actions.deleting") : t("messagePart.actions.delete")}
|
<Trash2 class="w-3.5 h-3.5" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
Reference in New Issue
Block a user