Improve full screen support

This commit introduces new mechanisms to solve some issues with full screen support:
1. Full screen covers disappear when its caller disappears (e.g. when it
   is an event in a lazy stack, and an orientation change causes the
   view to disappear along with the full screen cover)
2. There are no mechanisms for views to determine whether they are being
   presented under a full screen cover or not, and whether the device is
   in full screen mode or not.

The commit overcomes the above limitations through the following:
1. A full screen cover on `ContentView` that can be accessed by any view
   when calling `present(fullScreenItem)`
2. A new `damus_full_screen_cover` view modifier that automatically
   tracks whether a device is in full screen mode or not, and allows
   any descendant view in its hierarchy to introspect on which view
   layer it is being presented in.

This commit lays a foundation that will later become important for
improving video coordination.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
Daniel D’Aquino
2024-11-01 18:12:49 -07:00
parent a56a59f81d
commit 1bc660c9cd
7 changed files with 253 additions and 3 deletions

View File

@@ -0,0 +1,42 @@
//
// PresentFullScreenItemNotify.swift
// damus
//
// Created by Daniel DAquino on 2024-11-01.
//
struct PresentFullScreenItemNotify: Notify {
typealias Payload = FullScreenItem
var payload: Payload
}
extension NotifyHandler {
static var present_full_screen_item: NotifyHandler<PresentFullScreenItemNotify> {
.init()
}
}
extension Notifications {
static func present_full_screen_item(_ item: FullScreenItem) -> Notifications<PresentFullScreenItemNotify> {
.init(.init(payload: item))
}
}
/// Tell the app to present an item in full screen. Use this when presenting items coming from a timeline or any lazy stack.
///
/// ## Usage notes
///
/// Use this instead of `.damus_full_screen_cover` when the source view is on a lazy stack or timeline.
///
/// The reason is that when using a full screen modifier in those scenarios, the full screen view may abruptly disappear.
/// One example is when showing videos from the timeline in full screen, where changing the orientation of the device (landscape/portrait)
/// can cause the source view to be unloaded by the lazy stack, making your full screen overlay to simply disappear, causing a feeling of flakiness to the app
///
/// ## Implementation notes
///
/// The requests from this function will be received and handled at the top level app view (`ContentView`), which contains a `.damus_full_screen_cover`.
///
func present(full_screen_item: FullScreenItem) {
notify(.present_full_screen_item(full_screen_item))
}