Skip to content

Commit

Permalink
fix: navigation bar issue on linked pages(AppFlowy-IO#7111)
Browse files Browse the repository at this point in the history
  • Loading branch information
asjqkkkk committed Jan 4, 2025
1 parent 552c592 commit e05a043
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

expect(
find.text(LocaleKeys.menuAppHeader_defaultNewPageName.tr()),
findsNWidgets(3),
Expand All @@ -77,12 +72,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);
await tester.pumpAndSettle();

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand All @@ -101,11 +90,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -154,11 +138,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -212,11 +191,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -253,11 +227,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -303,11 +272,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -346,11 +310,6 @@ void main() {

await tester.insertSubPageFromSlashMenu(true);

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand Down Expand Up @@ -394,11 +353,6 @@ void main() {

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));
expect(find.byType(SubPageBlockComponent), findsOneWidget);
Expand All @@ -421,12 +375,6 @@ void main() {
await tester.createNewPageWithNameUnderParent(name: 'SubPageBlock');

await tester.insertSubPageFromSlashMenu();

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

await tester.renamePageWithSecondary(_defaultPageName, 'Child page');
expect(find.text('Child page'), findsNWidgets(2));

Expand All @@ -447,11 +395,6 @@ void main() {

await tester.insertSubPageFromSlashMenu(true);

await tester.expandOrCollapsePage(
pageName: 'SubPageBlock',
layout: ViewLayoutPB.Document,
);

expect(find.byType(SubPageBlockComponent), findsOneWidget);

final beforeNode = tester.editor.getNodeAtPath([1]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.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_backend/protobuf/flowy-folder/view.pbenum.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

Expand Down Expand Up @@ -44,5 +48,82 @@ void main() {
);
expect(isExpanded(type: FolderSpaceType.private), true);
});

testWidgets('Expanding with subpage', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
const page1 = 'SubPageBloc', page2 = '$page1 2';
await tester.createNewPageWithNameUnderParent(name: page1);
await tester.createNewPageWithNameUnderParent(
name: page2,
parentName: page1,
);

await tester.expandOrCollapsePage(
pageName: gettingStarted,
layout: ViewLayoutPB.Document,
);

await tester.tapNewPageButton();

await tester.editor.tapLineOfEditorAt(0);
await tester.pumpAndSettle();
await tester.editor.showSlashMenu();
await tester.pumpAndSettle();

final slashMenu = find
.ancestor(
of: find.byType(SelectionMenuItemWidget),
matching: find.byWidgetPredicate(
(widget) => widget is Scrollable,
),
)
.first;
final slashMenuItem = find.text(
LocaleKeys.document_slashMenu_name_linkedDoc.tr(),
);
await tester.scrollUntilVisible(
slashMenuItem,
100,
scrollable: slashMenu,
duration: const Duration(milliseconds: 250),
);

final menuItemFinder = find.byWidgetPredicate(
(w) =>
w is SelectionMenuItemWidget &&
w.item.name == LocaleKeys.document_slashMenu_name_linkedDoc.tr(),
);

final menuItem =
menuItemFinder.evaluate().first.widget as SelectionMenuItemWidget;

/// tapSlashMenuItemWithName is not working, so invoke this function directly
menuItem.item.handler(
menuItem.editorState,
menuItem.menuService,
menuItemFinder.evaluate().first,
);

await tester.pumpAndSettle();
final actionHandler = find.byType(InlineActionsHandler);
final subPage = find.descendant(
of: actionHandler,
matching: find.text(page2, findRichText: true),
);
await tester.tapButton(subPage);

final subpageBlock = find.descendant(
of: find.byType(AppFlowyEditor),
matching: find.text(page2, findRichText: true),
);

expect(find.text(page2, findRichText: true), findsOneWidget);
await tester.tapButton(subpageBlock);

/// one is in SectionFolder, another one is in CoverTitle
/// the last one is in FlowyNavigation
expect(find.text(page2, findRichText: true), findsNWidgets(3));
});
});
}
27 changes: 27 additions & 0 deletions frontend/appflowy_flutter/lib/util/expand_views.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:appflowy/workspace/application/view/view_bloc.dart';

/// the key is view id
final Map<String, Set<ViewBloc>> _recordBlocs = {};

bool isViewExpanded(String id) => getViewBloc(id)?.state.isExpanded ?? false;

void recordBloc(String id, ViewBloc bloc) {
final set = _recordBlocs[id] ?? {};
set.add(bloc);
_recordBlocs[id] = set;
}

void eraseBloc(String id, ViewBloc bloc) {
final set = _recordBlocs[id] ?? {};
set.remove(bloc);
if (set.isEmpty) {
_recordBlocs.remove(id);
} else {
_recordBlocs[id] = set;
}
}

ViewBloc? getViewBloc(String id) {
final set = _recordBlocs[id] ?? {};
return set.isEmpty ? null : set.first;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import 'dart:convert';

import 'package:appflowy/core/config/kv.dart';
import 'package:appflowy/core/config/kv_keys.dart';
import 'package:appflowy/plugins/blank/blank.dart';
import 'package:appflowy/plugins/util.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/expand_views.dart';
import 'package:appflowy/workspace/application/view/view_bloc.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:bloc/bloc.dart';
import 'package:collection/collection.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
Expand Down Expand Up @@ -71,6 +79,7 @@ class TabsBloc extends Bloc<TabsEvent, TabsState> {
emit(state.openPlugin(plugin: plugin, setLatest: setLatest));
if (setLatest) {
_setLatestOpenView(view);
if (view != null) _expandAncestors(view);
}
},
closeOtherTabs: (String pluginId) {
Expand Down Expand Up @@ -212,6 +221,24 @@ class TabsBloc extends Bloc<TabsEvent, TabsState> {
}
}

Future<void> _expandAncestors(ViewPB view) async {
if (isViewExpanded(view.parentViewId)) return;
final r = await getIt<KeyValueStorage>().get(KVKeys.expandedViews);
final Map map = r == null ? {} : jsonDecode(r);
final List<String> ancestors =
await ViewBackendService.getViewAncestors(view.id)
.fold((s) => s.items.map((e) => e.id).toList(), (f) => []);
ViewBloc? viewBloc;
for (final id in ancestors) {
map[id] = true;
final vb = getViewBloc(id);
if (vb == null) continue;
if (!vb.state.isExpanded && viewBloc == null) viewBloc = vb;
}
await getIt<KeyValueStorage>().set(KVKeys.expandedViews, jsonEncode(map));
viewBloc?.add(const ViewEvent.setIsExpanded(true));
}

int _adjustCurrentIndex({
required int currentIndex,
required int tabIndex,
Expand Down Expand Up @@ -249,26 +276,37 @@ class TabsBloc extends Bloc<TabsEvent, TabsState> {
@freezed
class TabsEvent with _$TabsEvent {
const factory TabsEvent.moveTab() = _MoveTab;

const factory TabsEvent.closeTab(String pluginId) = _CloseTab;

const factory TabsEvent.closeOtherTabs(String pluginId) = _CloseOtherTabs;

const factory TabsEvent.closeCurrentTab() = _CloseCurrentTab;

const factory TabsEvent.selectTab(int index) = _SelectTab;

const factory TabsEvent.togglePin(String pluginId) = _TogglePin;

const factory TabsEvent.openTab({
required Plugin plugin,
required ViewPB view,
}) = _OpenTab;

const factory TabsEvent.openPlugin({
required Plugin plugin,
ViewPB? view,
@Default(true) bool setLatest,
}) = _OpenPlugin;

const factory TabsEvent.openSecondaryPlugin({
required Plugin plugin,
ViewPB? view,
}) = _OpenSecondaryPlugin;

const factory TabsEvent.closeSecondaryPlugin() = _CloseSecondaryPlugin;

const factory TabsEvent.expandSecondaryPlugin() = _ExpandSecondaryPlugin;

const factory TabsEvent.switchWorkspace(String workspaceId) =
_SwitchWorkspace;
}
Expand All @@ -281,8 +319,11 @@ class TabsState {

final int currentIndex;
final List<PageManager> _pageManagers;

int get pages => _pageManagers.length;

PageManager get currentPageManager => _pageManagers[currentIndex];

List<PageManager> get pageManagers => _pageManagers;

bool get isAllPinned => _pageManagers.every((pm) => pm.isPinned);
Expand Down
Loading

0 comments on commit e05a043

Please sign in to comment.