Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desafio Myllene Silva. #42

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file added Globoplay/.DS_Store
Binary file not shown.
769 changes: 769 additions & 0 deletions Globoplay/Globoplay.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "824FDE29-B1B1-4E2B-8C5F-595B4E544C59"
type = "1"
version = "2.0">
</Bucket>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?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>SchemeUserState</key>
<dict>
<key>Globoplay.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
Binary file added Globoplay/Globoplay/.DS_Store
Binary file not shown.
Binary file added Globoplay/Globoplay/Assets.xcassets/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"images" : [
{
"filename" : "app.jpg",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions Globoplay/Globoplay/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
50 changes: 50 additions & 0 deletions Globoplay/Globoplay/Features/Favorites/View/FavoritesView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// HomeView.swift
// Globoplay
//
// Created by Myllene Silva on 11/11/24.
//

import SwiftUI

struct FavoritesView: View {
@EnvironmentObject var viewModel: FavoritesViewModel

var body: some View {
NavigationStack {
ScrollView {
VStack {
HStack {
Text("Favorites")
.font(.title)
.foregroundColor(.white)
.fontWeight(.heavy)
Spacer()
}
.padding(.horizontal)
}
if viewModel.favorites.isEmpty {
Text("No Results")
.foregroundColor(.white)
.padding()
} else {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(viewModel.favorites) { movie in
NavigationLink {
MovieDetailView(movie: movie)
} label: {
MovieCard(movieItem: movie)
}
}
.padding(.horizontal)
}
Spacer()
}
}
}
.background(Color.backgroundColor)
}
.toolbar(.visible, for: .tabBar)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// FavoritesViewModel.swift
// Globoplay
//
// Created by Myllene Silva on 12/11/24.
//

import SwiftUI
import Foundation

class FavoritesViewModel: ObservableObject {
@Published var favorites: [MovieModel] = []
private let favoritesKey = "fav_key"

init() {
self.favorites = loadFavorites()
}

func loadFavorites() -> [MovieModel] {
if let savedFavorites = UserDefaults.standard.data(forKey: "favorites") {
let decoder = JSONDecoder()
if let loadedFavorites = try? decoder.decode([MovieModel].self, from: savedFavorites) {
return loadedFavorites
}
}
return []
}

func saveFavorites() {
do {
let data = try JSONEncoder().encode(favorites)
UserDefaults.standard.set(data, forKey: favoritesKey)
} catch {
print("Erro ao salvar favoritos: \(error)")
}
}

func addFavorite(movie: MovieModel) {
if !favorites.contains(where: { $0.id == movie.id }) {
favorites.append(movie)
saveFavorites()
}
}

func removeFavorite(movie: MovieModel) {
if let index = favorites.firstIndex(of: movie) {
favorites.remove(at: index)
saveFavorites()
}
}

func isFavorite(movie: MovieModel) -> Bool {
return favorites.contains(where: { $0.id == movie.id })
}
}
36 changes: 36 additions & 0 deletions Globoplay/Globoplay/Features/Home/Model/MovieModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// MovieModel.swift
// Globoplay
//
// Created by Myllene Silva on 12/11/24.
//

import Foundation

struct MovieModel: Identifiable, Codable, Equatable {
let id: Int
let title: String
let posterPath: String?
let backdropPath: String?
let overview: String
let releaseDate: String

var backdropURL: URL? {
let baseURL = URL(string: "https://image.tmdb.org/t/p/w300")!
guard let backdropPath else { return nil }
return baseURL.appending(path: backdropPath)
}

var posterUrl: URL? {
let posterUrl = URL(string: "https://image.tmdb.org/t/p/w100")!
guard let posterPath else { return nil }
return posterUrl.appending(path: posterPath)
}

enum CodingKeys: String, CodingKey {
case backdropPath = "backdrop_path"
case posterPath = "poster_path"
case releaseDate = "release_date"
case id, title, overview
}
}
104 changes: 104 additions & 0 deletions Globoplay/Globoplay/Features/Home/View/HomeView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// HomeView.swift
// Globoplay
//
// Created by Myllene Silva on 11/11/24.
//

import SwiftUI

struct HomeView: View {

@EnvironmentObject var homeViewModel: HomeViewModel
@EnvironmentObject var favoritesViewModel: FavoritesViewModel
@State var searchText: String = ""
@State private var isLoading = true
@State private var isTabBarHidden: Visibility = .visible

var body: some View {
ZStack {
Color.backgroundColor
.edgesIgnoringSafeArea(.all)

if isLoading {
ProgressView("Loading...")
.progressViewStyle(CircularProgressViewStyle())
.scaleEffect(2)
.padding(50)
.foregroundColor(.white)
} else {
VStack {
HStack {
Text("Movies")
.font(.title)
.foregroundColor(.white)
.fontWeight(.heavy)
Spacer()
}
.padding(.horizontal)

if searchText.isEmpty {
if homeViewModel.movies.isEmpty {
Text("No Results")
.foregroundColor(.white)
} else {
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(homeViewModel.movies) { movie in
NavigationLink {
MovieDetailView(movie: movie)
.environmentObject(favoritesViewModel)
.onAppear {
isTabBarHidden = .hidden
}
} label: {
MovieCard(movieItem: movie)
}
}
}
.padding(.horizontal)
}
}
}
} else {
List {
ForEach(homeViewModel.searchResults) { movie in
NavigationLink {
MovieDetailView(movie: movie)
.environmentObject(favoritesViewModel)
} label: {
HStack {
Text(movie.title)
.font(.headline)
.foregroundColor(.white)
.foregroundColor(Color.backgroundColor)
Spacer()
Image(systemName: favoritesViewModel.isFavorite(movie: movie) ? "star.fill" : "star")
}
}
}
}
.listStyle(PlainListStyle())
.background(Color.backgroundColor)
}
Spacer()
}
.padding(.top, 20)
}
}
.searchable(text: $searchText)
.onChange(of: searchText) { _, newValue in
if newValue.count > 2 {
homeViewModel.fetchSearch(title: newValue)
}
}
.onAppear {
homeViewModel.fetchMovies() { _ in
self.isLoading = false
}
isTabBarHidden = .visible
}
.toolbar(isTabBarHidden, for: .tabBar)
}
}
Loading