This commit is contained in:
wzp 2024-08-29 16:25:25 +08:00
parent 5db5a7ea42
commit 860fd5f62e

View File

@ -1,4 +1,6 @@
import 'package:environmental_protection/common/user_information.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
class SocialPage extends StatefulWidget {
const SocialPage({super.key});
@ -8,49 +10,34 @@ class SocialPage extends StatefulWidget {
}
class _SocialPageState extends State<SocialPage> {
final List<Map<String, dynamic>> posts = [
{
"user": "邻居A",
"likes": 360,
},
{
"user": "邻居B",
"likes": 280,
},
{
"user": "邻居C",
"likes": 420,
},
{
"user": "邻居D",
"likes": 150,
},
{
"user": "邻居D",
"likes": 150,
},
{
"user": "邻居D",
"likes": 150,
},
{
"user": "邻居D",
"likes": 150,
},
{
"user": "邻居D",
"likes": 150,
},
{
"user": "邻居D",
"likes": 150,
},
List<Map<String, dynamic>> posts = [];
];
@override
void initState() {
super.initState();
_fetchPosts();
}
Future<void> _fetchPosts() async {
var global = GlobalInformation.getInstance();
final response = await global.requester.get(resolve('api/post/list'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
posts = List<Map<String, dynamic>>.from(data['rows']);
});
} else {
throw Exception('Failed to load posts');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("友邻社交"),
),
body: GridView.builder(
padding: const EdgeInsets.all(10.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
@ -67,7 +54,7 @@ class _SocialPageState extends State<SocialPage> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PostDetailPage(post: post),
builder: (context) => PostDetailPage(postId: post['id']),
),
);
},
@ -75,33 +62,26 @@ class _SocialPageState extends State<SocialPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Placeholder(
fallbackHeight: 150,
color: Colors.grey,
Image.network(
resolve(post['cover']).toString(),
fit: BoxFit.cover,
height: 150,
width: double.infinity,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(post['nickName'] ?? "未知用户", style: const TextStyle(fontSize: 16)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: [
const Icon(Icons.favorite, color: Colors.red, size: 16),
const SizedBox(width: 5),
Text(post['likeNum'].toString()),
],
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(post['user'], style: const TextStyle(fontSize: 16)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
const Icon(Icons.favorite, color: Colors.grey, size: 10,),
const SizedBox(width: 5),
Text(post['likes'].toString()),
],
),
],
),
),
],
)
],
),
),
@ -109,117 +89,204 @@ class _SocialPageState extends State<SocialPage> {
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
heroTag: 'uniqueTag',
onPressed: () {
//
},
child: const Icon(Icons.add),
),
);
}
}
//
class PostDetailPage extends StatelessWidget {
final Map<String, dynamic> post;
class PostDetailPage extends StatefulWidget {
final int postId;
PostDetailPage({super.key, required this.post});
const PostDetailPage({super.key, required this.postId});
//
final List<Map<String, dynamic>> comments = [
{
"username": "用户1",
"date": "2024-08-24",
"content": "这是一个很有趣的帖子!",
"likes": 120,
},
{
"username": "用户2",
"date": "2024-08-23",
"content": "我很喜欢这个内容。",
"likes": 89,
},
{
"username": "用户3",
"date": "2024-08-22",
"content": "赞同楼上的看法。",
"likes": 45,
},
];
@override
State<PostDetailPage> createState() => _PostDetailPageState();
}
class _PostDetailPageState extends State<PostDetailPage> {
Map<String, dynamic>? post;
List<Map<String, dynamic>> comments = [];
int pageNum = 1;
final int pageSize = 10;
bool isLoading = false;
bool hasMore = true;
final TextEditingController _commentController = TextEditingController();
@override
void initState() {
super.initState();
_fetchPostDetail();
_fetchComments();
}
Future<void> _fetchPostDetail() async {
final url = resolve('api/post/${widget.postId}');
final response = await GlobalInformation.getInstance().requester.get(url);
if (response.statusCode == 200) {
setState(() {
post = Map<String, dynamic>.from(jsonDecode(response.body)['data']);
});
} else {
throw Exception('Failed to load post detail');
}
}
Future<void> _fetchComments() async {
if (isLoading || !hasMore) return;
setState(() {
isLoading = true;
});
var url = resolve('api/post/comment/list');
url = url.replace(queryParameters: {
'postId': widget.postId.toString(),
'pageNum': pageNum.toString(),
'pageSize': pageSize.toString(),
});
final response = await GlobalInformation.getInstance().requester.get(
url,
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
setState(() {
comments.addAll(List<Map<String, dynamic>>.from(data['rows']));
hasMore = data['rows'].length == pageSize;
if (hasMore) {
pageNum++;
}
});
} else {
throw Exception('Failed to load comments');
}
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.keyboard_arrow_left),
),
title: const Text("帖子详情"),
centerTitle: true,
),
body: post == null
? const Center(child: CircularProgressIndicator())
: ListView(
children: [
Text(post['user'], style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
const Text("发布时间: 2024-08-24"),
const SizedBox(height: 20),
const Text("这是社交帖的内容。这是一段假数据。", style: TextStyle(fontSize: 16)),
],
),
),
const Divider(),
Expanded(
child: ListView.builder(
itemCount: comments.length,
itemBuilder: (context, index) {
final comment = comments[index];
return ListTile(
leading: const CircleAvatar(
child: Placeholder(),
),
title: Text(comment['username']),
subtitle: Column(
Container(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(comment['content']),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(comment['date'], style: const TextStyle(fontSize: 12, color: Colors.grey)),
Row(
children: [
const Icon(Icons.favorite, color: Colors.red, size: 16),
const SizedBox(width: 4),
Text(comment['likes'].toString()),
],
Text(post!['nickName'] ?? "未知用户", style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
Text("发布时间: ${post!['createTime']}"),
const SizedBox(height: 20),
Text(post!['content'] ?? "无内容", style: const TextStyle(fontSize: 16)),
const SizedBox(height: 10),
Image.network(resolve(post!['cover']).toString()),
],
),
),
const Divider(),
Expanded(
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (!isLoading &&
scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
_fetchComments();
}
return false;
},
child: SizedBox(
height: 600,
child: ListView.builder(
itemCount: comments.length + 1,
itemBuilder: (context, index) {
if (index == comments.length) {
return hasMore
? const Center(child: CircularProgressIndicator())
: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: Text("没有更多评论了")),
);
}
final comment = comments[index];
return ListTile(
leading: comment['avatar'] != null && comment['avatar'] != '' ? CircleAvatar(
backgroundImage: NetworkImage(resolve(comment['avatar']).toString()),
) : const SizedBox(width: 40, height: 40, child: Placeholder()),
title: Text(comment['nickName'] ?? "未知用户"),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(comment['content'] ?? ""),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(comment['createTime'] ?? "未知", style: const TextStyle(fontSize: 12, color: Colors.grey)),
Row(
children: [
const Icon(Icons.favorite, color: Colors.red, size: 16),
const SizedBox(width: 4),
Text(comment['likeNum'].toString()),
],
),
],
),
],
),
);
},
),
)
),
),
const Divider(),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
decoration: const InputDecoration(
hintText: '发表评论...',
border: OutlineInputBorder(),
),
],
controller: _commentController,
),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: () {
var global = GlobalInformation.getInstance();
global.requester.post(resolve('api/post/comment'), body: jsonEncode({"postId": widget.postId.toString(), "content": _commentController.text, "likeNum": "0", "parentId": 0}));
_commentController.clear();
},
child: const Text("发布"),
),
],
),
);
},
),
),
const Divider(),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
const Expanded(
child: TextField(
decoration: InputDecoration(
hintText: '发表评论...',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: () {},
child: const Text("发布"),
),
],
),
),
],
),
)
);
}
}