Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/yale-swe/f23-here
Browse files Browse the repository at this point in the history
  • Loading branch information
Lindsay-00 committed Nov 27, 2023
2 parents 22374ed + 60a0e88 commit ae9dcb0
Show file tree
Hide file tree
Showing 30 changed files with 908 additions and 490 deletions.
104 changes: 0 additions & 104 deletions Message_View.swift

This file was deleted.

7 changes: 7 additions & 0 deletions app/newHere1/newHere/CustomARView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@
//
// Created by TRACY LI on 2023/10/28.
//
// Description:
// This file defines a CustomARView class, which is a subclass of ARView from RealityKit.
// It's designed to be used for augmented reality experiences within the 'new_here' application.

import ARKit
import RealityKit
import SwiftUI

/// CustomARView is a subclass of ARView for creating custom AR experiences.
class CustomARView: ARView {
/// Initializes and returns a newly allocated view object with the specified frame rectangle.
required init (frame frameRect: CGRect){
super.init(frame: frameRect)
}

/// Returns an object initialized from data in a given unarchiver.
dynamic required init?(coder decoder: NSCoder){
fatalError("init(coder:) has not been implemented")
}

/// Convenience initializer to create a view with the main screen bounds.
convenience init(){
self.init(frame: UIScreen.main.bounds)
}
Expand Down
27 changes: 15 additions & 12 deletions app/newHere1/newHere/CustomARViewRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,32 @@
//
// Created by TRACY LI on 2023/10/28.
//
// Description:
// This Swift file defines a SwiftUI UIViewRepresentable for integrating ARKit functionality.
// It allows for rendering AR content, such as 3D bubbles with messages, in the 'new_here' application.
//

import SwiftUI
import ARKit

//class ARViewModel: ObservableObject {
// var messageToPlant: Message?
//
// func plantMessage(_ message: Message) {
// messageToPlant = message
// }
//}

struct CustomARViewRepresentable: UIViewRepresentable {
// Binding for user ID
@Binding var userId: String

// Environment objects for message and fetched messages states
@EnvironmentObject var messageState: MessageState
@EnvironmentObject var fetchedMessagesState: FetchedMessagesState

// Create the ARSCNView and configure it
func makeUIView(context: Context) -> ARSCNView {
// return CustomARView()
let sceneView = ARSCNView()
sceneView.delegate = context.coordinator

let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)
print("user id: \(userId)")

// Fetch and render user's messages
getUserMessages(userId: userId) {
result in
switch result {
Expand Down Expand Up @@ -60,6 +61,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {
return sceneView
}

// Update the AR view when a new message is available
func updateUIView (_ uiView: ARSCNView, context: Context) {
if let messageToPlant = messageState.currentMessage {
plantBubbleNode(to: uiView, message: messageToPlant)
Expand All @@ -68,6 +70,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {

}

// Create a coordinator for handling ARSCNViewDelegate methods
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
Expand All @@ -80,6 +83,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {
}
}

// Plant a bubble node with a message at a specific position
func plantBubbleNode(to sceneView: ARSCNView, message: Message) {
// Set the position based on the provided position
if let frame = sceneView.session.currentFrame {
Expand All @@ -99,6 +103,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {
}
}

// Render a history of bubble nodes with messages at random positions
func renderBubbleNodeHistory(to sceneView: ARSCNView, messages: [Message]) {
// Create a random number generator
var randomNumberGenerator = SystemRandomNumberGenerator()
Expand All @@ -121,6 +126,7 @@ struct CustomARViewRepresentable: UIViewRepresentable {
}
}

// Create a new bubble node with a message at a specified position
func newBubbleNode(to sceneView: ARSCNView, message:Message, position:SCNVector3) {
let bubble = SCNSphere(radius: 0.05)
bubble.firstMaterial?.diffuse.contents = UIColor(red: 135.0/255.0, green: 206.0/255.0, blue: 235.0/255.0, alpha: 1.0)
Expand All @@ -132,9 +138,6 @@ struct CustomARViewRepresentable: UIViewRepresentable {
textGeometry1.firstMaterial?.diffuse.contents = UIColor.black
let textNode1 = SCNNode(geometry: textGeometry1)


// TEXT POSITIONING RELATIVE TO BUBBLE - WILL HAVE TO ADJUST LATER

// Position the first textNode inside the bubble
textNode1.position = SCNVector3(-0.05, 0, -0.05) // Adjust the position inside the bubble
textNode1.scale = SCNVector3(0.001, 0.001, 0.001)
Expand Down
38 changes: 29 additions & 9 deletions app/newHere1/newHere/LoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,28 @@
//
// Created by TRACY LI on 2023/11/7.
//
// Description:
// This Swift file defines the LoginView, which is responsible for user login in the 'newHere' application.
// It includes input fields for username and password, and login logic to communicate with a remote server.
//

import SwiftUI

// Define the URL and API Key for the login API
let loginUrlString = "https://here-swe.vercel.app/auth/login"
let logApiKey = "qe5YT6jOgiA422_UcdbmVxxG1Z6G48aHV7fSV4TbAPs"

struct LoginView: View {
// User input fields
@State internal var username: String = ""
@State internal var password: String = ""

// State variables
@State internal var isRegistered = false
@Binding var isAuthenticated: Bool
@Binding var user_id: String

// Alert properties to display login status
@State internal var showingAlert = false
@State internal var alertMessage = ""

Expand All @@ -28,18 +37,21 @@ struct LoginView: View {
.font(.largeTitle)
.padding(.bottom, 50)

// Username input field
TextField("Username", text: $username)
.padding()
.background(Color(.systemGray6))
.cornerRadius(5.0)
.padding(.bottom, 20)

// Password input field
SecureField("Password", text: $password)
.padding()
.background(Color(.systemGray6))
.cornerRadius(5.0)
.padding(.bottom, 20)

// Login button
Button(action: LogInUser) {
Text("Login")
.frame(minWidth: 0, maxWidth: .infinity)
Expand All @@ -51,6 +63,7 @@ struct LoginView: View {
}
.padding(.horizontal)

// Navigation link to registration view
NavigationLink(destination: RegistrationView(isRegistered: $isRegistered, userId: $user_id)) {
Text("Don't have an account? Signup")
}
Expand All @@ -64,7 +77,8 @@ struct LoginView: View {
}
}
}


// Function to handle user login
func LogInUser(){
if username.isEmpty || password.isEmpty {
self.alertMessage = "Please enter both username and password."
Expand All @@ -73,28 +87,35 @@ struct LoginView: View {
}

print("Login user called")

// Prepare the request body with user input
let requestBody: [String: Any] = [
"inputLogin": username,
"password": password]

// Convert the request body to JSON data
guard let jsonData = try? JSONSerialization.data(withJSONObject: requestBody)
else{
return
}

// Create the URL for the login API
guard let url = URL(string: loginUrlString) else {
return
}

// Create a URLRequest for the API request
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(logApiKey, forHTTPHeaderField: "x-api-key")


// Perform the network request
URLSession.shared.dataTask(with: request) { data, response, error in
DispatchQueue.main.async {
if let error = error{
// Handle network error
self.alertMessage = "Login failed: \(error.localizedDescription)"
self.showingAlert = true
}else if let httpResponse = response as? HTTPURLResponse{
Expand All @@ -109,6 +130,7 @@ struct LoginView: View {
if let json = try JSONSerialization.jsonObject(with: jsonData, options:[]) as? [String: Any],
let extractedUserId = json["_id"] as? String {
print("User id: \(extractedUserId)")
// Extract and store user ID
self.user_id = extractedUserId;
print("updated: \(self.user_id)")
UserDefaults.standard.set(extractedUserId, forKey: "UserId")
Expand All @@ -118,26 +140,30 @@ struct LoginView: View {
if let json = try JSONSerialization.jsonObject(with: jsonData, options:[]) as? [String: Any],
let userName = json["userName"] as? String {
print("User Name:\(userName)")
// Store user's username
UserDefaults.standard.set(userName, forKey: "UserName")
}
} catch {
print("Error parsing JSON: \(error)")
}
}
}
// Set the user as authenticated
self.isAuthenticated = true;
print("authenticated: \(self.isAuthenticated)")
print("user_id: \(self.user_id)")
}
}else if statusCode == 404 {
// Handle user not found
self.alertMessage = "User not found. Please check your credentials."
self.showingAlert = true
}else{
// Handle other server errors
self.alertMessage = "Login failed: Server returned status code \(httpResponse.statusCode)"
self.showingAlert = true
}
}else{
// General error
// Handle unexpected errors
self.alertMessage = "Login failed: Unexpected error occurred"
self.showingAlert = true
}
Expand All @@ -148,9 +174,3 @@ struct LoginView: View {
}

}
//// Preview Provider
//struct LoginView_Previews: PreviewProvider {
// static var previews: some View {
// LoginView(isAuthenticated: $isAuthenticated)
// }
//}
Loading

0 comments on commit ae9dcb0

Please sign in to comment.