mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-02 19:13:28 +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(
|
||||
child: FadingIndexedStack(
|
||||
child: IndexedStack(
|
||||
index: selectedIndex,
|
||||
duration: const Duration(milliseconds: 350),
|
||||
children: state.pageManagers
|
||||
.map(
|
||||
(pm) => Column(
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user