💄 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: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,10 +13,7 @@ class ArticleContent extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return brief
|
final headingPart = Column(
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
@ -27,16 +25,18 @@ class ArticleContent extends StatelessWidget {
|
|||||||
style: Theme.of(context).textTheme.bodyMedium,
|
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,10 +38,23 @@ 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(
|
||||||
|
children: [
|
||||||
|
Image.network(
|
||||||
getFileUri().toString(),
|
getFileUri().toString(),
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
|
widget.badge == null
|
||||||
|
? Container()
|
||||||
|
: Positioned(
|
||||||
|
right: 12,
|
||||||
|
bottom: 8,
|
||||||
|
child: Chip(label: Text(widget.badge!)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -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,15 +28,42 @@ 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) {
|
||||||
|
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(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -51,33 +78,60 @@ class _PostItemState extends State<PostItem> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
...headingParts,
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Row(
|
child: renderContent(),
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.item.author.nick,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
renderAttachments(),
|
||||||
Text(
|
|
||||||
timeago.format(widget.item.createdAt)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
renderContent(),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
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