mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-10 16:00:28 -07:00
chore: Renaming of Trickplay -> TrickPlay and other cleanups (#130)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
556a33d613
commit
0b7b73134f
9 changed files with 58 additions and 71 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -3,7 +3,8 @@
|
||||||
"ficonsax",
|
"ficonsax",
|
||||||
"jellyfin",
|
"jellyfin",
|
||||||
"Jellyfin",
|
"Jellyfin",
|
||||||
"LTRB"
|
"LTRB",
|
||||||
|
"LTWH"
|
||||||
],
|
],
|
||||||
"dart.flutterSdkPath": ".fvm/versions/3.24.3",
|
"dart.flutterSdkPath": ".fvm/versions/3.24.3",
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ class TrickPlayModel with _$TrickPlayModel {
|
||||||
int get imagesPerTile => tileWidth * tileHeight;
|
int get imagesPerTile => tileWidth * tileHeight;
|
||||||
|
|
||||||
String? getTile(Duration position) {
|
String? getTile(Duration position) {
|
||||||
final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount);
|
final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount - 1);
|
||||||
final int indexOfTile = (currentIndex ~/ imagesPerTile).clamp(0, images.length);
|
final int indexOfTile = (currentIndex ~/ imagesPerTile).clamp(0, (images.length - 1));
|
||||||
return images.elementAtOrNull(indexOfTile);
|
return images.elementAtOrNull(indexOfTile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,7 +32,10 @@ class TrickPlayModel with _$TrickPlayModel {
|
||||||
final int tileIndex = currentIndex % imagesPerTile;
|
final int tileIndex = currentIndex % imagesPerTile;
|
||||||
final int column = tileIndex % tileWidth;
|
final int column = tileIndex % tileWidth;
|
||||||
final int row = tileIndex ~/ tileWidth;
|
final int row = tileIndex ~/ tileWidth;
|
||||||
return Offset((width * column).toDouble(), (height * row).toDouble());
|
return Offset(
|
||||||
|
(width * column).toDouble(),
|
||||||
|
(height * row).toDouble(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, TrickPlayModel> toTrickPlayMap(Map<String, dynamic> map) {
|
static Map<String, TrickPlayModel> toTrickPlayMap(Map<String, dynamic> map) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fladder/models/items/trick_play_model.dart';
|
|
||||||
import 'package:fladder/util/list_extensions.dart';
|
|
||||||
import 'package:fladder/wrappers/media_control_wrapper.dart'
|
|
||||||
if (dart.library.html) 'package:fladder/wrappers/media_control_wrapper_web.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
|
|
||||||
|
|
@ -12,10 +7,15 @@ import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/chapters_model.dart';
|
import 'package:fladder/models/items/chapters_model.dart';
|
||||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||||
import 'package:fladder/models/items/media_streams_model.dart';
|
import 'package:fladder/models/items/media_streams_model.dart';
|
||||||
|
import 'package:fladder/models/items/trick_play_model.dart';
|
||||||
import 'package:fladder/models/playback/playback_model.dart';
|
import 'package:fladder/models/playback/playback_model.dart';
|
||||||
import 'package:fladder/providers/api_provider.dart';
|
import 'package:fladder/providers/api_provider.dart';
|
||||||
import 'package:fladder/providers/video_player_provider.dart';
|
import 'package:fladder/providers/video_player_provider.dart';
|
||||||
import 'package:fladder/util/duration_extensions.dart';
|
import 'package:fladder/util/duration_extensions.dart';
|
||||||
|
import 'package:fladder/util/list_extensions.dart';
|
||||||
|
import 'package:fladder/wrappers/media_control_wrapper.dart'
|
||||||
|
if (dart.library.html) 'package:fladder/wrappers/media_control_wrapper_web.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
class DirectPlaybackModel implements PlaybackModel {
|
class DirectPlaybackModel implements PlaybackModel {
|
||||||
DirectPlaybackModel({
|
DirectPlaybackModel({
|
||||||
|
|
@ -147,13 +147,6 @@ class DirectPlaybackModel implements PlaybackModel {
|
||||||
@override
|
@override
|
||||||
Future<PlaybackModel?> updatePlaybackPosition(Duration position, bool isPlaying, Ref ref) async {
|
Future<PlaybackModel?> updatePlaybackPosition(Duration position, bool isPlaying, Ref ref) async {
|
||||||
final api = ref.read(jellyApiProvider);
|
final api = ref.read(jellyApiProvider);
|
||||||
|
|
||||||
//Check for newly generated scrubImages
|
|
||||||
if (trickPlay == null) {
|
|
||||||
final trickplay = await api.getTrickPlay(item: item, ref: ref);
|
|
||||||
ref.read(playBackModel.notifier).update((state) => copyWith(trickPlay: () => trickplay?.body));
|
|
||||||
}
|
|
||||||
|
|
||||||
await api.sessionsPlayingProgressPost(
|
await api.sessionsPlayingProgressPost(
|
||||||
body: PlaybackProgressInfo(
|
body: PlaybackProgressInfo(
|
||||||
canSeek: true,
|
canSeek: true,
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,6 @@ import 'dart:developer';
|
||||||
|
|
||||||
import 'package:chopper/chopper.dart';
|
import 'package:chopper/chopper.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
|
||||||
import 'package:fladder/models/items/season_model.dart';
|
|
||||||
import 'package:fladder/models/items/series_model.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
|
|
||||||
|
|
@ -12,7 +9,10 @@ import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/chapters_model.dart';
|
import 'package:fladder/models/items/chapters_model.dart';
|
||||||
import 'package:fladder/models/items/episode_model.dart';
|
import 'package:fladder/models/items/episode_model.dart';
|
||||||
|
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||||
import 'package:fladder/models/items/media_streams_model.dart';
|
import 'package:fladder/models/items/media_streams_model.dart';
|
||||||
|
import 'package:fladder/models/items/season_model.dart';
|
||||||
|
import 'package:fladder/models/items/series_model.dart';
|
||||||
import 'package:fladder/models/items/trick_play_model.dart';
|
import 'package:fladder/models/items/trick_play_model.dart';
|
||||||
import 'package:fladder/models/playback/direct_playback_model.dart';
|
import 'package:fladder/models/playback/direct_playback_model.dart';
|
||||||
import 'package:fladder/models/playback/offline_playback_model.dart';
|
import 'package:fladder/models/playback/offline_playback_model.dart';
|
||||||
|
|
@ -127,8 +127,8 @@ class PlaybackModelHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<EpisodeModel?> getNextUpEpisode(String itemId) async {
|
Future<EpisodeModel?> getNextUpEpisode(String itemId) async {
|
||||||
final responnse = await api.showsNextUpGet(parentId: itemId, fields: [ItemFields.overview]);
|
final response = await api.showsNextUpGet(parentId: itemId, fields: [ItemFields.overview]);
|
||||||
final episode = responnse.body?.items?.firstOrNull;
|
final episode = response.body?.items?.firstOrNull;
|
||||||
if (episode == null) {
|
if (episode == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fladder/models/items/trick_play_model.dart';
|
|
||||||
import 'package:fladder/util/list_extensions.dart';
|
|
||||||
import 'package:fladder/wrappers/media_control_wrapper.dart'
|
|
||||||
if (dart.library.html) 'package:fladder/wrappers/media_control_wrapper_web.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
|
|
||||||
|
|
@ -12,10 +7,15 @@ import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/chapters_model.dart';
|
import 'package:fladder/models/items/chapters_model.dart';
|
||||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||||
import 'package:fladder/models/items/media_streams_model.dart';
|
import 'package:fladder/models/items/media_streams_model.dart';
|
||||||
|
import 'package:fladder/models/items/trick_play_model.dart';
|
||||||
import 'package:fladder/models/playback/playback_model.dart';
|
import 'package:fladder/models/playback/playback_model.dart';
|
||||||
import 'package:fladder/providers/api_provider.dart';
|
import 'package:fladder/providers/api_provider.dart';
|
||||||
import 'package:fladder/providers/video_player_provider.dart';
|
import 'package:fladder/providers/video_player_provider.dart';
|
||||||
import 'package:fladder/util/duration_extensions.dart';
|
import 'package:fladder/util/duration_extensions.dart';
|
||||||
|
import 'package:fladder/util/list_extensions.dart';
|
||||||
|
import 'package:fladder/wrappers/media_control_wrapper.dart'
|
||||||
|
if (dart.library.html) 'package:fladder/wrappers/media_control_wrapper_web.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
class TranscodePlaybackModel implements PlaybackModel {
|
class TranscodePlaybackModel implements PlaybackModel {
|
||||||
TranscodePlaybackModel({
|
TranscodePlaybackModel({
|
||||||
|
|
@ -148,13 +148,6 @@ class TranscodePlaybackModel implements PlaybackModel {
|
||||||
@override
|
@override
|
||||||
Future<PlaybackModel?> updatePlaybackPosition(Duration position, bool isPlaying, Ref ref) async {
|
Future<PlaybackModel?> updatePlaybackPosition(Duration position, bool isPlaying, Ref ref) async {
|
||||||
final api = ref.read(jellyApiProvider);
|
final api = ref.read(jellyApiProvider);
|
||||||
|
|
||||||
//Check for newly generated scrubImages
|
|
||||||
if (trickPlay == null) {
|
|
||||||
final trickplay = await api.getTrickPlay(item: item, ref: ref);
|
|
||||||
ref.read(playBackModel.notifier).update((state) => copyWith(trickPlay: () => trickplay?.bodyOrThrow));
|
|
||||||
}
|
|
||||||
|
|
||||||
await api.sessionsPlayingProgressPost(
|
await api.sessionsPlayingProgressPost(
|
||||||
body: PlaybackProgressInfo(
|
body: PlaybackProgressInfo(
|
||||||
canSeek: true,
|
canSeek: true,
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,21 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:chopper/chopper.dart';
|
import 'package:chopper/chopper.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fladder/jellyfin/enum_models.dart';
|
|
||||||
import 'package:fladder/models/credentials_model.dart';
|
|
||||||
import 'package:fladder/models/items/intro_skip_model.dart';
|
|
||||||
import 'package:fladder/models/items/trick_play_model.dart';
|
|
||||||
import 'package:fladder/providers/image_provider.dart';
|
|
||||||
import 'package:fladder/util/duration_extensions.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
|
import 'package:fladder/jellyfin/enum_models.dart';
|
||||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||||
import 'package:fladder/models/account_model.dart';
|
import 'package:fladder/models/account_model.dart';
|
||||||
|
import 'package:fladder/models/credentials_model.dart';
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
|
import 'package:fladder/models/items/intro_skip_model.dart';
|
||||||
|
import 'package:fladder/models/items/trick_play_model.dart';
|
||||||
import 'package:fladder/providers/api_provider.dart';
|
import 'package:fladder/providers/api_provider.dart';
|
||||||
|
import 'package:fladder/providers/image_provider.dart';
|
||||||
import 'package:fladder/providers/user_provider.dart';
|
import 'package:fladder/providers/user_provider.dart';
|
||||||
|
import 'package:fladder/util/duration_extensions.dart';
|
||||||
import 'package:fladder/util/jellyfin_extension.dart';
|
import 'package:fladder/util/jellyfin_extension.dart';
|
||||||
import 'package:path/path.dart';
|
|
||||||
|
|
||||||
final jellyServiceProvider = StateProvider<JellyService>(
|
final jellyServiceProvider = StateProvider<JellyService>(
|
||||||
(ref) => JellyService(
|
(ref) => JellyService(
|
||||||
|
|
@ -913,8 +913,7 @@ class JellyService {
|
||||||
|
|
||||||
if (server == null) return null;
|
if (server == null) return null;
|
||||||
|
|
||||||
final lines = response.bodyString.split('\n')
|
final lines = response.bodyString.split('\n')..removeWhere((element) => element.startsWith('#'));
|
||||||
..removeWhere((element) => element.startsWith('#') || !element.contains('.jpg'));
|
|
||||||
return response.copyWith(
|
return response.copyWith(
|
||||||
body: trickPlayModel.copyWith(
|
body: trickPlayModel.copyWith(
|
||||||
images: lines
|
images: lines
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import 'package:fladder/util/list_padding.dart';
|
||||||
import 'package:fladder/util/string_extensions.dart';
|
import 'package:fladder/util/string_extensions.dart';
|
||||||
import 'package:fladder/widgets/gapped_container_shape.dart';
|
import 'package:fladder/widgets/gapped_container_shape.dart';
|
||||||
import 'package:fladder/widgets/shared/fladder_slider.dart';
|
import 'package:fladder/widgets/shared/fladder_slider.dart';
|
||||||
import 'package:fladder/widgets/shared/trickplay_image.dart';
|
import 'package:fladder/widgets/shared/trick_play_image.dart';
|
||||||
|
|
||||||
class ChapterProgressSlider extends ConsumerStatefulWidget {
|
class VideoProgressBar extends ConsumerStatefulWidget {
|
||||||
final Function(bool value) wasPlayingChanged;
|
final Function(bool value) wasPlayingChanged;
|
||||||
final bool wasPlaying;
|
final bool wasPlaying;
|
||||||
final VoidCallback timerReset;
|
final VoidCallback timerReset;
|
||||||
|
|
@ -24,7 +24,7 @@ class ChapterProgressSlider extends ConsumerStatefulWidget {
|
||||||
final bool buffering;
|
final bool buffering;
|
||||||
final Duration buffer;
|
final Duration buffer;
|
||||||
final Function(Duration duration) onPositionChanged;
|
final Function(Duration duration) onPositionChanged;
|
||||||
const ChapterProgressSlider({
|
const VideoProgressBar({
|
||||||
required this.wasPlayingChanged,
|
required this.wasPlayingChanged,
|
||||||
required this.wasPlaying,
|
required this.wasPlaying,
|
||||||
required this.timerReset,
|
required this.timerReset,
|
||||||
|
|
@ -40,7 +40,7 @@ class ChapterProgressSlider extends ConsumerStatefulWidget {
|
||||||
ConsumerState<ConsumerStatefulWidget> createState() => _ChapterProgressSliderState();
|
ConsumerState<ConsumerStatefulWidget> createState() => _ChapterProgressSliderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
class _ChapterProgressSliderState extends ConsumerState<VideoProgressBar> {
|
||||||
bool onHoverStart = false;
|
bool onHoverStart = false;
|
||||||
bool onDragStart = false;
|
bool onDragStart = false;
|
||||||
double _chapterPosition = 0.0;
|
double _chapterPosition = 0.0;
|
||||||
|
|
@ -54,12 +54,12 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
final isVisible = (onDragStart ? true : onHoverStart);
|
final isVisible = (onDragStart ? true : onHoverStart);
|
||||||
final player = ref.watch(videoPlayerProvider);
|
final player = ref.watch(videoPlayerProvider);
|
||||||
final position = onDragStart ? currentDuration : widget.position;
|
final position = onDragStart ? currentDuration : widget.position;
|
||||||
final IntroOutSkipModel? introOutro = ref.read(playBackModel.select((value) => value?.introSkipModel));
|
final IntroOutSkipModel? introCreditsModel = ref.read(playBackModel.select((value) => value?.introSkipModel));
|
||||||
final relativeFraction = position.inMilliseconds / widget.duration.inMilliseconds;
|
final relativeFraction = position.inMilliseconds / widget.duration.inMilliseconds;
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final sliderHeight = SliderTheme.of(context).trackHeight ?? (constraints.maxHeight / 3);
|
final sliderHeight = SliderTheme.of(context).trackHeight ?? (constraints.maxHeight / 3);
|
||||||
final bufferWidth = calculateFracionWidth(constraints, widget.buffer);
|
final bufferWidth = calculateFractionWidth(constraints, widget.buffer);
|
||||||
final bufferFraction = relativeFraction / (bufferWidth / constraints.maxWidth);
|
final bufferFraction = relativeFraction / (bufferWidth / constraints.maxWidth);
|
||||||
return Stack(
|
return Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
|
|
@ -138,10 +138,10 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (introOutro?.intro?.start != null && introOutro?.intro?.end != null)
|
if (introCreditsModel?.intro?.start != null && introCreditsModel?.intro?.end != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
left: calculateStartOffset(constraints, introOutro!.intro!.start),
|
left: calculateStartOffset(constraints, introCreditsModel!.intro!.start),
|
||||||
right: calculateRightOffset(constraints, introOutro.intro!.end),
|
right: calculateRightOffset(constraints, introCreditsModel.intro!.end),
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 6,
|
height: 6,
|
||||||
|
|
@ -153,10 +153,10 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (introOutro?.credits?.start != null && introOutro?.credits?.end != null)
|
if (introCreditsModel?.credits?.start != null && introCreditsModel?.credits?.end != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
left: calculateStartOffset(constraints, introOutro!.credits!.start),
|
left: calculateStartOffset(constraints, introCreditsModel!.credits!.start),
|
||||||
right: calculateRightOffset(constraints, introOutro.credits!.end),
|
right: calculateRightOffset(constraints, introCreditsModel.credits!.end),
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 6,
|
height: 6,
|
||||||
|
|
@ -259,7 +259,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
double calculateFracionWidth(BoxConstraints constraints, Duration incoming) {
|
double calculateFractionWidth(BoxConstraints constraints, Duration incoming) {
|
||||||
return (constraints.maxWidth * (incoming.inSeconds / widget.duration.inSeconds)).clamp(0, constraints.maxWidth);
|
return (constraints.maxWidth * (incoming.inSeconds / widget.duration.inSeconds)).clamp(0, constraints.maxWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,7 +320,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
: AspectRatio(
|
: AspectRatio(
|
||||||
aspectRatio: trickPlay.width.toDouble() / trickPlay.height.toDouble(),
|
aspectRatio: trickPlay.width.toDouble() / trickPlay.height.toDouble(),
|
||||||
child: TrickplayImage(
|
child: TrickPlayImage(
|
||||||
trickPlay,
|
trickPlay,
|
||||||
position: currentDuration,
|
position: currentDuration,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 25,
|
height: 25,
|
||||||
child: ChapterProgressSlider(
|
child: VideoProgressBar(
|
||||||
wasPlayingChanged: (value) => wasPlaying = value,
|
wasPlayingChanged: (value) => wasPlaying = value,
|
||||||
wasPlaying: wasPlaying,
|
wasPlaying: wasPlaying,
|
||||||
duration: mediaPlayback.duration,
|
duration: mediaPlayback.duration,
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,19 @@ import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'package:fladder/models/items/trick_play_model.dart';
|
import 'package:fladder/models/items/trick_play_model.dart';
|
||||||
|
|
||||||
class TrickplayImage extends ConsumerStatefulWidget {
|
class TrickPlayImage extends ConsumerStatefulWidget {
|
||||||
final TrickPlayModel trickplay;
|
final TrickPlayModel trickPlay;
|
||||||
final Duration? position;
|
final Duration? position;
|
||||||
|
|
||||||
const TrickplayImage(this.trickplay, {this.position, super.key});
|
const TrickPlayImage(this.trickPlay, {this.position, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<ConsumerStatefulWidget> createState() => _TrickplayImageState();
|
ConsumerState<ConsumerStatefulWidget> createState() => _TrickPlayImageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TrickplayImageState extends ConsumerState<TrickplayImage> {
|
class _TrickPlayImageState extends ConsumerState<TrickPlayImage> {
|
||||||
ui.Image? image;
|
ui.Image? image;
|
||||||
late TrickPlayModel model = widget.trickplay;
|
late TrickPlayModel model = widget.trickPlay;
|
||||||
late Duration time = widget.position ?? Duration.zero;
|
late Duration time = widget.position ?? Duration.zero;
|
||||||
late Offset currentOffset = const Offset(0, 0);
|
late Offset currentOffset = const Offset(0, 0);
|
||||||
String? currentUrl;
|
String? currentUrl;
|
||||||
|
|
@ -34,11 +34,11 @@ class _TrickplayImageState extends ConsumerState<TrickplayImage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant TrickplayImage oldWidget) {
|
void didUpdateWidget(covariant TrickPlayImage oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
if (oldWidget.position?.inMilliseconds != widget.position?.inMilliseconds) {
|
if (oldWidget.position?.inMilliseconds != widget.position?.inMilliseconds) {
|
||||||
time = widget.position ?? Duration.zero;
|
time = widget.position ?? Duration.zero;
|
||||||
model = widget.trickplay;
|
model = widget.trickPlay;
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,11 +48,9 @@ class _TrickplayImageState extends ConsumerState<TrickplayImage> {
|
||||||
return Container(
|
return Container(
|
||||||
child: image != null
|
child: image != null
|
||||||
? CustomPaint(
|
? CustomPaint(
|
||||||
painter: TilledPainter(image!, currentOffset, widget.trickplay),
|
painter: _TrickPlayPainter(image!, currentOffset, widget.trickPlay),
|
||||||
)
|
)
|
||||||
: Container(
|
: const SizedBox.shrink(),
|
||||||
color: Colors.purple,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,12 +94,12 @@ class _TrickplayImageState extends ConsumerState<TrickplayImage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TilledPainter extends CustomPainter {
|
class _TrickPlayPainter extends CustomPainter {
|
||||||
final ui.Image image;
|
final ui.Image image;
|
||||||
final Offset offset;
|
final Offset offset;
|
||||||
final TrickPlayModel model;
|
final TrickPlayModel model;
|
||||||
|
|
||||||
TilledPainter(this.image, this.offset, this.model);
|
_TrickPlayPainter(this.image, this.offset, this.model);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
Loading…
Add table
Add a link
Reference in a new issue