flet-dev / flet

Flet enables developers to easily build realtime web, mobile and desktop apps in Python. No frontend experience required.
https://flet.dev
Apache License 2.0
11.43k stars 445 forks source link

Snackbar disabling audio event handlers #2998

Open syleishere opened 7 months ago

syleishere commented 7 months ago

Displaying Snackbar to display current playing song while using audio package disables all audio event handlers. I have tried putting snackbar different places to avoid this behavior, including on_loaded, on_position, on_duration and just normal button click to play a song, same effect.

ndonkoHenri commented 7 months ago

Please use/fill out the issue template when reporting an issue.

syleishere commented 7 months ago

Sorry for delay, putting together simplest example for you to run was not going to take 5 min, more like 30 lol. Anyways here you go, simplest functional example of problem with snackbar:

import flet as ft
from flet_core.audio import ReleaseMode
from flet_core.types import AppView

class ConfigApp:
    def __init__(self, page):
        self.page = page
        self.SONG_LIST = [
            "https://mp3.sunsaturn.com/soshy.mp3",  # windows can't play opus
            "https://mp3.sunsaturn.com/viper.mp3",
            "https://mp3.sunsaturn.com/lonely.mp3",
            "https://mp3.sunsaturn.com/eclipse.mp3",
        ]
        self.audio = ft.Audio(
            src="https://mp3.sunsaturn.com/silent.mp3", autoplay=True,  # play() doesn't work on android without this True first time playing a song
            release_mode=ReleaseMode.STOP,  # again android issue calling release()
            on_loaded=self.loaded,
            on_duration_changed=self.duration,
            on_position_changed=self.position,
        )
        self.page.overlay.append(self.audio)

    async def loaded(self, e):
        self.audio.play()

    async def duration(self, e):
        print(f"Duration is now {int(e.data)}")

    async def position(self, e):
        print(f"Position is now {int(e.data)}")

    def snackbar(self, message):
        my_content = ft.Row(   # So we can align snackbar message in the center
                               # Unfortunately can't get nice snackbar flutter has
            alignment=ft.MainAxisAlignment.CENTER,
            controls=[
                ft.Text(value=f"{message}", color=ft.colors.ON_PRIMARY, weight=ft.FontWeight.W_600),
            ]
        )
        self.page.snack_bar = ft.SnackBar(content=my_content, bgcolor=ft.colors.PRIMARY,
                                          show_close_icon=True, duration=2000)  # 3000 milliseconds = 3 seconds
        self.page.snack_bar.open = True
        self.page.update()
        # Unfortunately can't get beautiful snackbar flutter has with progress indicator and GetX plugin ie:
        # snackbar(message) async {
        #     Get.snackbar(
        #         message,
        #         "SunSaturn Message",
        #         backgroundColor: Colors.black,
        #     snackPosition: SnackPosition.BOTTOM,
        #     colorText: Colors.white,
        #     leftBarIndicatorColor: Colors.pink,
        #     isDismissible: true,
        #     showProgressIndicator: true,
        #     duration: Duration(seconds: 5),
        # snackStyle: SnackStyle.FLOATING,
        # );

    async def play_song(self, e):
        index = int(e.control.key)
        self.audio.pause()  # Again android problems if call release()
        self.audio.src = self.SONG_LIST[index]
        self.snackbar(f"Now playing song: {self.audio.src} ")  # HERE IS PROBLEM UNCOMMENT THIS LINE AND DURATION AND POSITION WILL PRINT AGAIN!!!!!!!!
                                                               # You can PUT THIS anywhere, position function, duration etc will disable audio even handlers
        self.page.update()

async def main(page: ft.Page):
    config = ConfigApp(page)
    for i in range(0, len(config.SONG_LIST)):
        song = config.SONG_LIST[i].split("/")[-1]
        cnt = ft.Container(
            key=str(i),
            bgcolor=ft.colors.BLUE,
            on_click=config.play_song,
            content=ft.Text(value=f"Play {song}", color=ft.colors.WHITE),
        )
        page.controls.append(cnt)
    page.update()
ft.app(target=main, view=AppView.WEB_BROWSER)

I stuck snackbar in play_song function for you to see when you comment it out, you can print duration and position again to your screen.

BrentHuang commented 6 months ago

For the official demo 'https://flet.dev/docs/controls/snackbar/', when 'show_close_icon' is True, there is no close button in Desktop app.