-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
set up movie list and moive detail view
- Loading branch information
Showing
27 changed files
with
1,008 additions
and
65 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
8 changes: 8 additions & 0 deletions
8
Flicks.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>PreviewsEnabled</key> | ||
<false/> | ||
</dict> | ||
</plist> |
18 changes: 18 additions & 0 deletions
18
...eproj/project.xcworkspace/xcuserdata/noelobaseki.xcuserdatad/WorkspaceSettings.xcsettings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>BuildLocationStyle</key> | ||
<string>UseAppPreferences</string> | ||
<key>CustomBuildLocationType</key> | ||
<string>RelativeToDerivedData</string> | ||
<key>DerivedDataLocationStyle</key> | ||
<string>Default</string> | ||
<key>IssueFilterStyle</key> | ||
<string>ShowActiveSchemeOnly</string> | ||
<key>LiveSourceIssuesEnabled</key> | ||
<true/> | ||
<key>ShowSharedSchemesAutomaticallyEnabled</key> | ||
<true/> | ||
</dict> | ||
</plist> |
21 changes: 21 additions & 0 deletions
21
Flicks/Assets.xcassets/Loading_Default_Picture.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"filename" : "Loading_Default_Picture copy.jpg", | ||
"idiom" : "universal", | ||
"scale" : "1x" | ||
}, | ||
{ | ||
"idiom" : "universal", | ||
"scale" : "2x" | ||
}, | ||
{ | ||
"idiom" : "universal", | ||
"scale" : "3x" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
Binary file added
BIN
+14.9 KB
...sets.xcassets/Loading_Default_Picture.imageset/Loading_Default_Picture copy.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// | ||
// MovieDetailsView.swift | ||
// Flicks | ||
// | ||
// Created by Noel Obaseki on 06/06/2022. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct MovieDetailsView: View { | ||
@StateObject var viewModel: MovieDetailsViewModel | ||
@StateObject var imageHandlerViewModel = ImageProvider() | ||
|
||
var body: some View { | ||
VStack(spacing: 0) { | ||
if viewModel.showNoData { | ||
Text("Unable to load Movie details") | ||
} else if viewModel.isLoading { | ||
ProgressView() | ||
.frame(width: 50, height: 50) | ||
} else if let movieDetails = viewModel.movieDetails { | ||
if viewModel.isOffline { | ||
OfflineBarView() | ||
} | ||
|
||
ScrollView { | ||
|
||
Image(uiImage: imageHandlerViewModel.image).resizable() | ||
.renderingMode(.original) | ||
.aspectRatio(contentMode:.fill) | ||
.frame(width:60,height:300) | ||
.cornerRadius(10) | ||
.overlay(RoundedRectangle(cornerRadius: 10) | ||
.stroke(Color.black, lineWidth: 1)) | ||
.onAppear { | ||
imageHandlerViewModel.loadImage(url:URL(string: "\(Constants.Image.baseUrl)\(movieDetails.posterPath!)" )! ) | ||
} | ||
|
||
|
||
VStack(alignment: .leading, spacing: 10) { | ||
Text(movieDetails.title ?? "Missing Title") | ||
Text("Overview:").bold() | ||
Text(movieDetails.overview ?? "No Overview") | ||
.fixedSize(horizontal: false, vertical: true) | ||
} | ||
.padding(.horizontal, 8) | ||
Spacer() | ||
} | ||
} | ||
} | ||
.navigationBarTitle("Movie Details", displayMode: .inline) | ||
|
||
} | ||
} | ||
|
||
//struct MovieDetailsView_Previews: PreviewProvider { | ||
// static var previews: some View { | ||
// MovieDetailsView() | ||
// } | ||
//} |
26 changes: 26 additions & 0 deletions
26
Flicks/core/movieDetails/MovieDetailsViewDestination.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// MovieDetailsViewDestination.swift | ||
// Flicks | ||
// | ||
// Created by Noel Obaseki on 07/06/2022. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct MovieDetailsViewDestination: View { | ||
let movieId: String | ||
let viewModel: MovieListViewModel | ||
|
||
var body: some View { | ||
MovieDetailsView(viewModel: MovieDetailsViewModel(movieId: movieId)) | ||
.onDisappear(perform: { | ||
viewModel.loadMoviesIfNeeded() | ||
}) | ||
} | ||
} | ||
|
||
//struct MovieDetailsViewDestination_Previews: PreviewProvider { | ||
// static var previews: some View { | ||
// MovieDetailsViewDestination() | ||
// } | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// | ||
// MovieDetailViewModel.swift | ||
// Flicks | ||
// | ||
// Created by Noel Obaseki on 06/06/2022. | ||
// | ||
|
||
import Foundation | ||
import Combine | ||
|
||
|
||
class MovieDetailsViewModel: ObservableObject { | ||
|
||
private let movieId: String | ||
|
||
@Published var isLoading: Bool = false | ||
@Published var movieDetails: MovieDetails? = nil | ||
@Published var dataType: DataType = .noData | ||
|
||
@Published var isOffline = false | ||
@Published var showNoData = false | ||
@Published var showDetails = false | ||
|
||
private lazy var showOfflineView: AnyPublisher<Bool, Never> = { | ||
Publishers | ||
.CombineLatest3(self.$dataType, self.$isLoading, self.$movieDetails) | ||
.map { element in | ||
if element.0 == .cached, !element.1, element.2 != nil { | ||
return true | ||
} else { | ||
return false | ||
} | ||
} | ||
.eraseToAnyPublisher() | ||
}() | ||
|
||
private lazy var showNoDataLabel: AnyPublisher<Bool, Never> = { | ||
Publishers | ||
.CombineLatest(self.$movieDetails, self.$isLoading) | ||
.map { element in | ||
if element.0 == nil, !element.1 { | ||
return true | ||
} else { | ||
return false | ||
} | ||
} | ||
.eraseToAnyPublisher() | ||
}() | ||
|
||
private lazy var showDetailsView: AnyPublisher<Bool, Never> = { | ||
Publishers | ||
.CombineLatest(self.$movieDetails, self.$isLoading) | ||
.map { element in | ||
if element.0 != nil, !element.1 { | ||
return false | ||
} else { | ||
return true | ||
} | ||
} | ||
.eraseToAnyPublisher() | ||
}() | ||
|
||
@Published var error: Error? = nil | ||
|
||
let movieDetailsStore: MovieDetailsProtocol | ||
|
||
private var cancellableSet: Set<AnyCancellable> = [] | ||
|
||
init(movieId: String, movieDetailsStore: MovieDetailsProtocol = MovieDetailsService()) { | ||
self.movieId = movieId | ||
self.movieDetailsStore = movieDetailsStore | ||
|
||
showOfflineView.assign(to: &self.$isOffline) | ||
showNoDataLabel.assign(to: &self.$showNoData) | ||
showDetailsView.assign(to: &self.$showDetails) | ||
|
||
// NotificationCenter.default.publisher(for: .reachabilityChanged) | ||
// .sink(receiveValue: { [weak self] (notification) in | ||
// guard let self = self, let reachability = notification.object as? Reachability, | ||
// reachability.connection != .unavailable, self.dataType != .live else { return } | ||
// self.getMovieDetails() | ||
// }) | ||
// .store(in: &cancellableSet) | ||
|
||
bindStore() | ||
getMovieDetails() | ||
} | ||
|
||
func bindStore() { | ||
movieDetailsStore | ||
.movieDetailsSubject | ||
.sink { [weak self] (completion) in | ||
switch completion { | ||
case .finished: break | ||
case .failure(let error): | ||
self?.error = error | ||
} | ||
} receiveValue: { [weak self] (storeState) in | ||
self?.isLoading = false | ||
self?.dataType = storeState.dataType | ||
self?.movieDetails = storeState.movieDetails | ||
}.store(in: &cancellableSet) | ||
} | ||
|
||
func getMovieDetails() { | ||
self.isLoading = true | ||
movieDetailsStore.getMovieDetails(id: self.movieId) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// | ||
// ContentView.swift | ||
// Flicks | ||
// | ||
// Created by Noel Obaseki on 21/04/2022. | ||
// | ||
|
||
import SwiftUI | ||
import CoreData | ||
|
||
struct MovieListView: View { | ||
@Environment(\.managedObjectContext) private var viewContext | ||
|
||
@FetchRequest( | ||
sortDescriptors: [NSSortDescriptor(keyPath: \Movie.id, ascending: true)], | ||
animation: .default) | ||
private var movies: FetchedResults<Movie> | ||
|
||
@StateObject private var viewModel = MovieListViewModel() | ||
|
||
var body: some View { | ||
NavigationView { | ||
VStack(spacing: 0) { | ||
if viewModel.showNoData { | ||
Text("Unable to load Movies list") | ||
} else if viewModel.isLoading { | ||
ProgressView() | ||
.frame(width: 50, height: 50) | ||
} else { | ||
if viewModel.isOffline { | ||
OfflineBarView() | ||
} | ||
ScrollView { | ||
LazyVStack(spacing: 15) { | ||
ForEach(movies) { movie in | ||
NavigationLink(destination: MovieDetailsViewDestination(movieId: movie.id!, viewModel: viewModel)) { | ||
MovieView(movie: movie, height: 200) | ||
.background(Color.white) | ||
.cornerRadius(15) | ||
.shadow(radius: 3) | ||
} | ||
}.buttonStyle(PlainButtonStyle()) | ||
}.padding() | ||
} | ||
} | ||
} | ||
.navigationBarTitle("Movies", displayMode: .inline) | ||
} | ||
.background(Color(UIColor.systemGray6)) | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
//struct ContentView_Previews: PreviewProvider { | ||
// static var previews: some View { | ||
// MovieListView() | ||
// } | ||
//} |
Oops, something went wrong.