generated from dellevin/template
界面优化
This commit is contained in:
@@ -89,6 +89,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
_buildBasicInfo(book),
|
||||
Divider(height: 0.5, thickness: 0.5, color: colors.outline),
|
||||
_buildAuthorsSection(book),
|
||||
if (book.translators.isNotEmpty) _buildTranslatorsSection(book),
|
||||
if (book.genres.isNotEmpty) _buildGenresSection(book),
|
||||
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
|
||||
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
|
||||
@@ -190,6 +191,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
const SizedBox(height: 20),
|
||||
// 信息区块:无毛玻璃
|
||||
_buildAuthorsSection(book),
|
||||
if (book.translators.isNotEmpty) _buildTranslatorsSection(book),
|
||||
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
|
||||
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
|
||||
if (book.publishDate != null) _buildPublishDateSection(book),
|
||||
@@ -764,6 +766,39 @@ class _BookDetailPageState extends State<BookDetailPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTranslatorsSection(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: Text(
|
||||
book.translators.join(','),
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: isOverlay ? Colors.white : colors.onSurface,
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIsbnSection(Book book) {
|
||||
final isOverlay = _detailStyle == 1;
|
||||
final colors = Theme.of(context).colorScheme;
|
||||
|
||||
@@ -43,6 +43,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
late TextEditingController _isbnController;
|
||||
|
||||
List<String> _authors = [];
|
||||
List<String> _translators = [];
|
||||
List<String> _alternateTitles = [];
|
||||
List<String> _genres = [];
|
||||
String? _coverPath;
|
||||
@@ -74,6 +75,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
|
||||
if (book != null) {
|
||||
_authors = List.from(book.authors);
|
||||
_translators = List.from(book.translators);
|
||||
_alternateTitles = List.from(book.alternateTitles);
|
||||
_genres = List.from(book.genres);
|
||||
_coverPath = book.coverPath;
|
||||
@@ -165,7 +167,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
},
|
||||
),
|
||||
|
||||
// 作者 + 出版社
|
||||
// 作者 + 译者
|
||||
_halfCard('作者', _authors.isEmpty ? '' : '${_authors.length}人:${_authors.join('、')}', Icons.person_outline,
|
||||
onTap: () async {
|
||||
final provider = context.read<AppProvider>();
|
||||
@@ -174,6 +176,14 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
if (r != null) setState(() => _authors = r);
|
||||
},
|
||||
),
|
||||
_halfCard('译者', _translators.isEmpty ? '' : '${_translators.length}人:${_translators.join('、')}', Icons.translate,
|
||||
onTap: () async {
|
||||
final provider = context.read<AppProvider>();
|
||||
final data = provider.books.map((b) => b.translators).toList();
|
||||
final r = await GenreSelectorPage.show(context: context, title: '选择译者', existingTagsFuture: compute(_collectUnique, data), initialSelected: _translators, hint: '如:李继宏、许钧');
|
||||
if (r != null) setState(() => _translators = r);
|
||||
},
|
||||
),
|
||||
_halfCard('出版社', _publisherController.text, Icons.business_outlined,
|
||||
onTap: () async {
|
||||
final r = await TextInputPanel.show(context: context, title: '出版社', initialValue: _publisherController.text, hint: '请输入出版社');
|
||||
@@ -572,7 +582,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
if (_isbnController.text.trim().isNotEmpty) return true;
|
||||
if (_publisherController.text.trim().isNotEmpty) return true;
|
||||
if (_coverPath != null) return true;
|
||||
if (_authors.isNotEmpty || _alternateTitles.isNotEmpty || _genres.isNotEmpty) return true;
|
||||
if (_authors.isNotEmpty || _translators.isNotEmpty || _alternateTitles.isNotEmpty || _genres.isNotEmpty) return true;
|
||||
if (_publishDate != null) return true;
|
||||
if (_startDate != null) return true;
|
||||
if (_finishDate != null) return true;
|
||||
@@ -616,7 +626,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
}
|
||||
final newBook = Book(
|
||||
id: newBookId, title: _titleController.text.trim(), coverPath: finalCoverPath,
|
||||
authors: _authors, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
|
||||
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,
|
||||
@@ -625,7 +635,7 @@ class _BookFormPageState extends State<BookFormPage> {
|
||||
} else {
|
||||
final updatedBook = widget.book!.copyWith(
|
||||
title: _titleController.text.trim(), coverPath: _coverPath,
|
||||
authors: _authors, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
|
||||
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,
|
||||
|
||||
@@ -140,24 +140,6 @@ class _BookReviewsPageState extends State<BookReviewsPage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
InkWell(
|
||||
onTap: () => _navigateToAddReview(),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.primary,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'添加记录',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colors.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -91,24 +91,6 @@ class _MoviePostersPageState extends State<MoviePostersPage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
InkWell(
|
||||
onTap: _pickPoster,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.primary,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'添加记录',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colors.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -140,24 +140,6 @@ class _MovieReviewsPageState extends State<MovieReviewsPage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
InkWell(
|
||||
onTap: () => _navigateToAddReview(),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.primary,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'添加记录',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colors.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -66,6 +66,7 @@ class _PersonListPageState extends State<PersonListPage> {
|
||||
}
|
||||
for (final b in provider.books.where((b) => !b.isDeleted)) {
|
||||
for (final a in b.authors) addRole(a, '作者', book: b);
|
||||
for (final t in b.translators) addRole(t, '译者', book: b);
|
||||
}
|
||||
|
||||
var list = map.values.toList();
|
||||
@@ -119,7 +120,7 @@ class _PersonListPageState extends State<PersonListPage> {
|
||||
style: TextStyle(fontSize: 15, color: colors.onSurface),
|
||||
cursorColor: colors.primary,
|
||||
decoration: InputDecoration(
|
||||
hintText: '搜索导演、编剧、演员、作者',
|
||||
hintText: '搜索导演、编剧、演员、作者、译者',
|
||||
hintStyle: TextStyle(fontSize: 14, color: colors.onSurface.withValues(alpha: 0.3)),
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
@@ -156,7 +157,7 @@ class _PersonListPageState extends State<PersonListPage> {
|
||||
padding: const EdgeInsets.fromLTRB(20, 10, 20, 4),
|
||||
child: Row(
|
||||
children: [
|
||||
for (final f in ['all', '导演', '编剧', '主演', '作者'])
|
||||
for (final f in ['all', '导演', '编剧', '主演', '作者', '译者'])
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 6),
|
||||
child: GestureDetector(
|
||||
@@ -208,6 +209,7 @@ class _PersonListPageState extends State<PersonListPage> {
|
||||
'编剧': const Color(0xFF009688),
|
||||
'主演': const Color(0xFFE91E63),
|
||||
'作者': const Color(0xFF7E57C2),
|
||||
'译者': const Color(0xFFFF7043),
|
||||
};
|
||||
final totalWorks = person.movies.length + person.books.length;
|
||||
return ListTile(
|
||||
@@ -262,6 +264,7 @@ class _PersonDetailPage extends StatelessWidget {
|
||||
'编剧': const Color(0xFF009688),
|
||||
'主演': const Color(0xFFE91E63),
|
||||
'作者': const Color(0xFF7E57C2),
|
||||
'译者': const Color(0xFFFF7043),
|
||||
};
|
||||
|
||||
final movieItems = <_WorkItem>[];
|
||||
@@ -275,7 +278,10 @@ class _PersonDetailPage extends StatelessWidget {
|
||||
movieItems.add(_WorkItem(title: m.title, roles: roles, path: m.posterPath, data: m));
|
||||
}
|
||||
for (final b in person.books) {
|
||||
bookItems.add(_WorkItem(title: b.title, roles: const ['作者'], path: b.coverPath, data: b));
|
||||
final roles = <String>[];
|
||||
if (b.authors.contains(person.name)) roles.add('作者');
|
||||
if (b.translators.contains(person.name)) roles.add('译者');
|
||||
bookItems.add(_WorkItem(title: b.title, roles: roles, path: b.coverPath, data: b));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
|
||||
@@ -340,7 +340,7 @@ class _StrollPageState extends State<StrollPage> {
|
||||
/// 有图片的卡片:全屏沉浸式
|
||||
Widget _buildImmersiveCard(_StrollItem item, ColorScheme colors) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 56, horizontal: 8),
|
||||
margin: const EdgeInsets.symmetric(vertical: 80, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 8))],
|
||||
@@ -382,7 +382,7 @@ class _StrollPageState extends State<StrollPage> {
|
||||
/// 无图片的卡片:内容从顶部开始
|
||||
Widget _buildContentCard(_StrollItem item, ColorScheme colors) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 56, horizontal: 8),
|
||||
margin: const EdgeInsets.symmetric(vertical: 80, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.surface,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
|
||||
Reference in New Issue
Block a user