[flutter]: modify view's name in topbar

This commit is contained in:
appflowy 2021-11-10 18:26:38 +08:00
parent ec920e430c
commit 4f41c8d3e5
5 changed files with 114 additions and 60 deletions

View File

@ -61,14 +61,22 @@ class FlowyNavigation extends StatelessWidget {
);
},
update: (_, notifier, controller) => controller!..update(notifier),
child: Row(children: [
Selector<NavigationNotifier, PublishNotifier<bool>>(
selector: (context, notifier) => notifier.collapasedNotifier,
builder: (ctx, collapsedNotifier, child) => _renderCollapse(ctx, collapsedNotifier)),
Selector<NavigationNotifier, List<NavigationItem>>(
child: Expanded(
child: Row(children: [
Selector<NavigationNotifier, PublishNotifier<bool>>(
selector: (context, notifier) => notifier.collapasedNotifier,
builder: (ctx, collapsedNotifier, child) => _renderCollapse(ctx, collapsedNotifier)),
Selector<NavigationNotifier, List<NavigationItem>>(
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<Widget> 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('/')],
);
}
}

View File

@ -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<String, ShareActionWrapper> {
}
@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<String, ShareActionWrapper> {
// }).toList();
List<NavigationItem> _makeNavigationItems() {
return [this];
return [
this,
];
}
@override
@ -74,6 +79,74 @@ class DocStackContext extends HomeStackContext<String, ShareActionWrapper> {
}
}
class DocLeftBarItem extends StatefulWidget {
final View view;
const DocLeftBarItem({required this.view, Key? key}) : super(key: key);
@override
State<DocLeftBarItem> createState() => _DocLeftBarItemState();
}
class _DocLeftBarItemState extends State<DocLeftBarItem> {
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<AppTheme>();
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));

View File

@ -21,7 +21,7 @@ class HomeTopBar extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const FlowyNavigation(),
const Spacer(),
const HSpace(16),
ChangeNotifierProvider.value(
value: Provider.of<HomeStackNotifier>(context, listen: false),
child: Consumer(

View File

@ -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<StyledSearchTextInput> {
@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<StyledSearchTextInput> {
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<StyledSearchTextInput> {
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());

View File

@ -17,12 +17,15 @@ class RoundedInputField extends StatefulWidget {
final String errorText;
final TextStyle style;
final ValueChanged<String>? 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<RoundedInputField> {
borderRadius: Corners.s10Border,
borderColor: borderColor,
child: TextFormField(
initialValue: widget.initialValue,
onChanged: (value) {
widget._text = value;
if (widget.onChanged != null) {