Skip to content

fed-00006: Add bindings email - #27

Merged
alex-npmn merged 3 commits into
mainfrom
feature/fed-00006-bindingEmail
Jun 30, 2026
Merged

fed-00006: Add bindings email#27
alex-npmn merged 3 commits into
mainfrom
feature/fed-00006-bindingEmail

Conversation

@ckost9n

@ckost9n ckost9n commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Bindable var viewModel = viewModel
ScrollView {
VStack(alignment: .leading, spacing: 16) {
Text("auth_bindings_title")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

можно встроенный наивный кодген использовать, чтобы так стринги хрупко не писать

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Generate String Catalog Symbols» = Yes и все будет само кодгениться

Comment on lines +17 to +21
Text("auth_bindings_subtitle")
.font(.subheadline)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .center)
.multilineTextAlignment(.center)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

было бы хорошо такие вещи выносить в отдельные вью переменные чтобы в боди было легко читать состав, а сейчас фокус теряется из-за того, что весь экран заполнен модификаторами, плюс сам боди становится очень длинным

Comment on lines +13 to +17
Text("profile_edit_bind_email_title")
.font(.title3)
.fontWeight(.semibold)
.frame(maxWidth: .infinity, alignment: .center)
.multilineTextAlignment(.center)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

типа вот такое можно в переменную вынести внутри структуры EmailBindingView и было бы легко читать типа

VStack {
profile_edit_bind_email_title()
profile_edit_bind_email_subtitle()
email_binding_details()
}

типа такого

Comment on lines +18 to +26
Text("profile_edit_bind_email_subtitle")
.font(.subheadline)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .center)
.multilineTextAlignment(.center)
Text("email_binding_details")
.font(.footnote)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .center)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

а вообще тут все дублируется почти, так что еще лучше было бы сделать фабрику или кастомные модификатор, которые бы принимали параметры с различиями

Comment on lines +29 to +40
TextField(
String(localized: "profile_edit_bind_email_email_example"),
text: $viewModel.email
)
.keyboardType(.emailAddress)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.disabled(viewModel.isEmailLocked)
.padding(.horizontal, 14)
.padding(.vertical, 14)
.background(Color(uiColor: .secondarySystemGroupedBackground))
.clipShape(RoundedRectangle(cornerRadius: 12))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

тоже легко выносится в переменную с понятным названием

@State private var viewModel = EmailBindingViewModel()
@FocusState private var isCodeInputFocused: Bool

var body: some View {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

тут бы хорошо разбить весь боди на переменные, уж очень он длинный получился, больше 30 строк лучше не писать, читать код становится трудно

}
}

func confirmCode(onSuccess: @escaping (String) -> Void) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

почему замыкание, а не async await который может выдать ошибку?

Comment on lines +45 to +49
var formattedTimer: String {
let minutes = remainingSeconds / 60
let seconds = remainingSeconds % 60
return String(format: "%02d:%02d", minutes, seconds)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
var formattedTimer: String {
let minutes = remainingSeconds / 60
let seconds = remainingSeconds % 60
return String(format: "%02d:%02d", minutes, seconds)
}
var formattedTimer: String {
Duration.seconds(remainingSeconds)
.formatted(.time(pattern: .minuteSecond))
}

лучше так

private var cooldownTask: Task<Void, Never>?
private var stateChanged: ((State) -> Void)?
private let emailRegex =
try! Regex("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

сможем без форс анврапов?

Comment on lines +136 to +147
struct State {
let email: String
let code: String
let isSendingCode: Bool
let isConfirmingCode: Bool
let remainingSeconds: Int
let isEmailLocked: Bool
let canRequestCode: Bool
let isEmailValid: Bool
let canConfirm: Bool
let formattedTimer: String
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

если это вью модель (по названию не очевидно), то я бы поднял это на самый верх

@State private var viewModel = EmailLoginViewModel()
@FocusState private var isCodeInputFocused: Bool

var body: some View {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

тут я бы тоже вьюги вынес по переменным

.padding(.vertical, 14)
.background(Color(uiColor: .secondarySystemGroupedBackground))
.clipShape(RoundedRectangle(cornerRadius: 12))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

вообще всегда пустая строчка в коде - это верный признак того, что код можно разбить по разным функциям, или переменным, в нашем случае

@alex-npmn alex-npmn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

разнеси пожалуйста в бодях вещи по отдельным приватным компутед пропертям внутри той же структуры, где этот боди находится

тогда у тебя будет суперпонятный код типа

body {
VStack {
text
subtext
button
}
}

так же гораздо проще понимать, что к чему

ckost9n added 2 commits June 26, 2026 18:11
# Conflicts:
#	Friendly/Sources/ProfileEdit/ProfileEditView.swift
#	Friendly/Sources/ProfileEdit/ProfileEditViewModel.swift
@ckost9n
ckost9n force-pushed the feature/fed-00006-bindingEmail branch from 7b5331a to b639d79 Compare June 28, 2026 17:12
.focused($isFocused)
.opacity(0.01)
.frame(width: 1, height: 1)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

разобьешь тут тоже по переменным?

isPresented: .constant(viewModel.error != nil),
) {
Button("sign_up_error_ok") {
Button(String(localized: .signUpErrorOk)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

по моему не нужен инит через String()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

в основном везде есть инит по локализации

@alex-npmn
alex-npmn merged commit 401b60c into main Jun 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants