💄 Bug fixes and optimization
This commit is contained in:
parent
4489b604d6
commit
07935a4017
@ -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()
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user