import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:wc_form_validators/wc_form_validators.dart'; import '../../hooks/logged_in_action.dart'; import '../../hooks/stores.dart'; import '../../l10n/l10n.dart'; import '../../stores/accounts_store.dart'; import '../../util/async_store_listener.dart'; import '../../util/extensions/spaced.dart'; import '../../util/mobx_provider.dart'; import '../../util/observer_consumers.dart'; import '../../widgets/editor/editor.dart'; import '../../widgets/markdown_mode_icon.dart'; import 'create_post_community_picker.dart'; import 'create_post_instance_picker.dart'; import 'create_post_store.dart'; import 'create_post_url_field.dart'; /// Modal for creating a post to some community in some instance /// Pops the navigator stack with a [PostView] class CreatePostPage extends HookWidget { const CreatePostPage(); @override Widget build(BuildContext context) { final formKey = useMemoized(GlobalKey.new); final loggedInAction = useLoggedInAction( useStore((CreatePostStore store) => store.instanceHost), ); final titleFocusNode = useFocusNode(); handleSubmit(Jwt token) async { if (formKey.currentState!.validate()) { await context.read().submit(token); } } final title = ObserverBuilder( builder: (context, store) => TextFormField( initialValue: store.title, focusNode: titleFocusNode, keyboardType: TextInputType.text, textCapitalization: TextCapitalization.sentences, textInputAction: TextInputAction.next, validator: Validators.required(L10n.of(context).required_field), onChanged: (title) => store.title = title, minLines: 1, maxLines: 2, decoration: InputDecoration(labelText: L10n.of(context).title), ), ); final bodyController = useTextEditingController(text: context.read().body); final body = ObserverBuilder( builder: (context, store) => Editor( controller: bodyController, onChanged: (body) => store.body = body, labelText: L10n.of(context).body, instanceHost: store.instanceHost, fancy: store.showFancy, ), ); return AsyncStoreListener( asyncStore: context.read().submitState, onSuccess: (context, data) { Navigator.of(context).pop(data); }, child: Scaffold( appBar: AppBar( actions: [ ObserverBuilder( builder: (context, store) => IconButton( icon: markdownModeIcon(fancy: store.showFancy), onPressed: () => store.showFancy = !store.showFancy, ), ), ], ), body: Stack( children: [ SafeArea( child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(5), child: Form( key: formKey, child: Column( children: [ if (!context.read().isEdit) ...const [ CreatePostInstancePicker(), CreatePostCommunityPicker(), ], CreatePostUrlField(titleFocusNode), title, body, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ObserverBuilder( builder: (context, store) => GestureDetector( onTap: () => store.nsfw = !store.nsfw, child: Row( children: [ Checkbox( value: store.nsfw, onChanged: (val) { if (val != null) store.nsfw = val; }, ), Text(L10n.of(context).nsfw) ], ), ), ), ObserverBuilder( builder: (context, store) => TextButton( onPressed: store.submitState.isLoading ? () {} : loggedInAction(handleSubmit), child: store.submitState.isLoading ? const CircularProgressIndicator.adaptive() : Text( store.isEdit ? L10n.of(context).edit : L10n.of(context).post, ), ), ) ], ), EditorToolbar.safeArea, ].spaced(6), ), ), ), ), SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Spacer(), EditorToolbar( controller: bodyController, instanceHost: context.read().instanceHost, ), ], ), ), ], ), ), ); } static Route route() => MaterialPageRoute( builder: (context) => MobxProvider( create: (context) => CreatePostStore( instanceHost: context.read().loggedInInstances.first, ), child: const CreatePostPage(), ), fullscreenDialog: true, ); static Route toCommunityRoute(CommunityView community) => MaterialPageRoute( builder: (context) => MobxProvider( create: (context) => CreatePostStore( instanceHost: community.instanceHost, selectedCommunity: community, ), child: const CreatePostPage(), ), fullscreenDialog: true, ); static Route editRoute(Post post) => MaterialPageRoute( builder: (context) => MobxProvider( create: (context) => CreatePostStore( instanceHost: post.instanceHost, postToEdit: post, ), child: const CreatePostPage(), ), fullscreenDialog: true, ); }