mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: config rename Dialog
This commit is contained in:
parent
7a214ba3f4
commit
ba01235509
@ -6,21 +6,40 @@ PODS:
|
||||
- flowy_sdk (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_inappwebview (0.0.1):
|
||||
- Flutter
|
||||
- flutter_inappwebview/Core (= 0.0.1)
|
||||
- OrderedSet (~> 5.0)
|
||||
- flutter_inappwebview/Core (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (~> 5.0)
|
||||
- flutter_keyboard_visibility (0.0.1):
|
||||
- Flutter
|
||||
- image_picker (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (5.0.0)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- url_launcher (0.0.1):
|
||||
- Flutter
|
||||
- video_player (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- flowy_editor (from `.symlinks/plugins/flowy_editor/ios`)
|
||||
- flowy_infra_ui (from `.symlinks/plugins/flowy_infra_ui/ios`)
|
||||
- flowy_sdk (from `.symlinks/plugins/flowy_sdk/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
|
||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||
- video_player (from `.symlinks/plugins/video_player/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- OrderedSet
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
flowy_editor:
|
||||
@ -31,21 +50,31 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flowy_sdk/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_inappwebview:
|
||||
:path: ".symlinks/plugins/flutter_inappwebview/ios"
|
||||
flutter_keyboard_visibility:
|
||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||
image_picker:
|
||||
:path: ".symlinks/plugins/image_picker/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
url_launcher:
|
||||
:path: ".symlinks/plugins/url_launcher/ios"
|
||||
video_player:
|
||||
:path: ".symlinks/plugins/video_player/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
flowy_editor: bf8d58894ddb03453bd4d8521c57267ad638b837
|
||||
flowy_infra_ui: 146c88346fd55d2ee6a41ae35059a5bf095cfbb3
|
||||
flowy_sdk: c416222c639e678828776789bf0c1a1d0d59df3c
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||
image_picker: 9aa50e1d8cdacdbed739e925b7eea16d014367e6
|
||||
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||
video_player: ecd305f42e9044793efd34846e1ce64c31ea6fcb
|
||||
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ApplicationWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const ratio = 1.73;
|
||||
const minWidth = 500.0;
|
||||
const minWidth = 1000.0;
|
||||
setWindowMinSize(const Size(minWidth, minWidth / ratio));
|
||||
// const launchWidth = 1310.0;
|
||||
// setWindowFrame(const Rect.fromLTWH(0, 0, launchWidth, launchWidth / ratio));
|
||||
|
@ -2,6 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/application/sign_in_bloc.dart';
|
||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
@ -36,8 +37,7 @@ class SignInScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSuccessOrFail(
|
||||
Either<UserProfile, UserError> result, BuildContext context) {
|
||||
void _handleSuccessOrFail(Either<UserProfile, UserError> result, BuildContext context) {
|
||||
result.fold(
|
||||
(user) => router.pushWelcomeScreen(context, user),
|
||||
(error) => showSnapBar(context, error.msg),
|
||||
@ -93,8 +93,7 @@ class SignUpPrompt extends StatelessWidget {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return Row(
|
||||
children: [
|
||||
Text("Dont't have an account",
|
||||
style: TextStyle(color: theme.shader3, fontSize: 12)),
|
||||
Text("Dont't have an account", style: TextStyle(color: theme.shader3, fontSize: 12)),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
textStyle: const TextStyle(fontSize: 12),
|
||||
@ -122,12 +121,10 @@ class LoginButton extends StatelessWidget {
|
||||
return RoundedTextButton(
|
||||
title: 'Login',
|
||||
height: 48,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderRadius: Corners.s10Border,
|
||||
color: theme.main1,
|
||||
press: () {
|
||||
context
|
||||
.read<SignInBloc>()
|
||||
.add(const SignInEvent.signedInWithUserEmailAndPassword());
|
||||
onPressed: () {
|
||||
context.read<SignInBloc>().add(const SignInEvent.signedInWithUserEmailAndPassword());
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -166,25 +163,19 @@ class PasswordTextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BlocBuilder<SignInBloc, SignInState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.passwordError != current.passwordError,
|
||||
buildWhen: (previous, current) => previous.passwordError != current.passwordError,
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
fontSize: 14,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
obscureIcon: svg("home/Hide"),
|
||||
obscureHideIcon: svg("home/Show"),
|
||||
hintText: 'Password',
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorText: context
|
||||
.read<SignInBloc>()
|
||||
.state
|
||||
.passwordError
|
||||
.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context
|
||||
.read<SignInBloc>()
|
||||
.add(SignInEvent.passwordChanged(value)),
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignInBloc>().state.passwordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignInBloc>().add(SignInEvent.passwordChanged(value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -200,21 +191,16 @@ class EmailTextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BlocBuilder<SignInBloc, SignInState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.emailError != current.emailError,
|
||||
buildWhen: (previous, current) => previous.emailError != current.emailError,
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
hintText: 'Email',
|
||||
fontSize: 14,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorText: context
|
||||
.read<SignInBloc>()
|
||||
.state
|
||||
.emailError
|
||||
.fold(() => "", (error) => error),
|
||||
onChanged: (value) =>
|
||||
context.read<SignInBloc>().add(SignInEvent.emailChanged(value)),
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignInBloc>().state.emailError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignInBloc>().add(SignInEvent.emailChanged(value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/application/sign_up_bloc.dart';
|
||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
@ -34,8 +35,7 @@ class SignUpScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSuccessOrFail(
|
||||
BuildContext context, Either<UserProfile, UserError> result) {
|
||||
void _handleSuccessOrFail(BuildContext context, Either<UserProfile, UserError> result) {
|
||||
result.fold(
|
||||
(user) => router.pushWelcomeScreen(context, user),
|
||||
(error) => showSnapBar(context, error.msg),
|
||||
@ -112,12 +112,9 @@ class SignUpButton extends StatelessWidget {
|
||||
return RoundedTextButton(
|
||||
title: 'Get Started',
|
||||
height: 48,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: theme.main1,
|
||||
press: () {
|
||||
context
|
||||
.read<SignUpBloc>()
|
||||
.add(const SignUpEvent.signUpWithUserEmailAndPassword());
|
||||
onPressed: () {
|
||||
context.read<SignUpBloc>().add(const SignUpEvent.signUpWithUserEmailAndPassword());
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -132,26 +129,19 @@ class PasswordTextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BlocBuilder<SignUpBloc, SignUpState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.passwordError != current.passwordError,
|
||||
buildWhen: (previous, current) => previous.passwordError != current.passwordError,
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
obscureIcon: svg("home/Hide"),
|
||||
obscureHideIcon: svg("home/Show"),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
hintText: "Password",
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorText: context
|
||||
.read<SignUpBloc>()
|
||||
.state
|
||||
.passwordError
|
||||
.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context
|
||||
.read<SignUpBloc>()
|
||||
.add(SignUpEvent.passwordChanged(value)),
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.passwordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.passwordChanged(value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -167,26 +157,19 @@ class RepeatPasswordTextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BlocBuilder<SignUpBloc, SignUpState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.repeatPasswordError != current.repeatPasswordError,
|
||||
buildWhen: (previous, current) => previous.repeatPasswordError != current.repeatPasswordError,
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
obscureIcon: svg("home/Hide"),
|
||||
obscureHideIcon: svg("home/Show"),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
hintText: "Repeate password",
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorText: context
|
||||
.read<SignUpBloc>()
|
||||
.state
|
||||
.repeatPasswordError
|
||||
.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context
|
||||
.read<SignUpBloc>()
|
||||
.add(SignUpEvent.repeatPasswordChanged(value)),
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.repeatPasswordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.repeatPasswordChanged(value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -202,21 +185,16 @@ class EmailTextField extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BlocBuilder<SignUpBloc, SignUpState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.emailError != current.emailError,
|
||||
buildWhen: (previous, current) => previous.emailError != current.emailError,
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
hintText: 'Email',
|
||||
fontSize: 14,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorText: context
|
||||
.read<SignUpBloc>()
|
||||
.state
|
||||
.emailError
|
||||
.fold(() => "", (error) => error),
|
||||
onChanged: (value) =>
|
||||
context.read<SignUpBloc>().add(SignUpEvent.emailChanged(value)),
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.emailError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.emailChanged(value)),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
167
app_flowy/lib/workspace/presentation/widgets/dialogs.dart
Normal file
167
app_flowy/lib/workspace/presentation/widgets/dialogs.dart
Normal file
@ -0,0 +1,167 @@
|
||||
import 'package:flowy_infra/strings.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/secondary_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:app_flowy/startup/tasks/application_task.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
export 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
|
||||
class RenameDialog extends StatefulWidget {
|
||||
final String name;
|
||||
final String title;
|
||||
final void Function()? cancel;
|
||||
final void Function(String) confirm;
|
||||
|
||||
const RenameDialog({
|
||||
required this.title,
|
||||
required this.name,
|
||||
required this.confirm,
|
||||
this.cancel,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<RenameDialog> createState() => _CreateRenameDialog();
|
||||
}
|
||||
|
||||
class _CreateRenameDialog extends State<RenameDialog> {
|
||||
String newViewName = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
newViewName = widget.name;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return StyledDialog(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
...[
|
||||
FlowyText.medium(widget.title, color: theme.shader4),
|
||||
VSpace(Insets.sm * 1.5),
|
||||
],
|
||||
FlowyFormTextInput(
|
||||
hintText: widget.name,
|
||||
onChanged: (text) {
|
||||
newViewName = text;
|
||||
},
|
||||
),
|
||||
SizedBox(height: Insets.l),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: OkCancelButton(
|
||||
onOkPressed: () {
|
||||
widget.confirm(newViewName);
|
||||
},
|
||||
onCancelPressed: () {
|
||||
if (widget.cancel != null) {
|
||||
widget.cancel!();
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class OkCancelDialog extends StatelessWidget {
|
||||
final VoidCallback? onOkPressed;
|
||||
final VoidCallback? onCancelPressed;
|
||||
final String? okTitle;
|
||||
final String? cancelTitle;
|
||||
final String? title;
|
||||
final String message;
|
||||
final double? maxWidth;
|
||||
|
||||
const OkCancelDialog(
|
||||
{Key? key,
|
||||
this.onOkPressed,
|
||||
this.onCancelPressed,
|
||||
this.okTitle,
|
||||
this.cancelTitle,
|
||||
this.title,
|
||||
required this.message,
|
||||
this.maxWidth})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return StyledDialog(
|
||||
maxWidth: maxWidth ?? 500,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (title != null) ...[
|
||||
Text(title!.toUpperCase(), style: TextStyles.T1.textColor(theme.shader1)),
|
||||
VSpace(Insets.sm * 1.5),
|
||||
Container(color: theme.bg1, height: 1),
|
||||
VSpace(Insets.m * 1.5),
|
||||
],
|
||||
Text(message, style: TextStyles.Body1.textHeight(1.5)),
|
||||
SizedBox(height: Insets.l),
|
||||
OkCancelButton(
|
||||
onOkPressed: onOkPressed,
|
||||
onCancelPressed: onCancelPressed,
|
||||
okTitle: okTitle?.toUpperCase(),
|
||||
cancelTitle: cancelTitle?.toUpperCase(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class OkCancelButton extends StatelessWidget {
|
||||
final VoidCallback? onOkPressed;
|
||||
final VoidCallback? onCancelPressed;
|
||||
final String? okTitle;
|
||||
final String? cancelTitle;
|
||||
final double? minHeight;
|
||||
|
||||
const OkCancelButton(
|
||||
{Key? key, this.onOkPressed, this.onCancelPressed, this.okTitle, this.cancelTitle, this.minHeight})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
if (onCancelPressed != null)
|
||||
SecondaryTextButton(
|
||||
cancelTitle ?? S.BTN_CANCEL,
|
||||
onPressed: () {
|
||||
onCancelPressed!();
|
||||
AppGlobals.nav.pop();
|
||||
},
|
||||
bigMode: true,
|
||||
),
|
||||
HSpace(Insets.m),
|
||||
if (onOkPressed != null)
|
||||
PrimaryTextButton(
|
||||
okTitle ?? S.BTN_OK,
|
||||
onPressed: () {
|
||||
onOkPressed!();
|
||||
AppGlobals.nav.pop();
|
||||
},
|
||||
bigMode: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:app_flowy/workspace/domain/image.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
@ -40,9 +41,9 @@ class HomeTopBar extends StatelessWidget {
|
||||
height: 30,
|
||||
width: 60,
|
||||
fontSize: 12,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderRadius: Corners.s6Border,
|
||||
color: Colors.lightBlue,
|
||||
press: () {
|
||||
onPressed: () {
|
||||
debugPrint('share page');
|
||||
},
|
||||
);
|
||||
|
@ -1,12 +1,20 @@
|
||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/create_dialog.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/extension.dart';
|
||||
import 'package:app_flowy/startup/tasks/application_task.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:provider/src/provider.dart';
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
|
||||
class NewAppButton extends StatelessWidget {
|
||||
final Function(String)? press;
|
||||
@ -34,12 +42,64 @@ class NewAppButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
Future<void> _showCreateAppDialog(BuildContext context) async {
|
||||
await Dialogs.showWithContext(CreateAppDialogContext(
|
||||
await CreateAppDialog(
|
||||
confirm: (appName) {
|
||||
if (appName.isNotEmpty && press != null) {
|
||||
press!(appName);
|
||||
}
|
||||
},
|
||||
), context);
|
||||
).show(context);
|
||||
}
|
||||
}
|
||||
|
||||
class CreateAppDialog extends StatefulWidget {
|
||||
final void Function()? cancel;
|
||||
final void Function(String) confirm;
|
||||
|
||||
const CreateAppDialog({required this.confirm, this.cancel, Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CreateAppDialog> createState() => _CreateAppDialogState();
|
||||
}
|
||||
|
||||
class _CreateAppDialogState extends State<CreateAppDialog> {
|
||||
String appName = "";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return StyledDialog(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
...[
|
||||
Text('Create App'.toUpperCase(), style: TextStyles.T1.textColor(theme.shader4)),
|
||||
VSpace(Insets.sm * 1.5),
|
||||
// Container(color: theme.greyWeak.withOpacity(.35), height: 1),
|
||||
VSpace(Insets.m * 1.5),
|
||||
],
|
||||
FlowyFormTextInput(
|
||||
hintText: "App name",
|
||||
onChanged: (text) {
|
||||
appName = text;
|
||||
},
|
||||
),
|
||||
SizedBox(height: Insets.l),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: OkCancelButton(
|
||||
onOkPressed: () {
|
||||
widget.confirm(appName);
|
||||
},
|
||||
onCancelPressed: () {
|
||||
if (widget.cancel != null) {
|
||||
widget.cancel!();
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
import 'package:app_flowy/startup/tasks/application_task.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_input.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/ok_cancel_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/dialog_context.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:provider/src/provider.dart';
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CreateAppDialogContext extends DialogContext {
|
||||
String appName;
|
||||
final Function(String)? confirm;
|
||||
|
||||
CreateAppDialogContext({this.appName = "", this.confirm})
|
||||
: super(identifier: 'CreateAppDialogContext');
|
||||
|
||||
@override
|
||||
Widget buildWiget(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return StyledDialog(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
...[
|
||||
Text('Create App'.toUpperCase(),
|
||||
style: TextStyles.T1.textColor(theme.bg1)),
|
||||
VSpace(Insets.sm * 1.5),
|
||||
// Container(color: theme.greyWeak.withOpacity(.35), height: 1),
|
||||
VSpace(Insets.m * 1.5),
|
||||
],
|
||||
FlowyFormTextInput(
|
||||
hintText: "App name",
|
||||
onChanged: (text) {
|
||||
appName = text;
|
||||
},
|
||||
),
|
||||
SizedBox(height: Insets.l),
|
||||
OkCancelButton(
|
||||
onOkPressed: () {
|
||||
if (confirm != null) {
|
||||
confirm!(appName);
|
||||
AppGlobals.nav.pop();
|
||||
}
|
||||
},
|
||||
onCancelPressed: () {
|
||||
AppGlobals.nav.pop();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [identifier];
|
||||
|
||||
@override
|
||||
bool get barrierDismissable => false;
|
||||
}
|
@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/pop_up_window.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
@ -51,7 +51,7 @@ class ViewSectionItem extends StatelessWidget {
|
||||
},
|
||||
child: FlowyHover(
|
||||
config: HoverDisplayConfig(hoverColor: theme.bg3),
|
||||
builder: (context, onHover) => _render(context, onHover, state),
|
||||
builder: (_, onHover) => _render(context, onHover, state),
|
||||
isOnSelected: () => state.isEditing || isSelected,
|
||||
),
|
||||
);
|
||||
@ -91,12 +91,14 @@ class ViewSectionItem extends StatelessWidget {
|
||||
action.foldRight({}, (action, previous) {
|
||||
switch (action) {
|
||||
case ViewAction.rename:
|
||||
FlowyPoppuWindow.show(
|
||||
context,
|
||||
child: ViewRenamePannel(renameCallback: (name) {
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(name));
|
||||
}),
|
||||
);
|
||||
RenameDialog(
|
||||
title: 'Rename',
|
||||
name: context.read<ViewBloc>().state.view.name,
|
||||
confirm: (newName) {
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(newName));
|
||||
},
|
||||
).show(context);
|
||||
|
||||
break;
|
||||
case ViewAction.delete:
|
||||
context.read<ViewBloc>().add(const ViewEvent.delete());
|
||||
@ -133,13 +135,3 @@ class ViewDisclosureButton extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ViewRenamePannel extends StatelessWidget {
|
||||
final void Function(String) renameCallback;
|
||||
const ViewRenamePannel({Key? key, required this.renameCallback}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(width: 100, height: 200, child: Container(color: Colors.black));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -35,12 +36,12 @@ class MenuUser extends MenuItem {
|
||||
}
|
||||
|
||||
Widget _renderAvatar(BuildContext context) {
|
||||
return SizedBox(
|
||||
return const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: const Image(image: AssetImage('assets/images/avatar.jpg')),
|
||||
borderRadius: Corners.s5Border,
|
||||
child: Image(image: AssetImage('assets/images/avatar.jpg')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:window_size/window_size.dart';
|
||||
|
||||
@ -14,15 +15,48 @@ class FlowyPoppuWindow extends StatelessWidget {
|
||||
static Future<void> show(
|
||||
BuildContext context, {
|
||||
required Widget child,
|
||||
required Size size,
|
||||
}) async {
|
||||
final window = await getWindowInfo();
|
||||
FlowyOverlay.of(context).insertWithRect(
|
||||
widget: FlowyPoppuWindow(child: child),
|
||||
widget: SizedBox.fromSize(
|
||||
size: size,
|
||||
child: FlowyPoppuWindow(child: child),
|
||||
),
|
||||
identifier: 'FlowyPoppuWindow',
|
||||
anchorPosition: Offset.zero,
|
||||
anchorPosition: Offset(-size.width / 2.0, -size.height / 2.0),
|
||||
anchorSize: window.frame.size,
|
||||
anchorDirection: AnchorDirection.center,
|
||||
style: FlowyOverlayStyle(blur: true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PopupTextField extends StatelessWidget {
|
||||
final void Function(String) textDidChange;
|
||||
const PopupTextField({
|
||||
Key? key,
|
||||
required this.textDidChange,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: RoundedInputField(
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
hintText: '',
|
||||
normalBorderColor: const Color(0xffbdbdbd),
|
||||
onChanged: textDidChange,
|
||||
),
|
||||
type: MaterialType.transparency,
|
||||
);
|
||||
}
|
||||
|
||||
static void show({required BuildContext context, required Size size, required void Function(String) textDidChange}) {
|
||||
FlowyPoppuWindow.show(
|
||||
context,
|
||||
size: size,
|
||||
child: PopupTextField(textDidChange: textDidChange),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -58,35 +58,21 @@ class Sizes {
|
||||
}
|
||||
|
||||
class Corners {
|
||||
static double get btn => s5;
|
||||
static const BorderRadius s3Border = BorderRadius.all(s3Radius);
|
||||
static const Radius s3Radius = Radius.circular(3);
|
||||
|
||||
static double get dialog => 12;
|
||||
static const BorderRadius s5Border = BorderRadius.all(s5Radius);
|
||||
static const Radius s5Radius = Radius.circular(5);
|
||||
|
||||
/// Xs
|
||||
static double get s3 => 3;
|
||||
static const BorderRadius s6Border = BorderRadius.all(s6Radius);
|
||||
static const Radius s6Radius = Radius.circular(6);
|
||||
|
||||
static BorderRadius get s3Border => BorderRadius.all(s3Radius);
|
||||
static const BorderRadius s8Border = BorderRadius.all(s8Radius);
|
||||
static const Radius s8Radius = Radius.circular(8);
|
||||
|
||||
static Radius get s3Radius => Radius.circular(s3);
|
||||
static const BorderRadius s10Border = BorderRadius.all(s10Radius);
|
||||
static const Radius s10Radius = Radius.circular(10);
|
||||
|
||||
/// Small
|
||||
static double get s5 => 5;
|
||||
|
||||
static BorderRadius get s5Border => BorderRadius.all(s5Radius);
|
||||
|
||||
static Radius get s5Radius => Radius.circular(s5);
|
||||
|
||||
/// Medium
|
||||
static double get s8 => 8;
|
||||
|
||||
static BorderRadius get s8Border => BorderRadius.all(s8Radius);
|
||||
|
||||
static Radius get s8Radius => Radius.circular(s8);
|
||||
|
||||
/// Large
|
||||
static double get s10 => 10;
|
||||
|
||||
static BorderRadius get s10Border => BorderRadius.all(s10Radius);
|
||||
|
||||
static Radius get s10Radius => Radius.circular(s10);
|
||||
static const BorderRadius s12Border = BorderRadius.all(s12Radius);
|
||||
static const Radius s12Radius = Radius.circular(12);
|
||||
}
|
||||
|
@ -65,19 +65,16 @@ class TextStyles {
|
||||
static TextStyle get Body3 => lato.size(FontSizes.s11);
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
static TextStyle get Callout =>
|
||||
quicksand.size(FontSizes.s14).letterSpace(1.75);
|
||||
static TextStyle get Callout => quicksand.size(FontSizes.s14).letterSpace(1.75);
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
static TextStyle get CalloutFocus => Callout.bold;
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
static TextStyle get Btn =>
|
||||
quicksand.bold.size(FontSizes.s14).letterSpace(1.75);
|
||||
static TextStyle get Btn => quicksand.bold.size(FontSizes.s14).letterSpace(1.75);
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
static TextStyle get BtnSelected =>
|
||||
quicksand.size(FontSizes.s14).letterSpace(1.75);
|
||||
static TextStyle get BtnSelected => quicksand.size(FontSizes.s14).letterSpace(1.75);
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
static TextStyle get Footnote => quicksand.bold.size(FontSizes.s11);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ListOverlay extends StatelessWidget {
|
||||
@ -23,13 +24,7 @@ class ListOverlay extends StatelessWidget {
|
||||
type: MaterialType.transparency,
|
||||
child: Container(
|
||||
constraints: BoxConstraints.tight(Size(maxWidth, maxHeight)),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||
boxShadow: [
|
||||
BoxShadow(color: Colors.black.withOpacity(0.1), spreadRadius: 1, blurRadius: 20.0),
|
||||
],
|
||||
),
|
||||
decoration: FlowyDecoration.decoration(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 6),
|
||||
child: ListView.builder(
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
@ -26,7 +27,7 @@ class FlowyButton extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: FlowyHover(
|
||||
config: HoverDisplayConfig(borderRadius: BorderRadius.circular(6), hoverColor: hoverColor),
|
||||
config: HoverDisplayConfig(borderRadius: Corners.s6Border, hoverColor: hoverColor),
|
||||
builder: (context, onHover) => _render(),
|
||||
),
|
||||
);
|
||||
|
@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FlowyDecoration {
|
||||
static Decoration decoration() {
|
||||
return const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||
boxShadow: [
|
||||
BoxShadow(color: Color(0xfff2f2f2), spreadRadius: 1, blurRadius: 10.0),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ class BaseStyledButton extends StatefulWidget {
|
||||
final EdgeInsets? contentPadding;
|
||||
final double? minWidth;
|
||||
final double? minHeight;
|
||||
final double? borderRadius;
|
||||
final BorderRadius? borderRadius;
|
||||
final bool useBtnText;
|
||||
final bool autoFocus;
|
||||
|
||||
@ -78,19 +78,12 @@ class _BaseStyledBtnState extends State<BaseStyledButton> {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: widget.bgColor ?? theme.surface,
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius ?? Corners.s5),
|
||||
borderRadius: widget.borderRadius ?? Corners.s10Border,
|
||||
boxShadow: _isFocused
|
||||
? [
|
||||
BoxShadow(color: theme.shader6, offset: Offset.zero, blurRadius: 8.0, spreadRadius: 0.0),
|
||||
BoxShadow(
|
||||
color: theme.shader6,
|
||||
offset: Offset.zero,
|
||||
blurRadius: 8.0,
|
||||
spreadRadius: 0.0),
|
||||
BoxShadow(
|
||||
color: widget.bgColor ?? theme.surface,
|
||||
offset: Offset.zero,
|
||||
blurRadius: 8.0,
|
||||
spreadRadius: -4.0),
|
||||
color: widget.bgColor ?? theme.surface, offset: Offset.zero, blurRadius: 8.0, spreadRadius: -4.0),
|
||||
]
|
||||
: [],
|
||||
),
|
||||
@ -101,8 +94,7 @@ class _BaseStyledBtnState extends State<BaseStyledButton> {
|
||||
width: 1.8,
|
||||
color: theme.shader6,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(widget.borderRadius ?? Corners.s5),
|
||||
borderRadius: widget.borderRadius ?? Corners.s10Border,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
@ -129,14 +121,13 @@ class _BaseStyledBtnState extends State<BaseStyledButton> {
|
||||
),
|
||||
opacity: widget.onPressed != null ? 1 : .7,
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0),
|
||||
constraints: BoxConstraints(minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0),
|
||||
onPressed: widget.onPressed,
|
||||
shape: widget.shape ??
|
||||
RoundedRectangleBorder(
|
||||
side: BorderSide(color: widget.outlineColor, width: 1.5),
|
||||
borderRadius:
|
||||
BorderRadius.circular(widget.borderRadius ?? Corners.s5)),
|
||||
side: BorderSide(color: widget.outlineColor, width: 1.5),
|
||||
borderRadius: widget.borderRadius ?? Corners.s10Border,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/strings.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'primary_button.dart';
|
||||
import 'secondary_button.dart';
|
||||
|
||||
class OkCancelButton extends StatelessWidget {
|
||||
final VoidCallback? onOkPressed;
|
||||
final VoidCallback? onCancelPressed;
|
||||
final String? okTitle;
|
||||
final String? cancelTitle;
|
||||
final double? minHeight;
|
||||
|
||||
const OkCancelButton(
|
||||
{Key? key,
|
||||
this.onOkPressed,
|
||||
this.onCancelPressed,
|
||||
this.okTitle,
|
||||
this.cancelTitle,
|
||||
this.minHeight})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (onOkPressed != null)
|
||||
PrimaryTextButton(okTitle ?? S.BTN_OK.toUpperCase(),
|
||||
onPressed: onOkPressed),
|
||||
HSpace(Insets.m),
|
||||
if (onCancelPressed != null)
|
||||
SecondaryTextButton(cancelTitle ?? S.BTN_CANCEL.toUpperCase(),
|
||||
onPressed: onCancelPressed),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -4,51 +4,42 @@ import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'base_styled_button.dart';
|
||||
// ignore: import_of_legacy_library_into_null_safe
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
|
||||
class PrimaryButton extends StatelessWidget {
|
||||
final Widget child;
|
||||
final VoidCallback? onPressed;
|
||||
final bool bigMode;
|
||||
|
||||
const PrimaryButton(
|
||||
{Key? key, required this.child, this.onPressed, this.bigMode = false})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BaseStyledButton(
|
||||
minWidth: bigMode ? 160 : 78,
|
||||
minHeight: bigMode ? 60 : 42,
|
||||
contentPadding: EdgeInsets.all(bigMode ? Insets.l : Insets.m),
|
||||
bgColor: theme.bg1,
|
||||
hoverColor: theme.hover,
|
||||
downColor: theme.selector,
|
||||
borderRadius: bigMode ? Corners.s8 : Corners.s5,
|
||||
child: child,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PrimaryTextButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback? onPressed;
|
||||
final bool bigMode;
|
||||
|
||||
const PrimaryTextButton(this.label,
|
||||
{Key? key, this.onPressed, this.bigMode = false})
|
||||
: super(key: key);
|
||||
const PrimaryTextButton(this.label, {Key? key, this.onPressed, this.bigMode = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
TextStyle txtStyle = (bigMode ? TextStyles.Callout : TextStyles.Footnote)
|
||||
.textColor(Colors.white);
|
||||
return PrimaryButton(
|
||||
bigMode: bigMode,
|
||||
onPressed: onPressed,
|
||||
child: Text(label, style: txtStyle));
|
||||
TextStyle txtStyle = TextStyles.Footnote.textColor(Colors.white);
|
||||
return PrimaryButton(bigMode: bigMode, onPressed: onPressed, child: Text(label, style: txtStyle));
|
||||
}
|
||||
}
|
||||
|
||||
class PrimaryButton extends StatelessWidget {
|
||||
final Widget child;
|
||||
final VoidCallback? onPressed;
|
||||
final bool bigMode;
|
||||
|
||||
const PrimaryButton({Key? key, required this.child, this.onPressed, this.bigMode = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return BaseStyledButton(
|
||||
minWidth: bigMode ? 170 : 78,
|
||||
minHeight: bigMode ? 48 : 28,
|
||||
contentPadding: EdgeInsets.all(bigMode ? Insets.sm : Insets.l),
|
||||
bgColor: theme.main1,
|
||||
hoverColor: theme.main1,
|
||||
downColor: theme.main1,
|
||||
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
||||
child: child,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:flowy_infra_ui/style_widget/image_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// ignore: import_of_legacy_library_into_null_safe
|
||||
@ -11,84 +10,39 @@ import 'base_styled_button.dart';
|
||||
class SecondaryTextButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback? onPressed;
|
||||
final bool bigMode;
|
||||
|
||||
const SecondaryTextButton(this.label, {Key? key, this.onPressed}) : super(key: key);
|
||||
const SecondaryTextButton(this.label, {Key? key, this.onPressed, this.bigMode = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
TextStyle txtStyle = TextStyles.Footnote.textColor(theme.shader1);
|
||||
return SecondaryButton(onPressed: onPressed, child: Text(label, style: txtStyle));
|
||||
TextStyle txtStyle = TextStyles.Footnote.textColor(theme.main1);
|
||||
return SecondaryButton(bigMode: bigMode, onPressed: onPressed, child: Text(label, style: txtStyle));
|
||||
}
|
||||
}
|
||||
|
||||
class SecondaryIconButton extends StatelessWidget {
|
||||
/// Must be either an `AssetImage` for an `ImageIcon` or an `IconData` for a regular `Icon`
|
||||
final AssetImage icon;
|
||||
final Function()? onPressed;
|
||||
final Color? color;
|
||||
|
||||
const SecondaryIconButton(this.icon, {Key? key, this.onPressed, this.color})
|
||||
: assert((icon is IconData)),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return SecondaryButton(
|
||||
onPressed: onPressed,
|
||||
minHeight: 36,
|
||||
minWidth: 36,
|
||||
contentPadding: Insets.sm,
|
||||
child: FlowyImageIcon(icon, size: 20, color: color ?? theme.shader4),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SecondaryButton extends StatefulWidget {
|
||||
class SecondaryButton extends StatelessWidget {
|
||||
final Widget child;
|
||||
final VoidCallback? onPressed;
|
||||
final double? minWidth;
|
||||
final double? minHeight;
|
||||
final double? contentPadding;
|
||||
final Function(bool)? onFocusChanged;
|
||||
final bool bigMode;
|
||||
|
||||
const SecondaryButton(
|
||||
{Key? key,
|
||||
required this.child,
|
||||
this.onPressed,
|
||||
this.minWidth,
|
||||
this.minHeight,
|
||||
this.contentPadding,
|
||||
this.onFocusChanged})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_SecondaryButtonState createState() => _SecondaryButtonState();
|
||||
}
|
||||
|
||||
class _SecondaryButtonState extends State<SecondaryButton> {
|
||||
bool _isMouseOver = false;
|
||||
const SecondaryButton({Key? key, required this.child, this.onPressed, this.bigMode = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return MouseRegion(
|
||||
onEnter: (_) => setState(() => _isMouseOver = true),
|
||||
onExit: (_) => setState(() => _isMouseOver = false),
|
||||
child: BaseStyledButton(
|
||||
minWidth: widget.minWidth ?? 78,
|
||||
minHeight: widget.minHeight ?? 42,
|
||||
contentPadding: EdgeInsets.all(widget.contentPadding ?? Insets.m),
|
||||
bgColor: theme.bg1,
|
||||
outlineColor: (_isMouseOver ? theme.hover : theme.shader6),
|
||||
hoverColor: theme.hover,
|
||||
onFocusChanged: widget.onFocusChanged,
|
||||
downColor: theme.selector,
|
||||
borderRadius: Corners.s5,
|
||||
child: IgnorePointer(child: widget.child),
|
||||
onPressed: widget.onPressed,
|
||||
),
|
||||
return BaseStyledButton(
|
||||
minWidth: bigMode ? 170 : 78,
|
||||
minHeight: bigMode ? 48 : 28,
|
||||
contentPadding: EdgeInsets.all(bigMode ? Insets.sm : Insets.l),
|
||||
bgColor: theme.shader7,
|
||||
hoverColor: theme.hover,
|
||||
downColor: theme.main1,
|
||||
outlineColor: theme.main1,
|
||||
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
||||
child: child,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class DialogContext extends Equatable {
|
||||
bool get barrierDismissable => true;
|
||||
final String identifier;
|
||||
|
||||
const DialogContext({required this.identifier});
|
||||
Widget buildWiget(BuildContext context);
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
class DialogSize {
|
||||
static double get minDialogWidth => 380;
|
||||
static double get minDialogWidth => 480;
|
||||
}
|
||||
|
@ -1,105 +1,14 @@
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/widget/buttons/ok_cancel_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/dialog_size.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// ignore: import_of_legacy_library_into_null_safe
|
||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'dialog_context.dart';
|
||||
export 'dialog_context.dart';
|
||||
|
||||
class Dialogs {
|
||||
static Future<dynamic> show(Widget child, BuildContext context) async {
|
||||
return await Navigator.of(context).push(
|
||||
StyledDialogRoute(
|
||||
pageBuilder: (BuildContext buildContext, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return SafeArea(child: child);
|
||||
},
|
||||
),
|
||||
);
|
||||
/*return await showDialog(
|
||||
context: context ?? MainViewContext.value,
|
||||
builder: (context) => child,
|
||||
);*/
|
||||
}
|
||||
|
||||
static Future<dynamic> showWithContext(
|
||||
DialogContext dialogContext, BuildContext context) async {
|
||||
return await Navigator.of(context).push(
|
||||
StyledDialogRoute(
|
||||
barrierDismissible: dialogContext.barrierDismissable,
|
||||
pageBuilder: (BuildContext buildContext, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return SafeArea(child: dialogContext.buildWiget(buildContext));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class StyledDialogRoute<T> extends PopupRoute<T> {
|
||||
StyledDialogRoute({
|
||||
required RoutePageBuilder pageBuilder,
|
||||
bool barrierDismissible = false,
|
||||
String? barrierLabel,
|
||||
Color barrierColor = const Color(0x80000000),
|
||||
Duration transitionDuration = const Duration(milliseconds: 200),
|
||||
RouteTransitionsBuilder? transitionBuilder,
|
||||
RouteSettings? settings,
|
||||
}) : _pageBuilder = pageBuilder,
|
||||
_barrierDismissible = barrierDismissible,
|
||||
_barrierLabel = barrierLabel ?? '',
|
||||
_barrierColor = barrierColor,
|
||||
_transitionDuration = transitionDuration,
|
||||
_transitionBuilder = transitionBuilder,
|
||||
super(settings: settings);
|
||||
|
||||
final RoutePageBuilder _pageBuilder;
|
||||
|
||||
@override
|
||||
bool get barrierDismissible => _barrierDismissible;
|
||||
final bool _barrierDismissible;
|
||||
|
||||
@override
|
||||
String get barrierLabel => _barrierLabel;
|
||||
final String _barrierLabel;
|
||||
|
||||
@override
|
||||
Color get barrierColor => _barrierColor;
|
||||
final Color _barrierColor;
|
||||
|
||||
@override
|
||||
Duration get transitionDuration => _transitionDuration;
|
||||
final Duration _transitionDuration;
|
||||
|
||||
final RouteTransitionsBuilder? _transitionBuilder;
|
||||
|
||||
@override
|
||||
Widget buildPage(BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return Semantics(
|
||||
child: _pageBuilder(context, animation, secondaryAnimation),
|
||||
scopesRoute: true,
|
||||
explicitChildNodes: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildTransitions(BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) {
|
||||
if (_transitionBuilder == null) {
|
||||
return FadeTransition(
|
||||
opacity: CurvedAnimation(parent: animation, curve: Curves.linear),
|
||||
child: child);
|
||||
} else {
|
||||
return _transitionBuilder!(context, animation, secondaryAnimation, child);
|
||||
} // Some default transition
|
||||
extension IntoDialog on Widget {
|
||||
Future<dynamic> show(BuildContext context) async {
|
||||
await Dialogs.show(this, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,38 +30,36 @@ class StyledDialog extends StatelessWidget {
|
||||
this.padding,
|
||||
this.margin,
|
||||
this.bgColor,
|
||||
this.borderRadius,
|
||||
this.borderRadius = const BorderRadius.all(Radius.circular(6)),
|
||||
this.shrinkWrap = true,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final radius = borderRadius ?? Corners.s8Border;
|
||||
final theme = context.watch<AppTheme>();
|
||||
|
||||
Widget innerContent = Container(
|
||||
padding: padding ?? EdgeInsets.all(Insets.lGutter),
|
||||
color: bgColor ?? theme.bg1,
|
||||
color: bgColor ?? theme.shader7,
|
||||
child: child,
|
||||
);
|
||||
|
||||
if (shrinkWrap) {
|
||||
innerContent =
|
||||
IntrinsicWidth(child: IntrinsicHeight(child: innerContent));
|
||||
innerContent = IntrinsicWidth(child: IntrinsicHeight(child: innerContent));
|
||||
}
|
||||
|
||||
return FocusTraversalGroup(
|
||||
child: Container(
|
||||
margin: margin ?? EdgeInsets.all(Insets.lGutter * 2),
|
||||
alignment: Alignment.center,
|
||||
child: ConstrainedBox(
|
||||
child: Container(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: DialogSize.minDialogWidth,
|
||||
maxHeight: maxHeight ?? double.infinity,
|
||||
maxWidth: maxWidth ?? double.infinity,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: radius,
|
||||
borderRadius: borderRadius,
|
||||
child: SingleChildScrollView(
|
||||
physics: StyledScrollPhysics(),
|
||||
//https://medium.com/saugo360/https-medium-com-saugo360-flutter-using-overlay-to-display-floating-widgets-2e6d0e8decb9
|
||||
@ -168,51 +75,78 @@ class StyledDialog extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class OkCancelDialog extends StatelessWidget {
|
||||
final VoidCallback? onOkPressed;
|
||||
final VoidCallback? onCancelPressed;
|
||||
final String? okTitle;
|
||||
final String? cancelTitle;
|
||||
final String? title;
|
||||
final String message;
|
||||
final double? maxWidth;
|
||||
|
||||
const OkCancelDialog(
|
||||
{Key? key,
|
||||
this.onOkPressed,
|
||||
this.onCancelPressed,
|
||||
this.okTitle,
|
||||
this.cancelTitle,
|
||||
this.title,
|
||||
required this.message,
|
||||
this.maxWidth})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
return StyledDialog(
|
||||
maxWidth: maxWidth ?? 500,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (title != null) ...[
|
||||
Text(title!.toUpperCase(),
|
||||
style: TextStyles.T1.textColor(theme.shader1)),
|
||||
VSpace(Insets.sm * 1.5),
|
||||
Container(color: theme.bg1, height: 1),
|
||||
VSpace(Insets.m * 1.5),
|
||||
],
|
||||
Text(message, style: TextStyles.Body1.textHeight(1.5)),
|
||||
SizedBox(height: Insets.l),
|
||||
OkCancelButton(
|
||||
onOkPressed: onOkPressed,
|
||||
onCancelPressed: onCancelPressed,
|
||||
okTitle: okTitle?.toUpperCase(),
|
||||
cancelTitle: cancelTitle?.toUpperCase(),
|
||||
)
|
||||
],
|
||||
class Dialogs {
|
||||
static Future<dynamic> show(Widget child, BuildContext context) async {
|
||||
return await Navigator.of(context).push(
|
||||
StyledDialogRoute(
|
||||
barrier: DialogBarrier(color: Colors.black.withOpacity(0.4)),
|
||||
pageBuilder: (BuildContext buildContext, Animation<double> animation, Animation<double> secondaryAnimation) {
|
||||
return SafeArea(child: child);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DialogBarrier {
|
||||
String label;
|
||||
Color color;
|
||||
bool dismissible;
|
||||
ImageFilter filter;
|
||||
|
||||
DialogBarrier({
|
||||
this.dismissible = true,
|
||||
this.color = Colors.transparent,
|
||||
this.label = '',
|
||||
}) : filter = ImageFilter.blur(sigmaX: 4, sigmaY: 4);
|
||||
}
|
||||
|
||||
class StyledDialogRoute<T> extends PopupRoute<T> {
|
||||
final RoutePageBuilder _pageBuilder;
|
||||
final DialogBarrier barrier;
|
||||
|
||||
StyledDialogRoute({
|
||||
required RoutePageBuilder pageBuilder,
|
||||
required this.barrier,
|
||||
Duration transitionDuration = const Duration(milliseconds: 360),
|
||||
RouteTransitionsBuilder? transitionBuilder,
|
||||
RouteSettings? settings,
|
||||
}) : _pageBuilder = pageBuilder,
|
||||
_transitionDuration = transitionDuration,
|
||||
_transitionBuilder = transitionBuilder,
|
||||
super(settings: settings, filter: barrier.filter);
|
||||
|
||||
@override
|
||||
bool get barrierDismissible => barrier.dismissible;
|
||||
|
||||
@override
|
||||
String get barrierLabel => barrier.label;
|
||||
|
||||
@override
|
||||
Color get barrierColor => barrier.color;
|
||||
|
||||
@override
|
||||
Duration get transitionDuration => _transitionDuration;
|
||||
final Duration _transitionDuration;
|
||||
|
||||
final RouteTransitionsBuilder? _transitionBuilder;
|
||||
|
||||
@override
|
||||
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
|
||||
return Semantics(
|
||||
child: _pageBuilder(context, animation, secondaryAnimation),
|
||||
scopesRoute: true,
|
||||
explicitChildNodes: true,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildTransitions(
|
||||
BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
|
||||
if (_transitionBuilder == null) {
|
||||
return FadeTransition(opacity: CurvedAnimation(parent: animation, curve: Curves.easeInOut), child: child);
|
||||
} else {
|
||||
return _transitionBuilder!(context, animation, secondaryAnimation, child);
|
||||
} // Some default transition
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RoundedTextButton extends StatelessWidget {
|
||||
final VoidCallback? press;
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
final double? width;
|
||||
final double? height;
|
||||
@ -13,11 +14,11 @@ class RoundedTextButton extends StatelessWidget {
|
||||
|
||||
const RoundedTextButton({
|
||||
Key? key,
|
||||
this.press,
|
||||
this.onPressed,
|
||||
this.title,
|
||||
this.width,
|
||||
this.height,
|
||||
this.borderRadius = BorderRadius.zero,
|
||||
this.borderRadius = Corners.s12Border,
|
||||
this.borderColor = Colors.transparent,
|
||||
this.color = Colors.transparent,
|
||||
this.textColor = Colors.white,
|
||||
@ -45,7 +46,7 @@ class RoundedTextButton extends StatelessWidget {
|
||||
title ?? '',
|
||||
style: TextStyle(color: textColor, fontSize: fontSize),
|
||||
),
|
||||
onPressed: press,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -79,8 +80,7 @@ class RoundedImageButton extends StatelessWidget {
|
||||
child: TextButton(
|
||||
onPressed: press,
|
||||
style: ButtonStyle(
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(RoundedRectangleBorder(
|
||||
borderRadius: borderRadius,
|
||||
))),
|
||||
child: child,
|
||||
|
@ -1,9 +1,8 @@
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/text_field_container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class RoundedInputField extends StatefulWidget {
|
||||
@ -12,11 +11,11 @@ class RoundedInputField extends StatefulWidget {
|
||||
final bool obscureText;
|
||||
final Widget? obscureIcon;
|
||||
final Widget? obscureHideIcon;
|
||||
final FontWeight? fontWeight;
|
||||
final double? fontSize;
|
||||
final Color normalBorderColor;
|
||||
final Color highlightBorderColor;
|
||||
final Color cursorColor;
|
||||
final String errorText;
|
||||
final TextStyle style;
|
||||
final ValueChanged<String>? onChanged;
|
||||
late bool enableObscure;
|
||||
var _text = "";
|
||||
@ -31,8 +30,8 @@ class RoundedInputField extends StatefulWidget {
|
||||
this.onChanged,
|
||||
this.normalBorderColor = Colors.transparent,
|
||||
this.highlightBorderColor = Colors.transparent,
|
||||
this.fontWeight = FontWeight.normal,
|
||||
this.fontSize = 20,
|
||||
this.cursorColor = Colors.black,
|
||||
this.style = const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
|
||||
this.errorText = "",
|
||||
}) : super(key: key) {
|
||||
enableObscure = obscureText;
|
||||
@ -45,7 +44,6 @@ class RoundedInputField extends StatefulWidget {
|
||||
class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<AppTheme>();
|
||||
final Icon? newIcon = widget.icon == null
|
||||
? null
|
||||
: Icon(
|
||||
@ -61,7 +59,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
List<Widget> children = [
|
||||
TextFieldContainer(
|
||||
height: 48,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderRadius: Corners.s10Border,
|
||||
borderColor: borderColor,
|
||||
child: TextFormField(
|
||||
onChanged: (value) {
|
||||
@ -71,7 +69,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
cursorColor: theme.main1,
|
||||
cursorColor: widget.cursorColor,
|
||||
obscureText: widget.enableObscure,
|
||||
decoration: InputDecoration(
|
||||
icon: newIcon,
|
||||
@ -90,10 +88,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
widget.errorText,
|
||||
style: TextStyle(
|
||||
color: widget.highlightBorderColor,
|
||||
fontWeight: widget.fontWeight,
|
||||
fontSize: widget.fontSize),
|
||||
style: widget.style,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user