💄 Bug fixes and optimization
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
				
			|||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
import 'package:solian/screens/account.dart';
 | 
					import 'package:solian/screens/account.dart';
 | 
				
			||||||
import 'package:solian/screens/explore.dart';
 | 
					import 'package:solian/screens/explore.dart';
 | 
				
			||||||
 | 
					import 'package:solian/screens/posts/new_moment.dart';
 | 
				
			||||||
import 'package:solian/screens/posts/screen.dart';
 | 
					import 'package:solian/screens/posts/screen.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final router = GoRouter(
 | 
					final router = GoRouter(
 | 
				
			||||||
@@ -15,6 +16,11 @@ final router = GoRouter(
 | 
				
			|||||||
      name: 'account',
 | 
					      name: 'account',
 | 
				
			||||||
      builder: (context, state) => const AccountScreen(),
 | 
					      builder: (context, state) => const AccountScreen(),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
 | 
					    GoRoute(
 | 
				
			||||||
 | 
					      path: '/posts/moments/new',
 | 
				
			||||||
 | 
					      name: 'posts.moments.new',
 | 
				
			||||||
 | 
					      builder: (context, state) => const NewMomentScreen(),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
    GoRoute(
 | 
					    GoRoute(
 | 
				
			||||||
      path: '/posts/:dataset/:alias',
 | 
					      path: '/posts/:dataset/:alias',
 | 
				
			||||||
      name: 'posts.screen',
 | 
					      name: 'posts.screen',
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								lib/screens/posts/new_moment.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/screens/posts/new_moment.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NewMomentScreen extends StatelessWidget {
 | 
				
			||||||
 | 
					  const NewMomentScreen({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Center(
 | 
				
			||||||
 | 
					      child: Container(
 | 
				
			||||||
 | 
					        constraints: const BoxConstraints(maxWidth: 640),
 | 
				
			||||||
 | 
					        child: Column(
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -89,7 +89,7 @@ class CommentListHeader extends StatelessWidget {
 | 
				
			|||||||
    final auth = context.read<AuthProvider>();
 | 
					    final auth = context.read<AuthProvider>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Container(
 | 
					    return Container(
 | 
				
			||||||
      padding: const EdgeInsets.only(left: 10, right: 10, top: 20),
 | 
					      padding: const EdgeInsets.only(left: 8, right: 8, top: 20),
 | 
				
			||||||
      child: Row(
 | 
					      child: Row(
 | 
				
			||||||
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
					        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
import 'package:flutter_markdown/flutter_markdown.dart';
 | 
					import 'package:flutter_markdown/flutter_markdown.dart';
 | 
				
			||||||
import 'package:solian/models/post.dart';
 | 
					import 'package:solian/models/post.dart';
 | 
				
			||||||
import 'package:markdown/markdown.dart' as markdown;
 | 
					import 'package:markdown/markdown.dart' as markdown;
 | 
				
			||||||
 | 
					import 'package:solian/utils/service_url.dart';
 | 
				
			||||||
import 'package:url_launcher/url_launcher_string.dart';
 | 
					import 'package:url_launcher/url_launcher_string.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ArticleContent extends StatelessWidget {
 | 
					class ArticleContent extends StatelessWidget {
 | 
				
			||||||
@@ -12,31 +13,30 @@ class ArticleContent extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return brief
 | 
					    final headingPart = Column(
 | 
				
			||||||
        ? Padding(
 | 
					      crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
          padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
					      children: [
 | 
				
			||||||
          child: Column(
 | 
					        Text(
 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					          item.title,
 | 
				
			||||||
              children: [
 | 
					          style: Theme.of(context).textTheme.titleMedium,
 | 
				
			||||||
                Text(
 | 
					        ),
 | 
				
			||||||
                  item.title,
 | 
					        Text(
 | 
				
			||||||
                  style: Theme.of(context).textTheme.titleMedium,
 | 
					          item.description,
 | 
				
			||||||
                ),
 | 
					          style: Theme.of(context).textTheme.bodyMedium,
 | 
				
			||||||
                Text(
 | 
					 | 
				
			||||||
                  item.description,
 | 
					 | 
				
			||||||
                  style: Theme.of(context).textTheme.bodyMedium,
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return brief
 | 
				
			||||||
 | 
					        ? headingPart
 | 
				
			||||||
        : Column(
 | 
					        : Column(
 | 
				
			||||||
            children: [
 | 
					            children: [
 | 
				
			||||||
              ListTile(
 | 
					              Padding(
 | 
				
			||||||
                title: Text(item.title),
 | 
					                padding: const EdgeInsets.only(bottom: 12),
 | 
				
			||||||
                subtitle: Text(item.description),
 | 
					                child: headingPart,
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              const Divider(color: Color(0xffefefef)),
 | 
					 | 
				
			||||||
              Markdown(
 | 
					              Markdown(
 | 
				
			||||||
 | 
					                padding: const EdgeInsets.all(0),
 | 
				
			||||||
                selectable: !brief,
 | 
					                selectable: !brief,
 | 
				
			||||||
                data: item.content,
 | 
					                data: item.content,
 | 
				
			||||||
                shrinkWrap: true,
 | 
					                shrinkWrap: true,
 | 
				
			||||||
@@ -52,6 +52,15 @@ class ArticleContent extends StatelessWidget {
 | 
				
			|||||||
                    mode: LaunchMode.externalApplication,
 | 
					                    mode: LaunchMode.externalApplication,
 | 
				
			||||||
                  );
 | 
					                  );
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                imageBuilder: (url, _, __) {
 | 
				
			||||||
 | 
					                  if (url.toString().startsWith("/api/attachments")) {
 | 
				
			||||||
 | 
					                    return Image.network(
 | 
				
			||||||
 | 
					                        getRequestUri('interactive', url.toString())
 | 
				
			||||||
 | 
					                            .toString());
 | 
				
			||||||
 | 
					                  } else {
 | 
				
			||||||
 | 
					                    return Image.network(url.toString());
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/cupertino.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:chewie/chewie.dart';
 | 
					import 'package:chewie/chewie.dart';
 | 
				
			||||||
import 'package:solian/models/post.dart';
 | 
					import 'package:solian/models/post.dart';
 | 
				
			||||||
@@ -8,8 +9,9 @@ import 'package:video_player/video_player.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class AttachmentItem extends StatefulWidget {
 | 
					class AttachmentItem extends StatefulWidget {
 | 
				
			||||||
  final Attachment item;
 | 
					  final Attachment item;
 | 
				
			||||||
 | 
					  final String? badge;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const AttachmentItem({super.key, required this.item});
 | 
					  const AttachmentItem({super.key, required this.item, this.badge});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  State<AttachmentItem> createState() => _AttachmentItemState();
 | 
					  State<AttachmentItem> createState() => _AttachmentItemState();
 | 
				
			||||||
@@ -36,9 +38,22 @@ class _AttachmentItemState extends State<AttachmentItem> {
 | 
				
			|||||||
          borderRadius: const BorderRadius.all(borderRadius),
 | 
					          borderRadius: const BorderRadius.all(borderRadius),
 | 
				
			||||||
          child: Hero(
 | 
					          child: Hero(
 | 
				
			||||||
            tag: getTag(),
 | 
					            tag: getTag(),
 | 
				
			||||||
            child: Image.network(
 | 
					            child: Stack(
 | 
				
			||||||
              getFileUri().toString(),
 | 
					              children: [
 | 
				
			||||||
              fit: BoxFit.cover,
 | 
					                Image.network(
 | 
				
			||||||
 | 
					                  getFileUri().toString(),
 | 
				
			||||||
 | 
					                  width: double.infinity,
 | 
				
			||||||
 | 
					                  height: double.infinity,
 | 
				
			||||||
 | 
					                  fit: BoxFit.cover,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                widget.badge == null
 | 
				
			||||||
 | 
					                    ? Container()
 | 
				
			||||||
 | 
					                    : Positioned(
 | 
				
			||||||
 | 
					                        right: 12,
 | 
				
			||||||
 | 
					                        bottom: 8,
 | 
				
			||||||
 | 
					                        child: Chip(label: Text(widget.badge!)),
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
@@ -110,18 +125,21 @@ class AttachmentList extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    var renderProgress = 0;
 | 
				
			||||||
    return FlutterCarousel(
 | 
					    return FlutterCarousel(
 | 
				
			||||||
      options: CarouselOptions(
 | 
					      options: CarouselOptions(
 | 
				
			||||||
        aspectRatio: 16 / 9,
 | 
					        aspectRatio: 16 / 9,
 | 
				
			||||||
        showIndicator: true,
 | 
					        viewportFraction: 1,
 | 
				
			||||||
        slideIndicator: const CircularSlideIndicator(),
 | 
					 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      items: items.map((item) {
 | 
					      items: items.map((item) {
 | 
				
			||||||
 | 
					        renderProgress++;
 | 
				
			||||||
 | 
					        final badge = '$renderProgress/${items.length}';
 | 
				
			||||||
        return Builder(
 | 
					        return Builder(
 | 
				
			||||||
          builder: (BuildContext context) {
 | 
					          builder: (BuildContext context) {
 | 
				
			||||||
            return Padding(
 | 
					            return Padding(
 | 
				
			||||||
              padding: const EdgeInsets.symmetric(horizontal: 4),
 | 
					              padding: const EdgeInsets.symmetric(horizontal: 4),
 | 
				
			||||||
              child: AttachmentItem(item: item),
 | 
					              child: AttachmentItem(
 | 
				
			||||||
 | 
					                  item: item, badge: items.length <= 1 ? null : badge),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class MomentContent extends StatelessWidget {
 | 
				
			|||||||
      data: item.content,
 | 
					      data: item.content,
 | 
				
			||||||
      shrinkWrap: true,
 | 
					      shrinkWrap: true,
 | 
				
			||||||
      physics: const NeverScrollableScrollPhysics(),
 | 
					      physics: const NeverScrollableScrollPhysics(),
 | 
				
			||||||
      padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
					      padding: const EdgeInsets.all(0),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ class _PostItemState extends State<PostItem> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Widget renderContent() {
 | 
					  Widget renderContent() {
 | 
				
			||||||
    switch (widget.item.modelType) {
 | 
					    switch (widget.item.modelType) {
 | 
				
			||||||
      case "article":
 | 
					      case 'article':
 | 
				
			||||||
        return ArticleContent(item: widget.item, brief: widget.brief ?? true);
 | 
					        return ArticleContent(item: widget.item, brief: widget.brief ?? true);
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        return MomentContent(item: widget.item, brief: widget.brief ?? true);
 | 
					        return MomentContent(item: widget.item, brief: widget.brief ?? true);
 | 
				
			||||||
@@ -28,56 +28,110 @@ class _PostItemState extends State<PostItem> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget renderAttachments() {
 | 
					  Widget renderAttachments() {
 | 
				
			||||||
    if(widget.item.attachments != null && widget.item.attachments!.isNotEmpty) {
 | 
					    if (widget.item.modelType == 'article') return Container();
 | 
				
			||||||
      return AttachmentList(items: widget.item.attachments!);
 | 
					
 | 
				
			||||||
 | 
					    if (widget.item.attachments != null &&
 | 
				
			||||||
 | 
					        widget.item.attachments!.isNotEmpty) {
 | 
				
			||||||
 | 
					      return Padding(
 | 
				
			||||||
 | 
					        padding: const EdgeInsets.only(top: 8),
 | 
				
			||||||
 | 
					        child: AttachmentList(items: widget.item.attachments!),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return Container();
 | 
					      return Container();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String getAuthorDescribe() => widget.item.author.description.isNotEmpty
 | 
				
			||||||
 | 
					      ? widget.item.author.description
 | 
				
			||||||
 | 
					      : 'No description yet.';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Padding(
 | 
					    final headingParts = [
 | 
				
			||||||
      padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
 | 
					      Padding(
 | 
				
			||||||
      child: Column(
 | 
					        padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
				
			||||||
        children: [
 | 
					        child: Row(
 | 
				
			||||||
          Row(
 | 
					          children: [
 | 
				
			||||||
            crossAxisAlignment: CrossAxisAlignment.start,
 | 
					            Text(
 | 
				
			||||||
            children: [
 | 
					              widget.item.author.nick,
 | 
				
			||||||
              CircleAvatar(
 | 
					              style: const TextStyle(fontWeight: FontWeight.bold),
 | 
				
			||||||
                backgroundImage: NetworkImage(widget.item.author.avatar),
 | 
					            ),
 | 
				
			||||||
              ),
 | 
					            const SizedBox(width: 4),
 | 
				
			||||||
              Expanded(
 | 
					            Text(timeago.format(widget.item.createdAt))
 | 
				
			||||||
                child: Column(
 | 
					          ],
 | 
				
			||||||
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
					        ),
 | 
				
			||||||
                  children: [
 | 
					      ),
 | 
				
			||||||
                    Padding(
 | 
					    ];
 | 
				
			||||||
                      padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
					
 | 
				
			||||||
                      child: Row(
 | 
					    if (widget.brief ?? true) {
 | 
				
			||||||
                        children: [
 | 
					      return Padding(
 | 
				
			||||||
                          Text(
 | 
					        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
 | 
				
			||||||
                            widget.item.author.nick,
 | 
					        child: Column(
 | 
				
			||||||
                            style: const TextStyle(fontWeight: FontWeight.bold),
 | 
					          children: [
 | 
				
			||||||
                          ),
 | 
					            Row(
 | 
				
			||||||
                          const SizedBox(width: 4),
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
                          Text(
 | 
					              children: [
 | 
				
			||||||
                            timeago.format(widget.item.createdAt)
 | 
					                CircleAvatar(
 | 
				
			||||||
                          )
 | 
					                  backgroundImage: NetworkImage(widget.item.author.avatar),
 | 
				
			||||||
                        ],
 | 
					 | 
				
			||||||
                      ),
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                    renderContent(),
 | 
					 | 
				
			||||||
                  ],
 | 
					 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
              ),
 | 
					                Expanded(
 | 
				
			||||||
            ],
 | 
					                  child: Column(
 | 
				
			||||||
 | 
					                    crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					                    children: [
 | 
				
			||||||
 | 
					                      ...headingParts,
 | 
				
			||||||
 | 
					                      Padding(
 | 
				
			||||||
 | 
					                        padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
				
			||||||
 | 
					                        child: renderContent(),
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                      renderAttachments(),
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          Padding(
 | 
				
			||||||
 | 
					            padding: const EdgeInsets.only(left: 12, right: 12, top: 16),
 | 
				
			||||||
 | 
					            child: Row(
 | 
				
			||||||
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					              children: [
 | 
				
			||||||
 | 
					                CircleAvatar(
 | 
				
			||||||
 | 
					                  backgroundImage: NetworkImage(widget.item.author.avatar),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                Expanded(
 | 
				
			||||||
 | 
					                  child: Column(
 | 
				
			||||||
 | 
					                    crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					                    children: [
 | 
				
			||||||
 | 
					                      ...headingParts,
 | 
				
			||||||
 | 
					                      Padding(
 | 
				
			||||||
 | 
					                        padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
				
			||||||
 | 
					                        child: Text(
 | 
				
			||||||
 | 
					                          getAuthorDescribe(),
 | 
				
			||||||
 | 
					                          maxLines: 1,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          const Padding(
 | 
				
			||||||
 | 
					            padding: EdgeInsets.only(top: 6),
 | 
				
			||||||
 | 
					            child: Divider(thickness: 0.3),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          Padding(
 | 
					          Padding(
 | 
				
			||||||
            padding: const EdgeInsets.all(8.0),
 | 
					            padding: const EdgeInsets.symmetric(horizontal: 16),
 | 
				
			||||||
            child: renderAttachments(),
 | 
					            child: renderContent(),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
 | 
					          renderAttachments()
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      );
 | 
				
			||||||
    );
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user