Skip to content

Commit

Permalink
feat: support custom image icon on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
asjqkkkk committed Jan 18, 2025
1 parent f3465dc commit c5f8501
Show file tree
Hide file tree
Showing 21 changed files with 204 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'dart:io';

import 'package:appflowy/mobile/presentation/base/view_page/app_bar_buttons.dart';
import 'package:appflowy/mobile/presentation/presentation.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_icon.dart';
import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

import '../../shared/emoji.dart';
import '../../shared/util.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('document title:', () {
testWidgets('update page custom icon in title bar', (tester) async {
await tester.launchInAnonymousMode();

/// prepare local image
final imagePath = await rootBundle.load('assets/test/images/sample.jpeg');
final tempDirectory = await getTemporaryDirectory();
final localImagePath = p.join(tempDirectory.path, 'sample.jpeg');
final imageFile = File(localImagePath)
..writeAsBytesSync(imagePath.buffer.asUint8List());
final iconData = EmojiIconData.custom(imageFile.path);

/// create an empty page
await tester
.tapButton(find.byKey(BottomNavigationBarItemType.add.valueKey));

/// show Page style page
await tester.tapButton(find.byType(MobileViewPageLayoutButton));
final pageStyleIcon = find.byType(PageStyleIcon);
final iconInPageStyleIcon = find.descendant(
of: pageStyleIcon,
matching: find.byType(RawEmojiIconWidget),
);
expect(iconInPageStyleIcon, findsNothing);

/// show icon picker
await tester.tapButton(pageStyleIcon);

/// upload custom icon
await tester.pickImage(iconData);

/// check result
final documentPage = find.byType(MobileDocumentScreen);
final rawEmojiIconWidget = find
.descendant(
of: documentPage,
matching: find.byType(RawEmojiIconWidget),
)
.evaluate()
.first
.widget as RawEmojiIconWidget;
final iconDataInWidget = rawEmojiIconWidget.emoji;
expect(iconDataInWidget.type, FlowyIconType.custom);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extension MobileRouter on BuildContext {
bool showMoreButton = true,
String? fixedTitle,
String? blockId,
List<String>? tabs,
}) async {
// set the current view before pushing the new view
getIt<MenuSharedState>().latestOpenView = view;
Expand All @@ -37,6 +38,9 @@ extension MobileRouter on BuildContext {
queryParameters[MobileDocumentScreen.viewBlockId] = blockId;
}
}
if (tabs != null) {
queryParameters[MobileDocumentScreen.viewSelectTabs] = tabs.join('-');
}

final uri = Uri(
path: view.routeName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:appflowy/plugins/document/presentation/document_collaborators.da
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
Expand All @@ -34,6 +35,7 @@ class MobileViewPage extends StatefulWidget {
this.fixedTitle,
this.showMoreButton = true,
this.blockId,
this.tabs = const [PickerTabType.emoji, PickerTabType.icon],
});

/// view id
Expand All @@ -43,6 +45,7 @@ class MobileViewPage extends StatefulWidget {
final Map<String, dynamic>? arguments;
final bool showMoreButton;
final String? blockId;
final List<PickerTabType> tabs;

// only used in row page
final String? fixedTitle;
Expand Down Expand Up @@ -193,6 +196,7 @@ class _MobileViewPageState extends State<MobileViewPage> {
data: {
MobileDocumentScreen.viewFixedTitle: widget.fixedTitle,
MobileDocumentScreen.viewBlockId: widget.blockId,
MobileDocumentScreen.viewSelectTabs: widget.tabs,
},
);
},
Expand Down Expand Up @@ -242,6 +246,7 @@ class _MobileViewPageState extends State<MobileViewPage> {
view: view,
isImmersiveMode: isImmersiveMode,
appBarOpacity: _appBarOpacity,
tabs: widget.tabs,
),
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/plugins/document/presentation/editor_notification.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/page_style_bottom_sheet.dart';
import 'package:appflowy/plugins/shared/share/share_bloc.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/view/prelude.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
Expand Down Expand Up @@ -123,9 +124,11 @@ class MobileViewPageLayoutButton extends StatelessWidget {
required this.view,
required this.isImmersiveMode,
required this.appBarOpacity,
required this.tabs,
});

final ViewPB view;
final List<PickerTabType> tabs;
final bool isImmersiveMode;
final ValueListenable appBarOpacity;

Expand Down Expand Up @@ -156,6 +159,7 @@ class MobileViewPageLayoutButton extends StatelessWidget {
],
child: PageStyleBottomSheet(
view: context.read<ViewBloc>().state.view,
tabs: tabs,
),
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database/application/database_controller.dart';
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/workspace/application/view/prelude.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_backend/log.dart';
Expand Down Expand Up @@ -116,6 +117,7 @@ class _OpenRowPageButtonState extends State<OpenRowPageButton> {
addInRecent: false,
showMoreButton: false,
fixedTitle: fieldName,
tabs: [PickerTabType.emoji.name],
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';

Expand All @@ -10,6 +11,7 @@ class MobileDocumentScreen extends StatelessWidget {
this.showMoreButton = true,
this.fixedTitle,
this.blockId,
this.tabs = const [PickerTabType.emoji, PickerTabType.icon],
});

/// view id
Expand All @@ -18,13 +20,15 @@ class MobileDocumentScreen extends StatelessWidget {
final bool showMoreButton;
final String? fixedTitle;
final String? blockId;
final List<PickerTabType> tabs;

static const routeName = '/docs';
static const viewId = 'id';
static const viewTitle = 'title';
static const viewShowMoreButton = 'show_more_button';
static const viewFixedTitle = 'fixed_title';
static const viewBlockId = 'block_id';
static const viewSelectTabs = 'select_tabs';

@override
Widget build(BuildContext context) {
Expand All @@ -35,6 +39,7 @@ class MobileDocumentScreen extends StatelessWidget {
showMoreButton: showMoreButton,
fixedTitle: fixedTitle,
blockId: blockId,
tabs: tabs,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart';
import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.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/view/view_bloc.dart';
Expand Down Expand Up @@ -101,7 +102,14 @@ class _Pages extends StatelessWidget {
level: 0,
leftPadding: HomeSpaceViewSizes.leftPadding,
isFeedback: false,
onSelected: context.pushView,
onSelected: (v) => context.pushView(
v,
tabs: [
PickerTabType.emoji,
PickerTabType.icon,
PickerTabType.custom,
].map((e) => e.name).toList(),
),
endActionPane: (context) {
final view = context.read<ViewBloc>().state.view;
return buildEndActionPane(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emo
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy/shared/appflowy_network_image.dart';
import 'package:appflowy/shared/flowy_gradient_colors.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/util/string_extension.dart';
import 'package:appflowy/util/theme_extension.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
Expand Down Expand Up @@ -81,7 +82,14 @@ class MobileViewPage extends StatelessWidget {
spaceRatio: 4,
),
child: AnimatedGestureDetector(
onTapUp: () => context.pushView(view),
onTapUp: () => context.pushView(
view,
tabs: [
PickerTabType.emoji,
PickerTabType.icon,
PickerTabType.custom,
].map((e) => e.name).toList(),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Expand Down Expand Up @@ -140,7 +148,8 @@ class MobileViewPage extends StatelessWidget {
final iconUrl = userProfile?.iconUrl;
if (iconUrl == null ||
iconUrl.isEmpty ||
view.createdBy != userProfile?.id) {
view.createdBy != userProfile?.id ||
!isURL(iconUrl)) {
return const SizedBox.shrink();
}

Expand Down Expand Up @@ -182,7 +191,7 @@ class MobileViewPage extends StatelessWidget {
WidgetSpan(
child: SizedBox(
width: 20,
child: EmojiIconWidget(
child: RawEmojiIconWidget(
emoji: icon,
emojiSize: 18.0,
),
Expand All @@ -206,7 +215,7 @@ class MobileViewPage extends StatelessWidget {
Widget _buildAuthor(BuildContext context, RecentViewState state) {
return FlowyText.regular(
// view.createdBy.toString(),
'Lucas',
'',
fontSize: 12.0,
color: Theme.of(context).hintColor,
overflow: TextOverflow.ellipsis,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/home/space/mobile_space_header.dart';
import 'package:appflowy/mobile/presentation/home/space/mobile_space_menu.dart';
import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/shared/list_extension.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
Expand Down Expand Up @@ -151,7 +152,14 @@ class _Pages extends StatelessWidget {
level: 0,
leftPadding: HomeSpaceViewSizes.leftPadding,
isFeedback: false,
onSelected: context.pushView,
onSelected: (v) => context.pushView(
v,
tabs: [
PickerTabType.emoji,
PickerTabType.icon,
PickerTabType.custom,
].map((e) => e.name).toList(),
),
endActionPane: (context) {
final view = context.read<ViewBloc>().state.view;
final actions = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:appflowy/mobile/presentation/home/tab/_tab_bar.dart';
import 'package:appflowy/mobile/presentation/home/tab/space_order_bloc.dart';
import 'package:appflowy/mobile/presentation/presentation.dart';
import 'package:appflowy/mobile/presentation/setting/workspace/invite_members_screen.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.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/space/space_bloc.dart';
Expand Down Expand Up @@ -82,7 +83,14 @@ class _MobileSpaceTabState extends State<MobileSpaceTab>
listener: (context, state) {
final lastCreatedPage = state.lastCreatedRootView;
if (lastCreatedPage != null) {
context.pushView(lastCreatedPage);
context.pushView(
lastCreatedPage,
tabs: [
PickerTabType.emoji,
PickerTabType.icon,
PickerTabType.custom,
].map((e) => e.name).toList(),
);
}
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class MobileEmojiPickerScreen extends StatelessWidget {
body: SafeArea(
child: FlowyIconEmojiPicker(
tabs: tabs,
documentId: documentId,
initialType: selectedType,
onSelectedEmoji: (r) {
context.pop<EmojiIconData>(r.data);
Expand Down
8 changes: 8 additions & 0 deletions frontend/appflowy_flutter/lib/plugins/document/document.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:appflowy/plugins/document/presentation/document_collaborators.da
import 'package:appflowy/plugins/shared/share/share_button.dart';
import 'package:appflowy/plugins/util.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
Expand Down Expand Up @@ -107,6 +108,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder

final ViewInfoBloc bloc;
final ViewPluginNotifier notifier;

ViewPB get view => notifier.view;
int? deletedViewIndex;
final Selection? initialSelection;
Expand All @@ -130,6 +132,11 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder

final fixedTitle = data?[MobileDocumentScreen.viewFixedTitle];
final blockId = initialBlockId ?? data?[MobileDocumentScreen.viewBlockId];
final tabs = data?[MobileDocumentScreen.viewSelectTabs] ??
const [
PickerTabType.emoji,
PickerTabType.icon,
];

return BlocProvider<ViewInfoBloc>.value(
value: bloc,
Expand All @@ -141,6 +148,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder
initialSelection: initialSelection,
initialBlockId: blockId,
fixedTitle: fixedTitle,
tabs: tabs,
),
),
);
Expand Down
Loading

0 comments on commit c5f8501

Please sign in to comment.