Skip to content

Commit

Permalink
Merge pull request #23 from yale-swe/tracy_dev
Browse files Browse the repository at this point in the history
Merge tracy_dev
  • Loading branch information
TracyL5982 authored Dec 8, 2023
2 parents 93e2e1e + 61389c5 commit 5a2d2b7
Show file tree
Hide file tree
Showing 182 changed files with 321 additions and 37 deletions.
12 changes: 10 additions & 2 deletions app/newHere1/newHere.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
7194CFD42B2153D30094BE56 /* PhotoLibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7194CFD32B2153D30094BE56 /* PhotoLibraryManager.swift */; };
7194CFD62B2153DA0094BE56 /* ScreenshotUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7194CFD52B2153DA0094BE56 /* ScreenshotUtility.swift */; };
7194CFDC2B2154740094BE56 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7194CFDB2B2154740094BE56 /* ShareSheet.swift */; };
7194CFE42B2367AA0094BE56 /* UserProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7194CFE32B2367AA0094BE56 /* UserProfileViewModel.swift */; };
7194CFE62B2367BE0094BE56 /* EditProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7194CFE52B2367BE0094BE56 /* EditProfile.swift */; };
71D79DA22B1570E4009A054C /* BubbleAnimation.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 71D79DA12B1570E4009A054C /* BubbleAnimation.atlas */; };
FE32AC982B159A650056B003 /* PostTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE32AC972B159A650056B003 /* PostTest.swift */; };
FE32AC9A2B159A9E0056B003 /* MockMessageState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE32AC992B159A9E0056B003 /* MockMessageState.swift */; };
Expand Down Expand Up @@ -89,6 +91,8 @@
7194CFD32B2153D30094BE56 /* PhotoLibraryManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibraryManager.swift; sourceTree = "<group>"; };
7194CFD52B2153DA0094BE56 /* ScreenshotUtility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScreenshotUtility.swift; sourceTree = "<group>"; };
7194CFDB2B2154740094BE56 /* ShareSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = "<group>"; };
7194CFE32B2367AA0094BE56 /* UserProfileViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserProfileViewModel.swift; sourceTree = "<group>"; };
7194CFE52B2367BE0094BE56 /* EditProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditProfile.swift; sourceTree = "<group>"; };
71D79DA12B1570E4009A054C /* BubbleAnimation.atlas */ = {isa = PBXFileReference; lastKnownFileType = folder.skatlas; path = BubbleAnimation.atlas; sourceTree = "<group>"; };
FE32AC972B159A650056B003 /* PostTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PostTest.swift; path = newHereTests/PostTest.swift; sourceTree = SOURCE_ROOT; };
FE32AC992B159A9E0056B003 /* MockMessageState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMessageState.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -217,6 +221,7 @@
71D79DA52B15758E009A054C /* Profile */ = {
isa = PBXGroup;
children = (
7194CFE52B2367BE0094BE56 /* EditProfile.swift */,
1531A90A2AED964A009F644E /* Profile.swift */,
);
path = Profile;
Expand Down Expand Up @@ -293,6 +298,7 @@
71D79DAD2B1578F5009A054C /* Models */ = {
isa = PBXGroup;
children = (
7194CFE32B2367AA0094BE56 /* UserProfileViewModel.swift */,
1531A9122AEDAE2A009F644E /* LocationDataManager.swift */,
);
path = Models;
Expand Down Expand Up @@ -478,12 +484,14 @@
1531A90D2AED9663009F644E /* Messages.swift in Sources */,
158392302AFC72D3007A53C7 /* CustomARViewRepresentable.swift in Sources */,
7194CFD42B2153D30094BE56 /* PhotoLibraryManager.swift in Sources */,
7194CFE62B2367BE0094BE56 /* EditProfile.swift in Sources */,
1531A90F2AED9917009F644E /* Post.swift in Sources */,
1531A9152AEDCADB009F644E /* Message.swift in Sources */,
1531A9092AED9618009F644E /* Home.swift in Sources */,
158392332AFC72F3007A53C7 /* LoginView.swift in Sources */,
158392312AFC72D3007A53C7 /* CustomARView.swift in Sources */,
1531A8DE2AED95FD009F644E /* newHereApp.swift in Sources */,
7194CFE42B2367AA0094BE56 /* UserProfileViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -668,7 +676,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"newHere/Preview Content\"";
DEVELOPMENT_TEAM = A7X36A78B2;
DEVELOPMENT_TEAM = W23Y365YR7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand Down Expand Up @@ -713,7 +721,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"newHere/Preview Content\"";
DEVELOPMENT_TEAM = A7X36A78B2;
DEVELOPMENT_TEAM = W23Y365YR7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
Expand Down
29 changes: 29 additions & 0 deletions app/newHere1/newHere/Assets.xcassets/Color.colorset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"colors" : [
{
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
18 changes: 18 additions & 0 deletions app/newHere1/newHere/Models/UserProfileViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// UserProfileViewModel.swift
// newHere
//
// Created by YIMING GUAN on 2023/12/7.
//

import Foundation
import SwiftUI

class UserProfileViewModel: ObservableObject {
@Published var username: String = userName
@Published var email: String = userEmail
@Published var profileImage: UIImage? = nil
// Add other profile properties here

// Implement methods to update these properties, for example, from an API
}
49 changes: 49 additions & 0 deletions app/newHere1/newHere/Utils/api_call.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ struct MessageResponse: Codable {
let location: GeoJSONPoint
}

//// Structure for updating user profile
struct UpdateProfileRequest: Codable {
let userName: String?
let email: String?
let avatar: String? // Assuming avatar is a string (URL or base64 encoded image)
}

//// Structure for response of adding a friend
struct AddFriendResponse: Codable {
let message: String
Expand All @@ -74,6 +81,46 @@ struct UserMessage: Codable {
let replies: [String]
}

//// api call to update user profile
func updateUserProfile(userId: String, userName: String?, email: String?, avatar: String?, completion: @escaping (Result<Bool, Error>) -> Void) {
let urlString = "https://here-swe.vercel.app/user/\(userId)/update-profile" // Adjust URL as needed

guard let url = URL(string: urlString) else {
completion(.failure(URLError(.badURL)))
return
}

var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(apiKey, forHTTPHeaderField: "X-API-Key")

let requestBody = UpdateProfileRequest(userName: userName, email: email, avatar: avatar)
do {
request.httpBody = try JSONEncoder().encode(requestBody)
} catch {
completion(.failure(error))
return
}

let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
completion(.failure(error))
return
}

guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
completion(.failure(URLError(.badServerResponse)))
return
}

completion(.success(true))
}

task.resume()
}


//// Function to fetch user messages
func getUserMessages(userId: String, completion: @escaping (Result<[MessageResponse], Error>) -> Void) {
// API URL
Expand Down Expand Up @@ -474,6 +521,8 @@ func updateMetrics(completion: @escaping (Result<Bool, Error>) -> Void) {

task.resume()
}


//getAllUserFriends(userId: <#T##String#>, completion: <#T##(Result<[String : String], Error>) -> Void#>) { friendsList in
// guard let friendsList = friendsList else {
// print("Failed to fetch friends list.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {
textureAtlas.textureNames.forEach { print($0) } // Print each texture name

for i in 0..<numImages {
let textureName = "bubble-final\(String(format: "%04d", i))"
let textureName = "bubble-final\(String(format: "%03d", i))"
let texture = textureAtlas.textureNamed(textureName)
frames.append(texture)
}
Expand Down
2 changes: 1 addition & 1 deletion app/newHere1/newHere/Views/Home/Home.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct HomePageView: View {
HStack(alignment: .bottom, spacing: 28.0) {
Button(action: {updateARState.updateTrue = true})
{
Image(systemName: "map")
Image(systemName: "arrow.clockwise")
.foregroundColor(.white)
}

Expand Down
7 changes: 6 additions & 1 deletion app/newHere1/newHere/Views/Login/LoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let logApiKey = "qe5YT6jOgiA422_UcdbmVxxG1Z6G48aHV7fSV4TbAPs"

let userId = UserDefaults.standard.string(forKey: "UserId") ?? ""
let userName = UserDefaults.standard.string(forKey: "UserName") ?? ""

let userEmail = UserDefaults.standard.string(forKey: "UserEmail") ?? ""

/**
* LoginView
Expand Down Expand Up @@ -159,6 +159,11 @@ struct LoginView: View {
// Store the extracted username in UserDefaults.
UserDefaults.standard.set(userName, forKey: "UserName")
}
if let email = json["email"] as? String {
print("Email:\(email)")
// Store the extracted username in UserDefaults.
UserDefaults.standard.set(email, forKey: "UserEmail")
}
}
} catch {
// If JSON parsing fails, print an error message.
Expand Down
155 changes: 155 additions & 0 deletions app/newHere1/newHere/Views/Profile/EditProfile.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//
// EditProfile.swift
// newHere
//
// Created by TRACY LI on 2023/12/7.
//

import SwiftUI

struct EditProfile: View {
@Binding var isPresented: Bool
@ObservedObject var viewModel: UserProfileViewModel
@State private var image: Image? = Image(systemName: "person.crop.circle.fill")
@State private var isShowingImagePicker = false
@State private var inputImage: UIImage?
@State private var username: String = ""
@State private var email: String = ""

var body: some View {
VStack {
// Top bar with close button
HStack {
Spacer()
Button(action: {
isPresented.toggle()
}) {
Image(systemName: "xmark.circle")
.font(.system(size: 28))
.foregroundColor(.white)
.shadow(radius: 2.0)
}
.padding(.trailing, 20)
}
.padding(.vertical, 8)

// Edit Profile: Avatar photo, Name, Bio
VStack(alignment: .leading) {
// User Avatar
Button(action: {
self.isShowingImagePicker = true
}) {
VStack {
image?
.resizable()
.scaledToFill()
.clipShape(Circle())
.frame(width: 100, height: 100)
.shadow(radius: 3)
.foregroundColor(Color.white)

Text("Edit Profile Picture")
.foregroundColor(.white)
}
}
.sheet(isPresented: $isShowingImagePicker, onDismiss: loadImage) {
ImagePicker(image: self.$inputImage)
}

// Username Input
Text("Username:")
.foregroundColor(.white)
TextField("Enter new username", text: $username)
.textFieldStyle(RoundedBorderTextFieldStyle())
// Bio Input
Text("Email:")
.foregroundColor(.white)
TextField("Enter new email", text: $email)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding()

// Save Button
Button(action: {
// Action to save the profile details
saveProfile(userId: userId)
}) {
Text("Save")
.foregroundColor(.white)
.padding()
.frame(maxWidth: .infinity)
.background(Color.white.opacity(0.5))
.cornerRadius(10)
}
.padding()

Spacer()
}
.frame(width: 350, height: 600)
.padding(.top, 10)
.padding(.bottom, 10)
}

func loadImage() {
guard let inputImage = inputImage else { return }
image = Image(uiImage: inputImage)
viewModel.profileImage = inputImage
}
func saveProfile(userId: String) {
let userId = userId // Replace with actual user ID

let userNameToUpdate: String? = username.isEmpty ? nil : username
let emailToUpdate: String? = email.isEmpty ? nil : email
let avatarToUpdate: String? = nil // Replace with actual logic to handle avatar updates

updateUserProfile(userId: userId, userName: userNameToUpdate, email: emailToUpdate, avatar: avatarToUpdate) { result in
DispatchQueue.main.async {
switch result {
case .success:
print("Profile updated successfully.")
// Handle successful update (e.g., show confirmation message)
self.viewModel.username = self.username
self.viewModel.email = self.email
case .failure(let error):
print("Error updating profile: \(error.localizedDescription)")
// Handle error (e.g., show error message)
}
}
}
}
}

struct ImagePicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
@Binding var image: UIImage?

func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}

func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let parent: ImagePicker

init(_ parent: ImagePicker) {
self.parent = parent
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let uiImage = info[.originalImage] as? UIImage {
parent.image = uiImage
}

parent.presentationMode.wrappedValue.dismiss()
}
}
}


Loading

0 comments on commit 5a2d2b7

Please sign in to comment.