Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: launch review 0.5.9 #5443

Merged
merged 15 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/flutter_build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/flutter_integration_test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions frontend/appflowy_flutter/integration_test/shared/base.dart
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -20,15 +23,14 @@ 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';
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(
Expand Down Expand Up @@ -211,6 +213,10 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
style: styleCustomizer.selectionMenuStyleBuilder(),
).handler(editorState);

AFFocusManager? focusManager;

void _loseFocus() => widget.editorState.selection = null;

@override
void initState() {
super.initState();
Expand Down Expand Up @@ -251,17 +257,35 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
// 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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class _EmbedUrl extends StatefulWidget {

class _EmbedUrlState extends State<_EmbedUrl> {
bool isUrlValid = true;
bool isYouTubeError = false;
String inputText = '';

@override
Expand All @@ -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(
Expand All @@ -86,6 +94,7 @@ class _EmbedUrlState extends State<_EmbedUrl> {
return widget.onSubmit(inputText);
}

isYouTubeError = youtubeUrlRegex.hasMatch(inputText);
setState(() => isUrlValid = false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
@@ -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>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -67,62 +68,68 @@ class DesktopHomeScreen extends StatelessWidget {
return const WorkspaceFailedScreen();
}

return MultiBlocProvider(
key: ValueKey(userProfile.id),
providers: [
BlocProvider<ReminderBloc>.value(value: getIt<ReminderBloc>()),
BlocProvider<TabsBloc>.value(value: getIt<TabsBloc>()),
BlocProvider<HomeBloc>(
create: (_) =>
HomeBloc(workspaceSetting)..add(const HomeEvent.initial()),
),
BlocProvider<HomeSettingBloc>(
create: (_) => HomeSettingBloc(
workspaceSetting,
context.read<AppearanceSettingsCubit>(),
context.widthPx,
)..add(const HomeSettingEvent.initial()),
),
BlocProvider<FavoriteBloc>(
create: (context) =>
FavoriteBloc()..add(const FavoriteEvent.initial()),
),
],
child: Scaffold(
floatingActionButton: enableMemoryLeakDetect
? const FloatingActionButton(
onPressed: dumpMemoryLeak,
child: Icon(Icons.memory),
)
: null,
body: BlocListener<HomeBloc, HomeState>(
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<TabsBloc>().state.currentPageManager;
return AFFocusManager(
child: MultiBlocProvider(
key: ValueKey(userProfile.id),
providers: [
BlocProvider<ReminderBloc>.value(value: getIt<ReminderBloc>()),
BlocProvider<TabsBloc>.value(value: getIt<TabsBloc>()),
BlocProvider<HomeBloc>(
create: (_) =>
HomeBloc(workspaceSetting)..add(const HomeEvent.initial()),
),
BlocProvider<HomeSettingBloc>(
create: (_) => HomeSettingBloc(
workspaceSetting,
context.read<AppearanceSettingsCubit>(),
context.widthPx,
)..add(const HomeSettingEvent.initial()),
),
BlocProvider<FavoriteBloc>(
create: (context) =>
FavoriteBloc()..add(const FavoriteEvent.initial()),
),
],
child: Scaffold(
floatingActionButton: enableMemoryLeakDetect
? const FloatingActionButton(
onPressed: dumpMemoryLeak,
child: Icon(Icons.memory),
)
: null,
body: BlocListener<HomeBloc, HomeState>(
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<TabsBloc>().state.currentPageManager;

if (currentPageManager.plugin.pluginType ==
PluginType.blank) {
getIt<TabsBloc>().add(
TabsEvent.openPlugin(plugin: view.plugin()),
);
if (currentPageManager.plugin.pluginType ==
PluginType.blank) {
getIt<TabsBloc>().add(
TabsEvent.openPlugin(plugin: view.plugin()),
);
}
}
}
},
child: BlocBuilder<HomeSettingBloc, HomeSettingState>(
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<HomeSettingBloc, HomeSettingState>(
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,
),
),
),
),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -54,13 +55,24 @@ class _HomeHotKeysState extends State<HomeHotKeys> {
final windowSizeManager = WindowSizeManager();

late final items = [
// Collapse sidebar menu
// Collapse sidebar menu (using slash)
HotKeyItem(
hotKey: HotKey(
KeyCode.backslash,
modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control],
scope: HotKeyScope.inapp,
),
keyDownHandler: (_) => context
.read<HomeSettingBloc>()
.add(const HomeSettingEvent.collapseMenu()),
),

// Collapse sidebar menu (using .)
HotKeyItem(
hotKey: HotKey(
Platform.isMacOS ? KeyCode.period : KeyCode.backslash,
KeyCode.period,
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<HomeSettingBloc>()
Expand Down
Loading
Loading