Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@
5180CB9127356D48001FC7EF /* MessageSubjectNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180CB9027356D48001FC7EF /* MessageSubjectNode.swift */; };
5180CB9327357B67001FC7EF /* RawClientConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180CB9227357B67001FC7EF /* RawClientConfiguration.swift */; };
5180CB9527357BB0001FC7EF /* WkdApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180CB9427357BB0001FC7EF /* WkdApi.swift */; };
5180CB97273724E9001FC7EF /* ThreadMessageSenderCellNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180CB96273724E9001FC7EF /* ThreadMessageSenderCellNode.swift */; };
5180CB97273724E9001FC7EF /* ThreadMessageInfoCellNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5180CB96273724E9001FC7EF /* ThreadMessageInfoCellNode.swift */; };
518389C82726D7DD00131B2C /* UIViewController+Spinner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518389C72726D7DD00131B2C /* UIViewController+Spinner.swift */; };
518389CA2726D8F700131B2C /* UIApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518389C92726D8F700131B2C /* UIApplicationExtension.swift */; };
51938DC1274CC291007AD57B /* MessageQuoteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51938DC0274CC291007AD57B /* MessageQuoteType.swift */; };
51B0C7712729861C00124663 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B0C7702729861C00124663 /* String+Extension.swift */; };
51B0C774272AB61000124663 /* StringTestExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B0C773272AB61000124663 /* StringTestExtension.swift */; };
51B4AE51271444580001F33B /* PubKeyRealmObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B4AE50271444580001F33B /* PubKeyRealmObject.swift */; };
51B4AE5327144E590001F33B /* PubKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B4AE5227144E590001F33B /* PubKey.swift */; };
51B9EE6F27567B520080B2D5 /* MessageRecipientsNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B9EE6E27567B520080B2D5 /* MessageRecipientsNode.swift */; };
51C0C1EF271982A1000C9738 /* MailCore in Frameworks */ = {isa = PBXBuildFile; productRef = 51C0C1EE271982A1000C9738 /* MailCore */; };
51C0C1F2271987DB000C9738 /* Toast in Frameworks */ = {isa = PBXBuildFile; productRef = 51C0C1F1271987DB000C9738 /* Toast */; };
51DA5BD62721AB07001C4359 /* PubKeyState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DA5BD52721AB07001C4359 /* PubKeyState.swift */; };
Expand Down Expand Up @@ -493,14 +494,15 @@
5180CB9027356D48001FC7EF /* MessageSubjectNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSubjectNode.swift; sourceTree = "<group>"; };
5180CB9227357B67001FC7EF /* RawClientConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawClientConfiguration.swift; sourceTree = "<group>"; };
5180CB9427357BB0001FC7EF /* WkdApi.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WkdApi.swift; sourceTree = "<group>"; };
5180CB96273724E9001FC7EF /* ThreadMessageSenderCellNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadMessageSenderCellNode.swift; sourceTree = "<group>"; };
5180CB96273724E9001FC7EF /* ThreadMessageInfoCellNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadMessageInfoCellNode.swift; sourceTree = "<group>"; };
518389C72726D7DD00131B2C /* UIViewController+Spinner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Spinner.swift"; sourceTree = "<group>"; };
518389C92726D8F700131B2C /* UIApplicationExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIApplicationExtension.swift; sourceTree = "<group>"; };
51938DC0274CC291007AD57B /* MessageQuoteType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageQuoteType.swift; sourceTree = "<group>"; };
51B0C7702729861C00124663 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
51B0C773272AB61000124663 /* StringTestExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringTestExtension.swift; sourceTree = "<group>"; };
51B4AE50271444580001F33B /* PubKeyRealmObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PubKeyRealmObject.swift; sourceTree = "<group>"; };
51B4AE5227144E590001F33B /* PubKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PubKey.swift; sourceTree = "<group>"; };
51B9EE6E27567B520080B2D5 /* MessageRecipientsNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRecipientsNode.swift; sourceTree = "<group>"; };
51DA5BD52721AB07001C4359 /* PubKeyState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PubKeyState.swift; sourceTree = "<group>"; };
51DA5BD92722C82E001C4359 /* RecipientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipientTests.swift; sourceTree = "<group>"; };
51DAD9BC273E7DD20076CBA7 /* BadgeNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeNode.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1984,7 +1986,7 @@
5A39F433239EC61C001F4607 /* TitleCellNode.swift */,
5180CB9027356D48001FC7EF /* MessageSubjectNode.swift */,
9F82779D23737E3800E19C07 /* MessageTextSubjectNode.swift */,
5180CB96273724E9001FC7EF /* ThreadMessageSenderCellNode.swift */,
5180CB96273724E9001FC7EF /* ThreadMessageInfoCellNode.swift */,
9F56BD3123438B5B00A7371A /* InboxCellNode.swift */,
9F56BD3523438B9D00A7371A /* TextCellNode.swift */,
D24ABA6223FDB4FF002EE9DD /* RecipientEmailsCellNode.swift */,
Expand Down Expand Up @@ -2025,6 +2027,7 @@
D24FAFAA2520BFAE00BF46C5 /* CheckBoxNode.swift */,
50531BE32629B9A80039BAE9 /* AttachmentNode.swift */,
51DAD9BC273E7DD20076CBA7 /* BadgeNode.swift */,
51B9EE6E27567B520080B2D5 /* MessageRecipientsNode.swift */,
);
path = Nodes;
sourceTree = "<group>";
Expand Down Expand Up @@ -2502,8 +2505,6 @@
9FC413182683C492004C0A69 /* InMemoryPassPhraseStorageTest.swift in Sources */,
9F9764C5267E14AB0058419D /* GeneralConstantsTest.swift in Sources */,
9F976507267E165D0058419D /* ZBase32EncodingTests.swift in Sources */,
9F9764C5267E14AB0058419D /* GeneralConstantsTest.swift in Sources */,
9F976507267E165D0058419D /* ZBase32EncodingTests.swift in Sources */,
2C2A3B4D2719EF7300B7F27B /* PassPhraseServiceMock.swift in Sources */,
9F5F504A26FA6C8F00294FA2 /* ClientConfigurationProviderMock.swift in Sources */,
9FC4117D268118AE004C0A69 /* PassPhraseStorageMock.swift in Sources */,
Expand All @@ -2530,13 +2531,13 @@
51775C32270B01C200D7C944 /* PrvKeyInfoTests.swift in Sources */,
9F9500AF26F4BAE300E8C78B /* ClientConfigurationTests.swift in Sources */,
9FC413442683C912004C0A69 /* GmailServiceTest.swift in Sources */,
9FC413442683C912004C0A69 /* GmailServiceTest.swift in Sources */,
9F976556267E186D0058419D /* RawClientConfigurationTests.swift in Sources */,
A36108E9273C7A2E00A90E34 /* MockError.swift in Sources */,
9F7E8EC6269877E70021C07F /* KeyInfoTests.swift in Sources */,
9F5F504326FA6C7500294FA2 /* EnterpriseServerApiMock.swift in Sources */,
51DA5BDA2722C82E001C4359 /* RecipientTests.swift in Sources */,
9FC41171268118A7004C0A69 /* PassPhraseStorageTests.swift in Sources */,
9F6F3C7626ADFC37005BD9C6 /* KeyStorageMock.swift in Sources */,
51DA5BDA2722C82E001C4359 /* RecipientTests.swift in Sources */,
9FC41171268118A7004C0A69 /* PassPhraseStorageTests.swift in Sources */,
);
Expand Down Expand Up @@ -2779,7 +2780,7 @@
D2A9CA432426210200E1D898 /* SetupTitleNode.swift in Sources */,
D2F6D12F24324ACC00DB4065 /* SwitchCellNode.swift in Sources */,
51EBC5702746A06600178DE8 /* TextWithIconNode.swift in Sources */,
5180CB97273724E9001FC7EF /* ThreadMessageSenderCellNode.swift in Sources */,
5180CB97273724E9001FC7EF /* ThreadMessageInfoCellNode.swift in Sources */,
D2E26F6824F169E300612AF1 /* ContactCellNode.swift in Sources */,
D2A9CA38242618DF00E1D898 /* LinkButtonNode.swift in Sources */,
D24FAFA42520BF9100BF46C5 /* CheckBoxCircleView.swift in Sources */,
Expand All @@ -2804,6 +2805,7 @@
5109A77C272153B400D2CEB9 /* LeftAlignedCollectionViewFlowLayout.swift in Sources */,
D27177462424D59800BDA9A9 /* InboxCellNode.swift in Sources */,
D27177472424D59800BDA9A9 /* TextCellNode.swift in Sources */,
51B9EE6F27567B520080B2D5 /* MessageRecipientsNode.swift in Sources */,
D211CE6E23FC354200D1CE38 /* CellNode.swift in Sources */,
D24ABA6023FDB26C002EE9DD /* Helpers.swift in Sources */,
D211CE7323FC35AC00D1CE38 /* TextViewCellNode.swift in Sources */,
Expand Down
16 changes: 5 additions & 11 deletions FlowCrypt/Controllers/Inbox/InboxRenderable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,11 @@ extension InboxRenderable {
// for now its not exactly clear how titles on other folders should looks like
// so in scope of this PR we are applying this title presentation only for "sent" folder
if folderPath == MessageLabelType.sent.value {
var emails = thread.messages.compactMap(\.sender).unique()
// if we have only one email, it means that it could be "me" and we are not
// clearing our own email from that
if emails.count > 1 {
if let i = emails.firstIndex(of: activeUserEmail) {
emails.remove(at: i)
}
}
let recipients = emails
.compactMap { $0.components(separatedBy: "@").first }
.joined(separator: ",")
let recipients = thread.messages
.flatMap(\.allRecipients)
.map(\.displayName)
.unique()
.joined(separator: ", ")
return "To: \(recipients)"

} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import FlowCryptUI
*/

class SetupCreatePassphraseAbstractViewController: TableNodeViewController, PassPhraseSaveable, NavigationChildController {

enum Parts: Int, CaseIterable {
case title, description, passPhrase, divider, saveLocally, saveInMemory, action, subtitle, fetchedKeys
}
Expand Down
2 changes: 1 addition & 1 deletion FlowCrypt/Controllers/Threads/MessageAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Anton Kharchevskyi on 21.10.2021
// Copyright © 2017-present FlowCrypt a. s. All rights reserved.
//

import Foundation

typealias MessageActionCompletion = (MessageAction, InboxRenderable) -> Void
Expand Down
23 changes: 15 additions & 8 deletions FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,37 @@
import FlowCryptUI
import UIKit

extension ThreadMessageSenderCellNode.Input {
extension ThreadMessageInfoCellNode.Input {
init(threadMessage: ThreadDetailsViewController.Input) {
let sender = threadMessage.rawMessage.sender ?? "message_unknown_sender".localized
let recipientPrefix = "to".localized
let recipientsList = threadMessage.rawMessage
.allRecipients
.map(\.displayName)
.joined(separator: ", ")
let recipientLabel = [recipientPrefix, recipientsList].joined(separator: " ")
let date = DateFormatter().formatDate(threadMessage.rawMessage.date)
let isMessageRead = threadMessage.rawMessage.isMessageRead

let style: NSAttributedString.Style = isMessageRead
? .regular(17)
: .bold(17)
? .regular(16)
: .bold(16)

let dateColor: UIColor = isMessageRead
? .lightGray
: .main

let textColor: UIColor = isMessageRead
? .lightGray
: .mainTextUnreadColor

self.init(
encryptionBadge: makeEncryptionBadge(threadMessage),
signatureBadge: makeSignatureBadge(threadMessage),
sender: NSAttributedString.text(from: sender, style: style, color: textColor),
sender: NSAttributedString.text(from: sender, style: style, color: .label),
recipientLabel: NSAttributedString.text(from: recipientLabel, style: style, color: .secondaryLabel),
recipients: threadMessage.rawMessage.recipients.map(\.rawString),
ccRecipients: threadMessage.rawMessage.cc.map(\.rawString),
bccRecipients: threadMessage.rawMessage.bcc.map(\.rawString),
date: NSAttributedString.text(from: date, style: style, color: dateColor),
isExpanded: threadMessage.isExpanded,
shouldShowRecipientsList: threadMessage.shouldShowRecipientsList,
buttonColor: .messageButtonColor,
nodeInsets: UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 8)
)
Expand Down
58 changes: 34 additions & 24 deletions FlowCrypt/Controllers/Threads/ThreadDetailsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ final class ThreadDetailsViewController: TableNodeViewController {
class Input {
var rawMessage: Message
var isExpanded: Bool
var shouldShowRecipientsList: Bool
var processedMessage: ProcessedMessage?

init(message: Message, isExpanded: Bool) {
init(message: Message, isExpanded: Bool = false, shouldShowRecipientsList: Bool = false) {
self.rawMessage = message
self.isExpanded = isExpanded
self.shouldShowRecipientsList = shouldShowRecipientsList
}
}

Expand Down Expand Up @@ -91,7 +93,7 @@ final class ThreadDetailsViewController: TableNodeViewController {
self.onComplete = completion
self.input = thread.messages
.sorted(by: >)
.map { Input(message: $0, isExpanded: false) }
.map { Input(message: $0) }

super.init(node: TableNode())
}
Expand Down Expand Up @@ -119,7 +121,7 @@ extension ThreadDetailsViewController {
}

private func handleExpandTap(at indexPath: IndexPath) {
guard let threadNode = node.nodeForRow(at: indexPath) as? ThreadMessageSenderCellNode else {
guard let threadNode = node.nodeForRow(at: indexPath) as? ThreadMessageInfoCellNode else {
logger.logError("Fail to handle tap at \(indexPath)")
return
}
Expand Down Expand Up @@ -149,6 +151,14 @@ extension ThreadDetailsViewController {
}
}

private func handleRecipientsTap(at indexPath: IndexPath) {
input[indexPath.section - 1].shouldShowRecipientsList.toggle()

UIView.animate(withDuration: 0.3) {
self.node.reloadSections(IndexSet(integer: indexPath.section), with: .automatic)
}
}

private func handleReplyTap(at indexPath: IndexPath) {
composeNewMessage(at: indexPath, quoteType: .reply)
}
Expand Down Expand Up @@ -185,7 +195,7 @@ extension ThreadDetailsViewController {
let replyInfo = ComposeMessageInput.MessageQuoteInfo(
recipients: recipients,
sender: input.rawMessage.sender,
subject: "\(quoteType.subjectPrefix)\(subject)",
subject: [quoteType.subjectPrefix, subject].joined(),
mime: processedMessage.rawMimeData,
sentDate: input.rawMessage.date,
message: processedMessage.text,
Expand Down Expand Up @@ -374,7 +384,7 @@ extension ThreadDetailsViewController {
}

extension ThreadDetailsViewController: MessageActionsHandler {

private func handleSuccessfulMessage(action: MessageAction) {
hideSpinner()
onComplete(action, .init(thread: thread, folderPath: currentFolderPath, activeUserEmail: user.email))
Expand Down Expand Up @@ -454,37 +464,37 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
return MessageSubjectNode(subject.attributed(.medium(18)))
}

let section = self.input[indexPath.section-1]
let message = self.input[indexPath.section-1]

if indexPath.row == 0 {
return ThreadMessageSenderCellNode(
input: .init(threadMessage: section),
return ThreadMessageInfoCellNode(
input: .init(threadMessage: message),
onReplyTap: { [weak self] _ in self?.handleReplyTap(at: indexPath) },
onMenuTap: { [weak self] _ in self?.handleMenuTap(at: indexPath) }
onMenuTap: { [weak self] _ in self?.handleMenuTap(at: indexPath) },
onRecipientsTap: { [weak self] _ in self?.handleRecipientsTap(at: indexPath) }
)
}

if indexPath.row == 1, let message = section.processedMessage {
return MessageTextSubjectNode(message.attributedMessage)
}
guard let processedMessage = message.processedMessage
else { return ASCellNode() }

if indexPath.row > 1, let message = section.processedMessage {
let attachment = message.attachments[indexPath.row - 2]
return AttachmentNode(
input: .init(
msgAttachment: attachment,
index: indexPath.row - 2
),
onDownloadTap: { [weak self] in self?.attachmentManager.open(attachment) }
)
}
guard indexPath.row > 1
else { return MessageTextSubjectNode(processedMessage.attributedMessage) }

return ASCellNode()
let attachmentIndex = indexPath.row - 2
let attachment = processedMessage.attachments[attachmentIndex]
return AttachmentNode(
input: .init(
msgAttachment: attachment,
index: attachmentIndex
),
onDownloadTap: { [weak self] in self?.attachmentManager.open(attachment) }
)
}
}

func tableNode(_ tableNode: ASTableNode, didSelectRowAt indexPath: IndexPath) {
guard tableNode.nodeForRow(at: indexPath) is ThreadMessageSenderCellNode else {
guard tableNode.nodeForRow(at: indexPath) is ThreadMessageInfoCellNode else {
return
}
handleExpandTap(at: indexPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
import GoogleAPIClientForREST_Gmail

class GmailService: MailServiceProvider {

let mailServiceProviderType = MailServiceProviderType.gmail
let userService: GoogleUserServiceType
let backupSearchQueryProvider: GmailBackupSearchQueryProviderType
Expand Down Expand Up @@ -55,5 +55,7 @@ extension String {
static let subject = "subject"
static let date = "date"
static let to = "to"
static let cc = "cc"
static let bcc = "bcc"
static let identifier = "Message-ID"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Foundation
import MailCore

extension Imap {

func fetchMsg(message: MCOIMAPMessage, folder: String) async throws -> Data {
return try await execute("fetchMsg", { sess, respond in
sess.fetchMessageOperation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ protocol ImapSessionProviderType {
}

class ImapSessionProvider: ImapSessionProviderType {

private let user: User

init(user: User) {
self.user = user
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

extension Imap: MessageProvider {

func fetchMsg(
message: Message,
folder: String,
Expand Down
Loading