fix: tab change speed + remove favorite option (#6819)

This commit is contained in:
Mathias Mogensen 2024-11-18 10:11:39 +01:00 committed by GitHub
parent 3803cf2506
commit 9c22bb4fed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 25 additions and 168 deletions

View File

@ -1,79 +0,0 @@
import 'dart:async';
import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'tab_menu_bloc.freezed.dart';
class TabMenuBloc extends Bloc<TabMenuEvent, TabMenuState> {
TabMenuBloc({required this.viewId}) : super(const TabMenuState.isLoading()) {
_fetchView();
_dispatch();
}
final String viewId;
ViewPB? view;
void _dispatch() {
on<TabMenuEvent>(
(event, emit) async {
await event.when(
error: (error) async => emit(const TabMenuState.isError()),
fetchedView: (view) async =>
emit(TabMenuState.isReady(isFavorite: view.isFavorite)),
toggleFavorite: () async {
final didToggle = await ViewBackendService.favorite(viewId: viewId);
if (didToggle.isSuccess) {
final isFavorite = state.maybeMap(
isReady: (s) => s.isFavorite,
orElse: () => null,
);
if (isFavorite != null) {
emit(TabMenuState.isReady(isFavorite: !isFavorite));
}
}
},
);
},
);
}
Future<void> _fetchView() async {
final viewOrFailure = await ViewBackendService.getView(viewId);
viewOrFailure.fold(
(view) {
this.view = view;
add(TabMenuEvent.fetchedView(view));
},
(error) {
Log.error(error);
add(TabMenuEvent.error(error));
},
);
}
}
@freezed
class TabMenuEvent with _$TabMenuEvent {
const factory TabMenuEvent.error(FlowyError error) = _Error;
const factory TabMenuEvent.fetchedView(ViewPB view) = _FetchedView;
const factory TabMenuEvent.toggleFavorite() = _ToggleFavorite;
}
@freezed
class TabMenuState with _$TabMenuState {
const factory TabMenuState.isLoading() = _IsLoading;
/// This will only be the state in case fetching the view failed.
///
/// One such case can be from when a View is in the trash, as such we can disable
/// certain options in the TabMenu such as the favorite option.
///
const factory TabMenuState.isError() = _IsError;
const factory TabMenuState.isReady({required bool isFavorite}) = _IsReady;
}

View File

@ -85,9 +85,8 @@ class _HomeStackState extends State<HomeStack> {
),
),
Expanded(
child: FadingIndexedStack(
child: IndexedStack(
index: selectedIndex,
duration: const Duration(milliseconds: 350),
children: state.pageManagers
.map(
(pm) => Column(

View File

@ -1,6 +1,5 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/tabs/tab_menu_bloc.dart';
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
@ -51,12 +50,7 @@ class _FlowyTabState extends State<FlowyTab> {
showAtCursor: true,
popupBuilder: (_) => BlocProvider.value(
value: context.read<TabsBloc>(),
child: BlocProvider<TabMenuBloc>(
create: (_) => TabMenuBloc(
viewId: widget.pageManager.plugin.id,
),
child: TabMenu(pageId: widget.pageManager.plugin.id),
),
child: TabMenu(pageId: widget.pageManager.plugin.id),
),
child: ChangeNotifierProvider.value(
value: widget.pageManager.notifier,
@ -126,56 +120,21 @@ class TabMenu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<TabMenuBloc, TabMenuState>(
builder: (context, state) {
if (state.maybeMap(
isLoading: (_) => true,
orElse: () => false,
)) {
return const SizedBox.shrink();
}
final disableFavoriteOption = state.maybeWhen(
isReady: (_) => false,
orElse: () => true,
);
return SeparatedColumn(
separatorBuilder: () => const VSpace(4),
mainAxisSize: MainAxisSize.min,
children: [
FlowyButton(
text: FlowyText.regular(LocaleKeys.tabMenu_close.tr()),
onTap: () => _closeTab(context),
),
FlowyButton(
text: FlowyText.regular(
LocaleKeys.tabMenu_closeOthers.tr(),
),
onTap: () => _closeOtherTabs(context),
),
const Divider(height: 1),
_favoriteDisabledTooltip(
showTooltip: disableFavoriteOption,
child: FlowyButton(
disable: disableFavoriteOption,
text: FlowyText.regular(
state.maybeWhen(
isReady: (isFavorite) => isFavorite
? LocaleKeys.tabMenu_unfavorite.tr()
: LocaleKeys.tabMenu_favorite.tr(),
orElse: () => LocaleKeys.tabMenu_favorite.tr(),
),
color: disableFavoriteOption
? Theme.of(context).hintColor
: null,
),
onTap: () => _toggleFavorite(context),
),
),
],
);
},
return SeparatedColumn(
separatorBuilder: () => const VSpace(4),
mainAxisSize: MainAxisSize.min,
children: [
FlowyButton(
text: FlowyText.regular(LocaleKeys.tabMenu_close.tr()),
onTap: () => _closeTab(context),
),
FlowyButton(
text: FlowyText.regular(
LocaleKeys.tabMenu_closeOthers.tr(),
),
onTap: () => _closeOtherTabs(context),
),
],
);
}
@ -184,21 +143,4 @@ class TabMenu extends StatelessWidget {
void _closeOtherTabs(BuildContext context) =>
context.read<TabsBloc>().add(TabsEvent.closeOtherTabs(pageId));
void _toggleFavorite(BuildContext context) =>
context.read<TabMenuBloc>().add(const TabMenuEvent.toggleFavorite());
Widget _favoriteDisabledTooltip({
required bool showTooltip,
required Widget child,
}) {
if (showTooltip) {
return FlowyTooltip(
message: LocaleKeys.tabMenu_favoriteDisabledHint.tr(),
child: child,
);
}
return child;
}
}

View File

@ -6,19 +6,11 @@ import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/tabs/flowy_tab.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class TabsManager extends StatefulWidget {
const TabsManager({
super.key,
required this.onIndexChanged,
});
class TabsManager extends StatelessWidget {
const TabsManager({super.key, required this.onIndexChanged});
final void Function(int) onIndexChanged;
@override
State<TabsManager> createState() => _TabsManagerState();
}
class _TabsManagerState extends State<TabsManager> {
@override
Widget build(BuildContext context) {
return BlocProvider<TabsBloc>.value(
@ -26,7 +18,7 @@ class _TabsManagerState extends State<TabsManager> {
child: BlocListener<TabsBloc, TabsState>(
listenWhen: (prev, curr) =>
prev.currentIndex != curr.currentIndex || prev.pages != curr.pages,
listener: (context, state) => widget.onIndexChanged(state.currentIndex),
listener: (context, state) => onIndexChanged(state.currentIndex),
child: BlocBuilder<TabsBloc, TabsState>(
builder: (context, state) {
if (state.pages == 1) {
@ -54,7 +46,7 @@ class _TabsManagerState extends State<TabsManager> {
onTap: () {
if (state.currentPageManager != pm) {
final index = state.pageManagers.indexOf(pm);
widget.onIndexChanged(index);
onIndexChanged(index);
}
},
),

View File

@ -39,5 +39,8 @@ class _ViewTabBarItemState extends State<ViewTabBarItem> {
}
@override
Widget build(BuildContext context) => FlowyText.medium(view.nameOrDefault);
Widget build(BuildContext context) => FlowyText.medium(
view.nameOrDefault,
overflow: TextOverflow.ellipsis,
);
}