import 'package:blog_app/widget/common.dart'; import 'package:blog_app/widget/markdown.dart'; import 'package:provider/provider.dart'; import 'package:blog_app/provider/blog.dart'; import 'package:flutter/material.dart'; import 'package:markdown_widget/config/toc.dart'; class BlogDetailPage extends StatefulWidget { final int blogId; const BlogDetailPage({super.key, required this.blogId}); @override State createState() => _BlogDetailPageState(); } class _BlogDetailPageState extends State { final tocController = TocController(); bool _showToc = false; @override void initState() { super.initState(); // 初始化加载数据 WidgetsBinding.instance.addPostFrameCallback((_) { context.read().queryBlogById(widget.blogId); }); } Widget _buildBlogTitle(String title) { return Text( title, style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ), ); } Widget? buildFloatingActionButton(BlogProvider provider) { if (!provider.isLoading) { return FloatingActionButton( onPressed: () => setState(() => _showToc = !_showToc), mini: true, backgroundColor: Theme.of(context).primaryColor, child: Icon(_showToc ? Icons.close : Icons.list, color: Colors.white), ); } else { return null; } } Widget _buildContent(BlogProvider provider) { if (provider.error != null) { return buildErrorInfo( errorInfo: provider.error!, onPressed: () => provider.queryBlogById(widget.blogId), ); } return Stack( children: [ Column( children: [ _buildBlogTitle(provider.currentBlog.title), SizedBox(height: 10), Expanded( child: buildMarkdown( tocController: tocController, data: provider.currentBlog.content!, ), ), ], ), buildTocPanel(tocController: tocController, showToc: _showToc), ], ); } @override Widget build(BuildContext context) { final blogProvider = context.watch(); return Scaffold( appBar: AppBar(title: Text('博客详情')), body: Container( padding: EdgeInsets.all(16), child: Stack( children: [ if (blogProvider.isLoading) buildLoadingIndicator() else _buildContent(blogProvider), ], ), ), floatingActionButton: buildFloatingActionButton(blogProvider), ); } }