diff --git a/app_flowy/lib/workspace/presentation/home/navigation.dart b/app_flowy/lib/workspace/presentation/home/navigation.dart index 06e26e71eb..d2bd97aeff 100644 --- a/app_flowy/lib/workspace/presentation/home/navigation.dart +++ b/app_flowy/lib/workspace/presentation/home/navigation.dart @@ -61,14 +61,22 @@ class FlowyNavigation extends StatelessWidget { ); }, update: (_, notifier, controller) => controller!..update(notifier), - child: Row(children: [ - Selector>( - selector: (context, notifier) => notifier.collapasedNotifier, - builder: (ctx, collapsedNotifier, child) => _renderCollapse(ctx, collapsedNotifier)), - Selector>( + child: Expanded( + child: Row(children: [ + Selector>( + selector: (context, notifier) => notifier.collapasedNotifier, + builder: (ctx, collapsedNotifier, child) => _renderCollapse(ctx, collapsedNotifier)), + Selector>( selector: (context, notifier) => notifier.navigationItems, - builder: (ctx, items, child) => Row(children: _renderNavigationItems(items))), - ]), + builder: (ctx, items, child) => Expanded( + child: Wrap( + children: _renderNavigationItems(items), + crossAxisAlignment: WrapCrossAlignment.start, + ), + ), + ), + ]), + ), ); } @@ -106,7 +114,13 @@ class FlowyNavigation extends StatelessWidget { Widget last = NaviItemWidget(newItems.removeLast()); List widgets = List.empty(growable: true); - widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList()); + // widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList()); + + for (final item in newItems) { + widgets.add(NaviItemWidget(item)); + widgets.add(const Text('/')); + } + widgets.add(last); return widgets; @@ -129,39 +143,13 @@ class FlowyNavigation extends StatelessWidget { } } -class IconNaviItemWidget extends StatelessWidget { - final NavigationItem item; - const IconNaviItemWidget(this.item, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 24, - child: InkWell( - child: item.leftBarItem, - onTap: () { - debugPrint('show app document'); - }, - ).padding(horizontal: 8, vertical: 2), - ); - } -} - class NaviItemWidget extends StatelessWidget { final NavigationItem item; const NaviItemWidget(this.item, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return SizedBox( - height: 24, - child: InkWell( - child: item.leftBarItem, - onTap: () { - debugPrint('show app document'); - }, - ).padding(horizontal: 8, vertical: 2), - ); + return item.leftBarItem.padding(horizontal: 2, vertical: 2); } } @@ -172,7 +160,7 @@ class NaviItemDivider extends StatelessWidget { @override Widget build(BuildContext context) { return Row( - children: [child, const Text('/').padding(horizontal: 2)], + children: [child, const Text('/')], ); } } diff --git a/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart b/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart index 7120787037..f2aa26884b 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart +++ b/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart @@ -3,12 +3,15 @@ import 'package:app_flowy/workspace/application/doc/share_bloc.dart'; import 'package:app_flowy/workspace/domain/i_view.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/infrastructure/repos/view_repo.dart'; import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart'; import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/rounded_button.dart'; +import 'package:flowy_infra_ui/widget/rounded_input_field.dart'; import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/export.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart'; @@ -40,7 +43,7 @@ class DocStackContext extends HomeStackContext { } @override - Widget get leftBarItem => FlowyText.medium(_view.name, fontSize: 12); + Widget get leftBarItem => DocLeftBarItem(view: _view); @override Widget? get rightBarItem => DocShareButton(view: _view); @@ -65,7 +68,9 @@ class DocStackContext extends HomeStackContext { // }).toList(); List _makeNavigationItems() { - return [this]; + return [ + this, + ]; } @override @@ -74,6 +79,74 @@ class DocStackContext extends HomeStackContext { } } +class DocLeftBarItem extends StatefulWidget { + final View view; + + const DocLeftBarItem({required this.view, Key? key}) : super(key: key); + + @override + State createState() => _DocLeftBarItemState(); +} + +class _DocLeftBarItemState extends State { + final _controller = TextEditingController(); + final _focusNode = FocusNode(); + late ViewRepository repo; + + @override + void initState() { + repo = ViewRepository(view: widget.view); + _focusNode.addListener(_handleFocusChanged); + + super.initState(); + } + + @override + void dispose() { + _controller.dispose(); + _focusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + _controller.text = widget.view.name; + + final theme = context.watch(); + return IntrinsicWidth( + child: TextField( + controller: _controller, + focusNode: _focusNode, + scrollPadding: EdgeInsets.zero, + decoration: const InputDecoration( + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + isDense: true, + ), + style: TextStyle( + color: theme.shader1, + fontSize: 14, + fontWeight: FontWeight.w500, + overflow: TextOverflow.ellipsis, + ), + // cursorColor: widget.cursorColor, + // obscureText: widget.enableObscure, + ), + ); + } + + void _handleFocusChanged() { + if (_controller.text.isEmpty) { + _controller.text = widget.view.name; + return; + } + + if (_controller.text != widget.view.name) { + repo.updateView(name: _controller.text); + } + } +} + class DocShareButton extends StatelessWidget { final View view; DocShareButton({Key? key, required this.view}) : super(key: ValueKey(view.id)); diff --git a/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart b/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart index fb2ac3d1e8..0af6784ef9 100644 --- a/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart +++ b/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart @@ -21,7 +21,7 @@ class HomeTopBar extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ const FlowyNavigation(), - const Spacer(), + const HSpace(16), ChangeNotifierProvider.value( value: Provider.of(context, listen: false), child: Consumer( diff --git a/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_input.dart b/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_input.dart index 16fd01ff3e..5e72c30196 100644 --- a/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_input.dart +++ b/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_input.dart @@ -10,8 +10,7 @@ import 'package:provider/provider.dart'; import 'package:textstyle_extensions/textstyle_extensions.dart'; class FlowyFormTextInput extends StatelessWidget { - static EdgeInsets kDefaultTextInputPadding = - EdgeInsets.only(bottom: Insets.sm, top: 4); + static EdgeInsets kDefaultTextInputPadding = EdgeInsets.only(bottom: Insets.sm, top: 4); final String? label; final bool? autoFocus; @@ -61,8 +60,7 @@ class FlowyFormTextInput extends StatelessWidget { inputDecoration: InputDecoration( isDense: true, contentPadding: contentPadding ?? kDefaultTextInputPadding, - border: const ThinUnderlineBorder( - borderSide: BorderSide(width: 5, color: Colors.red)), + border: const ThinUnderlineBorder(borderSide: BorderSide(width: 5, color: Colors.red)), //focusedBorder: UnderlineInputBorder(borderSide: BorderSide(width: .5, color: Colors.red)), hintText: hintText, ), @@ -143,8 +141,7 @@ class StyledSearchTextInputState extends State { @override void initState() { - _controller = - widget.controller ?? TextEditingController(text: widget.initialValue); + _controller = widget.controller ?? TextEditingController(text: widget.initialValue); _focusNode = FocusNode( debugLabel: widget.label ?? '', onKey: (FocusNode node, RawKeyEvent evt) { @@ -160,8 +157,7 @@ class StyledSearchTextInputState extends State { canRequestFocus: true, ); // Listen for focus out events - _focusNode - .addListener(() => widget.onFocusChanged?.call(_focusNode.hasFocus)); + _focusNode.addListener(() => widget.onFocusChanged?.call(_focusNode.hasFocus)); widget.onFocusCreated?.call(_focusNode); if (widget.autoFocus ?? false) { scheduleMicrotask(() => _focusNode.requestFocus()); @@ -210,8 +206,7 @@ class StyledSearchTextInputState extends State { InputDecoration( prefixIcon: widget.prefixIcon, suffixIcon: widget.suffixIcon, - contentPadding: - widget.contentPadding ?? EdgeInsets.all(Insets.m), + contentPadding: widget.contentPadding ?? EdgeInsets.all(Insets.m), border: const OutlineInputBorder(borderSide: BorderSide.none), isDense: true, icon: widget.icon == null ? null : Icon(widget.icon), @@ -259,8 +254,7 @@ class ThinUnderlineBorder extends InputBorder { bool get isOutline => false; @override - UnderlineInputBorder copyWith( - {BorderSide? borderSide, BorderRadius? borderRadius}) { + UnderlineInputBorder copyWith({BorderSide? borderSide, BorderRadius? borderRadius}) { return UnderlineInputBorder( borderSide: borderSide ?? this.borderSide, borderRadius: borderRadius ?? this.borderRadius, @@ -280,8 +274,7 @@ class ThinUnderlineBorder extends InputBorder { @override Path getInnerPath(Rect rect, {TextDirection? textDirection}) { return Path() - ..addRect(Rect.fromLTWH(rect.left, rect.top, rect.width, - math.max(0.0, rect.height - borderSide.width))); + ..addRect(Rect.fromLTWH(rect.left, rect.top, rect.width, math.max(0.0, rect.height - borderSide.width))); } @override @@ -292,8 +285,7 @@ class ThinUnderlineBorder extends InputBorder { @override ShapeBorder? lerpFrom(ShapeBorder? a, double t) { if (a is UnderlineInputBorder) { - final newBorderRadius = - BorderRadius.lerp(a.borderRadius, borderRadius, t); + final newBorderRadius = BorderRadius.lerp(a.borderRadius, borderRadius, t); if (newBorderRadius != null) { return UnderlineInputBorder( @@ -308,8 +300,7 @@ class ThinUnderlineBorder extends InputBorder { @override ShapeBorder? lerpTo(ShapeBorder? b, double t) { if (b is UnderlineInputBorder) { - final newBorderRadius = - BorderRadius.lerp(b.borderRadius, borderRadius, t); + final newBorderRadius = BorderRadius.lerp(b.borderRadius, borderRadius, t); if (newBorderRadius != null) { return UnderlineInputBorder( borderSide: BorderSide.lerp(borderSide, b.borderSide, t), @@ -335,8 +326,7 @@ class ThinUnderlineBorder extends InputBorder { double gapPercentage = 0.0, TextDirection? textDirection, }) { - if (borderRadius.bottomLeft != Radius.zero || - borderRadius.bottomRight != Radius.zero) { + if (borderRadius.bottomLeft != Radius.zero || borderRadius.bottomRight != Radius.zero) { canvas.clipPath(getOuterPath(rect, textDirection: textDirection)); } canvas.drawLine(rect.bottomLeft, rect.bottomRight, borderSide.toPaint()); diff --git a/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart b/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart index 2ff674ae84..e6e9684854 100644 --- a/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart +++ b/app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart @@ -17,12 +17,15 @@ class RoundedInputField extends StatefulWidget { final String errorText; final TextStyle style; final ValueChanged? onChanged; + final String? initialValue; late bool enableObscure; var _text = ""; RoundedInputField({ Key? key, this.hintText, + this.errorText = "", + this.initialValue, this.icon, this.obscureText = false, this.obscureIcon, @@ -32,7 +35,6 @@ class RoundedInputField extends StatefulWidget { this.highlightBorderColor = Colors.transparent, this.cursorColor = Colors.black, this.style = const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), - this.errorText = "", }) : super(key: key) { enableObscure = obscureText; } @@ -62,6 +64,7 @@ class _RoundedInputFieldState extends State { borderRadius: Corners.s10Border, borderColor: borderColor, child: TextFormField( + initialValue: widget.initialValue, onChanged: (value) { widget._text = value; if (widget.onChanged != null) {