Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UI directionality in RTL apps #91

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/src/controllers/pod_getx_video_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ part 'pod_video_controller.dart';
part 'pod_video_quality_controller.dart';

class PodGetXVideoController extends _PodGesturesController {


///main videoplayer controller
VideoPlayerController? get videoCtr => _videoCtr;

Expand All @@ -36,6 +38,9 @@ class PodGetXVideoController extends _PodGesturesController {
///
Duration get videoPosition => _videoPosition;

///Core video player ui directionality
TextDirection uiDirectionality = TextDirection.ltr;

bool controllerInitialized = false;
late PodPlayerConfig podPlayerConfig;
late PlayVideoFrom playVideoFrom;
Expand Down Expand Up @@ -299,4 +304,9 @@ class PodGetXVideoController extends _PodGesturesController {
keyboardFocusWeb?.addListener(keyboadListner);
await videoInit();
}

@override
Future<void> changeVideoQuality(int? quality, {PlayVideoFrom? playVideoFromParam}) async {
return super.changeVideoQuality(quality, playVideoFromParam: playVideoFromParam ?? playVideoFrom);
}
}
16 changes: 11 additions & 5 deletions lib/src/controllers/pod_video_quality_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ class _PodVideoQualityController extends _PodVideoController {
) {
final _urls = urls;

///has issues with 240p
_urls?.removeWhere((element) => element.quality == 240);

///has issues with 144p in web
if (kIsWeb) {
_urls?.removeWhere((element) => element.quality == 144);
Expand Down Expand Up @@ -106,10 +103,13 @@ class _PodVideoQualityController extends _PodVideoController {
[];
}

Future<void> changeVideoQuality(int? quality) async {
Future<void> changeVideoQuality(int? quality, {PlayVideoFrom? playVideoFromParam}) async {
if (vimeoOrVideoUrls.isEmpty) {
throw Exception('videoQuality cannot be empty');
}
if (playVideoFromParam == null) {
throw Exception('playVideoFrom cannot be null');
}
if (vimeoPlayingVideoQuality != quality) {
_videoQualityUrl = vimeoOrVideoUrls
.where((element) => element.quality == quality)
Expand All @@ -121,7 +121,13 @@ class _PodVideoQualityController extends _PodVideoController {
podVideoStateChanger(PodVideoState.paused);
podVideoStateChanger(PodVideoState.loading);
playingVideoUrl = _videoQualityUrl;
_videoCtr = VideoPlayerController.network(_videoQualityUrl);
_videoCtr = VideoPlayerController.network(
_videoQualityUrl,
videoPlayerOptions: playVideoFromParam.videoPlayerOptions,
closedCaptionFile: playVideoFromParam.closedCaptionFile,
formatHint: playVideoFromParam.formatHint,
httpHeaders: playVideoFromParam.httpHeaders,
);
await _videoCtr?.initialize();
_videoDuration = _videoCtr?.value.duration ?? Duration.zero;
_videoCtr?.addListener(videoListner);
Expand Down
5 changes: 4 additions & 1 deletion lib/src/pod_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PodVideoPlayer extends StatefulWidget {
final Widget? videoTitle;
final Color? backgroundColor;
final DecorationImage? videoThumbnail;
final TextDirection uiDirectionality;

/// Optional callback, fired when full screen mode toggles.
///
Expand Down Expand Up @@ -73,6 +74,7 @@ class PodVideoPlayer extends StatefulWidget {
this.videoThumbnail,
this.onToggleFullScreen,
this.onLoading,
this.uiDirectionality = TextDirection.ltr,
}) : super(key: key) {
addToUiController();
}
Expand All @@ -91,7 +93,8 @@ class PodVideoPlayer extends StatefulWidget {
..videoTitle = videoTitle
..onToggleFullScreen = onToggleFullScreen
..onLoading = onLoading
..videoThumbnail = videoThumbnail;
..videoThumbnail = videoThumbnail
..uiDirectionality = uiDirectionality;
}

@override
Expand Down
238 changes: 118 additions & 120 deletions lib/src/widgets/core/pod_core_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,142 +15,140 @@ class _PodCoreVideoPlayer extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _podCtr = Get.find<PodGetXVideoController>(tag: tag);
return Builder(
builder: (_ctrx) {
return RawKeyboardListener(
autofocus: true,
focusNode:
(_podCtr.isFullScreen ? FocusNode() : _podCtr.keyboardFocusWeb) ??
FocusNode(),
onKey: (value) => _podCtr.onKeyBoardEvents(
event: value,
appContext: _ctrx,
tag: tag,
),
child: Stack(
fit: StackFit.expand,
children: [
Center(
child: AspectRatio(
aspectRatio: videoAspectRatio,
child: VideoPlayer(videoPlayerCtr),
return Directionality(
textDirection: _podCtr.uiDirectionality,
child: Builder(
builder: (_ctrx) {
return RawKeyboardListener(
autofocus: true,
focusNode: (_podCtr.isFullScreen ? FocusNode() : _podCtr.keyboardFocusWeb) ?? FocusNode(),
onKey: (value) => _podCtr.onKeyBoardEvents(
event: value,
appContext: _ctrx,
tag: tag,
),
child: Stack(
fit: StackFit.expand,
children: [
Center(
child: AspectRatio(
aspectRatio: videoAspectRatio,
child: VideoPlayer(videoPlayerCtr),
),
),
),
GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'podVideoState',
builder: (_) => GetBuilder<PodGetXVideoController>(
GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'video-progress',
builder: (_podCtr) {
if (_podCtr.videoThumbnail == null) {
return const SizedBox();
}
id: 'podVideoState',
builder: (_) => GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'video-progress',
builder: (_podCtr) {
if (_podCtr.videoThumbnail == null) {
return const SizedBox();
}

if (_podCtr.podVideoState == PodVideoState.paused &&
_podCtr.videoPosition == Duration.zero) {
return SizedBox.expand(
child: TweenAnimationBuilder<double>(
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
tween: Tween<double>(begin: 0.7, end: 1),
duration: const Duration(milliseconds: 400),
child: DecoratedBox(
decoration: BoxDecoration(
image: _podCtr.videoThumbnail,
if (_podCtr.podVideoState == PodVideoState.paused && _podCtr.videoPosition == Duration.zero) {
return SizedBox.expand(
child: TweenAnimationBuilder<double>(
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
tween: Tween<double>(begin: 0.7, end: 1),
duration: const Duration(milliseconds: 400),
child: DecoratedBox(
decoration: BoxDecoration(
image: _podCtr.videoThumbnail,
),
),
),
),
);
}
return const SizedBox();
},
),
),
_VideoOverlays(tag: tag),
IgnorePointer(
child: GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'podVideoState',
builder: (_podCtr) {
final loadingWidget = _podCtr.onLoading?.call(context) ??
const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.transparent,
color: Colors.white,
strokeWidth: 2,
),
);

if (kIsWeb) {
switch (_podCtr.podVideoState) {
case PodVideoState.loading:
return loadingWidget;
case PodVideoState.paused:
return const Center(
child: Icon(
Icons.play_arrow,
size: 45,
}
return const SizedBox();
},
),
),
_VideoOverlays(tag: tag),
IgnorePointer(
child: GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'podVideoState',
builder: (_podCtr) {
final loadingWidget = _podCtr.onLoading?.call(context) ??
const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.transparent,
color: Colors.white,
strokeWidth: 2,
),
);
case PodVideoState.playing:
return Center(
child: TweenAnimationBuilder<double>(
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
tween: Tween<double>(begin: 1, end: 0),
duration: const Duration(seconds: 1),
child: const Icon(
Icons.pause,

if (kIsWeb) {
switch (_podCtr.podVideoState) {
case PodVideoState.loading:
return loadingWidget;
case PodVideoState.paused:
return const Center(
child: Icon(
Icons.play_arrow,
size: 45,
color: Colors.white,
),
),
);
case PodVideoState.error:
return const SizedBox();
}
} else {
if (_podCtr.podVideoState == PodVideoState.loading) {
return loadingWidget;
);
case PodVideoState.playing:
return Center(
child: TweenAnimationBuilder<double>(
builder: (context, value, child) => Opacity(
opacity: value,
child: child,
),
tween: Tween<double>(begin: 1, end: 0),
duration: const Duration(seconds: 1),
child: const Icon(
Icons.pause,
size: 45,
color: Colors.white,
),
),
);
case PodVideoState.error:
return const SizedBox();
}
} else {
if (_podCtr.podVideoState == PodVideoState.loading) {
return loadingWidget;
}
return const SizedBox();
}
return const SizedBox();
}
},
},
),
),
),
if (!kIsWeb)
GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'full-screen',
builder: (_podCtr) => _podCtr.isFullScreen
? const SizedBox()
: GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'overlay',
builder: (_podCtr) => _podCtr.isOverlayVisible ||
!_podCtr.alwaysShowProgressBar
? const SizedBox()
: Align(
alignment: Alignment.bottomCenter,
child: PodProgressBar(
tag: tag,
if (!kIsWeb)
GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'full-screen',
builder: (_podCtr) => _podCtr.isFullScreen
? const SizedBox()
: GetBuilder<PodGetXVideoController>(
tag: tag,
id: 'overlay',
builder: (_podCtr) => _podCtr.isOverlayVisible || !_podCtr.alwaysShowProgressBar
? const SizedBox()
: Align(
alignment: Alignment.bottomCenter,
podProgressBarConfig:
_podCtr.podProgressBarConfig,
child: PodProgressBar(
tag: tag,
alignment: Alignment.bottomCenter,
podProgressBarConfig: _podCtr.podProgressBarConfig,
),
),
),
),
),
],
),
);
},
),
),
],
),
);
},
),
);
}
}
3 changes: 1 addition & 2 deletions lib/src/widgets/full_screen_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ class _FullScreenViewState extends State<FullScreenView>
? _PodCoreVideoPlayer(
tag: widget.tag,
videoPlayerCtr: _podCtr.videoCtr!,
videoAspectRatio:
_podCtr.videoCtr?.value.aspectRatio ?? 16 / 9,
videoAspectRatio: 16 / 9,
)
: loadingWidget,
),
Expand Down