fix: launch review 0.5.9 (#5443)

* fix: lose focus in editor on open settings dialog

* fix: support CTRL+. for sidebar toggle

* fix: make notify method private

* fix: copy for video block

* fix: copy for notification setting

* fix: add libmpv to appimage builder

* fix: missing tabs bloc from context

* ci: add libmpv-dev to missing workflows

* fix: do not depend on inherited widget in dispose

* test: add media kit ensureInitialized to integration tests

* fix: use maybeOf for AFFocusManager

* fix: use pattern matching for youtube error

* fix: missed null-promise on convertion
This commit is contained in:
Mathias Mogensen 2024-06-02 14:52:20 +02:00 committed by GitHub
parent 2c0cdfa6c5
commit 4ad7c48b25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 221 additions and 111 deletions

View File

@ -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/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 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 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 elif [ "$RUNNER_OS" == "Windows" ]; then
vcpkg integrate install vcpkg integrate install
elif [ "$RUNNER_OS" == "macOS" ]; then elif [ "$RUNNER_OS" == "macOS" ]; then

View File

@ -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/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 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 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 shell: bash
- name: Enable Flutter Desktop - name: Enable Flutter Desktop

View File

@ -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 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 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 -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 install keybinder-3.0
sudo apt-get -y install alien sudo apt-get install -y alien libnotify-dev libmpv-dev mpv
source $HOME/.cargo/env source $HOME/.cargo/env
cargo install --force cargo-make cargo install --force cargo-make
cargo install --force duckscript_cli cargo install --force duckscript_cli

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -36,6 +37,8 @@ extension AppFlowyTestBase on WidgetTester {
AuthenticatorType? cloudType, AuthenticatorType? cloudType,
String? email, String? email,
}) async { }) async {
VideoBlockKit.ensureInitialized();
if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) { if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
// Set the window size // Set the window size
await binding.setSurfaceSize(windowSize); await binding.setSurfaceSize(windowSize);

View File

@ -1,5 +1,8 @@
import 'dart:ui' as ui; 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/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/application/document_bloc.dart'; import 'package:appflowy/plugins/document/application/document_bloc.dart';
import 'package:appflowy/plugins/document/presentation/editor_configuration.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/appearance/appearance_cubit.dart';
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.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/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/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.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:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.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'; import 'package:flutter_bloc/flutter_bloc.dart';
final codeBlockLocalization = CodeBlockLocalizations( final codeBlockLocalization = CodeBlockLocalizations(
@ -211,6 +213,10 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
style: styleCustomizer.selectionMenuStyleBuilder(), style: styleCustomizer.selectionMenuStyleBuilder(),
).handler(editorState); ).handler(editorState);
AFFocusManager? focusManager;
void _loseFocus() => widget.editorState.selection = null;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -251,17 +257,35 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
// customize the dynamic theme color // customize the dynamic theme color
_customizeBlockComponentBackgroundColorDecorator(); _customizeBlockComponentBackgroundColorDecorator();
if (widget.initialSelection != null) { WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) {
widget.editorState.updateSelectionWithReason( return;
widget.initialSelection, }
);
}); 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 @override
void dispose() { void dispose() {
focusManager?.loseFocusNotifier.removeListener(_loseFocus);
if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) { if (widget.useViewInfoBloc && !viewInfoBloc.isClosed) {
viewInfoBloc.add(const ViewInfoEvent.unregisterEditorState()); viewInfoBloc.add(const ViewInfoEvent.unregisterEditorState());
} }

View File

@ -45,6 +45,7 @@ class _EmbedUrl extends StatefulWidget {
class _EmbedUrlState extends State<_EmbedUrl> { class _EmbedUrlState extends State<_EmbedUrl> {
bool isUrlValid = true; bool isUrlValid = true;
bool isYouTubeError = false;
String inputText = ''; String inputText = '';
@override @override
@ -60,11 +61,18 @@ class _EmbedUrlState extends State<_EmbedUrl> {
if (!isUrlValid) ...[ if (!isUrlValid) ...[
const VSpace(8), const VSpace(8),
FlowyText( 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, color: Theme.of(context).colorScheme.error,
), ),
], ],
const VSpace(8), const VSpace(8),
FlowyText(
LocaleKeys.document_plugins_video_supportedFormats.tr(),
color: Theme.of(context).hintColor,
),
const VSpace(8),
SizedBox( SizedBox(
width: 160, width: 160,
child: FlowyButton( child: FlowyButton(
@ -86,6 +94,7 @@ class _EmbedUrlState extends State<_EmbedUrl> {
return widget.onSubmit(inputText); return widget.onSubmit(inputText);
} }
isYouTubeError = youtubeUrlRegex.hasMatch(inputText);
setState(() => isUrlValid = false); setState(() => isUrlValid = false);
} }

View File

@ -22,6 +22,11 @@ const _videoUrlPattern =
r'(https?:\/\/)([^\s(["<,>/]*)(\/)[^\s[",><]*(.mp4|.mov|.avi|.webm|.flv|.m4v|.mpeg|.h264)(\?[^\s[",><]*)?'; r'(https?:\/\/)([^\s(["<,>/]*)(\/)[^\s[",><]*(.mp4|.mov|.avi|.webm|.flv|.m4v|.mpeg|.h264)(\?[^\s[",><]*)?';
final videoUrlRegex = RegExp(_videoUrlPattern); 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\/)(.*)'; const _appflowyCloudUrlPattern = r'^(https:\/\/)(.*)(\.appflowy\.cloud\/)(.*)';
final appflowyCloudUrlRegex = RegExp(_appflowyCloudUrlPattern); final appflowyCloudUrlRegex = RegExp(_appflowyCloudUrlPattern);

View File

@ -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<AFFocusManager>();
assert(result != null, "AFFocusManager could not be found");
return result!;
}
static AFFocusManager? maybeOf(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<AFFocusManager>();
}
}

View File

@ -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/user/user_workspace_bloc.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view/view_service.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/errors/workspace_failed_screen.dart';
import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart';
@ -67,62 +68,68 @@ class DesktopHomeScreen extends StatelessWidget {
return const WorkspaceFailedScreen(); return const WorkspaceFailedScreen();
} }
return MultiBlocProvider( return AFFocusManager(
key: ValueKey(userProfile.id), child: MultiBlocProvider(
providers: [ key: ValueKey(userProfile.id),
BlocProvider<ReminderBloc>.value(value: getIt<ReminderBloc>()), providers: [
BlocProvider<TabsBloc>.value(value: getIt<TabsBloc>()), BlocProvider<ReminderBloc>.value(value: getIt<ReminderBloc>()),
BlocProvider<HomeBloc>( BlocProvider<TabsBloc>.value(value: getIt<TabsBloc>()),
create: (_) => BlocProvider<HomeBloc>(
HomeBloc(workspaceSetting)..add(const HomeEvent.initial()), create: (_) =>
), HomeBloc(workspaceSetting)..add(const HomeEvent.initial()),
BlocProvider<HomeSettingBloc>( ),
create: (_) => HomeSettingBloc( BlocProvider<HomeSettingBloc>(
workspaceSetting, create: (_) => HomeSettingBloc(
context.read<AppearanceSettingsCubit>(), workspaceSetting,
context.widthPx, context.read<AppearanceSettingsCubit>(),
)..add(const HomeSettingEvent.initial()), context.widthPx,
), )..add(const HomeSettingEvent.initial()),
BlocProvider<FavoriteBloc>( ),
create: (context) => BlocProvider<FavoriteBloc>(
FavoriteBloc()..add(const FavoriteEvent.initial()), create: (context) =>
), FavoriteBloc()..add(const FavoriteEvent.initial()),
], ),
child: Scaffold( ],
floatingActionButton: enableMemoryLeakDetect child: Scaffold(
? const FloatingActionButton( floatingActionButton: enableMemoryLeakDetect
onPressed: dumpMemoryLeak, ? const FloatingActionButton(
child: Icon(Icons.memory), onPressed: dumpMemoryLeak,
) child: Icon(Icons.memory),
: null, )
body: BlocListener<HomeBloc, HomeState>( : null,
listenWhen: (p, c) => p.latestView != c.latestView, body: BlocListener<HomeBloc, HomeState>(
listener: (context, state) { listenWhen: (p, c) => p.latestView != c.latestView,
final view = state.latestView; listener: (context, state) {
if (view != null) { final view = state.latestView;
// Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null. if (view != 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. // Only open the last opened view if the [TabsState.currentPageManager] current opened plugin is blank and the last opened view is not null.
final currentPageManager = // 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.
context.read<TabsBloc>().state.currentPageManager; final currentPageManager =
context.read<TabsBloc>().state.currentPageManager;
if (currentPageManager.plugin.pluginType == if (currentPageManager.plugin.pluginType ==
PluginType.blank) { PluginType.blank) {
getIt<TabsBloc>().add( getIt<TabsBloc>().add(
TabsEvent.openPlugin(plugin: view.plugin()), TabsEvent.openPlugin(plugin: view.plugin()),
); );
}
} }
} },
}, child: BlocBuilder<HomeSettingBloc, HomeSettingState>(
child: BlocBuilder<HomeSettingBloc, HomeSettingState>( buildWhen: (previous, current) => previous != current,
buildWhen: (previous, current) => previous != current, builder: (context, state) => BlocProvider(
builder: (context, state) => BlocProvider( create: (_) => UserWorkspaceBloc(userProfile: userProfile)
create: (_) => UserWorkspaceBloc(userProfile: userProfile) ..add(const UserWorkspaceEvent.initial()),
..add(const UserWorkspaceEvent.initial()), child: HomeHotKeys(
child: HomeHotKeys( userProfile: userProfile,
userProfile: userProfile, child: FlowyContainer(
child: FlowyContainer( Theme.of(context).colorScheme.surface,
Theme.of(context).colorScheme.surface, child: _buildBody(
child: _buildBody(context, userProfile, workspaceSetting), context,
userProfile,
workspaceSetting,
),
),
), ),
), ),
), ),

View File

@ -1,5 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/startup/tasks/app_window_size_manager.dart'; import 'package:appflowy/startup/tasks/app_window_size_manager.dart';
import 'package:appflowy/workspace/application/home/home_setting_bloc.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/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart';
import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.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:hotkey_manager/hotkey_manager.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:scaled_app/scaled_app.dart'; import 'package:scaled_app/scaled_app.dart';
@ -54,13 +55,24 @@ class _HomeHotKeysState extends State<HomeHotKeys> {
final windowSizeManager = WindowSizeManager(); final windowSizeManager = WindowSizeManager();
late final items = [ late final items = [
// Collapse sidebar menu // Collapse sidebar menu (using slash)
HotKeyItem( HotKeyItem(
hotKey: HotKey( hotKey: HotKey(
Platform.isMacOS ? KeyCode.period : KeyCode.backslash, KeyCode.backslash,
modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control], modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control],
// Set hotkey scope (default is HotKeyScope.system) scope: HotKeyScope.inapp,
scope: HotKeyScope.inapp, // Set as inapp-wide hotkey. ),
keyDownHandler: (_) => context
.read<HomeSettingBloc>()
.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 keyDownHandler: (_) => context
.read<HomeSettingBloc>() .read<HomeSettingBloc>()

View File

@ -1,4 +1,7 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.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/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/tabs/tabs_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:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class FavoriteMoreActions extends StatelessWidget { class FavoriteMoreActions extends StatelessWidget {
@ -53,7 +55,7 @@ class FavoriteMoreActions extends StatelessWidget {
break; break;
case ViewMoreActionType.openInNewTab: case ViewMoreActionType.openInNewTab:
context.read<TabsBloc>().openTab(view); getIt<TabsBloc>().openTab(view);
break; break;
case ViewMoreActionType.delete: case ViewMoreActionType.delete:
case ViewMoreActionType.duplicate: case ViewMoreActionType.duplicate:

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/user/user_workspace_bloc.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/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
import 'package:appflowy/workspace/presentation/settings/settings_dialog.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:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';
@ -63,35 +65,37 @@ class UserSettingButton extends StatelessWidget {
} }
} }
void showSettingsDialog(BuildContext context, UserProfilePB userProfile) => void showSettingsDialog(BuildContext context, UserProfilePB userProfile) {
showDialog( AFFocusManager.of(context).notifyLoseFocus();
context: context, showDialog(
builder: (dialogContext) => MultiBlocProvider( context: context,
key: _settingsDialogKey, builder: (dialogContext) => MultiBlocProvider(
providers: [ key: _settingsDialogKey,
BlocProvider<DocumentAppearanceCubit>.value( providers: [
value: BlocProvider.of<DocumentAppearanceCubit>(dialogContext), BlocProvider<DocumentAppearanceCubit>.value(
), value: BlocProvider.of<DocumentAppearanceCubit>(dialogContext),
BlocProvider.value(value: context.read<UserWorkspaceBloc>()),
],
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();
},
), ),
BlocProvider.value(value: context.read<UserWorkspaceBloc>()),
],
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();
},
), ),
); ),
);
}

View File

@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
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); 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_stream_port(int64_t port);
int32_t set_log_stream_port(int64_t port);
void link_me_please(void); void link_me_please(void);
void rust_log(int64_t level, const char *data); void rust_log(int64_t level, const char *data);

View File

@ -442,7 +442,7 @@
"manageDataPage": { "manageDataPage": {
"menuLabel": "Manage data", "menuLabel": "Manage data",
"title": "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": { "dataStorage": {
"title": "File storage location", "title": "File storage location",
"tooltip": "The location where your files are stored", "tooltip": "The location where your files are stored",
@ -550,7 +550,7 @@
}, },
"showNotificationsIcon": { "showNotificationsIcon": {
"label": "Show notifications icon", "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": { "appearance": {
@ -1143,10 +1143,11 @@
"video": { "video": {
"label": "Video", "label": "Video",
"emptyLabel": "Add a 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", "copiedToPasteBoard": "The video link has been copied to the clipboard",
"insertVideo": "Insert video", "insertVideo": "Add video",
"invalidVideoUrl": "Invalid video url, must be a valid file.", "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" "supportedFormats": "Supported formats: MP4, WebM, MOV, AVI, FLV, MPEG/M4V, H.264"
} }
}, },

View File

@ -59,6 +59,7 @@ AppDir:
- libwayland-cursor0:amd64 - libwayland-cursor0:amd64
- libwayland-client0:amd64 - libwayland-client0:amd64
- libwayland-egl1:amd64 - libwayland-egl1:amd64
- libmpv-dev:amd64
- mpv:amd64 - mpv:amd64
files: files:
include: [] include: []