Commit 8d3c570b authored by Kateryna Kostiuk's avatar Kateryna Kostiuk

data transfer: accept small files automatically

Accept small files automatically at any application state.

Change-Id: I36a627809d7075aa79d4f9cad1aa6b97bc995f52
parent 0241a10b
......@@ -111,6 +111,8 @@ enum InteractionType: String {
case oTransfer = "OUTGOING_DATA_TRANSFER"
}
typealias savedMessageForConversation = (messageID: Int64, conversationID: Int64)
class DBManager {
let profileHepler: ProfileDataHelper
......@@ -133,7 +135,7 @@ class DBManager {
try interactionHepler.createTable()
}
func saveMessage(for accountUri: String, with contactUri: String, message: MessageModel, incoming: Bool, interactionType: InteractionType) -> Observable<Int64?> {
func saveMessage(for accountUri: String, with contactUri: String, message: MessageModel, incoming: Bool, interactionType: InteractionType) -> Observable<savedMessageForConversation> {
//create completable which will be executed on background thread
return Observable.create { [weak self] observable in
......@@ -181,8 +183,9 @@ class DBManager {
default:
result = nil
}
if let success = result {
observable.onNext(success)
if let messageID = result {
let savedMessage = savedMessageForConversation(messageID, conversationID)
observable.onNext(savedMessage)
observable.on(.completed)
} else {
observable.on(.error(DBBridgingError.saveMessageFailed))
......
......@@ -683,14 +683,6 @@ class ConversationViewController: UIViewController,
cell.statusLabel.textColor = UIColor.jamiSuccess
cell.cancelButton.setTitle(L10n.DataTransfer.readableStatusCancel, for: .normal)
} else if item.bubblePosition() == .received {
// accept automatically if less than 10MB and is an image
if let transferId = item.daemonId,
let isImage = viewModel.isTransferImage(transferId: transferId),
let size = viewModel.getTransferSize(transferId: transferId), isImage && size <= 10485760 {
if viewModel.acceptTransfer(transferId: transferId, interactionID: item.messageId, messageContent: &item.message.content) != .success {
_ = self.viewModel.cancelTransfer(transferId: transferId)
}
}
// hide status
cell.statusLabel.isHidden = true
cell.acceptButton?.isHidden = false
......
......@@ -39,4 +39,10 @@ class ConversationModel: Equatable {
public static func == (lhs: ConversationModel, rhs: ConversationModel) -> Bool {
return (lhs.recipientRingId == rhs.recipientRingId && lhs.accountId == rhs.accountId)
}
public func getMessage(withDaemonID daemonID: String) -> MessageModel? {
return self.messages.filter({ message in
return message.daemonId == daemonID
}).first
}
}
......@@ -33,6 +33,7 @@ class ConversationsManager: MessagesAdapterDelegate {
private let disposeBag = DisposeBag()
fileprivate let textPlainMIMEType = "text/plain"
fileprivate let maxSizeForAutoaccept = 20 * 1024 * 1024
private let notificationHandler = LocalNotificationsHelper()
init(with conversationService: ConversationsService, accountsService: AccountsService, nameService: NameService, dataTransferService: DataTransferService) {
......@@ -86,6 +87,11 @@ class ConversationsManager: MessagesAdapterDelegate {
accountRingId: accountHelper.ringId!,
accountId: currentAccount.id,
photoIdentifier: photoIdentifier)
.subscribe(onCompleted: {
guard let transferInfo = self.dataTransferService
.getTransferInfo(withId: transferId) else {return}
self.autoAcceptTransfer(transferInfo: transferInfo, transferId: transferId, accountId: currentAccount.id)
}).disposed(by: self.disposeBag)
case .dataTransferChanged:
self.log.debug("ConversationsManager: dataTransferChanged - id:\(transferId) status:\(stringFromEventCode(with: transferInfo.lastEvent))")
......@@ -93,14 +99,18 @@ class ConversationsManager: MessagesAdapterDelegate {
switch transferInfo.lastEvent {
case .closed_by_host, .closed_by_peer:
status = DataTransferStatus.canceled
self.conversationService.dataTransferMessageMap.removeValue(forKey: transferId)
case .invalid, .unsupported, .invalid_pathname, .unjoinable_peer:
status = DataTransferStatus.error
self.conversationService.dataTransferMessageMap.removeValue(forKey: transferId)
case .wait_peer_acceptance, .wait_host_acceptance:
status = DataTransferStatus.awaiting
self.autoAcceptTransfer(transferInfo: transferInfo, transferId: transferId, accountId: currentAccount.id)
case .ongoing:
status = DataTransferStatus.ongoing
case .finished:
status = DataTransferStatus.success
self.conversationService.dataTransferMessageMap.removeValue(forKey: transferId)
case .created:
break
}
......@@ -193,4 +203,22 @@ class ConversationsManager: MessagesAdapterDelegate {
fromAccount: account,
to: uri)
}
func autoAcceptTransfer(transferInfo: NSDataTransferInfo, transferId: UInt64, accountId: String) {
if transferInfo.flags != 1 || transferInfo.totalSize > maxSizeForAutoaccept ||
(transferInfo.lastEvent != .wait_peer_acceptance && transferInfo.lastEvent != .wait_host_acceptance) {
return
}
guard let messageData = self.conversationService.dataTransferMessageMap[transferId] else {return}
if !(self.dataTransferService.isTransferImage(withId: transferId, accountID: accountId,
conversationID: String(messageData.conversationID)) ?? false) {
return
}
var filename = ""
if self.dataTransferService.acceptTransfer(withId: transferId, interactionID: messageData.messageID,
fileName: &filename, accountID: accountId,
conversationID: String(messageData.conversationID)) != .success {
self.log.debug("ConversationsManager: accept transfer failed")
}
}
}
......@@ -40,7 +40,9 @@ class ConversationsService {
var messagesSemaphore = DispatchSemaphore(value: 1)
var dataTransferMessageMap = [UInt64: Int64]()
typealias savedMessageForConversation = (messageID: Int64, conversationID: Int64)
var dataTransferMessageMap = [UInt64: savedMessageForConversation]()
lazy var conversationsForCurrentAccount: Observable<[ConversationModel]> = {
return self.conversations.asObservable()
......@@ -221,7 +223,9 @@ class ConversationsService {
transferInfo: NSDataTransferInfo,
accountRingId: String,
accountId: String,
photoIdentifier: String?) {
photoIdentifier: String?) -> Completable {
return Completable.create(subscribe: { [unowned self] completable in
let fileSizeWithUnit = ByteCountFormatter.string(fromByteCount: transferInfo.totalSize, countStyle: .file)
var messageContent = transferInfo.displayName + "\n" + fileSizeWithUnit
......@@ -241,8 +245,8 @@ class ConversationsService {
self.messagesSemaphore.wait()
self.dbManager.saveMessage(for: accountRingId, with: contactRingId, message: message, incoming: isIncoming, interactionType: interactionType)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.subscribe(onNext: { [unowned self] messageId in
self.dataTransferMessageMap[transferId] = messageId
.subscribe(onNext: { [unowned self] message in
self.dataTransferMessageMap[transferId] = message
self.dbManager.getConversationsObservable(for: accountId, accountURI: accountRingId)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.subscribe(onNext: { conversationsModels in
......@@ -252,12 +256,16 @@ class ConversationsService {
var serviceEvent = ServiceEvent(withEventType: serviceEventType)
serviceEvent.addEventInput(.transferId, value: transferId)
self.responseStream.onNext(serviceEvent)
completable(.completed)
})
.disposed(by: (self.disposeBag))
}, onError: { [unowned self] _ in
}, onError: { [unowned self] error in
self.messagesSemaphore.signal()
completable(.error(error))
})
.disposed(by: self.disposeBag)
return Disposables.create { }
})
}
func status(forMessageId messageId: String) -> MessageStatus {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment