mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
fix
This commit is contained in:
parent
fe29eb6ecc
commit
32dbbd5e0e
9 changed files with 623 additions and 603 deletions
|
|
@ -921,7 +921,17 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
|
||||||
),
|
),
|
||||||
Row(children: [
|
Row(children: [
|
||||||
btnToShowChapterListDialog(
|
btnToShowChapterListDialog(
|
||||||
context, context.l10n.episodes, widget.episode),
|
context,
|
||||||
|
context.l10n.episodes,
|
||||||
|
widget.episode,
|
||||||
|
onChanged: (v) {
|
||||||
|
if (v) {
|
||||||
|
_player.play();
|
||||||
|
} else {
|
||||||
|
_player.pause();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// onPressed: () {
|
// onPressed: () {
|
||||||
// showDialog(
|
// showDialog(
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class SubtitleSettingsState extends _$SubtitleSettingsState {
|
||||||
@override
|
@override
|
||||||
PlayerSubtitleSettings build() {
|
PlayerSubtitleSettings build() {
|
||||||
final subSets = isar.settings.getSync(227)!.playerSubtitleSettings;
|
final subSets = isar.settings.getSync(227)!.playerSubtitleSettings;
|
||||||
if (subSets == null) {
|
if (subSets == null || subSets.backgroundColorA == null) {
|
||||||
set(PlayerSubtitleSettings(), true);
|
set(PlayerSubtitleSettings(), true);
|
||||||
return PlayerSubtitleSettings();
|
return PlayerSubtitleSettings();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,249 +189,254 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
const SingleActivator(LogicalKeyboardKey.escape): () =>
|
const SingleActivator(LogicalKeyboardKey.escape): () =>
|
||||||
setFullScreen(value: false),
|
setFullScreen(value: false),
|
||||||
},
|
},
|
||||||
child: Focus(
|
child: Stack(
|
||||||
autofocus: true,
|
children: [
|
||||||
child: Listener(
|
Consumer(
|
||||||
onPointerSignal: modifyVolumeOnScroll
|
builder: (context, ref, _) => Positioned(
|
||||||
? (e) {
|
child: CustomSubtitleView(
|
||||||
if (e is PointerScrollEvent) {
|
controller: widget.videoController,
|
||||||
if (e.delta.dy > 0) {
|
configuration:
|
||||||
final volume =
|
SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
||||||
widget.videoController.player.state.volume - 5.0;
|
)),
|
||||||
widget.videoController.player
|
),
|
||||||
.setVolume(volume.clamp(0.0, 100.0));
|
Focus(
|
||||||
}
|
autofocus: true,
|
||||||
if (e.delta.dy < 0) {
|
child: Listener(
|
||||||
final volume =
|
onPointerSignal: modifyVolumeOnScroll
|
||||||
widget.videoController.player.state.volume + 5.0;
|
? (e) {
|
||||||
widget.videoController.player
|
if (e is PointerScrollEvent) {
|
||||||
.setVolume(volume.clamp(0.0, 100.0));
|
if (e.delta.dy > 0) {
|
||||||
}
|
final volume =
|
||||||
}
|
widget.videoController.player.state.volume - 5.0;
|
||||||
}
|
widget.videoController.player
|
||||||
: null,
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
child: GestureDetector(
|
}
|
||||||
onTapUp: !toggleFullscreenOnDoublePress
|
if (e.delta.dy < 0) {
|
||||||
? null
|
final volume =
|
||||||
: (e) {
|
widget.videoController.player.state.volume + 5.0;
|
||||||
final now = DateTime.now();
|
widget.videoController.player
|
||||||
final difference = now.difference(last);
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
last = now;
|
}
|
||||||
if (difference < const Duration(milliseconds: 400)) {
|
|
||||||
setFullScreen();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onPanUpdate: modifyVolumeOnScroll
|
|
||||||
? (e) {
|
|
||||||
if (e.delta.dy > 0) {
|
|
||||||
final volume =
|
|
||||||
widget.videoController.player.state.volume - 5.0;
|
|
||||||
widget.videoController.player
|
|
||||||
.setVolume(volume.clamp(0.0, 100.0));
|
|
||||||
}
|
|
||||||
if (e.delta.dy < 0) {
|
|
||||||
final volume =
|
|
||||||
widget.videoController.player.state.volume + 5.0;
|
|
||||||
widget.videoController.player
|
|
||||||
.setVolume(volume.clamp(0.0, 100.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
child: MouseRegion(
|
|
||||||
onHover: (_) => onHover(),
|
|
||||||
onEnter: (_) => onEnter(),
|
|
||||||
onExit: (_) => onExit(),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
Consumer(
|
|
||||||
builder: (context, ref, _) => Positioned(
|
|
||||||
child: CustomSubtitleView(
|
|
||||||
controller: widget.videoController,
|
|
||||||
configuration: SubtitleViewConfiguration(
|
|
||||||
style: subtileTextStyle(ref)),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
AnimatedOpacity(
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
opacity: visible ? 1.0 : 0.0,
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
onEnd: () {
|
|
||||||
if (!visible) {
|
|
||||||
setState(() {
|
|
||||||
mount = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
child: Stack(
|
: null,
|
||||||
clipBehavior: Clip.none,
|
child: GestureDetector(
|
||||||
alignment: Alignment.bottomCenter,
|
onTapUp: !toggleFullscreenOnDoublePress
|
||||||
children: [
|
? null
|
||||||
// Top gradient.
|
: (e) {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final difference = now.difference(last);
|
||||||
|
last = now;
|
||||||
|
if (difference < const Duration(milliseconds: 400)) {
|
||||||
|
setFullScreen();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPanUpdate: modifyVolumeOnScroll
|
||||||
|
? (e) {
|
||||||
|
if (e.delta.dy > 0) {
|
||||||
|
final volume =
|
||||||
|
widget.videoController.player.state.volume - 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
|
}
|
||||||
|
if (e.delta.dy < 0) {
|
||||||
|
final volume =
|
||||||
|
widget.videoController.player.state.volume + 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: MouseRegion(
|
||||||
|
onHover: (_) => onHover(),
|
||||||
|
onEnter: (_) => onEnter(),
|
||||||
|
onExit: (_) => onExit(),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
AnimatedOpacity(
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
opacity: visible ? 1.0 : 0.0,
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
onEnd: () {
|
||||||
|
if (!visible) {
|
||||||
|
setState(() {
|
||||||
|
mount = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
children: [
|
||||||
|
// Top gradient.
|
||||||
|
|
||||||
Container(
|
Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
stops: [
|
stops: [
|
||||||
0.0,
|
0.0,
|
||||||
0.2,
|
0.2,
|
||||||
],
|
],
|
||||||
colors: [
|
colors: [
|
||||||
Color(0x61000000),
|
Color(0x61000000),
|
||||||
Color(0x00000000),
|
Color(0x00000000),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Bottom gradient.
|
|
||||||
|
|
||||||
Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topCenter,
|
|
||||||
end: Alignment.bottomCenter,
|
|
||||||
stops: [
|
|
||||||
0.5,
|
|
||||||
1.0,
|
|
||||||
],
|
|
||||||
colors: [
|
|
||||||
Color(0x00000000),
|
|
||||||
Color(0x61000000),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (mount)
|
|
||||||
Padding(
|
|
||||||
padding: (
|
|
||||||
// Add padding in fullscreen!
|
|
||||||
isFullscreen(context)
|
|
||||||
? MediaQuery.of(context).padding
|
|
||||||
: EdgeInsets.zero),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
widget.topButtonBarWidget,
|
|
||||||
// Only display [primaryButtonBar] if [buffering] is false.
|
|
||||||
Expanded(
|
|
||||||
child: AnimatedOpacity(
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
opacity: buffering
|
|
||||||
? 0.0
|
|
||||||
: !showSwipeDuration
|
|
||||||
? 0.0
|
|
||||||
: 1.0,
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
child: Center(
|
|
||||||
child: seekIndicatorTextWidget(
|
|
||||||
Duration(seconds: swipeDuration),
|
|
||||||
widget.videoController.player
|
|
||||||
.state.position))),
|
|
||||||
),
|
|
||||||
widget.seekToWidget,
|
|
||||||
Transform.translate(
|
|
||||||
offset: Offset.zero,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 5),
|
|
||||||
child: CustomSeekBar(
|
|
||||||
onSeekStart: (value) {
|
|
||||||
setState(() {
|
|
||||||
swipeDuration = value.inSeconds;
|
|
||||||
showSwipeDuration = true;
|
|
||||||
widget.tempDuration(widget
|
|
||||||
.videoController
|
|
||||||
.player
|
|
||||||
.state
|
|
||||||
.position +
|
|
||||||
value);
|
|
||||||
});
|
|
||||||
_timer?.cancel();
|
|
||||||
},
|
|
||||||
onSeekEnd: (value) {
|
|
||||||
_timer = Timer(
|
|
||||||
controlsHoverDuration,
|
|
||||||
() {
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
visible = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
setState(() {
|
|
||||||
showSwipeDuration = false;
|
|
||||||
});
|
|
||||||
widget.tempDuration(null);
|
|
||||||
},
|
|
||||||
player: widget.videoController.player,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
widget.bottomButtonBarWidget
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Buffering Indicator.
|
|
||||||
IgnorePointer(
|
|
||||||
child: Padding(
|
|
||||||
padding: (
|
|
||||||
// Add padding in fullscreen!
|
|
||||||
isFullscreen(context)
|
|
||||||
? MediaQuery.of(context).padding
|
|
||||||
: EdgeInsets.zero),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: buttonBarHeight,
|
|
||||||
margin: const EdgeInsets.all(0),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: Center(
|
|
||||||
child: TweenAnimationBuilder<double>(
|
|
||||||
tween: Tween<double>(
|
|
||||||
begin: 0.0,
|
|
||||||
end: buffering ? 1.0 : 0.0,
|
|
||||||
),
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
builder: (context, value, child) {
|
|
||||||
// Only mount the buffering indicator if the opacity is greater than 0.0.
|
|
||||||
// This has been done to prevent redundant resource usage in [CircularProgressIndicator].
|
|
||||||
if (value > 0.0) {
|
|
||||||
return Opacity(
|
|
||||||
opacity: value,
|
|
||||||
child: child!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
},
|
|
||||||
child: const CircularProgressIndicator(
|
|
||||||
color: Color(0xFFFFFFFF),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
// Bottom gradient.
|
||||||
Container(
|
|
||||||
height: buttonBarHeight,
|
Container(
|
||||||
margin: bottomButtonBarMargin,
|
decoration: const BoxDecoration(
|
||||||
),
|
gradient: LinearGradient(
|
||||||
],
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
stops: [
|
||||||
|
0.5,
|
||||||
|
1.0,
|
||||||
|
],
|
||||||
|
colors: [
|
||||||
|
Color(0x00000000),
|
||||||
|
Color(0x61000000),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (mount)
|
||||||
|
Padding(
|
||||||
|
padding: (
|
||||||
|
// Add padding in fullscreen!
|
||||||
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
widget.topButtonBarWidget,
|
||||||
|
// Only display [primaryButtonBar] if [buffering] is false.
|
||||||
|
Expanded(
|
||||||
|
child: AnimatedOpacity(
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
opacity: buffering
|
||||||
|
? 0.0
|
||||||
|
: !showSwipeDuration
|
||||||
|
? 0.0
|
||||||
|
: 1.0,
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
child: Center(
|
||||||
|
child: seekIndicatorTextWidget(
|
||||||
|
Duration(
|
||||||
|
seconds: swipeDuration),
|
||||||
|
widget.videoController.player
|
||||||
|
.state.position))),
|
||||||
|
),
|
||||||
|
widget.seekToWidget,
|
||||||
|
Transform.translate(
|
||||||
|
offset: Offset.zero,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 5),
|
||||||
|
child: CustomSeekBar(
|
||||||
|
onSeekStart: (value) {
|
||||||
|
setState(() {
|
||||||
|
swipeDuration = value.inSeconds;
|
||||||
|
showSwipeDuration = true;
|
||||||
|
widget.tempDuration(widget
|
||||||
|
.videoController
|
||||||
|
.player
|
||||||
|
.state
|
||||||
|
.position +
|
||||||
|
value);
|
||||||
|
});
|
||||||
|
_timer?.cancel();
|
||||||
|
},
|
||||||
|
onSeekEnd: (value) {
|
||||||
|
_timer = Timer(
|
||||||
|
controlsHoverDuration,
|
||||||
|
() {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
visible = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
showSwipeDuration = false;
|
||||||
|
});
|
||||||
|
widget.tempDuration(null);
|
||||||
|
},
|
||||||
|
player: widget.videoController.player,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
widget.bottomButtonBarWidget
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
// Buffering Indicator.
|
||||||
|
IgnorePointer(
|
||||||
|
child: Padding(
|
||||||
|
padding: (
|
||||||
|
// Add padding in fullscreen!
|
||||||
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: buttonBarHeight,
|
||||||
|
margin: const EdgeInsets.all(0),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Center(
|
||||||
|
child: TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween<double>(
|
||||||
|
begin: 0.0,
|
||||||
|
end: buffering ? 1.0 : 0.0,
|
||||||
|
),
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
// Only mount the buffering indicator if the opacity is greater than 0.0.
|
||||||
|
// This has been done to prevent redundant resource usage in [CircularProgressIndicator].
|
||||||
|
if (value > 0.0) {
|
||||||
|
return Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: child!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
child: const CircularProgressIndicator(
|
||||||
|
color: Color(0xFFFFFFFF),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: buttonBarHeight,
|
||||||
|
margin: bottomButtonBarMargin,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -286,374 +286,381 @@ class _MobileControllerWidgetState
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Focus(
|
return Stack(
|
||||||
autofocus: true,
|
children: [
|
||||||
child: Stack(
|
Consumer(
|
||||||
clipBehavior: Clip.none,
|
builder: (context, ref, _) => Positioned(
|
||||||
alignment: Alignment.center,
|
child: CustomSubtitleView(
|
||||||
children: [
|
controller: widget.videoController,
|
||||||
// // Controls:
|
configuration:
|
||||||
AnimatedOpacity(
|
SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
||||||
curve: Curves.easeInOut,
|
)),
|
||||||
opacity: visible ? 1.0 : 0.0,
|
),
|
||||||
duration: controlsTransitionDuration,
|
Focus(
|
||||||
onEnd: () {
|
autofocus: true,
|
||||||
setState(() {
|
child: Stack(
|
||||||
if (!visible) {
|
clipBehavior: Clip.none,
|
||||||
mount = false;
|
alignment: Alignment.center,
|
||||||
}
|
children: [
|
||||||
});
|
// // Controls:
|
||||||
},
|
AnimatedOpacity(
|
||||||
child: Stack(
|
curve: Curves.easeInOut,
|
||||||
clipBehavior: Clip.none,
|
opacity: visible ? 1.0 : 0.0,
|
||||||
alignment: Alignment.center,
|
duration: controlsTransitionDuration,
|
||||||
children: [
|
onEnd: () {
|
||||||
Consumer(
|
setState(() {
|
||||||
builder: (context, ref, _) => Positioned(
|
if (!visible) {
|
||||||
child: CustomSubtitleView(
|
mount = false;
|
||||||
controller: widget.videoController,
|
}
|
||||||
configuration:
|
});
|
||||||
SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
},
|
||||||
)),
|
child: Stack(
|
||||||
),
|
clipBehavior: Clip.none,
|
||||||
Positioned.fill(
|
alignment: Alignment.center,
|
||||||
child: Container(
|
children: [
|
||||||
color: backdropColor,
|
Positioned.fill(
|
||||||
),
|
child: Container(
|
||||||
),
|
color: backdropColor,
|
||||||
// We are adding 16.0 boundary around the actual controls (which contain the vertical drag gesture detectors).
|
),
|
||||||
// This will make the hit-test on edges (e.g. swiping to: show status-bar, show navigation-bar, go back in navigation) not activate the swipe gesture annoyingly.
|
|
||||||
Positioned.fill(
|
|
||||||
left: 16.0,
|
|
||||||
top: 16.0,
|
|
||||||
right: 16.0,
|
|
||||||
bottom: 16.0,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
onDoubleTapDown: _handleTapDown,
|
|
||||||
onDoubleTap: () {
|
|
||||||
if (_tapPosition != null &&
|
|
||||||
_tapPosition!.dx >
|
|
||||||
MediaQuery.of(context).size.width / 2) {
|
|
||||||
onDoubleTapSeekForward();
|
|
||||||
} else {
|
|
||||||
onDoubleTapSeekBackward();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onHorizontalDragUpdate: (details) {
|
|
||||||
onHorizontalDragUpdate(details);
|
|
||||||
},
|
|
||||||
onHorizontalDragEnd: (details) {
|
|
||||||
onHorizontalDragEnd();
|
|
||||||
},
|
|
||||||
onVerticalDragUpdate: (e) async {
|
|
||||||
final delta = e.delta.dy;
|
|
||||||
final Offset position = e.localPosition;
|
|
||||||
|
|
||||||
if (position.dx <=
|
|
||||||
MediaQuery.of(context).size.width / 2) {
|
|
||||||
// Left side of screen swiped
|
|
||||||
|
|
||||||
final brightness = _brightnessValue.value -
|
|
||||||
delta / verticalGestureSensitivity;
|
|
||||||
final result = brightness.clamp(0.0, 1.0);
|
|
||||||
setBrightness(result);
|
|
||||||
} else {
|
|
||||||
// Right side of screen swiped
|
|
||||||
|
|
||||||
final volume = _volumeValue.value -
|
|
||||||
delta / verticalGestureSensitivity;
|
|
||||||
final result = volume.clamp(0.0, 1.0);
|
|
||||||
setVolume(result);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
color: const Color(0x00000000),
|
|
||||||
),
|
),
|
||||||
),
|
// We are adding 16.0 boundary around the actual controls (which contain the vertical drag gesture detectors).
|
||||||
),
|
// This will make the hit-test on edges (e.g. swiping to: show status-bar, show navigation-bar, go back in navigation) not activate the swipe gesture annoyingly.
|
||||||
if (mount)
|
Positioned.fill(
|
||||||
Padding(
|
left: 16.0,
|
||||||
padding: (
|
top: 16.0,
|
||||||
// Add padding in fullscreen!
|
right: 16.0,
|
||||||
isFullscreen(context)
|
bottom: 16.0,
|
||||||
? MediaQuery.of(context).padding
|
child: GestureDetector(
|
||||||
: EdgeInsets.zero),
|
onTap: onTap,
|
||||||
child: Column(
|
onDoubleTapDown: _handleTapDown,
|
||||||
mainAxisSize: MainAxisSize.min,
|
onDoubleTap: () {
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
if (_tapPosition != null &&
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
_tapPosition!.dx >
|
||||||
children: [
|
MediaQuery.of(context).size.width / 2) {
|
||||||
widget.topButtonBarWidget,
|
onDoubleTapSeekForward();
|
||||||
// Only display [primaryButtonBar] if [buffering] is false.
|
} else {
|
||||||
Expanded(
|
onDoubleTapSeekBackward();
|
||||||
child: AnimatedOpacity(
|
}
|
||||||
curve: Curves.easeInOut,
|
},
|
||||||
opacity: buffering
|
onHorizontalDragUpdate: (details) {
|
||||||
? 0.0
|
onHorizontalDragUpdate(details);
|
||||||
: showSwipeDuration
|
},
|
||||||
? 0.0
|
onHorizontalDragEnd: (details) {
|
||||||
: 1.0,
|
onHorizontalDragEnd();
|
||||||
duration: controlsTransitionDuration,
|
},
|
||||||
child: Center(
|
onVerticalDragUpdate: (e) async {
|
||||||
child: Row(
|
final delta = e.delta.dy;
|
||||||
children: mobilePrimaryButtonBar(
|
final Offset position = e.localPosition;
|
||||||
context,
|
|
||||||
widget.videoStatekey,
|
if (position.dx <=
|
||||||
widget.streamController,
|
MediaQuery.of(context).size.width / 2) {
|
||||||
widget.videoController)),
|
// Left side of screen swiped
|
||||||
),
|
|
||||||
),
|
final brightness = _brightnessValue.value -
|
||||||
|
delta / verticalGestureSensitivity;
|
||||||
|
final result = brightness.clamp(0.0, 1.0);
|
||||||
|
setBrightness(result);
|
||||||
|
} else {
|
||||||
|
// Right side of screen swiped
|
||||||
|
|
||||||
|
final volume = _volumeValue.value -
|
||||||
|
delta / verticalGestureSensitivity;
|
||||||
|
final result = volume.clamp(0.0, 1.0);
|
||||||
|
setVolume(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: const Color(0x00000000),
|
||||||
),
|
),
|
||||||
Stack(
|
),
|
||||||
alignment: Alignment.bottomCenter,
|
),
|
||||||
|
if (mount)
|
||||||
|
Padding(
|
||||||
|
padding: (
|
||||||
|
// Add padding in fullscreen!
|
||||||
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
widget.topButtonBarWidget,
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
// Only display [primaryButtonBar] if [buffering] is false.
|
||||||
child: CustomSeekBar(
|
Expanded(
|
||||||
onSeekStart: (value) {
|
child: AnimatedOpacity(
|
||||||
setState(() {
|
curve: Curves.easeInOut,
|
||||||
swipeDuration = value.inSeconds;
|
opacity: buffering
|
||||||
showSwipeDuration = true;
|
? 0.0
|
||||||
});
|
: showSwipeDuration
|
||||||
_timer?.cancel();
|
? 0.0
|
||||||
},
|
: 1.0,
|
||||||
onSeekEnd: (value) {
|
duration: controlsTransitionDuration,
|
||||||
_timer = Timer(
|
child: Center(
|
||||||
controlsHoverDuration,
|
child: Row(
|
||||||
() {
|
children: mobilePrimaryButtonBar(
|
||||||
if (mounted) {
|
context,
|
||||||
setState(() {
|
widget.videoStatekey,
|
||||||
visible = false;
|
widget.streamController,
|
||||||
});
|
widget.videoController)),
|
||||||
}
|
),
|
||||||
},
|
|
||||||
);
|
|
||||||
setState(() {
|
|
||||||
showSwipeDuration = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
player: widget.videoController.player,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
widget.bottomButtonBarWidget
|
Stack(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: CustomSeekBar(
|
||||||
|
onSeekStart: (value) {
|
||||||
|
setState(() {
|
||||||
|
swipeDuration = value.inSeconds;
|
||||||
|
showSwipeDuration = true;
|
||||||
|
});
|
||||||
|
_timer?.cancel();
|
||||||
|
},
|
||||||
|
onSeekEnd: (value) {
|
||||||
|
_timer = Timer(
|
||||||
|
controlsHoverDuration,
|
||||||
|
() {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
visible = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
setState(() {
|
||||||
|
showSwipeDuration = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
player: widget.videoController.player,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
widget.bottomButtonBarWidget
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
// // Double-Tap Seek Seek-Bar:
|
||||||
),
|
if (!mount)
|
||||||
// // Double-Tap Seek Seek-Bar:
|
if (_mountSeekBackwardButton ||
|
||||||
if (!mount)
|
_mountSeekForwardButton ||
|
||||||
if (_mountSeekBackwardButton ||
|
showSwipeDuration)
|
||||||
_mountSeekForwardButton ||
|
Column(
|
||||||
showSwipeDuration)
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const Spacer(),
|
|
||||||
Stack(
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
const Spacer(),
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
Stack(
|
||||||
child: CustomSeekBar(
|
alignment: Alignment.bottomCenter,
|
||||||
delta: _seekBarDeltaValueNotifier,
|
children: [
|
||||||
player: widget.videoController.player),
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: CustomSeekBar(
|
||||||
|
delta: _seekBarDeltaValueNotifier,
|
||||||
|
player: widget.videoController.player),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
// // Buffering Indicator.
|
||||||
),
|
IgnorePointer(
|
||||||
// // Buffering Indicator.
|
child: Padding(
|
||||||
IgnorePointer(
|
padding: (
|
||||||
child: Padding(
|
// Add padding in fullscreen!
|
||||||
padding: (
|
isFullscreen(context)
|
||||||
// Add padding in fullscreen!
|
? MediaQuery.of(context).padding
|
||||||
isFullscreen(context)
|
: EdgeInsets.zero),
|
||||||
? MediaQuery.of(context).padding
|
child: Column(
|
||||||
: EdgeInsets.zero),
|
children: [
|
||||||
child: Column(
|
Container(
|
||||||
children: [
|
height: buttonBarHeight,
|
||||||
Container(
|
margin: const EdgeInsets.all(0),
|
||||||
height: buttonBarHeight,
|
),
|
||||||
margin: const EdgeInsets.all(0),
|
Expanded(
|
||||||
),
|
child: Center(
|
||||||
Expanded(
|
child: TweenAnimationBuilder<double>(
|
||||||
child: Center(
|
tween: Tween<double>(
|
||||||
child: TweenAnimationBuilder<double>(
|
begin: 0.0,
|
||||||
tween: Tween<double>(
|
end: buffering ? 1.0 : 0.0,
|
||||||
begin: 0.0,
|
),
|
||||||
end: buffering ? 1.0 : 0.0,
|
duration: controlsTransitionDuration,
|
||||||
),
|
builder: (context, value, child) {
|
||||||
duration: controlsTransitionDuration,
|
// Only mount the buffering indicator if the opacity is greater than 0.0.
|
||||||
builder: (context, value, child) {
|
// This has been done to prevent redundant resource usage in [CircularProgressIndicator].
|
||||||
// Only mount the buffering indicator if the opacity is greater than 0.0.
|
if (value > 0.0) {
|
||||||
// This has been done to prevent redundant resource usage in [CircularProgressIndicator].
|
return Opacity(
|
||||||
if (value > 0.0) {
|
opacity: value,
|
||||||
return Opacity(
|
child: child!,
|
||||||
opacity: value,
|
);
|
||||||
child: child!,
|
}
|
||||||
);
|
return const SizedBox.shrink();
|
||||||
}
|
},
|
||||||
return const SizedBox.shrink();
|
child: const CircularProgressIndicator(
|
||||||
},
|
color: Color(0xFFFFFFFF),
|
||||||
child: const CircularProgressIndicator(
|
),
|
||||||
color: Color(0xFFFFFFFF),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Container(
|
||||||
|
height: buttonBarHeight,
|
||||||
|
margin: bottomButtonBarMargin,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Container(
|
),
|
||||||
height: buttonBarHeight,
|
),
|
||||||
margin: bottomButtonBarMargin,
|
// // Volume Indicator.
|
||||||
),
|
IgnorePointer(
|
||||||
],
|
child: ValueListenableBuilder(
|
||||||
|
valueListenable: _volumeIndicator,
|
||||||
|
builder: (context, value, child) => AnimatedOpacity(
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
opacity: value ? 1.0 : 0.0,
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
child: MediaIndicatorBuilder(
|
||||||
|
value: _volumeValue, isVolumeIndicator: true)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// // Brightness Indicator.
|
||||||
|
IgnorePointer(
|
||||||
|
child: ValueListenableBuilder(
|
||||||
|
valueListenable: _brightnessIndicator,
|
||||||
|
builder: (context, value, child) => AnimatedOpacity(
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
opacity: value ? 1.0 : 0.0,
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
child: MediaIndicatorBuilder(
|
||||||
|
value: _brightnessValue, isVolumeIndicator: false)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Seek Indicator.
|
||||||
|
IgnorePointer(
|
||||||
|
child: AnimatedOpacity(
|
||||||
|
duration: controlsTransitionDuration,
|
||||||
|
opacity: showSwipeDuration ? 1 : 0,
|
||||||
|
child: seekIndicatorTextWidget(
|
||||||
|
Duration(seconds: swipeDuration),
|
||||||
|
widget.videoController.player.state.position)),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
// // Volume Indicator.
|
|
||||||
IgnorePointer(
|
|
||||||
child: ValueListenableBuilder(
|
|
||||||
valueListenable: _volumeIndicator,
|
|
||||||
builder: (context, value, child) => AnimatedOpacity(
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
opacity: value ? 1.0 : 0.0,
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
child: MediaIndicatorBuilder(
|
|
||||||
value: _volumeValue, isVolumeIndicator: true)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// // Brightness Indicator.
|
|
||||||
IgnorePointer(
|
|
||||||
child: ValueListenableBuilder(
|
|
||||||
valueListenable: _brightnessIndicator,
|
|
||||||
builder: (context, value, child) => AnimatedOpacity(
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
opacity: value ? 1.0 : 0.0,
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
child: MediaIndicatorBuilder(
|
|
||||||
value: _brightnessValue, isVolumeIndicator: false)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Seek Indicator.
|
|
||||||
IgnorePointer(
|
|
||||||
child: AnimatedOpacity(
|
|
||||||
duration: controlsTransitionDuration,
|
|
||||||
opacity: showSwipeDuration ? 1 : 0,
|
|
||||||
child: seekIndicatorTextWidget(Duration(seconds: swipeDuration),
|
|
||||||
widget.videoController.player.state.position)),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Double-Tap Seek Button(s):
|
// Double-Tap Seek Button(s):
|
||||||
if (_mountSeekBackwardButton || _mountSeekForwardButton)
|
if (_mountSeekBackwardButton || _mountSeekForwardButton)
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _mountSeekBackwardButton
|
child: _mountSeekBackwardButton
|
||||||
? TweenAnimationBuilder<double>(
|
? TweenAnimationBuilder<double>(
|
||||||
tween: Tween<double>(
|
tween: Tween<double>(
|
||||||
begin: 0.0,
|
begin: 0.0,
|
||||||
end: _hideSeekBackwardButton ? 0.0 : 1.0,
|
end: _hideSeekBackwardButton ? 0.0 : 1.0,
|
||||||
),
|
),
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
builder: (context, value, child) => Opacity(
|
builder: (context, value, child) => Opacity(
|
||||||
opacity: value,
|
opacity: value,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
onEnd: () {
|
onEnd: () {
|
||||||
if (_hideSeekBackwardButton) {
|
if (_hideSeekBackwardButton) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_hideSeekBackwardButton = false;
|
_hideSeekBackwardButton = false;
|
||||||
_mountSeekBackwardButton = false;
|
_mountSeekBackwardButton = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
|
||||||
child: _BackwardSeekIndicator(
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
_seekBarDeltaValueNotifier = widget
|
|
||||||
.videoController
|
|
||||||
.player
|
|
||||||
.state
|
|
||||||
.position -
|
|
||||||
value;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
onSubmitted: (value) {
|
child: _BackwardSeekIndicator(
|
||||||
setState(() {
|
onChanged: (value) {
|
||||||
_hideSeekBackwardButton = true;
|
setState(() {
|
||||||
});
|
_seekBarDeltaValueNotifier = widget
|
||||||
var result = widget.videoController.player
|
.videoController
|
||||||
.state.position -
|
.player
|
||||||
value;
|
.state
|
||||||
result = result.clamp(
|
.position -
|
||||||
Duration.zero,
|
value;
|
||||||
widget
|
});
|
||||||
.videoController.player.state.duration,
|
},
|
||||||
);
|
onSubmitted: (value) {
|
||||||
widget.videoController.player.seek(result);
|
setState(() {
|
||||||
|
_hideSeekBackwardButton = true;
|
||||||
|
});
|
||||||
|
var result = widget.videoController.player
|
||||||
|
.state.position -
|
||||||
|
value;
|
||||||
|
result = result.clamp(
|
||||||
|
Duration.zero,
|
||||||
|
widget.videoController.player.state
|
||||||
|
.duration,
|
||||||
|
);
|
||||||
|
widget.videoController.player
|
||||||
|
.seek(result);
|
||||||
|
},
|
||||||
|
skipDuration: skipDuration),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: _mountSeekForwardButton
|
||||||
|
? TweenAnimationBuilder<double>(
|
||||||
|
tween: Tween<double>(
|
||||||
|
begin: 0.0,
|
||||||
|
end: _hideSeekForwardButton ? 0.0 : 1.0,
|
||||||
|
),
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
builder: (context, value, child) => Opacity(
|
||||||
|
opacity: value,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
onEnd: () {
|
||||||
|
if (_hideSeekForwardButton) {
|
||||||
|
setState(() {
|
||||||
|
_hideSeekForwardButton = false;
|
||||||
|
_mountSeekForwardButton = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
skipDuration: skipDuration),
|
child: _ForwardSeekIndicator(
|
||||||
)
|
onChanged: (value) {
|
||||||
: const SizedBox(),
|
setState(() {
|
||||||
|
_seekBarDeltaValueNotifier = widget
|
||||||
|
.videoController
|
||||||
|
.player
|
||||||
|
.state
|
||||||
|
.position +
|
||||||
|
value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onSubmitted: (value) {
|
||||||
|
setState(() {
|
||||||
|
_hideSeekForwardButton = true;
|
||||||
|
});
|
||||||
|
var result = widget.videoController.player
|
||||||
|
.state.position +
|
||||||
|
value;
|
||||||
|
result = result.clamp(
|
||||||
|
Duration.zero,
|
||||||
|
widget.videoController.player.state
|
||||||
|
.duration,
|
||||||
|
);
|
||||||
|
widget.videoController.player
|
||||||
|
.seek(result);
|
||||||
|
},
|
||||||
|
skipDuration: skipDuration),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: _mountSeekForwardButton
|
],
|
||||||
? TweenAnimationBuilder<double>(
|
),
|
||||||
tween: Tween<double>(
|
),
|
||||||
begin: 0.0,
|
],
|
||||||
end: _hideSeekForwardButton ? 0.0 : 1.0,
|
|
||||||
),
|
|
||||||
duration: const Duration(milliseconds: 200),
|
|
||||||
builder: (context, value, child) => Opacity(
|
|
||||||
opacity: value,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
onEnd: () {
|
|
||||||
if (_hideSeekForwardButton) {
|
|
||||||
setState(() {
|
|
||||||
_hideSeekForwardButton = false;
|
|
||||||
_mountSeekForwardButton = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: _ForwardSeekIndicator(
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
_seekBarDeltaValueNotifier = widget
|
|
||||||
.videoController
|
|
||||||
.player
|
|
||||||
.state
|
|
||||||
.position +
|
|
||||||
value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onSubmitted: (value) {
|
|
||||||
setState(() {
|
|
||||||
_hideSeekForwardButton = true;
|
|
||||||
});
|
|
||||||
var result = widget.videoController.player
|
|
||||||
.state.position +
|
|
||||||
value;
|
|
||||||
result = result.clamp(
|
|
||||||
Duration.zero,
|
|
||||||
widget
|
|
||||||
.videoController.player.state.duration,
|
|
||||||
);
|
|
||||||
widget.videoController.player.seek(result);
|
|
||||||
},
|
|
||||||
skipDuration: skipDuration),
|
|
||||||
)
|
|
||||||
: const SizedBox(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ class ColorSettingWidget extends ConsumerStatefulWidget {
|
||||||
class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
String selector = "text";
|
String selector = "text";
|
||||||
|
|
||||||
Widget button(String text, Color color) {
|
Widget button(String text, String value, Color color) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
|
|
@ -154,7 +154,7 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
shadowColor: Colors.transparent),
|
shadowColor: Colors.transparent),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
selector = text.toLowerCase();
|
selector = value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -175,9 +175,7 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
Text("#${color.hexCode}", style: TextStyle(color: context.textColor)),
|
Text("#${color.hexCode}", style: TextStyle(color: context.textColor)),
|
||||||
Icon(
|
Icon(
|
||||||
Icons.arrow_drop_down,
|
Icons.arrow_drop_down,
|
||||||
color: selector != text.toLowerCase()
|
color: selector != value ? Colors.transparent : context.textColor,
|
||||||
? Colors.transparent
|
|
||||||
: context.textColor,
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -218,12 +216,15 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(flex: 3, child: button(context.l10n.text, textColor)),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3, child: button(context.l10n.border, borderColor)),
|
flex: 3, child: button(context.l10n.text, "text", textColor)),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: button(context.l10n.background, backgroundColor)),
|
child: button(context.l10n.border, "border", borderColor)),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: button(
|
||||||
|
context.l10n.background, "backgroud", backgroundColor)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ import 'package:mangayomi/utils/date.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
Widget btnToShowChapterListDialog(
|
Widget btnToShowChapterListDialog(
|
||||||
BuildContext context, String title, Chapter chapter) {
|
BuildContext context, String title, Chapter chapter,
|
||||||
|
{void Function(bool)? onChanged}) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
showDialog(
|
onChanged?.call(false);
|
||||||
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
|
|
@ -22,6 +24,7 @@ Widget btnToShowChapterListDialog(
|
||||||
child: ChapterListWidget(chapter: chapter)),
|
child: ChapterListWidget(chapter: chapter)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
onChanged?.call(true);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.format_list_numbered_outlined));
|
icon: const Icon(Icons.format_list_numbered_outlined));
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +63,6 @@ class _ChapterListWidgetState extends State<ChapterListWidget> {
|
||||||
return DraggableScrollbarWidget(
|
return DraggableScrollbarWidget(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
itemCount: chapterList.length,
|
itemCount: chapterList.length,
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,8 @@ class AppearanceScreen extends ConsumerWidget {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 12, horizontal: 8),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -209,7 +210,6 @@ class AppearanceScreen extends ConsumerWidget {
|
||||||
controller: controller,
|
controller: controller,
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
shrinkWrap: true,
|
|
||||||
itemCount: values.length,
|
itemCount: values.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final value = values[index];
|
final value = values[index];
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <desktop_webview_window/desktop_webview_window_plugin.h>
|
|
||||||
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
#include <isar_flutter_libs/isar_flutter_libs_plugin.h>
|
||||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin.h>
|
#include <media_kit_video/media_kit_video_plugin.h>
|
||||||
|
|
@ -16,9 +15,6 @@
|
||||||
#include <window_to_front/window_to_front_plugin.h>
|
#include <window_to_front/window_to_front_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) desktop_webview_window_registrar =
|
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewWindowPlugin");
|
|
||||||
desktop_webview_window_plugin_register_with_registrar(desktop_webview_window_registrar);
|
|
||||||
g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar =
|
g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin");
|
||||||
isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar);
|
isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
desktop_webview_window
|
|
||||||
isar_flutter_libs
|
isar_flutter_libs
|
||||||
media_kit_libs_linux
|
media_kit_libs_linux
|
||||||
media_kit_video
|
media_kit_video
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue