Add login flow, session routing, and MainTab shell aligned with reference UI.

Implement token-based root routing, Android-matched login screen, five-slot MainTabBar with scan action, and placeholder tab pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 15:12:34 +08:00
parent e290656322
commit b7d74905b7
70 changed files with 1588 additions and 48 deletions

View File

@ -0,0 +1,59 @@
//
// AppButton.swift
// suixinkan
//
import SnapKit
import UIKit
/// Android `AppButton`
final class AppButton: UIButton {
enum Style {
case primary
case secondary
}
private let style: Style
init(title: String, style: Style = .primary) {
self.style = style
super.init(frame: .zero)
setupUI(title: title)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isEnabled: Bool {
didSet { updateAppearance() }
}
private func setupUI(title: String) {
titleLabel?.font = .systemFont(ofSize: 14, weight: .regular)
layer.cornerRadius = 10
clipsToBounds = true
setTitle(title, for: .normal)
updateAppearance()
snp.makeConstraints { make in
make.height.equalTo(46)
}
}
private func updateAppearance() {
switch style {
case .primary:
backgroundColor = isEnabled ? AppColor.primary : AppColor.buttonDisabled
setTitleColor(.white, for: .normal)
setTitleColor(.white, for: .disabled)
case .secondary:
backgroundColor = AppColor.secondaryButtonBackground
setTitleColor(AppColor.primary, for: .normal)
setTitleColor(AppColor.primary, for: .disabled)
alpha = isEnabled ? 1 : 0.6
}
}
}