Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

.DS_Store
FlatMate/Secrets.plist

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we all have to have a separate API key? Could we not just all use the same secrets.plist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope we are all using the same Api key and obviously I cant push the secrets.plist file in the github because this repo is public and the key would get corrupted right

.DS_Store
64 changes: 47 additions & 17 deletions FlatMate/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,65 @@ import SwiftUI

struct ContentView: View {
@EnvironmentObject var viewModel: AuthViewModel
@State private var isLoadingUser = true
@State private var fakeProgress: Double = 0 // We'll animate this from 0 to 1

var body: some View {
Group {
if viewModel.userSession != nil {
if viewModel.hasCompletedOnboarding {
MainView()
} else {
OnboardingPageView(onComplete: {
Task {
do {
try await viewModel.completeOnboarding() // Update Firebase and ViewModel
} catch {
print("DEBUG: Failed to mark onboarding as complete: \(error)")
}
}
})
if isLoadingUser {
// Custom Loading Screen
VStack(spacing: 20) {
Text("Loading your data...")
.font(.headline)

// Linear progress bar from 0..1
ProgressView(value: fakeProgress, total: 1.0)
.progressViewStyle(LinearProgressViewStyle(tint: .blue))
.frame(width: 200)

// Optional extra text
}
.onAppear {
// Animate our fake progress to 100% in ~2 seconds
withAnimation(.linear(duration: 2.0)) {
fakeProgress = 1.0
}
}

} else {
NavigationStack {
LandingPageView()
// Once done loading, show real content
if viewModel.userSession != nil {
if viewModel.hasCompletedOnboarding {
MainView()
} else {
OnboardingPageView(onComplete: {
Task {
do {
try await viewModel.completeOnboarding()
} catch {
print("DEBUG: Failed to mark onboarding as complete: \(error)")
}
}
})
}
} else {
NavigationStack {
LandingPageView()
}
}
}
}
.onAppear {
print("ContentView appeared")
.task {
// fetch the user from Firebase
await viewModel.fetchUser()
// Once the data is in, turn the loading flag off
isLoadingUser = false
}
}
}


Copy link

@doowoncho doowoncho Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental new line


#Preview {
ContentView()
}
Expand Down
41 changes: 41 additions & 0 deletions FlatMate/Models/PixabayImage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// PixabayImage.swift
// FlatMate
//
// Created by Ivan on 2025-02-04.
//

struct PixabayResponse: Decodable {
let total: Int
let totalHits: Int
let hits: [PixabayImage]
}

struct PixabayImage: Decodable, Identifiable {
let id: Int
let pageURL: String?
let type: String?
let tags: String?

let previewURL: String?
let previewWidth: Int?
let previewHeight: Int?

let webformatURL: String?
let webformatWidth: Int?
let webformatHeight: Int?

let largeImageURL: String?
let imageWidth: Int?
let imageHeight: Int?
let imageSize: Int?

let views: Int?
let downloads: Int?
let likes: Int?
let comments: Int?

let user_id: Int?
let user: String?
let userImageURL: String?
}
8 changes: 8 additions & 0 deletions FlatMate/Secrets.template.plist
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>PIXABAY_API_KEY</key>
<string>YOUR_PIXABAY_API_KEY</string>
</dict>
</plist>
51 changes: 51 additions & 0 deletions FlatMate/Services/PixabayService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// PixabayService.swift
// FlatMate
//
// Created by Ivan on 2025-02-04.
//


import Foundation
import Combine

/// Represents the entire JSON response from Pixabay



class PixabayService: ObservableObject {

private lazy var apiKey: String = {
guard
let path = Bundle.main.path(forResource: "Secrets", ofType: "plist"),
let dict = NSDictionary(contentsOfFile: path) as? [String: Any],
let key = dict["PIXABAY_API_KEY"] as? String
else {
fatalError("Couldn't find 'PIXABAY_API_KEY' in Secrets.plist.")
}
return key
}()

func fetchImages(query: String) -> AnyPublisher<[PixabayImage], Error> {

let encodedQuery = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? query

let urlString = "https://pixabay.com/api/?key=\(apiKey)&q=\(encodedQuery)&image_type=photo"

guard let url = URL(string: urlString) else {
return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
}

return URLSession.shared.dataTaskPublisher(for: url)
.tryMap { (data, response) -> Data in

return data
}
// Decode the JSON into `PixabayResponse`
.decode(type: PixabayResponse.self, decoder: JSONDecoder())
.map { $0.hits }
.receive(on: DispatchQueue.main)
// Convert to an AnyPublisher
.eraseToAnyPublisher()
}
}
49 changes: 29 additions & 20 deletions FlatMate/View/EditProfileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ struct EditProfileView: View {
@State private var selectedGuestFrequency: String = frequencies[0]
@State private var noiseTolerance: Double = 0.0
@State private var profileImage: UIImage? = nil
@State private var isImagePickerPresented = false
// @State private var isImagePickerPresented = false
@State private var errorMessage: String?
@State private var selectedItem: PhotosPickerItem? = nil
// @State private var selectedItem: PhotosPickerItem? = nil

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh so are we not gonna let users upload their own photos? Just using pixby?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont have any problems with letting users adding their photos but you have upload pictures manually for them right so i feel like pixabay is a better way of solving the limited picture issues.

@State private var updateSuccess: Bool = false
@State private var showPixabaySheet = false

var body: some View {
NavigationView {
Expand All @@ -56,39 +57,30 @@ struct EditProfileView: View {
.fill(Color.gray)
.frame(width: 100, height: 100)
}
PhotosPicker(
selection: $selectedItem,
matching: .images,
photoLibrary: .shared()
) {

Button {
// Show your pixabay sheet
showPixabaySheet = true
} label: {
Image(systemName: "plus")
.font(.system(size: 15, weight: .bold))
.foregroundColor(.white)
.frame(width: 30, height: 30)
.background(Circle().fill(Color("primary")))
.shadow(radius: 5)
}
.onChange(of: selectedItem) { oldValue, newValue in
Task {
if let data = try? await newValue?.loadTransferable(type: Data.self),
let uiImage = UIImage(data: data) {
DispatchQueue.main.async {
profileImage = uiImage
}
}
}
}
.offset(x: 35, y: 35)
}

}
.padding(.trailing, 10)
// First Name, Last Name, Date of Birth
VStack(alignment: .leading) {
ProfileField(title: "First Name", text: $firstName)
ProfileField(title: "Last Name", text: $lastName)
DatePicker("Date of Birth", selection: $dob, displayedComponents: .date)
.onChange(of: dob) {
age = calculateAge(from: dob)
.onChange(of: dob) { newDate in
age = calculateAge(from: newDate)
}
}
}
Expand Down Expand Up @@ -173,7 +165,24 @@ struct EditProfileView: View {
updateSuccess = false
}
} message: {
Text("Profile Updated Successfully")
Text("Changes Updated Successfully")
}.sheet(isPresented: $showPixabaySheet) {
PixabaySearchView { selectedImage in
// The user tapped a PixabayImage. We can load its largeImageURL or webformatURL.
if let urlStr = selectedImage.largeImageURL ?? selectedImage.webformatURL,
let url = URL(string: urlStr) {
Task {
do {
let (data, _) = try await URLSession.shared.data(from: url)
if let downloadedImg = UIImage(data: data) {
self.profileImage = downloadedImg
}
} catch {
print("Error downloading chosen Pixabay image: \(error.localizedDescription)")
}
}
}
}
}
}

Expand Down
Loading