Add editing post

This commit is contained in:
shilangyu 2021-04-17 23:59:33 +02:00
parent 4f6d03c5cb
commit 2c91d3aa5f
3 changed files with 91 additions and 30 deletions

View File

@ -46,20 +46,35 @@ class CreatePostFab extends HookWidget {
class CreatePostPage extends HookWidget { class CreatePostPage extends HookWidget {
final CommunityView? community; final CommunityView? community;
const CreatePostPage() : community = null; final bool _isEdit;
const CreatePostPage.toCommunity(CommunityView this.community); final Post? post;
const CreatePostPage()
: community = null,
_isEdit = false,
post = null;
const CreatePostPage.toCommunity(CommunityView this.community)
: _isEdit = false,
post = null;
const CreatePostPage.edit(this.post)
: _isEdit = true,
community = null;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final urlController = useTextEditingController(); final urlController =
final titleController = useTextEditingController(); useTextEditingController(text: _isEdit ? post?.url : null);
final bodyController = useTextEditingController(); final titleController =
useTextEditingController(text: _isEdit ? post?.name : null);
final bodyController =
useTextEditingController(text: _isEdit ? post?.body : null);
final accStore = useAccountsStore(); final accStore = useAccountsStore();
final selectedInstance = final selectedInstance = useState(_isEdit
useState(community?.instanceHost ?? accStore.loggedInInstances.first); ? post!.instanceHost
: community?.instanceHost ?? accStore.loggedInInstances.first);
final selectedCommunity = useState(community); final selectedCommunity = useState(community);
final showFancy = useState(false); final showFancy = useState(false);
final nsfw = useState(false); final nsfw = useState(_isEdit && post!.nsfw);
final delayed = useDelayedLoading(); final delayed = useDelayedLoading();
final imagePicker = useImagePicker(); final imagePicker = useImagePicker();
final imageUploadLoading = useState(false); final imageUploadLoading = useState(false);
@ -100,7 +115,6 @@ class CreatePostPage extends HookWidget {
urlController.text = urlController.text =
pathToPictrs(selectedInstance.value, upload.files[0].file); pathToPictrs(selectedInstance.value, upload.files[0].file);
} }
print(urlController.text);
// ignore: avoid_catches_without_on_clauses // ignore: avoid_catches_without_on_clauses
} catch (e) { } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -120,7 +134,7 @@ class CreatePostPage extends HookWidget {
final instanceDropdown = RadioPicker<String>( final instanceDropdown = RadioPicker<String>(
values: accStore.loggedInInstances.toList(), values: accStore.loggedInInstances.toList(),
groupValue: selectedInstance.value, groupValue: selectedInstance.value,
onChanged: (value) => selectedInstance.value = value, onChanged: _isEdit ? null : (value) => selectedInstance.value = value,
buttonBuilder: (context, displayValue, onPressed) => TextButton( buttonBuilder: (context, displayValue, onPressed) => TextButton(
onPressed: onPressed, onPressed: onPressed,
child: Row( child: Row(
@ -159,7 +173,8 @@ class CreatePostPage extends HookWidget {
} }
handleSubmit(Jwt token) async { handleSubmit(Jwt token) async {
if (selectedCommunity.value == null || titleController.text.isEmpty) { if ((!_isEdit && selectedCommunity.value == null) ||
titleController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Choosing a community and a title is required'), content: Text('Choosing a community and a title is required'),
)); ));
@ -170,14 +185,27 @@ class CreatePostPage extends HookWidget {
delayed.start(); delayed.start();
try { try {
final res = await api.run(CreatePost( final res = await () {
url: urlController.text.isEmpty ? null : urlController.text, if (_isEdit) {
body: bodyController.text.isEmpty ? null : bodyController.text, return api.run(EditPost(
nsfw: nsfw.value, url: urlController.text.isEmpty ? null : urlController.text,
name: titleController.text, body: bodyController.text.isEmpty ? null : bodyController.text,
communityId: selectedCommunity.value!.community.id, nsfw: nsfw.value,
auth: token.raw, name: titleController.text,
)); postId: post!.id,
auth: token.raw,
));
} else {
return api.run(CreatePost(
url: urlController.text.isEmpty ? null : urlController.text,
body: bodyController.text.isEmpty ? null : bodyController.text,
nsfw: nsfw.value,
name: titleController.text,
communityId: selectedCommunity.value!.community.id,
auth: token.raw,
));
}
}();
unawaited(goToReplace(context, (_) => FullPostPage.fromPostView(res))); unawaited(goToReplace(context, (_) => FullPostPage.fromPostView(res)));
return; return;
// ignore: avoid_catches_without_on_clauses // ignore: avoid_catches_without_on_clauses
@ -191,27 +219,34 @@ class CreatePostPage extends HookWidget {
// TODO: use lazy autocomplete // TODO: use lazy autocomplete
final communitiesDropdown = InputDecorator( final communitiesDropdown = InputDecorator(
decoration: const InputDecoration( decoration: const InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 1, horizontal: 20), contentPadding: EdgeInsets.symmetric(vertical: 1, horizontal: 20),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)))), borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<int>( child: DropdownButton<int>(
value: selectedCommunity.value?.community.id, value: selectedCommunity.value?.community.id,
hint: Text(L10n.of(context)!.community), hint: Text(L10n.of(context)!.community),
onChanged: (communityId) => selectedCommunity.value = onChanged: _isEdit
allCommunitiesSnap.data ? null
?.firstWhere((e) => e.community.id == communityId), : (communityId) {
selectedCommunity.value = allCommunitiesSnap.data
?.firstWhere((e) => e.community.id == communityId);
},
items: communitiesList(), items: communitiesList(),
), ),
), ),
); );
final enabledUrlField = pictrsDeleteToken.value == null;
final url = Row(children: [ final url = Row(children: [
Expanded( Expanded(
child: TextField( child: TextField(
enabled: pictrsDeleteToken.value == null, enabled: enabledUrlField,
controller: urlController, controller: urlController,
autofillHints: const [AutofillHints.url], autofillHints: enabledUrlField ? const [AutofillHints.url] : null,
keyboardType: TextInputType.url, keyboardType: TextInputType.url,
onSubmitted: (_) => titleFocusNode.requestFocus(), onSubmitted: (_) => titleFocusNode.requestFocus(),
decoration: InputDecoration( decoration: InputDecoration(
@ -311,7 +346,9 @@ class CreatePostPage extends HookWidget {
delayed.pending ? () {} : loggedInAction(handleSubmit), delayed.pending ? () {} : loggedInAction(handleSubmit),
child: delayed.loading child: delayed.loading
? const CircularProgressIndicator() ? const CircularProgressIndicator()
: Text(L10n.of(context)!.post), : Text(_isEdit
? L10n.of(context)!.edit
: L10n.of(context)!.post),
) )
], ],
), ),

View File

@ -5,12 +5,15 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:lemmy_api_client/v3.dart'; import 'package:lemmy_api_client/v3.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart' as ul; import 'package:url_launcher/url_launcher.dart' as ul;
import '../hooks/delayed_loading.dart'; import '../hooks/delayed_loading.dart';
import '../hooks/logged_in_action.dart'; import '../hooks/logged_in_action.dart';
import '../l10n/l10n.dart'; import '../l10n/l10n.dart';
import '../pages/create_post.dart';
import '../pages/full_post.dart'; import '../pages/full_post.dart';
import '../stores/accounts_store.dart';
import '../url_launcher.dart'; import '../url_launcher.dart';
import '../util/cleanup_url.dart'; import '../util/cleanup_url.dart';
import '../util/extensions/api.dart'; import '../util/extensions/api.dart';
@ -61,6 +64,12 @@ class PostWidget extends HookWidget {
// == ACTIONS == // == ACTIONS ==
static void showMoreMenu(BuildContext context, PostView post) { static void showMoreMenu(BuildContext context, PostView post) {
final isMine = context
.read<AccountsStore>()
.defaultUserDataFor(post.instanceHost)
?.userId ==
post.creator.id;
showBottomModal( showBottomModal(
context: context, context: context,
builder: (context) => Column( builder: (context) => Column(
@ -84,6 +93,17 @@ class PostWidget extends HookWidget {
}); });
}, },
), ),
if (isMine)
ListTile(
leading: const Icon(Icons.edit),
title: const Text('Edit'),
onTap: () {
showCupertinoModalPopup(
context: context,
builder: (_) => CreatePostPage.edit(post.post),
);
},
),
], ],
), ),
); );

View File

@ -14,7 +14,7 @@ class RadioPicker<T> extends StatelessWidget {
/// custom button builder. When null, an OutlinedButton is used /// custom button builder. When null, an OutlinedButton is used
final Widget Function( final Widget Function(
BuildContext context, String displayValue, VoidCallback onPressed)? BuildContext context, String displayValue, VoidCallback? onPressed)?
buttonBuilder; buttonBuilder;
final Widget? trailing; final Widget? trailing;
@ -71,6 +71,10 @@ class RadioPicker<T> extends StatelessWidget {
} }
} }
return buttonBuilder(context, mapValueToString(groupValue), onPressed); return buttonBuilder(
context,
mapValueToString(groupValue),
onChanged == null ? null : onPressed,
);
} }
} }