|
|
@@ -31,9 +31,14 @@ import { DiffChanges } from "@opencode-ai/ui/diff-changes"
|
|
|
import { FileIcon } from "@opencode-ai/ui/file-icon"
|
|
|
import { Icon } from "@opencode-ai/ui/icon"
|
|
|
import { IconButton } from "@opencode-ai/ui/icon-button"
|
|
|
+import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
|
|
|
+import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
|
|
|
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
|
|
+import { MenuV2 } from "@opencode-ai/ui/v2/menu-v2"
|
|
|
import { Dialog } from "@opencode-ai/ui/dialog"
|
|
|
+import { DialogFooter, DialogHeader, DialogTitleGroup, DialogV2 } from "@opencode-ai/ui/v2/dialog-v2"
|
|
|
import { InlineInput } from "@opencode-ai/ui/inline-input"
|
|
|
+import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
|
|
|
import { SessionRetry } from "@opencode-ai/session-ui/session-retry"
|
|
|
import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
|
|
import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
|
|
|
@@ -671,6 +676,34 @@ export function MessageTimeline(props: {
|
|
|
if (!shareEnabled()) return
|
|
|
unshareMutation.mutate(id)
|
|
|
}
|
|
|
+ const copyShareUrl = () => {
|
|
|
+ const url = shareUrl()
|
|
|
+ if (!url) return
|
|
|
+ void navigator.clipboard
|
|
|
+ .writeText(url)
|
|
|
+ .then(() =>
|
|
|
+ showToast({
|
|
|
+ variant: "success",
|
|
|
+ icon: "circle-check",
|
|
|
+ title: language.t("session.share.copy.copied"),
|
|
|
+ description: url,
|
|
|
+ }),
|
|
|
+ )
|
|
|
+ .catch((err: unknown) =>
|
|
|
+ showToast({
|
|
|
+ title: language.t("common.requestFailed"),
|
|
|
+ description: errorMessage(err),
|
|
|
+ }),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const selectShareUrlText: JSX.EventHandler<HTMLDivElement, MouseEvent> = (event) => {
|
|
|
+ const selection = window.getSelection()
|
|
|
+ if (!selection) return
|
|
|
+ const range = document.createRange()
|
|
|
+ range.selectNodeContents(event.currentTarget)
|
|
|
+ selection.removeAllRanges()
|
|
|
+ selection.addRange(range)
|
|
|
+ }
|
|
|
|
|
|
createEffect(
|
|
|
on(
|
|
|
@@ -856,6 +889,26 @@ export function MessageTimeline(props: {
|
|
|
dialog.close()
|
|
|
}
|
|
|
|
|
|
+ if (settings.general.newLayoutDesigns())
|
|
|
+ return (
|
|
|
+ <DialogV2 fit>
|
|
|
+ <DialogHeader hideClose>
|
|
|
+ <DialogTitleGroup
|
|
|
+ title={language.t("session.delete.title")}
|
|
|
+ description={language.t("session.delete.confirm", { name: name() })}
|
|
|
+ />
|
|
|
+ </DialogHeader>
|
|
|
+ <DialogFooter>
|
|
|
+ <ButtonV2 variant="ghost" onClick={() => dialog.close()}>
|
|
|
+ {language.t("common.cancel")}
|
|
|
+ </ButtonV2>
|
|
|
+ <ButtonV2 variant="danger" onClick={handleDelete}>
|
|
|
+ {language.t("session.delete.button")}
|
|
|
+ </ButtonV2>
|
|
|
+ </DialogFooter>
|
|
|
+ </DialogV2>
|
|
|
+ )
|
|
|
+
|
|
|
return (
|
|
|
<Dialog title={language.t("session.delete.title")} fit>
|
|
|
<div class="flex flex-col gap-4 pl-6 pr-2.5 pb-3">
|
|
|
@@ -1304,11 +1357,16 @@ export function MessageTimeline(props: {
|
|
|
"pr-3": true,
|
|
|
"pl-4": settings.general.newLayoutDesigns(),
|
|
|
"pl-2 md:pl-4": !settings.general.newLayoutDesigns(),
|
|
|
- "md:max-w-200 md:mx-auto 2xl:max-w-[1000px]": props.centered,
|
|
|
+ "md:max-w-200 md:mx-auto 2xl:max-w-[1000px]": props.centered && !settings.general.newLayoutDesigns(),
|
|
|
}}
|
|
|
>
|
|
|
<div class="h-12 w-full flex items-center justify-between gap-2">
|
|
|
- <div class="flex items-center gap-1 min-w-0 flex-1 pr-3">
|
|
|
+ <div
|
|
|
+ classList={{
|
|
|
+ "flex items-center gap-1 min-w-0 flex-1": true,
|
|
|
+ "pr-3": !settings.general.newLayoutDesigns(),
|
|
|
+ }}
|
|
|
+ >
|
|
|
<div class="flex items-center min-w-0 grow-1">
|
|
|
<Show when={parentID()}>
|
|
|
<button
|
|
|
@@ -1347,8 +1405,17 @@ export function MessageTimeline(props: {
|
|
|
data-slot="session-title-child"
|
|
|
value={title.draft}
|
|
|
disabled={titleMutation.isPending}
|
|
|
- class="text-14-medium text-text-strong grow-1 min-w-0 rounded-[6px] pl-1 -ml-1"
|
|
|
- style={{ "--inline-input-shadow": "var(--shadow-xs-border-select)" }}
|
|
|
+ classList={{
|
|
|
+ "text-14-medium text-text-strong grow-1 min-w-0 pl-1 -ml-1": true,
|
|
|
+ "h-6 leading-4 rounded-[3px] focus:shadow-none focus:outline focus:outline-1 focus:outline-offset-[-1px] focus:outline-v2-border-border-focus":
|
|
|
+ settings.general.newLayoutDesigns(),
|
|
|
+ "rounded-[6px]": !settings.general.newLayoutDesigns(),
|
|
|
+ }}
|
|
|
+ style={{
|
|
|
+ "--inline-input-shadow": settings.general.newLayoutDesigns()
|
|
|
+ ? "none"
|
|
|
+ : "var(--shadow-xs-border-select)",
|
|
|
+ }}
|
|
|
onInput={(event) => setTitle("draft", event.currentTarget.value)}
|
|
|
onKeyDown={(event) => {
|
|
|
event.stopPropagation()
|
|
|
@@ -1370,88 +1437,170 @@ export function MessageTimeline(props: {
|
|
|
</div>
|
|
|
<Show when={sessionID()} keyed>
|
|
|
{(id) => (
|
|
|
- <div class="shrink-0 flex items-center gap-3">
|
|
|
- <SessionContextUsage placement="bottom" />
|
|
|
+ <div
|
|
|
+ classList={{
|
|
|
+ "shrink-0 flex items-center": true,
|
|
|
+ "gap-2": settings.general.newLayoutDesigns(),
|
|
|
+ "gap-3": !settings.general.newLayoutDesigns(),
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <SessionContextUsage
|
|
|
+ placement="bottom"
|
|
|
+ buttonAppearance={settings.general.newLayoutDesigns() ? "v2" : "default"}
|
|
|
+ />
|
|
|
<Show when={!parentID()}>
|
|
|
- <DropdownMenu
|
|
|
- gutter={4}
|
|
|
- placement="bottom-end"
|
|
|
- open={title.menuOpen}
|
|
|
- onOpenChange={(open) => {
|
|
|
- setTitle("menuOpen", open)
|
|
|
- if (open) return
|
|
|
- }}
|
|
|
+ <Show
|
|
|
+ when={settings.general.newLayoutDesigns()}
|
|
|
+ fallback={
|
|
|
+ <DropdownMenu
|
|
|
+ gutter={4}
|
|
|
+ placement="bottom-end"
|
|
|
+ open={title.menuOpen}
|
|
|
+ onOpenChange={(open) => {
|
|
|
+ setTitle("menuOpen", open)
|
|
|
+ if (open) return
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <DropdownMenu.Trigger
|
|
|
+ as={IconButton}
|
|
|
+ icon="dot-grid"
|
|
|
+ variant="ghost"
|
|
|
+ class="size-6 rounded-md data-[expanded]:bg-surface-base-active"
|
|
|
+ classList={{
|
|
|
+ "bg-surface-base-active": share.open || title.pendingShare,
|
|
|
+ }}
|
|
|
+ aria-label={language.t("common.moreOptions")}
|
|
|
+ aria-expanded={title.menuOpen || share.open || title.pendingShare}
|
|
|
+ ref={(el: HTMLButtonElement) => {
|
|
|
+ more = el
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <DropdownMenu.Portal>
|
|
|
+ <DropdownMenu.Content
|
|
|
+ style={{ "min-width": "104px" }}
|
|
|
+ onCloseAutoFocus={(event) => {
|
|
|
+ if (title.pendingRename) {
|
|
|
+ event.preventDefault()
|
|
|
+ setTitle("pendingRename", false)
|
|
|
+ openTitleEditor()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (title.pendingShare) {
|
|
|
+ event.preventDefault()
|
|
|
+ requestAnimationFrame(() => {
|
|
|
+ setShare({ open: true, dismiss: null })
|
|
|
+ setTitle("pendingShare", false)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <DropdownMenu.Item
|
|
|
+ onSelect={() => {
|
|
|
+ setTitle("pendingRename", true)
|
|
|
+ setTitle("menuOpen", false)
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <DropdownMenu.ItemLabel>{language.t("common.rename")}</DropdownMenu.ItemLabel>
|
|
|
+ </DropdownMenu.Item>
|
|
|
+ <Show when={shareEnabled()}>
|
|
|
+ <DropdownMenu.Item
|
|
|
+ onSelect={() => {
|
|
|
+ setTitle({ pendingShare: true, menuOpen: false })
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <DropdownMenu.ItemLabel>
|
|
|
+ {language.t("session.share.action.share")}
|
|
|
+ </DropdownMenu.ItemLabel>
|
|
|
+ </DropdownMenu.Item>
|
|
|
+ </Show>
|
|
|
+ <DropdownMenu.Item onSelect={() => void archiveSession(id)}>
|
|
|
+ <DropdownMenu.ItemLabel>{language.t("common.archive")}</DropdownMenu.ItemLabel>
|
|
|
+ </DropdownMenu.Item>
|
|
|
+ <DropdownMenu.Separator />
|
|
|
+ <DropdownMenu.Item
|
|
|
+ onSelect={() => dialog.show(() => <DialogDeleteSession sessionID={id} />)}
|
|
|
+ >
|
|
|
+ <DropdownMenu.ItemLabel>{language.t("common.delete")}</DropdownMenu.ItemLabel>
|
|
|
+ </DropdownMenu.Item>
|
|
|
+ </DropdownMenu.Content>
|
|
|
+ </DropdownMenu.Portal>
|
|
|
+ </DropdownMenu>
|
|
|
+ }
|
|
|
>
|
|
|
- <DropdownMenu.Trigger
|
|
|
- as={IconButton}
|
|
|
- icon="dot-grid"
|
|
|
- variant="ghost"
|
|
|
- class="size-6 rounded-md data-[expanded]:bg-surface-base-active"
|
|
|
- classList={{
|
|
|
- "bg-surface-base-active": share.open || title.pendingShare,
|
|
|
- }}
|
|
|
- aria-label={language.t("common.moreOptions")}
|
|
|
- aria-expanded={title.menuOpen || share.open || title.pendingShare}
|
|
|
- ref={(el: HTMLButtonElement) => {
|
|
|
- more = el
|
|
|
+ <MenuV2
|
|
|
+ gutter={6}
|
|
|
+ placement="bottom-end"
|
|
|
+ open={title.menuOpen}
|
|
|
+ onOpenChange={(open) => {
|
|
|
+ setTitle("menuOpen", open)
|
|
|
+ if (open) return
|
|
|
}}
|
|
|
- />
|
|
|
- <DropdownMenu.Portal>
|
|
|
- <DropdownMenu.Content
|
|
|
- style={{ "min-width": "104px" }}
|
|
|
- onCloseAutoFocus={(event) => {
|
|
|
- if (title.pendingRename) {
|
|
|
- event.preventDefault()
|
|
|
- setTitle("pendingRename", false)
|
|
|
- openTitleEditor()
|
|
|
- return
|
|
|
- }
|
|
|
- if (title.pendingShare) {
|
|
|
- event.preventDefault()
|
|
|
- requestAnimationFrame(() => {
|
|
|
- setShare({ open: true, dismiss: null })
|
|
|
- setTitle("pendingShare", false)
|
|
|
- })
|
|
|
- }
|
|
|
+ >
|
|
|
+ <MenuV2.Trigger
|
|
|
+ as={IconButtonV2}
|
|
|
+ icon={<IconV2 name="outline-dots" />}
|
|
|
+ variant="ghost-muted"
|
|
|
+ size="large"
|
|
|
+ state={share.open || title.pendingShare ? "pressed" : undefined}
|
|
|
+ aria-label={language.t("common.moreOptions")}
|
|
|
+ aria-expanded={title.menuOpen || share.open || title.pendingShare}
|
|
|
+ ref={(el: HTMLButtonElement) => {
|
|
|
+ more = el
|
|
|
}}
|
|
|
- >
|
|
|
- <DropdownMenu.Item
|
|
|
- onSelect={() => {
|
|
|
- setTitle("pendingRename", true)
|
|
|
- setTitle("menuOpen", false)
|
|
|
+ />
|
|
|
+ <MenuV2.Portal>
|
|
|
+ <MenuV2.Content
|
|
|
+ style={{ width: "120px", "min-width": "120px" }}
|
|
|
+ onCloseAutoFocus={(event) => {
|
|
|
+ if (title.pendingRename) {
|
|
|
+ event.preventDefault()
|
|
|
+ setTitle("pendingRename", false)
|
|
|
+ openTitleEditor()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (title.pendingShare) {
|
|
|
+ event.preventDefault()
|
|
|
+ requestAnimationFrame(() => {
|
|
|
+ setShare({ open: true, dismiss: null })
|
|
|
+ setTitle("pendingShare", false)
|
|
|
+ })
|
|
|
+ }
|
|
|
}}
|
|
|
>
|
|
|
- <DropdownMenu.ItemLabel>{language.t("common.rename")}</DropdownMenu.ItemLabel>
|
|
|
- </DropdownMenu.Item>
|
|
|
- <Show when={shareEnabled()}>
|
|
|
- <DropdownMenu.Item
|
|
|
+ <MenuV2.Item
|
|
|
onSelect={() => {
|
|
|
- setTitle({ pendingShare: true, menuOpen: false })
|
|
|
+ setTitle("pendingRename", true)
|
|
|
+ setTitle("menuOpen", false)
|
|
|
}}
|
|
|
>
|
|
|
- <DropdownMenu.ItemLabel>
|
|
|
- {language.t("session.share.action.share")}
|
|
|
- </DropdownMenu.ItemLabel>
|
|
|
- </DropdownMenu.Item>
|
|
|
- </Show>
|
|
|
- <DropdownMenu.Item onSelect={() => void archiveSession(id)}>
|
|
|
- <DropdownMenu.ItemLabel>{language.t("common.archive")}</DropdownMenu.ItemLabel>
|
|
|
- </DropdownMenu.Item>
|
|
|
- <DropdownMenu.Separator />
|
|
|
- <DropdownMenu.Item
|
|
|
- onSelect={() => dialog.show(() => <DialogDeleteSession sessionID={id} />)}
|
|
|
- >
|
|
|
- <DropdownMenu.ItemLabel>{language.t("common.delete")}</DropdownMenu.ItemLabel>
|
|
|
- </DropdownMenu.Item>
|
|
|
- </DropdownMenu.Content>
|
|
|
- </DropdownMenu.Portal>
|
|
|
- </DropdownMenu>
|
|
|
+ {language.t("common.rename")}
|
|
|
+ </MenuV2.Item>
|
|
|
+ <Show when={shareEnabled()}>
|
|
|
+ <MenuV2.Item
|
|
|
+ onSelect={() => {
|
|
|
+ setTitle({ pendingShare: true, menuOpen: false })
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {language.t("session.share.action.share")}...
|
|
|
+ </MenuV2.Item>
|
|
|
+ </Show>
|
|
|
+ <MenuV2.Item onSelect={() => void archiveSession(id)}>
|
|
|
+ {language.t("common.archive")}
|
|
|
+ </MenuV2.Item>
|
|
|
+ <MenuV2.Separator />
|
|
|
+ <MenuV2.Item onSelect={() => dialog.show(() => <DialogDeleteSession sessionID={id} />)}>
|
|
|
+ {language.t("common.delete")}...
|
|
|
+ </MenuV2.Item>
|
|
|
+ </MenuV2.Content>
|
|
|
+ </MenuV2.Portal>
|
|
|
+ </MenuV2>
|
|
|
+ </Show>
|
|
|
|
|
|
<KobaltePopover
|
|
|
open={share.open}
|
|
|
anchorRef={() => more}
|
|
|
placement="bottom-end"
|
|
|
- gutter={4}
|
|
|
+ gutter={settings.general.newLayoutDesigns() ? 6 : 4}
|
|
|
modal={false}
|
|
|
onOpenChange={(open) => {
|
|
|
if (open) setShare("dismiss", null)
|
|
|
@@ -1461,6 +1610,10 @@ export function MessageTimeline(props: {
|
|
|
<KobaltePopover.Portal>
|
|
|
<KobaltePopover.Content
|
|
|
data-component="popover-content"
|
|
|
+ classList={{
|
|
|
+ "flex w-80 max-w-none flex-col items-start gap-3 rounded-[10px] border-0 bg-v2-background-bg-layer-01 p-3 shadow-[var(--v2-elevation-floating)]":
|
|
|
+ settings.general.newLayoutDesigns(),
|
|
|
+ }}
|
|
|
style={{ "min-width": "320px" }}
|
|
|
onEscapeKeyDown={(event) => {
|
|
|
setShare({ dismiss: "escape", open: false })
|
|
|
@@ -1478,24 +1631,90 @@ export function MessageTimeline(props: {
|
|
|
setShare("dismiss", null)
|
|
|
}}
|
|
|
>
|
|
|
- <div class="flex flex-col p-3">
|
|
|
- <div class="flex flex-col gap-1">
|
|
|
- <div class="text-13-medium text-text-strong">
|
|
|
+ <Show
|
|
|
+ when={settings.general.newLayoutDesigns()}
|
|
|
+ fallback={
|
|
|
+ <div class="flex flex-col p-3">
|
|
|
+ <div class="flex flex-col gap-1">
|
|
|
+ <div class="text-13-medium text-text-strong">
|
|
|
+ {language.t("session.share.popover.title")}
|
|
|
+ </div>
|
|
|
+ <div class="text-12-regular text-text-weak">
|
|
|
+ {shareUrl()
|
|
|
+ ? language.t("session.share.popover.description.shared")
|
|
|
+ : language.t("session.share.popover.description.unshared")}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mt-3 flex flex-col gap-2">
|
|
|
+ <Show
|
|
|
+ when={shareUrl()}
|
|
|
+ fallback={
|
|
|
+ <Button
|
|
|
+ size="large"
|
|
|
+ variant="primary"
|
|
|
+ class="w-full"
|
|
|
+ onClick={shareSession}
|
|
|
+ disabled={shareMutation.isPending}
|
|
|
+ >
|
|
|
+ {shareMutation.isPending
|
|
|
+ ? language.t("session.share.action.publishing")
|
|
|
+ : language.t("session.share.action.publish")}
|
|
|
+ </Button>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div class="flex flex-col gap-2">
|
|
|
+ <TextField
|
|
|
+ value={shareUrl() ?? ""}
|
|
|
+ readOnly
|
|
|
+ copyable
|
|
|
+ copyKind="link"
|
|
|
+ tabIndex={-1}
|
|
|
+ class="w-full"
|
|
|
+ />
|
|
|
+ <div class="grid grid-cols-2 gap-2">
|
|
|
+ <Button
|
|
|
+ size="large"
|
|
|
+ variant="secondary"
|
|
|
+ class="w-full shadow-none border border-border-weak-base"
|
|
|
+ onClick={unshareSession}
|
|
|
+ disabled={unshareMutation.isPending}
|
|
|
+ >
|
|
|
+ {unshareMutation.isPending
|
|
|
+ ? language.t("session.share.action.unpublishing")
|
|
|
+ : language.t("session.share.action.unpublish")}
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ size="large"
|
|
|
+ variant="primary"
|
|
|
+ class="w-full"
|
|
|
+ onClick={viewShare}
|
|
|
+ disabled={unshareMutation.isPending}
|
|
|
+ >
|
|
|
+ {language.t("session.share.action.view")}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Show>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div class="flex w-full flex-col gap-1.5 px-0.5 pt-0.5">
|
|
|
+ <div class="select-none text-[13px] font-[530] leading-none tracking-[-0.04px] text-v2-text-text-base [font-variation-settings:'slnt'_0]">
|
|
|
{language.t("session.share.popover.title")}
|
|
|
</div>
|
|
|
- <div class="text-12-regular text-text-weak">
|
|
|
+ <div class="select-none text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-muted [font-variation-settings:'slnt'_0]">
|
|
|
{shareUrl()
|
|
|
? language.t("session.share.popover.description.shared")
|
|
|
: language.t("session.share.popover.description.unshared")}
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="mt-3 flex flex-col gap-2">
|
|
|
+ <div class="flex w-full flex-col gap-2">
|
|
|
<Show
|
|
|
when={shareUrl()}
|
|
|
fallback={
|
|
|
- <Button
|
|
|
- size="large"
|
|
|
- variant="primary"
|
|
|
+ <ButtonV2
|
|
|
+ variant="contrast"
|
|
|
class="w-full"
|
|
|
onClick={shareSession}
|
|
|
disabled={shareMutation.isPending}
|
|
|
@@ -1503,48 +1722,57 @@ export function MessageTimeline(props: {
|
|
|
{shareMutation.isPending
|
|
|
? language.t("session.share.action.publishing")
|
|
|
: language.t("session.share.action.publish")}
|
|
|
- </Button>
|
|
|
+ </ButtonV2>
|
|
|
}
|
|
|
>
|
|
|
<div class="flex flex-col gap-2">
|
|
|
- <TextField
|
|
|
- value={shareUrl() ?? ""}
|
|
|
- readOnly
|
|
|
- copyable
|
|
|
- copyKind="link"
|
|
|
- tabIndex={-1}
|
|
|
- class="w-full"
|
|
|
- />
|
|
|
- <div class="grid grid-cols-2 gap-2">
|
|
|
- <Button
|
|
|
- size="large"
|
|
|
- variant="secondary"
|
|
|
- class={
|
|
|
- settings.general.newLayoutDesigns()
|
|
|
- ? "w-full shadow-none border-[0.5px] border-border-weak-base"
|
|
|
- : "w-full shadow-none border border-border-weak-base"
|
|
|
- }
|
|
|
+ <div
|
|
|
+ class="flex h-8 w-full items-center gap-1.5 rounded-[6px] py-1 pl-2.5 pr-1.5 shadow-[var(--v2-elevation-button-neutral)]"
|
|
|
+ style={{
|
|
|
+ background:
|
|
|
+ "linear-gradient(180deg, var(--v2-alpha-light-2) 0%, var(--v2-alpha-light-0) 100%), var(--v2-background-bg-button-neutral)",
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="min-w-0 flex-1 truncate select-text cursor-text text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-base [font-variation-settings:'slnt'_0]"
|
|
|
+ onClick={selectShareUrlText}
|
|
|
+ >
|
|
|
+ {shareUrl()}
|
|
|
+ </div>
|
|
|
+ <IconButtonV2
|
|
|
+ type="button"
|
|
|
+ size="small"
|
|
|
+ variant="ghost-muted"
|
|
|
+ icon={<IconV2 name="outline-copy" />}
|
|
|
+ aria-label={language.t("session.share.copy.copyLink")}
|
|
|
+ onClick={copyShareUrl}
|
|
|
+ />
|
|
|
+ <IconButtonV2
|
|
|
+ type="button"
|
|
|
+ size="small"
|
|
|
+ variant="ghost-muted"
|
|
|
+ icon={<IconV2 name="outline-square-arrow" />}
|
|
|
+ aria-label={language.t("session.share.action.view")}
|
|
|
+ onClick={viewShare}
|
|
|
+ disabled={unshareMutation.isPending}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="flex w-full">
|
|
|
+ <ButtonV2
|
|
|
+ variant="outline"
|
|
|
+ class="w-full"
|
|
|
onClick={unshareSession}
|
|
|
disabled={unshareMutation.isPending}
|
|
|
>
|
|
|
{unshareMutation.isPending
|
|
|
? language.t("session.share.action.unpublishing")
|
|
|
: language.t("session.share.action.unpublish")}
|
|
|
- </Button>
|
|
|
- <Button
|
|
|
- size="large"
|
|
|
- variant="primary"
|
|
|
- class="w-full"
|
|
|
- onClick={viewShare}
|
|
|
- disabled={unshareMutation.isPending}
|
|
|
- >
|
|
|
- {language.t("session.share.action.view")}
|
|
|
- </Button>
|
|
|
+ </ButtonV2>
|
|
|
</div>
|
|
|
</div>
|
|
|
</Show>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </Show>
|
|
|
</KobaltePopover.Content>
|
|
|
</KobaltePopover.Portal>
|
|
|
</KobaltePopover>
|