Merge branch 'feature/byline-dictation' into develop
Add dictation mic button to the page byline next to the info icon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -14,8 +14,11 @@ import {
|
|||||||
UnstyledButton,
|
UnstyledButton,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconInfoCircle } from "@tabler/icons-react";
|
import { IconInfoCircle } from "@tabler/icons-react";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import { userAtom } from "@/features/user/atoms/current-user-atom.ts";
|
import {
|
||||||
|
userAtom,
|
||||||
|
workspaceAtom,
|
||||||
|
} from "@/features/user/atoms/current-user-atom.ts";
|
||||||
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
|
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { IContributor } from "@/features/page/types/page.types.ts";
|
import { IContributor } from "@/features/page/types/page.types.ts";
|
||||||
@@ -24,7 +27,11 @@ import { PageEditMode } from "@/features/user/types/user.types.ts";
|
|||||||
import { useAsideTriggerProps } from "@/hooks/use-toggle-aside.tsx";
|
import { useAsideTriggerProps } from "@/hooks/use-toggle-aside.tsx";
|
||||||
import { DeletedPageBanner } from "@/features/page/trash/components/deleted-page-banner.tsx";
|
import { DeletedPageBanner } from "@/features/page/trash/components/deleted-page-banner.tsx";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { currentPageEditModeAtom } from "@/features/editor/atoms/editor-atoms.ts";
|
import {
|
||||||
|
currentPageEditModeAtom,
|
||||||
|
pageEditorAtom,
|
||||||
|
} from "@/features/editor/atoms/editor-atoms.ts";
|
||||||
|
import { DictationGroup } from "@/features/editor/components/fixed-toolbar/groups/dictation-group";
|
||||||
|
|
||||||
const MemoizedTitleEditor = React.memo(TitleEditor);
|
const MemoizedTitleEditor = React.memo(TitleEditor);
|
||||||
const MemoizedPageEditor = React.memo(PageEditor);
|
const MemoizedPageEditor = React.memo(PageEditor);
|
||||||
@@ -65,6 +72,8 @@ export function FullEditor({
|
|||||||
canComment,
|
canComment,
|
||||||
}: FullEditorProps) {
|
}: FullEditorProps) {
|
||||||
const [user] = useAtom(userAtom);
|
const [user] = useAtom(userAtom);
|
||||||
|
const workspace = useAtomValue(workspaceAtom);
|
||||||
|
const isDictationEnabled = workspace?.settings?.ai?.dictation === true;
|
||||||
const fullPageWidth = user.settings?.preferences?.fullPageWidth;
|
const fullPageWidth = user.settings?.preferences?.fullPageWidth;
|
||||||
const editorToolbarEnabled =
|
const editorToolbarEnabled =
|
||||||
user.settings?.preferences?.editorToolbar ?? false;
|
user.settings?.preferences?.editorToolbar ?? false;
|
||||||
@@ -104,6 +113,9 @@ export function FullEditor({
|
|||||||
<PageByline
|
<PageByline
|
||||||
creator={creator}
|
creator={creator}
|
||||||
contributors={contributors}
|
contributors={contributors}
|
||||||
|
editable={editable}
|
||||||
|
isEditMode={isEditMode}
|
||||||
|
isDictationEnabled={isDictationEnabled}
|
||||||
/>
|
/>
|
||||||
<MemoizedPageEditor
|
<MemoizedPageEditor
|
||||||
pageId={pageId}
|
pageId={pageId}
|
||||||
@@ -118,11 +130,24 @@ export function FullEditor({
|
|||||||
type PageBylineProps = {
|
type PageBylineProps = {
|
||||||
creator?: PageUser;
|
creator?: PageUser;
|
||||||
contributors?: IContributor[];
|
contributors?: IContributor[];
|
||||||
|
editable?: boolean;
|
||||||
|
isEditMode?: boolean;
|
||||||
|
isDictationEnabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function PageByline({ creator, contributors }: PageBylineProps) {
|
function PageByline({
|
||||||
|
creator,
|
||||||
|
contributors,
|
||||||
|
editable,
|
||||||
|
isEditMode,
|
||||||
|
isDictationEnabled,
|
||||||
|
}: PageBylineProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const detailsTriggerProps = useAsideTriggerProps("details");
|
const detailsTriggerProps = useAsideTriggerProps("details");
|
||||||
|
const editor = useAtomValue(pageEditorAtom);
|
||||||
|
const showDictation = Boolean(
|
||||||
|
isDictationEnabled && editable && isEditMode && editor,
|
||||||
|
);
|
||||||
|
|
||||||
const otherContributors = (contributors ?? []).filter(
|
const otherContributors = (contributors ?? []).filter(
|
||||||
(c) => c.id !== creator?.id,
|
(c) => c.id !== creator?.id,
|
||||||
@@ -207,6 +232,9 @@ function PageByline({ creator, contributors }: PageBylineProps) {
|
|||||||
<IconInfoCircle size={20} stroke={1.5} />
|
<IconInfoCircle size={20} stroke={1.5} />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
{/* Shown only in edit mode when workspace dictation is enabled, so
|
||||||
|
dictation stays reachable even when the fixed toolbar is hidden. */}
|
||||||
|
{showDictation && editor && <DictationGroup editor={editor} />}
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user