Improve chapters display

This commit is contained in:
2025-02-13 10:05:38 +08:00
parent 18c5d5d85a
commit 34194559f5
2 changed files with 101 additions and 85 deletions

View File

@@ -331,7 +331,8 @@
"Create a folder": "新建收藏夹", "Create a folder": "新建收藏夹",
"Created successfully": "创建成功", "Created successfully": "创建成功",
"name": "名称", "name": "名称",
"Reverse tap to turn Pages": "反转点击翻页" "Reverse tap to turn Pages": "反转点击翻页",
"Show all": "显示全部"
}, },
"zh_TW": { "zh_TW": {
"Home": "首頁", "Home": "首頁",
@@ -665,6 +666,7 @@
"Create a folder": "新建收藏夾", "Create a folder": "新建收藏夾",
"Created successfully": "創建成功", "Created successfully": "創建成功",
"name": "名稱", "name": "名稱",
"Reverse tap to turn Pages": "反轉點擊翻頁" "Reverse tap to turn Pages": "反轉點擊翻頁",
"Show all": "顯示全部"
} }
} }

View File

@@ -1106,94 +1106,108 @@ class _ComicChaptersState extends State<_ComicChapters> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final eps = state.comic.chapters!; final eps = state.comic.chapters!;
int length = eps.length; return SliverLayoutBuilder(
builder: (context, constrains) {
int length = eps.length;
bool canShowAll = showAll;
if (!showAll) {
var width = constrains.crossAxisExtent;
var crossItems = width ~/ 200;
if (width % 200 != 0) {
crossItems += 1;
}
length = math.min(length, crossItems * 8);
if (length == eps.length) {
canShowAll = true;
}
}
if (!showAll) { return SliverMainAxisGroup(
length = math.min(length, 20); slivers: [
} SliverToBoxAdapter(
child: ListTile(
return SliverMainAxisGroup( title: Text("Chapters".tl),
slivers: [ trailing: Tooltip(
SliverToBoxAdapter( message: "Order".tl,
child: ListTile( child: IconButton(
title: Text("Chapters".tl), icon: Icon(reverse
trailing: Tooltip( ? Icons.vertical_align_top
message: "Order".tl, : Icons.vertical_align_bottom_outlined),
child: IconButton( onPressed: () {
icon: Icon(reverse setState(() {
? Icons.vertical_align_top reverse = !reverse;
: Icons.vertical_align_bottom_outlined), });
onPressed: () { },
setState(() {
reverse = !reverse;
});
},
),
),
),
),
SliverGrid(
delegate:
SliverChildBuilderDelegate(childCount: length, (context, i) {
if (reverse) {
i = eps.length - i - 1;
}
var key = eps.keys.elementAt(i);
var value = eps[key]!;
bool visited =
(state.history?.readEpisode ?? const {}).contains(i + 1);
return Padding(
padding: const EdgeInsets.fromLTRB(8, 4, 8, 4),
child: Material(
color: context.colorScheme.surfaceContainer,
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: InkWell(
onTap: () => state.read(i + 1),
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Center(
child: Text(
value,
maxLines: 1,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: visited ? context.colorScheme.outline : null,
),
),
),
), ),
), ),
), ),
);
}),
gridDelegate: const SliverGridDelegateWithFixedHeight(
maxCrossAxisExtent: 200, itemHeight: 48),
).sliverPadding(const EdgeInsets.symmetric(horizontal: 8)),
if (eps.length > 20 && !showAll)
SliverToBoxAdapter(
child: Align(
alignment: Alignment.center,
child: FilledButton.tonal(
style: ButtonStyle(
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)))),
),
onPressed: () {
setState(() {
showAll = true;
});
},
child: Text("${"Show all".tl} (${eps.length})"),
).paddingTop(12),
), ),
), SliverGrid(
const SliverToBoxAdapter( delegate: SliverChildBuilderDelegate(
child: Divider(), childCount: length,
), (context, i) {
], if (reverse) {
i = eps.length - i - 1;
}
var key = eps.keys.elementAt(i);
var value = eps[key]!;
bool visited =
(state.history?.readEpisode ?? const {}).contains(i + 1);
return Padding(
padding: const EdgeInsets.fromLTRB(6, 4, 6, 4),
child: Material(
color: context.colorScheme.surfaceContainer,
borderRadius: BorderRadius.circular(16),
child: InkWell(
onTap: () => state.read(i + 1),
borderRadius: BorderRadius.circular(16),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Center(
child: Text(
value,
maxLines: 1,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: visited
? context.colorScheme.outline
: null,
),
),
),
),
),
),
);
},
),
gridDelegate: const SliverGridDelegateWithFixedHeight(
maxCrossAxisExtent: 200,
itemHeight: 48,
),
).sliverPadding(const EdgeInsets.symmetric(horizontal: 8)),
if (eps.length > 20 && !canShowAll)
SliverToBoxAdapter(
child: Align(
alignment: Alignment.center,
child: TextButton.icon(
icon: const Icon(Icons.arrow_drop_down),
onPressed: () {
setState(() {
showAll = true;
});
},
label: Text("${"Show all".tl} (${eps.length})"),
).paddingTop(12),
),
),
const SliverToBoxAdapter(
child: Divider(),
),
],
);
},
); );
} }
} }