Skip to content

Commit

Permalink
update code
Browse files Browse the repository at this point in the history
  • Loading branch information
codekeyz committed Jan 6, 2024
1 parent 2621cc7 commit 17afdf1
Show file tree
Hide file tree
Showing 8 changed files with 426 additions and 121 deletions.
131 changes: 64 additions & 67 deletions frontend/lib/blog/blog_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,78 +34,75 @@ class BlogDetail extends StatelessWidget {

final imageHost = article.imageUrl == null ? null : Uri.tryParse(article.imageUrl!)?.host;

return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
PageHeader(
title: Text(article.title, style: const TextStyle(color: Colors.black)),
commandBar: CommandBar(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
primaryItems: [
if (isPostOwner)
CommandBarButton(
icon: const Icon(FluentIcons.edit),
label: const Text('Edit'),
onPressed: () => router.pushReplacement('/posts/${article.id}/edit'),
),
],
),
padding: 0,
return Column(
mainAxisSize: MainAxisSize.min,
children: [
PageHeader(
title: Text(article.title, style: const TextStyle(color: Colors.black)),
commandBar: CommandBar(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
primaryItems: [
if (isPostOwner)
CommandBarButton(
icon: const Icon(FluentIcons.edit),
label: const Text('Edit'),
onPressed: () => router.pushReplacement('/posts/${article.id}/edit'),
),
],
),
Divider(
style: DividerThemeData(
thickness: 0.2,
decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.grey.withOpacity(0.05)))),
),
padding: 0,
),
Divider(
style: DividerThemeData(
thickness: 0.2,
decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.grey.withOpacity(0.05)))),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200,
height: 150,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: Card(child: imageView(article.imageUrl!))),
if (imageHost != null) ...[
const SizedBox(height: 8),
Text(imageHost, style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
]
],
),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200,
height: 150,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: Card(child: imageView(article.imageUrl!))),
if (imageHost != null) ...[
const SizedBox(height: 8),
Text(imageHost, style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
]
],
),
const SizedBox(width: 24),
Expanded(
child: Container(
constraints: const BoxConstraints(minHeight: 250),
alignment: Alignment.topRight,
child: MarkdownWidget(data: article.description, shrinkWrap: true),
),
),
const SizedBox(width: 24),
Expanded(
child: Container(
constraints: const BoxConstraints(minHeight: 350),
alignment: Alignment.topRight,
child: MarkdownWidget(data: article.description, shrinkWrap: true),
),
],
),
),
],
),
),
Container(
height: 40,
decoration: BoxDecoration(
border: Border(top: BorderSide(color: Colors.grey.withOpacity(0.5))),
),
child: Row(
children: [
Text('Last updated ${timeago.format(article.updatedAt)}', style: footerStyle),
const Spacer(),
if (owner != null) Text('Posted by: ${owner.name}', style: footerStyle)
],
),
Container(
height: 40,
decoration: BoxDecoration(
border: Border(top: BorderSide(color: Colors.grey.withOpacity(0.5))),
),
child: Row(
children: [
Text('Last updated ${timeago.format(article.updatedAt)}', style: footerStyle),
const Spacer(),
if (owner != null) Text('Posted by: ${owner.name}', style: footerStyle)
],
),
)
],
),
)
],
);
},
);
Expand Down
5 changes: 4 additions & 1 deletion frontend/lib/blog/widgets/article_base_layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ class ArticleBaseLayoutState extends State<ArticleBaseLayout> {
if (_showingLoading) const SizedBox(width: double.maxFinite, child: ProgressBar()),
Container(
padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16),
child: widget.child(_detailProvider, this),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: widget.child(_detailProvider, this),
),
),
],
),
Expand Down
3 changes: 2 additions & 1 deletion frontend/lib/blog/widgets/article_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class ArticleCard extends StatelessWidget {
width: 300,
height: 250,
child: Card(
borderRadius: const BorderRadius.all(Radius.circular(5)),
borderColor: Colors.grey.withOpacity(0.3),
borderRadius: BorderRadius.zero,
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 24),
child: GestureDetector(
onTap: () => router.push('/posts/${article.id}'),
Expand Down
102 changes: 64 additions & 38 deletions frontend/lib/blog/widgets/article_form.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:frontend/blog/widgets/article_base_layout.dart';
import 'package:frontend/data/providers/article_provider.dart';
Expand All @@ -17,18 +18,17 @@ class ArticleFormView extends StatefulWidget {
}

class _ArticleFormViewState extends State<ArticleFormView> {
String? title;
String? description;
String? imageUrl;

final _titleCtrl = TextEditingController();
final _descriptionCtrl = TextEditingController();
final _imageUrlCtrl = TextEditingController();

bool hasSetDefaults = false;

int? articleId;

EditorState? editorState;

bool get isValidPost => _titleCtrl.text.trim().isNotEmpty && editorState != null && !editorState!.document.isEmpty;

@override
void initState() {
super.initState();
Expand All @@ -37,6 +37,7 @@ class _ArticleFormViewState extends State<ArticleFormView> {
articleId = int.tryParse(widget.articleId!);
if (articleId == null) router.pop();
}
if (widget.articleId == null) editorState = EditorState.blank();
}

@override
Expand All @@ -49,16 +50,35 @@ class _ArticleFormViewState extends State<ArticleFormView> {
final articleProv = context.read<ArticleProvider>();
final maybeArticle = detailProv.article;

if (articleId != null && maybeArticle == null) {
if (detailProv.isLoading) return loadingView();
if (detailProv.hasError) {
layout.handleErrors(ProviderEvent.error(errorMessage: detailProv.errorMessage!));
router.pop();
return const SizedBox.shrink();
}
}

if (maybeArticle != null && !hasSetDefaults) {
_titleCtrl.text = maybeArticle.title;
_descriptionCtrl.text = maybeArticle.description;
_imageUrlCtrl.text = maybeArticle.imageUrl ?? '';
editorState = EditorState(document: markdownToDocument(maybeArticle.description));
final imageUrl = maybeArticle.imageUrl;
if (imageUrl != null) _imageUrlCtrl.text = imageUrl;
}

createOrUpdateAction(String title, String description, String? imageUrl) async {
createOrUpdateAction() async {
if (!isValidPost) {
layout.handleErrors(const ProviderEvent.error(errorMessage: 'Post is not valid'));
return;
}

final title = _titleCtrl.text.trim();
final description = documentToMarkdown(editorState!.document);
final imageUrl = Uri.tryParse(_imageUrlCtrl.text)?.toString();

layout.setLoading(true);

if (widget.articleId != null && maybeArticle != null) {
if (maybeArticle != null) {
await articleProv.updateArticle(maybeArticle.id, title, description, imageUrl);
} else if (widget.articleId == null) {
await articleProv.addArticle(title, description, imageUrl);
Expand All @@ -74,52 +94,59 @@ class _ArticleFormViewState extends State<ArticleFormView> {
router.pushReplacement('/');
}

if (editorState == null) return loadingView();

return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.articleId == null ? "New Post" : "Edit Post",
style: typography.bodyStrong!.copyWith(color: blogColor, fontSize: 20),
maxLines: 1,
overflow: TextOverflow.ellipsis,
PageHeader(
title: Text(maybeArticle != null ? 'Update Post' : 'New Post'),
padding: 0,
),
const SizedBox(height: 24),
InfoLabel(
label: 'Blog Title',
child: TextBox(
controller: _titleCtrl,
keyboardType: TextInputType.name,
onChanged: (value) => setState(() => title = value.trim()))),
_spacing,
InfoLabel(
label: 'Description',
label: 'Title',
labelStyle: const TextStyle(fontWeight: FontWeight.w300),
child: TextBox(
controller: _descriptionCtrl,
keyboardType: TextInputType.multiline,
onChanged: (value) => setState(() => description = value),
maxLines: null,
minLines: 5,
controller: _titleCtrl,
keyboardType: TextInputType.text,
autofocus: true,
placeholder: 'Post Title',
style: typography.bodyLarge!.copyWith(color: blogColor),
),
),
const SizedBox(height: 32),
InfoLabel(label: 'Write your post'),
const SizedBox(height: 8),
Container(
constraints: const BoxConstraints(maxHeight: 150),
width: double.maxFinite,
child: Card(
borderColor: blogColor.withOpacity(0.1),
borderRadius: BorderRadius.zero,
child: AppFlowyEditor(
shrinkWrap: true,
editorStyle: EditorStyle.desktop(
padding: EdgeInsets.zero, selectionColor: Colors.grey.withOpacity(0.5), cursorColor: blogColor),
editorState: editorState!,
),
),
),
_spacing,
InfoLabel(
label: 'Image Url (Optional)',
child: TextBox(
controller: _imageUrlCtrl,
keyboardType: TextInputType.name,
onChanged: (value) => setState(() => imageUrl = value.trim()))),
label: 'Image Url',
labelStyle: const TextStyle(fontWeight: FontWeight.w300),
child: TextBox(controller: _imageUrlCtrl, keyboardType: TextInputType.url),
),
const SizedBox(height: 28),
Row(
children: [
const Expanded(child: SizedBox.shrink()),
FilledButton(
style: ButtonStyle(
shape: ButtonState.all(const RoundedRectangleBorder(borderRadius: BorderRadius.zero)),
),
onPressed: [title, description].contains(null)
? null
: () => createOrUpdateAction(title!, description!, imageUrl),
shape: ButtonState.all(const RoundedRectangleBorder(borderRadius: BorderRadius.zero))),
onPressed: createOrUpdateAction,
child: Text(widget.articleId == null ? 'Add Post' : 'Update Post'),
)
],
Expand All @@ -134,7 +161,6 @@ class _ArticleFormViewState extends State<ArticleFormView> {
void dispose() {
super.dispose();
_titleCtrl.dispose();
_descriptionCtrl.dispose();
_imageUrlCtrl.dispose();
}
}
Loading

0 comments on commit 17afdf1

Please sign in to comment.