Skip to content

Commit

Permalink
New explore design
Browse files Browse the repository at this point in the history
  • Loading branch information
wuyuehyang committed Apr 12, 2024
1 parent 62043ef commit 6978789
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 287 deletions.
12 changes: 4 additions & 8 deletions Mixin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,8 @@
94B2CD782B0F88D300D268E1 /* DepositView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94B2CD772B0F88D300D268E1 /* DepositView.xib */; };
94B5776A2B5E554800AE576E /* ExploreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B577692B5E554800AE576E /* ExploreViewController.swift */; };
94B5776F2B5E555B00AE576E /* ExploreView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 94B5776E2B5E555B00AE576E /* ExploreView.xib */; };
94B577772B5E6E3700AE576E /* ExploreFavoriteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B577752B5E6E3700AE576E /* ExploreFavoriteViewController.swift */; };
94B5777D2B5E755100AE576E /* SeparatorHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B5777C2B5E755100AE576E /* SeparatorHeaderFooterView.swift */; };
94B577822B5E79B800AE576E /* ExploreAllAppsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B577812B5E79B800AE576E /* ExploreAllAppsViewController.swift */; };
94B577822B5E79B800AE576E /* ExploreBotsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B577812B5E79B800AE576E /* ExploreBotsViewController.swift */; };
94B577872B5EC11500AE576E /* ExploreAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B577862B5EC11500AE576E /* ExploreAction.swift */; };
94B61EC32B344A7A00BD39AF /* HomeTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B61EC22B344A7A00BD39AF /* HomeTabBarController.swift */; };
94B6EDFE2B707F15001DCC50 /* WithdrawPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B6EDFD2B707F15001DCC50 /* WithdrawPreviewViewController.swift */; };
Expand Down Expand Up @@ -2054,9 +2053,8 @@
94B2CD772B0F88D300D268E1 /* DepositView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DepositView.xib; sourceTree = "<group>"; };
94B577692B5E554800AE576E /* ExploreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreViewController.swift; sourceTree = "<group>"; };
94B5776E2B5E555B00AE576E /* ExploreView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExploreView.xib; sourceTree = "<group>"; };
94B577752B5E6E3700AE576E /* ExploreFavoriteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreFavoriteViewController.swift; sourceTree = "<group>"; };
94B5777C2B5E755100AE576E /* SeparatorHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorHeaderFooterView.swift; sourceTree = "<group>"; };
94B577812B5E79B800AE576E /* ExploreAllAppsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreAllAppsViewController.swift; sourceTree = "<group>"; };
94B577812B5E79B800AE576E /* ExploreBotsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreBotsViewController.swift; sourceTree = "<group>"; };
94B577862B5EC11500AE576E /* ExploreAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreAction.swift; sourceTree = "<group>"; };
94B61EC22B344A7A00BD39AF /* HomeTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTabBarController.swift; sourceTree = "<group>"; };
94B6EDFD2B707F15001DCC50 /* WithdrawPreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithdrawPreviewViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3849,8 +3847,7 @@
9473F8272AE51097004E5739 /* RegisterToSafeViewController.swift */,
94B5776E2B5E555B00AE576E /* ExploreView.xib */,
94B577692B5E554800AE576E /* ExploreViewController.swift */,
94B577752B5E6E3700AE576E /* ExploreFavoriteViewController.swift */,
94B577812B5E79B800AE576E /* ExploreAllAppsViewController.swift */,
94B577812B5E79B800AE576E /* ExploreBotsViewController.swift */,
94B13FC12B5ED5F9001333BE /* ExploreSearchView.xib */,
94B13FC02B5ED5F9001333BE /* ExploreSearchViewController.swift */,
94CF1F262BA1B74A00BC52C1 /* Web3WalletViewController.swift */,
Expand Down Expand Up @@ -5299,8 +5296,7 @@
7B5E9B4A243740C4000AE24E /* ConversationCircleEditorFooterView.swift in Sources */,
7BFE47E22284394000FC4379 /* CheckmarkPeerCell.swift in Sources */,
7CDF316C29890FB200421808 /* ConversationFontSet.swift in Sources */,
94B577772B5E6E3700AE576E /* ExploreFavoriteViewController.swift in Sources */,
94B577822B5E79B800AE576E /* ExploreAllAppsViewController.swift in Sources */,
94B577822B5E79B800AE576E /* ExploreBotsViewController.swift in Sources */,
7B369208233A43C1007321A7 /* SegmentedControl.swift in Sources */,
9427D51A25E0D42E00B1EF0E /* MusicInfoView.swift in Sources */,
7C2AC42928F2B384005F369A /* DepositSuspendedView.swift in Sources */,
Expand Down

This file was deleted.

220 changes: 220 additions & 0 deletions Mixin/UserInterface/Controllers/Home/ExploreBotsViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import UIKit
import MixinServices

final class ExploreBotsViewController: UITableViewController {

private enum FixedSection: Int, CaseIterable {
case actions = 0
case favorites
}

private let headerReuseID = "header"
private let actions: [ExploreAction] = [
.camera, .linkDesktop, .customerService,
]

private(set) var allUsers: [User]? = nil

private var favoriteAppUsers: [User] = []
private var indexTitles: [String]? = nil
private var indexedUsers: [[User]] = []

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = R.color.background()
tableView.separatorStyle = .none
tableView.register(R.nib.exploreActionCell)
tableView.register(R.nib.peerCell)
tableView.register(PeerHeaderView.self, forHeaderFooterViewReuseIdentifier: headerReuseID)
tableView.sectionIndexColor = R.color.text_tertiary()
tableView.rowHeight = 70
tableView.contentInset.bottom = 10
reloadFavoriteAppsFromLocal()
reloadFavoriteAppsFromRemote()
reloadAllApps()
let center: NotificationCenter = .default
center.addObserver(self,
selector: #selector(reloadAllApps),
name: UserDAO.usersDidChangeNotification,
object: nil)
center.addObserver(self,
selector: #selector(reloadFavoriteAppsFromLocal),
name: UserDAO.usersDidChangeNotification,
object: nil)
center.addObserver(self,
selector: #selector(reloadFavoriteAppsFromLocal),
name: FavoriteAppsDAO.favoriteAppsDidChangeNotification,
object: nil)
center.addObserver(self,
selector: #selector(updateLinkDesktopAction),
name: AppGroupUserDefaults.Account.extensionSessionDidChangeNotification,
object: nil)
}

// MARK: - UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int {
FixedSection.allCases.count + (indexTitles?.count ?? 0)
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch FixedSection(rawValue: section) {
case .actions:
actions.count
case .favorites:
favoriteAppUsers.count
default:
indexedUsers(at: section).count
}
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch FixedSection(rawValue: indexPath.section) {
case .actions:
let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.explore_action, for: indexPath)!
let action = actions[indexPath.row]
cell.load(action: action)
return cell
case .favorites:
if indexPath.row < favoriteAppUsers.count {
let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.peer, for: indexPath)!
let user = favoriteAppUsers[indexPath.row]
cell.peerInfoView.render(user: user, description: .identityNumber)
cell.peerInfoView.avatarImageView.hasShadow = false
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.explore_action, for: indexPath)!
cell.load(action: .editFavoriteApps)
return cell
}
default:
let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.peer, for: indexPath)!
let user = indexedUser(at: indexPath)
cell.peerInfoView.render(user: user, description: .identityNumber)
return cell
}
}

override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
indexTitles
}

override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
index + FixedSection.allCases.count
}

// MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
switch FixedSection(rawValue: section) {
case .actions:
0
default:
34
}
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerReuseID) as! PeerHeaderView
switch FixedSection(rawValue: section) {
case .actions:
return nil
case .favorites:
header.label.text = R.string.localizable.favorite()
return header
default:
header.label.text = indexTitles?[section - FixedSection.allCases.count]
return header
}
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let explore = parent as? ExploreViewController {
let user = indexedUser(at: indexPath)
explore.presentProfile(user: user)
}
}

@objc private func reloadAllApps() {

class ObjcAccessibleUser: NSObject {

@objc let fullName: String
let user: User

init(user: User) {
self.fullName = user.fullName ?? ""
self.user = user
super.init()
}

}

DispatchQueue.global().async {
let allUsers = UserDAO.shared.getAppUsers()
let objcAccessibleUsers = allUsers.map(ObjcAccessibleUser.init(user:))
let (titles, indexedObjcUsers) = UILocalizedIndexedCollation.current()
.catalog(objcAccessibleUsers, usingSelector: #selector(getter: ObjcAccessibleUser.fullName))
let indexedUsers = indexedObjcUsers.map { $0.map(\.user) }
DispatchQueue.main.async {
self.allUsers = allUsers
self.indexTitles = titles
self.indexedUsers = indexedUsers
self.tableView.reloadData()
self.tableView.checkEmpty(dataCount: allUsers.count,
text: R.string.localizable.no_bots(),
photo: R.image.emptyIndicator.ic_data()!)
}
}
}

@objc private func reloadFavoriteAppsFromLocal() {
DispatchQueue.global().async { [weak self] in
let users = FavoriteAppsDAO.shared.favoriteAppUsersOfUser(withId: myUserId)
DispatchQueue.main.async {
guard let self else {
return
}
self.favoriteAppUsers = users
let favorites = IndexSet(integer: FixedSection.favorites.rawValue)
UIView.performWithoutAnimation {
self.tableView.reloadSections(favorites, with: .none)
}
}
}
}

private func reloadFavoriteAppsFromRemote() {
UserAPI.getFavoriteApps(ofUserWith: myUserId) { (result) in
guard case let .success(apps) = result else {
return
}
DispatchQueue.global().async {
FavoriteAppsDAO.shared.updateFavoriteApps(apps, forUserWith: myUserId)
let appUserIds = apps.map({ $0.appId })
UserAPI.showUsers(userIds: appUserIds) { (result) in
guard case let .success(users) = result else {
return
}
UserDAO.shared.updateUsers(users: users)
}
}
}
}

@objc private func updateLinkDesktopAction() {
guard let row = actions.firstIndex(of: .linkDesktop) else {
return
}
let indexPath = IndexPath(row: row, section: FixedSection.actions.rawValue)
tableView.reloadRows(at: [indexPath], with: .none)
}

private func indexedUsers(at section: Int) -> [User] {
indexedUsers[section - FixedSection.allCases.count]
}

private func indexedUser(at indexPath: IndexPath) -> User {
indexedUsers(at: indexPath.section)[indexPath.row]
}

}
Loading

0 comments on commit 6978789

Please sign in to comment.