mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-04-14 05:15:54 +00:00
Merge branch 'master' into ios-one-hand-ui
This commit is contained in:
@@ -147,13 +147,14 @@ struct ChatInfoView: View {
|
||||
}
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
.padding(.bottom, 18)
|
||||
|
||||
GeometryReader { g in
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
let buttonWidth = g.size.width / 4
|
||||
searchButton(width: buttonWidth)
|
||||
AudioCallButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) }, width: buttonWidth)
|
||||
VideoButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) }, width: buttonWidth)
|
||||
AudioCallButton(chat: chat, contact: contact, width: buttonWidth) { alert = .someAlert(alert: $0) }
|
||||
VideoButton(chat: chat, contact: contact, width: buttonWidth) { alert = .someAlert(alert: $0) }
|
||||
muteButton(width: buttonWidth)
|
||||
}
|
||||
}
|
||||
@@ -328,11 +329,10 @@ struct ChatInfoView: View {
|
||||
}
|
||||
|
||||
private func contactInfoHeader() -> some View {
|
||||
VStack {
|
||||
VStack(spacing: 8) {
|
||||
let cInfo = chat.chatInfo
|
||||
ChatInfoImage(chat: chat, size: 192, color: Color(uiColor: .tertiarySystemFill))
|
||||
.padding(.top, 12)
|
||||
.padding()
|
||||
.padding(.vertical, 12)
|
||||
if contact.verified {
|
||||
(
|
||||
Text(Image(systemName: "checkmark.shield"))
|
||||
@@ -394,21 +394,19 @@ struct ChatInfoView: View {
|
||||
}
|
||||
|
||||
private func searchButton(width: CGFloat) -> some View {
|
||||
InfoViewActionButtonLayout(image: "magnifyingglass", title: "search", width: width)
|
||||
.onTapGesture {
|
||||
dismiss()
|
||||
onSearch()
|
||||
}
|
||||
.disabled(!contact.ready || chat.chatItems.isEmpty)
|
||||
InfoViewButton(image: "magnifyingglass", title: "search", width: width) {
|
||||
dismiss()
|
||||
onSearch()
|
||||
}
|
||||
.disabled(!contact.ready || chat.chatItems.isEmpty)
|
||||
}
|
||||
|
||||
private func muteButton(width: CGFloat) -> some View {
|
||||
InfoViewActionButtonLayout(
|
||||
InfoViewButton(
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash.fill" : "speaker.wave.2.fill",
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute",
|
||||
width: width
|
||||
)
|
||||
.onTapGesture {
|
||||
) {
|
||||
toggleNotifications(chat, enableNtfs: !chat.chatInfo.ntfsEnabled)
|
||||
}
|
||||
.disabled(!contact.ready || !contact.active)
|
||||
@@ -623,8 +621,8 @@ struct ChatInfoView: View {
|
||||
struct AudioCallButton: View {
|
||||
var chat: Chat
|
||||
var contact: Contact
|
||||
var width: CGFloat
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
CallButton(
|
||||
@@ -633,8 +631,8 @@ struct AudioCallButton: View {
|
||||
image: "phone.fill",
|
||||
title: "call",
|
||||
mediaType: .audio,
|
||||
showAlert: showAlert,
|
||||
width: width
|
||||
width: width,
|
||||
showAlert: showAlert
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -642,8 +640,8 @@ struct AudioCallButton: View {
|
||||
struct VideoButton: View {
|
||||
var chat: Chat
|
||||
var contact: Contact
|
||||
var width: CGFloat
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
CallButton(
|
||||
@@ -652,8 +650,8 @@ struct VideoButton: View {
|
||||
image: "video.fill",
|
||||
title: "video",
|
||||
mediaType: .video,
|
||||
showAlert: showAlert,
|
||||
width: width
|
||||
width: width,
|
||||
showAlert: showAlert
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -664,91 +662,89 @@ private struct CallButton: View {
|
||||
var image: String
|
||||
var title: LocalizedStringKey
|
||||
var mediaType: CallMediaType
|
||||
var width: CGFloat
|
||||
var showAlert: (SomeAlert) -> Void
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
|
||||
var body: some View {
|
||||
let canCall = contact.ready && contact.active && chat.chatInfo.featureEnabled(.calls) && ChatModel.shared.activeCall == nil
|
||||
|
||||
InfoViewActionButtonLayout(image: image, title: title, disabledLook: !canCall, width: width)
|
||||
.onTapGesture {
|
||||
if canCall {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
} else if contact.nextSendGrpInv {
|
||||
InfoViewButton(image: image, title: title, disabledLook: !canCall, width: width) {
|
||||
if canCall {
|
||||
CallController.shared.startCall(contact, mediaType)
|
||||
} else if contact.nextSendGrpInv {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Send message to enable calls."
|
||||
),
|
||||
id: "can't call contact, send message"
|
||||
))
|
||||
} else if !contact.active {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Contact is deleted."
|
||||
),
|
||||
id: "can't call contact, contact deleted"
|
||||
))
|
||||
} else if !contact.ready {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Connecting to contact, please wait or check later!"
|
||||
),
|
||||
id: "can't call contact, contact not ready"
|
||||
))
|
||||
} else if !chat.chatInfo.featureEnabled(.calls) {
|
||||
switch chat.chatInfo.showEnableCallsAlert {
|
||||
case .userEnable:
|
||||
showAlert(SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Allow calls?"),
|
||||
message: Text("You need to allow your contact to call to be able to call them."),
|
||||
primaryButton: .default(Text("Allow")) {
|
||||
allowFeatureToContact(contact, .calls)
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
),
|
||||
id: "allow calls"
|
||||
))
|
||||
case .askContact:
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Send message to enable calls."
|
||||
title: "Calls prohibited!",
|
||||
message: "Please ask your contact to enable calls."
|
||||
),
|
||||
id: "can't call contact, send message"
|
||||
id: "calls prohibited, ask contact"
|
||||
))
|
||||
} else if !contact.active {
|
||||
case .other:
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Contact is deleted."
|
||||
),
|
||||
id: "can't call contact, contact deleted"
|
||||
))
|
||||
} else if !contact.ready {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Can't call contact",
|
||||
message: "Connecting to contact, please wait or check later!"
|
||||
),
|
||||
id: "can't call contact, contact not ready"
|
||||
))
|
||||
} else if !chat.chatInfo.featureEnabled(.calls) {
|
||||
switch chat.chatInfo.showEnableCallsAlert {
|
||||
case .userEnable:
|
||||
showAlert(SomeAlert(
|
||||
alert: Alert(
|
||||
title: Text("Allow calls?"),
|
||||
message: Text("You need to allow your contact to call to be able to call them."),
|
||||
primaryButton: .default(Text("Allow")) {
|
||||
allowFeatureToContact(contact, .calls)
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
),
|
||||
id: "allow calls"
|
||||
))
|
||||
case .askContact:
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Calls prohibited!",
|
||||
message: "Please ask your contact to enable calls."
|
||||
),
|
||||
id: "calls prohibited, ask contact"
|
||||
))
|
||||
case .other:
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(
|
||||
title: "Calls prohibited!",
|
||||
message: "Please check yours and your contact preferences."
|
||||
)
|
||||
, id: "calls prohibited, other"
|
||||
))
|
||||
}
|
||||
} else {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(title: "Can't call contact"),
|
||||
id: "can't call contact"
|
||||
title: "Calls prohibited!",
|
||||
message: "Please check yours and your contact preferences."
|
||||
)
|
||||
, id: "calls prohibited, other"
|
||||
))
|
||||
}
|
||||
} else {
|
||||
showAlert(SomeAlert(
|
||||
alert: mkAlert(title: "Can't call contact"),
|
||||
id: "can't call contact"
|
||||
))
|
||||
}
|
||||
.disabled(ChatModel.shared.activeCall != nil)
|
||||
}
|
||||
.disabled(ChatModel.shared.activeCall != nil)
|
||||
}
|
||||
}
|
||||
|
||||
let infoViewActionButtonWidth: CGFloat = 83
|
||||
|
||||
let infoViewActionButtonHeight: CGFloat = 60
|
||||
|
||||
struct InfoViewActionButtonLayout: View {
|
||||
struct InfoViewButton: View {
|
||||
var image: String
|
||||
var title: LocalizedStringKey
|
||||
var disabledLook: Bool = false
|
||||
var width: CGFloat = infoViewActionButtonWidth
|
||||
var width: CGFloat
|
||||
var action: () -> Void
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 4) {
|
||||
@@ -765,6 +761,7 @@ struct InfoViewActionButtonLayout: View {
|
||||
.cornerRadius(10.0)
|
||||
.frame(width: width, height: infoViewActionButtonHeight)
|
||||
.disabled(disabledLook)
|
||||
.onTapGesture(perform: action)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ struct GroupChatInfoView: View {
|
||||
List {
|
||||
groupInfoHeader()
|
||||
.listRowBackground(Color.clear)
|
||||
.padding(.bottom, 18)
|
||||
|
||||
infoActionButtons()
|
||||
.padding(.horizontal)
|
||||
@@ -209,31 +210,33 @@ struct GroupChatInfoView: View {
|
||||
}
|
||||
|
||||
func infoActionButtons() -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
searchButton()
|
||||
if groupInfo.canAddMembers {
|
||||
addMembersActionButton()
|
||||
GeometryReader { g in
|
||||
let buttonWidth = g.size.width / 4
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
searchButton(width: buttonWidth)
|
||||
if groupInfo.canAddMembers {
|
||||
addMembersActionButton(width: buttonWidth)
|
||||
}
|
||||
muteButton(width: buttonWidth)
|
||||
}
|
||||
muteButton()
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
}
|
||||
|
||||
private func searchButton() -> some View {
|
||||
InfoViewActionButtonLayout(image: "magnifyingglass", title: "search")
|
||||
.onTapGesture {
|
||||
dismiss()
|
||||
onSearch()
|
||||
}
|
||||
.disabled(!groupInfo.ready || chat.chatItems.isEmpty)
|
||||
private func searchButton(width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "magnifyingglass", title: "search", width: width) {
|
||||
dismiss()
|
||||
onSearch()
|
||||
}
|
||||
.disabled(!groupInfo.ready || chat.chatItems.isEmpty)
|
||||
}
|
||||
|
||||
@ViewBuilder private func addMembersActionButton() -> some View {
|
||||
@ViewBuilder private func addMembersActionButton(width: CGFloat) -> some View {
|
||||
if chat.chatInfo.incognito {
|
||||
ZStack {
|
||||
InfoViewActionButtonLayout(image: "link.badge.plus", title: "invite")
|
||||
.onTapGesture {
|
||||
groupLinkNavLinkActive = true
|
||||
}
|
||||
InfoViewButton(image: "link.badge.plus", title: "invite", width: width) {
|
||||
groupLinkNavLinkActive = true
|
||||
}
|
||||
|
||||
NavigationLink(isActive: $groupLinkNavLinkActive) {
|
||||
groupLinkDestinationView()
|
||||
@@ -246,10 +249,9 @@ struct GroupChatInfoView: View {
|
||||
.disabled(!groupInfo.ready)
|
||||
} else {
|
||||
ZStack {
|
||||
InfoViewActionButtonLayout(image: "person.fill.badge.plus", title: "invite")
|
||||
.onTapGesture {
|
||||
addMembersNavLinkActive = true
|
||||
}
|
||||
InfoViewButton(image: "person.fill.badge.plus", title: "invite", width: width) {
|
||||
addMembersNavLinkActive = true
|
||||
}
|
||||
|
||||
NavigationLink(isActive: $addMembersNavLinkActive) {
|
||||
addMembersDestinationView()
|
||||
@@ -263,12 +265,12 @@ struct GroupChatInfoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func muteButton() -> some View {
|
||||
InfoViewActionButtonLayout(
|
||||
private func muteButton(width: CGFloat) -> some View {
|
||||
InfoViewButton(
|
||||
image: chat.chatInfo.ntfsEnabled ? "speaker.slash.fill" : "speaker.wave.2.fill",
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute"
|
||||
)
|
||||
.onTapGesture {
|
||||
title: chat.chatInfo.ntfsEnabled ? "mute" : "unmute",
|
||||
width: width
|
||||
) {
|
||||
toggleNotifications(chat, enableNtfs: !chat.chatInfo.ntfsEnabled)
|
||||
}
|
||||
.disabled(!groupInfo.ready)
|
||||
|
||||
@@ -84,7 +84,8 @@ struct GroupMemberInfoView: View {
|
||||
groupMemberInfoHeader(member)
|
||||
.listRowBackground(Color.clear)
|
||||
.listRowSeparator(.hidden)
|
||||
|
||||
.padding(.bottom, 18)
|
||||
|
||||
infoActionButtons(member)
|
||||
.padding(.horizontal)
|
||||
.frame(maxWidth: .infinity)
|
||||
@@ -254,29 +255,33 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
|
||||
func infoActionButtons(_ member: GroupMember) -> some View {
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let contactId = member.memberContactId, let (chat, contact) = knownDirectChat(contactId) {
|
||||
knownDirectChatButton(chat)
|
||||
AudioCallButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
VideoButton(chat: chat, contact: contact, showAlert: { alert = .someAlert(alert: $0) })
|
||||
} else if groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
if let contactId = member.memberContactId {
|
||||
newDirectChatButton(contactId)
|
||||
} else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false {
|
||||
createMemberContactButton()
|
||||
GeometryReader { g in
|
||||
let buttonWidth = g.size.width / 4
|
||||
HStack(alignment: .center, spacing: 8) {
|
||||
if let contactId = member.memberContactId, let (chat, contact) = knownDirectChat(contactId) {
|
||||
knownDirectChatButton(chat, width: buttonWidth)
|
||||
AudioCallButton(chat: chat, contact: contact, width: buttonWidth) { alert = .someAlert(alert: $0) }
|
||||
VideoButton(chat: chat, contact: contact, width: buttonWidth) { alert = .someAlert(alert: $0) }
|
||||
} else if groupInfo.fullGroupPreferences.directMessages.on(for: groupInfo.membership) {
|
||||
if let contactId = member.memberContactId {
|
||||
newDirectChatButton(contactId, width: buttonWidth)
|
||||
} else if member.activeConn?.peerChatVRange.isCompatibleRange(CREATE_MEMBER_CONTACT_VRANGE) ?? false {
|
||||
createMemberContactButton(width: buttonWidth)
|
||||
}
|
||||
InfoViewButton(image: "phone.fill", title: "call", disabledLook: true, width: buttonWidth) { showSendMessageToEnableCallsAlert()
|
||||
}
|
||||
InfoViewButton(image: "video.fill", title: "video", disabledLook: true, width: buttonWidth) { showSendMessageToEnableCallsAlert()
|
||||
}
|
||||
} else { // no known contact chat && directMessages are off
|
||||
InfoViewButton(image: "message.fill", title: "message", disabledLook: true, width: buttonWidth) { showDirectMessagesProhibitedAlert("Can't message member")
|
||||
}
|
||||
InfoViewButton(image: "phone.fill", title: "call", disabledLook: true, width: buttonWidth) { showDirectMessagesProhibitedAlert("Can't call member")
|
||||
}
|
||||
InfoViewButton(image: "video.fill", title: "video", disabledLook: true, width: buttonWidth) { showDirectMessagesProhibitedAlert("Can't call member")
|
||||
}
|
||||
}
|
||||
InfoViewActionButtonLayout(image: "phone.fill", title: "call", disabledLook: true)
|
||||
.onTapGesture { showSendMessageToEnableCallsAlert() }
|
||||
InfoViewActionButtonLayout(image: "video.fill", title: "video", disabledLook: true)
|
||||
.onTapGesture { showSendMessageToEnableCallsAlert() }
|
||||
} else { // no known contact chat && directMessages are off
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't message member") }
|
||||
InfoViewActionButtonLayout(image: "phone.fill", title: "call", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't call member") }
|
||||
InfoViewActionButtonLayout(image: "video.fill", title: "video", disabledLook: true)
|
||||
.onTapGesture { showDirectMessagesProhibitedAlert("Can't call member") }
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,56 +319,53 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func knownDirectChatButton(_ chat: Chat) -> some View {
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
func knownDirectChatButton(_ chat: Chat, width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.chatId = chat.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newDirectChatButton(_ contactId: Int64, width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
do {
|
||||
let chat = try apiGetChat(type: .direct, id: contactId)
|
||||
chatModel.addChat(chat)
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.chatId = chat.id
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newDirectChatButton(_ contactId: Int64) -> some View {
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
func createMemberContactButton(width: CGFloat) -> some View {
|
||||
InfoViewButton(image: "message.fill", title: "message", width: width) {
|
||||
progressIndicator = true
|
||||
Task {
|
||||
do {
|
||||
let chat = try apiGetChat(type: .direct, id: contactId)
|
||||
chatModel.addChat(chat)
|
||||
dismissAllSheets(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.chatId = chat.id
|
||||
let memberContact = try await apiCreateMemberContact(groupInfo.apiId, groupMember.groupMemberId)
|
||||
await MainActor.run {
|
||||
progressIndicator = false
|
||||
chatModel.addChat(Chat(chatInfo: .direct(contact: memberContact)))
|
||||
dismissAllSheets(animated: true)
|
||||
chatModel.chatId = memberContact.id
|
||||
chatModel.setContactNetworkStatus(memberContact, .connected)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("openDirectChatButton apiGetChat error: \(responseError(error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createMemberContactButton() -> some View {
|
||||
InfoViewActionButtonLayout(image: "message.fill", title: "message")
|
||||
.onTapGesture {
|
||||
progressIndicator = true
|
||||
Task {
|
||||
do {
|
||||
let memberContact = try await apiCreateMemberContact(groupInfo.apiId, groupMember.groupMemberId)
|
||||
await MainActor.run {
|
||||
progressIndicator = false
|
||||
chatModel.addChat(Chat(chatInfo: .direct(contact: memberContact)))
|
||||
dismissAllSheets(animated: true)
|
||||
chatModel.chatId = memberContact.id
|
||||
chatModel.setContactNetworkStatus(memberContact, .connected)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))")
|
||||
let a = getErrorAlert(error, "Error creating member contact")
|
||||
await MainActor.run {
|
||||
progressIndicator = false
|
||||
alert = .error(title: a.title, error: a.message)
|
||||
}
|
||||
logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))")
|
||||
let a = getErrorAlert(error, "Error creating member contact")
|
||||
await MainActor.run {
|
||||
progressIndicator = false
|
||||
alert = .error(title: a.title, error: a.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func groupMemberInfoHeader(_ mem: GroupMember) -> some View {
|
||||
|
||||
@@ -292,13 +292,19 @@ struct SubsStatusIndicator: View {
|
||||
@AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
showServersSummary = true
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: hasSess)
|
||||
ZStack {
|
||||
if subs.total == 0 && !hasSess {
|
||||
EmptyView()
|
||||
} else {
|
||||
Button {
|
||||
showServersSummary = true
|
||||
} label: {
|
||||
HStack(spacing: 4) {
|
||||
SubscriptionStatusIndicatorView(subs: subs, hasSess: hasSess)
|
||||
if showSubscriptionPercentage {
|
||||
SubscriptionStatusPercentageView(subs: subs, hasSess: hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,8 +314,9 @@ struct SubsStatusIndicator: View {
|
||||
.onDisappear {
|
||||
stopTimer()
|
||||
}
|
||||
.sheet(isPresented: $showServersSummary) {
|
||||
.appSheet(isPresented: $showServersSummary) {
|
||||
ServersSummaryView()
|
||||
.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -359,8 +359,12 @@ fun SubscriptionStatusIndicator(click: (() -> Unit)) {
|
||||
}
|
||||
}
|
||||
|
||||
SimpleButtonFrame(click = click) {
|
||||
SubscriptionStatusIndicatorView(subs = subs, hasSess = hasSess)
|
||||
if (subs.total == 0 && !hasSess) {
|
||||
Box {}
|
||||
} else {
|
||||
SimpleButtonFrame(click = click) {
|
||||
SubscriptionStatusIndicatorView(subs = subs, hasSess = hasSess)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user