generated from dellevin/template
android:v0.2.9
This commit is contained in:
@@ -260,6 +260,13 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
])),
|
||||
]),
|
||||
],
|
||||
if (book.readCount > 0) ...[
|
||||
const SizedBox(height: 8),
|
||||
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
SizedBox(width: 56, child: Text('阅读次数', style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.4)))),
|
||||
Expanded(child: Text('${book.readCount} 次', style: TextStyle(fontSize: 13, color: colors.onSurface))),
|
||||
]),
|
||||
],
|
||||
if (book.summary != null && book.summary!.isNotEmpty) ...[
|
||||
Divider(height: 32, thickness: 0.5, color: colors.outline),
|
||||
Row(children: [
|
||||
@@ -798,7 +805,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
|
||||
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
|
||||
if (book.publishDate != null) _buildPublishDateSection(book),
|
||||
if (book.startDate != null || book.finishDate != null) _buildReadingDatesSection(book),
|
||||
if (book.startDate != null || book.finishDate != null || book.readCount > 0) _buildReadingDatesSection(book),
|
||||
Divider(height: 0.5, thickness: 0.5, color: colors.outline),
|
||||
if (book.summary != null && book.summary!.isNotEmpty) _buildSummarySection(book),
|
||||
Divider(height: 0.5, thickness: 0.5, color: colors.outline),
|
||||
@@ -899,7 +906,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
|
||||
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
|
||||
if (book.publishDate != null) _buildPublishDateSection(book),
|
||||
if (book.startDate != null || book.finishDate != null) _buildReadingDatesSection(book),
|
||||
if (book.startDate != null || book.finishDate != null || book.readCount > 0) _buildReadingDatesSection(book),
|
||||
// 类型标签毛玻璃
|
||||
if (book.genres.isNotEmpty) _buildGenresSection(book),
|
||||
// 简介:内部已有毛玻璃卡片
|
||||
@@ -1613,35 +1620,64 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
Widget _buildReadingDatesSection(Book book) {
|
||||
final isOverlay = _detailStyle == 1;
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: isOverlay ? 5 : 16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 64,
|
||||
child: Text(
|
||||
'阅读日期',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isOverlay ? const Color(0x66FFFFFF) : colors.onSurface.withValues(alpha: 0.4),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 8,
|
||||
return Column(
|
||||
children: [
|
||||
if (book.startDate != null || book.finishDate != null)
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: isOverlay ? 5 : 16),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (book.startDate != null)
|
||||
_buildDateChip('开始', book.startDate!, isOverlay),
|
||||
if (book.finishDate != null)
|
||||
_buildDateChip('读完', book.finishDate!, isOverlay),
|
||||
SizedBox(
|
||||
width: 64,
|
||||
child: Text(
|
||||
'阅读日期',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isOverlay ? const Color(0x66FFFFFF) : colors.onSurface.withValues(alpha: 0.4),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
if (book.startDate != null)
|
||||
_buildDateChip('开始', book.startDate!, isOverlay),
|
||||
if (book.finishDate != null)
|
||||
_buildDateChip('读完', book.finishDate!, isOverlay),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (book.readCount > 0)
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: isOverlay ? 5 : 4),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 64,
|
||||
child: Text(
|
||||
'阅读次数',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isOverlay ? const Color(0x66FFFFFF) : colors.onSurface.withValues(alpha: 0.4),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${book.readCount} 次',
|
||||
style: TextStyle(fontSize: 13, color: isOverlay ? Colors.white70 : colors.onSurface),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
DateTime? _publishDate;
|
||||
DateTime? _startDate;
|
||||
DateTime? _finishDate;
|
||||
int _readCount = 0;
|
||||
bool _isDownloading = false;
|
||||
|
||||
@override
|
||||
@@ -84,6 +85,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
_publishDate = book.publishDate;
|
||||
_startDate = book.startDate;
|
||||
_finishDate = book.finishDate;
|
||||
_readCount = book.readCount;
|
||||
} else if (widget.initialStatus != null) {
|
||||
_status = widget.initialStatus!;
|
||||
}
|
||||
@@ -238,6 +240,11 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
onTap: () => _selectFinishDate(),
|
||||
),
|
||||
|
||||
// 阅读次数
|
||||
_halfCard('阅读次数', _readCount > 0 ? '$_readCount 次' : '', Icons.repeat_outlined,
|
||||
onTap: () => _editReadCount(),
|
||||
),
|
||||
|
||||
// 书籍简介
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
@@ -585,6 +592,30 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
if (picked != null) setState(() => _finishDate = picked);
|
||||
}
|
||||
|
||||
Future<void> _editReadCount() async {
|
||||
final controller = TextEditingController(text: _readCount > 0 ? '$_readCount' : '');
|
||||
final result = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text('阅读次数'),
|
||||
content: TextField(
|
||||
controller: controller,
|
||||
keyboardType: TextInputType.number,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(hintText: '输入次数'),
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('取消')),
|
||||
TextButton(onPressed: () => Navigator.pop(ctx, controller.text), child: const Text('确定')),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (result != null) {
|
||||
final val = int.tryParse(result) ?? 0;
|
||||
setState(() => _readCount = val < 0 ? 0 : val);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _editSummary() async {
|
||||
final result = await Navigator.push<String>(context, MaterialPageRoute(builder: (_) => _SummaryEditorPage(initialText: _summaryController.text)));
|
||||
if (!mounted) return;
|
||||
@@ -646,7 +677,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
authors: _authors, translators: _translators, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
|
||||
genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status,
|
||||
isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null,
|
||||
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, createdAt: now, updatedAt: now,
|
||||
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, readCount: _readCount, createdAt: now, updatedAt: now,
|
||||
);
|
||||
await context.read<AppProvider>().addBook(newBook);
|
||||
await context.read<AppProvider>().loadBooks();
|
||||
@@ -656,7 +687,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
authors: _authors, translators: _translators, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
|
||||
genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status,
|
||||
isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null,
|
||||
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, updatedAt: now,
|
||||
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, readCount: _readCount, updatedAt: now,
|
||||
);
|
||||
await context.read<AppProvider>().updateBook(updatedBook);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ class _BookTabPageState extends State<BookTabPage> {
|
||||
int _lastScrollSignal = 0;
|
||||
int _lastEditRefreshCounter = 0;
|
||||
int _prevBookCount = -1;
|
||||
int _prevSortMode = -1;
|
||||
double _dragDelta = 0.0; // 当前拖动偏移量
|
||||
|
||||
void _onBookTap(Book book) {
|
||||
@@ -82,6 +83,7 @@ class _BookTabPageState extends State<BookTabPage> {
|
||||
|
||||
// 仅在数据实际变化时刷新列表,避免底部导航栏显隐等UI变化误触发重载
|
||||
final statusChanged = provider.bookStatusIndex != _lastStatusIndex;
|
||||
final sortModeChanged = UserPrefs().bookSortMode != _prevSortMode;
|
||||
final countChanged = provider.books.length != _prevBookCount;
|
||||
final editRefreshed = provider.editRefreshCounter > _lastEditRefreshCounter;
|
||||
if (editRefreshed && provider.lastEditedItemId != null) {
|
||||
@@ -98,7 +100,8 @@ class _BookTabPageState extends State<BookTabPage> {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (statusChanged || countChanged || editRefreshed) {
|
||||
if (statusChanged || sortModeChanged || countChanged || editRefreshed) {
|
||||
_prevSortMode = UserPrefs().bookSortMode;
|
||||
_prevBookCount = provider.books.length;
|
||||
_loadFirst();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user