Skip to content

Commit 8a61b04

Browse files
committed
fix: some launch review issues
1 parent 71f880b commit 8a61b04

File tree

9 files changed

+150
-42
lines changed

9 files changed

+150
-42
lines changed

frontend/appflowy_flutter/lib/mobile/presentation/selection_menu/mobile_selection_menu.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:appflowy/mobile/presentation/selection_menu/mobile_selection_men
55
import 'package:appflowy_editor/appflowy_editor.dart';
66
import 'package:flutter/material.dart';
77

8+
import 'mobile_selection_menu_item_widget.dart';
89
import 'mobile_selection_menu_widget.dart';
910

1011
class MobileSelectionMenu extends SelectionMenuService {
@@ -14,7 +15,7 @@ class MobileSelectionMenu extends SelectionMenuService {
1415
required this.selectionMenuItems,
1516
this.deleteSlashByDefault = false,
1617
this.deleteKeywordsByDefault = false,
17-
this.style = SelectionMenuStyle.light,
18+
this.style = MobileSelectionMenuStyle.light,
1819
this.itemCountFilter = 0,
1920
this.startOffset = 0,
2021
this.singleColumn = false,
@@ -28,7 +29,7 @@ class MobileSelectionMenu extends SelectionMenuService {
2829
final bool singleColumn;
2930

3031
@override
31-
final SelectionMenuStyle style;
32+
final MobileSelectionMenuStyle style;
3233

3334
OverlayEntry? _selectionMenuEntry;
3435
Offset _offset = Offset.zero;

frontend/appflowy_flutter/lib/mobile/presentation/selection_menu/mobile_selection_menu_item_widget.dart

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ class MobileSelectionMenuItemWidget extends StatelessWidget {
1111
required this.item,
1212
required this.isSelected,
1313
required this.selectionMenuStyle,
14+
required this.onTap,
1415
});
1516

1617
final EditorState editorState;
1718
final SelectionMenuService menuService;
1819
final SelectionMenuItem item;
1920
final bool isSelected;
20-
final SelectionMenuStyle selectionMenuStyle;
21+
final MobileSelectionMenuStyle selectionMenuStyle;
22+
final VoidCallback onTap;
2123

2224
@override
2325
Widget build(BuildContext context) {
@@ -58,12 +60,13 @@ class MobileSelectionMenuItemWidget extends StatelessWidget {
5860
Spacer(),
5961
Icon(
6062
Icons.keyboard_arrow_right_rounded,
61-
color: style.selectionMenuItemTextColor.withValues(alpha: 0.3),
63+
color: style.selectionMenuItemRightIconColor,
6264
),
6365
],
6466
],
6567
),
6668
onPressed: () {
69+
onTap.call();
6770
item.handler(
6871
editorState,
6972
menuService,
@@ -74,3 +77,37 @@ class MobileSelectionMenuItemWidget extends StatelessWidget {
7477
);
7578
}
7679
}
80+
81+
class MobileSelectionMenuStyle extends SelectionMenuStyle {
82+
const MobileSelectionMenuStyle({
83+
required super.selectionMenuBackgroundColor,
84+
required super.selectionMenuItemTextColor,
85+
required super.selectionMenuItemIconColor,
86+
required super.selectionMenuItemSelectedTextColor,
87+
required super.selectionMenuItemSelectedIconColor,
88+
required super.selectionMenuItemSelectedColor,
89+
required this.selectionMenuItemRightIconColor,
90+
});
91+
92+
final Color selectionMenuItemRightIconColor;
93+
94+
static const MobileSelectionMenuStyle light = MobileSelectionMenuStyle(
95+
selectionMenuBackgroundColor: Color(0xFFFFFFFF),
96+
selectionMenuItemTextColor: Color(0xFF1F2225),
97+
selectionMenuItemIconColor: Color(0xFF333333),
98+
selectionMenuItemSelectedColor: Color(0xFFF2F5F7),
99+
selectionMenuItemRightIconColor: Color(0xB31E2022),
100+
selectionMenuItemSelectedTextColor: Color.fromARGB(255, 56, 91, 247),
101+
selectionMenuItemSelectedIconColor: Color.fromARGB(255, 56, 91, 247),
102+
);
103+
104+
static const MobileSelectionMenuStyle dark = MobileSelectionMenuStyle(
105+
selectionMenuBackgroundColor: Color(0xFF424242),
106+
selectionMenuItemTextColor: Color(0xFFFFFFFF),
107+
selectionMenuItemIconColor: Color(0xFFFFFFFF),
108+
selectionMenuItemSelectedColor: Color(0xFF666666),
109+
selectionMenuItemRightIconColor: Color(0xB3FFFFFF),
110+
selectionMenuItemSelectedTextColor: Color(0xFF131720),
111+
selectionMenuItemSelectedIconColor: Color(0xFF131720),
112+
);
113+
}

frontend/appflowy_flutter/lib/mobile/presentation/selection_menu/mobile_selection_menu_widget.dart

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class MobileSelectionMenuWidget extends StatefulWidget {
3232

3333
final VoidCallback onExit;
3434

35-
final SelectionMenuStyle selectionMenuStyle;
35+
final MobileSelectionMenuStyle selectionMenuStyle;
3636

3737
final bool deleteSlashByDefault;
3838
final bool singleColumn;
@@ -105,10 +105,9 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
105105
!(widget.deleteSlashByDefault && _searchCounter < 2)) {
106106
return widget.onExit();
107107
}
108-
setState(() {
109-
selectedIndex = 0;
110-
_showingItems = items;
111-
});
108+
109+
_showingItems = items;
110+
refreshSelectedIndex();
112111

113112
if (_showingItems.isEmpty) {
114113
_searchCounter++;
@@ -132,10 +131,8 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
132131
if (!mounted) return false;
133132
final hasItemsChanged = !isInitialItems();
134133
if (keyword.isEmpty && hasItemsChanged) {
135-
setState(() {
136-
_showingItems = buildInitialItems();
137-
selectedIndex = 0;
138-
});
134+
_showingItems = buildInitialItems();
135+
refreshSelectedIndex();
139136
return true;
140137
}
141138
return false;
@@ -228,6 +225,7 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
228225
if (widget.singleColumn) {
229226
final List<Widget> itemWidgets = [];
230227
for (var i = 0; i < items.length; i++) {
228+
final item = items[i];
231229
itemWidgets.add(
232230
GestureDetector(
233231
onTapDown: (e) {
@@ -236,11 +234,14 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
236234
});
237235
},
238236
child: MobileSelectionMenuItemWidget(
239-
item: items[i],
237+
item: item,
240238
isSelected: i == selectedIndex,
241239
editorState: editorState,
242240
menuService: menuService,
243241
selectionMenuStyle: widget.selectionMenuStyle,
242+
onTap: () {
243+
if (item is MobileSelectionMenuItem) refreshSelectedIndex();
244+
},
244245
),
245246
),
246247
);
@@ -266,6 +267,7 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
266267
}
267268

268269
for (var i = 0; i < items.length; i++) {
270+
final item = items[i];
269271
if (i != 0 && i % (widget.maxItemInRow) == 0) {
270272
columns.add(
271273
Column(
@@ -277,11 +279,14 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
277279
}
278280
itemWidgets.add(
279281
MobileSelectionMenuItemWidget(
280-
item: items[i],
282+
item: item,
281283
isSelected: false,
282284
editorState: editorState,
283285
menuService: menuService,
284286
selectionMenuStyle: widget.selectionMenuStyle,
287+
onTap: () {
288+
if (item is MobileSelectionMenuItem) refreshSelectedIndex();
289+
},
285290
),
286291
);
287292
}
@@ -301,6 +306,13 @@ class _MobileSelectionMenuWidgetState extends State<MobileSelectionMenuWidget> {
301306
}
302307
}
303308

309+
void refreshSelectedIndex() {
310+
if (!mounted) return;
311+
setState(() {
312+
selectedIndex = 0;
313+
});
314+
}
315+
304316
Widget _buildNoResultsWidget(BuildContext context) {
305317
return const Padding(
306318
padding: EdgeInsets.all(8.0),

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:appflowy/mobile/presentation/selection_menu/mobile_selection_menu.dart';
2+
import 'package:appflowy/mobile/presentation/selection_menu/mobile_selection_menu_item_widget.dart';
23
import 'package:appflowy/plugins/document/presentation/editor_configuration.dart';
34
import 'package:appflowy_editor/appflowy_editor.dart';
45
import 'package:flutter/material.dart';
@@ -94,6 +95,7 @@ Future<bool> _showSlashMenu(
9495

9596
final context = editorState.getNodeAtPath(selection.start.path)?.context;
9697
if (context != null && context.mounted) {
98+
final isLight = Theme.of(context).brightness == Brightness.light;
9799
_selectionMenuService?.dismiss();
98100
_selectionMenuService = UniversalPlatform.isMobile
99101
? MobileSelectionMenu(
@@ -103,7 +105,9 @@ Future<bool> _showSlashMenu(
103105
deleteSlashByDefault: shouldInsertSlash,
104106
deleteKeywordsByDefault: deleteKeywordsByDefault,
105107
singleColumn: singleColumn,
106-
style: style,
108+
style: isLight
109+
? MobileSelectionMenuStyle.light
110+
: MobileSelectionMenuStyle.dark,
107111
startOffset: editorState.selection?.start.offset ?? 0,
108112
)
109113
: SelectionMenu(

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/slash_menu/slash_menu_items/mobile_items.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ final List<SelectionMenuItem> mobileItems = [
1212
listMobileSlashMenuItem,
1313
toggleListMobileSlashMenuItem,
1414
fileAndMediaMobileSlashMenuItem,
15-
tableSlashMenuItem,
15+
mobileTableSlashMenuItem,
1616
visualsMobileSlashMenuItem,
1717
dateOrReminderSlashMenuItem,
1818
subPageSlashMenuItem,
@@ -103,7 +103,7 @@ MobileSelectionMenuItem visualsMobileSlashMenuItem = MobileSelectionMenuItem(
103103
getName: LocaleKeys.document_slashMenu_name_visuals.tr,
104104
handler: _handler,
105105
icon: (_, isSelected, style) => SelectableSvgWidget(
106-
data: FlowySvgs.slash_menu_icon_simple_table_s,
106+
data: FlowySvgs.slash_menu_icon_visuals_s,
107107
isSelected: isSelected,
108108
style: style,
109109
),
@@ -119,7 +119,7 @@ MobileSelectionMenuItem advancedMobileSlashMenuItem = MobileSelectionMenuItem(
119119
getName: LocaleKeys.document_slashMenu_name_advanced.tr,
120120
handler: _handler,
121121
icon: (_, isSelected, style) => SelectableSvgWidget(
122-
data: FlowySvgs.m_aa_font_color_m,
122+
data: FlowySvgs.drag_element_s,
123123
isSelected: isSelected,
124124
style: style,
125125
),

frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/slash_menu/slash_menu_items/simple_table_item.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ SelectionMenuItem tableSlashMenuItem = SelectionMenuItem(
2727
),
2828
);
2929

30+
SelectionMenuItem mobileTableSlashMenuItem = SelectionMenuItem(
31+
getName: () => LocaleKeys.document_slashMenu_name_simpleTable.tr(),
32+
keywords: _keywords,
33+
handler: (editorState, _, __) async => editorState.insertSimpleTable(),
34+
nameBuilder: slashMenuItemNameBuilder,
35+
icon: (_, isSelected, style) => SelectableSvgWidget(
36+
data: FlowySvgs.slash_menu_icon_simple_table_s,
37+
isSelected: isSelected,
38+
style: style,
39+
),
40+
);
41+
3042
extension on EditorState {
3143
Future<void> insertSimpleTable() async {
3244
final selection = this.selection;

frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_uploader.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
2222
import 'package:flowy_svg/flowy_svg.dart';
2323
import 'package:flutter/material.dart';
2424
import 'package:flutter/services.dart';
25+
import 'package:http/http.dart';
2526
import 'package:image_picker/image_picker.dart';
2627
import 'package:string_validator/string_validator.dart';
2728
import 'package:universal_platform/universal_platform.dart';
@@ -249,13 +250,39 @@ class _IconUploaderState extends State<IconUploader> {
249250
final data = await getIt<ClipboardService>().getData();
250251
final plainText = data.plainText;
251252
Log.info('pasteAsAnImage plainText:$plainText');
252-
if (isURL(plainText)) {
253+
if (plainText == null) return;
254+
if (isURL(plainText) && (await validateImage(plainText))) {
253255
setState(() {
254256
pickedImages.clear();
255-
pickedImages.add(_NetworkImage(plainText!));
257+
pickedImages.add(_NetworkImage(plainText));
256258
});
257259
}
258260
}
261+
262+
Future<bool> validateImage(String imageUrl) async {
263+
Response res;
264+
try {
265+
res = await get(Uri.parse(imageUrl));
266+
} catch (e) {
267+
return false;
268+
}
269+
if (res.statusCode != 200) return false;
270+
final Map<String, dynamic> data = res.headers;
271+
return checkIfImage(data['content-type']);
272+
}
273+
274+
bool checkIfImage(String? param) {
275+
if (param == 'image/jpeg' ||
276+
param == 'image/png' ||
277+
param == 'image/gif' ||
278+
param == 'image/tiff' ||
279+
param == 'image/webp' ||
280+
param == 'image/svg+xml' ||
281+
param == 'image/svg') {
282+
return true;
283+
}
284+
return false;
285+
}
259286
}
260287

261288
class _ConfirmButton extends StatelessWidget {

frontend/appflowy_flutter/lib/shared/markdown_to_document.dart

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'dart:convert';
12
import 'dart:io';
23

34
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/sub_page_node_parser.dart';
@@ -36,34 +37,41 @@ Future<String> customDocumentToMarkdown(
3637
fileName = p.basenameWithoutExtension(path),
3738
dirName = resourceDir.name;
3839

39-
final markdown = documentToMarkdown(
40-
document,
41-
customParsers: [
42-
const MathEquationNodeParser(),
43-
const CalloutNodeParser(),
44-
const ToggleListNodeParser(),
45-
CustomImageNodeFileParser(fileFutures, dirName),
46-
CustomMultiImageNodeFileParser(fileFutures, dirName),
47-
GridNodeParser(fileFutures, dirName),
48-
BoardNodeParser(fileFutures, dirName),
49-
CalendarNodeParser(fileFutures, dirName),
50-
const CustomParagraphNodeParser(),
51-
const SubPageNodeParser(),
52-
const SimpleTableNodeParser(),
53-
const LinkPreviewNodeParser(),
54-
const FileBlockNodeParser(),
55-
],
56-
);
40+
String markdown = '';
41+
try {
42+
markdown = documentToMarkdown(
43+
document,
44+
customParsers: [
45+
const MathEquationNodeParser(),
46+
const CalloutNodeParser(),
47+
const ToggleListNodeParser(),
48+
CustomImageNodeFileParser(fileFutures, dirName),
49+
CustomMultiImageNodeFileParser(fileFutures, dirName),
50+
GridNodeParser(fileFutures, dirName),
51+
BoardNodeParser(fileFutures, dirName),
52+
CalendarNodeParser(fileFutures, dirName),
53+
const CustomParagraphNodeParser(),
54+
const SubPageNodeParser(),
55+
const SimpleTableNodeParser(),
56+
const LinkPreviewNodeParser(),
57+
const FileBlockNodeParser(),
58+
],
59+
);
60+
} catch (e) {
61+
Log.error('documentToMarkdown error: $e');
62+
}
5763

5864
/// create resource directory
5965
if (fileFutures.isNotEmpty) archive.addFile(resourceDir);
6066

61-
/// add markdown file to Archive
62-
archive.addFile(ArchiveFile.string('$fileName-$id.md', markdown));
63-
6467
for (final fileFuture in fileFutures) {
6568
archive.addFile(await fileFuture);
6669
}
70+
71+
/// add markdown file to Archive
72+
final dataBytes = utf8.encode(markdown);
73+
archive.addFile(ArchiveFile('$fileName-$id.md', dataBytes.length, dataBytes));
74+
6775
if (archive.isNotEmpty && path.isNotEmpty) {
6876
if (onArchive == null) {
6977
final zipEncoder = ZipEncoder();
Lines changed: 7 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)