Skip to content

Fix zoomAndPan not having an effect #920

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

Merged
merged 7 commits into from
Jul 1, 2025
Merged
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
56 changes: 44 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ name: CI

on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- master
types: [opened, synchronize, reopened]
paths-ignore:
- '**.md'
workflow_dispatch:
Expand All @@ -15,24 +11,56 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
# Define global environment variables for the workflow
# The version of Flutter to use should use the minimum Dart SDK version supported by the package,
# refer to https://docs.flutter.dev/development/tools/sdk/releases.
# Note: The version below should be manually updated to the latest second most recent version
# after a new stable version comes out.
# Current minimum is set to Flutter 3.29. Make this the new minimum once the next
# stable version is released
FLUTTER_VERSION_MINIMUM_DEFAULT: "3.29.3"
FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT: "3.x"

jobs:
setup_matrix:
name: Determine Flutter Test Versions # Name for the setup_matrix job
runs-on: ubuntu-latest
outputs:
flutter_versions_json: ${{ steps.set_versions.outputs.versions_json }}
flutter_version_minimum: ${{ steps.set_versions.outputs.version_min }}
steps:
- name: Determine Flutter versions
id: set_versions
run: |
MIN_VERSION_VALUE="${{ env.FLUTTER_VERSION_MINIMUM_DEFAULT }}"
LATEST_VERSION_VALUE="${{ env.FLUTTER_VERSION_LATEST_STABLE_CHANNEL_DEFAULT }}"

echo "version_min=$MIN_VERSION_VALUE" >> $GITHUB_OUTPUT
echo "version_latest=$LATEST_VERSION_VALUE" >> $GITHUB_OUTPUT

VERSIONS_JSON=$(jq -c --null-input '$ARGS.positional' --args "$MIN_VERSION_VALUE" "$LATEST_VERSION_VALUE")
echo "versions_json=$VERSIONS_JSON" >> $GITHUB_OUTPUT

echo "Determined Min Version: $MIN_VERSION_VALUE"
echo "Determined Latest Version: $LATEST_VERSION_VALUE"
echo "Determined JSON: $VERSIONS_JSON"

# Does a sanity check that packages at least pass analysis on the N-1
# versions of Flutter stable if the package claims to support that version.
# This is to minimize accidentally making changes that break old versions
# (which we don't commit to supporting, but don't want to actively break)
# without updating the constraints.
lint_and_build:
name: Flutter Version ${{ matrix.flutter-version }} Lint and Build.
needs: setup_matrix # Ensures this job runs after setup_matrix completes
runs-on: ubuntu-latest
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
FLUTTER_VERSION_MINIMUM: ${{ needs.setup_matrix.outputs.flutter_version_minimum }}
strategy:
matrix:
flutter-version:
# The version of Flutter to use should use the minimum Dart SDK version supported by the package,
# refer to https://docs.flutter.dev/development/tools/sdk/releases.
# Note: The version below should be manually updated to the latest second most recent version
# after a new stable version comes out.
- "3.29.3"
- "3.x"
flutter-version: ${{ fromJSON(needs.setup_matrix.outputs.flutter_versions_json) }}
fail-fast: false
steps:
- name: 📚 Git Checkout
Expand All @@ -51,6 +79,10 @@ jobs:

- name: ✨ Check Formatting
run: dart format --set-exit-if-changed lib
# Only continue on error if this is the job for the MINIMUM Flutter version
# This allows formatting issues to be warnings on older supported versions
# but enforces them on the latest stable or primary development version.
continue-on-error: ${{ matrix.flutter-version == env.FLUTTER_VERSION_MINIMUM }}

- name: 🕵️ Analyze
run: flutter analyze lib
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if (keystorePropertiesFile.exists()) {

android {
namespace "com.example.example"
compileSdk 34
compileSdk 35

compileOptions {
sourceCompatibility JavaVersion.VERSION_17
Expand Down
36 changes: 0 additions & 36 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
5B171717BA079CE808D1B32C /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73C604A80B929E096139088E /* Pods_RunnerTests.framework */; };
65355E45871BBAC473F56EC4 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 161F52A253A901BB69307277 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
Expand Down Expand Up @@ -50,11 +49,8 @@
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
6AEFCF184013ED5CA996B82B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
6D5C22CEED22C7791375B03E /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
73C604A80B929E096139088E /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
75018BE4F219FC27188BF5C2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
Expand All @@ -63,7 +59,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CCE42FB5D8CBF00852B83E23 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
D9EB2FAA5097BC9A403E4AC5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand All @@ -80,7 +75,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5B171717BA079CE808D1B32C /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -93,9 +87,6 @@
D9EB2FAA5097BC9A403E4AC5 /* Pods-Runner.debug.xcconfig */,
6AEFCF184013ED5CA996B82B /* Pods-Runner.release.xcconfig */,
0EA25D90DB1772C2D6071B55 /* Pods-Runner.profile.xcconfig */,
CCE42FB5D8CBF00852B83E23 /* Pods-RunnerTests.debug.xcconfig */,
75018BE4F219FC27188BF5C2 /* Pods-RunnerTests.release.xcconfig */,
6D5C22CEED22C7791375B03E /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
Expand All @@ -105,7 +96,6 @@
isa = PBXGroup;
children = (
161F52A253A901BB69307277 /* Pods_Runner.framework */,
73C604A80B929E096139088E /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down Expand Up @@ -172,7 +162,6 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
3FADDB6B4D6AA8657115BAF4 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
ADF676FEC51290FAF51E0789 /* Frameworks */,
Expand Down Expand Up @@ -303,28 +292,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
3FADDB6B4D6AA8657115BAF4 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
6B3BB5498CBA14DCD8E20CF8 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -488,7 +455,6 @@
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CCE42FB5D8CBF00852B83E23 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
Expand All @@ -506,7 +472,6 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 75018BE4F219FC27188BF5C2 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
Expand All @@ -522,7 +487,6 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6D5C22CEED22C7791375B03E /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
Expand Down Expand Up @@ -54,11 +55,13 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
Expand Down
1 change: 1 addition & 0 deletions example/lib/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class _ChewieDemoState extends State<ChewieDemo> {
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController1,
autoPlay: true,
zoomAndPan: true,
looping: true,
progressIndicatorDelay:
bufferDelay != null ? Duration(milliseconds: bufferDelay!) : null,
Expand Down
14 changes: 12 additions & 2 deletions lib/src/chewie_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,12 @@
cupertinoProgressColors ?? this.cupertinoProgressColors,
materialProgressColors:
materialProgressColors ?? this.materialProgressColors,
zoomAndPan: zoomAndPan ?? this.zoomAndPan,
maxScale: maxScale ?? this.maxScale,

Check warning on line 384 in lib/src/chewie_player.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chewie_player.dart#L383-L384

Added lines #L383 - L384 were not covered by tests
controlsSafeAreaMinimum:
controlsSafeAreaMinimum ?? this.controlsSafeAreaMinimum,

Check warning on line 386 in lib/src/chewie_player.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chewie_player.dart#L386

Added line #L386 was not covered by tests
transformationController:
transformationController ?? this.transformationController,

Check warning on line 388 in lib/src/chewie_player.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/chewie_player.dart#L388

Added line #L388 was not covered by tests
materialSeekButtonFadeDuration:
materialSeekButtonFadeDuration ?? this.materialSeekButtonFadeDuration,
materialSeekButtonSize:
Expand Down Expand Up @@ -490,10 +496,14 @@
/// Whether or not to show the controls at all
final bool showControls;

/// Controller to pass into the [InteractiveViewer] component
/// Controller to pass into the [InteractiveViewer] component.
/// If it is required to control the transformation only via the controller,
/// `zoomAndPan` should be set to false.
final TransformationController? transformationController;

/// Whether or not to allow zooming and panning
/// Whether or not to allow zooming and panning.
/// This can still be false, and the `transformationController` can be used to control the
/// transformation.
final bool zoomAndPan;

/// Max scale when zooming
Expand Down
44 changes: 30 additions & 14 deletions lib/src/player_with_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,17 @@
ChewieController chewieController,
BuildContext context,
) {
return Stack(
children: <Widget>[
final playerNotifier = context.read<PlayerNotifier>();
final child = Stack(
children: [
if (chewieController.placeholder != null)
chewieController.placeholder!,
InteractiveViewer(
transformationController: chewieController.transformationController,
maxScale: chewieController.maxScale,
panEnabled: chewieController.zoomAndPan,
scaleEnabled: chewieController.zoomAndPan,
child: Center(
child: AspectRatio(
aspectRatio:
chewieController.aspectRatio ??
chewieController.videoPlayerController.value.aspectRatio,
child: VideoPlayer(chewieController.videoPlayerController),
),
Center(
child: AspectRatio(
aspectRatio:
chewieController.aspectRatio ??
chewieController.videoPlayerController.value.aspectRatio,
child: VideoPlayer(chewieController.videoPlayerController),
),
),
if (chewieController.overlay != null) chewieController.overlay!,
Expand Down Expand Up @@ -80,6 +75,27 @@
),
],
);

if (chewieController.zoomAndPan ||
chewieController.transformationController != null) {
return InteractiveViewer(
transformationController: chewieController.transformationController,
maxScale: chewieController.maxScale,
panEnabled: chewieController.zoomAndPan,
scaleEnabled: chewieController.zoomAndPan,

Check warning on line 85 in lib/src/player_with_controls.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/player_with_controls.dart#L81-L85

Added lines #L81 - L85 were not covered by tests
onInteractionUpdate:
chewieController.zoomAndPan
? (_) => playerNotifier.hideStuff = true

Check warning on line 88 in lib/src/player_with_controls.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/player_with_controls.dart#L87-L88

Added lines #L87 - L88 were not covered by tests
: null,
onInteractionEnd:
chewieController.zoomAndPan
? (_) => playerNotifier.hideStuff = false

Check warning on line 92 in lib/src/player_with_controls.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/player_with_controls.dart#L91-L92

Added lines #L91 - L92 were not covered by tests
: null,
child: child,
);
}

return child;
}

return LayoutBuilder(
Expand Down