mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-10 23:48:17 +00:00
fix: tab change speed + remove favorite option (#6819)
This commit is contained in:
parent
3803cf2506
commit
9c22bb4fed
@ -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;
|
|
||||||
}
|
|
||||||
@ -85,9 +85,8 @@ class _HomeStackState extends State<HomeStack> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FadingIndexedStack(
|
child: IndexedStack(
|
||||||
index: selectedIndex,
|
index: selectedIndex,
|
||||||
duration: const Duration(milliseconds: 350),
|
|
||||||
children: state.pageManagers
|
children: state.pageManagers
|
||||||
.map(
|
.map(
|
||||||
(pm) => Column(
|
(pm) => Column(
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.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/application/tabs/tabs_bloc.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
@ -51,13 +50,8 @@ class _FlowyTabState extends State<FlowyTab> {
|
|||||||
showAtCursor: true,
|
showAtCursor: true,
|
||||||
popupBuilder: (_) => BlocProvider.value(
|
popupBuilder: (_) => BlocProvider.value(
|
||||||
value: context.read<TabsBloc>(),
|
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(
|
child: ChangeNotifierProvider.value(
|
||||||
value: widget.pageManager.notifier,
|
value: widget.pageManager.notifier,
|
||||||
child: Consumer<PageNotifier>(
|
child: Consumer<PageNotifier>(
|
||||||
@ -126,20 +120,6 @@ class TabMenu extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
return SeparatedColumn(
|
||||||
separatorBuilder: () => const VSpace(4),
|
separatorBuilder: () => const VSpace(4),
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -154,29 +134,8 @@ class TabMenu extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
onTap: () => _closeOtherTabs(context),
|
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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _closeTab(BuildContext context) =>
|
void _closeTab(BuildContext context) =>
|
||||||
@ -184,21 +143,4 @@ class TabMenu extends StatelessWidget {
|
|||||||
|
|
||||||
void _closeOtherTabs(BuildContext context) =>
|
void _closeOtherTabs(BuildContext context) =>
|
||||||
context.read<TabsBloc>().add(TabsEvent.closeOtherTabs(pageId));
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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:appflowy/workspace/presentation/home/tabs/flowy_tab.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class TabsManager extends StatefulWidget {
|
class TabsManager extends StatelessWidget {
|
||||||
const TabsManager({
|
const TabsManager({super.key, required this.onIndexChanged});
|
||||||
super.key,
|
|
||||||
required this.onIndexChanged,
|
|
||||||
});
|
|
||||||
|
|
||||||
final void Function(int) onIndexChanged;
|
final void Function(int) onIndexChanged;
|
||||||
|
|
||||||
@override
|
|
||||||
State<TabsManager> createState() => _TabsManagerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TabsManagerState extends State<TabsManager> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider<TabsBloc>.value(
|
return BlocProvider<TabsBloc>.value(
|
||||||
@ -26,7 +18,7 @@ class _TabsManagerState extends State<TabsManager> {
|
|||||||
child: BlocListener<TabsBloc, TabsState>(
|
child: BlocListener<TabsBloc, TabsState>(
|
||||||
listenWhen: (prev, curr) =>
|
listenWhen: (prev, curr) =>
|
||||||
prev.currentIndex != curr.currentIndex || prev.pages != curr.pages,
|
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>(
|
child: BlocBuilder<TabsBloc, TabsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state.pages == 1) {
|
if (state.pages == 1) {
|
||||||
@ -54,7 +46,7 @@ class _TabsManagerState extends State<TabsManager> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
if (state.currentPageManager != pm) {
|
if (state.currentPageManager != pm) {
|
||||||
final index = state.pageManagers.indexOf(pm);
|
final index = state.pageManagers.indexOf(pm);
|
||||||
widget.onIndexChanged(index);
|
onIndexChanged(index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -39,5 +39,8 @@ class _ViewTabBarItemState extends State<ViewTabBarItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => FlowyText.medium(view.nameOrDefault);
|
Widget build(BuildContext context) => FlowyText.medium(
|
||||||
|
view.nameOrDefault,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user