Improve comic chapters.

This commit is contained in:
2025-02-20 13:08:55 +08:00
parent 2b3c7a8564
commit bd5d10e919
14 changed files with 324 additions and 97 deletions

View File

@@ -279,7 +279,7 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
List<String> tags = context.reader.widget.tags;
String author = context.reader.widget.author;
var epName = context.reader.widget.chapters?.values
var epName = context.reader.widget.chapters?.titles
.elementAtOrNull(context.reader.chapter - 1) ??
"E${context.reader.chapter}";
var translatedTags = tags.map((e) => e.translateTagsToCN).toList();
@@ -561,7 +561,7 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
}
Widget buildPageInfoText() {
var epName = context.reader.widget.chapters?.values
var epName = context.reader.widget.chapters?.titles
.elementAtOrNull(context.reader.chapter - 1) ??
"E${context.reader.chapter}";
if (epName.length > 8) {
@@ -614,7 +614,9 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
void openChapterDrawer() {
showSideBar(
context,
_ChaptersView(context.reader),
context.reader.widget.chapters!.isGrouped
? _GroupedChaptersView(context.reader)
: _ChaptersView(context.reader),
width: 400,
);
}
@@ -1030,14 +1032,27 @@ class _ChaptersView extends StatefulWidget {
class _ChaptersViewState extends State<_ChaptersView> {
bool desc = false;
late final ScrollController _scrollController;
@override
void initState() {
super.initState();
int epIndex = widget.reader.chapter - 2;
_scrollController = ScrollController(
initialScrollOffset: (epIndex * 48.0 + 52).clamp(0, double.infinity),
);
}
@override
Widget build(BuildContext context) {
var chapters = widget.reader.widget.chapters!;
var current = widget.reader.chapter - 1;
return Scaffold(
body: SmoothCustomScrollView(
controller: _scrollController,
slivers: [
SliverAppbar(
style: AppbarStyle.shadow,
title: Text("Chapters".tl),
actions: [
Tooltip(
@@ -1063,26 +1078,35 @@ class _ChaptersViewState extends State<_ChaptersView> {
if (desc) {
index = chapters.length - 1 - index;
}
var chapter = chapters.values.elementAt(index);
return ListTile(
shape: Border(
left: BorderSide(
color: current == index
? context.colorScheme.primary
: Colors.transparent,
width: 4,
),
),
title: Text(
chapter,
style: current == index
? ts.withColor(context.colorScheme.primary).bold
: null,
),
var chapter = chapters.titles.elementAt(index);
return InkWell(
onTap: () {
widget.reader.toChapter(index + 1);
Navigator.of(context).pop();
},
child: Container(
height: 48,
padding: const EdgeInsets.only(left: 16),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
color: current == index
? context.colorScheme.primary
: Colors.transparent,
width: 2,
),
),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
chapter,
style: current == index
? ts.withColor(context.colorScheme.primary).bold.s16
: ts.s16,
),
),
),
);
},
childCount: chapters.length,
@@ -1093,3 +1117,120 @@ class _ChaptersViewState extends State<_ChaptersView> {
);
}
}
class _GroupedChaptersView extends StatefulWidget {
const _GroupedChaptersView(this.reader);
final _ReaderState reader;
@override
State<_GroupedChaptersView> createState() => _GroupedChaptersViewState();
}
class _GroupedChaptersViewState extends State<_GroupedChaptersView>
with SingleTickerProviderStateMixin {
ComicChapters get chapters => widget.reader.widget.chapters!;
late final TabController tabController;
late final ScrollController _scrollController;
late final initialGroupName;
@override
void initState() {
super.initState();
int index = 0;
int epIndex = widget.reader.chapter - 1;
while (epIndex >= 0) {
epIndex -= chapters.getGroupByIndex(index).length;
index++;
}
tabController = TabController(
length: chapters.groups.length,
vsync: this,
initialIndex: index - 1,
);
initialGroupName = chapters.groups.elementAt(index - 1);
var epIndexAtGroup = widget.reader.chapter - 1;
for (var i = 0; i < index-1; i++) {
epIndexAtGroup -= chapters.getGroupByIndex(i).length;
}
_scrollController = ScrollController(
initialScrollOffset: (epIndexAtGroup * 48.0).clamp(0, double.infinity),
);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Appbar(title: Text("Chapters".tl)),
AppTabBar(
controller: tabController,
tabs: chapters.groups.map((e) => Tab(text: e)).toList(),
),
Expanded(
child: TabViewBody(
controller: tabController,
children: chapters.groups.map(buildGroup).toList(),
),
),
],
);
}
Widget buildGroup(String groupName) {
var group = chapters.getGroup(groupName);
return SmoothCustomScrollView(
controller: initialGroupName == groupName ? _scrollController : null,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
var name = group.values.elementAt(index);
var i = 0;
for (var g in chapters.groups) {
if (g == groupName) {
break;
}
i += chapters.getGroup(g).length;
}
i += index + 1;
return InkWell(
onTap: () {
widget.reader.toChapter(i);
context.pop();
},
child: Container(
height: 48,
padding: const EdgeInsets.only(left: 16),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
color: widget.reader.chapter == i
? context.colorScheme.primary
: Colors.transparent,
width: 2,
),
),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
name,
style: widget.reader.chapter == i
? ts.withColor(context.colorScheme.primary).bold.s16
: ts.s16,
),
),
),
);
},
childCount: group.length,
),
),
],
);
}
}