add delete solo session
This commit is contained in:
parent
020aa8de5d
commit
854561b5f7
@ -345,6 +345,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Вы выйдете из выбранной сессии." : {
|
||||
"comment" : "Описание подтверждения завершения конкретной сессии"
|
||||
},
|
||||
"Вы выйдете со всех устройств, кроме текущего." : {
|
||||
"comment" : "Описание подтверждения завершения сессий"
|
||||
},
|
||||
@ -458,7 +461,7 @@
|
||||
|
||||
},
|
||||
"Завершить" : {
|
||||
"comment" : "Подтверждение завершения других сессий"
|
||||
"comment" : "Кнопка завершения конкретной сессии\nПодтверждение завершения других сессий\nПодтверждение завершения конкретной сессии"
|
||||
},
|
||||
"Завершить другие сессии" : {
|
||||
"comment" : "Кнопка завершения других сессий"
|
||||
@ -466,6 +469,9 @@
|
||||
"Завершить сессии на других устройствах?" : {
|
||||
"comment" : "Заголовок подтверждения завершения сессий"
|
||||
},
|
||||
"Завершить эту сессию?" : {
|
||||
"comment" : "Заголовок подтверждения завершения отдельной сессии"
|
||||
},
|
||||
"Заглушка: Push-уведомления" : {
|
||||
|
||||
},
|
||||
|
||||
@ -7,6 +7,8 @@ struct ActiveSessionsView: View {
|
||||
@State private var revokeInProgress = false
|
||||
@State private var activeAlert: SessionsAlert?
|
||||
@State private var showRevokeConfirmation = false
|
||||
@State private var sessionPendingRevoke: SessionViewData?
|
||||
@State private var revokingSessionIds: Set<UUID> = []
|
||||
|
||||
private let sessionsService = SessionsService()
|
||||
private var currentSession: SessionViewData? {
|
||||
@ -60,7 +62,18 @@ struct ActiveSessionsView: View {
|
||||
if !otherSessions.isEmpty {
|
||||
Section(header: Text(String(format: NSLocalizedString("Другие устройства (%d)", comment: "Заголовок секции других устройств с количеством"), otherSessions.count))) {
|
||||
ForEach(otherSessions) { session in
|
||||
sessionRow(for: session)
|
||||
let isRevoking = isRevoking(session: session)
|
||||
|
||||
sessionRow(for: session, isRevoking: isRevoking)
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||
Button(role: .destructive) {
|
||||
sessionPendingRevoke = session
|
||||
} label: {
|
||||
Label(NSLocalizedString("Завершить", comment: "Кнопка завершения конкретной сессии"), systemImage: "trash")
|
||||
}
|
||||
.disabled(isRevoking)
|
||||
}
|
||||
.disabled(isRevoking)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,6 +87,24 @@ struct ActiveSessionsView: View {
|
||||
.refreshable {
|
||||
await loadSessions(force: true)
|
||||
}
|
||||
.confirmationDialog(
|
||||
NSLocalizedString("Завершить эту сессию?", comment: "Заголовок подтверждения завершения отдельной сессии"),
|
||||
isPresented: Binding(
|
||||
get: { sessionPendingRevoke != nil },
|
||||
set: { if !$0 { sessionPendingRevoke = nil } }
|
||||
),
|
||||
presenting: sessionPendingRevoke
|
||||
) { session in
|
||||
Button(NSLocalizedString("Завершить", comment: "Подтверждение завершения конкретной сессии"), role: .destructive) {
|
||||
sessionPendingRevoke = nil
|
||||
Task { await revoke(session: session) }
|
||||
}
|
||||
Button(NSLocalizedString("Отмена", comment: "Общий текст кнопки отмены"), role: .cancel) {
|
||||
sessionPendingRevoke = nil
|
||||
}
|
||||
} message: { _ in
|
||||
Text(NSLocalizedString("Вы выйдете из выбранной сессии.", comment: "Описание подтверждения завершения конкретной сессии"))
|
||||
}
|
||||
.alert(item: $activeAlert) { alert in
|
||||
Alert(
|
||||
title: Text(alert.title),
|
||||
@ -136,7 +167,7 @@ struct ActiveSessionsView: View {
|
||||
.listRowSeparator(.hidden)
|
||||
}
|
||||
|
||||
private func sessionRow(for session: SessionViewData) -> some View {
|
||||
private func sessionRow(for session: SessionViewData, isRevoking: Bool = false) -> some View {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
HStack(alignment: .top) {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
@ -157,6 +188,9 @@ struct ActiveSessionsView: View {
|
||||
.background(Color.accentColor.opacity(0.15))
|
||||
.foregroundColor(.accentColor)
|
||||
.clipShape(Capsule())
|
||||
} else if isRevoking {
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,6 +259,34 @@ struct ActiveSessionsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func revoke(session: SessionViewData) async {
|
||||
guard !session.isCurrent, !isRevoking(session: session) else {
|
||||
return
|
||||
}
|
||||
|
||||
revokingSessionIds.insert(session.id)
|
||||
defer { revokingSessionIds.remove(session.id) }
|
||||
|
||||
do {
|
||||
let message = try await sessionsService.revoke(sessionId: session.id)
|
||||
sessions.removeAll { $0.id == session.id }
|
||||
activeAlert = SessionsAlert(
|
||||
title: NSLocalizedString("Готово", comment: "Заголовок успешного уведомления"),
|
||||
message: message
|
||||
)
|
||||
} catch {
|
||||
activeAlert = SessionsAlert(
|
||||
title: NSLocalizedString("Ошибка", comment: "Заголовок сообщения об ошибке"),
|
||||
message: error.localizedDescription
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func isRevoking(session: SessionViewData) -> Bool {
|
||||
revokingSessionIds.contains(session.id)
|
||||
}
|
||||
|
||||
private var revokeOtherSessionsButton: some View {
|
||||
let primaryColor: Color = revokeInProgress ? .secondary : .red
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user