toolbar is now only present when textfield is focused
also added it to manage account page
This commit is contained in:
parent
55daacf221
commit
cc8441dabc
|
@ -31,6 +31,7 @@ class CreatePostPage extends HookWidget {
|
|||
);
|
||||
|
||||
final titleFocusNode = useFocusNode();
|
||||
final editorFocusNode = useFocusNode();
|
||||
|
||||
handleSubmit(Jwt token) async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
|
@ -63,6 +64,7 @@ class CreatePostPage extends HookWidget {
|
|||
labelText: L10n.of(context).body,
|
||||
instanceHost: store.instanceHost,
|
||||
fancy: store.showFancy,
|
||||
focusNode: editorFocusNode,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -146,6 +148,7 @@ class CreatePostPage extends HookWidget {
|
|||
children: [
|
||||
const Spacer(),
|
||||
EditorToolbar(
|
||||
editorFocusNode: editorFocusNode,
|
||||
controller: bodyController,
|
||||
instanceHost: context.read<CreatePostStore>().instanceHost,
|
||||
),
|
||||
|
|
|
@ -234,150 +234,169 @@ class _ManageAccount extends HookWidget {
|
|||
}
|
||||
}
|
||||
|
||||
return ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
return Stack(
|
||||
children: [
|
||||
_ImagePicker(
|
||||
user: user,
|
||||
name: L10n.of(context).avatar,
|
||||
initialUrl: avatar.value,
|
||||
onChange: (value) => avatar.value = value,
|
||||
informAcceptedRef: informAcceptedAvatarRef,
|
||||
ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
children: [
|
||||
_ImagePicker(
|
||||
user: user,
|
||||
name: L10n.of(context).avatar,
|
||||
initialUrl: avatar.value,
|
||||
onChange: (value) => avatar.value = value,
|
||||
informAcceptedRef: informAcceptedAvatarRef,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_ImagePicker(
|
||||
user: user,
|
||||
name: L10n.of(context).banner,
|
||||
initialUrl: banner.value,
|
||||
onChange: (value) => banner.value = value,
|
||||
informAcceptedRef: informAcceptedBannerRef,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).display_name,
|
||||
style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
controller: displayNameController,
|
||||
onSubmitted: (_) => bioFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).bio, style: theme.textTheme.headline6),
|
||||
Editor(
|
||||
controller: bioController,
|
||||
focusNode: bioFocusNode,
|
||||
onSubmitted: (_) => emailFocusNode.requestFocus(),
|
||||
instanceHost: user.instanceHost,
|
||||
maxLines: 10,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).email, style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
focusNode: emailFocusNode,
|
||||
controller: emailController,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
onSubmitted: (_) => matrixUserFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).matrix_user,
|
||||
style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
focusNode: matrixUserFocusNode,
|
||||
controller: matrixUserController,
|
||||
onSubmitted: (_) => newPasswordFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.new_password, style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: newPasswordFocusNode,
|
||||
// controller: newPasswordController,
|
||||
// autofillHints: const [AutofillHints.newPassword],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// onSubmitted: (_) => verifyPasswordFocusNode.requestFocus(),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.verify_password,
|
||||
// style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: verifyPasswordFocusNode,
|
||||
// controller: newPasswordVerifyController,
|
||||
// autofillHints: const [AutofillHints.newPassword],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// onSubmitted: (_) => oldPasswordFocusNode.requestFocus(),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.old_password, style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: oldPasswordFocusNode,
|
||||
// controller: oldPasswordController,
|
||||
// autofillHints: const [AutofillHints.password],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showNsfw.value,
|
||||
onChanged: (checked) {
|
||||
showNsfw.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_nsfw),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: botAccount.value,
|
||||
onChanged: (checked) {
|
||||
botAccount.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).bot_account),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showBotAccounts.value,
|
||||
onChanged: (checked) {
|
||||
showBotAccounts.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_bot_accounts),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showReadPosts.value,
|
||||
onChanged: (checked) {
|
||||
showReadPosts.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_read_posts),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: sendNotificationsToEmail.value,
|
||||
onChanged: (checked) {
|
||||
sendNotificationsToEmail.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).send_notifications_to_email),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: saveDelayedLoading.loading ? null : handleSubmit,
|
||||
child: saveDelayedLoading.loading
|
||||
? const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
)
|
||||
: Text(L10n.of(context).save),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: deleteAccountDialog,
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.red,
|
||||
),
|
||||
child: Text(L10n.of(context).delete_account.toUpperCase()),
|
||||
),
|
||||
const BottomSafe(),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_ImagePicker(
|
||||
user: user,
|
||||
name: L10n.of(context).banner,
|
||||
initialUrl: banner.value,
|
||||
onChange: (value) => banner.value = value,
|
||||
informAcceptedRef: informAcceptedBannerRef,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).display_name, style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
controller: displayNameController,
|
||||
onSubmitted: (_) => bioFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).bio, style: theme.textTheme.headline6),
|
||||
Editor(
|
||||
controller: bioController,
|
||||
focusNode: bioFocusNode,
|
||||
onSubmitted: (_) => emailFocusNode.requestFocus(),
|
||||
instanceHost: user.instanceHost,
|
||||
maxLines: 10,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).email, style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
focusNode: emailFocusNode,
|
||||
controller: emailController,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
onSubmitted: (_) => matrixUserFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(L10n.of(context).matrix_user, style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
focusNode: matrixUserFocusNode,
|
||||
controller: matrixUserController,
|
||||
onSubmitted: (_) => newPasswordFocusNode.requestFocus(),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.new_password, style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: newPasswordFocusNode,
|
||||
// controller: newPasswordController,
|
||||
// autofillHints: const [AutofillHints.newPassword],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// onSubmitted: (_) => verifyPasswordFocusNode.requestFocus(),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.verify_password,
|
||||
// style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: verifyPasswordFocusNode,
|
||||
// controller: newPasswordVerifyController,
|
||||
// autofillHints: const [AutofillHints.newPassword],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// onSubmitted: (_) => oldPasswordFocusNode.requestFocus(),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// Text(L10n.of(context)!.old_password, style: theme.textTheme.headline6),
|
||||
// TextField(
|
||||
// focusNode: oldPasswordFocusNode,
|
||||
// controller: oldPasswordController,
|
||||
// autofillHints: const [AutofillHints.password],
|
||||
// keyboardType: TextInputType.visiblePassword,
|
||||
// obscureText: true,
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showNsfw.value,
|
||||
onChanged: (checked) {
|
||||
showNsfw.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_nsfw),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: botAccount.value,
|
||||
onChanged: (checked) {
|
||||
botAccount.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).bot_account),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showBotAccounts.value,
|
||||
onChanged: (checked) {
|
||||
showBotAccounts.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_bot_accounts),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: showReadPosts.value,
|
||||
onChanged: (checked) {
|
||||
showReadPosts.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).show_read_posts),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
value: sendNotificationsToEmail.value,
|
||||
onChanged: (checked) {
|
||||
sendNotificationsToEmail.value = checked;
|
||||
},
|
||||
title: Text(L10n.of(context).send_notifications_to_email),
|
||||
dense: true,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: saveDelayedLoading.loading ? null : handleSubmit,
|
||||
child: saveDelayedLoading.loading
|
||||
? const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
)
|
||||
: Text(L10n.of(context).save),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: deleteAccountDialog,
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.red,
|
||||
SafeArea(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Spacer(),
|
||||
EditorToolbar(
|
||||
editorFocusNode: bioFocusNode,
|
||||
controller: bioController,
|
||||
instanceHost: user.instanceHost,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(L10n.of(context).delete_account.toUpperCase()),
|
||||
),
|
||||
const BottomSafe(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -52,18 +52,22 @@ class Editor extends HookWidget {
|
|||
);
|
||||
}
|
||||
|
||||
return TextField(
|
||||
controller: actualController,
|
||||
focusNode: focusNode,
|
||||
autofocus: autofocus,
|
||||
keyboardType: TextInputType.multiline,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
onChanged: onChanged,
|
||||
onSubmitted: onSubmitted,
|
||||
maxLines: maxLines,
|
||||
minLines: minLines,
|
||||
decoration: InputDecoration(labelText: labelText),
|
||||
inputFormatters: [MarkdownFormatter()],
|
||||
return FocusScope(
|
||||
child: Focus(
|
||||
focusNode: focusNode,
|
||||
child: TextField(
|
||||
controller: actualController,
|
||||
autofocus: autofocus,
|
||||
keyboardType: TextInputType.multiline,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
onChanged: onChanged,
|
||||
onSubmitted: onSubmitted,
|
||||
maxLines: maxLines,
|
||||
minLines: minLines,
|
||||
decoration: InputDecoration(labelText: labelText),
|
||||
inputFormatters: [MarkdownFormatter()],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,37 +39,50 @@ enum HeaderLevel {
|
|||
final int value;
|
||||
}
|
||||
|
||||
class EditorToolbar extends StatelessWidget {
|
||||
class EditorToolbar extends HookWidget {
|
||||
final TextEditingController controller;
|
||||
final String instanceHost;
|
||||
final EditorToolbarStore store;
|
||||
final FocusNode editorFocusNode;
|
||||
static const _height = 50.0;
|
||||
|
||||
EditorToolbar({
|
||||
required this.controller,
|
||||
required this.instanceHost,
|
||||
required this.editorFocusNode,
|
||||
}) : store = EditorToolbarStore(instanceHost);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final visible = useState(editorFocusNode.hasFocus);
|
||||
useEffect(() {
|
||||
editorFocusNode.addListener(() {
|
||||
visible.value = editorFocusNode.hasFocus;
|
||||
});
|
||||
|
||||
return;
|
||||
}, [editorFocusNode]);
|
||||
|
||||
return MobxProvider(
|
||||
create: (context) => store,
|
||||
child: AsyncStoreListener(
|
||||
asyncStore: store.imageUploadState,
|
||||
child: Container(
|
||||
height: _height,
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).cardColor,
|
||||
child: Material(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: _ToolbarBody(
|
||||
controller: controller,
|
||||
instanceHost: instanceHost,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: visible.value
|
||||
? Container(
|
||||
height: _height,
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).cardColor,
|
||||
child: Material(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: _ToolbarBody(
|
||||
controller: controller,
|
||||
instanceHost: instanceHost,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ class WriteComment extends HookWidget {
|
|||
final showFancy = useState(false);
|
||||
final delayed = useDelayedLoading();
|
||||
final loggedInAction = useLoggedInAction(post.instanceHost);
|
||||
final editorFocusNode = useFocusNode();
|
||||
|
||||
final preview = () {
|
||||
final body = () {
|
||||
|
@ -117,6 +118,7 @@ class WriteComment extends HookWidget {
|
|||
controller: controller,
|
||||
autofocus: true,
|
||||
fancy: showFancy.value,
|
||||
focusNode: editorFocusNode,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
|
@ -141,6 +143,7 @@ class WriteComment extends HookWidget {
|
|||
children: [
|
||||
const Spacer(),
|
||||
EditorToolbar(
|
||||
editorFocusNode: editorFocusNode,
|
||||
controller: controller,
|
||||
instanceHost: post.instanceHost,
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue