fix: disambiguate SwiftUI State with macOS 27 SDK
Use a file-private ViewState alias for all twelve state properties, including start-screen hover and playback queue state, on current main@origin. Document the standalone Command Line Tools workaround. Verified: make release; release check-runtime; release CLI --help; dlopen of the release player library and terebi_app_main symbol lookup.
This commit is contained in:
@@ -15,6 +15,8 @@ make run
|
|||||||
|
|
||||||
The first build downloads pinned dependencies. Build natively on Apple Silicon or Intel; cross-architecture and Rosetta builds are not supported.
|
The first build downloads pinned dependencies. Build natively on Apple Silicon or Intel; cross-architecture and Rosetta builds are not supported.
|
||||||
|
|
||||||
|
With the macOS 27 SDK, the player uses a private `ViewState` alias for the `SwiftUI.State<Value>` property wrapper to avoid selecting the same-named macro, whose `SwiftUIMacros` plugin is absent from standalone Command Line Tools. Full Xcode or an older SDK is not required.
|
||||||
|
|
||||||
The resulting `.build/terebi.app` is self-contained: copy the whole app to a compatible Mac of the same architecture. No separate FFmpeg, Python, or yt-dlp installation is needed to run it.
|
The resulting `.build/terebi.app` is self-contained: copy the whole app to a compatible Mac of the same architecture. No separate FFmpeg, Python, or yt-dlp installation is needed to run it.
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|||||||
+15
-12
@@ -2068,9 +2068,12 @@ struct PlaybackSurface: NSViewRepresentable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select the property wrapper, not the macOS 27 macro missing from Command Line Tools.
|
||||||
|
private typealias ViewState<Value> = SwiftUI.State<Value>
|
||||||
|
|
||||||
private struct StartScreenButtonStyle: ButtonStyle {
|
private struct StartScreenButtonStyle: ButtonStyle {
|
||||||
var prominent = false
|
var prominent = false
|
||||||
@State private var hovered = false
|
@ViewState private var hovered = false
|
||||||
|
|
||||||
func makeBody(configuration: Configuration) -> some View {
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
configuration.label
|
configuration.label
|
||||||
@@ -2089,19 +2092,19 @@ private struct StartScreenButtonStyle: ButtonStyle {
|
|||||||
private struct PlayerContent: View {
|
private struct PlayerContent: View {
|
||||||
@ObservedObject var model: PlayerModel
|
@ObservedObject var model: PlayerModel
|
||||||
@Environment(\.accessibilityReduceMotion) private var reduceMotion
|
@Environment(\.accessibilityReduceMotion) private var reduceMotion
|
||||||
@State private var showsRemainingTime = false
|
@ViewState private var showsRemainingTime = false
|
||||||
@State private var dropTargeted = false
|
@ViewState private var dropTargeted = false
|
||||||
@State private var showsYouTubeInput = false
|
@ViewState private var showsYouTubeInput = false
|
||||||
@State private var youTubeURL = ""
|
@ViewState private var youTubeURL = ""
|
||||||
@FocusState private var youTubeInputFocused: Bool
|
@FocusState private var youTubeInputFocused: Bool
|
||||||
@State private var controlSize = CGSize(width: 440, height: 68)
|
@ViewState private var controlSize = CGSize(width: 440, height: 68)
|
||||||
@State private var queueFrames: [UUID: CGRect] = [:]
|
@ViewState private var queueFrames: [UUID: CGRect] = [:]
|
||||||
@State private var queueDrag: PlaybackQueueDrag?
|
@ViewState private var queueDrag: PlaybackQueueDrag?
|
||||||
@GestureState private var queueDragging = false
|
@GestureState private var queueDragging = false
|
||||||
@State private var queueScroll = ScrollPosition(y: 0)
|
@ViewState private var queueScroll = ScrollPosition(y: 0)
|
||||||
@State private var queueScrollOffset: CGFloat = 0
|
@ViewState private var queueScrollOffset: CGFloat = 0
|
||||||
@State private var queueViewportHeight: CGFloat = 0
|
@ViewState private var queueViewportHeight: CGFloat = 0
|
||||||
@State private var queueContentHeight: CGFloat = 0
|
@ViewState private var queueContentHeight: CGFloat = 0
|
||||||
|
|
||||||
private func compactTitleLabel(progress: String?, constrained: Bool) -> some View {
|
private func compactTitleLabel(progress: String?, constrained: Bool) -> some View {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
|||||||
@@ -10,5 +10,6 @@
|
|||||||
- local seek preroll skips disposable non-reference pictures without sacrificing exact target frames; measured 1080p/10-second-GOP paused seek improved from 541 ms to 400 ms and playing seek from 682 ms to 488 ms; timestamp/pixel checks passed across six decoder formats; long-GOP reference decoding remains necessary, and the originally affected files still need manual verification
|
- local seek preroll skips disposable non-reference pictures without sacrificing exact target frames; measured 1080p/10-second-GOP paused seek improved from 541 ms to 400 ms and playing seek from 682 ms to 488 ms; timestamp/pixel checks passed across six decoder formats; long-GOP reference decoding remains necessary, and the originally affected files still need manual verification
|
||||||
- [x] make the sidebar expand/collapse with a nice transition
|
- [x] make the sidebar expand/collapse with a nice transition
|
||||||
- synchronized 250 ms sidebar/window reveal, reversible mid-transition, with immediate Reduce Motion changes; top-right controls stay anchored to the moving window corner; native checks passed for rendered controls during transitions, stable video size, reversals, screen-edge fitting, fullscreen and compact restoration; animation feel and Reduce Motion still need manual verification
|
- synchronized 250 ms sidebar/window reveal, reversible mid-transition, with immediate Reduce Motion changes; top-right controls stay anchored to the moving window corner; native checks passed for rendered controls during transitions, stable video size, reversals, screen-edge fitting, fullscreen and compact restoration; animation feel and Reduce Motion still need manual verification
|
||||||
|
- [ ] make the window draggable (in all cases/view states) so long as a button/clickable element is not hovered.
|
||||||
- [ ] in the "choose what to play" screen, we should change the youtube button to general streaming
|
- [ ] in the "choose what to play" screen, we should change the youtube button to general streaming
|
||||||
- we can figure out the stream and how to handle it from the url (i.e. if youtube url, handle as youtube stream; if miruro url, handle accordingly)
|
- we can figure out the stream and how to handle it from the url (i.e. if youtube url, handle as youtube stream; if miruro url, handle accordingly)
|
||||||
Reference in New Issue
Block a user