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

Improve URL and image handling for NewListingForm #512

Merged
merged 1 commit into from
Mar 15, 2024
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
28 changes: 26 additions & 2 deletions PennMobile/Subletting/Listings/NewListingForm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ import PennForms
import PennMobileShared
import OrderedCollections

struct URLValidator: Validator {
let message: String? = "Enter a valid URL"

func isValid(_ input: String?) -> Bool {
guard let input, !input.isEmpty else { return true }
guard let url = URL(string: input) else { return false }
guard let scheme = url.scheme else { return true }

return scheme.wholeMatch(of: /https?/.ignoresCase()) != nil
}
}

struct NewListingForm: View {
@EnvironmentObject var navigationManager: NavigationManager
@EnvironmentObject var sublettingViewModel: SublettingViewModel
Expand Down Expand Up @@ -91,8 +103,11 @@ struct NewListingForm: View {
NumericField($subletData.baths, title: "# Bath")
}

TextLineField($subletData.externalLink, placeholder: "e.g. https://lauder.house.upenn.edu", title: "External Link")
.validator(.required)
ComponentWrapper {
TextLineField($subletData.externalLink, placeholder: "e.g. https://lauder.house.upenn.edu", title: "External Link")
.validator(URLValidator())
.keyboardType(.URL)
}

DateField(date: $subletData.expiresAt, title: "Listing Expiry Date")
.validator(.required)
Expand Down Expand Up @@ -170,6 +185,15 @@ struct NewListingForm: View {
data.endDate = Day(date: endDate)
data.amenities = Array(selectedAmenities)

if let link = data.externalLink, let url = URL(string: link) {
if url.scheme == nil {
let newUrl = "https://\(link)"
if URL(string: newUrl) != nil {
data.externalLink = newUrl
}
}
}

Task {
var sublet = originalSublet

Expand Down
18 changes: 14 additions & 4 deletions PennMobileShared/Subletting/SublettingModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,17 @@ public struct SubletDraft: Identifiable, Codable, Hashable {
public let id: UUID
public var data: SubletData
public var images: [UIImage]
public var compressedImages = [UIImage: Data]()

public subscript<T>(dynamicMember keyPath: KeyPath<SubletData, T>) -> T {
data[keyPath: keyPath]
}

public init(id: UUID = UUID(), data: SubletData, images: [UIImage]) {
public init(id: UUID = UUID(), data: SubletData, images: [UIImage], compressedImages: [UIImage: Data] = [:]) {
self.id = id
self.data = data
self.images = images
self.compressedImages = compressedImages
}

public init(from decoder: Decoder) throws {
Expand All @@ -102,16 +104,24 @@ public struct SubletDraft: Identifiable, Codable, Hashable {
let container = try decoder.container(keyedBy: CodingKeys.self)
let id = try container.decode(UUID.self, forKey: .id)
let imageData = try container.decode([Data].self, forKey: .images)
let images = imageData.compactMap { UIImage(data: $0) }

self.init(id: id, data: data, images: images)
var images = [UIImage]()
var compressedImages = [UIImage: Data]()
for imageDatum in imageData {
if let image = UIImage(data: imageDatum) {
images.append(image)
compressedImages[image] = imageDatum
}
}

self.init(id: id, data: data, images: images, compressedImages: compressedImages)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try data.encode(to: encoder)
let imageData = images.compactMap { $0.pngData() }
let imageData = images.compactMap { compressedImages[$0] ?? $0.jpegData(compressionQuality: 0.5) }
try container.encode(imageData, forKey: .images)
}

Expand Down