[flutter]: config question bubble

This commit is contained in:
appflowy 2021-11-05 16:23:44 +08:00
parent 2f4f440097
commit 56324bf8b9
7 changed files with 120 additions and 52 deletions

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
import 'package:app_flowy/workspace/domain/i_user.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
@ -47,12 +48,15 @@ class WelcomeScreen extends StatelessWidget {
}
Widget _renderCreateButton(BuildContext context) {
final theme = context.watch<AppTheme>();
return SizedBox(
width: 200,
height: 40,
child: FlowyTextButton(
"Create workspace",
fontSize: 14,
hoverColor: theme.bg3,
onPressed: () {
context.read<WelcomeBloc>().add(const WelcomeEvent.createWorkspace("workspace", ""));
},
@ -89,10 +93,13 @@ class WorkspaceItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return SizedBox(
height: 46,
child: FlowyTextButton(
workspace.name,
hoverColor: theme.bg3,
fontSize: 14,
onPressed: () => onPressed(workspace),
),

View File

@ -2,6 +2,7 @@ import 'package:app_flowy/workspace/application/home/home_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:flowy_log/flowy_log.dart';
@ -13,29 +14,6 @@ import 'package:styled_widget/styled_widget.dart';
import 'home_layout.dart';
// [[diagram: Home's widget structure]]
// 1.start listening user auth state
//
// HomeListenBloc IUserListener
//
//
// HomeScreen
//
// BlocListener
//
//
// HomeBloc HomeStack
//
//
// BlocBuilder HomeMenu
//
//
// 2.1 show login screen if user EditPannel
// session is invalid
//
// 2.2 build home screen
//
//
class HomeScreen extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
final UserProfile user;
@ -92,7 +70,14 @@ class HomeScreen extends StatelessWidget {
layout: layout,
context: context,
);
return _layoutWidgets(layout: layout, homeStack: homeStack, homeMenu: menu, editPannel: editPannel);
const bubble = QuestionBubble();
return _layoutWidgets(
layout: layout,
homeStack: homeStack,
homeMenu: menu,
editPannel: editPannel,
bubble: bubble,
);
},
);
}
@ -124,8 +109,13 @@ class HomeScreen extends StatelessWidget {
return editPannel;
}
Widget _layoutWidgets(
{required HomeLayout layout, required Widget homeMenu, required Widget homeStack, required Widget editPannel}) {
Widget _layoutWidgets({
required HomeLayout layout,
required Widget homeMenu,
required Widget homeStack,
required Widget editPannel,
required Widget bubble,
}) {
return Stack(
children: [
homeMenu
@ -146,6 +136,13 @@ class HomeScreen extends StatelessWidget {
isClosed: !layout.showEditPannel,
)
.positioned(right: 0, top: 0, bottom: 0, width: layout.editPannelWidth),
bubble
.positioned(
right: 20,
bottom: 20,
animate: true,
)
.animate(layout.animDuration, Curves.easeOut),
],
);
}

View File

@ -0,0 +1,26 @@
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class QuestionBubble extends StatelessWidget {
const QuestionBubble({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return SizedBox(
width: 30,
height: 30,
child: FlowyTextButton(
'?',
fontSize: 12,
fontWeight: FontWeight.w600,
fillColor: theme.selector,
mainAxisAlignment: MainAxisAlignment.center,
radius: BorderRadius.circular(10),
onPressed: () {},
),
);
}
}

View File

@ -14,12 +14,9 @@ class NewAppButton extends StatelessWidget {
const NewAppButton({this.press, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// final theme = context.watch<AppTheme>();
final child = FlowyTextButton(
'New App',
fontSize: 12,
enableHover: false,
onPressed: () async => await _showCreateAppDialog(context),
heading: svgWithSize("home/new_app", const Size(16, 16)),
padding: EdgeInsets.symmetric(horizontal: Insets.l, vertical: 20),

View File

@ -55,53 +55,88 @@ class FlowyButton extends StatelessWidget {
class FlowyTextButton extends StatelessWidget {
final String text;
final double fontSize;
final TextOverflow overflow;
final FontWeight fontWeight;
final VoidCallback? onPressed;
final EdgeInsets padding;
final bool enableHover;
final Widget? heading;
final Color? hoverColor;
final Color? fillColor;
final BorderRadius? radius;
final MainAxisAlignment mainAxisAlignment;
// final HoverDisplayConfig? hoverDisplay;
const FlowyTextButton(
this.text, {
Key? key,
this.onPressed,
this.fontSize = 16,
this.enableHover = true,
this.overflow = TextOverflow.ellipsis,
this.fontWeight = FontWeight.w400,
this.padding = const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
this.hoverColor,
this.fillColor,
this.heading,
this.radius,
this.mainAxisAlignment = MainAxisAlignment.start,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
List<Widget> children = [];
if (heading != null) {
children.add(heading!);
children.add(const HSpace(6));
}
children.add(FlowyText(text, fontSize: fontSize));
children.add(
FlowyText(
text,
overflow: overflow,
fontWeight: fontWeight,
fontSize: fontSize,
textAlign: TextAlign.center,
),
);
Widget child = Padding(
padding: padding,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: mainAxisAlignment,
children: children,
),
);
if (enableHover) {
return InkWell(
onTap: onPressed,
child: FlowyHover(
config: HoverDisplayConfig(borderRadius: BorderRadius.circular(6), hoverColor: theme.bg3),
builder: (context, onHover) => child,
),
);
} else {
return InkWell(
onTap: onPressed,
child: child,
);
}
return RawMaterialButton(
visualDensity: VisualDensity.compact,
hoverElevation: 0,
highlightElevation: 0,
shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)),
fillColor: fillColor,
hoverColor: hoverColor ?? Colors.transparent,
focusColor: Colors.transparent,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
elevation: 0,
onPressed: onPressed,
child: child,
);
// if (hoverColor != null) {
// return InkWell(
// onTap: onPressed,
// child: FlowyHover(
// config: HoverDisplayConfig(borderRadius: radius ?? BorderRadius.circular(6), hoverColor: hoverColor!),
// builder: (context, onHover) => child,
// ),
// );
// } else {
// return InkWell(
// onTap: onPressed,
// child: child,
// );
// }
}
}
// return TextButton(

View File

@ -11,6 +11,7 @@ class FlowyIconButton extends StatelessWidget {
final Color? fillColor;
final Color? hoverColor;
final EdgeInsets iconPadding;
final BorderRadius? radius;
const FlowyIconButton({
Key? key,
@ -20,6 +21,7 @@ class FlowyIconButton extends StatelessWidget {
this.fillColor = Colors.transparent,
this.hoverColor = Colors.transparent,
this.iconPadding = EdgeInsets.zero,
this.radius,
required this.icon,
}) : super(key: key);
@ -50,7 +52,7 @@ class FlowyIconButton extends StatelessWidget {
visualDensity: VisualDensity.compact,
hoverElevation: 0,
highlightElevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)),
shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)),
fillColor: fillColor,
hoverColor: hoverColor,
focusColor: Colors.transparent,

View File

@ -7,6 +7,7 @@ class FlowyText extends StatelessWidget {
final TextOverflow overflow;
final double fontSize;
final FontWeight fontWeight;
final TextAlign? textAlign;
final Color? color;
const FlowyText(
this.title, {
@ -14,20 +15,23 @@ class FlowyText extends StatelessWidget {
this.overflow = TextOverflow.ellipsis,
this.fontSize = 16,
this.fontWeight = FontWeight.w400,
this.textAlign,
this.color,
}) : super(key: key);
const FlowyText.semibold(this.title, {Key? key, this.fontSize = 16, TextOverflow? overflow, this.color})
const FlowyText.semibold(this.title,
{Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign})
: fontWeight = FontWeight.w600,
overflow = overflow ?? TextOverflow.ellipsis,
super(key: key);
const FlowyText.medium(this.title, {Key? key, this.fontSize = 16, TextOverflow? overflow, this.color})
const FlowyText.medium(this.title, {Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign})
: fontWeight = FontWeight.w500,
overflow = overflow ?? TextOverflow.ellipsis,
super(key: key);
const FlowyText.regular(this.title, {Key? key, this.fontSize = 16, TextOverflow? overflow, this.color})
const FlowyText.regular(this.title,
{Key? key, this.fontSize = 16, TextOverflow? overflow, this.color, this.textAlign})
: fontWeight = FontWeight.w400,
overflow = overflow ?? TextOverflow.ellipsis,
super(key: key);