Skip to content

feat: update “Import account” ui #1316

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

Draft
wants to merge 30 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5277d15
feat: update “Import account” ui
zhouxl May 21, 2025
afa0025
feat: udpate multi-backup UI
zhouxl May 26, 2025
c02bc93
feat: rename ImportAccountListView
zhouxl May 29, 2025
97e1316
feat: avatar
zhouxl May 29, 2025
47da5c2
feat: Account Info View
zhouxl May 29, 2025
982b8c9
feat: multi-account on sidemenu
zhouxl Jun 3, 2025
726ba8e
feat: remove debug code
zhouxl Jun 3, 2025
3eeaf45
feat: fetch count of token and NFT for accounts
zhouxl Jun 4, 2025
fbccde9
feat: enable EVM
zhouxl Jun 4, 2025
0a97ced
feat: [SideMenu] sorted account by flow balance and nft count
zhouxl Jun 4, 2025
92f40a7
feat: remove useless code
zhouxl Jun 4, 2025
c7891d8
feat: remove error
zhouxl Jun 4, 2025
bfd95a1
feat: switch Profile
zhouxl Jun 4, 2025
eca50d0
feat: update avatar to square
zhouxl Jun 4, 2025
77f6e29
feat: upate setting Profile info
zhouxl Jun 5, 2025
614976a
feat: update account list on setting-1
zhouxl Jun 5, 2025
f9a24ba
feat: update Account Detail
zhouxl Jun 5, 2025
af47031
feat: UI for linked account page
zhouxl Jun 6, 2025
dbc15ec
feat: unlink account & add maincount to `sendTransaction` of FlowNetwork
zhouxl Jun 6, 2025
77aa81b
feat: don’t hide current account
zhouxl Jun 6, 2025
7d7b593
feat: update logic of account filter
zhouxl Jun 6, 2025
96b7121
feat: import profile
zhouxl Jun 7, 2025
fb6fef5
feat: sync multi-account by device
zhouxl Jun 9, 2025
be5ddc1
feat: update status of hide on account
zhouxl Jun 10, 2025
5f6e2e4
feat: update wallet user profile
zhouxl Jun 10, 2025
633f389
feat: remove testdata
zhouxl Jun 10, 2025
b4151b1
feat: update struct for account
zhouxl Jun 11, 2025
308159f
feat: create a new account
zhouxl Jun 12, 2025
d7b1f65
feat: create account on side menu
zhouxl Jun 12, 2025
6562b27
feat: update randomDifferentElements and rename filterAccounts
zhouxl Jun 12, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,4 @@ iOSInjectionProject/
.DS_Store
/FRW/App/Env/Dev/ServiceConfig.plist
/FRW/App/Env/Prod/ServiceConfig.plist
/.cursor
256 changes: 237 additions & 19 deletions FRW.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = "en"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand All @@ -49,6 +50,13 @@
ReferencedContainer = "container:FRW.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
2 changes: 2 additions & 0 deletions FRW/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ extension AppDelegate {
if UserManager.shared.isLoggedIn {
DeviceManager.shared.updateDevice()
}

UserManager.shared.start()
}

private func commonConfig() {
Expand Down
85 changes: 85 additions & 0 deletions FRW/Foundation/Model/AccountInfoProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// AccountInfoProtocol.swift
// FRW
//
// Created by cat on 5/29/25.
//

import FlowWalletKit
import SwiftUI

protocol AccountInfoProtocol {
var infoName: String { get }
var infoAddress: String { get }
var accountType: FWAccount.AccountType { get }

var walletMetadata: WalletUserProfile.User { get }

func avatar(isSelected: Bool, subAvatar: AvatarSource?) -> AvatarView
}

extension AccountInfoProtocol {
var walletMetadata: WalletUserProfile.User {
WalletManager.shared.walletAccount.readInfo(at: infoAddress)
}
}

// MARK: Account

extension FlowWalletKit.Account: AccountInfoProtocol {
func avatar(isSelected: Bool, subAvatar: AvatarSource?) -> AvatarView {
AvatarView(mainAvatar: .user(walletMetadata), subAvatar: subAvatar, backgroundColor: Color.Summer.cards, isSelected: isSelected)
}

var infoName: String {
walletMetadata.name
}

var infoAddress: String {
hexAddr
}

var accountType: FWAccount.AccountType {
.main
}
}

// MARK: COA

extension FlowWalletKit.COA: AccountInfoProtocol {
func avatar(isSelected: Bool, subAvatar: AvatarSource?) -> AvatarView {
AvatarView(mainAvatar: .user(walletMetadata), subAvatar: subAvatar, backgroundColor: Color.Summer.cards, isSelected: isSelected)
}

var infoName: String {
walletMetadata.name
}

var infoAddress: String {
address
}

var accountType: FWAccount.AccountType {
.coa
}
}

// MARK: FlowWalletKit.Account of AccountInfoProtocol

extension FlowWalletKit.ChildAccount: AccountInfoProtocol {
func avatar(isSelected: Bool, subAvatar: AvatarSource?) -> AvatarView {
AvatarView(mainAvatar: .url(icon ?? AppPlaceholder.imageURL), subAvatar: subAvatar, isSelected: isSelected)
}

var infoName: String {
name ?? "unknown"
}

var infoAddress: String {
address.hexAddr
}

var accountType: FWAccount.AccountType {
.child
}
}
56 changes: 56 additions & 0 deletions FRW/Foundation/Model/AccountModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// AccountModel.swift
// FRW
//
// Created by cat on 6/3/25.
//

import Foundation

struct AccountModel: Equatable {
static func == (lhs: AccountModel, rhs: AccountModel) -> Bool {
lhs.account.infoAddress == rhs.account.infoAddress
}

var account: any AccountInfoProtocol
/// not nil when account type is coa or child,other is nil
var mainAccount: (any AccountInfoProtocol)?
var flowCount: String
var nftCount: UInt
}

// MARK: - UI

extension AccountModel {
var hideFlow: Bool {
account.accountType == .child
}

var showAmount: String {
var amount = ""
let flowCount = Double(flowCount) ?? 0
if flowCount >= 0 {
Comment on lines +32 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Double(flowCount) conversion could fail silently if flowCount contains an invalid number format. Consider using a more robust number parsing approach or handling the failure case explicitly.

amount += "\(flowCount.formatCurrencyString()) Flow" + " | "
}
if nftCount >= 0 {
amount += "\(nftCount) NFT's"
}
return amount
}

func isSelected(_ address: String) -> Bool {
account.infoAddress == address
}

var isMain: Bool {
account.accountType == .main
}

var isCoa: Bool {
account.accountType == .coa
}

var isChild: Bool {
account.accountType == .child
}
}
2 changes: 1 addition & 1 deletion FRW/Foundation/Model/AddressBookInfoModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct Contact: Codable, Identifiable {
let domain: Domain?
let id: Int
let username: String?
var user: WalletAccount.User? = nil
var user: WalletUserProfile.User? = nil
var walletType: WalletType? = .flow

var needShowLocalAvatar: Bool {
Expand Down
49 changes: 49 additions & 0 deletions FRW/Foundation/Model/MockAccountInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import SwiftUI

struct MockAccountInfo: AccountInfoProtocol {
var infoName: String
var infoAddress: String
var accountType: FWAccount.AccountType
var walletMetadata: WalletUserProfile.User

func avatar(isSelected: Bool, subAvatar: AvatarSource?) -> AvatarView {
AvatarView(mainAvatar: .system("person.crop.circle.fill"), subAvatar: subAvatar, backgroundColor: Color.Summer.cards, isSelected: isSelected)
}
}

extension MockAccountInfo {
static func mockSamples() -> [MockAccountInfo] {
[
MockAccountInfo(
infoName: "mainAccount",
infoAddress: "0x1234567890abcdef",
accountType: .main,
walletMetadata: WalletUserProfile.User(emoji: .koala, address: "0x1234567890abcdef")
),
MockAccountInfo(
infoName: "Child",
infoAddress: "0xabcdef1234567890",
accountType: .child,
walletMetadata: WalletUserProfile.User(emoji: .lion, address: "0xabcdef1234567890")
),
MockAccountInfo(
infoName: "EVM",
infoAddress: "0x8e5b4a8e5b4a8e5b4a8e5b4a8e5b4a8e5b4a8e5b",
accountType: .coa,
walletMetadata: WalletUserProfile.User(emoji: .avocado, address: "0x8e5b4a8e5b4a8e5b4a8e5b4a8e5b4a8e5b4a8e5b")
),
]
}
}

extension AccountModel {
/// 生成一组典型的 AccountModel mock 测试数据
static func mockSamples() -> [AccountModel] {
let accounts = MockAccountInfo.mockSamples()
return [
AccountModel(account: accounts[0], mainAccount: nil, flowCount: "123.45", nftCount: 7),
AccountModel(account: accounts[1], mainAccount: accounts[0], flowCount: "0.00", nftCount: 0),
AccountModel(account: accounts[2], mainAccount: accounts[0], flowCount: "999.99", nftCount: 99),
]
}
}
2 changes: 1 addition & 1 deletion FRW/Foundation/Model/UserModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct UserInfo: Codable {

func toContactWithCurrentUserAddress() -> Contact {
let address = WalletManager.shared.getPrimaryWalletAddress()
var user: WalletAccount.User?
var user: WalletUserProfile.User?
if let addr = address {
user = WalletManager.shared.walletAccount.readInfo(at: addr)
}
Expand Down
2 changes: 1 addition & 1 deletion FRW/Modules/Alert/EmptyKeychainAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extension AlertViewController {
),
buttons: [
AlertView.ButtonItem(type: .primaryAction, title: "restore_wallet".localized, action: {
Router.route(to: RouteMap.RestoreLogin.restoreList)
Router.route(to: RouteMap.RestoreLogin.importAccountList)
}),

AlertView.ButtonItem(type: .normal, title: "tutorial_restore".localized, action: {
Expand Down
2 changes: 1 addition & 1 deletion FRW/Modules/Browser/View/BrowserAuthnView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ struct BrowserAuthnView: View {
.cornerRadius(12)
}

var user: WalletAccount.User {
var user: WalletUserProfile.User {
WalletManager.shared.walletAccount.readInfo(at: vm.walletAddress ?? "")
}

Expand Down
26 changes: 6 additions & 20 deletions FRW/Modules/EVM/View/EVMTagView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,22 @@

import SwiftUI

// MARK: - EVMTagView

struct EVMTagView: View {
var body: some View {
Text("EVM")
.font(.inter(size: 9))
.kerning(0.144)
.foregroundStyle(Color.white)
.frame(width: 36, height: 16)
.background(Color.Theme.evm)
.cornerRadius(8)
}
}

// MARK: - TagView

struct TagView: View {
var size: CGFloat = 8
var type: Contact.WalletType = .flow

var body: some View {
HStack {
if type != .flow {
Text(title)
.font(.inter(size: 9))
.kerning(0.144)
.font(.inter(size: size))
.foregroundStyle(Color.white)
.frame(height: 16)
.padding(.horizontal, 8)
.padding(.horizontal, 4)
.padding(.vertical, 2)
.background(BGColor)
.cornerRadius(8)
.clipShape(Capsule())
}
}
}
Expand Down Expand Up @@ -65,5 +51,5 @@ struct TagView: View {
}

#Preview {
TagView()
TagView(type: .evm)
}
Loading