Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Jan 8, 2025
2 parents 105d188 + bcb7c8b commit 146c968
Show file tree
Hide file tree
Showing 31 changed files with 1,152 additions and 193 deletions.
18 changes: 12 additions & 6 deletions apps/ios/Shared/Model/SimpleXAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ import SimpleXChat

private var chatController: chat_ctrl?

// currentChatVersion in core
public let CURRENT_CHAT_VERSION: Int = 2

// version range that supports establishing direct connection with a group member (xGrpDirectInvVRange in core)
public let CREATE_MEMBER_CONTACT_VRANGE = VersionRange(minVersion: 2, maxVersion: CURRENT_CHAT_VERSION)

private let networkStatusesLock = DispatchQueue(label: "chat.simplex.app.network-statuses.lock")

enum TerminalItem: Identifiable {
Expand Down Expand Up @@ -460,6 +454,18 @@ func apiCreateChatItems(noteFolderId: Int64, composedMessages: [ComposedMessage]
return nil
}

func apiReportMessage(groupId: Int64, chatItemId: Int64, reportReason: ReportReason, reportText: String) async -> [ChatItem]? {
let r = await chatSendCmd(.apiReportMessage(groupId: groupId, chatItemId: chatItemId, reportReason: reportReason, reportText: reportText))
if case let .newChatItems(_, aChatItems) = r { return aChatItems.map { $0.chatItem } }

logger.error("apiReportMessage error: \(String(describing: r))")
AlertManager.shared.showAlertMsg(
title: "Error creating report",
message: "Error: \(responseError(r))"
)
return nil
}

private func sendMessageErrorAlert(_ r: ChatResponse) {
logger.error("send message error: \(String(describing: r))")
AlertManager.shared.showAlertMsg(
Expand Down
23 changes: 18 additions & 5 deletions apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@ struct FramedItemView: View {
var body: some View {
let v = ZStack(alignment: .bottomTrailing) {
VStack(alignment: .leading, spacing: 0) {
if let di = chatItem.meta.itemDeleted {
if chatItem.isReport {
if chatItem.meta.itemDeleted == nil {
let txt = chatItem.chatDir.sent ?
Text("Only you and moderators see it") :
Text("Only sender and moderators see it")

framedItemHeader(icon: "flag", iconColor: .red, caption: txt.italic())
} else {
framedItemHeader(icon: "flag", caption: Text("archived report").italic())
}
} else if let di = chatItem.meta.itemDeleted {
switch di {
case let .moderated(_, byGroupMember):
framedItemHeader(icon: "flag", caption: Text("moderated by \(byGroupMember.displayName)").italic())
Expand Down Expand Up @@ -144,6 +154,8 @@ struct FramedItemView: View {
}
case let .file(text):
ciFileView(chatItem, text)
case let .report(text, reason):
ciMsgContentView(chatItem, Text(text.isEmpty ? reason.text : "\(reason.text): ").italic().foregroundColor(.red))
case let .link(_, preview):
CILinkView(linkPreview: preview)
ciMsgContentView(chatItem)
Expand All @@ -159,13 +171,14 @@ struct FramedItemView: View {
}
}

@ViewBuilder func framedItemHeader(icon: String? = nil, caption: Text, pad: Bool = false) -> some View {
@ViewBuilder func framedItemHeader(icon: String? = nil, iconColor: Color? = nil, caption: Text, pad: Bool = false) -> some View {
let v = HStack(spacing: 6) {
if let icon = icon {
Image(systemName: icon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 14, height: 14)
.foregroundColor(iconColor ?? theme.colors.secondary)
}
caption
.font(.caption)
Expand Down Expand Up @@ -228,7 +241,6 @@ struct FramedItemView: View {
.overlay { if case .voice = chatItem.content.msgContent {} else { DetermineWidth() } }
.frame(minWidth: msgWidth, alignment: .leading)
.background(chatItemFrameContextColor(chatItem, theme))

if let mediaWidth = maxMediaWidth(), mediaWidth < maxWidth {
v.frame(maxWidth: mediaWidth, alignment: .leading)
} else {
Expand Down Expand Up @@ -281,7 +293,7 @@ struct FramedItemView: View {
}
}

@ViewBuilder private func ciMsgContentView(_ ci: ChatItem) -> some View {
@ViewBuilder private func ciMsgContentView(_ ci: ChatItem, _ txtPrefix: Text? = nil) -> some View {
let text = ci.meta.isLive ? ci.content.msgContent?.text ?? ci.text : ci.text
let rtl = isRightToLeft(text)
let ft = text == "" ? [] : ci.formattedText
Expand All @@ -291,7 +303,8 @@ struct FramedItemView: View {
formattedText: ft,
meta: ci.meta,
rightToLeft: rtl,
showSecrets: showSecrets
showSecrets: showSecrets,
prefix: txtPrefix
))
.multilineTextAlignment(rtl ? .trailing : .leading)
.padding(.vertical, 6)
Expand Down
14 changes: 9 additions & 5 deletions apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,15 @@ struct MarkedDeletedItemView: View {
// same texts are in markedDeletedText in ChatPreviewView, but it returns String;
// can be refactored into a single function if functions calling these are changed to return same type
var markedDeletedText: LocalizedStringKey {
switch chatItem.meta.itemDeleted {
case let .moderated(_, byGroupMember): "moderated by \(byGroupMember.displayName)"
case .blocked: "blocked"
case .blockedByAdmin: "blocked by admin"
case .deleted, nil: "marked deleted"
if chatItem.meta.itemDeleted != nil, chatItem.isReport {
"archived report"
} else {
switch chatItem.meta.itemDeleted {
case let .moderated(_, byGroupMember): "moderated by \(byGroupMember.displayName)"
case .blocked: "blocked"
case .blockedByAdmin: "blocked by admin"
case .deleted, nil: "marked deleted"
}
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct MsgContentView: View {
var meta: CIMeta? = nil
var rightToLeft = false
var showSecrets: Bool
var prefix: Text? = nil
@State private var typingIdx = 0
@State private var timer: Timer?

Expand Down Expand Up @@ -67,7 +68,7 @@ struct MsgContentView: View {
}

private func msgContentView() -> Text {
var v = messageText(text, formattedText, sender, showSecrets: showSecrets, secondaryColor: theme.colors.secondary)
var v = messageText(text, formattedText, sender, showSecrets: showSecrets, secondaryColor: theme.colors.secondary, prefix: prefix)
if let mt = meta {
if mt.isLive {
v = v + typingIndicator(mt.recent)
Expand All @@ -89,9 +90,10 @@ struct MsgContentView: View {
}
}

func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: String?, icon: String? = nil, preview: Bool = false, showSecrets: Bool, secondaryColor: Color) -> Text {
func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: String?, icon: String? = nil, preview: Bool = false, showSecrets: Bool, secondaryColor: Color, prefix: Text? = nil) -> Text {
let s = text
var res: Text

if let ft = formattedText, ft.count > 0 && ft.count <= 200 {
res = formatText(ft[0], preview, showSecret: showSecrets)
var i = 1
Expand All @@ -106,6 +108,10 @@ func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: St
if let i = icon {
res = Text(Image(systemName: i)).foregroundColor(secondaryColor) + textSpace + res
}

if let p = prefix {
res = p + res
}

if let s = sender {
let t = Text(s)
Expand Down
Loading

0 comments on commit 146c968

Please sign in to comment.