Skip to content

Commit

Permalink
MOB-2154 - Load and display purchase domains suggestions (#629)
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleg-Pecheneg authored Aug 12, 2024
1 parent 1c3c2b1 commit b888266
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct PurchaseDomainsSearchView: View, ViewAnalyticsLogger {
@StateObject private var debounceObject = DebounceObject()
@StateObject private var ecommFlagTracker = UDMaintenanceModeFeatureFlagTracker(featureFlag: .isMaintenanceEcommEnabled)
private var localCart: PurchaseDomains.LocalCart { viewModel.localCart }
@State private var suggestions: [DomainToPurchaseSuggestion] = []
@State private var suggestions: [DomainToPurchase] = []
@State private var searchResultHolder: PurchaseDomains.SearchResultHolder = .init()
@State private var searchFiltersHolder: PurchaseDomains.SearchFiltersHolder = .init()
@State private var isLoading: Bool = false
Expand Down Expand Up @@ -195,12 +195,20 @@ private extension PurchaseDomainsSearchView {
if searchResultHolder.hasTakenDomains {
showHideTakenDomainsView()
}
suggestionsSectionView()
}

@ViewBuilder
func resultDomainsListView(_ domains: [DomainToPurchase]) -> some View {
domainsListViewWith(title: String.Constants.results.localized(),
domains: domains)
}

@ViewBuilder
func domainsListViewWith(title: String,
domains: [DomainToPurchase]) -> some View {
LazyVStack(alignment: .leading, spacing: 20) {
sectionTitleView(String.Constants.results.localized())
sectionTitleView(title)
ForEach(domains) { domain in
resultDomainRowView(domain)
}
Expand Down Expand Up @@ -261,35 +269,9 @@ private extension PurchaseDomainsSearchView {

@ViewBuilder
func suggestionsSectionView() -> some View {
UDCollectionSectionBackgroundView(withShadow: true) {
VStack(alignment: .leading, spacing: 16) {
HStack {
Image.statsIcon
.resizable()
.squareFrame(16)
Text(String.Constants.trending.localized())
.font(.currentFont(size: 14, weight: .semibold))
}
.foregroundColor(.foregroundDefault)

FlowLayoutView(suggestions) { suggestion in
Button(action: {
UDVibration.buttonTap.vibrate()
logButtonPressedAnalyticEvents(button: .suggestedName, parameters: [.value: suggestion.name])
search(text: suggestion.name, searchType: .suggestion)
debounceObject.text = suggestion.name
}, label: {
Text(suggestion.name)
.font(.currentFont(size: 14, weight: .medium))
.foregroundColor(.foregroundDefault)
.padding(EdgeInsets(top: 8, leading: 12,
bottom: 8, trailing: 12))
.background(Color.backgroundMuted2)
.cornerRadius(16)
})
}
}
.padding()
if !suggestions.isEmpty {
domainsListViewWith(title: String.Constants.suggestedForYou.localized(),
domains: suggestions)
}
}

Expand Down Expand Up @@ -362,7 +344,6 @@ private extension PurchaseDomainsSearchView {
private extension PurchaseDomainsSearchView {
func onAppear() {
setupSkeletonItemsWidth()
loadSuggestions()
}

func setupSkeletonItemsWidth() {
Expand All @@ -375,11 +356,14 @@ private extension PurchaseDomainsSearchView {
}

func loadSuggestions() {
guard suggestions.isEmpty else { return }

suggestions.removeAll()
let searchingText = self.searchingText
Task {
do {
let suggestions = try await purchaseDomainsService.getDomainsSuggestions(hint: nil)
let suggestions = try await purchaseDomainsService.getDomainsSuggestions(hint: searchingText,
tlds: searchFiltersHolder.tlds)
guard searchingText == self.searchingText else { return }

self.suggestions = suggestions
} catch {
Debugger.printFailure("Failed to load suggestions")
Expand All @@ -402,6 +386,7 @@ private extension PurchaseDomainsSearchView {
searchType: SearchResultType) {
let text = text.trimmedSpaces.lowercased()
guard searchingText != text else { return }
loadSuggestions()
searchingText = text
loadingError = nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ class BaseFirebaseInteractionService {
static var USER_PROFILE_URL: String { USER_URL.appendingURLPathComponent("profile") }

static var DOMAIN_URL: String { baseAPIURL.appendingURLPathComponent("domain") }
static var DOMAIN_SEARCH_URL: String { DOMAIN_URL.appendingURLPathComponents("search", "internal") }
static var DOMAIN_AI_SUGGESTIONS_URL: String { DOMAIN_URL.appendingURLPathComponents("search", "ai-suggestions") }
static var DOMAIN_SEARCH_URL: String { DOMAIN_URL.appendingURLPathComponents("search") }
static var DOMAIN_UD_SEARCH_URL: String { DOMAIN_SEARCH_URL.appendingURLPathComponents("internal") }
static var DOMAIN_SUGGESTIONS_URL: String { DOMAIN_SEARCH_URL.appendingURLPathComponents("suggestions") }
static var DOMAIN_AI_SUGGESTIONS_URL: String { DOMAIN_UD_SEARCH_URL.appendingURLPathComponents("ai-suggestions") }
static func DOMAIN_ENS_STATUS_URL(domain: String) -> String {
DOMAIN_URL.appendingURLPathComponents(domain, "ens-status")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ extension MockFirebaseInteractionsService: PurchaseDomainsServiceProtocol {
try await searchForDomains(key: "ai_" + hint)
}

func getDomainsSuggestions(hint: String?) async throws -> [DomainToPurchaseSuggestion] {
func getDomainsSuggestions(hint: String, tlds: Set<String>) async throws -> [DomainToPurchase] {
await Task.sleep(seconds: 0.4)

return ["greenfashion", "naturalstyle", "savvydressers", "ethicalclothes", "urbanfashions", "wearables", "consciouslook", "activegears", "minimalista", "outsizeoutfits", "styletone"].map { DomainToPurchaseSuggestion(name: $0) }
return try await searchForDomains(key: "suggest_" + hint)
}

func addDomainsToCart(_ domains: [DomainToPurchase]) async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ extension FirebasePurchaseDomainsService: PurchaseDomainsServiceProtocol {
return domains
}

func getDomainsSuggestions(hint: String?) async throws -> [DomainToPurchaseSuggestion] {
let domainProducts = try await aiSearchForFBDomains(hint: hint ?? "Anything you think is trending now")
return domainProducts.map { DomainToPurchaseSuggestion(name: $0.domain.label) }
func getDomainsSuggestions(hint: String, tlds: Set<String>) async throws -> [DomainToPurchase] {
let domainProducts = try await getDomainsSearchSuggestions(hint: hint,
tlds: tlds)
let domains = transformDomainProductItemsToDomainsToPurchase(domainProducts)
return domains
}

func addDomainsToCart(_ domains: [DomainToPurchase]) async throws {
Expand Down Expand Up @@ -177,9 +179,24 @@ private extension FirebasePurchaseDomainsService {
return searchResponse
}


func getDomainsSearchSuggestions(hint: String, tlds: Set<String>) async throws -> [Ecom.DomainProductItem] {
var queryComponents: [String : String] = ["q" : hint,
"page" : "1",
"rowsPerPage" : "10"]
var urlString = URLSList.DOMAIN_SUGGESTIONS_URL.appendingURLQueryComponents(queryComponents)
for tld in tlds {
urlString += "&extension[]=\(tld)"
}
let request = try APIRequest(urlString: urlString,
method: .get)
let response: SuggestDomainsResponse = try await NetworkService().makeDecodableAPIRequest(request)
return response.suggestions
}

func aiSearchForFBDomains(hint: String) async throws -> [Ecom.DomainProductItem] {
let queryComponents = ["extension" : "All",
"phrase" : hint]
let queryComponents: [String : String] = ["extension" : "All",
"phrase" : hint]
let urlString = URLSList.DOMAIN_AI_SUGGESTIONS_URL.appendingURLQueryComponents(queryComponents)
let request = try APIRequest(urlString: urlString,
method: .get)
Expand All @@ -188,8 +205,8 @@ private extension FirebasePurchaseDomainsService {
}

func makeSearchDomainsRequestWith(key: String) async throws -> SearchDomainsResponse {
let queryComponents = ["q" : key]
let urlString = URLSList.DOMAIN_SEARCH_URL.appendingURLQueryComponents(queryComponents)
let queryComponents: [String : String] = ["q" : key]
let urlString = URLSList.DOMAIN_UD_SEARCH_URL.appendingURLQueryComponents(queryComponents)
let request = try APIRequest(urlString: urlString,
method: .get)
let response: SearchDomainsResponse = try await NetworkService().makeDecodableAPIRequest(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ protocol PurchaseDomainsServiceProtocol {

func searchForDomains(key: String) async throws -> [DomainToPurchase]
func aiSearchForDomains(hint: String) async throws -> [DomainToPurchase]
func getDomainsSuggestions(hint: String?) async throws -> [DomainToPurchaseSuggestion]
func getDomainsSuggestions(hint: String, tlds: Set<String>) async throws -> [DomainToPurchase]

func authoriseWithWallet(_ wallet: UDWallet, toPurchaseDomains domains: [DomainToPurchase]) async throws
func setDomainsToPurchase(_ domains: [DomainToPurchase]) async throws
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@
"CHECKOUT_FROM_WEB_PULL_UP_TITLE" = "Checkout from website";
"CHECKOUT_FROM_WEB_PULL_UP_SUBTITLE" = "For purchases above $10,000 at once, checkout is only possible using crypto. However, the app currently doesn’t support crypto checkout.";
"ENDINGS" = "Endings";
"SUGGESTIONS" = "Suggestions";

// Home
"HOME_WALLET_TOKENS_COME_TITLE" = "No more tokens here yet";
Expand Down

0 comments on commit b888266

Please sign in to comment.