diff --git a/CHANGELOG.md b/CHANGELOG.md index 597864e6..53ba2ac5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - closes #104 - fix(voice): update the status message in the voice setup page when the access key is set/cleared - closes #105 +- fix(camera) - back button in the camera viewfinder doesn't cancel the parent application/menu + - closes #106 ## Version 0.14.1 diff --git a/ubo_app/services/040-camera/reducer.py b/ubo_app/services/040-camera/reducer.py index e51a3978..3e9570ab 100644 --- a/ubo_app/services/040-camera/reducer.py +++ b/ubo_app/services/040-camera/reducer.py @@ -22,7 +22,7 @@ CameraStopViewfinderEvent, InputDescription, ) -from ubo_app.store.services.keypad import Key, KeypadAction +from ubo_app.store.services.keypad import Key, KeypadKeyPressAction Action = InitAction | CameraAction @@ -96,7 +96,7 @@ def reducer( return state - if isinstance(action, KeypadAction): # noqa: SIM102 + if isinstance(action, KeypadKeyPressAction): # noqa: SIM102 if action.key == Key.BACK: return CompleteReducerResult( state=pop_queue(state), diff --git a/ubo_app/services/040-camera/setup.py b/ubo_app/services/040-camera/setup.py index 68ba609e..ac23e963 100644 --- a/ubo_app/services/040-camera/setup.py +++ b/ubo_app/services/040-camera/setup.py @@ -8,10 +8,12 @@ import headless_kivy_pi.config import numpy as np from debouncer import DebounceOptions, debounce -from kivy.clock import Clock +from kivy.clock import Clock, mainthread from pyzbar.pyzbar import decode +from ubo_gui.page import PageWidget from ubo_app.store import dispatch, subscribe_event +from ubo_app.store.main import CloseApplicationEvent, OpenApplicationEvent from ubo_app.store.services.camera import ( CameraReportBarcodeAction, CameraStartViewfinderEvent, @@ -49,6 +51,11 @@ async def check_codes(codes: list[str]) -> None: dispatch(CameraReportBarcodeAction(codes=codes)) +class CameraApplication(PageWidget): + def go_back(self: CameraApplication) -> bool: + return True + + def run_fake_camera() -> None: # pragma: no cover async def provide() -> None: while True: @@ -60,9 +67,12 @@ async def provide() -> None: path.unlink(missing_ok=True) await check_codes([data]) + @mainthread def run_provider() -> None: from kivy.core.window import Window + application = CameraApplication() + dispatch(OpenApplicationEvent(application=application)) Window.opacity = 0.2 def set_task(task: asyncio.Task) -> None: @@ -70,6 +80,7 @@ def stop() -> None: task.cancel() cancel_subscription() Window.opacity = 1 + dispatch(CloseApplicationEvent(application=application)) cancel_subscription = subscribe_event( CameraStopViewfinderEvent, @@ -106,7 +117,10 @@ def init_service() -> None: picam2.start() + @mainthread def start_camera_viewfinder() -> None: + application = CameraApplication() + dispatch(OpenApplicationEvent(application=application)) display = headless_kivy_pi.config._display # noqa: SLF001 if not display: return @@ -174,6 +188,7 @@ def feed_viewfinder(_: object) -> None: headless_kivy_pi.config.pause() def handle_stop_viewfinder() -> None: + dispatch(CloseApplicationEvent(application=application)) feed_viewfinder_scheduler.cancel() headless_kivy_pi.config.resume() cancel_subscription() diff --git a/ubo_app/utils/qrcode.py b/ubo_app/utils/qrcode.py index 45716d41..92e5fa06 100644 --- a/ubo_app/utils/qrcode.py +++ b/ubo_app/utils/qrcode.py @@ -118,7 +118,7 @@ async def handle_barcode_event(event: CameraBarcodeEvent) -> None: def handle_cancel(event: CameraStopViewfinderEvent) -> None: if event.id == id: - future.cancel() + loop.call_soon_threadsafe(future.cancel) subscribe_event( CameraBarcodeEvent,