mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: show member count on mobile (#4991)
* feat: show member count on mobile * fix: favorite section not sync after switching workspace * fix: favorite page will throw an error * fix: flutter analyze
This commit is contained in:
parent
a1b183f330
commit
6e5b346f25
@ -4,7 +4,7 @@ import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_fa
|
|||||||
import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart';
|
import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart';
|
||||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -16,11 +16,11 @@ class MobileFavoritePageFolder extends StatelessWidget {
|
|||||||
const MobileFavoritePageFolder({
|
const MobileFavoritePageFolder({
|
||||||
super.key,
|
super.key,
|
||||||
required this.userProfile,
|
required this.userProfile,
|
||||||
required this.workspaceSetting,
|
required this.workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
final UserProfilePB userProfile;
|
final UserProfilePB userProfile;
|
||||||
final WorkspaceSettingPB workspaceSetting;
|
final String workspaceId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -31,7 +31,7 @@ class MobileFavoritePageFolder extends StatelessWidget {
|
|||||||
..add(
|
..add(
|
||||||
SidebarSectionsEvent.initial(
|
SidebarSectionsEvent.initial(
|
||||||
userProfile,
|
userProfile,
|
||||||
workspaceSetting.workspaceId,
|
workspaceId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -39,45 +39,52 @@ class MobileFavoritePageFolder extends StatelessWidget {
|
|||||||
create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()),
|
create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: MultiBlocListener(
|
child: BlocListener<UserWorkspaceBloc, UserWorkspaceState>(
|
||||||
listeners: [
|
listener: (context, state) {
|
||||||
BlocListener<SidebarSectionsBloc, SidebarSectionsState>(
|
context.read<FavoriteBloc>().add(
|
||||||
listenWhen: (p, c) =>
|
const FavoriteEvent.initial(),
|
||||||
p.lastCreatedRootView?.id != c.lastCreatedRootView?.id,
|
|
||||||
listener: (context, state) =>
|
|
||||||
context.pushView(state.lastCreatedRootView!),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) {
|
|
||||||
final favoriteState = context.watch<FavoriteBloc>().state;
|
|
||||||
if (favoriteState.views.isEmpty) {
|
|
||||||
return FlowyMobileStateContainer.info(
|
|
||||||
emoji: '😁',
|
|
||||||
title: LocaleKeys.favorite_noFavorite.tr(),
|
|
||||||
description: LocaleKeys.favorite_noFavoriteHintText.tr(),
|
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
return Scrollbar(
|
child: MultiBlocListener(
|
||||||
child: SingleChildScrollView(
|
listeners: [
|
||||||
child: Padding(
|
BlocListener<SidebarSectionsBloc, SidebarSectionsState>(
|
||||||
padding: const EdgeInsets.all(8.0),
|
listenWhen: (p, c) =>
|
||||||
child: SlidableAutoCloseBehavior(
|
p.lastCreatedRootView?.id != c.lastCreatedRootView?.id,
|
||||||
child: Column(
|
listener: (context, state) =>
|
||||||
children: [
|
context.pushView(state.lastCreatedRootView!),
|
||||||
MobileFavoriteFolder(
|
),
|
||||||
showHeader: false,
|
],
|
||||||
forceExpanded: true,
|
child: Builder(
|
||||||
views: favoriteState.views,
|
builder: (context) {
|
||||||
),
|
final favoriteState = context.watch<FavoriteBloc>().state;
|
||||||
const VSpace(100.0),
|
if (favoriteState.views.isEmpty) {
|
||||||
],
|
return FlowyMobileStateContainer.info(
|
||||||
|
emoji: '😁',
|
||||||
|
title: LocaleKeys.favorite_noFavorite.tr(),
|
||||||
|
description: LocaleKeys.favorite_noFavoriteHintText.tr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Scrollbar(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: SlidableAutoCloseBehavior(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
MobileFavoriteFolder(
|
||||||
|
showHeader: false,
|
||||||
|
forceExpanded: true,
|
||||||
|
views: favoriteState.views,
|
||||||
|
),
|
||||||
|
const VSpace(100.0),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -57,9 +57,17 @@ class MobileFavoriteScreen extends StatelessWidget {
|
|||||||
..add(
|
..add(
|
||||||
const UserWorkspaceEvent.initial(),
|
const UserWorkspaceEvent.initial(),
|
||||||
),
|
),
|
||||||
child: MobileFavoritePage(
|
child: BlocBuilder<UserWorkspaceBloc, UserWorkspaceState>(
|
||||||
userProfile: userProfile,
|
buildWhen: (previous, current) =>
|
||||||
workspaceSetting: workspaceSetting,
|
previous.currentWorkspace?.workspaceId !=
|
||||||
|
current.currentWorkspace?.workspaceId,
|
||||||
|
builder: (context, state) {
|
||||||
|
return MobileFavoritePage(
|
||||||
|
userProfile: userProfile,
|
||||||
|
workspaceId: state.currentWorkspace?.workspaceId ??
|
||||||
|
workspaceSetting.workspaceId,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -73,11 +81,11 @@ class MobileFavoritePage extends StatelessWidget {
|
|||||||
const MobileFavoritePage({
|
const MobileFavoritePage({
|
||||||
super.key,
|
super.key,
|
||||||
required this.userProfile,
|
required this.userProfile,
|
||||||
required this.workspaceSetting,
|
required this.workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
final UserProfilePB userProfile;
|
final UserProfilePB userProfile;
|
||||||
final WorkspaceSettingPB workspaceSetting;
|
final String workspaceId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -100,7 +108,7 @@ class MobileFavoritePage extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: MobileFavoritePageFolder(
|
child: MobileFavoritePageFolder(
|
||||||
userProfile: userProfile,
|
userProfile: userProfile,
|
||||||
workspaceSetting: workspaceSetting,
|
workspaceId: workspaceId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||||
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart';
|
||||||
import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.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/mobile/presentation/page_item/mobile_view_item.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/folder/folder_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -38,9 +41,19 @@ class MobileSectionFolder extends StatelessWidget {
|
|||||||
onPressed: () => context
|
onPressed: () => context
|
||||||
.read<FolderBloc>()
|
.read<FolderBloc>()
|
||||||
.add(const FolderEvent.expandOrUnExpand()),
|
.add(const FolderEvent.expandOrUnExpand()),
|
||||||
onAdded: () => context.read<FolderBloc>().add(
|
onAdded: () {
|
||||||
const FolderEvent.expandOrUnExpand(isExpanded: true),
|
context.read<SidebarSectionsBloc>().add(
|
||||||
),
|
SidebarSectionsEvent.createRootViewInSection(
|
||||||
|
name:
|
||||||
|
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
|
index: 0,
|
||||||
|
viewSection: categoryType.toViewSectionPB,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
context.read<FolderBloc>().add(
|
||||||
|
const FolderEvent.expandOrUnExpand(isExpanded: true),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const VSpace(8.0),
|
const VSpace(8.0),
|
||||||
const Divider(
|
const Divider(
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
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/workspace/application/menu/sidebar_sections_bloc.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
const Key mobileCreateNewPageButtonKey = Key('mobileCreateNewPageButtonKey');
|
const Key mobileCreateNewPageButtonKey = Key('mobileCreateNewPageButtonKey');
|
||||||
@ -72,15 +67,7 @@ class _MobileSectionFolderHeaderState extends State<MobileSectionFolderHeader> {
|
|||||||
FlowySvgs.add_s,
|
FlowySvgs.add_s,
|
||||||
size: Size.square(iconSize),
|
size: Size.square(iconSize),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: widget.onAdded,
|
||||||
context.read<SidebarSectionsBloc>().add(
|
|
||||||
SidebarSectionsEvent.createRootViewInSection(
|
|
||||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
|
||||||
index: 0,
|
|
||||||
viewSection: ViewSectionPB.Public,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
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/mobile/presentation/widgets/widgets.dart';
|
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
// Only works on mobile.
|
// Only works on mobile.
|
||||||
class MobileWorkspaceMenu extends StatelessWidget {
|
class MobileWorkspaceMenu extends StatelessWidget {
|
||||||
@ -25,21 +30,12 @@ class MobileWorkspaceMenu extends StatelessWidget {
|
|||||||
for (var i = 0; i < workspaces.length; i++) {
|
for (var i = 0; i < workspaces.length; i++) {
|
||||||
final workspace = workspaces[i];
|
final workspace = workspaces[i];
|
||||||
children.add(
|
children.add(
|
||||||
FlowyOptionTile.text(
|
_WorkspaceMenuItem(
|
||||||
text: workspace.name,
|
userProfile: userProfile,
|
||||||
|
workspace: workspace,
|
||||||
showTopBorder: i == 0,
|
showTopBorder: i == 0,
|
||||||
leftIcon: WorkspaceIcon(
|
currentWorkspace: currentWorkspace,
|
||||||
enableEdit: false,
|
onWorkspaceSelected: onWorkspaceSelected,
|
||||||
iconSize: 22,
|
|
||||||
workspace: workspace,
|
|
||||||
),
|
|
||||||
trailing: workspace.workspaceId == currentWorkspace.workspaceId
|
|
||||||
? const FlowySvg(
|
|
||||||
FlowySvgs.m_blue_check_s,
|
|
||||||
blendMode: null,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
onTap: () => onWorkspaceSelected(workspace),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -48,3 +44,76 @@ class MobileWorkspaceMenu extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _WorkspaceMenuItem extends StatelessWidget {
|
||||||
|
const _WorkspaceMenuItem({
|
||||||
|
required this.userProfile,
|
||||||
|
required this.workspace,
|
||||||
|
required this.showTopBorder,
|
||||||
|
required this.currentWorkspace,
|
||||||
|
required this.onWorkspaceSelected,
|
||||||
|
});
|
||||||
|
|
||||||
|
final UserProfilePB userProfile;
|
||||||
|
final UserWorkspacePB workspace;
|
||||||
|
final bool showTopBorder;
|
||||||
|
final UserWorkspacePB currentWorkspace;
|
||||||
|
final void Function(UserWorkspacePB workspace) onWorkspaceSelected;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (_) => WorkspaceMemberBloc(
|
||||||
|
userProfile: userProfile,
|
||||||
|
workspace: workspace,
|
||||||
|
)..add(const WorkspaceMemberEvent.initial()),
|
||||||
|
child: BlocBuilder<WorkspaceMemberBloc, WorkspaceMemberState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final members = state.members;
|
||||||
|
return FlowyOptionTile.text(
|
||||||
|
content: Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
FlowyText(
|
||||||
|
workspace.name,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
FlowyText(
|
||||||
|
state.isLoading
|
||||||
|
? ''
|
||||||
|
: LocaleKeys.settings_appearance_members_membersCount
|
||||||
|
.plural(
|
||||||
|
members.length,
|
||||||
|
),
|
||||||
|
fontSize: 10.0,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 60,
|
||||||
|
showTopBorder: showTopBorder,
|
||||||
|
leftIcon: WorkspaceIcon(
|
||||||
|
enableEdit: false,
|
||||||
|
iconSize: 26,
|
||||||
|
workspace: workspace,
|
||||||
|
),
|
||||||
|
trailing: workspace.workspaceId == currentWorkspace.workspaceId
|
||||||
|
? const FlowySvg(
|
||||||
|
FlowySvgs.m_blue_check_s,
|
||||||
|
blendMode: null,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
onTap: () => onWorkspaceSelected(workspace),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -406,7 +406,10 @@ class _SingleMobileInnerViewItemState extends State<SingleMobileInnerViewItem> {
|
|||||||
ViewEvent.createView(
|
ViewEvent.createView(
|
||||||
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
layout,
|
layout,
|
||||||
section: widget.categoryType.toViewSectionPB,
|
section:
|
||||||
|
widget.categoryType != FolderCategoryType.favorite
|
||||||
|
? widget.categoryType.toViewSectionPB
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -36,26 +36,31 @@ class FlowyOptionTile extends StatelessWidget {
|
|||||||
this.content,
|
this.content,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.fontFamily,
|
this.fontFamily,
|
||||||
|
this.height,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory FlowyOptionTile.text({
|
factory FlowyOptionTile.text({
|
||||||
required String text,
|
String? text,
|
||||||
|
Widget? content,
|
||||||
Color? textColor,
|
Color? textColor,
|
||||||
bool showTopBorder = true,
|
bool showTopBorder = true,
|
||||||
bool showBottomBorder = true,
|
bool showBottomBorder = true,
|
||||||
Widget? leftIcon,
|
Widget? leftIcon,
|
||||||
Widget? trailing,
|
Widget? trailing,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
|
double? height,
|
||||||
}) {
|
}) {
|
||||||
return FlowyOptionTile._(
|
return FlowyOptionTile._(
|
||||||
type: FlowyOptionTileType.text,
|
type: FlowyOptionTileType.text,
|
||||||
text: text,
|
text: text,
|
||||||
|
content: content,
|
||||||
textColor: textColor,
|
textColor: textColor,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
showTopBorder: showTopBorder,
|
showTopBorder: showTopBorder,
|
||||||
showBottomBorder: showBottomBorder,
|
showBottomBorder: showBottomBorder,
|
||||||
leading: leftIcon,
|
leading: leftIcon,
|
||||||
trailing: trailing,
|
trailing: trailing,
|
||||||
|
height: height,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +179,8 @@ class FlowyOptionTile extends StatelessWidget {
|
|||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
final String? fontFamily;
|
final String? fontFamily;
|
||||||
|
|
||||||
|
final double? height;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final leadingWidget = _buildLeading();
|
final leadingWidget = _buildLeading();
|
||||||
@ -182,16 +189,19 @@ class FlowyOptionTile extends StatelessWidget {
|
|||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
showTopBorder: showTopBorder,
|
showTopBorder: showTopBorder,
|
||||||
showBottomBorder: showBottomBorder,
|
showBottomBorder: showBottomBorder,
|
||||||
child: Padding(
|
child: SizedBox(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
height: height,
|
||||||
child: Row(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
if (leadingWidget != null) leadingWidget,
|
child: Row(
|
||||||
if (content != null) content!,
|
children: [
|
||||||
if (content == null) _buildText(),
|
if (leadingWidget != null) leadingWidget,
|
||||||
if (content == null) _buildTextField(),
|
if (content != null) content!,
|
||||||
if (trailing != null) trailing!,
|
if (content == null) _buildText(),
|
||||||
],
|
if (content == null) _buildTextField(),
|
||||||
|
if (trailing != null) trailing!,
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -27,8 +27,8 @@ class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
|||||||
void _dispatch() {
|
void _dispatch() {
|
||||||
on<FavoriteEvent>(
|
on<FavoriteEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.when(
|
||||||
initial: (e) async {
|
initial: () async {
|
||||||
_listener.start(
|
_listener.start(
|
||||||
favoritesUpdated: _onFavoritesUpdated,
|
favoritesUpdated: _onFavoritesUpdated,
|
||||||
);
|
);
|
||||||
@ -44,23 +44,23 @@ class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
didFavorite: (e) {
|
fetchFavorites: () async {
|
||||||
|
final result = await _service.readFavorites();
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(views: [...state.views, ...e.favorite.items]),
|
result.fold(
|
||||||
|
(view) => state.copyWith(
|
||||||
|
views: view.items,
|
||||||
|
),
|
||||||
|
(error) => state.copyWith(
|
||||||
|
views: [],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
didUnfavorite: (e) {
|
toggle: (view) async {
|
||||||
final views = [...state.views]..removeWhere(
|
|
||||||
(view) => e.favorite.items.any((item) => item.id == view.id),
|
|
||||||
);
|
|
||||||
emit(
|
|
||||||
state.copyWith(views: views),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
toggle: (e) async {
|
|
||||||
await _service.toggleFavorite(
|
await _service.toggleFavorite(
|
||||||
e.view.id,
|
view.id,
|
||||||
!e.view.isFavorite,
|
!view.isFavorite,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -73,9 +73,7 @@ class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
|||||||
bool didFavorite,
|
bool didFavorite,
|
||||||
) {
|
) {
|
||||||
favoriteOrFailed.fold(
|
favoriteOrFailed.fold(
|
||||||
(favorite) => didFavorite
|
(favorite) => add(const FetchFavorites()),
|
||||||
? add(FavoriteEvent.didFavorite(favorite))
|
|
||||||
: add(FavoriteEvent.didUnfavorite(favorite)),
|
|
||||||
(error) => Log.error(error),
|
(error) => Log.error(error),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -84,11 +82,8 @@ class FavoriteBloc extends Bloc<FavoriteEvent, FavoriteState> {
|
|||||||
@freezed
|
@freezed
|
||||||
class FavoriteEvent with _$FavoriteEvent {
|
class FavoriteEvent with _$FavoriteEvent {
|
||||||
const factory FavoriteEvent.initial() = Initial;
|
const factory FavoriteEvent.initial() = Initial;
|
||||||
const factory FavoriteEvent.didFavorite(RepeatedViewPB favorite) =
|
|
||||||
DidFavorite;
|
|
||||||
const factory FavoriteEvent.didUnfavorite(RepeatedViewPB favorite) =
|
|
||||||
DidUnfavorite;
|
|
||||||
const factory FavoriteEvent.toggle(ViewPB view) = ToggleFavorite;
|
const factory FavoriteEvent.toggle(ViewPB view) = ToggleFavorite;
|
||||||
|
const factory FavoriteEvent.fetchFavorites() = FetchFavorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -37,24 +37,25 @@ class FavoriteListener {
|
|||||||
FolderNotification ty,
|
FolderNotification ty,
|
||||||
FlowyResult<Uint8List, FlowyError> result,
|
FlowyResult<Uint8List, FlowyError> result,
|
||||||
) {
|
) {
|
||||||
if (_favoriteUpdated == null) {
|
switch (ty) {
|
||||||
return;
|
case FolderNotification.DidFavoriteView:
|
||||||
}
|
result.onSuccess(
|
||||||
|
(success) => _favoriteUpdated?.call(
|
||||||
final isFavorite = ty == FolderNotification.DidFavoriteView;
|
FlowyResult.success(RepeatedViewPB.fromBuffer(success)),
|
||||||
result.fold(
|
true,
|
||||||
(payload) {
|
),
|
||||||
final view = RepeatedViewPB.fromBuffer(payload);
|
|
||||||
_favoriteUpdated!(
|
|
||||||
FlowyResult.success(view),
|
|
||||||
isFavorite,
|
|
||||||
);
|
);
|
||||||
},
|
case FolderNotification.DidUnfavoriteView:
|
||||||
(error) => _favoriteUpdated!(
|
result.map(
|
||||||
FlowyResult.failure(error),
|
(success) => _favoriteUpdated?.call(
|
||||||
isFavorite,
|
FlowyResult.success(RepeatedViewPB.fromBuffer(success)),
|
||||||
),
|
false,
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> stop() async {
|
Future<void> stop() async {
|
||||||
|
@ -363,7 +363,7 @@ class ViewEvent with _$ViewEvent {
|
|||||||
ViewLayoutPB layoutType, {
|
ViewLayoutPB layoutType, {
|
||||||
/// open the view after created
|
/// open the view after created
|
||||||
@Default(true) bool openAfterCreated,
|
@Default(true) bool openAfterCreated,
|
||||||
required ViewSectionPB section,
|
ViewSectionPB? section,
|
||||||
}) = CreateView;
|
}) = CreateView;
|
||||||
const factory ViewEvent.viewDidUpdate(
|
const factory ViewEvent.viewDidUpdate(
|
||||||
FlowyResult<ViewPB, FlowyError> result,
|
FlowyResult<ViewPB, FlowyError> result,
|
||||||
|
@ -174,10 +174,10 @@ class _SidebarSwitchWorkspaceButtonState
|
|||||||
children: [
|
children: [
|
||||||
const HSpace(2.0),
|
const HSpace(2.0),
|
||||||
SizedBox.square(
|
SizedBox.square(
|
||||||
dimension: 28.0,
|
dimension: 30.0,
|
||||||
child: WorkspaceIcon(
|
child: WorkspaceIcon(
|
||||||
workspace: widget.currentWorkspace,
|
workspace: widget.currentWorkspace,
|
||||||
iconSize: 18,
|
iconSize: 20,
|
||||||
enableEdit: false,
|
enableEdit: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:appflowy/plugins/base/icon/icon_picker.dart';
|
import 'package:appflowy/plugins/base/icon/icon_picker.dart';
|
||||||
import 'package:appflowy/util/color_generator/color_generator.dart';
|
import 'package:appflowy/util/color_generator/color_generator.dart';
|
||||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||||
@ -31,16 +33,16 @@ class _WorkspaceIconState extends State<WorkspaceIcon> {
|
|||||||
Widget child = widget.workspace.icon.isNotEmpty
|
Widget child = widget.workspace.icon.isNotEmpty
|
||||||
? Container(
|
? Container(
|
||||||
width: widget.iconSize,
|
width: widget.iconSize,
|
||||||
margin: const EdgeInsets.all(2),
|
alignment: Alignment.center,
|
||||||
child: FlowyText(
|
child: FlowyText(
|
||||||
widget.workspace.icon,
|
widget.workspace.icon,
|
||||||
textAlign: TextAlign.center,
|
|
||||||
fontSize: widget.iconSize,
|
fontSize: widget.iconSize,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
width: widget.iconSize,
|
width: widget.iconSize,
|
||||||
|
height: max(widget.iconSize, 26),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorGenerator.generateColorFromString(
|
color: ColorGenerator.generateColorFromString(
|
||||||
widget.workspace.name,
|
widget.workspace.name,
|
||||||
|
Loading…
Reference in New Issue
Block a user