Skip to content

Commit 9a4cde0

Browse files
authored
Merge pull request #1991 from AppFlowy-IO/fix_0_1_1
Fix release/0.1.1 known issues.
2 parents 972ef21 + d6d591f commit 9a4cde0

File tree

16 files changed

+320
-110
lines changed

16 files changed

+320
-110
lines changed

frontend/appflowy_flutter/assets/translations/en.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,16 +344,18 @@
344344
"referencedGrid": "Referenced Grid",
345345
"autoCompletionMenuItemName": "Auto Completion",
346346
"autoGeneratorMenuItemName": "Auto Generator",
347-
"autoGeneratorTitleName": "Open AI: Auto Generator",
347+
"autoGeneratorTitleName": "OpenAI: Ask AI to write anything...",
348348
"autoGeneratorLearnMore": "Learn more",
349349
"autoGeneratorGenerate": "Generate",
350350
"autoGeneratorHintText": "Tell us what you want to generate by OpenAI ...",
351351
"autoGeneratorCantGetOpenAIKey": "Can't get OpenAI key",
352-
"smartEditTitleName": "Open AI: Smart Edit",
352+
"smartEdit": "Smart Edit",
353+
"smartEditTitleName": "OpenAI: Smart Edit",
353354
"smartEditFixSpelling": "Fix spelling",
354355
"smartEditSummarize": "Summarize",
355356
"smartEditCouldNotFetchResult": "Could not fetch result from OpenAI",
356357
"smartEditCouldNotFetchKey": "Could not fetch OpenAI key",
358+
"smartEditDisabled": "Connect OpenAI in Settings",
357359
"cover": {
358360
"changeCover": "Change Cover",
359361
"colors": "Colors",

frontend/appflowy_flutter/lib/plugins/document/document_page.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,7 @@ class _AppFlowyEditorPageState extends State<_AppFlowyEditorPage> {
183183
],
184184
],
185185
toolbarItems: [
186-
if (openAIKey != null && openAIKey!.isNotEmpty) ...[
187-
smartEditItem,
188-
]
186+
smartEditItem,
189187
],
190188
themeData: theme.copyWith(extensions: [
191189
...theme.extensions.values,

frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
1616
import 'package:flowy_infra_ui/style_widget/text.dart';
1717
import 'package:flutter/material.dart';
1818
import 'package:shared_preferences/shared_preferences.dart';
19+
import 'package:path/path.dart' as path;
1920

2021
const String kLocalImagesKey = 'local_images';
2122

@@ -263,7 +264,7 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
263264
if (path != null) {
264265
final directory = await _coverPath();
265266
final newPath = await File(path).copy(
266-
'$directory/${path.split('/').last}',
267+
'$directory/${path.split(path).last}}',
267268
);
268269
imageNames.add(newPath.path);
269270
}
@@ -274,7 +275,7 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
274275

275276
Future<String> _coverPath() async {
276277
final directory = await getIt<SettingsLocationCubit>().fetchLocation();
277-
return Directory('$directory/covers')
278+
return Directory(path.join(directory, 'covers'))
278279
.create(recursive: true)
279280
.then((value) => value.path);
280281
}

frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/openai/widgets/auto_completion_node_widget.dart

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
99
import 'package:flowy_infra_ui/style_widget/text_field.dart';
1010
import 'package:flowy_infra_ui/widget/spacing.dart';
1111
import 'package:flutter/material.dart';
12-
import 'package:flutter/services.dart';
1312
import 'package:http/http.dart' as http;
1413
import 'package:appflowy/generated/locale_keys.g.dart';
1514
import 'package:easy_localization/easy_localization.dart';
@@ -127,26 +126,12 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
127126
}
128127

129128
Widget _buildInputWidget(BuildContext context) {
130-
return RawKeyboardListener(
131-
focusNode: focusNode,
132-
onKey: (RawKeyEvent event) async {
133-
if (event is! RawKeyDownEvent) return;
134-
if (event.logicalKey == LogicalKeyboardKey.enter) {
135-
if (controller.text.isNotEmpty) {
136-
textFieldFocusNode.unfocus();
137-
await _onGenerate();
138-
}
139-
} else if (event.logicalKey == LogicalKeyboardKey.escape) {
140-
await _onExit();
141-
}
142-
},
143-
child: FlowyTextField(
144-
hintText: LocaleKeys.document_plugins_autoGeneratorHintText.tr(),
145-
controller: controller,
146-
maxLines: 3,
147-
focusNode: textFieldFocusNode,
148-
autoFocus: false,
149-
),
129+
return FlowyTextField(
130+
hintText: LocaleKeys.document_plugins_autoGeneratorHintText.tr(),
131+
controller: controller,
132+
maxLines: 3,
133+
focusNode: textFieldFocusNode,
134+
autoFocus: false,
150135
);
151136
}
152137

@@ -157,15 +142,9 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
157142
TextSpan(
158143
children: [
159144
TextSpan(
160-
text: '${LocaleKeys.button_generate.tr()} ',
145+
text: LocaleKeys.button_generate.tr(),
161146
style: Theme.of(context).textTheme.bodyMedium,
162147
),
163-
TextSpan(
164-
text: '↵',
165-
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
166-
color: Colors.grey,
167-
),
168-
),
169148
],
170149
),
171150
onPressed: () async => await _onGenerate(),
@@ -175,15 +154,9 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
175154
TextSpan(
176155
children: [
177156
TextSpan(
178-
text: '${LocaleKeys.button_Cancel.tr()} ',
157+
text: LocaleKeys.button_Cancel.tr(),
179158
style: Theme.of(context).textTheme.bodyMedium,
180159
),
181-
TextSpan(
182-
text: LocaleKeys.button_esc.tr(),
183-
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
184-
color: Colors.grey,
185-
),
186-
),
187160
],
188161
),
189162
onPressed: () async => await _onExit(),

frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/openai/widgets/smart_edit_action.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ enum SmartEditAction {
1010
String get toInstruction {
1111
switch (this) {
1212
case SmartEditAction.summarize:
13-
return 'Make it shorter';
13+
return 'Make this shorter and more concise:';
1414
case SmartEditAction.fixSpelling:
15-
return 'Fix all the spelling mistakes';
15+
return 'Correct this to standard English:';
1616
}
1717
}
1818
}

frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/openai/widgets/smart_edit_node_widget.dart

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
88
import 'package:flowy_infra_ui/style_widget/text.dart';
99
import 'package:flowy_infra_ui/widget/spacing.dart';
1010
import 'package:flutter/material.dart';
11-
import 'package:flutter/services.dart';
1211
import 'package:appflowy/generated/locale_keys.g.dart';
1312
import 'package:easy_localization/easy_localization.dart';
1413
import 'package:http/http.dart' as http;
@@ -99,28 +98,16 @@ class _SmartEditInputState extends State<_SmartEditInput> {
9998
}
10099

101100
Widget _buildSmartEditPanel(BuildContext context) {
102-
return RawKeyboardListener(
103-
focusNode: focusNode,
104-
onKey: (RawKeyEvent event) async {
105-
if (event is! RawKeyDownEvent) return;
106-
if (event.logicalKey == LogicalKeyboardKey.enter) {
107-
await _onReplace();
108-
await _onExit();
109-
} else if (event.logicalKey == LogicalKeyboardKey.escape) {
110-
await _onExit();
111-
}
112-
},
113-
child: Column(
114-
mainAxisSize: MainAxisSize.min,
115-
crossAxisAlignment: CrossAxisAlignment.start,
116-
children: [
117-
_buildHeaderWidget(context),
118-
const Space(0, 10),
119-
_buildResultWidget(context),
120-
const Space(0, 10),
121-
_buildInputFooterWidget(context),
122-
],
123-
),
101+
return Column(
102+
mainAxisSize: MainAxisSize.min,
103+
crossAxisAlignment: CrossAxisAlignment.start,
104+
children: [
105+
_buildHeaderWidget(context),
106+
const Space(0, 10),
107+
_buildResultWidget(context),
108+
const Space(0, 10),
109+
_buildInputFooterWidget(context),
110+
],
124111
);
125112
}
126113

@@ -140,9 +127,12 @@ class _SmartEditInputState extends State<_SmartEditInput> {
140127
}
141128

142129
Widget _buildResultWidget(BuildContext context) {
143-
final loading = SizedBox.fromSize(
144-
size: const Size.square(14),
145-
child: const CircularProgressIndicator(),
130+
final loading = Padding(
131+
padding: const EdgeInsets.symmetric(horizontal: 4.0),
132+
child: SizedBox.fromSize(
133+
size: const Size.square(14),
134+
child: const CircularProgressIndicator(),
135+
),
146136
);
147137
if (result == null) {
148138
return loading;
@@ -172,15 +162,9 @@ class _SmartEditInputState extends State<_SmartEditInput> {
172162
TextSpan(
173163
children: [
174164
TextSpan(
175-
text: '${LocaleKeys.button_replace.tr()} ',
165+
text: LocaleKeys.button_replace.tr(),
176166
style: Theme.of(context).textTheme.bodyMedium,
177167
),
178-
TextSpan(
179-
text: '↵',
180-
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
181-
color: Colors.grey,
182-
),
183-
),
184168
],
185169
),
186170
onPressed: () {
@@ -193,15 +177,9 @@ class _SmartEditInputState extends State<_SmartEditInput> {
193177
TextSpan(
194178
children: [
195179
TextSpan(
196-
text: '${LocaleKeys.button_Cancel.tr()} ',
180+
text: LocaleKeys.button_Cancel.tr(),
197181
style: Theme.of(context).textTheme.bodyMedium,
198182
),
199-
TextSpan(
200-
text: LocaleKeys.button_esc.tr(),
201-
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
202-
color: Colors.grey,
203-
),
204-
),
205183
],
206184
),
207185
onPressed: () async => await _onExit(),
@@ -222,7 +200,6 @@ class _SmartEditInputState extends State<_SmartEditInput> {
222200

223201
final texts = result!.asRight().choices.first.text.split('\n')
224202
..removeWhere((element) => element.isEmpty);
225-
assert(texts.length == selectedNodes.length);
226203
final transaction = widget.editorState.transaction;
227204
transaction.replaceTexts(
228205
selectedNodes.toList(growable: false),
@@ -254,7 +231,7 @@ class _SmartEditInputState extends State<_SmartEditInput> {
254231
final edits = await openAIRepository.getEdits(
255232
input: input,
256233
instruction: instruction,
257-
n: input.split('\n').length,
234+
n: 1,
258235
);
259236
return edits.fold((error) async {
260237
return dartz.Left(

frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/openai/widgets/smart_edit_toolbar_item.dart

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/smart_edit_action.dart';
22
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/smart_edit_node_widget.dart';
3+
import 'package:appflowy/user/application/user_service.dart';
34
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
45
import 'package:appflowy_editor/appflowy_editor.dart';
56
import 'package:appflowy_popover/appflowy_popover.dart';
67
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
8+
import 'package:flowy_infra_ui/style_widget/text.dart';
79
import 'package:flutter/material.dart';
10+
import 'package:appflowy/generated/locale_keys.g.dart';
11+
import 'package:easy_localization/easy_localization.dart';
812

913
ToolbarItem smartEditItem = ToolbarItem(
1014
id: 'appflowy.toolbar.smart_edit',
1115
type: 0, // headmost
1216
validator: (editorState) {
1317
// All selected nodes must be text.
1418
final nodes = editorState.service.selectionService.currentSelectedNodes;
15-
return nodes.whereType<TextNode>().length == nodes.length;
19+
return nodes.whereType<TextNode>().length == nodes.length &&
20+
nodes.length == 1;
1621
},
1722
itemBuilder: (context, editorState) {
1823
return _SmartEditWidget(
@@ -33,6 +38,20 @@ class _SmartEditWidget extends StatefulWidget {
3338
}
3439

3540
class _SmartEditWidgetState extends State<_SmartEditWidget> {
41+
bool isOpenAIEnabled = false;
42+
43+
@override
44+
void initState() {
45+
super.initState();
46+
47+
UserBackendService.getCurrentUserProfile().then((value) {
48+
setState(() {
49+
isOpenAIEnabled =
50+
value.fold((l) => l.openaiKey.isNotEmpty, (r) => false);
51+
});
52+
});
53+
}
54+
3655
@override
3756
Widget build(BuildContext context) {
3857
return PopoverActionList<SmartEditActionWrapper>(
@@ -43,15 +62,21 @@ class _SmartEditWidgetState extends State<_SmartEditWidget> {
4362
buildChild: (controller) {
4463
return FlowyIconButton(
4564
hoverColor: Colors.transparent,
46-
tooltipText: 'Smart Edit',
65+
tooltipText: isOpenAIEnabled
66+
? LocaleKeys.document_plugins_smartEdit.tr()
67+
: LocaleKeys.document_plugins_smartEditDisabled.tr(),
4768
preferBelow: false,
4869
icon: const Icon(
4970
Icons.lightbulb_outline,
5071
size: 13,
5172
color: Colors.white,
5273
),
5374
onPressed: () {
54-
controller.show();
75+
if (isOpenAIEnabled) {
76+
controller.show();
77+
} else {
78+
_showError(LocaleKeys.document_plugins_smartEditDisabled.tr());
79+
}
5580
},
5681
);
5782
},
@@ -97,4 +122,18 @@ class _SmartEditWidgetState extends State<_SmartEditWidget> {
97122
withUpdateCursor: false,
98123
);
99124
}
125+
126+
Future<void> _showError(String message) async {
127+
ScaffoldMessenger.of(context).showSnackBar(
128+
SnackBar(
129+
action: SnackBarAction(
130+
label: LocaleKeys.button_Cancel.tr(),
131+
onPressed: () {
132+
ScaffoldMessenger.of(context).hideCurrentSnackBar();
133+
},
134+
),
135+
content: FlowyText(message),
136+
),
137+
);
138+
}
100139
}

frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:io';
22

33
import 'package:appflowy_backend/appflowy_backend.dart';
44
import 'package:path_provider/path_provider.dart';
5+
import 'package:path/path.dart' as path;
56

67
import '../startup.dart';
78

@@ -35,11 +36,11 @@ Future<Directory> appFlowyDocumentDirectory() async {
3536
switch (integrationEnv()) {
3637
case IntegrationMode.develop:
3738
Directory documentsDir = await getApplicationDocumentsDirectory();
38-
return Directory('${documentsDir.path}/flowy_dev').create();
39+
return Directory(path.join(documentsDir.path, 'flowy_dev')).create();
3940
case IntegrationMode.release:
4041
Directory documentsDir = await getApplicationDocumentsDirectory();
41-
return Directory('${documentsDir.path}/flowy').create();
42+
return Directory(path.join(documentsDir.path, 'flowy')).create();
4243
case IntegrationMode.test:
43-
return Directory("${Directory.current.path}/.sandbox");
44+
return Directory(path.join(Directory.current.path, '.sandbox'));
4445
}
4546
}

frontend/appflowy_flutter/packages/appflowy_editor/lib/src/commands/command_extension.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ extension CommandExtension on EditorState {
5757
Selection selection,
5858
) {
5959
List<String> res = [];
60-
if (!selection.isCollapsed) {
60+
if (selection.isSingle) {
61+
final plainText = textNodes.first.toPlainText();
62+
res.add(plainText.substring(selection.startIndex, selection.endIndex));
63+
} else if (!selection.isCollapsed) {
6164
for (var i = 0; i < textNodes.length; i++) {
6265
final plainText = textNodes[i].toPlainText();
6366
if (i == 0) {

0 commit comments

Comments
 (0)