Skip to content

fix(ads): refactor InterstitialAd to a Service and BannerAd to a LayoutControl#6235

Open
ndonkoHenri wants to merge 18 commits intomainfrom
fix-ads
Open

fix(ads): refactor InterstitialAd to a Service and BannerAd to a LayoutControl#6235
ndonkoHenri wants to merge 18 commits intomainfrom
fix-ads

Conversation

@ndonkoHenri
Copy link
Contributor

@ndonkoHenri ndonkoHenri commented Mar 1, 2026

Fix #6194

Test code

code

import flet as ft
import flet_ads as fta

# Test ad unit IDs
ids = {
    ft.PagePlatform.ANDROID: {
        "banner": "ca-app-pub-3940256099942544/6300978111",
        "interstitial": "ca-app-pub-3940256099942544/1033173712",
    },
    ft.PagePlatform.IOS: {
        "banner": "ca-app-pub-3940256099942544/2934735716",
        "interstitial": "ca-app-pub-3940256099942544/4411468910",
    },
}


def main(page: ft.Page):
    page.appbar = ft.AppBar(
        adaptive=True,
        title="Mobile Ads Playground",
        bgcolor=ft.Colors.LIGHT_BLUE_300,
    )
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
    page.scroll = ft.ScrollMode.AUTO

    def show_new_interstitial_ad():
        async def show_iad(e: ft.Event[fta.InterstitialAd]):
            await iad.show()

        iad = fta.InterstitialAd(
            unit_id=ids[page.platform]["interstitial"],
            on_load=show_iad,
            on_error=lambda e: print("InterstitialAd error", e.data),
            on_open=lambda e: print("InterstitialAd opened"),
            on_close=lambda e: print("InterstitialAd closed"),
            on_impression=lambda e: print("InterstitialAd impression"),
            on_click=lambda e: print("InterstitialAd clicked"),
        )

    def get_new_banner_ad() -> fta.BannerAd:
        return fta.BannerAd(
            unit_id=ids[page.platform]["banner"],
            width=320,
            height=50,
            on_click=lambda e: print("BannerAd clicked"),
            on_load=lambda e: print("BannerAd loaded"),
            on_error=lambda e: print("BannerAd error", e.data),
            on_open=lambda e: print("BannerAd opened"),
            on_close=lambda e: print("BannerAd closed"),
            on_impression=lambda e: print("BannerAd impression"),
            on_will_dismiss=lambda e: print("BannerAd will dismiss"),
        )

    page.add(
        ft.OutlinedButton(
            content="Show InterstitialAd",
            on_click=show_new_interstitial_ad,
            disabled=page.web or not page.platform.is_mobile(),  # mobile only
        ),
        ft.OutlinedButton(
            content="Show BannerAd",
            on_click=lambda e: page.add(get_new_banner_ad()),
            disabled=page.web or not page.platform.is_mobile(),  # mobile only
        ),
    )


ft.run(main)

Summary by Sourcery

Refine ads controls and cross-platform permission handling while expanding and clarifying platform-specific documentation and examples.

New Features:

  • Add an Image control example demonstrating gapless playback behavior when changing image sources.

Bug Fixes:

  • Fix cross-platform permission bundle handling for iOS and macOS in the CLI and docs, including correct Info.plist keys, entitlements, and boolean parsing for Info.plist overrides.

Enhancements:

  • Refactor flet-ads BaseAd to derive from BaseControl and make InterstitialAd a service control and BannerAd a layout control, updating the example app and documentation accordingly.
  • Clarify and expand platform-specific requirements and configuration examples for audio recorder, geolocator, camera, video, permission handler, ads, and webview documentation.
  • Improve Border and BorderSide API documentation for clarity about omitting sides and factory methods.
  • Adjust webview and ads docs layout and example image usage for consistency and readability.

Build:

  • Restrict Python extension packaging to include Flutter pubspec and lib sources for multiple flet-* packages instead of all files.
  • Add chardet as a constrained dependency for the flet-cli package for compatibility.

Documentation:

  • Update multiple docs pages to detail Android/iOS/macOS/Linux requirements, permissions, and configuration snippets for extensions like audio_recorder, geolocator, camera, video, webview, ads, permission_handler, and image gapless playback.
  • Document AdMob test IDs and configuration requirements for the flet-ads package and extension usage.
  • Clarify deep-linking and cleanup options examples in publish docs for better readability.

Chores:

  • Tidy iOS Info.plist formatting, adjust client and core Flutter dependencies, and update release-preparation skill instructions to handle Unreleased changelog sections.

`flet-cli` pulls `cookiecutter`, which depends on `binaryornot` and allows unconstrained `chardet`.
With `uvx`, this can resolve to `chardet==6.x`, while `requests==2.32.5` still checks for `chardet<6` and emits:

`RequestsDependencyWarning: urllib3 (...) or chardet (...)/charset_normalizer (...) doesn't match a supported version`

Add `chardet <6` to `sdk/python/packages/flet-cli/pyproject.toml` to keep the dependency set compatible and remove the warning during `flet build apk`.
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 1, 2026

Deploying flet-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: c34a0b4
Status: ✅  Deploy successful!
Preview URL: https://480cbdc5.flet-docs.pages.dev
Branch Preview URL: https://fix-ads.flet-docs.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 1, 2026

Deploying flet-examples with  Cloudflare Pages  Cloudflare Pages

Latest commit: c34a0b4
Status: ✅  Deploy successful!
Preview URL: https://fc51f043.flet-examples.pages.dev
Branch Preview URL: https://fix-ads.flet-examples.pages.dev

View logs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes issue #6194 by refactoring InterstitialAd from a regular control to a Service (which auto-registers itself to the page's service registry upon instantiation, without needing to be added to page.overlay), and BannerAd from a base Control to a LayoutControl. It also separates iOS and macOS Info.plist permission handling in the CLI, and adds various documentation improvements for extension packages.

Changes:

  • InterstitialAd refactored to ft.Service and BannerAd to ft.LayoutControl in flet-ads
  • Cross-platform CLI permissions split into platform-specific ios_info_plist and macos_info_plist keys, replacing the shared info_plist key
  • Documentation overhaul for several extension packages (ads, audio recorder, camera, geolocator, video, permission handler, webview)

Reviewed changes

Copilot reviewed 44 out of 47 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
flet-ads/src/flet_ads/base_ad.py Converted BaseAd to a @dataclass(kw_only=True) mixin on ft.BaseControl
flet-ads/src/flet_ads/banner_ad.py Changed BannerAd base class to ft.LayoutControl
flet-ads/src/flet_ads/interstitial_ad.py Changed InterstitialAd base class to ft.Service to fix issue #6194
flet-ads/CHANGELOG.md Documents the unreleased refactoring changes
examples/controls/ads/example_1.py Updated example to use new Service-based InterstitialAd pattern
flet-cli/src/flet_cli/commands/build_base.py Split iOS/macOS plist keys and updated info-plist boolean parsing
flet-cli/pyproject.toml Added chardet <6 dependency
flet/docs/audio_recorder/index.md Expanded platform requirements documentation
flet/docs/video/index.md Expanded platform requirements documentation
flet/docs/camera/index.md Expanded platform requirements documentation
flet/docs/geolocator/index.md Expanded platform requirements documentation
flet/docs/permission_handler/index.md Added platform-specific requirements section
flet/docs/ads/index.md Reorganized ad configuration and test values
flet/docs/ads/bannerad.md Minor formatting cleanup
flet/docs/ads/interstitialad.md Minor formatting cleanup
flet/docs/webview/index.md Improved description
flet/docs/publish/index.md Reformatted long CLI commands for readability
flet/docs/controls/image.md Added gapless playback example reference
flet/docs/extras/macros/cross_platform_permissions.py Updated to handle ios_info_plist/macos_info_plist keys
examples/controls/image/gapless_playback.py New example for Image.gapless_playback
packages/flet/pubspec.yaml Moved cupertino_icons, package_info_plus, wakelock_plus to main package
packages/flet/lib/src/controls/datatable.dart Added external ClipRRect when border radius + clip is set
client/pubspec.yaml Cleaned up dependencies moved to flet package
client/ios/Runner/Info.plist Minor XML formatting (removed space before />)
flet-geolocator/src/flet_geolocator/geolocator.py Minor code style cleanups
Multiple */pyproject.toml Narrowed package-data patterns for Flutter extension packages
.codex/skills/prepare-flet-release/SKILL.md Added instruction to handle Unreleased changelog sections

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Configuration to be made to access the microphone:

- [`NSMicrophoneUsageDescription`](https://developer.apple.com/documentation/BundleResources/Information-Property-List/NSMicrophoneUsageDescription): Required for recording audio.
- [`com.apple.security.device.audio-input`](https://developer.apple.com/documentation/BundleResources/Entitlements/com.apple.security.device.audio-input) (optional): Required for recording audio.
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entitlement com.apple.security.device.audio-input is listed as "(optional)" in the bullet description, but the text also says it is "Required for recording audio." This is contradictory. If the entitlement is required for macOS audio recording, it should not be labeled as optional.

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +55
android.permission.READ_EXTERNAL_STORAGE=True
android.permission.WRITE_EXTERNAL_STORAGE=True
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flet build command example is missing a backslash (\) at the end of line 54 (android.permission.READ_EXTERNAL_STORAGE=True). Without it, android.permission.WRITE_EXTERNAL_STORAGE=True on the next line will not be part of the same command and will be interpreted as a separate shell command, so it will be silently ignored.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: unkonow InterstitialAd controls in (flet_ads)

2 participants