@@ -36,33 +36,47 @@ struct HomeScreen: View {
3636 )
3737 }
3838
39+ let heroMoviesRef : QueryRefObservation < ListMoviesQuery . Data , ListMoviesQuery . Variables >
3940 private var heroMovies : [ Movie ] {
40- connector. listMoviesQuery
41- . ref { optionalVars in
42- optionalVars. limit = 3
43- optionalVars. orderByReleaseYear = . DESC
44- }
41+ heroMoviesRef
4542 . data? . movies. map ( Movie . init) ?? [ ]
4643 }
4744
45+ let topMoviesRef : QueryRefObservation < ListMoviesQuery . Data , ListMoviesQuery . Variables >
4846 private var topMovies : [ Movie ] {
49- connector. listMoviesQuery
50- . ref { optionalVars in
51- optionalVars. limit = 5
52- optionalVars. orderByRating = . DESC
53- }
54- . data? . movies. map ( Movie . init) ?? [ ]
47+ topMoviesRef. data? . movies. map ( Movie . init) ?? [ ]
5548 }
5649
57- let watchListRef : QueryRefObservation <
58- GetUserFavoriteMoviesQuery . Data ,
59- GetUserFavoriteMoviesQuery . Variables
60- >
50+ let watchListRef :
51+ QueryRefObservation <
52+ GetUserFavoriteMoviesQuery . Data ,
53+ GetUserFavoriteMoviesQuery . Variables
54+ >
6155 private var watchList : [ Movie ] {
6256 watchListRef. data? . user? . favoriteMovies. map ( Movie . init) ?? [ ]
6357 }
6458
59+ private var isEmpty : Bool {
60+ heroMovies. count == 0
61+ }
62+
63+ private func refresh( ) async {
64+ async let _ = heroMoviesRef. execute ( )
65+ async let _ = topMoviesRef. execute ( )
66+ async let _ = watchListRef. execute ( )
67+ }
68+
6569 init ( ) {
70+ heroMoviesRef = connector. listMoviesQuery
71+ . ref { optionalVars in
72+ optionalVars. limit = 3
73+ optionalVars. orderByReleaseYear = . DESC
74+ }
75+ topMoviesRef = connector. listMoviesQuery
76+ . ref { optionalVars in
77+ optionalVars. limit = 5
78+ optionalVars. orderByRating = . DESC
79+ }
6680 watchListRef = connector. getUserFavoriteMoviesQuery. ref ( )
6781 }
6882}
@@ -71,45 +85,62 @@ extension HomeScreen {
7185 var body : some View {
7286 NavigationStack {
7387 ScrollView {
74- TabView {
75- ForEach ( heroMovies) { movie in
76- NavigationLink ( value: movie) {
77- MovieTeaserView (
78- title: movie. title,
79- subtitle: movie. description,
80- imageUrl: movie. imageUrl
81- )
82- . matchedTransitionSource ( id: movie. id, in: namespace)
88+ if isEmpty {
89+ GeometryReader { geometry in
90+ ContentUnavailableView {
91+ Label ( " No movies available " , systemImage: " rectangle.on.rectangle.slash " )
92+ } description: {
93+ VStack {
94+ Text ( " Follow the instructions in the README.md file to get started. " )
95+ }
8396 }
84- . buttonStyle ( . noHighlight )
97+ . frame ( width : geometry . size . width , height : geometry . size . height )
8598 }
86- }
87- . frame ( height: 600 )
88- . navigationDestination ( for: Movie . self) { movie in
89- MovieCardView ( showDetails: true , movie: movie)
90- . navigationTransition ( . zoom( sourceID: movie. id, in: namespace) )
91- }
92- . tabViewStyle ( . page( indexDisplayMode: . always) )
99+ . frame ( height: UIScreen . main. bounds. height)
100+ } else {
101+ TabView {
102+ ForEach ( heroMovies) { movie in
103+ NavigationLink ( value: movie) {
104+ MovieTeaserView (
105+ title: movie. title,
106+ subtitle: movie. description,
107+ imageUrl: movie. imageUrl
108+ )
109+ . matchedTransitionSource ( id: movie. id, in: namespace)
110+ }
111+ . buttonStyle ( . noHighlight)
112+ }
113+ }
114+ . frame ( height: 600 )
115+ . navigationDestination ( for: Movie . self) { movie in
116+ MovieCardView ( showDetails: true , movie: movie)
117+ . navigationTransition ( . zoom( sourceID: movie. id, in: namespace) )
118+ }
119+ . tabViewStyle ( . page( indexDisplayMode: . always) )
93120
94- Group {
95- MovieListSection ( namespace: namespace, title: " Top Movies " , movies: topMovies)
96- if isSignedIn {
97- MovieListSection ( namespace: namespace, title: " Watch List " , movies: watchList)
98- . onAppear {
99- Task {
100- try await watchListRef. execute ( )
121+ Group {
122+ MovieListSection ( namespace: namespace, title: " Top Movies " , movies: topMovies)
123+ if isSignedIn {
124+ MovieListSection ( namespace: namespace, title: " Watch List " , movies: watchList)
125+ . onAppear {
126+ Task {
127+ try await watchListRef. execute ( )
128+ }
101129 }
102- }
130+ }
103131 }
132+ . navigationDestination ( for: [ Movie ] . self) { movies in
133+ MovieListScreen ( namespace: namespace, movies: movies)
134+ }
135+ . navigationDestination ( for: SectionedMovie . self) { sectionedMovie in
136+ MovieCardView ( showDetails: true , movie: sectionedMovie. movie)
137+ . navigationTransition ( . zoom( sourceID: sectionedMovie. id, in: namespace) )
138+ }
139+ . padding ( )
104140 }
105- . navigationDestination ( for: [ Movie ] . self) { movies in
106- MovieListScreen ( namespace: namespace, movies: movies)
107- }
108- . navigationDestination ( for: SectionedMovie . self) { sectionedMovie in
109- MovieCardView ( showDetails: true , movie: sectionedMovie. movie)
110- . navigationTransition ( . zoom( sourceID: sectionedMovie. id, in: namespace) )
111- }
112- . padding ( )
141+ }
142+ . refreshable {
143+ await refresh ( )
113144 }
114145 . navigationTitle ( " Home " )
115146 . toolbar {
0 commit comments