Skip to content

Commit a0481e8

Browse files
authored
chore: bump version 0.3.0 (#3252)
1 parent affd253 commit a0481e8

File tree

11 files changed

+106
-37
lines changed

11 files changed

+106
-37
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Release Notes
22

3+
## Version 0.3.0 - 08/22/2023
4+
5+
### New Features
6+
7+
- Improve paste features:
8+
- Paste HTML content from website.
9+
- Paste image from clipboard.
10+
11+
- Support Group by Date in Kanban Board.
12+
- Notarize the macOS package, which is now verified by Apple.
13+
- Add Persian language translations.
14+
15+
### Bug fixes
16+
17+
- Some UI issues
18+
319
## Version 0.2.9 - 08/08/2023
420

521
### New Features

frontend/Makefile.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
2424
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
2525
CARGO_MAKE_CRATE_NAME = "dart-ffi"
2626
LIB_NAME = "dart_ffi"
27-
CURRENT_APP_VERSION = "0.2.9"
27+
CURRENT_APP_VERSION = "0.3.0"
2828
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
2929
PRODUCT_NAME = "AppFlowy"
3030
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html

frontend/appflowy_flutter/integration_test/document/document_copy_and_paste_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ extension on WidgetTester {
245245
await beforeTest?.call(editor.getCurrentEditorState());
246246

247247
// mock the clipboard
248-
getIt<ClipboardService>().setData(
248+
await getIt<ClipboardService>().setData(
249249
ClipboardServiceData(
250250
plainText: plainText,
251251
html: html,

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
5252
...codeBlockCommands,
5353
customCopyCommand,
5454
customPasteCommand,
55+
customCutCommand,
5556
...standardCommandShortcutEvents,
5657
];
5758

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ final inAppJsonFormat = CustomValueFormat<String>(
2222
}
2323
return null;
2424
},
25+
onEncode: (value, platformType) => utf8.encode(value),
2526
);
2627

2728
class ClipboardServiceData {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart';
2+
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
3+
import 'package:appflowy_editor/appflowy_editor.dart';
4+
import 'package:flutter/material.dart';
5+
6+
/// cut.
7+
///
8+
/// - support
9+
/// - desktop
10+
/// - web
11+
/// - mobile
12+
///
13+
final CommandShortcutEvent customCutCommand = CommandShortcutEvent(
14+
key: 'cut the selected content',
15+
command: 'ctrl+x',
16+
macOSCommand: 'cmd+x',
17+
handler: _cutCommandHandler,
18+
);
19+
20+
CommandShortcutEventHandler _cutCommandHandler = (editorState) {
21+
customCopyCommand.execute(editorState);
22+
editorState.deleteSelectionIfNeeded();
23+
return KeyEventResult.handled;
24+
};

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/copy_and_paste/editor_state_paste_node_extension.dart

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,29 @@ extension PasteNodes on EditorState {
1414
final transaction = this.transaction;
1515
final insertedDelta = insertedNode.delta;
1616
// if the node is empty, replace it with the inserted node.
17-
if (delta.isEmpty || insertedDelta == null) {
17+
if (delta.isEmpty) {
1818
transaction.insertNode(
1919
selection.end.path.next,
20-
node.copyWith(
21-
type: node.type,
22-
attributes: {
23-
...node.attributes,
24-
...insertedNode.attributes,
25-
},
26-
),
20+
insertedDelta == null
21+
? node.copyWith(
22+
type: node.type,
23+
attributes: {
24+
...node.attributes,
25+
...insertedNode.attributes,
26+
},
27+
)
28+
: insertedNode,
2729
);
2830
transaction.deleteNode(node);
31+
final path = calculatePath(selection.end.path, [insertedNode]);
32+
final offset = calculateLength([insertedNode]);
2933
transaction.afterSelection = Selection.collapsed(
3034
Position(
31-
path: selection.end.path,
32-
offset: insertedDelta?.length ?? 0,
35+
path: path,
36+
offset: offset,
3337
),
3438
);
35-
} else {
39+
} else if (insertedDelta != null) {
3640
// if the node is not empty, insert the delta from inserted node after the selection.
3741
transaction.insertTextDelta(node, selection.endIndex, insertedDelta);
3842
}
@@ -53,7 +57,7 @@ extension PasteNodes on EditorState {
5357
}
5458
final transaction = this.transaction;
5559

56-
final lastNodeLength = nodes.last.delta?.length ?? 0;
60+
final lastNodeLength = calculateLength(nodes);
5761
// merge the current selected node delta into the nodes.
5862
if (delta.isNotEmpty) {
5963
nodes.first.insertDelta(
@@ -86,13 +90,10 @@ extension PasteNodes on EditorState {
8690
// delete the current node.
8791
transaction.deleteNode(node);
8892

89-
var path = selection.end.path;
90-
for (var i = 0; i < nodes.length; i++) {
91-
path = path.next;
92-
}
93+
final path = calculatePath(selection.start.path, nodes);
9394
transaction.afterSelection = Selection.collapsed(
9495
Position(
95-
path: path.previous, // because a node is deleted.
96+
path: path,
9697
offset: lastNodeLength,
9798
),
9899
);
@@ -116,6 +117,28 @@ extension PasteNodes on EditorState {
116117
assert(this.selection?.isCollapsed == true);
117118
return this.selection;
118119
}
120+
121+
Path calculatePath(Path start, List<Node> nodes) {
122+
var path = start;
123+
for (var i = 0; i < nodes.length; i++) {
124+
path = path.next;
125+
}
126+
path = path.previous;
127+
if (nodes.last.children.isNotEmpty) {
128+
return [
129+
...path,
130+
...calculatePath([0], nodes.last.children.toList())
131+
];
132+
}
133+
return path;
134+
}
135+
136+
int calculateLength(List<Node> nodes) {
137+
if (nodes.last.children.isNotEmpty) {
138+
return calculateLength(nodes.last.children.toList());
139+
}
140+
return nodes.last.delta?.length ?? 0;
141+
}
119142
}
120143

121144
extension on Node {

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export 'callout/callout_block_component.dart';
44
export 'code_block/code_block_component.dart';
55
export 'code_block/code_block_shortcut_event.dart';
66
export 'copy_and_paste/custom_copy_command.dart';
7+
export 'copy_and_paste/custom_cut_command.dart';
78
export 'copy_and_paste/custom_paste_command.dart';
89
export 'database/database_view_block_component.dart';
910
export 'database/inline_database_menu_item.dart';

frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_user_view.dart

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import 'dart:convert';
21
import 'dart:async';
2+
import 'dart:convert';
33

44
import 'package:appflowy/env/env.dart';
55
import 'package:appflowy/generated/flowy_svgs.g.dart';
@@ -65,7 +65,7 @@ class SettingsUserView extends StatelessWidget {
6565
);
6666
}
6767

68-
/// Renders either a login or logout button based on the user's authentication status.
68+
/// Renders either a login or logout button based on the user's authentication status, or nothing if Supabase is not enabled.
6969
///
7070
/// This function checks the current user's authentication type and Supabase
7171
/// configuration to determine whether to render a third-party login button
@@ -74,14 +74,17 @@ class SettingsUserView extends StatelessWidget {
7474
BuildContext context,
7575
SettingsUserState state,
7676
) {
77-
if (isSupabaseEnabled) {
78-
// If the user is logged in locally, render a third-party login button.
79-
if (state.userProfile.authType == AuthTypePB.Local) {
80-
return SettingThirdPartyLogin(
81-
didLogin: didLogin,
82-
);
83-
}
77+
if (!isSupabaseEnabled) {
78+
return const SizedBox.shrink();
8479
}
80+
81+
// If the user is logged in locally, render a third-party login button.
82+
if (state.userProfile.authType == AuthTypePB.Local) {
83+
return SettingThirdPartyLogin(
84+
didLogin: didLogin,
85+
);
86+
}
87+
8588
return SettingLogoutButton(user: user, didLogout: didLogout);
8689
}
8790

frontend/appflowy_flutter/pubspec.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ packages:
5454
dependency: "direct main"
5555
description:
5656
path: "."
57-
ref: "56474e8b"
58-
resolved-ref: "56474e8bd9f08be7090495c255eea20a694ab1f3"
57+
ref: f4db21c
58+
resolved-ref: f4db21c3678290d133ae6cffa015d3d79920bf84
5959
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
6060
source: git
6161
version: "1.2.3"
@@ -1451,18 +1451,18 @@ packages:
14511451
dependency: "direct main"
14521452
description:
14531453
name: super_clipboard
1454-
sha256: "204284b1a721d33a65bcab077b191a3b7379b46a231f05688d17220153338ede"
1454+
sha256: ba484eb42ce621b69241d18d2a8494109589e8796eb6a3399e6c8f9cdaab8303
14551455
url: "https://pub.dev"
14561456
source: hosted
1457-
version: "0.6.0"
1457+
version: "0.6.3"
14581458
super_native_extensions:
14591459
dependency: transitive
14601460
description:
14611461
name: super_native_extensions
1462-
sha256: "1f15e9b1adb0bc59cf9b889a0b248f3c192fa17e2d5c923aeeec6d4fa2eeffd6"
1462+
sha256: dfe0a1c74430db946be973878da3f8611b8f124137f1dcbdf883e4605db40bd8
14631463
url: "https://pub.dev"
14641464
source: hosted
1465-
version: "0.6.0"
1465+
version: "0.6.3"
14661466
sync_http:
14671467
dependency: transitive
14681468
description:

0 commit comments

Comments
 (0)