mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-20 03:06:59 +08:00
@@ -200,6 +200,186 @@ class _AudioPageState extends State<AudioPage> {
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final colorScheme = theme.colorScheme;
|
final colorScheme = theme.colorScheme;
|
||||||
|
Widget child = CustomScrollView(
|
||||||
|
controller: scrollController,
|
||||||
|
physics: _controller.reachStart
|
||||||
|
? null
|
||||||
|
: const AlwaysScrollableScrollPhysics(),
|
||||||
|
slivers: [
|
||||||
|
SliverPadding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.paddingOf(context).bottom + 100,
|
||||||
|
),
|
||||||
|
sliver: SliverList.builder(
|
||||||
|
itemCount: playlist.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
if (index == playlist.length - 1) {
|
||||||
|
_controller.loadNext(context);
|
||||||
|
}
|
||||||
|
final isCurr = index == _controller.index;
|
||||||
|
final item = playlist[index];
|
||||||
|
if (item.parts.length > 1) {
|
||||||
|
final subId = _controller.subId.firstOrNull;
|
||||||
|
return ExpansionTile(
|
||||||
|
dense: true,
|
||||||
|
minTileHeight: 45,
|
||||||
|
initiallyExpanded: isCurr,
|
||||||
|
collapsedIconColor: isCurr ? colorScheme.primary : null,
|
||||||
|
iconColor: isCurr ? null : colorScheme.onSurfaceVariant,
|
||||||
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
|
title: Text(
|
||||||
|
item.arc.title,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: isCurr
|
||||||
|
? TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
)
|
||||||
|
: const TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
trailing: isCurr
|
||||||
|
? null
|
||||||
|
: iconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () {
|
||||||
|
if (index < _controller.index!) {
|
||||||
|
_controller.index -= 1;
|
||||||
|
}
|
||||||
|
playlist.removeAt(index);
|
||||||
|
(context as Element).markNeedsBuild();
|
||||||
|
},
|
||||||
|
iconColor: colorScheme.outline,
|
||||||
|
size: 28,
|
||||||
|
iconSize: 18,
|
||||||
|
),
|
||||||
|
children: item.parts.map((e) {
|
||||||
|
final isCurr = e.subId == subId;
|
||||||
|
return ListTile(
|
||||||
|
dense: true,
|
||||||
|
minTileHeight: 45,
|
||||||
|
contentPadding: const EdgeInsetsDirectional.only(
|
||||||
|
start: 56.0,
|
||||||
|
end: 24.0,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
if (!isCurr) {
|
||||||
|
_controller.playIndex(
|
||||||
|
index,
|
||||||
|
subId: [e.subId],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: Text.rich(
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: isCurr
|
||||||
|
? TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
if (isCurr) ...[
|
||||||
|
WidgetSpan(
|
||||||
|
alignment: .bottom,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/live.gif',
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
cacheWidth: 16.cacheSize(
|
||||||
|
context,
|
||||||
|
),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const TextSpan(text: ' '),
|
||||||
|
],
|
||||||
|
TextSpan(text: e.title),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return ListTile(
|
||||||
|
dense: true,
|
||||||
|
minTileHeight: 45,
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
if (!isCurr) {
|
||||||
|
_controller.playIndex(index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: Text.rich(
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: isCurr
|
||||||
|
? TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: colorScheme.primary,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
)
|
||||||
|
: const TextStyle(fontSize: 14),
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
if (isCurr) ...[
|
||||||
|
WidgetSpan(
|
||||||
|
alignment: .bottom,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/live.gif',
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
cacheWidth: 16.cacheSize(
|
||||||
|
context,
|
||||||
|
),
|
||||||
|
color: colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const TextSpan(text: ' '),
|
||||||
|
],
|
||||||
|
TextSpan(
|
||||||
|
text: item.arc.title,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: isCurr
|
||||||
|
? null
|
||||||
|
: iconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () {
|
||||||
|
if (index < _controller.index!) {
|
||||||
|
_controller.index -= 1;
|
||||||
|
}
|
||||||
|
playlist.removeAt(index);
|
||||||
|
(context as Element).markNeedsBuild();
|
||||||
|
},
|
||||||
|
iconColor: colorScheme.outline,
|
||||||
|
size: 28,
|
||||||
|
iconSize: 18,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
if (!_controller.reachStart) {
|
||||||
|
child = refreshIndicator(
|
||||||
|
onRefresh: () => _controller.loadPrev(context),
|
||||||
|
isClampingScrollPhysics: true,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
return FractionallySizedBox(
|
return FractionallySizedBox(
|
||||||
heightFactor:
|
heightFactor:
|
||||||
PlatformUtils.isMobile && !context.mediaQuerySize.isPortrait
|
PlatformUtils.isMobile && !context.mediaQuerySize.isPortrait
|
||||||
@@ -219,9 +399,7 @@ class _AudioPageState extends State<AudioPage> {
|
|||||||
height: 3,
|
height: 3,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: colorScheme.outline,
|
color: colorScheme.outline,
|
||||||
borderRadius: const BorderRadius.all(
|
borderRadius: const .all(.circular(3)),
|
||||||
Radius.circular(3),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -231,200 +409,8 @@ class _AudioPageState extends State<AudioPage> {
|
|||||||
child: Material(
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: theme.copyWith(
|
data: theme.copyWith(dividerColor: Colors.transparent),
|
||||||
dividerColor: Colors.transparent,
|
child: child,
|
||||||
),
|
|
||||||
child: refreshIndicator(
|
|
||||||
onRefresh: () => _controller.loadPrev(context),
|
|
||||||
isClampingScrollPhysics: true,
|
|
||||||
child: CustomScrollView(
|
|
||||||
controller: scrollController,
|
|
||||||
physics: _controller.reachStart
|
|
||||||
? const ClampingScrollPhysics()
|
|
||||||
: const AlwaysScrollableScrollPhysics(
|
|
||||||
parent: ClampingScrollPhysics(),
|
|
||||||
),
|
|
||||||
slivers: [
|
|
||||||
SliverPadding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
bottom:
|
|
||||||
MediaQuery.paddingOf(context).bottom + 100,
|
|
||||||
),
|
|
||||||
sliver: SliverList.builder(
|
|
||||||
itemCount: playlist.length,
|
|
||||||
itemBuilder: (_, index) {
|
|
||||||
if (index == playlist.length - 1) {
|
|
||||||
_controller.loadNext(context);
|
|
||||||
}
|
|
||||||
final isCurr = index == _controller.index;
|
|
||||||
final item = playlist[index];
|
|
||||||
if (item.parts.length > 1) {
|
|
||||||
final subId = _controller.subId.firstOrNull;
|
|
||||||
return ExpansionTile(
|
|
||||||
dense: true,
|
|
||||||
minTileHeight: 45,
|
|
||||||
initiallyExpanded: isCurr,
|
|
||||||
collapsedIconColor: isCurr
|
|
||||||
? colorScheme.primary
|
|
||||||
: null,
|
|
||||||
iconColor: isCurr
|
|
||||||
? null
|
|
||||||
: colorScheme.onSurfaceVariant,
|
|
||||||
controlAffinity:
|
|
||||||
ListTileControlAffinity.leading,
|
|
||||||
title: Text(
|
|
||||||
item.arc.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: isCurr
|
|
||||||
? TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: colorScheme.primary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
)
|
|
||||||
: const TextStyle(fontSize: 14),
|
|
||||||
),
|
|
||||||
trailing: isCurr
|
|
||||||
? null
|
|
||||||
: iconButton(
|
|
||||||
icon: const Icon(Icons.clear),
|
|
||||||
onPressed: () {
|
|
||||||
if (index <
|
|
||||||
_controller.index!) {
|
|
||||||
_controller.index -= 1;
|
|
||||||
}
|
|
||||||
playlist.removeAt(index);
|
|
||||||
(context as Element)
|
|
||||||
.markNeedsBuild();
|
|
||||||
},
|
|
||||||
iconColor: colorScheme.outline,
|
|
||||||
size: 28,
|
|
||||||
iconSize: 18,
|
|
||||||
),
|
|
||||||
children: item.parts.map((e) {
|
|
||||||
final isCurr = e.subId == subId;
|
|
||||||
return ListTile(
|
|
||||||
dense: true,
|
|
||||||
minTileHeight: 45,
|
|
||||||
contentPadding:
|
|
||||||
const EdgeInsetsDirectional.only(
|
|
||||||
start: 56.0,
|
|
||||||
end: 24.0,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Get.back();
|
|
||||||
if (!isCurr) {
|
|
||||||
_controller.playIndex(
|
|
||||||
index,
|
|
||||||
subId: [e.subId],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title: Text.rich(
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: isCurr
|
|
||||||
? TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: colorScheme.primary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
)
|
|
||||||
: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: colorScheme
|
|
||||||
.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
children: [
|
|
||||||
if (isCurr) ...[
|
|
||||||
WidgetSpan(
|
|
||||||
alignment: .bottom,
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/live.gif',
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
cacheWidth: 16.cacheSize(
|
|
||||||
context,
|
|
||||||
),
|
|
||||||
color:
|
|
||||||
colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const TextSpan(text: ' '),
|
|
||||||
],
|
|
||||||
TextSpan(text: e.title),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return ListTile(
|
|
||||||
dense: true,
|
|
||||||
minTileHeight: 45,
|
|
||||||
onTap: () {
|
|
||||||
Get.back();
|
|
||||||
if (!isCurr) {
|
|
||||||
_controller.playIndex(index);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title: Text.rich(
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: isCurr
|
|
||||||
? TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: colorScheme.primary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
)
|
|
||||||
: const TextStyle(fontSize: 14),
|
|
||||||
TextSpan(
|
|
||||||
children: [
|
|
||||||
if (isCurr) ...[
|
|
||||||
WidgetSpan(
|
|
||||||
alignment: .bottom,
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/live.gif',
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
cacheWidth: 16.cacheSize(
|
|
||||||
context,
|
|
||||||
),
|
|
||||||
color: colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const TextSpan(text: ' '),
|
|
||||||
],
|
|
||||||
TextSpan(
|
|
||||||
text: item.arc.title,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: isCurr
|
|
||||||
? null
|
|
||||||
: iconButton(
|
|
||||||
icon: const Icon(Icons.clear),
|
|
||||||
onPressed: () {
|
|
||||||
if (index < _controller.index!) {
|
|
||||||
_controller.index -= 1;
|
|
||||||
}
|
|
||||||
playlist.removeAt(index);
|
|
||||||
(context as Element)
|
|
||||||
.markNeedsBuild();
|
|
||||||
},
|
|
||||||
iconColor: colorScheme.outline,
|
|
||||||
size: 28,
|
|
||||||
iconSize: 18,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -185,11 +185,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
|
|||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
key: ValueKey(scrollController.hashCode),
|
key: ValueKey(scrollController.hashCode),
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
physics: widget.isNested
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
? const AlwaysScrollableScrollPhysics(
|
|
||||||
parent: ClampingScrollPhysics(),
|
|
||||||
)
|
|
||||||
: const AlwaysScrollableScrollPhysics(),
|
|
||||||
slivers: [
|
slivers: [
|
||||||
if (!isDialogue) ...[
|
if (!isDialogue) ...[
|
||||||
if ((widget.firstFloor ?? _controller.firstFloor.value)
|
if ((widget.firstFloor ?? _controller.firstFloor.value)
|
||||||
|
|||||||
Reference in New Issue
Block a user