From 53c531c9318405c2b0c36da87df6e345a752a855 Mon Sep 17 00:00:00 2001 From: pengx17 Date: Tue, 6 May 2025 09:29:57 +0000 Subject: [PATCH] feat(electron): add welcome page for meetings (#12042) fix AF-2572 ![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/0e56b58a-97b4-4984-81fa-f8e45f8cc561.png) ![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/T2klNLEk0wxLh4NRDzhk/97e3bb97-e326-48f6-8dd4-27734f583775.png) ## Summary by CodeRabbit - **New Features** - Introduced a Meetings welcome page with a beta disclaimer and "Get Started" flow. - Added separate toggles for AI auto summary and AI auto todo list in meeting settings. - Added "Beta" labels to relevant settings and sidebar items for clearer feature status. - Enhanced settings UI with improved headers, subtitles, and new styling. - **Improvements** - Meeting settings now allow independent control over AI-generated summaries and todo lists. - Updated internationalization to support new meeting and AI transcription features, including richer prompts and hints. - Refined logic for enabling meeting recording, including improved permission handling. - Simplified transcription logic to rely solely on AI enablement flag. - **Bug Fixes** - Fixed display and control of meeting settings based on beta disclaimer acceptance. - **Chores** - Updated localization files and completeness percentages for several languages. - Removed deprecated feature flag for enabling meetings. --- .../src/app/effects/recording.ts | 12 +- .../electron/src/main/shared-state-schema.ts | 12 +- .../setting-components/setting-header.tsx | 9 +- .../setting-components/share.css.ts | 19 +- .../dialogs/setting/general-setting/index.tsx | 176 ++++--- .../general-setting/meetings/index.tsx | 101 ++-- .../meetings/meeting-apps.dark.assets.svg | 473 ++++++++++++++++++ .../meetings/meeting-apps.light.assets.svg | 473 ++++++++++++++++++ .../meetings/use-enable-recording.ts | 49 ++ .../meetings/welcome-page.css.ts | 110 ++++ .../general-setting/meetings/welcome-page.tsx | 81 +++ .../dialogs/setting/setting-sidebar/index.tsx | 3 + .../setting/setting-sidebar/style.css.ts | 13 + .../core/src/desktop/dialogs/setting/types.ts | 1 + .../core/src/modules/feature-flag/constant.ts | 12 - .../media/entities/audio-attachment-block.ts | 12 +- .../frontend/core/src/modules/media/index.ts | 6 +- .../media/services/meeting-settings.ts | 22 +- .../i18n/src/i18n-completenesses.json | 2 +- packages/frontend/i18n/src/i18n.gen.ts | 44 +- packages/frontend/i18n/src/resources/ar.json | 2 - packages/frontend/i18n/src/resources/de.json | 2 - .../frontend/i18n/src/resources/el-GR.json | 2 - packages/frontend/i18n/src/resources/en.json | 11 +- packages/frontend/i18n/src/resources/es.json | 2 - packages/frontend/i18n/src/resources/fa.json | 2 - packages/frontend/i18n/src/resources/fr.json | 2 - .../frontend/i18n/src/resources/it-IT.json | 2 - packages/frontend/i18n/src/resources/ja.json | 2 - packages/frontend/i18n/src/resources/pl.json | 2 - .../frontend/i18n/src/resources/pt-BR.json | 2 - packages/frontend/i18n/src/resources/ru.json | 2 - .../frontend/i18n/src/resources/sv-SE.json | 2 - packages/frontend/i18n/src/resources/uk.json | 2 - .../frontend/i18n/src/resources/zh-Hans.json | 2 - .../frontend/i18n/src/resources/zh-Hant.json | 2 - 36 files changed, 1470 insertions(+), 201 deletions(-) create mode 100644 packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.dark.assets.svg create mode 100644 packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.light.assets.svg create mode 100644 packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/use-enable-recording.ts create mode 100644 packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.css.ts create mode 100644 packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.tsx diff --git a/packages/frontend/apps/electron-renderer/src/app/effects/recording.ts b/packages/frontend/apps/electron-renderer/src/app/effects/recording.ts index 4cb92294bd..0e01ace578 100644 --- a/packages/frontend/apps/electron-renderer/src/app/effects/recording.ts +++ b/packages/frontend/apps/electron-renderer/src/app/effects/recording.ts @@ -2,7 +2,6 @@ import type { DocProps } from '@affine/core/blocksuite/initialization'; import { DocsService } from '@affine/core/modules/doc'; import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { AudioAttachmentService } from '@affine/core/modules/media/services/audio-attachment'; -import { MeetingSettingsService } from '@affine/core/modules/media/services/meeting-settings'; import { WorkbenchService } from '@affine/core/modules/workbench'; import { DebugLogger } from '@affine/debug'; import { apis, events } from '@affine/electron-api'; @@ -94,16 +93,7 @@ export function setupRecordingEvents(frameworkProvider: FrameworkProvider) { model.props.sourceId = blobId; model.props.embed = true; - const meetingSettingsService = frameworkProvider.get( - MeetingSettingsService - ); - - if ( - !meetingSettingsService.settings.autoTranscription || - !aiEnabled - ) { - // auto transcription is disabled, - // so we don't need to transcribe the recording by default + if (!aiEnabled) { return; } diff --git a/packages/frontend/apps/electron/src/main/shared-state-schema.ts b/packages/frontend/apps/electron/src/main/shared-state-schema.ts index fcad2ecb78..9d2d3b4c66 100644 --- a/packages/frontend/apps/electron/src/main/shared-state-schema.ts +++ b/packages/frontend/apps/electron/src/main/shared-state-schema.ts @@ -59,7 +59,6 @@ export const MenubarStateSchema = z.object({ enabled: z.boolean().default(true), }); -// eslint-disable-next-line no-redeclare export type MenubarStateSchema = z.infer; export const MeetingSettingsKey = 'meetingSettings' as const; @@ -67,15 +66,20 @@ export const MeetingSettingsSchema = z.object({ // global meeting feature control enabled: z.boolean().default(false), + // if false (and enabled = false), show a prompt page + betaDisclaimerAccepted: z.boolean().default(false), + // when recording is saved, where to create the recording block recordingSavingMode: z.enum(['new-doc', 'journal-today']).default('new-doc'), - // whether to enable auto transcription for new meeting recordings - autoTranscription: z.boolean().default(true), + // whether to enable generation of summary for new meeting recordings + autoTranscriptionSummary: z.boolean().default(true), + + // whether to enable generation of todo list for new meeting recordings + autoTranscriptionTodo: z.boolean().default(true), // recording reactions to new meeting events recordingMode: z.enum(['none', 'prompt', 'auto-start']).default('prompt'), }); -// eslint-disable-next-line no-redeclare export type MeetingSettingsSchema = z.infer; diff --git a/packages/frontend/component/src/components/setting-components/setting-header.tsx b/packages/frontend/component/src/components/setting-components/setting-header.tsx index 635e2776f5..75e98f42d1 100644 --- a/packages/frontend/component/src/components/setting-components/setting-header.tsx +++ b/packages/frontend/component/src/components/setting-components/setting-header.tsx @@ -1,21 +1,26 @@ import type { HTMLAttributes, ReactNode } from 'react'; -import { settingHeader } from './share.css'; +import { settingHeader, settingHeaderBeta } from './share.css'; interface SettingHeaderProps extends Omit, 'title'> { title: ReactNode; subtitle?: ReactNode; + beta?: boolean; } export const SettingHeader = ({ title, subtitle, + beta, ...otherProps }: SettingHeaderProps) => { return (
-
{title}
+
+ {title} + {beta ?
Beta
: null} +
{subtitle ?
{subtitle}
: null}
); diff --git a/packages/frontend/component/src/components/setting-components/share.css.ts b/packages/frontend/component/src/components/setting-components/share.css.ts index f0906de910..092501683f 100644 --- a/packages/frontend/component/src/components/setting-components/share.css.ts +++ b/packages/frontend/component/src/components/setting-components/share.css.ts @@ -1,20 +1,26 @@ import { cssVar } from '@toeverything/theme'; +import { cssVarV2 } from '@toeverything/theme/v2'; import { globalStyle, style } from '@vanilla-extract/css'; export const settingHeader = style({ borderBottom: `1px solid ${cssVar('borderColor')}`, paddingBottom: '16px', marginBottom: '24px', + whiteSpace: 'pre-wrap', }); globalStyle(`${settingHeader} .title`, { fontSize: cssVar('fontBase'), fontWeight: 600, lineHeight: '24px', + display: 'flex', + alignItems: 'center', + gap: '12px', + position: 'relative', }); globalStyle(`${settingHeader} .subtitle`, { paddingTop: '4px', paddingBottom: '8px', fontSize: cssVar('fontXs'), - lineHeight: '16px', + lineHeight: '20px', color: cssVar('textSecondaryColor'), }); export const wrapper = style({ @@ -90,3 +96,14 @@ globalStyle(`${settingRow} .right-col`, { paddingLeft: '15px', flexShrink: 0, }); + +export const settingHeaderBeta = style({ + fontSize: cssVar('fontXs'), + background: cssVarV2('chip/label/blue'), + padding: '0 8px', + borderRadius: '4px', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + height: 20, +}); diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/index.tsx index 890ee511e1..7518ea09cc 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/index.tsx @@ -1,6 +1,7 @@ import { UserFeatureService } from '@affine/core/modules/cloud/services/user-feature'; import type { SettingTab } from '@affine/core/modules/dialogs/constant'; import { FeatureFlagService } from '@affine/core/modules/feature-flag'; +import { MeetingSettingsService } from '@affine/core/modules/media/services/meeting-settings'; import { useI18n } from '@affine/i18n'; import { AppearanceIcon, @@ -13,7 +14,7 @@ import { PenIcon, } from '@blocksuite/icons/rc'; import { useLiveData, useServices } from '@toeverything/infra'; -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { AuthService, ServerService } from '../../../../modules/cloud'; import type { SettingSidebarItem, SettingState } from '../types'; @@ -33,13 +34,19 @@ export type GeneralSettingList = SettingSidebarItem[]; export const useGeneralSettingList = (): GeneralSettingList => { const t = useI18n(); - const { authService, serverService, userFeatureService, featureFlagService } = - useServices({ - AuthService, - ServerService, - UserFeatureService, - FeatureFlagService, - }); + const { + authService, + serverService, + userFeatureService, + featureFlagService, + meetingSettingsService, + } = useServices({ + AuthService, + ServerService, + UserFeatureService, + FeatureFlagService, + MeetingSettingsService, + }); const status = useLiveData(authService.session.status$); const loggedIn = status === 'authenticated'; const hasPaymentFeature = useLiveData( @@ -48,97 +55,102 @@ export const useGeneralSettingList = (): GeneralSettingList => { const enableEditorSettings = useLiveData( featureFlagService.flags.enable_editor_settings.$ ); - const enableMeetings = useLiveData( - featureFlagService.flags.enable_meetings.$ - ); useEffect(() => { userFeatureService.userFeature.revalidate(); }, [userFeatureService]); - const settings: GeneralSettingList = [ - { - key: 'appearance', - title: t['com.affine.settings.appearance'](), - icon: , - testId: 'appearance-panel-trigger', - }, - { - key: 'shortcuts', - title: t['com.affine.keyboardShortcuts.title'](), - icon: , - testId: 'shortcuts-panel-trigger', - }, - ]; - if (loggedIn) { - settings.push({ - key: 'notifications', - title: t['com.affine.setting.notifications'](), - icon: , - testId: 'notifications-panel-trigger', - }); - } - if (enableEditorSettings) { - // add editor settings to second position - settings.splice(1, 0, { - key: 'editor', - title: t['com.affine.settings.editorSettings'](), - icon: , - testId: 'editor-panel-trigger', - }); - } + const meetingSettings = useLiveData(meetingSettingsService.settings$); + + return useMemo(() => { + const settings: GeneralSettingList = [ + { + key: 'appearance', + title: t['com.affine.settings.appearance'](), + icon: , + testId: 'appearance-panel-trigger', + }, + { + key: 'shortcuts', + title: t['com.affine.keyboardShortcuts.title'](), + icon: , + testId: 'shortcuts-panel-trigger', + }, + ]; + if (loggedIn) { + settings.push({ + key: 'notifications', + title: t['com.affine.setting.notifications'](), + icon: , + testId: 'notifications-panel-trigger', + }); + } + if (enableEditorSettings) { + // add editor settings to second position + settings.splice(1, 0, { + key: 'editor', + title: t['com.affine.settings.editorSettings'](), + icon: , + testId: 'editor-panel-trigger', + }); + } - if (enableMeetings) { settings.push({ key: 'meetings', title: t['com.affine.settings.meetings'](), icon: , testId: 'meetings-panel-trigger', + beta: !meetingSettings?.enabled, }); - } - if (hasPaymentFeature) { - settings.splice(4, 0, { - key: 'plans', - title: t['com.affine.payment.title'](), - icon: , - testId: 'plans-panel-trigger', - }); - if (loggedIn) { + if (hasPaymentFeature) { settings.splice(4, 0, { - key: 'billing', - title: t['com.affine.payment.billing-setting.title'](), - icon: , - testId: 'billing-panel-trigger', + key: 'plans', + title: t['com.affine.payment.title'](), + icon: , + testId: 'plans-panel-trigger', + }); + if (loggedIn) { + settings.splice(4, 0, { + key: 'billing', + title: t['com.affine.payment.billing-setting.title'](), + icon: , + testId: 'billing-panel-trigger', + }); + } + } + + if (BUILD_CONFIG.isElectron) { + settings.push({ + key: 'backup', + title: t['com.affine.settings.workspace.backup'](), + icon: , + testId: 'backup-panel-trigger', }); } - } - if (BUILD_CONFIG.isElectron) { - settings.push({ - key: 'backup', - title: t['com.affine.settings.workspace.backup'](), - icon: , - testId: 'backup-panel-trigger', - }); - } - - settings.push( - { - key: 'experimental-features', - title: t['com.affine.settings.workspace.experimental-features'](), - icon: , - testId: 'experimental-features-trigger', - }, - { - key: 'about', - title: t['com.affine.aboutAFFiNE.title'](), - icon: , - testId: 'about-panel-trigger', - } - ); - - return settings; + settings.push( + { + key: 'experimental-features', + title: t['com.affine.settings.workspace.experimental-features'](), + icon: , + testId: 'experimental-features-trigger', + }, + { + key: 'about', + title: t['com.affine.aboutAFFiNE.title'](), + icon: , + testId: 'about-panel-trigger', + } + ); + return settings; + }, [ + t, + loggedIn, + enableEditorSettings, + meetingSettings?.enabled, + hasPaymentFeature, + ]); }; interface GeneralSettingProps { diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx index f7fbe821ab..59906d3acf 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx @@ -4,7 +4,6 @@ import { MenuItem, MenuTrigger, Switch, - useConfirmModal, } from '@affine/component'; import { SettingHeader, @@ -15,7 +14,6 @@ import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hoo import { MeetingSettingsService } from '@affine/core/modules/media/services/meeting-settings'; import type { MeetingSettingsSchema } from '@affine/electron/main/shared-state-schema'; import { Trans, useI18n } from '@affine/i18n'; -import track from '@affine/track'; import { ArrowRightSmallIcon, DoneIcon, @@ -25,6 +23,8 @@ import { useLiveData, useService } from '@toeverything/infra'; import { useCallback, useEffect, useMemo, useState } from 'react'; import * as styles from './styles.css'; +import { useEnableRecording } from './use-enable-recording'; +import { MeetingsWelcomePage } from './welcome-page'; const RecordingModes: MeetingSettingsSchema['recordingMode'][] = [ 'prompt', @@ -130,7 +130,7 @@ const PermissionSettingRow = ({ ); }; -export const MeetingsSettings = () => { +const MeetingsSettingsMain = () => { const t = useI18n(); const meetingSettingsService = useService(MeetingSettingsService); const settings = useLiveData(meetingSettingsService.settings$); @@ -142,8 +142,6 @@ export const MeetingsSettings = () => { microphone: boolean; }>(); - const confirmModal = useConfirmModal(); - useEffect(() => { meetingSettingsService .isRecordingFeatureAvailable() @@ -161,44 +159,18 @@ export const MeetingsSettings = () => { .catch(err => console.log(err)); }, [meetingSettingsService]); - const handleEnabledChange = useAsyncCallback( - async (checked: boolean) => { - try { - track.$.settingsPanel.meetings.toggleMeetingFeatureFlag({ - option: checked ? 'on' : 'off', - type: 'Meeting record', - }); - await meetingSettingsService.setEnabled(checked); - } catch { - confirmModal.openConfirmModal({ - title: - t['com.affine.settings.meetings.record.permission-modal.title'](), - description: - t[ - 'com.affine.settings.meetings.record.permission-modal.description' - ](), - onConfirm: async () => { - await meetingSettingsService.showRecordingPermissionSetting( - 'screen' - ); - }, - cancelText: t['com.affine.recording.dismiss'](), - confirmButtonOptions: { - variant: 'primary', - }, - confirmText: - t[ - 'com.affine.settings.meetings.record.permission-modal.open-setting' - ](), - }); - } + const handleEnabledChange = useEnableRecording(); + + const handleAutoSummaryChange = useCallback( + (checked: boolean) => { + meetingSettingsService.setAutoSummary(checked); }, - [confirmModal, meetingSettingsService, t] + [meetingSettingsService] ); - const handleAutoTranscriptionChange = useCallback( + const handleAutoTodoChange = useCallback( (checked: boolean) => { - meetingSettingsService.setAutoTranscription(checked); + meetingSettingsService.setAutoTodo(checked); }, [meetingSettingsService] ); @@ -225,7 +197,22 @@ export const MeetingsSettings = () => { return (
- + , + }} + /> + ) + } + /> { > + + + @@ -324,3 +323,15 @@ export const MeetingsSettings = () => {
); }; + +export const MeetingsSettings = () => { + const meetingSettingsService = useService(MeetingSettingsService); + const settings = useLiveData(meetingSettingsService.settings$); + const accepted = settings.betaDisclaimerAccepted || settings.enabled; + + if (!accepted) { + return ; + } + + return ; +}; diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.dark.assets.svg b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.dark.assets.svg new file mode 100644 index 0000000000..ba5c889b71 --- /dev/null +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.dark.assets.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.light.assets.svg b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.light.assets.svg new file mode 100644 index 0000000000..c1647ae48b --- /dev/null +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/meeting-apps.light.assets.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/use-enable-recording.ts b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/use-enable-recording.ts new file mode 100644 index 0000000000..b683e95c35 --- /dev/null +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/use-enable-recording.ts @@ -0,0 +1,49 @@ +import { useConfirmModal } from '@affine/component'; +import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks'; +import { MeetingSettingsService } from '@affine/core/modules/media/services/meeting-settings'; +import { useI18n } from '@affine/i18n'; +import track from '@affine/track'; +import { useService } from '@toeverything/infra'; + +export const useEnableRecording = () => { + const meetingSettingsService = useService(MeetingSettingsService); + const confirmModal = useConfirmModal(); + const t = useI18n(); + + const handleEnabledChange = useAsyncCallback( + async (checked: boolean) => { + try { + track.$.settingsPanel.meetings.toggleMeetingFeatureFlag({ + option: checked ? 'on' : 'off', + type: 'Meeting record', + }); + await meetingSettingsService.setEnabled(checked); + } catch { + confirmModal.openConfirmModal({ + title: + t['com.affine.settings.meetings.record.permission-modal.title'](), + description: + t[ + 'com.affine.settings.meetings.record.permission-modal.description' + ](), + onConfirm: async () => { + await meetingSettingsService.showRecordingPermissionSetting( + 'screen' + ); + }, + cancelText: t['com.affine.recording.dismiss'](), + confirmButtonOptions: { + variant: 'primary', + }, + confirmText: + t[ + 'com.affine.settings.meetings.record.permission-modal.open-setting' + ](), + }); + } + }, + [confirmModal, meetingSettingsService, t] + ); + + return handleEnabledChange; +}; diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.css.ts b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.css.ts new file mode 100644 index 0000000000..00379b428c --- /dev/null +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.css.ts @@ -0,0 +1,110 @@ +import { cssVar } from '@toeverything/theme'; +import { cssVarV2 } from '@toeverything/theme/v2'; +import { globalStyle, style } from '@vanilla-extract/css'; + +export const root = style({ + height: '100%', + position: 'absolute', + display: 'flex', + flexDirection: 'column', +}); + +export const titleWrapper = style({ + display: 'flex', + flexDirection: 'column', + gap: '8px', +}); + +export const title = style({ + display: 'flex', + fontSize: cssVar('fontH4'), + fontWeight: 600, + lineHeight: '30px', + whiteSpace: 'pre-wrap', + position: 'relative', +}); + +export const subtitle = style({ + display: 'inline-flex', + fontSize: cssVar('fontBase'), + fontWeight: 400, + lineHeight: '24px', + whiteSpace: 'pre-wrap', + color: cssVarV2('text/secondary'), +}); + +export const beta = style({ + fontSize: cssVar('fontXs'), + background: cssVarV2('chip/label/blue'), + padding: '0 8px', + borderRadius: '4px', + position: 'absolute', + right: 32, + top: 0, +}); + +export const meetingAppsWrapper = style({ + display: 'flex', + alignItems: 'center', + height: 100, + margin: '20px 0', +}); + +export const hintsContainer = style({ + display: 'flex', + flexDirection: 'column', + flex: 1, +}); + +export const hints = style({ + fontSize: cssVar('fontSm'), + lineHeight: '24px', + whiteSpace: 'pre-wrap', +}); + +globalStyle(`${hints} strong`, { + fontWeight: 600, +}); + +globalStyle(`${hints} ul`, { + padding: '12px 0', + marginLeft: 15, +}); + +globalStyle(`${hints} li`, { + listStyleType: 'disc', + padding: '6px 0', +}); + +globalStyle(`${hints} li::marker`, { + color: cssVarV2('block/list/header'), +}); + +export const learnMoreLink = style({ + fontSize: cssVar('fontXs'), + display: 'flex', + alignItems: 'center', + gap: '4px', + fontWeight: 500, + color: cssVarV2('text/primary'), +}); + +export const linkIcon = style({ + width: 16, + height: 16, + color: cssVarV2('icon/primary'), +}); + +export const betaFreePrompt = style({ + fontSize: cssVar('fontXs'), + color: cssVarV2('text/secondary'), +}); + +export const getStartedButton = style({ + marginTop: 'auto', + alignSelf: 'center', +}); + +globalStyle(`${betaFreePrompt} strong`, { + fontWeight: 700, +}); diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.tsx new file mode 100644 index 0000000000..5766b8b2e8 --- /dev/null +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/welcome-page.tsx @@ -0,0 +1,81 @@ +import { Button } from '@affine/component'; +import { MeetingSettingsService } from '@affine/core/modules/media/services/meeting-settings'; +import { Trans, useI18n } from '@affine/i18n'; +import { DualLinkIcon } from '@blocksuite/icons/rc'; +import { useService } from '@toeverything/infra'; +import { useTheme } from 'next-themes'; +import { useCallback } from 'react'; + +import meetingAppsDark from './meeting-apps.dark.assets.svg'; +import meetingAppsLight from './meeting-apps.light.assets.svg'; +import { useEnableRecording } from './use-enable-recording'; +import * as styles from './welcome-page.css'; + +export const MeetingsWelcomePage = () => { + const t = useI18n(); + const meetingSettingsService = useService(MeetingSettingsService); + const enableRecording = useEnableRecording(); + const getStartedClicked = useCallback(() => { + meetingSettingsService.setBetaDisclaimerAccepted(true); + enableRecording(true); + }, [meetingSettingsService, enableRecording]); + const theme = useTheme(); + const meetingApps = + theme.resolvedTheme === 'dark' ? meetingAppsDark : meetingAppsLight; + return ( +
+
+
+ {t['com.affine.settings.meetings.setting.welcome']()} +
Beta
+
+
+ {t['com.affine.settings.meetings.setting.prompt']()} +
+
+
+ meeting-apps +
+ +
+
+ , + ul:
+ +
+
+ ); +}; diff --git a/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/index.tsx index 126ee07bb3..e255503fca 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/index.tsx @@ -111,6 +111,7 @@ type SettingSidebarItemProps = { title: string; key: string; testId?: string; + beta?: boolean; } & HTMLAttributes; const SettingSidebarItem = ({ @@ -118,6 +119,7 @@ const SettingSidebarItem = ({ icon, title, testId, + beta, ...props }: SettingSidebarItemProps) => { return ( @@ -131,6 +133,7 @@ const SettingSidebarItem = ({ >
{icon}
{title}
+ {beta ?
Beta
: null} ); }; diff --git a/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/style.css.ts b/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/style.css.ts index 5c5aef91ee..fdac834180 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/style.css.ts +++ b/packages/frontend/core/src/desktop/dialogs/setting/setting-sidebar/style.css.ts @@ -89,6 +89,19 @@ export const sidebarSelectItemName = style({ flexGrow: 1, }); +export const sidebarSelectItemBeta = style({ + fontSize: cssVar('fontXs'), + color: cssVarV2('text/primary'), + background: cssVarV2('chip/label/blue'), + height: 20, + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + padding: '0 8px', + borderRadius: '4px', + transform: 'translateX(2px)', +}); + export const currentWorkspaceLabel = style({ width: '20px', height: '20px', diff --git a/packages/frontend/core/src/desktop/dialogs/setting/types.ts b/packages/frontend/core/src/desktop/dialogs/setting/types.ts index 6df4fd37d3..94caf3b9cd 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/types.ts +++ b/packages/frontend/core/src/desktop/dialogs/setting/types.ts @@ -11,4 +11,5 @@ export interface SettingSidebarItem { title: string; icon: ReactElement; testId: string; + beta?: boolean; } diff --git a/packages/frontend/core/src/modules/feature-flag/constant.ts b/packages/frontend/core/src/modules/feature-flag/constant.ts index 9bdfca573f..c5a5e09161 100644 --- a/packages/frontend/core/src/modules/feature-flag/constant.ts +++ b/packages/frontend/core/src/modules/feature-flag/constant.ts @@ -260,18 +260,6 @@ export const AFFINE_FLAGS = { configurable: isCanaryBuild, defaultState: false, }, - enable_meetings: { - category: 'affine', - displayName: - 'com.affine.settings.workspace.experimental-features.enable-meetings.name', - description: - 'com.affine.settings.workspace.experimental-features.enable-meetings.description', - configurable: !isMobile && environment.isMacOs && BUILD_CONFIG.isElectron, - feedbackType: 'discord', - feedbackLink: - 'https://discord.com/channels/959027316334407691/1358384103925350542', - defaultState: false, - }, // TODO(@L-Sun): remove this flag after the feature is released enable_embed_doc_with_alias: { category: 'blocksuite', diff --git a/packages/frontend/core/src/modules/media/entities/audio-attachment-block.ts b/packages/frontend/core/src/modules/media/entities/audio-attachment-block.ts index ed2092766e..3dc1b90ae4 100644 --- a/packages/frontend/core/src/modules/media/entities/audio-attachment-block.ts +++ b/packages/frontend/core/src/modules/media/entities/audio-attachment-block.ts @@ -16,6 +16,7 @@ import { cssVarV2 } from '@toeverything/theme/v2'; import type { WorkspaceService } from '../../workspace'; import type { AudioMediaManagerService } from '../services/audio-media-manager'; +import type { MeetingSettingsService } from '../services/meeting-settings'; import type { AudioMedia } from './audio-media'; import { AudioTranscriptionJob } from './audio-transcription-job'; import type { TranscriptionResult } from './types'; @@ -44,7 +45,8 @@ export class AudioAttachmentBlock extends Entity { readonly audioMedia: AudioMedia; constructor( readonly audioMediaManagerService: AudioMediaManagerService, - readonly workspaceService: WorkspaceService + readonly workspaceService: WorkspaceService, + readonly meetingSettingsService: MeetingSettingsService ) { super(); const mediaRef = audioMediaManagerService.ensureMediaEntity(this.props); @@ -256,7 +258,11 @@ export class AudioAttachmentBlock extends Entity { ); }; fillTranscription(result.segments); - await fillSummary(result.summary); - await fillActions(result.actions); + if (this.meetingSettingsService.settings.autoTranscriptionSummary) { + await fillSummary(result.summary); + } + if (this.meetingSettingsService.settings.autoTranscriptionTodo) { + await fillActions(result.actions); + } }; } diff --git a/packages/frontend/core/src/modules/media/index.ts b/packages/frontend/core/src/modules/media/index.ts index a38be034e1..e9ce8272a5 100644 --- a/packages/frontend/core/src/modules/media/index.ts +++ b/packages/frontend/core/src/modules/media/index.ts @@ -22,7 +22,11 @@ export function configureMediaModule(framework: Framework) { .service(MeetingSettingsService, [GlobalStateService]) .scope(WorkspaceScope) .entity(AudioMedia, [WorkspaceService]) - .entity(AudioAttachmentBlock, [AudioMediaManagerService, WorkspaceService]) + .entity(AudioAttachmentBlock, [ + AudioMediaManagerService, + WorkspaceService, + MeetingSettingsService, + ]) .entity(AudioTranscriptionJob, [ WorkspaceServerService, DefaultServerService, diff --git a/packages/frontend/core/src/modules/media/services/meeting-settings.ts b/packages/frontend/core/src/modules/media/services/meeting-settings.ts index dacd4dc8a2..2e8b49ac8a 100644 --- a/packages/frontend/core/src/modules/media/services/meeting-settings.ts +++ b/packages/frontend/core/src/modules/media/services/meeting-settings.ts @@ -12,8 +12,10 @@ const MEETING_SETTINGS_KEY: typeof MeetingSettingsKey = 'meetingSettings'; const defaultMeetingSettings: MeetingSettingsSchema = { enabled: false, + betaDisclaimerAccepted: false, recordingSavingMode: 'new-doc', - autoTranscription: true, + autoTranscriptionSummary: true, + autoTranscriptionTodo: true, recordingMode: 'prompt', }; @@ -41,6 +43,13 @@ export class MeetingSettingsService extends Service { return this.settings$.value; } + setBetaDisclaimerAccepted(accepted: boolean) { + this.globalStateService.globalState.set(MEETING_SETTINGS_KEY, { + ...this.settings$.value, + betaDisclaimerAccepted: accepted, + }); + } + // we do not want the caller to directly set the settings, // there could be some side effects when the settings are changed. async setEnabled(enabled: boolean) { @@ -91,10 +100,17 @@ export class MeetingSettingsService extends Service { }); } - setAutoTranscription(autoTranscription: boolean) { + setAutoSummary(autoSummary: boolean) { this.globalStateService.globalState.set(MEETING_SETTINGS_KEY, { ...this.settings$.value, - autoTranscription, + autoTranscriptionSummary: autoSummary, + }); + } + + setAutoTodo(autoTodo: boolean) { + this.globalStateService.globalState.set(MEETING_SETTINGS_KEY, { + ...this.settings$.value, + autoTranscriptionTodo: autoTodo, }); } diff --git a/packages/frontend/i18n/src/i18n-completenesses.json b/packages/frontend/i18n/src/i18n-completenesses.json index a095a239c7..e0a59b1b6c 100644 --- a/packages/frontend/i18n/src/i18n-completenesses.json +++ b/packages/frontend/i18n/src/i18n-completenesses.json @@ -14,7 +14,7 @@ "it-IT": 98, "it": 1, "ja": 98, - "ko": 57, + "ko": 56, "pl": 98, "pt-BR": 98, "ru": 98, diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts index b15f20299b..17fdc72a68 100644 --- a/packages/frontend/i18n/src/i18n.gen.ts +++ b/packages/frontend/i18n/src/i18n.gen.ts @@ -5389,6 +5389,19 @@ export function useAFFiNEI18N(): { * `Meetings` */ ["com.affine.settings.meetings"](): string; + /** + * `Beyond Recording + Your AI Meeting Assistant is Here` + */ + ["com.affine.settings.meetings.setting.welcome"](): string; + /** + * `Native Audio Capture, No Bots Required - Direct from Your Mac to Meeting Intelligence.` + */ + ["com.affine.settings.meetings.setting.prompt"](): string; + /** + * `Learn more` + */ + ["com.affine.settings.meetings.setting.welcome.learn-more"](): string; /** * `Enable meeting notes` */ @@ -5418,13 +5431,21 @@ export function useAFFiNEI18N(): { */ ["com.affine.settings.meetings.transcription.header"](): string; /** - * `Auto transcription` + * `AI auto summary` */ - ["com.affine.settings.meetings.transcription.auto-transcription"](): string; + ["com.affine.settings.meetings.transcription.auto-summary"](): string; /** - * `Automatically transcribe the meeting notes.` + * `Automatically generate a summary of the meeting notes.` */ - ["com.affine.settings.meetings.transcription.auto-transcription.description"](): string; + ["com.affine.settings.meetings.transcription.auto-summary.description"](): string; + /** + * `AI auto todo list` + */ + ["com.affine.settings.meetings.transcription.auto-todo"](): string; + /** + * `Automatically generate a todo list of the meeting notes.` + */ + ["com.affine.settings.meetings.transcription.auto-todo.description"](): string; /** * `Privacy & Security` */ @@ -8712,6 +8733,21 @@ export const TypedTrans: { ["1"]: JSX.Element; ["2"]: JSX.Element; }>>; + /** + * `Meeting Features Available Free in Beta Phase` + */ + ["com.affine.settings.meetings.setting.prompt.2"]: ComponentType, { + strong: JSX.Element; + }>>; + /** + * `Where AI meets your meetings - affine your collaboration. +
  • Extract Action Items & Key Insights Instantly
  • Smart Auto-Capture Starts With Your Meeting
  • Seamless Integration Across All Meeting Platforms
  • One Unified Space for All Your Meeting's Context
  • Your AI Assistant with Every Meeting Context Preserved
` + */ + ["com.affine.settings.meetings.setting.welcome.hints"]: ComponentType, { + strong: JSX.Element; + ul: JSX.Element; + li: JSX.Element; + }>>; /** * `Utilize the meeting notes and AI summarization features provided by AFFiNE. <1>Discuss more in the community.` */ diff --git a/packages/frontend/i18n/src/resources/ar.json b/packages/frontend/i18n/src/resources/ar.json index 3d2ffa21f2..30be50fc1c 100644 --- a/packages/frontend/i18n/src/resources/ar.json +++ b/packages/frontend/i18n/src/resources/ar.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "افتح التسجيلات المحفوظة", "com.affine.settings.meetings.record.open-saved-file.description": "افتح الملفات المسجلة المخزنة محليًا.", "com.affine.settings.meetings.transcription.header": "النسخ باستخدام الذكاء الاصطناعي", - "com.affine.settings.meetings.transcription.auto-transcription": "النسخ التلقائي", - "com.affine.settings.meetings.transcription.auto-transcription.description": "انسخ ملاحظات الاجتماع تلقائيًا.", "com.affine.settings.meetings.privacy.header": "الخصوصية والأمان", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "تسجيل الصوت من النظام والشاشة", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "تتطلب ميزة الاجتماع إذنًا للاستخدام.", diff --git a/packages/frontend/i18n/src/resources/de.json b/packages/frontend/i18n/src/resources/de.json index 5b3204b5be..eebb41f2f6 100644 --- a/packages/frontend/i18n/src/resources/de.json +++ b/packages/frontend/i18n/src/resources/de.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Gespeicherte Aufzeichnungen öffnen", "com.affine.settings.meetings.record.open-saved-file.description": "Öffne die lokal gespeicherten Aufzeichnungsdateien.", "com.affine.settings.meetings.transcription.header": "Transkription mit KI", - "com.affine.settings.meetings.transcription.auto-transcription": "Automatische Transkription", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Automatische Transkription der Besprechungsnotizen.", "com.affine.settings.meetings.privacy.header": "Datenschutz & Sicherheit", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Bildschirm- und Systemaudioaufnahme", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Für die Nutzung der Besprechungsfunktion ist eine Berechtigung erforderlich.", diff --git a/packages/frontend/i18n/src/resources/el-GR.json b/packages/frontend/i18n/src/resources/el-GR.json index 75e9d1ebb4..6d0e093bd8 100644 --- a/packages/frontend/i18n/src/resources/el-GR.json +++ b/packages/frontend/i18n/src/resources/el-GR.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Άνοιγμα αποθηκευμένων ηχογραφήσεων", "com.affine.settings.meetings.record.open-saved-file.description": "Άνοιγμα τοπικά αποθηκευμένων αρχείων ηχογράφησης.", "com.affine.settings.meetings.transcription.header": "Μεταγραφή με AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Αυτόματη μεταγραφή", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Αυτόματη μεταγραφή των σημειώσεων συνάντησης.", "com.affine.settings.meetings.privacy.header": "Απόρρητο & Ασφάλεια", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Ηχογράφηση Οθόνης & Συστήματος", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Η δυνατότητα Συνάντηση απαιτεί άδεια για χρήση.", diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index cd6c867d20..86557dc6c2 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1344,6 +1344,11 @@ "com.affine.settings.translucent-style": "Translucent UI on the sidebar", "com.affine.settings.translucent-style-description": "Use transparency effect on the sidebar.", "com.affine.settings.meetings": "Meetings", + "com.affine.settings.meetings.setting.welcome": "Beyond Recording\nYour AI Meeting Assistant is Here", + "com.affine.settings.meetings.setting.prompt": "Native Audio Capture, No Bots Required - Direct from Your Mac to Meeting Intelligence.", + "com.affine.settings.meetings.setting.prompt.2": "Meeting Features Available Free in Beta Phase", + "com.affine.settings.meetings.setting.welcome.hints": "Where AI meets your meetings - affine your collaboration.\n
  • Extract Action Items & Key Insights Instantly
  • Smart Auto-Capture Starts With Your Meeting
  • Seamless Integration Across All Meeting Platforms
  • One Unified Space for All Your Meeting's Context
  • Your AI Assistant with Every Meeting Context Preserved
", + "com.affine.settings.meetings.setting.welcome.learn-more": "Learn more", "com.affine.settings.meetings.enable.title": "Enable meeting notes", "com.affine.settings.meetings.enable.description": "Utilize the meeting notes and AI summarization features provided by AFFiNE. <1>Discuss more in the community.", "com.affine.settings.meetings.record.header": "Meeting recording", @@ -1352,8 +1357,10 @@ "com.affine.settings.meetings.record.open-saved-file": "Open saved recordings", "com.affine.settings.meetings.record.open-saved-file.description": "Open the locally stored recording files.", "com.affine.settings.meetings.transcription.header": "Transcription with AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Auto transcription", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Automatically transcribe the meeting notes.", + "com.affine.settings.meetings.transcription.auto-summary": "AI auto summary", + "com.affine.settings.meetings.transcription.auto-summary.description": "Automatically generate a summary of the meeting notes.", + "com.affine.settings.meetings.transcription.auto-todo": "AI auto todo list", + "com.affine.settings.meetings.transcription.auto-todo.description": "Automatically generate a todo list of the meeting notes.", "com.affine.settings.meetings.privacy.header": "Privacy & Security", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Screen & System audio recording", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "The Meeting feature requires permission to be used.", diff --git a/packages/frontend/i18n/src/resources/es.json b/packages/frontend/i18n/src/resources/es.json index 537bff2bf4..02810ab67b 100644 --- a/packages/frontend/i18n/src/resources/es.json +++ b/packages/frontend/i18n/src/resources/es.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Abrir grabaciones guardadas", "com.affine.settings.meetings.record.open-saved-file.description": "Abrir los archivos de grabación almacenados localmente.", "com.affine.settings.meetings.transcription.header": "Transcripción con IA", - "com.affine.settings.meetings.transcription.auto-transcription": "Transcripción automática", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Transcribe automáticamente las notas de la reunión.", "com.affine.settings.meetings.privacy.header": "Privacidad y seguridad", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Grabación de audio de pantalla y sistema", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "La función de reunión requiere permiso para ser utilizada.", diff --git a/packages/frontend/i18n/src/resources/fa.json b/packages/frontend/i18n/src/resources/fa.json index cd41998f3d..206ccac118 100644 --- a/packages/frontend/i18n/src/resources/fa.json +++ b/packages/frontend/i18n/src/resources/fa.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "باز کردن ضبط‌های ذخیره‌شده", "com.affine.settings.meetings.record.open-saved-file.description": "فایل‌های ضبط‌شده ذخیره‌شده به صورت محلی را باز کنید.", "com.affine.settings.meetings.transcription.header": "متن با AI", - "com.affine.settings.meetings.transcription.auto-transcription": "متن خودکار", - "com.affine.settings.meetings.transcription.auto-transcription.description": "یادداشت‌های جلسه را به صورت خودکار رونوشت کنید.", "com.affine.settings.meetings.privacy.header": "حریم خصوصی و امنیت", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "ضبط صدا و سیستم صفحه‌نمایش", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "برای استفاده از ویژگی جلسه به اجازه نیاز است.", diff --git a/packages/frontend/i18n/src/resources/fr.json b/packages/frontend/i18n/src/resources/fr.json index d1d9f1996c..adeb5897a4 100644 --- a/packages/frontend/i18n/src/resources/fr.json +++ b/packages/frontend/i18n/src/resources/fr.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Ouvrir les enregistrements sauvegardés", "com.affine.settings.meetings.record.open-saved-file.description": "Ouvrez les fichiers d'enregistrement stockés localement.", "com.affine.settings.meetings.transcription.header": "Transcription avec IA", - "com.affine.settings.meetings.transcription.auto-transcription": "Transcription automatique", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Transcrivez automatiquement les notes de la réunion.", "com.affine.settings.meetings.privacy.header": "Confidentialité et sécurité", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Enregistrement de l'écran et de l'audio système", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "La fonction de réunion nécessite une autorisation pour être utilisée.", diff --git a/packages/frontend/i18n/src/resources/it-IT.json b/packages/frontend/i18n/src/resources/it-IT.json index 608ed2533f..1832e2d0ba 100644 --- a/packages/frontend/i18n/src/resources/it-IT.json +++ b/packages/frontend/i18n/src/resources/it-IT.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Apri registrazioni salvate", "com.affine.settings.meetings.record.open-saved-file.description": "Apri i file di registrazione archiviati localmente.", "com.affine.settings.meetings.transcription.header": "Trascrizione con AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Trascrizione automatica", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Trascrivi automaticamente le note riunioni.", "com.affine.settings.meetings.privacy.header": "Privacy & Sicurezza", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Registrazione audio schermo e sistema", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "La funzione Riunione richiede un permesso per essere utilizzata.", diff --git a/packages/frontend/i18n/src/resources/ja.json b/packages/frontend/i18n/src/resources/ja.json index 42783c35d8..590a8ed90b 100644 --- a/packages/frontend/i18n/src/resources/ja.json +++ b/packages/frontend/i18n/src/resources/ja.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "保存された録音を開く", "com.affine.settings.meetings.record.open-saved-file.description": "ローカルに保存された録音ファイルを開く。", "com.affine.settings.meetings.transcription.header": "AIによる文字起こし", - "com.affine.settings.meetings.transcription.auto-transcription": "自動文字起こし", - "com.affine.settings.meetings.transcription.auto-transcription.description": "会議メモを自動的に文字起こしします。", "com.affine.settings.meetings.privacy.header": "プライバシー & セキュリティ", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "画面 & システム音声録音", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "会議機能の利用には許可が必要です。", diff --git a/packages/frontend/i18n/src/resources/pl.json b/packages/frontend/i18n/src/resources/pl.json index 301b9e3f25..e0eca8d5cc 100644 --- a/packages/frontend/i18n/src/resources/pl.json +++ b/packages/frontend/i18n/src/resources/pl.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Otwórz zapisane nagrania", "com.affine.settings.meetings.record.open-saved-file.description": "Otwórz lokalnie zapisane pliki nagrań.", "com.affine.settings.meetings.transcription.header": "Transkrypcja z AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Automatyczna transkrypcja", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Automatycznie transkrybuj notatki ze spotkania.", "com.affine.settings.meetings.privacy.header": "Prywatność i bezpieczeństwo", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Nagrywanie ekranu i dźwięku systemu", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Funkcja spotkań wymaga zezwolenia na użycie.", diff --git a/packages/frontend/i18n/src/resources/pt-BR.json b/packages/frontend/i18n/src/resources/pt-BR.json index 33856c9cd9..fede63b98d 100644 --- a/packages/frontend/i18n/src/resources/pt-BR.json +++ b/packages/frontend/i18n/src/resources/pt-BR.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Abrir gravações salvas", "com.affine.settings.meetings.record.open-saved-file.description": "Abra os arquivos de gravação armazenados localmente.", "com.affine.settings.meetings.transcription.header": "Transcrição com IA", - "com.affine.settings.meetings.transcription.auto-transcription": "Transcrição automática", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Transcreva automaticamente as notas da reunião.", "com.affine.settings.meetings.privacy.header": "Privacidade & Segurança", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Gravação de áudio de tela & sistema", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "O recurso de reunião requer permissão para ser usado.", diff --git a/packages/frontend/i18n/src/resources/ru.json b/packages/frontend/i18n/src/resources/ru.json index 39efd4236c..2903fea07a 100644 --- a/packages/frontend/i18n/src/resources/ru.json +++ b/packages/frontend/i18n/src/resources/ru.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Открыть сохраненные записи", "com.affine.settings.meetings.record.open-saved-file.description": "Открыть локально сохраненные файлы записи.", "com.affine.settings.meetings.transcription.header": "Транскрипция с ИИ", - "com.affine.settings.meetings.transcription.auto-transcription": "Автотранскрипция", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Автоматическая транскрипция заметок к встречам.", "com.affine.settings.meetings.privacy.header": "Конфиденциальность и безопасность", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Запись экрана и системного звука", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Для использования функции встреч требуется разрешение.", diff --git a/packages/frontend/i18n/src/resources/sv-SE.json b/packages/frontend/i18n/src/resources/sv-SE.json index defa2c0d49..1c1dd1dc53 100644 --- a/packages/frontend/i18n/src/resources/sv-SE.json +++ b/packages/frontend/i18n/src/resources/sv-SE.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Öppna sparade inspelningar", "com.affine.settings.meetings.record.open-saved-file.description": "Öppna de lokalt sparade inspelningsfilerna.", "com.affine.settings.meetings.transcription.header": "Transkription med AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Automatisk transkription", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Transkribera mötesanteckningarna automatiskt.", "com.affine.settings.meetings.privacy.header": "Sekretess & Säkerhet", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Skärm- & systemljudinspelning", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Mötesfunktionen kräver tillstånd för att användas.", diff --git a/packages/frontend/i18n/src/resources/uk.json b/packages/frontend/i18n/src/resources/uk.json index 3c6fc9e5f7..d887eada02 100644 --- a/packages/frontend/i18n/src/resources/uk.json +++ b/packages/frontend/i18n/src/resources/uk.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "Відкрити збережені записи", "com.affine.settings.meetings.record.open-saved-file.description": "Відкрити локально збережені файли записів.", "com.affine.settings.meetings.transcription.header": "Транскрипція з AI", - "com.affine.settings.meetings.transcription.auto-transcription": "Авто транскрипція", - "com.affine.settings.meetings.transcription.auto-transcription.description": "Автоматично транскрибувати замітки зустрічей.", "com.affine.settings.meetings.privacy.header": "Конфіденційність та безпека", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "Запис екрану та системного аудіо", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "Для використання функції зустрічей потрібен дозвіл.", diff --git a/packages/frontend/i18n/src/resources/zh-Hans.json b/packages/frontend/i18n/src/resources/zh-Hans.json index e1436192ab..48841376e3 100644 --- a/packages/frontend/i18n/src/resources/zh-Hans.json +++ b/packages/frontend/i18n/src/resources/zh-Hans.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "打开已保存的录制", "com.affine.settings.meetings.record.open-saved-file.description": "打开本地存储的录制文件。", "com.affine.settings.meetings.transcription.header": "AI转录", - "com.affine.settings.meetings.transcription.auto-transcription": "自动转录", - "com.affine.settings.meetings.transcription.auto-transcription.description": "自动转录会议记录。", "com.affine.settings.meetings.privacy.header": "隐私 & 安全", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "屏幕和系统音频录制", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "会议功能需要权限才能使用。", diff --git a/packages/frontend/i18n/src/resources/zh-Hant.json b/packages/frontend/i18n/src/resources/zh-Hant.json index cda9563ca4..06184cde83 100644 --- a/packages/frontend/i18n/src/resources/zh-Hant.json +++ b/packages/frontend/i18n/src/resources/zh-Hant.json @@ -1338,8 +1338,6 @@ "com.affine.settings.meetings.record.open-saved-file": "打開已保存的錄音", "com.affine.settings.meetings.record.open-saved-file.description": "打開本地存儲的錄音文件。", "com.affine.settings.meetings.transcription.header": "AI 轉錄", - "com.affine.settings.meetings.transcription.auto-transcription": "自動轉錄", - "com.affine.settings.meetings.transcription.auto-transcription.description": "自動轉錄會議筆記。", "com.affine.settings.meetings.privacy.header": "隱私與安全", "com.affine.settings.meetings.privacy.screen-system-audio-recording": "屏幕和系統音頻錄音", "com.affine.settings.meetings.privacy.screen-system-audio-recording.description": "需要許可才能使用會議功能。",