💄 Bug fixes and optimization
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
			
		||||
import 'package:go_router/go_router.dart';
 | 
			
		||||
import 'package:solian/screens/account.dart';
 | 
			
		||||
import 'package:solian/screens/explore.dart';
 | 
			
		||||
import 'package:solian/screens/posts/new_moment.dart';
 | 
			
		||||
import 'package:solian/screens/posts/screen.dart';
 | 
			
		||||
 | 
			
		||||
final router = GoRouter(
 | 
			
		||||
@@ -15,6 +16,11 @@ final router = GoRouter(
 | 
			
		||||
      name: 'account',
 | 
			
		||||
      builder: (context, state) => const AccountScreen(),
 | 
			
		||||
    ),
 | 
			
		||||
    GoRoute(
 | 
			
		||||
      path: '/posts/moments/new',
 | 
			
		||||
      name: 'posts.moments.new',
 | 
			
		||||
      builder: (context, state) => const NewMomentScreen(),
 | 
			
		||||
    ),
 | 
			
		||||
    GoRoute(
 | 
			
		||||
      path: '/posts/:dataset/:alias',
 | 
			
		||||
      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>();
 | 
			
		||||
 | 
			
		||||
    return Container(
 | 
			
		||||
      padding: const EdgeInsets.only(left: 10, right: 10, top: 20),
 | 
			
		||||
      padding: const EdgeInsets.only(left: 8, right: 8, top: 20),
 | 
			
		||||
      child: Row(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
        children: [
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_markdown/flutter_markdown.dart';
 | 
			
		||||
import 'package:solian/models/post.dart';
 | 
			
		||||
import 'package:markdown/markdown.dart' as markdown;
 | 
			
		||||
import 'package:solian/utils/service_url.dart';
 | 
			
		||||
import 'package:url_launcher/url_launcher_string.dart';
 | 
			
		||||
 | 
			
		||||
class ArticleContent extends StatelessWidget {
 | 
			
		||||
@@ -12,10 +13,7 @@ class ArticleContent extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return brief
 | 
			
		||||
        ? Padding(
 | 
			
		||||
          padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
			
		||||
          child: Column(
 | 
			
		||||
    final headingPart = Column(
 | 
			
		||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
      children: [
 | 
			
		||||
        Text(
 | 
			
		||||
@@ -27,16 +25,18 @@ class ArticleContent extends StatelessWidget {
 | 
			
		||||
          style: Theme.of(context).textTheme.bodyMedium,
 | 
			
		||||
        )
 | 
			
		||||
      ],
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return brief
 | 
			
		||||
        ? headingPart
 | 
			
		||||
        : Column(
 | 
			
		||||
            children: [
 | 
			
		||||
              ListTile(
 | 
			
		||||
                title: Text(item.title),
 | 
			
		||||
                subtitle: Text(item.description),
 | 
			
		||||
              Padding(
 | 
			
		||||
                padding: const EdgeInsets.only(bottom: 12),
 | 
			
		||||
                child: headingPart,
 | 
			
		||||
              ),
 | 
			
		||||
              const Divider(color: Color(0xffefefef)),
 | 
			
		||||
              Markdown(
 | 
			
		||||
                padding: const EdgeInsets.all(0),
 | 
			
		||||
                selectable: !brief,
 | 
			
		||||
                data: item.content,
 | 
			
		||||
                shrinkWrap: true,
 | 
			
		||||
@@ -52,6 +52,15 @@ class ArticleContent extends StatelessWidget {
 | 
			
		||||
                    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:chewie/chewie.dart';
 | 
			
		||||
import 'package:solian/models/post.dart';
 | 
			
		||||
@@ -8,8 +9,9 @@ import 'package:video_player/video_player.dart';
 | 
			
		||||
 | 
			
		||||
class AttachmentItem extends StatefulWidget {
 | 
			
		||||
  final Attachment item;
 | 
			
		||||
  final String? badge;
 | 
			
		||||
 | 
			
		||||
  const AttachmentItem({super.key, required this.item});
 | 
			
		||||
  const AttachmentItem({super.key, required this.item, this.badge});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<AttachmentItem> createState() => _AttachmentItemState();
 | 
			
		||||
@@ -36,10 +38,23 @@ class _AttachmentItemState extends State<AttachmentItem> {
 | 
			
		||||
          borderRadius: const BorderRadius.all(borderRadius),
 | 
			
		||||
          child: Hero(
 | 
			
		||||
            tag: getTag(),
 | 
			
		||||
            child: Image.network(
 | 
			
		||||
            child: Stack(
 | 
			
		||||
              children: [
 | 
			
		||||
                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!)),
 | 
			
		||||
                      )
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        onTap: () {
 | 
			
		||||
@@ -110,18 +125,21 @@ class AttachmentList extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    var renderProgress = 0;
 | 
			
		||||
    return FlutterCarousel(
 | 
			
		||||
      options: CarouselOptions(
 | 
			
		||||
        aspectRatio: 16 / 9,
 | 
			
		||||
        showIndicator: true,
 | 
			
		||||
        slideIndicator: const CircularSlideIndicator(),
 | 
			
		||||
        viewportFraction: 1,
 | 
			
		||||
      ),
 | 
			
		||||
      items: items.map((item) {
 | 
			
		||||
        renderProgress++;
 | 
			
		||||
        final badge = '$renderProgress/${items.length}';
 | 
			
		||||
        return Builder(
 | 
			
		||||
          builder: (BuildContext context) {
 | 
			
		||||
            return Padding(
 | 
			
		||||
              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,
 | 
			
		||||
      shrinkWrap: true,
 | 
			
		||||
      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() {
 | 
			
		||||
    switch (widget.item.modelType) {
 | 
			
		||||
      case "article":
 | 
			
		||||
      case 'article':
 | 
			
		||||
        return ArticleContent(item: widget.item, brief: widget.brief ?? true);
 | 
			
		||||
      default:
 | 
			
		||||
        return MomentContent(item: widget.item, brief: widget.brief ?? true);
 | 
			
		||||
@@ -28,15 +28,42 @@ class _PostItemState extends State<PostItem> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget renderAttachments() {
 | 
			
		||||
    if(widget.item.attachments != null && widget.item.attachments!.isNotEmpty) {
 | 
			
		||||
      return AttachmentList(items: widget.item.attachments!);
 | 
			
		||||
    if (widget.item.modelType == 'article') return Container();
 | 
			
		||||
 | 
			
		||||
    if (widget.item.attachments != null &&
 | 
			
		||||
        widget.item.attachments!.isNotEmpty) {
 | 
			
		||||
      return Padding(
 | 
			
		||||
        padding: const EdgeInsets.only(top: 8),
 | 
			
		||||
        child: AttachmentList(items: widget.item.attachments!),
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      return Container();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String getAuthorDescribe() => widget.item.author.description.isNotEmpty
 | 
			
		||||
      ? widget.item.author.description
 | 
			
		||||
      : 'No description yet.';
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final headingParts = [
 | 
			
		||||
      Padding(
 | 
			
		||||
        padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
			
		||||
        child: Row(
 | 
			
		||||
          children: [
 | 
			
		||||
            Text(
 | 
			
		||||
              widget.item.author.nick,
 | 
			
		||||
              style: const TextStyle(fontWeight: FontWeight.bold),
 | 
			
		||||
            ),
 | 
			
		||||
            const SizedBox(width: 4),
 | 
			
		||||
            Text(timeago.format(widget.item.createdAt))
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    if (widget.brief ?? true) {
 | 
			
		||||
      return Padding(
 | 
			
		||||
        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
 | 
			
		||||
        child: Column(
 | 
			
		||||
@@ -51,33 +78,60 @@ class _PostItemState extends State<PostItem> {
 | 
			
		||||
                  child: Column(
 | 
			
		||||
                    crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                    children: [
 | 
			
		||||
                      ...headingParts,
 | 
			
		||||
                      Padding(
 | 
			
		||||
                        padding: const EdgeInsets.symmetric(horizontal: 12),
 | 
			
		||||
                      child: Row(
 | 
			
		||||
                        children: [
 | 
			
		||||
                          Text(
 | 
			
		||||
                            widget.item.author.nick,
 | 
			
		||||
                            style: const TextStyle(fontWeight: FontWeight.bold),
 | 
			
		||||
                        child: renderContent(),
 | 
			
		||||
                      ),
 | 
			
		||||
                          const SizedBox(width: 4),
 | 
			
		||||
                          Text(
 | 
			
		||||
                            timeago.format(widget.item.createdAt)
 | 
			
		||||
                          )
 | 
			
		||||
                        ],
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    renderContent(),
 | 
			
		||||
                      renderAttachments(),
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.all(8.0),
 | 
			
		||||
            child: 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: const EdgeInsets.symmetric(horizontal: 16),
 | 
			
		||||
            child: renderContent(),
 | 
			
		||||
          ),
 | 
			
		||||
          renderAttachments()
 | 
			
		||||
        ],
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user