diff --git a/.github/actions/flutter_build/action.yml b/.github/actions/flutter_build/action.yml index 81b2845949..66bfce44a5 100644 --- a/.github/actions/flutter_build/action.yml +++ b/.github/actions/flutter_build/action.yml @@ -63,7 +63,7 @@ runs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev libmpv-dev mpv elif [ "$RUNNER_OS" == "Windows" ]; then vcpkg integrate install elif [ "$RUNNER_OS" == "macOS" ]; then diff --git a/.github/actions/flutter_integration_test/action.yml b/.github/actions/flutter_integration_test/action.yml index 6df3ec005d..63066e0f38 100644 --- a/.github/actions/flutter_integration_test/action.yml +++ b/.github/actions/flutter_integration_test/action.yml @@ -52,7 +52,7 @@ runs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list sudo apt-get update - sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev network-manager + sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev network-manager libmpv-dev mpv shell: bash - name: Enable Flutter Desktop diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e91d95f969..3c589b2611 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -367,8 +367,8 @@ jobs: sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub sudo apt-get update sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev - sudo apt-get install keybinder-3.0 libnotify-dev - sudo apt-get -y install alien + sudo apt-get install keybinder-3.0 + sudo apt-get install -y alien libnotify-dev libmpv-dev mpv source $HOME/.cargo/env cargo install --force cargo-make cargo install --force duckscript_cli diff --git a/frontend/appflowy_flutter/integration_test/shared/base.dart b/frontend/appflowy_flutter/integration_test/shared/base.dart index ab72247c24..bd2577b96c 100644 --- a/frontend/appflowy_flutter/integration_test/shared/base.dart +++ b/frontend/appflowy_flutter/integration_test/shared/base.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:io'; +import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/services.dart'; @@ -36,6 +37,8 @@ extension AppFlowyTestBase on WidgetTester { AuthenticatorType? cloudType, String? email, }) async { + VideoBlockKit.ensureInitialized(); + if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) { // Set the window size await binding.setSurfaceSize(windowSize); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 996aa4ced1..2199d0bb3b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -1,5 +1,8 @@ import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; @@ -20,6 +23,7 @@ import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart'; import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; @@ -27,8 +31,6 @@ import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; final codeBlockLocalization = CodeBlockLocalizations( @@ -211,6 +213,10 @@ class _AppFlowyEditorPageState extends State { style: styleCustomizer.selectionMenuStyleBuilder(), ).handler(editorState); + AFFocusManager? focusManager; + + void _loseFocus() => widget.editorState.selection = null; + @override void initState() { super.initState(); @@ -251,17 +257,35 @@ class _AppFlowyEditorPageState extends State { // customize the dynamic theme color _customizeBlockComponentBackgroundColorDecorator(); - if (widget.initialSelection != null) { - WidgetsBinding.instance.addPostFrameCallback((_) { - widget.editorState.updateSelectionWithReason( - widget.initialSelection, - ); - }); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) { + return; + } + + focusManager = AFFocusManager.maybeOf(context); + focusManager?.loseFocusNotifier.addListener(_loseFocus); + + if (widget.initialSelection != null) { + widget.editorState.updateSelectionWithReason(widget.initialSelection); + } + }); + } + + @override + void didChangeDependencies() { + final currFocusManager = AFFocusManager.maybeOf(context); + if (focusManager != currFocusManager) { + focusManager?.loseFocusNotifier.removeListener(_loseFocus); + focusManager = currFocusManager; + focusManager?.loseFocusNotifier.addListener(_loseFocus); } + super.didChangeDependencies(); } @override void dispose() { + focusManager?.loseFocusNotifier.removeListener(_loseFocus); + if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) { viewInfoBloc.add(const ViewInfoEvent.unregisterEditorState()); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart index 2b2752e3f5..83fa36ceff 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/video/upload_video_menu.dart @@ -45,6 +45,7 @@ class _EmbedUrl extends StatefulWidget { class _EmbedUrlState extends State<_EmbedUrl> { bool isUrlValid = true; + bool isYouTubeError = false; String inputText = ''; @override @@ -60,11 +61,18 @@ class _EmbedUrlState extends State<_EmbedUrl> { if (!isUrlValid) ...[ const VSpace(8), FlowyText( - LocaleKeys.document_plugins_video_invalidVideoUrl.tr(), + isYouTubeError + ? LocaleKeys.document_plugins_video_invalidVideoUrlYouTube.tr() + : LocaleKeys.document_plugins_video_invalidVideoUrl.tr(), color: Theme.of(context).colorScheme.error, ), ], const VSpace(8), + FlowyText( + LocaleKeys.document_plugins_video_supportedFormats.tr(), + color: Theme.of(context).hintColor, + ), + const VSpace(8), SizedBox( width: 160, child: FlowyButton( @@ -86,6 +94,7 @@ class _EmbedUrlState extends State<_EmbedUrl> { return widget.onSubmit(inputText); } + isYouTubeError = youtubeUrlRegex.hasMatch(inputText); setState(() => isUrlValid = false); } diff --git a/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart b/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart index ea5da4f44a..fb9cd9f226 100644 --- a/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart +++ b/frontend/appflowy_flutter/lib/shared/patterns/common_patterns.dart @@ -22,6 +22,11 @@ const _videoUrlPattern = r'(https?:\/\/)([^\s(["<,>/]*)(\/)[^\s[",><]*(.mp4|.mov|.avi|.webm|.flv|.m4v|.mpeg|.h264)(\?[^\s[",><]*)?'; final videoUrlRegex = RegExp(_videoUrlPattern); +/// This pattern matches both youtube.com and shortened youtu.be urls. +/// +const _youtubeUrlPattern = r'^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/'; +final youtubeUrlRegex = RegExp(_youtubeUrlPattern); + const _appflowyCloudUrlPattern = r'^(https:\/\/)(.*)(\.appflowy\.cloud\/)(.*)'; final appflowyCloudUrlRegex = RegExp(_appflowyCloudUrlPattern); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart new file mode 100644 index 0000000000..17d09b6821 --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/af_focus_manager.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +/// Simple ChangeNotifier that can be listened to, notifies the +/// application on events that should trigger focus loss. +/// +/// Eg. lose focus in AppFlowyEditor +/// +abstract class ShouldLoseFocus with ChangeNotifier {} + +/// Private implementation to allow the [AFFocusManager] to +/// call [notifyListeners] without being directly invokable. +/// +class _ShouldLoseFocusImpl extends ShouldLoseFocus { + void notify() => notifyListeners(); +} + +class AFFocusManager extends InheritedWidget { + AFFocusManager({super.key, required super.child}); + + final ShouldLoseFocus loseFocusNotifier = _ShouldLoseFocusImpl(); + + void notifyLoseFocus() { + (loseFocusNotifier as _ShouldLoseFocusImpl).notify(); + } + + @override + bool updateShouldNotify(covariant InheritedWidget oldWidget) => false; + + static AFFocusManager of(BuildContext context) { + final AFFocusManager? result = + context.dependOnInheritedWidgetOfExactType(); + + assert(result != null, "AFFocusManager could not be found"); + return result!; + } + + static AFFocusManager? maybeOf(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart index e7b74ef4e9..6fce01aabc 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart @@ -15,6 +15,7 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_service.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart'; @@ -67,62 +68,68 @@ class DesktopHomeScreen extends StatelessWidget { return const WorkspaceFailedScreen(); } - return MultiBlocProvider( - key: ValueKey(userProfile.id), - providers: [ - BlocProvider.value(value: getIt()), - BlocProvider.value(value: getIt()), - BlocProvider( - create: (_) => - HomeBloc(workspaceSetting)..add(const HomeEvent.initial()), - ), - BlocProvider( - create: (_) => HomeSettingBloc( - workspaceSetting, - context.read(), - context.widthPx, - )..add(const HomeSettingEvent.initial()), - ), - BlocProvider( - create: (context) => - FavoriteBloc()..add(const FavoriteEvent.initial()), - ), - ], - child: Scaffold( - floatingActionButton: enableMemoryLeakDetect - ? const FloatingActionButton( - onPressed: dumpMemoryLeak, - child: Icon(Icons.memory), - ) - : null, - body: BlocListener( - listenWhen: (p, c) => p.latestView != c.latestView, - listener: (context, state) { - final view = state.latestView; - if (view != null) { - // Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null. - // All opened widgets that display on the home screen are in the form of plugins. There is a list of built-in plugins defined in the [PluginType] enum, including board, grid and trash. - final currentPageManager = - context.read().state.currentPageManager; + return AFFocusManager( + child: MultiBlocProvider( + key: ValueKey(userProfile.id), + providers: [ + BlocProvider.value(value: getIt()), + BlocProvider.value(value: getIt()), + BlocProvider( + create: (_) => + HomeBloc(workspaceSetting)..add(const HomeEvent.initial()), + ), + BlocProvider( + create: (_) => HomeSettingBloc( + workspaceSetting, + context.read(), + context.widthPx, + )..add(const HomeSettingEvent.initial()), + ), + BlocProvider( + create: (context) => + FavoriteBloc()..add(const FavoriteEvent.initial()), + ), + ], + child: Scaffold( + floatingActionButton: enableMemoryLeakDetect + ? const FloatingActionButton( + onPressed: dumpMemoryLeak, + child: Icon(Icons.memory), + ) + : null, + body: BlocListener( + listenWhen: (p, c) => p.latestView != c.latestView, + listener: (context, state) { + final view = state.latestView; + if (view != null) { + // Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null. + // All opened widgets that display on the home screen are in the form of plugins. There is a list of built-in plugins defined in the [PluginType] enum, including board, grid and trash. + final currentPageManager = + context.read().state.currentPageManager; - if (currentPageManager.plugin.pluginType == - PluginType.blank) { - getIt().add( - TabsEvent.openPlugin(plugin: view.plugin()), - ); + if (currentPageManager.plugin.pluginType == + PluginType.blank) { + getIt().add( + TabsEvent.openPlugin(plugin: view.plugin()), + ); + } } - } - }, - child: BlocBuilder( - buildWhen: (previous, current) => previous != current, - builder: (context, state) => BlocProvider( - create: (_) => UserWorkspaceBloc(userProfile: userProfile) - ..add(const UserWorkspaceEvent.initial()), - child: HomeHotKeys( - userProfile: userProfile, - child: FlowyContainer( - Theme.of(context).colorScheme.surface, - child: _buildBody(context, userProfile, workspaceSetting), + }, + child: BlocBuilder( + buildWhen: (previous, current) => previous != current, + builder: (context, state) => BlocProvider( + create: (_) => UserWorkspaceBloc(userProfile: userProfile) + ..add(const UserWorkspaceEvent.initial()), + child: HomeHotKeys( + userProfile: userProfile, + child: FlowyContainer( + Theme.of(context).colorScheme.surface, + child: _buildBody( + context, + userProfile, + workspaceSetting, + ), + ), ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart index b2d9945b2b..3ac4274fb7 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/hotkeys.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/tasks/app_window_size_manager.dart'; import 'package:appflowy/workspace/application/home/home_setting_bloc.dart'; @@ -9,7 +11,6 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; -import 'package:flutter/material.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:provider/provider.dart'; import 'package:scaled_app/scaled_app.dart'; @@ -54,13 +55,24 @@ class _HomeHotKeysState extends State { final windowSizeManager = WindowSizeManager(); late final items = [ - // Collapse sidebar menu + // Collapse sidebar menu (using slash) HotKeyItem( hotKey: HotKey( - Platform.isMacOS ? KeyCode.period : KeyCode.backslash, + KeyCode.backslash, modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], - // Set hotkey scope (default is HotKeyScope.system) - scope: HotKeyScope.inapp, // Set as inapp-wide hotkey. + scope: HotKeyScope.inapp, + ), + keyDownHandler: (_) => context + .read() + .add(const HomeSettingEvent.collapseMenu()), + ), + + // Collapse sidebar menu (using .) + HotKeyItem( + hotKey: HotKey( + KeyCode.period, + modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], + scope: HotKeyScope.inapp, ), keyDownHandler: (_) => context .read() diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart index 40c2167626..2fc1b311ad 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart @@ -1,4 +1,7 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; @@ -11,7 +14,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FavoriteMoreActions extends StatelessWidget { @@ -53,7 +55,7 @@ class FavoriteMoreActions extends StatelessWidget { break; case ViewMoreActionType.openInNewTab: - context.read().openTab(view); + getIt().openTab(view); break; case ViewMoreActionType.delete: case ViewMoreActionType.duplicate: diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart index 8c6d9c5cf7..20c2338ebc 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart @@ -1,8 +1,11 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart'; @@ -13,7 +16,6 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; @@ -63,35 +65,37 @@ class UserSettingButton extends StatelessWidget { } } -void showSettingsDialog(BuildContext context, UserProfilePB userProfile) => - showDialog( - context: context, - builder: (dialogContext) => MultiBlocProvider( - key: _settingsDialogKey, - providers: [ - BlocProvider.value( - value: BlocProvider.of(dialogContext), - ), - BlocProvider.value(value: context.read()), - ], - child: SettingsDialog( - userProfile, - didLogout: () async { - // Pop the dialog using the dialog context - Navigator.of(dialogContext).pop(); - await runAppFlowy(); - }, - dismissDialog: () { - if (Navigator.of(dialogContext).canPop()) { - return Navigator.of(dialogContext).pop(); - } - Log.warn("Can't pop dialog context"); - }, - restartApp: () async { - // Pop the dialog using the dialog context - Navigator.of(dialogContext).pop(); - await runAppFlowy(); - }, +void showSettingsDialog(BuildContext context, UserProfilePB userProfile) { + AFFocusManager.of(context).notifyLoseFocus(); + showDialog( + context: context, + builder: (dialogContext) => MultiBlocProvider( + key: _settingsDialogKey, + providers: [ + BlocProvider.value( + value: BlocProvider.of(dialogContext), ), + BlocProvider.value(value: context.read()), + ], + child: SettingsDialog( + userProfile, + didLogout: () async { + // Pop the dialog using the dialog context + Navigator.of(dialogContext).pop(); + await runAppFlowy(); + }, + dismissDialog: () { + if (Navigator.of(dialogContext).canPop()) { + return Navigator.of(dialogContext).pop(); + } + Log.warn("Can't pop dialog context"); + }, + restartApp: () async { + // Pop the dialog using the dialog context + Navigator.of(dialogContext).pop(); + await runAppFlowy(); + }, ), - ); + ), + ); +} diff --git a/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h b/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h index 9d9128671c..78992141ca 100644 --- a/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h +++ b/frontend/appflowy_flutter/linux/flutter/dart_ffi/binding.h @@ -3,7 +3,7 @@ #include #include -int64_t init_sdk(char *data); +int64_t init_sdk(int64_t port, char *data); void async_event(int64_t port, const uint8_t *input, uintptr_t len); @@ -11,6 +11,8 @@ const uint8_t *sync_event(const uint8_t *input, uintptr_t len); int32_t set_stream_port(int64_t port); +int32_t set_log_stream_port(int64_t port); + void link_me_please(void); void rust_log(int64_t level, const char *data); diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 9504a20136..b5f2bae5a0 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -442,7 +442,7 @@ "manageDataPage": { "menuLabel": "Manage data", "title": "Manage data", - "description": "Manage data local storage or Import your existing data into @:appName. You can secure your data with end to end encryption.", + "description": "Manage data local storage or Import your existing data into @:appName.", "dataStorage": { "title": "File storage location", "tooltip": "The location where your files are stored", @@ -550,7 +550,7 @@ }, "showNotificationsIcon": { "label": "Show notifications icon", - "hint": "Turn off to hide notification icons in the app." + "hint": "Toggle off to hide the notification icon in the sidebar." } }, "appearance": { @@ -1143,10 +1143,11 @@ "video": { "label": "Video", "emptyLabel": "Add a video", - "placeholder": "Enter a link to a video", + "placeholder": "Paste the video link", "copiedToPasteBoard": "The video link has been copied to the clipboard", - "insertVideo": "Insert video", - "invalidVideoUrl": "Invalid video url, must be a valid file.", + "insertVideo": "Add video", + "invalidVideoUrl": "The source URL is not supported yet.", + "invalidVideoUrlYouTube": "YouTube is not supported yet.", "supportedFormats": "Supported formats: MP4, WebM, MOV, AVI, FLV, MPEG/M4V, H.264" } }, diff --git a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml index 5049ff5eb3..a0da34dec9 100644 --- a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml +++ b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml @@ -59,6 +59,7 @@ AppDir: - libwayland-cursor0:amd64 - libwayland-client0:amd64 - libwayland-egl1:amd64 + - libmpv-dev:amd64 - mpv:amd64 files: include: []