mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: merge with main
This commit is contained in:
2
.github/workflows/android_ci.yaml.bak
vendored
2
.github/workflows/android_ci.yaml.bak
vendored
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
# env:
|
# env:
|
||||||
# CARGO_TERM_COLOR: always
|
# CARGO_TERM_COLOR: always
|
||||||
# FLUTTER_VERSION: "3.19.0"
|
# FLUTTER_VERSION: "3.22.0"
|
||||||
# RUST_TOOLCHAIN: "1.77.2"
|
# RUST_TOOLCHAIN: "1.77.2"
|
||||||
# CARGO_MAKE_VERSION: "0.36.6"
|
# CARGO_MAKE_VERSION: "0.36.6"
|
||||||
|
|
||||||
|
2
.github/workflows/flutter_ci.yaml
vendored
2
.github/workflows/flutter_ci.yaml
vendored
@ -25,7 +25,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
FLUTTER_VERSION: "3.19.0"
|
FLUTTER_VERSION: "3.22.0"
|
||||||
RUST_TOOLCHAIN: "1.77.2"
|
RUST_TOOLCHAIN: "1.77.2"
|
||||||
CARGO_MAKE_VERSION: "0.36.6"
|
CARGO_MAKE_VERSION: "0.36.6"
|
||||||
|
|
||||||
|
2
.github/workflows/ios_ci.yaml
vendored
2
.github/workflows/ios_ci.yaml
vendored
@ -20,7 +20,7 @@ on:
|
|||||||
- "!frontend/appflowy_web_app/**"
|
- "!frontend/appflowy_web_app/**"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.19.0"
|
FLUTTER_VERSION: "3.22.0"
|
||||||
RUST_TOOLCHAIN: "1.77.2"
|
RUST_TOOLCHAIN: "1.77.2"
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.19.0"
|
FLUTTER_VERSION: "3.22.0"
|
||||||
RUST_TOOLCHAIN: "1.77.2"
|
RUST_TOOLCHAIN: "1.77.2"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
2
.github/workflows/rust_coverage.yml
vendored
2
.github/workflows/rust_coverage.yml
vendored
@ -10,7 +10,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
FLUTTER_VERSION: "3.19.0"
|
FLUTTER_VERSION: "3.22.0"
|
||||||
RUST_TOOLCHAIN: "1.77.2"
|
RUST_TOOLCHAIN: "1.77.2"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -1,4 +1,21 @@
|
|||||||
# Release Notes
|
# Release Notes
|
||||||
|
## Version 0.5.8 - 05/20/2024
|
||||||
|
### New Features
|
||||||
|
- Improvement to the Callout block to insert new lines
|
||||||
|
- New settings page "Manage data" replaced the "Files" page
|
||||||
|
- New settings page "Workspace" replaced the "Appearance" and "Language" pages
|
||||||
|
- A custom implementation of a title bar for Windows users
|
||||||
|
- Added support for selecting Cards in kanban and performing grouped keyboard shortcuts
|
||||||
|
- Added support for default system font family
|
||||||
|
- Support for scaling the application up/down using a keyboard shortcut (CMD/CTRL + PLUS/MINUS)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- Resolved and refined the UI on Mobile
|
||||||
|
- Resolved issue with text editing in database
|
||||||
|
- Improved appearance of empty text cells in kanban/calendar
|
||||||
|
- Resolved an issue where a page's more actions (delete, duplicate) did not work properly
|
||||||
|
- Resolved and inconsistency in padding on get started screen on Desktop
|
||||||
|
|
||||||
## Version 0.5.7 - 05/10/2024
|
## Version 0.5.7 - 05/10/2024
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
- Resolved page opening issue on Android.
|
- Resolved page opening issue on Android.
|
||||||
@ -88,7 +105,7 @@
|
|||||||
- Fixed a bug where newly created rows were not being automatically sorted.
|
- Fixed a bug where newly created rows were not being automatically sorted.
|
||||||
- Fixed issues related to deleting a sorting field or sort not removing existing sorts properly.
|
- Fixed issues related to deleting a sorting field or sort not removing existing sorts properly.
|
||||||
### Notes
|
### Notes
|
||||||
- Windows 7, Windows 8, and iOS 11 are not yet supported due to the upgrade to Flutter 3.19.0.
|
- Windows 7, Windows 8, and iOS 11 are not yet supported due to the upgrade to Flutter 3.22.0.
|
||||||
|
|
||||||
## Version 0.4.9 - 02/17/2024
|
## Version 0.4.9 - 02/17/2024
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
|||||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||||
LIB_NAME = "dart_ffi"
|
LIB_NAME = "dart_ffi"
|
||||||
APPFLOWY_VERSION = "0.5.7"
|
APPFLOWY_VERSION = "0.5.8"
|
||||||
FLUTTER_DESKTOP_FEATURES = "dart"
|
FLUTTER_DESKTOP_FEATURES = "dart"
|
||||||
PRODUCT_NAME = "AppFlowy"
|
PRODUCT_NAME = "AppFlowy"
|
||||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/env/cloud_env.dart';
|
import 'package:appflowy/env/cloud_env.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart';
|
||||||
@ -12,14 +10,15 @@ import 'package:appflowy/startup/startup.dart';
|
|||||||
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
||||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart';
|
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
|
import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/uuid.dart';
|
import 'package:flowy_infra/uuid.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
import '../../shared/database_test_op.dart';
|
||||||
|
import '../../shared/util.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('board field test', () {
|
||||||
|
testWidgets('change field type whithin card #5360', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
await tester.tapAnonymousSignInButton();
|
||||||
|
|
||||||
|
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||||
|
const name = 'Card 1';
|
||||||
|
final card1 = find.text(name);
|
||||||
|
await tester.tapButton(card1);
|
||||||
|
|
||||||
|
const fieldName = "test change field";
|
||||||
|
await tester.createField(
|
||||||
|
FieldType.RichText,
|
||||||
|
fieldName,
|
||||||
|
layout: ViewLayoutPB.Board,
|
||||||
|
);
|
||||||
|
await tester.tapButton(card1);
|
||||||
|
await tester.changeFieldTypeOfFieldWithName(
|
||||||
|
fieldName,
|
||||||
|
FieldType.Checkbox,
|
||||||
|
layout: ViewLayoutPB.Board,
|
||||||
|
);
|
||||||
|
await tester.hoverOnWidget(find.text('Card 2'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
import 'board_row_test.dart' as board_row_test;
|
|
||||||
import 'board_add_row_test.dart' as board_add_row_test;
|
import 'board_add_row_test.dart' as board_add_row_test;
|
||||||
import 'board_group_test.dart' as board_group_test;
|
import 'board_group_test.dart' as board_group_test;
|
||||||
|
import 'board_row_test.dart' as board_row_test;
|
||||||
|
|
||||||
void startTesting() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
// Board integration tests
|
// Board integration tests
|
||||||
|
@ -66,6 +66,7 @@ void main() {
|
|||||||
LogicalKeyboardKey.keyR,
|
LogicalKeyboardKey.keyR,
|
||||||
],
|
],
|
||||||
tester: tester,
|
tester: tester,
|
||||||
|
withKeyUp: true,
|
||||||
);
|
);
|
||||||
expect(first.attributes[blockComponentAlign], rightAlignmentKey);
|
expect(first.attributes[blockComponentAlign], rightAlignmentKey);
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ void main() {
|
|||||||
LogicalKeyboardKey.keyE,
|
LogicalKeyboardKey.keyE,
|
||||||
],
|
],
|
||||||
tester: tester,
|
tester: tester,
|
||||||
|
withKeyUp: true,
|
||||||
);
|
);
|
||||||
expect(first.attributes[blockComponentAlign], centerAlignmentKey);
|
expect(first.attributes[blockComponentAlign], centerAlignmentKey);
|
||||||
|
|
||||||
@ -88,6 +90,7 @@ void main() {
|
|||||||
LogicalKeyboardKey.keyL,
|
LogicalKeyboardKey.keyL,
|
||||||
],
|
],
|
||||||
tester: tester,
|
tester: tester,
|
||||||
|
withKeyUp: true,
|
||||||
);
|
);
|
||||||
expect(first.attributes[blockComponentAlign], leftAlignmentKey);
|
expect(first.attributes[blockComponentAlign], leftAlignmentKey);
|
||||||
});
|
});
|
||||||
|
@ -111,6 +111,7 @@ Future<void> triggerReferenceDocumentBySlashMenu(WidgetTester tester) async {
|
|||||||
LogicalKeyboardKey.enter,
|
LogicalKeyboardKey.enter,
|
||||||
],
|
],
|
||||||
tester: tester,
|
tester: tester,
|
||||||
|
withKeyUp: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -129,6 +130,7 @@ Future<void> enterDocumentText(WidgetTester tester) async {
|
|||||||
LogicalKeyboardKey.keyT,
|
LogicalKeyboardKey.keyT,
|
||||||
],
|
],
|
||||||
tester: tester,
|
tester: tester,
|
||||||
|
withKeyUp: true,
|
||||||
);
|
);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
import '../../shared/util.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('MoreViewActions', () {
|
||||||
|
testWidgets('can duplicate and delete from menu', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
await tester.tapAnonymousSignInButton();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final pageFinder = find.byType(ViewItem);
|
||||||
|
expect(pageFinder, findsNWidgets(1));
|
||||||
|
|
||||||
|
// Duplicate
|
||||||
|
await tester.openMoreViewActions();
|
||||||
|
await tester.duplicateByMoreViewActions();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(pageFinder, findsNWidgets(2));
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
await tester.openMoreViewActions();
|
||||||
|
await tester.deleteByMoreViewActions();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(pageFinder, findsNWidgets(1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -6,6 +6,9 @@ import 'document_copy_and_paste_test.dart' as document_copy_and_paste_test;
|
|||||||
import 'document_create_and_delete_test.dart'
|
import 'document_create_and_delete_test.dart'
|
||||||
as document_create_and_delete_test;
|
as document_create_and_delete_test;
|
||||||
import 'document_option_action_test.dart' as document_option_action_test;
|
import 'document_option_action_test.dart' as document_option_action_test;
|
||||||
|
import 'document_inline_page_reference_test.dart'
|
||||||
|
as document_inline_page_reference_test;
|
||||||
|
import 'document_more_actions_test.dart' as document_more_actions_test;
|
||||||
import 'document_text_direction_test.dart' as document_text_direction_test;
|
import 'document_text_direction_test.dart' as document_text_direction_test;
|
||||||
import 'document_with_cover_image_test.dart' as document_with_cover_image_test;
|
import 'document_with_cover_image_test.dart' as document_with_cover_image_test;
|
||||||
import 'document_with_database_test.dart' as document_with_database_test;
|
import 'document_with_database_test.dart' as document_with_database_test;
|
||||||
@ -16,8 +19,6 @@ import 'document_with_inline_page_test.dart' as document_with_inline_page_test;
|
|||||||
import 'document_with_outline_block_test.dart' as document_with_outline_block;
|
import 'document_with_outline_block_test.dart' as document_with_outline_block;
|
||||||
import 'document_with_toggle_list_test.dart' as document_with_toggle_list_test;
|
import 'document_with_toggle_list_test.dart' as document_with_toggle_list_test;
|
||||||
import 'edit_document_test.dart' as document_edit_test;
|
import 'edit_document_test.dart' as document_edit_test;
|
||||||
import 'document_inline_page_reference_test.dart'
|
|
||||||
as document_inline_page_reference_test;
|
|
||||||
|
|
||||||
void startTesting() {
|
void startTesting() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
@ -38,4 +39,5 @@ void startTesting() {
|
|||||||
document_option_action_test.main();
|
document_option_action_test.main();
|
||||||
document_with_image_block_test.main();
|
document_with_image_block_test.main();
|
||||||
document_inline_page_reference_test.main();
|
document_inline_page_reference_test.main();
|
||||||
|
document_more_actions_test.main();
|
||||||
}
|
}
|
||||||
|
@ -130,24 +130,24 @@ void main() {
|
|||||||
final searchEmojiTextField = find.byWidgetPredicate(
|
final searchEmojiTextField = find.byWidgetPredicate(
|
||||||
(widget) =>
|
(widget) =>
|
||||||
widget is TextField &&
|
widget is TextField &&
|
||||||
widget.decoration!.hintText == LocaleKeys.emoji_search.tr(),
|
widget.decoration!.hintText == LocaleKeys.search_label.tr(),
|
||||||
);
|
);
|
||||||
await tester.enterText(
|
await tester.enterText(
|
||||||
searchEmojiTextField,
|
searchEmojiTextField,
|
||||||
'hand',
|
'punch',
|
||||||
);
|
);
|
||||||
|
|
||||||
// change skin tone
|
// change skin tone
|
||||||
await tester.editor.changeEmojiSkinTone(EmojiSkinTone.dark);
|
await tester.editor.changeEmojiSkinTone(EmojiSkinTone.dark);
|
||||||
|
|
||||||
// select an icon with skin tone
|
// select an icon with skin tone
|
||||||
const hand = '👋🏿';
|
const punch = '👊🏿';
|
||||||
await tester.tapEmoji(hand);
|
await tester.tapEmoji(punch);
|
||||||
tester.expectToSeeDocumentIcon(hand);
|
tester.expectToSeeDocumentIcon(punch);
|
||||||
tester.expectViewHasIcon(
|
tester.expectViewHasIcon(
|
||||||
gettingStarted,
|
gettingStarted,
|
||||||
ViewLayoutPB.Document,
|
ViewLayoutPB.Document,
|
||||||
hand,
|
punch,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.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/presentation/home/menu/sidebar/sidebar_folder.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@ -12,8 +12,8 @@ void main() {
|
|||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
group('sidebar expand test', () {
|
group('sidebar expand test', () {
|
||||||
bool isExpanded({required FolderCategoryType type}) {
|
bool isExpanded({required FolderSpaceType type}) {
|
||||||
if (type == FolderCategoryType.private) {
|
if (type == FolderSpaceType.private) {
|
||||||
return find
|
return find
|
||||||
.descendant(
|
.descendant(
|
||||||
of: find.byType(PrivateSectionFolder),
|
of: find.byType(PrivateSectionFolder),
|
||||||
@ -30,19 +30,19 @@ void main() {
|
|||||||
await tester.tapAnonymousSignInButton();
|
await tester.tapAnonymousSignInButton();
|
||||||
|
|
||||||
// first time is expanded
|
// first time is expanded
|
||||||
expect(isExpanded(type: FolderCategoryType.private), true);
|
expect(isExpanded(type: FolderSpaceType.private), true);
|
||||||
|
|
||||||
// collapse the personal folder
|
// collapse the personal folder
|
||||||
await tester.tapButton(
|
await tester.tapButton(
|
||||||
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
||||||
);
|
);
|
||||||
expect(isExpanded(type: FolderCategoryType.private), false);
|
expect(isExpanded(type: FolderSpaceType.private), false);
|
||||||
|
|
||||||
// expand the personal folder
|
// expand the personal folder
|
||||||
await tester.tapButton(
|
await tester.tapButton(
|
||||||
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
||||||
);
|
);
|
||||||
expect(isExpanded(type: FolderCategoryType.private), true);
|
expect(isExpanded(type: FolderSpaceType.private), true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
@ -46,7 +46,7 @@ void main() {
|
|||||||
await tester.favoriteViewByName(names[1]);
|
await tester.favoriteViewByName(names[1]);
|
||||||
expect(
|
expect(
|
||||||
tester.findFavoritePageName(names[1]),
|
tester.findFavoritePageName(names[1]),
|
||||||
findsNWidgets(2),
|
findsNWidgets(1),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.unfavoriteViewByName(gettingStarted);
|
await tester.unfavoriteViewByName(gettingStarted);
|
||||||
@ -120,9 +120,9 @@ void main() {
|
|||||||
(widget) =>
|
(widget) =>
|
||||||
widget is SingleInnerViewItem &&
|
widget is SingleInnerViewItem &&
|
||||||
widget.view.isFavorite &&
|
widget.view.isFavorite &&
|
||||||
widget.categoryType == FolderCategoryType.favorite,
|
widget.spaceType == FolderSpaceType.favorite,
|
||||||
),
|
),
|
||||||
findsNWidgets(6),
|
findsNWidgets(3),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.hoverOnPageName(
|
await tester.hoverOnPageName(
|
||||||
@ -135,7 +135,7 @@ void main() {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
tester.findAllFavoritePages(),
|
tester.findAllFavoritePages(),
|
||||||
findsNWidgets(3),
|
findsNWidgets(2),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.hoverOnPageName(
|
await tester.hoverOnPageName(
|
||||||
@ -168,7 +168,7 @@ void main() {
|
|||||||
widget.isSelected != null &&
|
widget.isSelected != null &&
|
||||||
widget.isSelected!(),
|
widget.isSelected!(),
|
||||||
),
|
),
|
||||||
findsNWidgets(2),
|
findsNWidgets(1),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@ import 'sidebar_favorites_test.dart' as sidebar_favorite_test;
|
|||||||
import 'sidebar_icon_test.dart' as sidebar_icon_test;
|
import 'sidebar_icon_test.dart' as sidebar_icon_test;
|
||||||
import 'sidebar_test.dart' as sidebar_test;
|
import 'sidebar_test.dart' as sidebar_test;
|
||||||
|
|
||||||
void startTesting() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
// Sidebar integration tests
|
// Sidebar integration tests
|
||||||
|
@ -27,7 +27,7 @@ Future<void> runIntegration3OnDesktop() async {
|
|||||||
settings_test_runner.main();
|
settings_test_runner.main();
|
||||||
share_markdown_test.main();
|
share_markdown_test.main();
|
||||||
import_files_test.main();
|
import_files_test.main();
|
||||||
sidebar_test_runner.startTesting();
|
sidebar_test_runner.main();
|
||||||
board_test_runner.startTesting();
|
board_test_runner.main();
|
||||||
tabs_test.main();
|
tabs_test.main();
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import 'package:appflowy/shared/feature_flags.dart';
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/screens.dart';
|
import 'package:appflowy/user/presentation/screens/screens.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart';
|
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
|
||||||
@ -22,6 +22,8 @@ import 'package:appflowy/workspace/presentation/notifications/widgets/flowy_tab.
|
|||||||
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart';
|
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart';
|
||||||
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_tab_bar.dart';
|
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_tab_bar.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/more_view_actions.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/common_view_action.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
|
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
@ -57,6 +59,7 @@ extension CommonOperations on WidgetTester {
|
|||||||
/// Tap the + button on the home page.
|
/// Tap the + button on the home page.
|
||||||
Future<void> tapAddViewButton({
|
Future<void> tapAddViewButton({
|
||||||
String name = gettingStarted,
|
String name = gettingStarted,
|
||||||
|
ViewLayoutPB layout = ViewLayoutPB.Document,
|
||||||
}) async {
|
}) async {
|
||||||
await hoverOnPageName(
|
await hoverOnPageName(
|
||||||
name,
|
name,
|
||||||
@ -276,7 +279,7 @@ extension CommonOperations on WidgetTester {
|
|||||||
bool openAfterCreated = true,
|
bool openAfterCreated = true,
|
||||||
}) async {
|
}) async {
|
||||||
// create a new page
|
// create a new page
|
||||||
await tapAddViewButton(name: parentName ?? gettingStarted);
|
await tapAddViewButton(name: parentName ?? gettingStarted, layout: layout);
|
||||||
await tapButtonWithName(layout.menuName);
|
await tapButtonWithName(layout.menuName);
|
||||||
final settingsOrFailure = await getIt<KeyValueStorage>().getWithFormat(
|
final settingsOrFailure = await getIt<KeyValueStorage>().getWithFormat(
|
||||||
KVKeys.showRenameDialogWhenCreatingNewFile,
|
KVKeys.showRenameDialogWhenCreatingNewFile,
|
||||||
@ -564,6 +567,44 @@ extension CommonOperations on WidgetTester {
|
|||||||
);
|
);
|
||||||
await tapButton(button);
|
await tapButton(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> openMoreViewActions() async {
|
||||||
|
final button = find.byType(MoreViewActions);
|
||||||
|
await tap(button);
|
||||||
|
await pumpAndSettle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Presses on the Duplicate ViewAction in the [MoreViewActions] popup.
|
||||||
|
///
|
||||||
|
/// [openMoreViewActions] must be called beforehand!
|
||||||
|
///
|
||||||
|
Future<void> duplicateByMoreViewActions() async {
|
||||||
|
final button = find.descendant(
|
||||||
|
of: find.byType(ListView),
|
||||||
|
matching: find.byWidgetPredicate(
|
||||||
|
(widget) =>
|
||||||
|
widget is ViewAction && widget.type == ViewActionType.duplicate,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tap(button);
|
||||||
|
await pump();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Presses on the Delete ViewAction in the [MoreViewActions] popup.
|
||||||
|
///
|
||||||
|
/// [openMoreViewActions] must be called beforehand!
|
||||||
|
///
|
||||||
|
Future<void> deleteByMoreViewActions() async {
|
||||||
|
final button = find.descendant(
|
||||||
|
of: find.byType(ListView),
|
||||||
|
matching: find.byWidgetPredicate(
|
||||||
|
(widget) =>
|
||||||
|
widget is ViewAction && widget.type == ViewActionType.delete,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tap(button);
|
||||||
|
await pump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SettingsFinder on CommonFinders {
|
extension SettingsFinder on CommonFinders {
|
||||||
|
@ -661,10 +661,13 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
|||||||
|
|
||||||
Future<void> changeFieldTypeOfFieldWithName(
|
Future<void> changeFieldTypeOfFieldWithName(
|
||||||
String name,
|
String name,
|
||||||
FieldType type,
|
FieldType type, {
|
||||||
) async {
|
ViewLayoutPB layout = ViewLayoutPB.Grid,
|
||||||
|
}) async {
|
||||||
await tapGridFieldWithName(name);
|
await tapGridFieldWithName(name);
|
||||||
await tapEditFieldButton();
|
if (layout == ViewLayoutPB.Grid) {
|
||||||
|
await tapEditFieldButton();
|
||||||
|
}
|
||||||
|
|
||||||
await tapSwitchFieldTypeButton();
|
await tapSwitchFieldTypeButton();
|
||||||
await selectFieldType(type);
|
await selectFieldType(type);
|
||||||
@ -881,8 +884,14 @@ extension AppFlowyDatabaseTest on WidgetTester {
|
|||||||
await tapButtonWithName(LocaleKeys.grid_row_delete.tr());
|
await tapButtonWithName(LocaleKeys.grid_row_delete.tr());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createField(FieldType fieldType, String name) async {
|
Future<void> createField(
|
||||||
await scrollToRight(find.byType(GridPage));
|
FieldType fieldType,
|
||||||
|
String name, {
|
||||||
|
ViewLayoutPB layout = ViewLayoutPB.Grid,
|
||||||
|
}) async {
|
||||||
|
if (layout == ViewLayoutPB.Grid) {
|
||||||
|
await scrollToRight(find.byType(GridPage));
|
||||||
|
}
|
||||||
await tapNewPropertyButton();
|
await tapNewPropertyButton();
|
||||||
await renameField(name);
|
await renameField(name);
|
||||||
await tapSwitchFieldTypeButton();
|
await tapSwitchFieldTypeButton();
|
||||||
|
@ -81,15 +81,12 @@ class EditorOperations {
|
|||||||
|
|
||||||
/// Taps the 'Remove Icon' button in the cover toolbar and the icon popover
|
/// Taps the 'Remove Icon' button in the cover toolbar and the icon popover
|
||||||
Future<void> tapRemoveIconButton({bool isInPicker = false}) async {
|
Future<void> tapRemoveIconButton({bool isInPicker = false}) async {
|
||||||
Finder button =
|
final Finder button = !isInPicker
|
||||||
find.text(LocaleKeys.document_plugins_cover_removeIcon.tr());
|
? find.text(LocaleKeys.document_plugins_cover_removeIcon.tr())
|
||||||
if (isInPicker) {
|
: find.descendant(
|
||||||
button = find.descendant(
|
of: find.byType(FlowyIconPicker),
|
||||||
of: find.byType(FlowyIconPicker),
|
matching: find.text(LocaleKeys.button_remove.tr()),
|
||||||
matching: button,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tester.tapButton(button);
|
await tester.tapButton(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ extension Expectation on WidgetTester {
|
|||||||
(widget) =>
|
(widget) =>
|
||||||
widget is SingleInnerViewItem &&
|
widget is SingleInnerViewItem &&
|
||||||
widget.view.isFavorite &&
|
widget.view.isFavorite &&
|
||||||
widget.categoryType == FolderCategoryType.favorite &&
|
widget.spaceType == FolderSpaceType.favorite &&
|
||||||
widget.view.name == name &&
|
widget.view.name == name &&
|
||||||
widget.view.layout == layout,
|
widget.view.layout == layout,
|
||||||
skipOffstage: false,
|
skipOffstage: false,
|
||||||
@ -175,7 +175,7 @@ extension Expectation on WidgetTester {
|
|||||||
(widget) =>
|
(widget) =>
|
||||||
widget is SingleInnerViewItem &&
|
widget is SingleInnerViewItem &&
|
||||||
widget.view.isFavorite &&
|
widget.view.isFavorite &&
|
||||||
widget.categoryType == FolderCategoryType.favorite,
|
widget.spaceType == FolderSpaceType.favorite,
|
||||||
);
|
);
|
||||||
|
|
||||||
Finder findPageName(
|
Finder findPageName(
|
||||||
|
@ -5,10 +5,18 @@ class FlowyTestKeyboard {
|
|||||||
static Future<void> simulateKeyDownEvent(
|
static Future<void> simulateKeyDownEvent(
|
||||||
List<LogicalKeyboardKey> keys, {
|
List<LogicalKeyboardKey> keys, {
|
||||||
required flutter_test.WidgetTester tester,
|
required flutter_test.WidgetTester tester,
|
||||||
|
bool withKeyUp = false,
|
||||||
}) async {
|
}) async {
|
||||||
for (final LogicalKeyboardKey key in keys) {
|
for (final LogicalKeyboardKey key in keys) {
|
||||||
await flutter_test.simulateKeyDownEvent(key);
|
await flutter_test.simulateKeyDownEvent(key);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withKeyUp) {
|
||||||
|
for (final LogicalKeyboardKey key in keys) {
|
||||||
|
await flutter_test.simulateKeyUpEvent(key);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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/workspace/application/settings/prelude.dart';
|
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_setting.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/pages/settings_account_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/settings_account_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
||||||
@ -12,7 +12,6 @@ import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../desktop/board/board_hide_groups_test.dart';
|
import '../desktop/board/board_hide_groups_test.dart';
|
||||||
|
|
||||||
import 'base.dart';
|
import 'base.dart';
|
||||||
import 'common_operations.dart';
|
import 'common_operations.dart';
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/base/icon/icon_picker.dart';
|
import 'package:appflowy/plugins/base/icon/icon_picker.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart';
|
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'base.dart';
|
import 'util.dart';
|
||||||
|
|
||||||
extension AppFlowyWorkspace on WidgetTester {
|
extension AppFlowyWorkspace on WidgetTester {
|
||||||
/// Open workspace menu
|
/// Open workspace menu
|
||||||
@ -36,12 +36,19 @@ extension AppFlowyWorkspace on WidgetTester {
|
|||||||
matching: find.byType(WorkspaceMoreActionList),
|
matching: find.byType(WorkspaceMoreActionList),
|
||||||
);
|
);
|
||||||
expect(moreButton, findsOneWidget);
|
expect(moreButton, findsOneWidget);
|
||||||
await tapButton(moreButton);
|
await hoverOnWidget(
|
||||||
await tapButton(find.findTextInFlowyText(LocaleKeys.button_rename.tr()));
|
moreButton,
|
||||||
final input = find.byType(TextFormField);
|
onHover: () async {
|
||||||
expect(input, findsOneWidget);
|
await tapButton(moreButton);
|
||||||
await enterText(input, name);
|
await tapButton(
|
||||||
await tapButton(find.text(LocaleKeys.button_ok.tr()));
|
find.findTextInFlowyText(LocaleKeys.button_rename.tr()),
|
||||||
|
);
|
||||||
|
final input = find.byType(TextFormField);
|
||||||
|
expect(input, findsOneWidget);
|
||||||
|
await enterText(input, name);
|
||||||
|
await tapButton(find.text(LocaleKeys.button_ok.tr()));
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeWorkspaceIcon(String icon) async {
|
Future<void> changeWorkspaceIcon(String icon) async {
|
||||||
|
@ -173,7 +173,7 @@ SPEC CHECKSUMS:
|
|||||||
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
|
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
|
||||||
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
|
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
|
||||||
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
|
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
|
||||||
integration_test: 13825b8a9334a850581300559b8839134b124670
|
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
||||||
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
||||||
keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86
|
keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86
|
||||||
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
||||||
|
@ -481,7 +481,7 @@ class _AFDropdownMenuState<T> extends State<AFDropdownMenu<T>> {
|
|||||||
|
|
||||||
ButtonStyle effectiveStyle = entry.style ?? defaultStyle;
|
ButtonStyle effectiveStyle = entry.style ?? defaultStyle;
|
||||||
final Color focusedBackgroundColor = effectiveStyle.foregroundColor
|
final Color focusedBackgroundColor = effectiveStyle.foregroundColor
|
||||||
?.resolve(<MaterialState>{MaterialState.focused}) ??
|
?.resolve(<WidgetState>{WidgetState.focused}) ??
|
||||||
Theme.of(context).colorScheme.onSurface;
|
Theme.of(context).colorScheme.onSurface;
|
||||||
|
|
||||||
Widget label = entry.labelWidget ?? Text(entry.label);
|
Widget label = entry.labelWidget ?? Text(entry.label);
|
||||||
@ -499,7 +499,7 @@ class _AFDropdownMenuState<T> extends State<AFDropdownMenu<T>> {
|
|||||||
// color will also change to foregroundColor.withOpacity(0.12).
|
// color will also change to foregroundColor.withOpacity(0.12).
|
||||||
effectiveStyle = entry.enabled && i == focusedIndex
|
effectiveStyle = entry.enabled && i == focusedIndex
|
||||||
? effectiveStyle.copyWith(
|
? effectiveStyle.copyWith(
|
||||||
backgroundColor: MaterialStatePropertyAll<Color>(
|
backgroundColor: WidgetStatePropertyAll<Color>(
|
||||||
focusedBackgroundColor.withOpacity(0.12),
|
focusedBackgroundColor.withOpacity(0.12),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -628,17 +628,17 @@ class _AFDropdownMenuState<T> extends State<AFDropdownMenu<T>> {
|
|||||||
final double? anchorWidth = getWidth(_anchorKey);
|
final double? anchorWidth = getWidth(_anchorKey);
|
||||||
if (widget.width != null) {
|
if (widget.width != null) {
|
||||||
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
||||||
minimumSize: MaterialStatePropertyAll<Size?>(Size(widget.width!, 0.0)),
|
minimumSize: WidgetStatePropertyAll<Size?>(Size(widget.width!, 0.0)),
|
||||||
);
|
);
|
||||||
} else if (anchorWidth != null) {
|
} else if (anchorWidth != null) {
|
||||||
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
||||||
minimumSize: MaterialStatePropertyAll<Size?>(Size(anchorWidth, 0.0)),
|
minimumSize: WidgetStatePropertyAll<Size?>(Size(anchorWidth, 0.0)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.menuHeight != null) {
|
if (widget.menuHeight != null) {
|
||||||
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
effectiveMenuStyle = effectiveMenuStyle.copyWith(
|
||||||
maximumSize: MaterialStatePropertyAll<Size>(
|
maximumSize: WidgetStatePropertyAll<Size>(
|
||||||
Size(double.infinity, widget.menuHeight!),
|
Size(double.infinity, widget.menuHeight!),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -1029,8 +1029,8 @@ class _DropdownMenuDefaultsM3 extends DropdownMenuThemeData {
|
|||||||
@override
|
@override
|
||||||
MenuStyle get menuStyle {
|
MenuStyle get menuStyle {
|
||||||
return const MenuStyle(
|
return const MenuStyle(
|
||||||
minimumSize: MaterialStatePropertyAll<Size>(Size(_kMinimumWidth, 0.0)),
|
minimumSize: WidgetStatePropertyAll<Size>(Size(_kMinimumWidth, 0.0)),
|
||||||
maximumSize: MaterialStatePropertyAll<Size>(Size.infinite),
|
maximumSize: WidgetStatePropertyAll<Size>(Size.infinite),
|
||||||
visualDensity: VisualDensity.standard,
|
visualDensity: VisualDensity.standard,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder;
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TypeOptionMenuItemValue<T> {
|
class TypeOptionMenuItemValue<T> {
|
||||||
|
@ -12,6 +12,7 @@ import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
|||||||
import 'package:appflowy/workspace/application/view/prelude.dart';
|
import 'package:appflowy/workspace/application/view/prelude.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -92,7 +93,7 @@ class MobileViewPageMoreButton extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) => MultiBlocProvider(
|
builder: (_) => MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider.value(value: context.read<ViewBloc>()),
|
BlocProvider.value(value: context.read<ViewBloc>()),
|
||||||
@ -144,7 +145,7 @@ class MobileViewPageLayoutButton extends StatelessWidget {
|
|||||||
showDoneButton: true,
|
showDoneButton: true,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
title: LocaleKeys.pageStyle_title.tr(),
|
title: LocaleKeys.pageStyle_title.tr(),
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) => MultiBlocProvider(
|
builder: (_) => MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider.value(value: context.read<DocumentPageStyleBloc>()),
|
BlocProvider.value(value: context.read<DocumentPageStyleBloc>()),
|
||||||
|
@ -38,6 +38,7 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {
|
|||||||
case MobileViewBottomSheetBodyAction.removeFromFavorites:
|
case MobileViewBottomSheetBodyAction.removeFromFavorites:
|
||||||
context.pop();
|
context.pop();
|
||||||
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view));
|
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MobileViewBottomSheetBodyAction.undo:
|
case MobileViewBottomSheetBodyAction.undo:
|
||||||
EditorNotification.undo().post();
|
EditorNotification.undo().post();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.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/material.dart';
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class BottomSheetActionWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final iconColor =
|
final iconColor =
|
||||||
this.iconColor ?? Theme.of(context).colorScheme.onBackground;
|
this.iconColor ?? AFThemeExtension.of(context).onBackground;
|
||||||
|
|
||||||
if (svg == null) {
|
if (svg == null) {
|
||||||
return OutlinedButton(
|
return OutlinedButton(
|
||||||
|
@ -3,6 +3,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
|||||||
import 'package:appflowy/mobile/presentation/page_item/mobile_slide_action_button.dart';
|
import 'package:appflowy/mobile/presentation/page_item/mobile_slide_action_button.dart';
|
||||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||||
@ -54,7 +55,7 @@ enum MobilePaneActionType {
|
|||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart';
|
||||||
import 'package:appflowy/plugins/base/drag_handler.dart';
|
import 'package:appflowy/plugins/base/drag_handler.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder;
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
extension BottomSheetPaddingExtension on BuildContext {
|
extension BottomSheetPaddingExtension on BuildContext {
|
||||||
|
@ -15,6 +15,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||||
import 'package:appflowy_board/appflowy_board.dart';
|
import 'package:appflowy_board/appflowy_board.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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -265,7 +266,7 @@ class _BoardContentState extends State<_BoardContent> {
|
|||||||
BoxDecoration _makeBoxDecoration(BuildContext context) {
|
BoxDecoration _makeBoxDecoration(BuildContext context) {
|
||||||
final themeMode = context.read<AppearanceSettingsCubit>().state.themeMode;
|
final themeMode = context.read<AppearanceSettingsCubit>().state.themeMode;
|
||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: AFThemeExtension.of(context).background,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
border: themeMode == ThemeMode.light
|
border: themeMode == ThemeMode.light
|
||||||
? Border.fromBorderSide(
|
? Border.fromBorderSide(
|
||||||
|
@ -60,7 +60,7 @@ class _MobileBoardTrailingState extends State<MobileBoardTrailing> {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.close,
|
Icons.close,
|
||||||
color: style.colorScheme.onBackground,
|
color: style.colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
setState(() => _textController.clear()),
|
setState(() => _textController.clear()),
|
||||||
@ -86,7 +86,7 @@ class _MobileBoardTrailingState extends State<MobileBoardTrailing> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
LocaleKeys.button_cancel.tr(),
|
LocaleKeys.button_cancel.tr(),
|
||||||
style: style.textTheme.titleSmall?.copyWith(
|
style: style.textTheme.titleSmall?.copyWith(
|
||||||
color: style.colorScheme.onBackground,
|
color: style.colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () => setState(() => isEditing = false),
|
onPressed: () => setState(() => isEditing = false),
|
||||||
@ -96,7 +96,7 @@ class _MobileBoardTrailingState extends State<MobileBoardTrailing> {
|
|||||||
LocaleKeys.button_add.tr(),
|
LocaleKeys.button_add.tr(),
|
||||||
style: style.textTheme.titleSmall?.copyWith(
|
style: style.textTheme.titleSmall?.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: style.colorScheme.onBackground,
|
color: style.colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -117,14 +117,14 @@ class _MobileBoardTrailingState extends State<MobileBoardTrailing> {
|
|||||||
)
|
)
|
||||||
: ElevatedButton.icon(
|
: ElevatedButton.icon(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: style.colorScheme.onBackground,
|
foregroundColor: style.colorScheme.onSurface,
|
||||||
backgroundColor: style.colorScheme.secondary,
|
backgroundColor: style.colorScheme.secondary,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
).copyWith(
|
).copyWith(
|
||||||
overlayColor:
|
overlayColor:
|
||||||
MaterialStateProperty.all(Theme.of(context).hoverColor),
|
WidgetStateProperty.all(Theme.of(context).hoverColor),
|
||||||
),
|
),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
label: Text(
|
label: Text(
|
||||||
|
@ -9,6 +9,7 @@ import 'package:appflowy/plugins/database/widgets/cell/card_cell_skeleton/text_c
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
import 'package:collection/collection.dart';
|
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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -168,7 +169,7 @@ class MobileHiddenGroup extends StatelessWidget {
|
|||||||
return TextButton(
|
return TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
textStyle: Theme.of(context).textTheme.bodyMedium,
|
textStyle: Theme.of(context).textTheme.bodyMedium,
|
||||||
foregroundColor: Theme.of(context).colorScheme.onBackground,
|
foregroundColor: AFThemeExtension.of(context).onBackground,
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
),
|
),
|
||||||
child: CardCellBuilder(
|
child: CardCellBuilder(
|
||||||
|
@ -20,6 +20,7 @@ import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'
|
|||||||
import 'package:appflowy/plugins/database/widgets/row/row_property.dart';
|
import 'package:appflowy/plugins/database/widgets/row/row_property.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -131,7 +132,7 @@ class _MobileRowDetailPageState extends State<MobileRowDetailPage> {
|
|||||||
void _showCardActions(BuildContext context) {
|
void _showCardActions(BuildContext context) {
|
||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
builder: (_) => Column(
|
builder: (_) => Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -22,17 +22,17 @@ class MobileRowDetailCreateFieldButton extends StatelessWidget {
|
|||||||
constraints: const BoxConstraints(minWidth: double.infinity),
|
constraints: const BoxConstraints(minWidth: double.infinity),
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
overlayColor: MaterialStateProperty.all<Color>(
|
overlayColor: WidgetStateProperty.all<Color>(
|
||||||
Theme.of(context).hoverColor,
|
Theme.of(context).hoverColor,
|
||||||
),
|
),
|
||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
splashFactory: NoSplash.splashFactory,
|
splashFactory: NoSplash.splashFactory,
|
||||||
padding: const MaterialStatePropertyAll(
|
padding: const WidgetStatePropertyAll(
|
||||||
EdgeInsets.symmetric(vertical: 14, horizontal: 6),
|
EdgeInsets.symmetric(vertical: 14, horizontal: 6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
|
||||||
import 'package:appflowy/plugins/database/widgets/card/card.dart';
|
import 'package:appflowy/plugins/database/widgets/card/card.dart';
|
||||||
|
import 'package:appflowy/plugins/database/widgets/card/card_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/cell/card_cell_builder.dart';
|
import 'package:appflowy/plugins/database/widgets/cell/card_cell_builder.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/cell/card_cell_style_maps/mobile_board_card_cell_style.dart';
|
import 'package:appflowy/plugins/database/widgets/cell/card_cell_style_maps/mobile_board_card_cell_style.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
@ -16,7 +16,7 @@ class MobileCardContent extends StatelessWidget {
|
|||||||
|
|
||||||
final RowMetaPB rowMeta;
|
final RowMetaPB rowMeta;
|
||||||
final CardCellBuilder cellBuilder;
|
final CardCellBuilder cellBuilder;
|
||||||
final List<CellContext> cells;
|
final List<CellMeta> cells;
|
||||||
final RowCardStyleConfiguration styleConfiguration;
|
final RowCardStyleConfiguration styleConfiguration;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -26,9 +26,9 @@ class MobileCardContent extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: cells.map(
|
children: cells.map(
|
||||||
(cellContext) {
|
(cellMeta) {
|
||||||
return cellBuilder.build(
|
return cellBuilder.build(
|
||||||
cellContext: cellContext,
|
cellContext: cellMeta.cellContext(),
|
||||||
styleMap: mobileBoardCardCellStyleMap(context),
|
styleMap: mobileBoardCardCellStyleMap(context),
|
||||||
hasNotes: !rowMeta.isDocumentEmpty,
|
hasNotes: !rowMeta.isDocumentEmpty,
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.da
|
|||||||
import 'package:appflowy/util/field_type_extension.dart';
|
import 'package:appflowy/util/field_type_extension.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ Future<FieldType?> showFieldTypeGridBottomSheet(
|
|||||||
showCloseButton: true,
|
showCloseButton: true,
|
||||||
elevation: 20,
|
elevation: 20,
|
||||||
title: title,
|
title: title,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
enableDraggableScrollable: true,
|
enableDraggableScrollable: true,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final typeOptionMenuItemValue = mobileSupportedFieldTypes
|
final typeOptionMenuItemValue = mobileSupportedFieldTypes
|
||||||
|
@ -438,7 +438,7 @@ class _SortDetailContent extends StatelessWidget {
|
|||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
),
|
),
|
||||||
splashFactory: NoSplash.splashFactory,
|
splashFactory: NoSplash.splashFactory,
|
||||||
overlayColor: const MaterialStatePropertyAll(
|
overlayColor: const WidgetStatePropertyAll(
|
||||||
Colors.transparent,
|
Colors.transparent,
|
||||||
),
|
),
|
||||||
onTap: (index) {
|
onTap: (index) {
|
||||||
|
@ -11,6 +11,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||||
import 'package:collection/collection.dart';
|
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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -183,7 +184,7 @@ class MobileDatabaseViewListButton extends StatelessWidget {
|
|||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return BlocProvider<ViewBloc>(
|
return BlocProvider<ViewBloc>(
|
||||||
create: (_) =>
|
create: (_) =>
|
||||||
|
@ -234,7 +234,6 @@ class DatabaseViewSettingTile extends StatelessWidget {
|
|||||||
showHeader: true,
|
showHeader: true,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: LocaleKeys.grid_settings_properties.tr(),
|
title: LocaleKeys.grid_settings_properties.tr(),
|
||||||
showDivider: true,
|
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: context.read<ViewBloc>(),
|
value: context.read<ViewBloc>(),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
||||||
import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder_header.dart';
|
import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder_header.dart';
|
||||||
@ -7,6 +5,7 @@ import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart';
|
|||||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.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_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class MobileFavoriteFolder extends StatelessWidget {
|
class MobileFavoriteFolder extends StatelessWidget {
|
||||||
@ -28,7 +27,7 @@ class MobileFavoriteFolder extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return BlocProvider<FolderBloc>(
|
return BlocProvider<FolderBloc>(
|
||||||
create: (context) => FolderBloc(type: FolderCategoryType.favorite)
|
create: (context) => FolderBloc(type: FolderSpaceType.favorite)
|
||||||
..add(
|
..add(
|
||||||
const FolderEvent.initial(),
|
const FolderEvent.initial(),
|
||||||
),
|
),
|
||||||
@ -55,9 +54,9 @@ class MobileFavoriteFolder extends StatelessWidget {
|
|||||||
...views.map(
|
...views.map(
|
||||||
(view) => MobileViewItem(
|
(view) => MobileViewItem(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'${FolderCategoryType.favorite.name} ${view.id}',
|
'${FolderSpaceType.favorite.name} ${view.id}',
|
||||||
),
|
),
|
||||||
categoryType: FolderCategoryType.favorite,
|
spaceType: FolderSpaceType.favorite,
|
||||||
isDraggable: false,
|
isDraggable: false,
|
||||||
isFirstChild: view.id == views.first.id,
|
isFirstChild: view.id == views.first.id,
|
||||||
isFeedback: false,
|
isFeedback: false,
|
||||||
|
@ -70,20 +70,20 @@ class MobileFolders extends StatelessWidget {
|
|||||||
? [
|
? [
|
||||||
MobileSectionFolder(
|
MobileSectionFolder(
|
||||||
title: LocaleKeys.sideBar_workspace.tr(),
|
title: LocaleKeys.sideBar_workspace.tr(),
|
||||||
categoryType: FolderCategoryType.public,
|
spaceType: FolderSpaceType.public,
|
||||||
views: state.section.publicViews,
|
views: state.section.publicViews,
|
||||||
),
|
),
|
||||||
const VSpace(8.0),
|
const VSpace(8.0),
|
||||||
MobileSectionFolder(
|
MobileSectionFolder(
|
||||||
title: LocaleKeys.sideBar_private.tr(),
|
title: LocaleKeys.sideBar_private.tr(),
|
||||||
categoryType: FolderCategoryType.private,
|
spaceType: FolderSpaceType.private,
|
||||||
views: state.section.privateViews,
|
views: state.section.privateViews,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
MobileSectionFolder(
|
MobileSectionFolder(
|
||||||
title: LocaleKeys.sideBar_personal.tr(),
|
title: LocaleKeys.sideBar_personal.tr(),
|
||||||
categoryType: FolderCategoryType.public,
|
spaceType: FolderSpaceType.public,
|
||||||
views: state.section.publicViews,
|
views: state.section.publicViews,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
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/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
@ -15,6 +13,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sid
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
@ -126,6 +125,7 @@ class _MobileWorkspace extends StatelessWidget {
|
|||||||
child: WorkspaceIcon(
|
child: WorkspaceIcon(
|
||||||
workspace: currentWorkspace,
|
workspace: currentWorkspace,
|
||||||
iconSize: 26,
|
iconSize: 26,
|
||||||
|
fontSize: 16.0,
|
||||||
enableEdit: false,
|
enableEdit: false,
|
||||||
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
||||||
UserWorkspaceEvent.updateWorkspaceIcon(
|
UserWorkspaceEvent.updateWorkspaceIcon(
|
||||||
|
@ -178,7 +178,7 @@ class _DeletedFilesListView extends StatelessWidget {
|
|||||||
title: Text(
|
title: Text(
|
||||||
deletedFile.name,
|
deletedFile.name,
|
||||||
style: theme.textTheme.labelMedium
|
style: theme.textTheme.labelMedium
|
||||||
?.copyWith(color: theme.colorScheme.onBackground),
|
?.copyWith(color: theme.colorScheme.onSurface),
|
||||||
),
|
),
|
||||||
horizontalTitleGap: 0,
|
horizontalTitleGap: 0,
|
||||||
tileColor: theme.colorScheme.onSurface.withOpacity(0.1),
|
tileColor: theme.colorScheme.onSurface.withOpacity(0.1),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
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/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
@ -9,7 +7,9 @@ import 'package:appflowy/workspace/application/recent/prelude.dart';
|
|||||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class _RecentViews extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
||||||
@ -8,9 +6,11 @@ import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart';
|
|||||||
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
import 'package:appflowy/workspace/application/menu/sidebar_sections_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/view/view_bloc.dart';
|
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class MobileSectionFolder extends StatelessWidget {
|
class MobileSectionFolder extends StatelessWidget {
|
||||||
@ -18,17 +18,17 @@ class MobileSectionFolder extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.views,
|
required this.views,
|
||||||
required this.categoryType,
|
required this.spaceType,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
final List<ViewPB> views;
|
final List<ViewPB> views;
|
||||||
final FolderCategoryType categoryType;
|
final FolderSpaceType spaceType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider<FolderBloc>(
|
return BlocProvider<FolderBloc>(
|
||||||
create: (context) => FolderBloc(type: categoryType)
|
create: (context) => FolderBloc(type: spaceType)
|
||||||
..add(
|
..add(
|
||||||
const FolderEvent.initial(),
|
const FolderEvent.initial(),
|
||||||
),
|
),
|
||||||
@ -48,7 +48,7 @@ class MobileSectionFolder extends StatelessWidget {
|
|||||||
name:
|
name:
|
||||||
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
index: 0,
|
index: 0,
|
||||||
viewSection: categoryType.toViewSectionPB,
|
viewSection: spaceType.toViewSectionPB,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
context.read<FolderBloc>().add(
|
context.read<FolderBloc>().add(
|
||||||
@ -64,13 +64,13 @@ class MobileSectionFolder extends StatelessWidget {
|
|||||||
...views.map(
|
...views.map(
|
||||||
(view) => MobileViewItem(
|
(view) => MobileViewItem(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'${FolderCategoryType.private.name} ${view.id}',
|
'${FolderSpaceType.private.name} ${view.id}',
|
||||||
),
|
),
|
||||||
categoryType: categoryType,
|
spaceType: spaceType,
|
||||||
isFirstChild: view.id == views.first.id,
|
isFirstChild: view.id == views.first.id,
|
||||||
view: view,
|
view: view,
|
||||||
level: 0,
|
level: 0,
|
||||||
leftPadding: 16,
|
leftPadding: HomeSpaceViewSizes.leftPadding,
|
||||||
isFeedback: false,
|
isFeedback: false,
|
||||||
onSelected: context.pushView,
|
onSelected: context.pushView,
|
||||||
endActionPane: (context) {
|
endActionPane: (context) {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
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/mobile/presentation/widgets/widgets.dart';
|
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||||
@ -9,6 +7,7 @@ import 'package:appflowy/workspace/presentation/settings/widgets/members/workspa
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
// Only works on mobile.
|
// Only works on mobile.
|
||||||
@ -106,6 +105,7 @@ class _WorkspaceMenuItem extends StatelessWidget {
|
|||||||
leftIcon: WorkspaceIcon(
|
leftIcon: WorkspaceIcon(
|
||||||
enableEdit: false,
|
enableEdit: false,
|
||||||
iconSize: 26,
|
iconSize: 26,
|
||||||
|
fontSize: 16.0,
|
||||||
workspace: workspace,
|
workspace: workspace,
|
||||||
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
onSelected: (result) => context.read<UserWorkspaceBloc>().add(
|
||||||
UserWorkspaceEvent.updateWorkspaceIcon(
|
UserWorkspaceEvent.updateWorkspaceIcon(
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
@ -12,6 +10,7 @@ import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_it
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ class MobileViewItem extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
required this.view,
|
required this.view,
|
||||||
this.parentView,
|
this.parentView,
|
||||||
required this.categoryType,
|
required this.spaceType,
|
||||||
required this.level,
|
required this.level,
|
||||||
this.leftPadding = 10,
|
this.leftPadding = 10,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
@ -39,7 +38,7 @@ class MobileViewItem extends StatelessWidget {
|
|||||||
final ViewPB view;
|
final ViewPB view;
|
||||||
final ViewPB? parentView;
|
final ViewPB? parentView;
|
||||||
|
|
||||||
final FolderCategoryType categoryType;
|
final FolderSpaceType spaceType;
|
||||||
|
|
||||||
// indicate the level of the view item
|
// indicate the level of the view item
|
||||||
// used to calculate the left padding
|
// used to calculate the left padding
|
||||||
@ -80,7 +79,7 @@ class MobileViewItem extends StatelessWidget {
|
|||||||
view: state.view,
|
view: state.view,
|
||||||
parentView: parentView,
|
parentView: parentView,
|
||||||
childViews: state.view.childViews,
|
childViews: state.view.childViews,
|
||||||
categoryType: categoryType,
|
spaceType: spaceType,
|
||||||
level: level,
|
level: level,
|
||||||
leftPadding: leftPadding,
|
leftPadding: leftPadding,
|
||||||
showActions: true,
|
showActions: true,
|
||||||
@ -104,7 +103,7 @@ class InnerMobileViewItem extends StatelessWidget {
|
|||||||
required this.view,
|
required this.view,
|
||||||
required this.parentView,
|
required this.parentView,
|
||||||
required this.childViews,
|
required this.childViews,
|
||||||
required this.categoryType,
|
required this.spaceType,
|
||||||
this.isDraggable = true,
|
this.isDraggable = true,
|
||||||
this.isExpanded = true,
|
this.isExpanded = true,
|
||||||
required this.level,
|
required this.level,
|
||||||
@ -120,7 +119,7 @@ class InnerMobileViewItem extends StatelessWidget {
|
|||||||
final ViewPB view;
|
final ViewPB view;
|
||||||
final ViewPB? parentView;
|
final ViewPB? parentView;
|
||||||
final List<ViewPB> childViews;
|
final List<ViewPB> childViews;
|
||||||
final FolderCategoryType categoryType;
|
final FolderSpaceType spaceType;
|
||||||
|
|
||||||
final bool isDraggable;
|
final bool isDraggable;
|
||||||
final bool isExpanded;
|
final bool isExpanded;
|
||||||
@ -144,7 +143,7 @@ class InnerMobileViewItem extends StatelessWidget {
|
|||||||
parentView: parentView,
|
parentView: parentView,
|
||||||
level: level,
|
level: level,
|
||||||
showActions: showActions,
|
showActions: showActions,
|
||||||
categoryType: categoryType,
|
spaceType: spaceType,
|
||||||
onSelected: onSelected,
|
onSelected: onSelected,
|
||||||
isExpanded: isExpanded,
|
isExpanded: isExpanded,
|
||||||
isDraggable: isDraggable,
|
isDraggable: isDraggable,
|
||||||
@ -159,9 +158,9 @@ class InnerMobileViewItem extends StatelessWidget {
|
|||||||
if (childViews.isNotEmpty) {
|
if (childViews.isNotEmpty) {
|
||||||
final children = childViews.map((childView) {
|
final children = childViews.map((childView) {
|
||||||
return MobileViewItem(
|
return MobileViewItem(
|
||||||
key: ValueKey('${categoryType.name} ${childView.id}'),
|
key: ValueKey('${spaceType.name} ${childView.id}'),
|
||||||
parentView: view,
|
parentView: view,
|
||||||
categoryType: categoryType,
|
spaceType: spaceType,
|
||||||
isFirstChild: childView.id == childViews.first.id,
|
isFirstChild: childView.id == childViews.first.id,
|
||||||
view: childView,
|
view: childView,
|
||||||
level: level + 1,
|
level: level + 1,
|
||||||
@ -235,7 +234,7 @@ class InnerMobileViewItem extends StatelessWidget {
|
|||||||
return MobileViewItem(
|
return MobileViewItem(
|
||||||
view: view,
|
view: view,
|
||||||
parentView: parentView,
|
parentView: parentView,
|
||||||
categoryType: categoryType,
|
spaceType: spaceType,
|
||||||
level: level,
|
level: level,
|
||||||
onSelected: onSelected,
|
onSelected: onSelected,
|
||||||
isDraggable: false,
|
isDraggable: false,
|
||||||
@ -262,7 +261,7 @@ class SingleMobileInnerViewItem extends StatefulWidget {
|
|||||||
required this.level,
|
required this.level,
|
||||||
required this.leftPadding,
|
required this.leftPadding,
|
||||||
this.isDraggable = true,
|
this.isDraggable = true,
|
||||||
required this.categoryType,
|
required this.spaceType,
|
||||||
required this.showActions,
|
required this.showActions,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
required this.isFeedback,
|
required this.isFeedback,
|
||||||
@ -282,7 +281,7 @@ class SingleMobileInnerViewItem extends StatefulWidget {
|
|||||||
final bool isDraggable;
|
final bool isDraggable;
|
||||||
final bool showActions;
|
final bool showActions;
|
||||||
final ViewItemOnSelected onSelected;
|
final ViewItemOnSelected onSelected;
|
||||||
final FolderCategoryType categoryType;
|
final FolderSpaceType spaceType;
|
||||||
final ActionPaneBuilder? startActionPane;
|
final ActionPaneBuilder? startActionPane;
|
||||||
final ActionPaneBuilder? endActionPane;
|
final ActionPaneBuilder? endActionPane;
|
||||||
|
|
||||||
@ -407,10 +406,9 @@ class _SingleMobileInnerViewItemState extends State<SingleMobileInnerViewItem> {
|
|||||||
ViewEvent.createView(
|
ViewEvent.createView(
|
||||||
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
layout,
|
layout,
|
||||||
section:
|
section: widget.spaceType != FolderSpaceType.favorite
|
||||||
widget.categoryType != FolderCategoryType.favorite
|
? widget.spaceType.toViewSectionPB
|
||||||
? widget.categoryType.toViewSectionPB
|
: null,
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,6 @@ class RTLSetting extends StatelessWidget {
|
|||||||
showHeader: true,
|
showHeader: true,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
showCloseButton: false,
|
|
||||||
title: LocaleKeys.settings_appearance_textDirection_label.tr(),
|
title: LocaleKeys.settings_appearance_textDirection_label.tr(),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final layoutDirection =
|
final layoutDirection =
|
||||||
|
@ -45,7 +45,6 @@ class TextScaleSetting extends StatelessWidget {
|
|||||||
showHeader: true,
|
showHeader: true,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
showCloseButton: false,
|
|
||||||
title: LocaleKeys.settings_appearance_fontScaleFactor.tr(),
|
title: LocaleKeys.settings_appearance_fontScaleFactor.tr(),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return FontSizeStepper(
|
return FontSizeStepper(
|
||||||
|
@ -38,7 +38,6 @@ class ThemeSetting extends StatelessWidget {
|
|||||||
showHeader: true,
|
showHeader: true,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
showCloseButton: false,
|
|
||||||
title: LocaleKeys.settings_appearance_themeMode_label.tr(),
|
title: LocaleKeys.settings_appearance_themeMode_label.tr(),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final themeMode =
|
final themeMode =
|
||||||
|
@ -29,9 +29,7 @@ class FontPickerScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LanguagePickerPage extends StatefulWidget {
|
class LanguagePickerPage extends StatefulWidget {
|
||||||
const LanguagePickerPage({
|
const LanguagePickerPage({super.key});
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<LanguagePickerPage> createState() => _LanguagePickerPageState();
|
State<LanguagePickerPage> createState() => _LanguagePickerPageState();
|
||||||
@ -43,7 +41,6 @@ class _LanguagePickerPageState extends State<LanguagePickerPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
availableFonts = _availableFonts;
|
availableFonts = _availableFonts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +87,6 @@ class _FontSelectorState extends State<FontSelector> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
availableFonts = _availableFonts;
|
availableFonts = _availableFonts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class MobileQuickActionButton extends StatelessWidget {
|
|||||||
onTap: enable ? onTap : null,
|
onTap: enable ? onTap : null,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
overlayColor:
|
overlayColor:
|
||||||
enable ? null : const MaterialStatePropertyAll(Colors.transparent),
|
enable ? null : const WidgetStatePropertyAll(Colors.transparent),
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 44,
|
height: 44,
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:appflowy/plugins/base/emoji/emoji_picker_header.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_picker_header.dart';
|
||||||
import 'package:appflowy/plugins/base/emoji/emoji_search_bar.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_search_bar.dart';
|
||||||
import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
|
||||||
|
import 'package:flowy_infra/size.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/material.dart';
|
||||||
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
|
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
|
|
||||||
// use a global value to store the selected emoji to prevent reloading every time.
|
// use a global value to store the selected emoji to prevent reloading every time.
|
||||||
EmojiData? kCachedEmojiData;
|
EmojiData? kCachedEmojiData;
|
||||||
@ -27,7 +25,6 @@ class FlowyEmojiPicker extends StatefulWidget {
|
|||||||
|
|
||||||
class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
||||||
EmojiData? emojiData;
|
EmojiData? emojiData;
|
||||||
List<String>? fallbackFontFamily;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -46,13 +43,6 @@ class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isAndroid || Platform.isLinux) {
|
|
||||||
final notoColorEmoji = GoogleFonts.notoColorEmoji().fontFamily;
|
|
||||||
if (notoColorEmoji != null) {
|
|
||||||
fallbackFontFamily = [notoColorEmoji];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -82,14 +72,18 @@ class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemBuilder: (context, emojiId, emoji, callback) {
|
itemBuilder: (context, emojiId, emoji, callback) {
|
||||||
return FlowyIconButton(
|
return SizedBox(
|
||||||
iconPadding: const EdgeInsets.all(2.0),
|
width: 36,
|
||||||
icon: FlowyText(
|
height: 36,
|
||||||
emoji,
|
child: FlowyButton(
|
||||||
fontSize: 28.0,
|
margin: EdgeInsets.zero,
|
||||||
fallbackFontFamily: fallbackFontFamily,
|
radius: Corners.s8Border,
|
||||||
|
text: FlowyText.emoji(
|
||||||
|
emoji,
|
||||||
|
fontSize: 24.0,
|
||||||
|
),
|
||||||
|
onTap: () => callback(emojiId, emoji),
|
||||||
),
|
),
|
||||||
onPressed: () => callback(emojiId, emoji),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
searchBarBuilder: (context, keyword, skinTone) {
|
searchBarBuilder: (context, keyword, skinTone) {
|
||||||
|
@ -16,9 +16,14 @@ class FlowyEmojiHeader extends StatelessWidget {
|
|||||||
if (PlatformExtension.isDesktopOrWeb) {
|
if (PlatformExtension.isDesktopOrWeb) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 22,
|
height: 22,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
|
||||||
color: Theme.of(context).cardColor,
|
color: Theme.of(context).cardColor,
|
||||||
child: FlowyText.regular(category.id),
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 4.0),
|
||||||
|
child: FlowyText.regular(
|
||||||
|
category.id,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Column(
|
return Column(
|
||||||
|
@ -42,7 +42,7 @@ class _FlowyEmojiSearchBarState extends State<FlowyEmojiSearchBar> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: 8.0,
|
vertical: 12.0,
|
||||||
horizontal: PlatformExtension.isDesktopOrWeb ? 0.0 : 8.0,
|
horizontal: PlatformExtension.isDesktopOrWeb ? 0.0 : 8.0,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -52,16 +52,15 @@ class _FlowyEmojiSearchBarState extends State<FlowyEmojiSearchBar> {
|
|||||||
onKeywordChanged: widget.onKeywordChanged,
|
onKeywordChanged: widget.onKeywordChanged,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(6.0),
|
const HSpace(8.0),
|
||||||
_RandomEmojiButton(
|
_RandomEmojiButton(
|
||||||
emojiData: widget.emojiData,
|
emojiData: widget.emojiData,
|
||||||
onRandomEmojiSelected: widget.onRandomEmojiSelected,
|
onRandomEmojiSelected: widget.onRandomEmojiSelected,
|
||||||
),
|
),
|
||||||
const HSpace(6.0),
|
const HSpace(8.0),
|
||||||
FlowyEmojiSkinToneSelector(
|
FlowyEmojiSkinToneSelector(
|
||||||
onEmojiSkinToneChanged: widget.onSkinToneChanged,
|
onEmojiSkinToneChanged: widget.onSkinToneChanged,
|
||||||
),
|
),
|
||||||
const HSpace(6.0),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -79,20 +78,30 @@ class _RandomEmojiButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyTooltip(
|
return Container(
|
||||||
message: LocaleKeys.emoji_random.tr(),
|
width: 36,
|
||||||
child: FlowyButton(
|
height: 36,
|
||||||
useIntrinsicWidth: true,
|
decoration: ShapeDecoration(
|
||||||
text: const Icon(
|
shape: RoundedRectangleBorder(
|
||||||
Icons.shuffle_rounded,
|
side: const BorderSide(color: Color(0x1E171717)),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: FlowyTooltip(
|
||||||
|
message: LocaleKeys.emoji_random.tr(),
|
||||||
|
child: FlowyButton(
|
||||||
|
useIntrinsicWidth: true,
|
||||||
|
text: const FlowySvg(
|
||||||
|
FlowySvgs.icon_shuffle_s,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
final random = emojiData.random;
|
||||||
|
onRandomEmojiSelected(
|
||||||
|
random.$1,
|
||||||
|
random.$2,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onTap: () {
|
|
||||||
final random = emojiData.random;
|
|
||||||
onRandomEmojiSelected(
|
|
||||||
random.$1,
|
|
||||||
random.$2,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -123,32 +132,35 @@ class _SearchTextFieldState extends State<_SearchTextField> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ConstrainedBox(
|
return SizedBox(
|
||||||
constraints: const BoxConstraints(
|
height: 36.0,
|
||||||
maxHeight: 32.0,
|
|
||||||
),
|
|
||||||
child: FlowyTextField(
|
child: FlowyTextField(
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
hintText: LocaleKeys.emoji_search.tr(),
|
hintText: LocaleKeys.search_label.tr(),
|
||||||
|
hintStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
onChanged: widget.onKeywordChanged,
|
onChanged: widget.onKeywordChanged,
|
||||||
prefixIcon: const Padding(
|
prefixIcon: const Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 8.0,
|
left: 14.0,
|
||||||
right: 4.0,
|
right: 8.0,
|
||||||
),
|
),
|
||||||
child: FlowySvg(
|
child: FlowySvg(
|
||||||
FlowySvgs.search_s,
|
FlowySvgs.search_s,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
prefixIconConstraints: const BoxConstraints(
|
prefixIconConstraints: const BoxConstraints(
|
||||||
maxHeight: 18.0,
|
maxHeight: 20.0,
|
||||||
),
|
),
|
||||||
suffixIcon: Padding(
|
suffixIcon: Padding(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: const EdgeInsets.all(4.0),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: const FlowySvg(
|
text: const FlowySvg(
|
||||||
FlowySvgs.close_lg,
|
FlowySvgs.m_app_bar_close_s,
|
||||||
),
|
),
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
|
@ -57,7 +57,7 @@ class _FlowyEmojiSkinToneSelectorState
|
|||||||
child: FlowyTooltip(
|
child: FlowyTooltip(
|
||||||
message: LocaleKeys.emoji_selectSkinTone.tr(),
|
message: LocaleKeys.emoji_selectSkinTone.tr(),
|
||||||
child: _buildIconButton(
|
child: _buildIconButton(
|
||||||
lastSelectedEmojiSkinTone?.icon ?? '✋',
|
lastSelectedEmojiSkinTone?.icon ?? '👋',
|
||||||
() => controller.show(),
|
() => controller.show(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -65,19 +65,22 @@ class _FlowyEmojiSkinToneSelectorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIconButton(String icon, VoidCallback onPressed) {
|
Widget _buildIconButton(String icon, VoidCallback onPressed) {
|
||||||
return FlowyIconButton(
|
return Container(
|
||||||
key: emojiSkinToneKey(icon),
|
width: 36,
|
||||||
icon: Padding(
|
height: 36,
|
||||||
// add a left padding to align the emoji center
|
decoration: BoxDecoration(
|
||||||
padding: const EdgeInsets.only(
|
border: Border.all(color: const Color(0x1E171717)),
|
||||||
left: 3.0,
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: FlowyText(
|
child: FlowyButton(
|
||||||
icon,
|
key: emojiSkinToneKey(icon),
|
||||||
fontSize: 22.0,
|
margin: EdgeInsets.zero,
|
||||||
),
|
text: FlowyText.emoji(
|
||||||
|
icon,
|
||||||
|
fontSize: 24.0,
|
||||||
|
),
|
||||||
|
onTap: onPressed,
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,17 +89,17 @@ extension EmojiSkinToneIcon on EmojiSkinTone {
|
|||||||
String get icon {
|
String get icon {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case EmojiSkinTone.none:
|
case EmojiSkinTone.none:
|
||||||
return '✋';
|
return '👋';
|
||||||
case EmojiSkinTone.light:
|
case EmojiSkinTone.light:
|
||||||
return '✋🏻';
|
return '👋🏻';
|
||||||
case EmojiSkinTone.mediumLight:
|
case EmojiSkinTone.mediumLight:
|
||||||
return '✋🏼';
|
return '👋🏼';
|
||||||
case EmojiSkinTone.medium:
|
case EmojiSkinTone.medium:
|
||||||
return '✋🏽';
|
return '👋🏽';
|
||||||
case EmojiSkinTone.mediumDark:
|
case EmojiSkinTone.mediumDark:
|
||||||
return '✋🏾';
|
return '👋🏾';
|
||||||
case EmojiSkinTone.dark:
|
case EmojiSkinTone.dark:
|
||||||
return '✋🏿';
|
return '👋🏿';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ class EmojiText extends StatelessWidget {
|
|||||||
emoji,
|
emoji,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
textAlign: textAlign,
|
textAlign: textAlign,
|
||||||
|
strutStyle: const StrutStyle(forceStrutHeight: true),
|
||||||
fallbackFontFamily: _cachedFallbackFontFamily,
|
fallbackFontFamily: _cachedFallbackFontFamily,
|
||||||
lineHeight: lineHeight,
|
lineHeight: lineHeight,
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import 'package:flutter/material.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/base/emoji/emoji_picker.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_picker.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
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/style_widget/hover.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
extension ToProto on FlowyIconType {
|
extension ToProto on FlowyIconType {
|
||||||
ViewIconTypePB toProto() {
|
ViewIconTypePB toProto() {
|
||||||
@ -54,57 +51,28 @@ class FlowyIconPicker extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// ONLY supports emoji picker for now
|
return Padding(
|
||||||
return DefaultTabController(
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
length: 1,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
const VSpace(8.0),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
_buildTabs(context),
|
FlowyText(LocaleKeys.newSettings_workplace_chooseAnIcon.tr()),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
_RemoveIconButton(
|
_RemoveIconButton(
|
||||||
onTap: () => onSelected(EmojiPickerResult.none()),
|
onTap: () => onSelected(EmojiPickerResult.none()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Divider(height: 2),
|
const VSpace(12.0),
|
||||||
|
const Divider(height: 0.5),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TabBarView(
|
child: FlowyEmojiPicker(
|
||||||
children: [
|
emojiPerLine: _getEmojiPerLine(context),
|
||||||
FlowyEmojiPicker(
|
onEmojiSelected: (_, emoji) =>
|
||||||
emojiPerLine: _getEmojiPerLine(context),
|
onSelected(EmojiPickerResult.emoji(emoji)),
|
||||||
onEmojiSelected: (_, emoji) =>
|
|
||||||
onSelected(EmojiPickerResult.emoji(emoji)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTabs(BuildContext context) {
|
|
||||||
return Align(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: TabBar(
|
|
||||||
indicatorSize: TabBarIndicatorSize.label,
|
|
||||||
isScrollable: true,
|
|
||||||
overlayColor: MaterialStatePropertyAll(
|
|
||||||
Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
tabs: [
|
|
||||||
FlowyHover(
|
|
||||||
style: const HoverStyle(borderRadius: BorderRadius.zero),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12.0,
|
|
||||||
vertical: 8.0,
|
|
||||||
),
|
|
||||||
child: FlowyText(LocaleKeys.emoji_emojiTab.tr()),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -117,7 +85,7 @@ class FlowyIconPicker extends StatelessWidget {
|
|||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
final width = MediaQuery.of(context).size.width;
|
final width = MediaQuery.of(context).size.width;
|
||||||
return width ~/ 46.0; // the size of the emoji
|
return width ~/ 40.0; // the size of the emoji
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,14 +97,14 @@ class _RemoveIconButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 28,
|
height: 24,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
text: FlowyText.small(
|
text: FlowyText.regular(
|
||||||
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
LocaleKeys.button_remove.tr(),
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
leftIcon: const FlowySvg(FlowySvgs.delete_s),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
|||||||
import 'package:appflowy_board/appflowy_board.dart';
|
import 'package:appflowy_board/appflowy_board.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
@ -671,7 +672,7 @@ class _BoardCardState extends State<_BoardCard> {
|
|||||||
? const Color(0x0F1F2329)
|
? const Color(0x0F1F2329)
|
||||||
: const Color(0x0FEFF4FB),
|
: const Color(0x0FEFF4FB),
|
||||||
foregroundColorOnHover:
|
foregroundColorOnHover:
|
||||||
Theme.of(context).colorScheme.onBackground,
|
AFThemeExtension.of(context).onBackground,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onStartEditing: () =>
|
onStartEditing: () =>
|
||||||
|
@ -238,7 +238,7 @@ class NewEventButton extends StatelessWidget {
|
|||||||
child: FlowyIconButton(
|
child: FlowyIconButton(
|
||||||
onPressed: onCreate,
|
onPressed: onCreate,
|
||||||
icon: const FlowySvg(FlowySvgs.add_s),
|
icon: const FlowySvg(FlowySvgs.add_s),
|
||||||
fillColor: Theme.of(context).colorScheme.background,
|
fillColor: Theme.of(context).colorScheme.surface,
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
width: 22,
|
width: 22,
|
||||||
tooltipText: LocaleKeys.calendar_newEventButtonTooltip.tr(),
|
tooltipText: LocaleKeys.calendar_newEventButtonTooltip.tr(),
|
||||||
@ -289,8 +289,8 @@ class _DayBadge extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Color dayTextColor = Theme.of(context).colorScheme.onBackground;
|
Color dayTextColor = AFThemeExtension.of(context).onBackground;
|
||||||
Color monthTextColor = Theme.of(context).colorScheme.onBackground;
|
Color monthTextColor = AFThemeExtension.of(context).onBackground;
|
||||||
final String monthString =
|
final String monthString =
|
||||||
DateFormat("MMM ", context.locale.toLanguageTag()).format(date);
|
DateFormat("MMM ", context.locale.toLanguageTag()).format(date);
|
||||||
final String dayString = date.day.toString();
|
final String dayString = date.day.toString();
|
||||||
|
@ -8,6 +8,7 @@ import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.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:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -15,7 +16,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../application/calendar_bloc.dart';
|
import '../application/calendar_bloc.dart';
|
||||||
|
|
||||||
import 'calendar_event_editor.dart';
|
import 'calendar_event_editor.dart';
|
||||||
|
|
||||||
class EventCard extends StatefulWidget {
|
class EventCard extends StatefulWidget {
|
||||||
@ -102,7 +102,7 @@ class _EventCardState extends State<EventCard> {
|
|||||||
hoverColor: Theme.of(context).brightness == Brightness.light
|
hoverColor: Theme.of(context).brightness == Brightness.light
|
||||||
? const Color(0x0F1F2329)
|
? const Color(0x0F1F2329)
|
||||||
: const Color(0x0FEFF4FB),
|
: const Color(0x0FEFF4FB),
|
||||||
foregroundColorOnHover: Theme.of(context).colorScheme.onBackground,
|
foregroundColorOnHover: AFThemeExtension.of(context).onBackground,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onStartEditing: () {},
|
onStartEditing: () {},
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
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/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
@ -21,12 +19,12 @@ import 'package:flowy_infra/size.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: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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../../application/row/row_controller.dart';
|
import '../../application/row/row_controller.dart';
|
||||||
import '../../widgets/row/row_detail.dart';
|
import '../../widgets/row/row_detail.dart';
|
||||||
|
|
||||||
import 'calendar_day.dart';
|
import 'calendar_day.dart';
|
||||||
import 'layout/sizes.dart';
|
import 'layout/sizes.dart';
|
||||||
import 'toolbar/calendar_setting_bar.dart';
|
import 'toolbar/calendar_setting_bar.dart';
|
||||||
|
@ -43,7 +43,7 @@ Widget getGridFabs(BuildContext context) {
|
|||||||
.read<GridBloc>()
|
.read<GridBloc>()
|
||||||
.add(const GridEvent.createRow(openRowDetail: true));
|
.add(const GridEvent.createRow(openRowDetail: true));
|
||||||
},
|
},
|
||||||
overlayColor: const MaterialStatePropertyAll<Color>(Color(0xFF009FD1)),
|
overlayColor: const WidgetStatePropertyAll<Color>(Color(0xFF009FD1)),
|
||||||
boxShadow: const BoxShadow(
|
boxShadow: const BoxShadow(
|
||||||
offset: Offset(0, 8),
|
offset: Offset(0, 8),
|
||||||
color: Color(0x6612BFEF),
|
color: Color(0x6612BFEF),
|
||||||
@ -75,7 +75,7 @@ class MobileGridFab extends StatelessWidget {
|
|||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final FlowySvgData icon;
|
final FlowySvgData icon;
|
||||||
final Size iconSize;
|
final Size iconSize;
|
||||||
final MaterialStateProperty<Color?>? overlayColor;
|
final WidgetStateProperty<Color?>? overlayColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -77,22 +77,22 @@ class _DatabaseViewSelectorButton extends StatelessWidget {
|
|||||||
|
|
||||||
return TextButton(
|
return TextButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: const MaterialStatePropertyAll(
|
padding: const WidgetStatePropertyAll(
|
||||||
EdgeInsets.fromLTRB(12, 8, 8, 8),
|
EdgeInsets.fromLTRB(12, 8, 8, 8),
|
||||||
),
|
),
|
||||||
maximumSize: const MaterialStatePropertyAll(Size(200, 48)),
|
maximumSize: const WidgetStatePropertyAll(Size(200, 48)),
|
||||||
minimumSize: const MaterialStatePropertyAll(Size(48, 0)),
|
minimumSize: const WidgetStatePropertyAll(Size(48, 0)),
|
||||||
shape: const MaterialStatePropertyAll(
|
shape: const WidgetStatePropertyAll(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
backgroundColor: MaterialStatePropertyAll(
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
Theme.of(context).brightness == Brightness.light
|
Theme.of(context).brightness == Brightness.light
|
||||||
? const Color(0x0F212729)
|
? const Color(0x0F212729)
|
||||||
: const Color(0x0FFFFFFF),
|
: const Color(0x0FFFFFFF),
|
||||||
),
|
),
|
||||||
overlayColor: MaterialStatePropertyAll(
|
overlayColor: WidgetStatePropertyAll(
|
||||||
Theme.of(context).colorScheme.secondary,
|
Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -119,7 +119,6 @@ class _DatabaseViewSelectorButton extends StatelessWidget {
|
|||||||
showTransitionMobileBottomSheet(
|
showTransitionMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
initialStop: 1.0,
|
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -236,7 +236,8 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder {
|
|||||||
final String? initialRowId;
|
final String? initialRowId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget get leftBarItem => ViewTitleBar(view: notifier.view);
|
Widget get leftBarItem =>
|
||||||
|
ViewTitleBar(key: ValueKey(notifier.view.id), view: notifier.view);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view);
|
Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view);
|
||||||
@ -278,7 +279,7 @@ class DatabasePluginWidgetBuilder extends PluginWidgetBuilder {
|
|||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
DatabaseShareButton(key: ValueKey(view.id), view: view),
|
DatabaseShareButton(key: ValueKey(view.id), view: view),
|
||||||
const HSpace(4),
|
const HSpace(10),
|
||||||
ViewFavoriteButton(view: view),
|
ViewFavoriteButton(view: view),
|
||||||
const HSpace(4),
|
const HSpace(4),
|
||||||
MoreViewActions(view: view, isDocument: false),
|
MoreViewActions(view: view, isDocument: false),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/mobile/presentation/database/card/card.dart';
|
import 'package:appflowy/mobile/presentation/database/card/card.dart';
|
||||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
|
||||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||||
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
||||||
import 'package:appflowy/plugins/database/grid/presentation/widgets/row/action.dart';
|
import 'package:appflowy/plugins/database/grid/presentation/widgets/row/action.dart';
|
||||||
@ -186,7 +185,7 @@ class _CardContent extends StatelessWidget {
|
|||||||
|
|
||||||
final RowMetaPB rowMeta;
|
final RowMetaPB rowMeta;
|
||||||
final CardCellBuilder cellBuilder;
|
final CardCellBuilder cellBuilder;
|
||||||
final List<CellContext> cells;
|
final List<CellMeta> cells;
|
||||||
final RowCardStyleConfiguration styleConfiguration;
|
final RowCardStyleConfiguration styleConfiguration;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -210,9 +209,9 @@ class _CardContent extends StatelessWidget {
|
|||||||
List<Widget> _makeCells(
|
List<Widget> _makeCells(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
RowMetaPB rowMeta,
|
RowMetaPB rowMeta,
|
||||||
List<CellContext> cells,
|
List<CellMeta> cells,
|
||||||
) {
|
) {
|
||||||
return cells.mapIndexed((int index, CellContext cellContext) {
|
return cells.mapIndexed((int index, CellMeta cellMeta) {
|
||||||
EditableCardNotifier? cellNotifier;
|
EditableCardNotifier? cellNotifier;
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
@ -225,7 +224,7 @@ class _CardContent extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cellBuilder.build(
|
return cellBuilder.build(
|
||||||
cellContext: cellContext,
|
cellContext: cellMeta.cellContext(),
|
||||||
cellNotifier: cellNotifier,
|
cellNotifier: cellNotifier,
|
||||||
styleMap: styleConfiguration.cellStyleMap,
|
styleMap: styleConfiguration.cellStyleMap,
|
||||||
hasNotes: !rowMeta.isDocumentEmpty,
|
hasNotes: !rowMeta.isDocumentEmpty,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:appflowy/plugins/database/application/row/row_service.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
||||||
@ -7,7 +9,6 @@ import 'package:appflowy/plugins/database/application/field/field_controller.dar
|
|||||||
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
import 'package:appflowy/plugins/database/application/row/row_cache.dart';
|
||||||
import 'package:appflowy/plugins/database/domain/row_listener.dart';
|
import 'package:appflowy/plugins/database/domain/row_listener.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart';
|
import 'package:appflowy/plugins/database/widgets/setting/field_visibility_extension.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/row_entities.pb.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ class CardBloc extends Bloc<CardEvent, CardState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CellContext> _makeCells(
|
List<CellMeta> _makeCells(
|
||||||
FieldController fieldController,
|
FieldController fieldController,
|
||||||
String? groupFieldId,
|
String? groupFieldId,
|
||||||
List<CellContext> cellContexts,
|
List<CellContext> cellContexts,
|
||||||
@ -116,7 +117,15 @@ List<CellContext> _makeCells(
|
|||||||
!(fieldInfo.visibility?.isVisibleState() ?? false) ||
|
!(fieldInfo.visibility?.isVisibleState() ?? false) ||
|
||||||
(groupFieldId != null && cellContext.fieldId == groupFieldId);
|
(groupFieldId != null && cellContext.fieldId == groupFieldId);
|
||||||
});
|
});
|
||||||
return cellContexts.toList();
|
return cellContexts
|
||||||
|
.map(
|
||||||
|
(cellCtx) => CellMeta(
|
||||||
|
fieldId: cellCtx.fieldId,
|
||||||
|
rowId: cellCtx.rowId,
|
||||||
|
fieldType: fieldController.getField(cellCtx.fieldId)!.fieldType,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -124,17 +133,30 @@ class CardEvent with _$CardEvent {
|
|||||||
const factory CardEvent.initial() = _InitialRow;
|
const factory CardEvent.initial() = _InitialRow;
|
||||||
const factory CardEvent.setIsEditing(bool isEditing) = _IsEditing;
|
const factory CardEvent.setIsEditing(bool isEditing) = _IsEditing;
|
||||||
const factory CardEvent.didReceiveCells(
|
const factory CardEvent.didReceiveCells(
|
||||||
List<CellContext> cells,
|
List<CellMeta> cells,
|
||||||
ChangedReason reason,
|
ChangedReason reason,
|
||||||
) = _DidReceiveCells;
|
) = _DidReceiveCells;
|
||||||
const factory CardEvent.didUpdateRowMeta(RowMetaPB rowMeta) =
|
const factory CardEvent.didUpdateRowMeta(RowMetaPB rowMeta) =
|
||||||
_DidUpdateRowMeta;
|
_DidUpdateRowMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class CellMeta with _$CellMeta {
|
||||||
|
const CellMeta._();
|
||||||
|
|
||||||
|
const factory CellMeta({
|
||||||
|
required String fieldId,
|
||||||
|
required RowId rowId,
|
||||||
|
required FieldType fieldType,
|
||||||
|
}) = _DatabaseCellMeta;
|
||||||
|
|
||||||
|
CellContext cellContext() => CellContext(fieldId: fieldId, rowId: rowId);
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class CardState with _$CardState {
|
class CardState with _$CardState {
|
||||||
const factory CardState({
|
const factory CardState({
|
||||||
required List<CellContext> cells,
|
required List<CellMeta> cells,
|
||||||
required RowMetaPB rowMeta,
|
required RowMetaPB rowMeta,
|
||||||
required bool isEditing,
|
required bool isEditing,
|
||||||
ChangedReason? changeReason,
|
ChangedReason? changeReason,
|
||||||
@ -142,7 +164,7 @@ class CardState with _$CardState {
|
|||||||
|
|
||||||
factory CardState.initial(
|
factory CardState.initial(
|
||||||
RowMetaPB rowMeta,
|
RowMetaPB rowMeta,
|
||||||
List<CellContext> cells,
|
List<CellMeta> cells,
|
||||||
bool isEditing,
|
bool isEditing,
|
||||||
) =>
|
) =>
|
||||||
CardState(
|
CardState(
|
||||||
|
@ -42,7 +42,6 @@ class MobileGridRelationCellSkin extends IEditableRelationCellSkin {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return const FlowyText("Coming soon");
|
return const FlowyText("Coming soon");
|
||||||
|
@ -2,6 +2,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_she
|
|||||||
import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart';
|
import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart';
|
import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ class MobileGridURLCellSkin extends IEditableURLCellSkin {
|
|||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (context) => BlocProvider.value(
|
builder: (context) => BlocProvider.value(
|
||||||
value: bloc,
|
value: bloc,
|
||||||
child: MobileURLEditor(
|
child: MobileURLEditor(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
|
||||||
import 'package:appflowy/plugins/database/application/cell/bloc/checkbox_cell_bloc.dart';
|
import 'package:appflowy/plugins/database/application/cell/bloc/checkbox_cell_bloc.dart';
|
||||||
|
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../editable_cell_skeleton/checkbox.dart';
|
import '../editable_cell_skeleton/checkbox.dart';
|
||||||
@ -31,7 +32,7 @@ class MobileRowDetailCheckboxCellSkin extends IEditableCheckboxCellSkin {
|
|||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
child: FlowySvg(
|
child: FlowySvg(
|
||||||
state.isSelected ? FlowySvgs.check_filled_s : FlowySvgs.uncheck_s,
|
state.isSelected ? FlowySvgs.check_filled_s : FlowySvgs.uncheck_s,
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: AFThemeExtension.of(context).onBackground,
|
||||||
blendMode: BlendMode.dst,
|
blendMode: BlendMode.dst,
|
||||||
size: const Size.square(24),
|
size: const Size.square(24),
|
||||||
),
|
),
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
|
||||||
import 'package:appflowy/plugins/database/application/cell/bloc/checklist_cell_bloc.dart';
|
import 'package:appflowy/plugins/database/application/cell/bloc/checklist_cell_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_progress_bar.dart';
|
import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_progress_bar.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/cell_editor/mobile_checklist_cell_editor.dart';
|
import 'package:appflowy/plugins/database/widgets/cell_editor/mobile_checklist_cell_editor.dart';
|
||||||
|
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.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/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/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -25,7 +26,7 @@ class MobileRowDetailChecklistCellSkin extends IEditableChecklistCellSkin {
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
||||||
onTap: () => showMobileBottomSheet(
|
onTap: () => showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: bloc,
|
value: bloc,
|
||||||
|
@ -19,7 +19,6 @@ class MobileRowDetailRelationCellSkin extends IEditableRelationCellSkin {
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
||||||
onTap: () => showMobileBottomSheet(
|
onTap: () => showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return const FlowyText("Coming soon");
|
return const FlowyText("Coming soon");
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
||||||
import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart';
|
import 'package:appflowy/plugins/database/application/cell/bloc/url_cell_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart';
|
import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
|
|
||||||
import '../editable_cell_skeleton/url.dart';
|
import '../editable_cell_skeleton/url.dart';
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class MobileRowDetailURLCellSkin extends IEditableURLCellSkin {
|
|||||||
onTap: () => showMobileBottomSheet(
|
onTap: () => showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: bloc,
|
value: bloc,
|
||||||
|
@ -423,7 +423,7 @@ class _DeleteTaskButton extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DeleteTaskButtonState extends State<_DeleteTaskButton> {
|
class _DeleteTaskButtonState extends State<_DeleteTaskButton> {
|
||||||
final _materialStatesController = MaterialStatesController();
|
final _materialStatesController = WidgetStatesController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@ -438,16 +438,16 @@ class _DeleteTaskButtonState extends State<_DeleteTaskButton> {
|
|||||||
onHover: (_) => setState(() {}),
|
onHover: (_) => setState(() {}),
|
||||||
onFocusChange: (_) => setState(() {}),
|
onFocusChange: (_) => setState(() {}),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
fixedSize: const MaterialStatePropertyAll(Size.square(32)),
|
fixedSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
minimumSize: const MaterialStatePropertyAll(Size.square(32)),
|
minimumSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
maximumSize: const MaterialStatePropertyAll(Size.square(32)),
|
maximumSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
overlayColor: MaterialStateProperty.resolveWith((state) {
|
overlayColor: WidgetStateProperty.resolveWith((state) {
|
||||||
if (state.contains(MaterialState.focused)) {
|
if (state.contains(WidgetState.focused)) {
|
||||||
return AFThemeExtension.of(context).greyHover;
|
return AFThemeExtension.of(context).greyHover;
|
||||||
}
|
}
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
}),
|
}),
|
||||||
shape: const MaterialStatePropertyAll(
|
shape: const WidgetStatePropertyAll(
|
||||||
RoundedRectangleBorder(borderRadius: Corners.s6Border),
|
RoundedRectangleBorder(borderRadius: Corners.s6Border),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -455,8 +455,8 @@ class _DeleteTaskButtonState extends State<_DeleteTaskButton> {
|
|||||||
child: FlowySvg(
|
child: FlowySvg(
|
||||||
FlowySvgs.delete_s,
|
FlowySvgs.delete_s,
|
||||||
color: _materialStatesController.value
|
color: _materialStatesController.value
|
||||||
.contains(MaterialState.hovered) ||
|
.contains(WidgetState.hovered) ||
|
||||||
_materialStatesController.value.contains(MaterialState.focused)
|
_materialStatesController.value.contains(WidgetState.focused)
|
||||||
? Theme.of(context).colorScheme.error
|
? Theme.of(context).colorScheme.error
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
@ -422,7 +422,7 @@ class _UnselectRowButton extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _UnselectRowButtonState extends State<_UnselectRowButton> {
|
class _UnselectRowButtonState extends State<_UnselectRowButton> {
|
||||||
final _materialStatesController = MaterialStatesController();
|
final _materialStatesController = WidgetStatesController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@ -437,26 +437,25 @@ class _UnselectRowButtonState extends State<_UnselectRowButton> {
|
|||||||
onHover: (_) => setState(() {}),
|
onHover: (_) => setState(() {}),
|
||||||
onFocusChange: (_) => setState(() {}),
|
onFocusChange: (_) => setState(() {}),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
fixedSize: const MaterialStatePropertyAll(Size.square(32)),
|
fixedSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
minimumSize: const MaterialStatePropertyAll(Size.square(32)),
|
minimumSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
maximumSize: const MaterialStatePropertyAll(Size.square(32)),
|
maximumSize: const WidgetStatePropertyAll(Size.square(32)),
|
||||||
overlayColor: MaterialStateProperty.resolveWith((state) {
|
overlayColor: WidgetStateProperty.resolveWith((state) {
|
||||||
if (state.contains(MaterialState.focused)) {
|
if (state.contains(WidgetState.focused)) {
|
||||||
return AFThemeExtension.of(context).greyHover;
|
return AFThemeExtension.of(context).greyHover;
|
||||||
}
|
}
|
||||||
return Colors.transparent;
|
return Colors.transparent;
|
||||||
}),
|
}),
|
||||||
shape: const MaterialStatePropertyAll(
|
shape: const WidgetStatePropertyAll(
|
||||||
RoundedRectangleBorder(borderRadius: Corners.s6Border),
|
RoundedRectangleBorder(borderRadius: Corners.s6Border),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
statesController: _materialStatesController,
|
statesController: _materialStatesController,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: _materialStatesController.value
|
color: _materialStatesController.value.contains(WidgetState.hovered) ||
|
||||||
.contains(MaterialState.hovered) ||
|
_materialStatesController.value.contains(WidgetState.focused)
|
||||||
_materialStatesController.value.contains(MaterialState.focused)
|
|
||||||
? Theme.of(context).colorScheme.primary
|
? Theme.of(context).colorScheme.primary
|
||||||
: Theme.of(context).colorScheme.onBackground,
|
: AFThemeExtension.of(context).onBackground,
|
||||||
width: 12,
|
width: 12,
|
||||||
height: 1,
|
height: 1,
|
||||||
),
|
),
|
||||||
|
@ -380,7 +380,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
|
|||||||
icon: FlowySvg(
|
icon: FlowySvg(
|
||||||
FlowySvgs.three_dots_s,
|
FlowySvgs.three_dots_s,
|
||||||
size: const Size.square(16),
|
size: const Size.square(16),
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: AFThemeExtension.of(context).onBackground,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -462,7 +462,7 @@ class SelectOptionTagCell extends StatelessWidget {
|
|||||||
child: FlowySvg(
|
child: FlowySvg(
|
||||||
FlowySvgs.drag_element_s,
|
FlowySvgs.drag_element_s,
|
||||||
size: const Size.square(14),
|
size: const Size.square(14),
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: AFThemeExtension.of(context).onBackground,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -20,7 +20,7 @@ const List<FieldType> _supportedFieldTypes = [
|
|||||||
FieldType.LastEditedTime,
|
FieldType.LastEditedTime,
|
||||||
FieldType.CreatedTime,
|
FieldType.CreatedTime,
|
||||||
FieldType.Relation,
|
FieldType.Relation,
|
||||||
// FieldType.Summary,
|
FieldType.Summary,
|
||||||
];
|
];
|
||||||
|
|
||||||
class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate {
|
class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate {
|
||||||
|
@ -314,17 +314,17 @@ class ToggleHiddenFieldsVisibilityButton extends StatelessWidget {
|
|||||||
constraints: const BoxConstraints(minWidth: double.infinity),
|
constraints: const BoxConstraints(minWidth: double.infinity),
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
style: Theme.of(context).textButtonTheme.style?.copyWith(
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
overlayColor: MaterialStateProperty.all<Color>(
|
overlayColor: WidgetStateProperty.all<Color>(
|
||||||
Theme.of(context).hoverColor,
|
Theme.of(context).hoverColor,
|
||||||
),
|
),
|
||||||
alignment: AlignmentDirectional.centerStart,
|
alignment: AlignmentDirectional.centerStart,
|
||||||
splashFactory: NoSplash.splashFactory,
|
splashFactory: NoSplash.splashFactory,
|
||||||
padding: const MaterialStatePropertyAll(
|
padding: const WidgetStatePropertyAll(
|
||||||
EdgeInsets.symmetric(vertical: 14, horizontal: 6),
|
EdgeInsets.symmetric(vertical: 14, horizontal: 6),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -9,6 +9,7 @@ import 'package:appflowy/plugins/database/grid/application/sort/sort_editor_bloc
|
|||||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
import 'package:appflowy/workspace/application/view/view_bloc.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_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -128,7 +129,6 @@ void _showDatabaseFieldListFromToolbar(
|
|||||||
showHeader: true,
|
showHeader: true,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: LocaleKeys.grid_settings_properties.tr(),
|
title: LocaleKeys.grid_settings_properties.tr(),
|
||||||
showDivider: true,
|
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: context.read<ViewBloc>(),
|
value: context.read<ViewBloc>(),
|
||||||
@ -150,7 +150,7 @@ void _showEditSortPanelFromToolbar(
|
|||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
showDivider: false,
|
showDivider: false,
|
||||||
useSafeArea: false,
|
useSafeArea: false,
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
backgroundColor: AFThemeExtension.of(context).background,
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: context.read<SortEditorBloc>(),
|
value: context.read<SortEditorBloc>(),
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/database/application/share_bloc.dart';
|
import 'package:appflowy/plugins/database/application/share_bloc.dart';
|
||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
@ -13,6 +11,7 @@ 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/file_picker/file_picker_service.dart';
|
import 'package:flowy_infra/file_picker/file_picker_service.dart';
|
||||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class DatabaseShareButton extends StatelessWidget {
|
class DatabaseShareButton extends StatelessWidget {
|
||||||
@ -39,11 +38,7 @@ class DatabaseShareButton extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: BlocBuilder<DatabaseShareBloc, DatabaseShareState>(
|
child: BlocBuilder<DatabaseShareBloc, DatabaseShareState>(
|
||||||
builder: (context, state) => ConstrainedBox(
|
builder: (context, state) => IntrinsicWidth(
|
||||||
constraints: const BoxConstraints.expand(
|
|
||||||
height: 30,
|
|
||||||
width: 100,
|
|
||||||
),
|
|
||||||
child: DatabaseShareActionList(view: view),
|
child: DatabaseShareActionList(view: view),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -106,6 +101,8 @@ class DatabaseShareActionListState extends State<DatabaseShareActionList> {
|
|||||||
onPointerDown: (_) => controller.show(),
|
onPointerDown: (_) => controller.show(),
|
||||||
child: RoundedTextButton(
|
child: RoundedTextButton(
|
||||||
title: LocaleKeys.shareAction_buttonText.tr(),
|
title: LocaleKeys.shareAction_buttonText.tr(),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
fontSize: 14.0,
|
||||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
|
@ -20,7 +20,6 @@ import 'package:appflowy/util/debounce.dart';
|
|||||||
import 'package:appflowy/util/throttle.dart';
|
import 'package:appflowy/util/throttle.dart';
|
||||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -76,13 +75,15 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
|
|
||||||
StreamSubscription? _transactionSubscription;
|
StreamSubscription? _transactionSubscription;
|
||||||
|
|
||||||
final _updateSelectionDebounce = Debounce();
|
bool isClosing = false;
|
||||||
final _syncThrottle = Throttler(duration: const Duration(milliseconds: 500));
|
|
||||||
|
static const _syncDuration = Duration(milliseconds: 250);
|
||||||
|
final _updateSelectionDebounce = Debounce(duration: _syncDuration);
|
||||||
|
final _syncThrottle = Throttler(duration: _syncDuration);
|
||||||
|
|
||||||
// The conflict handle logic is not fully implemented yet
|
// The conflict handle logic is not fully implemented yet
|
||||||
// use the syncTimer to force to reload the document state when the conflict happens.
|
// use the syncTimer to force to reload the document state when the conflict happens.
|
||||||
Timer? _syncTimer;
|
Timer? _syncTimer;
|
||||||
bool _shouldSync = false;
|
|
||||||
|
|
||||||
bool get isLocalMode {
|
bool get isLocalMode {
|
||||||
final userProfilePB = state.userProfilePB;
|
final userProfilePB = state.userProfilePB;
|
||||||
@ -92,6 +93,10 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
isClosing = true;
|
||||||
|
_updateSelectionDebounce.dispose();
|
||||||
|
_syncThrottle.dispose();
|
||||||
|
await _documentService.syncAwarenessStates(documentId: documentId);
|
||||||
await _documentListener.stop();
|
await _documentListener.stop();
|
||||||
await _syncStateListener.stop();
|
await _syncStateListener.stop();
|
||||||
await _viewListener?.stop();
|
await _viewListener?.stop();
|
||||||
@ -110,7 +115,6 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
) async {
|
) async {
|
||||||
await event.when(
|
await event.when(
|
||||||
initial: () async {
|
initial: () async {
|
||||||
_resetSyncTimer();
|
|
||||||
final result = await _fetchDocumentState();
|
final result = await _fetchDocumentState();
|
||||||
_onViewChanged();
|
_onViewChanged();
|
||||||
_onDocumentChanged();
|
_onDocumentChanged();
|
||||||
@ -205,19 +209,6 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resetSyncTimer() {
|
|
||||||
_syncTimer?.cancel();
|
|
||||||
_syncTimer = null;
|
|
||||||
_syncTimer = Timer.periodic(const Duration(seconds: 10), (_) {
|
|
||||||
if (!_shouldSync) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.debug('auto sync document');
|
|
||||||
// unawaited(_documentCollabAdapter.forceReload());
|
|
||||||
_shouldSync = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetch document
|
/// Fetch document
|
||||||
Future<FlowyResult<EditorState?, FlowyError>> _fetchDocumentState() async {
|
Future<FlowyResult<EditorState?, FlowyError>> _fetchDocumentState() async {
|
||||||
final result = await _documentService.openDocument(documentId: documentId);
|
final result = await _documentService.openDocument(documentId: documentId);
|
||||||
@ -257,10 +248,6 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
// ignore: invalid_use_of_visible_for_testing_member
|
// ignore: invalid_use_of_visible_for_testing_member
|
||||||
emit(state.copyWith(isDocumentEmpty: editorState.document.isEmpty));
|
emit(state.copyWith(isDocumentEmpty: editorState.document.isEmpty));
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the sync timer
|
|
||||||
_shouldSync = true;
|
|
||||||
_resetSyncTimer();
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -322,8 +309,6 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unawaited(_documentCollabAdapter.syncV3(docEvent: docEvent));
|
unawaited(_documentCollabAdapter.syncV3(docEvent: docEvent));
|
||||||
|
|
||||||
_resetSyncTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAwarenessStatesUpdate(
|
Future<void> _onAwarenessStatesUpdate(
|
||||||
@ -347,13 +332,15 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _throttleSyncDoc(DocEventPB docEvent) {
|
void _throttleSyncDoc(DocEventPB docEvent) {
|
||||||
_shouldSync = true;
|
|
||||||
_syncThrottle.call(() {
|
_syncThrottle.call(() {
|
||||||
_onDocumentStateUpdate(docEvent);
|
_onDocumentStateUpdate(docEvent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSelectionUpdate() async {
|
Future<void> _onSelectionUpdate() async {
|
||||||
|
if (isClosing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final user = state.userProfilePB;
|
final user = state.userProfilePB;
|
||||||
final deviceId = ApplicationInfo.deviceId;
|
final deviceId = ApplicationInfo.deviceId;
|
||||||
if (!FeatureFlag.syncDocument.isOn || user == null) {
|
if (!FeatureFlag.syncDocument.isOn || user == null) {
|
||||||
|
@ -183,7 +183,7 @@ class DocumentCollabAdapter {
|
|||||||
for (final state in values) {
|
for (final state in values) {
|
||||||
// the following code is only for version 1
|
// the following code is only for version 1
|
||||||
if (state.version != 1 || state.metadata.isEmpty) {
|
if (state.version != 1 || state.metadata.isEmpty) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
final uid = state.user.uid.toString();
|
final uid = state.user.uid.toString();
|
||||||
final did = state.user.deviceId;
|
final did = state.user.deviceId;
|
||||||
@ -244,9 +244,8 @@ class DocumentCollabAdapter {
|
|||||||
);
|
);
|
||||||
remoteSelections.add(remoteSelection);
|
remoteSelections.add(remoteSelection);
|
||||||
}
|
}
|
||||||
if (remoteSelections.isNotEmpty) {
|
|
||||||
editorState.remoteSelections.value = remoteSelections;
|
editorState.remoteSelections.value = remoteSelections;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||||
@ -10,7 +11,13 @@ import 'package:appflowy_editor/appflowy_editor.dart'
|
|||||||
Delta,
|
Delta,
|
||||||
ParagraphBlockKeys,
|
ParagraphBlockKeys,
|
||||||
NodeIterator,
|
NodeIterator,
|
||||||
NodeExternalValues;
|
NodeExternalValues,
|
||||||
|
HeadingBlockKeys,
|
||||||
|
QuoteBlockKeys,
|
||||||
|
NumberedListBlockKeys,
|
||||||
|
BulletedListBlockKeys,
|
||||||
|
blockComponentDelta;
|
||||||
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:nanoid/nanoid.dart';
|
import 'package:nanoid/nanoid.dart';
|
||||||
|
|
||||||
@ -144,21 +151,25 @@ extension BlockToNode on BlockPB {
|
|||||||
final deltaString = meta.textMap[externalId];
|
final deltaString = meta.textMap[externalId];
|
||||||
if (deltaString != null) {
|
if (deltaString != null) {
|
||||||
final delta = jsonDecode(deltaString);
|
final delta = jsonDecode(deltaString);
|
||||||
map['delta'] = delta;
|
map[blockComponentDelta] = delta;
|
||||||
// map.putIfAbsent(
|
|
||||||
// 'delta',
|
|
||||||
// () => delta,
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Attributes adapterCallback(Attributes map) => map
|
||||||
|
..putIfAbsent(
|
||||||
|
blockComponentDelta,
|
||||||
|
() => Delta().toJson(),
|
||||||
|
);
|
||||||
|
|
||||||
final adapter = {
|
final adapter = {
|
||||||
ParagraphBlockKeys.type: (Attributes map) => map
|
ParagraphBlockKeys.type: adapterCallback,
|
||||||
..putIfAbsent(
|
HeadingBlockKeys.type: adapterCallback,
|
||||||
'delta',
|
CodeBlockKeys.type: adapterCallback,
|
||||||
() => Delta().toJson(),
|
QuoteBlockKeys.type: adapterCallback,
|
||||||
),
|
NumberedListBlockKeys.type: adapterCallback,
|
||||||
|
BulletedListBlockKeys.type: adapterCallback,
|
||||||
|
ToggleListBlockKeys.type: adapterCallback,
|
||||||
};
|
};
|
||||||
return adapter[ty]?.call(map) ?? map;
|
return adapter[ty]?.call(map) ?? map;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
library document_plugin;
|
library document_plugin;
|
||||||
|
|
||||||
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';
|
||||||
@ -22,6 +20,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
|||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class DocumentPluginBuilder extends PluginBuilder {
|
class DocumentPluginBuilder extends PluginBuilder {
|
||||||
@ -130,7 +129,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget get leftBarItem => ViewTitleBar(view: view);
|
Widget get leftBarItem => ViewTitleBar(key: ValueKey(view.id), view: view);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view);
|
Widget tabBarItem(String pluginId) => ViewTabBarItem(view: notifier.view);
|
||||||
@ -162,7 +161,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder
|
|||||||
key: ValueKey('share_button_${view.id}'),
|
key: ValueKey('share_button_${view.id}'),
|
||||||
view: view,
|
view: view,
|
||||||
),
|
),
|
||||||
const HSpace(4),
|
const HSpace(10),
|
||||||
ViewFavoriteButton(
|
ViewFavoriteButton(
|
||||||
key: ValueKey('favorite_button_${view.id}'),
|
key: ValueKey('favorite_button_${view.id}'),
|
||||||
view: view,
|
view: view,
|
||||||
|
@ -23,7 +23,7 @@ class DocumentBanner extends StatelessWidget {
|
|||||||
constraints: const BoxConstraints(minHeight: 60),
|
constraints: const BoxConstraints(minHeight: 60),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: colorScheme.surfaceVariant,
|
color: colorScheme.surfaceContainerHighest,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
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/mobile/application/page_style/document_page_style_bloc.dart';
|
import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_page.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_page.dart';
|
||||||
@ -13,6 +10,8 @@ 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';
|
||||||
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
|
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
|
||||||
import 'package:flowy_infra/theme_extension.dart';
|
import 'package:flowy_infra/theme_extension.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';
|
||||||
|
|
||||||
Map<String, BlockComponentBuilder> getEditorBuilderMap({
|
Map<String, BlockComponentBuilder> getEditorBuilderMap({
|
||||||
@ -93,8 +92,9 @@ Map<String, BlockComponentBuilder> getEditorBuilderMap({
|
|||||||
final factor = pageStyle.fontLayout.factor;
|
final factor = pageStyle.fontLayout.factor;
|
||||||
final headingPaddings = pageStyle.lineHeightLayout.headingPaddings
|
final headingPaddings = pageStyle.lineHeightLayout.headingPaddings
|
||||||
.map((e) => e * factor);
|
.map((e) => e * factor);
|
||||||
final level = node.attributes[HeadingBlockKeys.level] ?? 6;
|
int level = node.attributes[HeadingBlockKeys.level] ?? 6;
|
||||||
return EdgeInsets.only(top: headingPaddings.elementAt(level));
|
level = level.clamp(1, 6);
|
||||||
|
return EdgeInsets.only(top: headingPaddings.elementAt(level - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return const EdgeInsets.only(top: 12.0, bottom: 4.0);
|
return const EdgeInsets.only(top: 12.0, bottom: 4.0);
|
||||||
|
@ -56,7 +56,18 @@ final List<CommandShortcutEvent> commandShortcutEvents = [
|
|||||||
customPasteCommand,
|
customPasteCommand,
|
||||||
customCutCommand,
|
customCutCommand,
|
||||||
...customTextAlignCommands,
|
...customTextAlignCommands,
|
||||||
...standardCommandShortcutEvents,
|
|
||||||
|
// remove standard shortcuts for copy, cut, paste, todo
|
||||||
|
...standardCommandShortcutEvents
|
||||||
|
..removeWhere(
|
||||||
|
(shortcut) => [
|
||||||
|
copyCommand,
|
||||||
|
cutCommand,
|
||||||
|
pasteCommand,
|
||||||
|
toggleTodoListCommand,
|
||||||
|
].contains(shortcut),
|
||||||
|
),
|
||||||
|
|
||||||
emojiShortcutEvent,
|
emojiShortcutEvent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -90,7 +101,6 @@ class AppFlowyEditorPage extends StatefulWidget {
|
|||||||
final String Function(Node)? placeholderText;
|
final String Function(Node)? placeholderText;
|
||||||
|
|
||||||
/// Used to provide an initial selection on Page-load
|
/// Used to provide an initial selection on Page-load
|
||||||
///
|
|
||||||
final Selection? initialSelection;
|
final Selection? initialSelection;
|
||||||
|
|
||||||
final bool useViewInfoBloc;
|
final bool useViewInfoBloc;
|
||||||
@ -111,15 +121,8 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
late final List<CommandShortcutEvent> commandShortcutEvents = [
|
late final List<CommandShortcutEvent> cmdShortcutEvents = [
|
||||||
toggleToggleListCommand,
|
...commandShortcutEvents,
|
||||||
...localizedCodeBlockCommands,
|
|
||||||
customCopyCommand,
|
|
||||||
customPasteCommand,
|
|
||||||
customCutCommand,
|
|
||||||
...customTextAlignCommands,
|
|
||||||
...standardCommandShortcutEvents,
|
|
||||||
emojiShortcutEvent,
|
|
||||||
..._buildFindAndReplaceCommands(),
|
..._buildFindAndReplaceCommands(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -309,7 +312,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
),
|
),
|
||||||
// customize the shortcuts
|
// customize the shortcuts
|
||||||
characterShortcutEvents: characterShortcutEvents,
|
characterShortcutEvents: characterShortcutEvents,
|
||||||
commandShortcutEvents: commandShortcutEvents,
|
commandShortcutEvents: cmdShortcutEvents,
|
||||||
// customize the context menu items
|
// customize the context menu items
|
||||||
contextMenuItems: customContextMenuItems,
|
contextMenuItems: customContextMenuItems,
|
||||||
// customize the header and footer.
|
// customize the header and footer.
|
||||||
@ -392,12 +395,6 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
if (widget.editorState.document.isEmpty) {
|
if (widget.editorState.document.isEmpty) {
|
||||||
return (true, Selection.collapsed(Position(path: [0])));
|
return (true, Selection.collapsed(Position(path: [0])));
|
||||||
}
|
}
|
||||||
final nodes =
|
|
||||||
widget.editorState.document.root.children.where((e) => e.delta != null);
|
|
||||||
final isAllEmpty = nodes.isNotEmpty && nodes.every((e) => e.delta!.isEmpty);
|
|
||||||
if (isAllEmpty) {
|
|
||||||
return (true, Selection.collapsed(Position(path: nodes.first.path)));
|
|
||||||
}
|
|
||||||
return const (false, null);
|
return const (false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +404,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
final customizeShortcuts =
|
final customizeShortcuts =
|
||||||
await settingsShortcutService.getCustomizeShortcuts();
|
await settingsShortcutService.getCustomizeShortcuts();
|
||||||
await settingsShortcutService.updateCommandShortcuts(
|
await settingsShortcutService.updateCommandShortcuts(
|
||||||
commandShortcutEvents,
|
cmdShortcutEvents,
|
||||||
customizeShortcuts,
|
customizeShortcuts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -437,7 +434,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
Material(
|
Material(
|
||||||
child: DecoratedBox(
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
child: FindAndReplaceMenuWidget(
|
child: FindAndReplaceMenuWidget(
|
||||||
|
@ -74,7 +74,6 @@ class MobileBlockActionButtons extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
showCloseButton: true,
|
showCloseButton: true,
|
||||||
showDivider: true,
|
|
||||||
showDragHandle: true,
|
showDragHandle: true,
|
||||||
title: LocaleKeys.document_plugins_action.tr(),
|
title: LocaleKeys.document_plugins_action.tr(),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -141,7 +141,7 @@ enum OptionDepthType {
|
|||||||
|
|
||||||
class DividerOptionAction extends CustomActionCell {
|
class DividerOptionAction extends CustomActionCell {
|
||||||
@override
|
@override
|
||||||
Widget buildWithContext(BuildContext context) {
|
Widget buildWithContext(BuildContext context, PopoverController controller) {
|
||||||
return const Divider(
|
return const Divider(
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
thickness: 1.0,
|
thickness: 1.0,
|
||||||
@ -300,7 +300,7 @@ class ColorOptionAction extends PopoverActionCell {
|
|||||||
colors: colors,
|
colors: colors,
|
||||||
selected: selectedColor,
|
selected: selectedColor,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: AFThemeExtension.of(context).onBackground,
|
||||||
),
|
),
|
||||||
onTap: (option, index) async {
|
onTap: (option, index) async {
|
||||||
final transaction = editorState.transaction;
|
final transaction = editorState.transaction;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
|
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
|
||||||
import 'package:appflowy/plugins/base/icon/icon_picker.dart';
|
import 'package:appflowy/plugins/base/icon/icon_picker.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_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
class EmojiPickerButton extends StatelessWidget {
|
class EmojiPickerButton extends StatelessWidget {
|
||||||
@ -19,6 +18,7 @@ class EmojiPickerButton extends StatelessWidget {
|
|||||||
this.offset,
|
this.offset,
|
||||||
this.direction,
|
this.direction,
|
||||||
this.title,
|
this.title,
|
||||||
|
this.showBorder = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String emoji;
|
final String emoji;
|
||||||
@ -30,6 +30,7 @@ class EmojiPickerButton extends StatelessWidget {
|
|||||||
final Offset? offset;
|
final Offset? offset;
|
||||||
final PopoverDirection? direction;
|
final PopoverDirection? direction;
|
||||||
final String? title;
|
final String? title;
|
||||||
|
final bool showBorder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -51,22 +52,28 @@ class EmojiPickerButton extends StatelessWidget {
|
|||||||
onExit: () {},
|
onExit: () {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: emoji.isEmpty && defaultIcon != null
|
child: Container(
|
||||||
? FlowyButton(
|
width: 30.0,
|
||||||
useIntrinsicWidth: true,
|
height: 30.0,
|
||||||
text: defaultIcon!,
|
decoration: BoxDecoration(
|
||||||
onTap: popoverController.show,
|
borderRadius: BorderRadius.circular(8),
|
||||||
)
|
border: showBorder
|
||||||
: FlowyTextButton(
|
? Border.all(
|
||||||
emoji,
|
color: Theme.of(context).dividerColor,
|
||||||
overflow: TextOverflow.visible,
|
)
|
||||||
fontSize: emojiSize,
|
: null,
|
||||||
padding: EdgeInsets.zero,
|
),
|
||||||
constraints: const BoxConstraints(minWidth: 35.0),
|
child: FlowyButton(
|
||||||
fillColor: Colors.transparent,
|
margin: emoji.isEmpty && defaultIcon != null
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
? EdgeInsets.zero
|
||||||
onPressed: popoverController.show,
|
: const EdgeInsets.only(left: 2.0),
|
||||||
),
|
expandText: false,
|
||||||
|
text: emoji.isEmpty && defaultIcon != null
|
||||||
|
? defaultIcon!
|
||||||
|
: FlowyText.emoji(emoji, fontSize: emojiSize),
|
||||||
|
onTap: popoverController.show,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return FlowyTextButton(
|
return FlowyTextButton(
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selectable_item_list_menu.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selectable_item_list_menu.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/string_extension.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/string_extension.dart';
|
||||||
@ -8,7 +6,9 @@ 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';
|
||||||
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/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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
CodeBlockLanguagePickerBuilder codeBlockLanguagePickerBuilder = (
|
CodeBlockLanguagePickerBuilder codeBlockLanguagePickerBuilder = (
|
||||||
@ -70,7 +70,7 @@ class _CodeBlockLanguageSelectorState
|
|||||||
widget.language?.capitalize() ??
|
widget.language?.capitalize() ??
|
||||||
LocaleKeys.document_codeBlock_language_auto.tr(),
|
LocaleKeys.document_codeBlock_language_auto.tr(),
|
||||||
constraints: const BoxConstraints(minWidth: 50),
|
constraints: const BoxConstraints(minWidth: 50),
|
||||||
fontColor: Theme.of(context).colorScheme.onBackground,
|
fontColor: AFThemeExtension.of(context).onBackground,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 4),
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
@ -61,7 +61,7 @@ class _ErrorBlockComponentWidgetState extends State<ErrorBlockComponentWidget>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget child = DecoratedBox(
|
Widget child = DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
@ -74,17 +74,9 @@ class _ErrorBlockComponentWidgetState extends State<ErrorBlockComponentWidget>
|
|||||||
ClipboardServiceData(plainText: jsonEncode(node.toJson())),
|
ClipboardServiceData(plainText: jsonEncode(node.toJson())),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
text: SizedBox(
|
text: PlatformExtension.isDesktopOrWeb
|
||||||
height: 52,
|
? _buildDesktopErrorBlock(context)
|
||||||
child: Row(
|
: _buildMobileErrorBlock(context),
|
||||||
children: [
|
|
||||||
const HSpace(4),
|
|
||||||
FlowyText(
|
|
||||||
LocaleKeys.document_errorBlock_theBlockIsNotSupported.tr(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -111,4 +103,44 @@ class _ErrorBlockComponentWidgetState extends State<ErrorBlockComponentWidget>
|
|||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildDesktopErrorBlock(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
child: Wrap(
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
const HSpace(4),
|
||||||
|
FlowyText.regular(
|
||||||
|
LocaleKeys.document_errorBlock_theBlockIsNotSupported.tr(),
|
||||||
|
),
|
||||||
|
const HSpace(4),
|
||||||
|
FlowyText.regular(
|
||||||
|
'(${LocaleKeys.document_errorBlock_clickToCopyTheBlockContent.tr()})',
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildMobileErrorBlock(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 4),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
FlowyText.regular(
|
||||||
|
LocaleKeys.document_errorBlock_theBlockIsNotSupported.tr(),
|
||||||
|
),
|
||||||
|
const VSpace(6),
|
||||||
|
FlowyText.regular(
|
||||||
|
'(${LocaleKeys.document_errorBlock_clickToCopyTheBlockContent.tr()})',
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
fontSize: 12.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ 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_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder;
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
@ -300,9 +300,10 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
: (CoverType.color, '0xffe8e0ff'),
|
: (CoverType.color, '0xffe8e0ff'),
|
||||||
),
|
),
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: const FlowySvg(FlowySvgs.image_s),
|
leftIcon: const FlowySvg(FlowySvgs.add_cover_s),
|
||||||
text: FlowyText.small(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_addCover.tr(),
|
LocaleKeys.document_plugins_cover_addCover.tr(),
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -311,28 +312,24 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
if (widget.hasIcon) {
|
if (widget.hasIcon) {
|
||||||
children.add(
|
children.add(
|
||||||
FlowyButton(
|
FlowyButton(
|
||||||
leftIconSize: const Size.square(18),
|
|
||||||
onTap: () => widget.onIconOrCoverChanged(icon: ""),
|
onTap: () => widget.onIconOrCoverChanged(icon: ""),
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: const Icon(
|
leftIcon: const FlowySvg(FlowySvgs.add_icon_s),
|
||||||
Icons.emoji_emotions_outlined,
|
iconPadding: 4.0,
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
text: FlowyText.small(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Widget child = FlowyButton(
|
Widget child = FlowyButton(
|
||||||
leftIconSize: const Size.square(18),
|
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: const Icon(
|
leftIcon: const FlowySvg(FlowySvgs.add_icon_s),
|
||||||
Icons.emoji_emotions_outlined,
|
iconPadding: 4.0,
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
text: FlowyText.small(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_addIcon.tr(),
|
LocaleKeys.document_plugins_cover_addIcon.tr(),
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
onTap: PlatformExtension.isDesktop
|
onTap: PlatformExtension.isDesktop
|
||||||
? null
|
? null
|
||||||
|
@ -49,7 +49,7 @@ class ImagePlaceholderState extends State<ImagePlaceholder> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Widget child = DecoratedBox(
|
final Widget child = DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
child: FlowyHover(
|
child: FlowyHover(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user