Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added temporary voice messages #1874

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
10 changes: 10 additions & 0 deletions NextcloudTalk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@
DA66583127B6B24E00B46B11 /* UserProfileTableViewController+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA66583027B6B24E00B46B11 /* UserProfileTableViewController+Utils.swift */; };
DA75580F278EEA1000A48A1B /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA75580E278EEA1000A48A1B /* SettingsTableViewController.swift */; };
DA8801A227A2DA00009EF248 /* UserProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8801A127A2DA00009EF248 /* UserProfileTableViewController.swift */; };
F644A2DD2CE287FA00E2ED81 /* ChatFileUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F644A2DC2CE287FA00E2ED81 /* ChatFileUploader.swift */; };
F644A2DF2CE28C8D00E2ED81 /* NCChatFileStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4DA7F2C023FF300C1B952 /* NCChatFileStatus.swift */; };
F644A2E02CE28C9A00E2ED81 /* NCChatFileStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4DA7F2C023FF300C1B952 /* NCChatFileStatus.swift */; };
F644A2E12CE28CA500E2ED81 /* NCChatFileStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4DA7F2C023FF300C1B952 /* NCChatFileStatus.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -1207,6 +1211,7 @@
DA66583027B6B24E00B46B11 /* UserProfileTableViewController+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserProfileTableViewController+Utils.swift"; sourceTree = "<group>"; };
DA75580E278EEA1000A48A1B /* SettingsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
DA8801A127A2DA00009EF248 /* UserProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileTableViewController.swift; sourceTree = "<group>"; };
F644A2DC2CE287FA00E2ED81 /* ChatFileUploader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatFileUploader.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -2148,6 +2153,7 @@
1F35F8FA2AEEDBC600044BDA /* ChatViewControllerExtension.swift */,
2C4230F62B207AB00013E1FA /* ContextChatViewController.swift */,
1F0B0A712BA264540073FF8D /* MentionSuggestion.swift */,
F644A2DC2CE287FA00E2ED81 /* ChatFileUploader.swift */,
);
name = Chat;
sourceTree = "<group>";
Expand Down Expand Up @@ -2801,6 +2807,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F644A2E12CE28CA500E2ED81 /* NCChatFileStatus.swift in Sources */,
1F1B504B2B90CF0C00B0F2F4 /* FederatedCapabilities.m in Sources */,
1F77A5F22AB9A436007B6037 /* EmojiUtils.swift in Sources */,
1F77A5FA2AB9A4DF007B6037 /* NCMessageLocationParameter.m in Sources */,
Expand Down Expand Up @@ -3090,6 +3097,7 @@
2CB6ACBC26385A3800D3D641 /* ShareLocationViewController.m in Sources */,
2C04249B2CA33681004772F6 /* AudioPlayerView.swift in Sources */,
1F1B0F462BE047CE003FD766 /* InteractionControlling.swift in Sources */,
F644A2DD2CE287FA00E2ED81 /* ChatFileUploader.swift in Sources */,
1FDCC3D429EBF6E700DEB39B /* AvatarImageView.swift in Sources */,
1FB78E262B6AE5A600B0D69D /* FederationInvitation.swift in Sources */,
1FDFC94D2BA50B9100670DF4 /* UIFontExtension.swift in Sources */,
Expand Down Expand Up @@ -3117,6 +3125,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F644A2E02CE28C9A00E2ED81 /* NCChatFileStatus.swift in Sources */,
1F4DD3ED2571C688007DC98E /* EmojiUtils.swift in Sources */,
1F35F8EB2AEEBC1100044BDA /* UIResponder+SLKAdditions.m in Sources */,
2C62B02424C1BDCF007E460A /* NCAppBranding.m in Sources */,
Expand Down Expand Up @@ -3207,6 +3216,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F644A2DF2CE28C8D00E2ED81 /* NCChatFileStatus.swift in Sources */,
2C1ABDCF257E939600AEDFB6 /* NCContact.m in Sources */,
2CC001DC24A37AD400A20167 /* NCAppBranding.m in Sources */,
2C4446D42658147900DF1DBC /* TalkAccount.m in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions NextcloudTalk/BaseChatTableViewCell+Audio.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ extension BaseChatTableViewCell {
}

func audioPlayerPlayButtonPressed() {
guard let audioFileParameter = message?.file() else {
guard let audioFile = message else {
return
}

self.delegate?.cellWants(toPlayAudioFile: audioFileParameter)
self.delegate?.cellWants(toPlayAudioFile: audioFile)
}

func audioPlayerPauseButtonPressed() {
Expand Down
2 changes: 1 addition & 1 deletion NextcloudTalk/BaseChatTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protocol BaseChatTableViewCellDelegate: AnyObject {

func cellWants(toOpenLocation geoLocationRichObject: GeoLocationRichObject)

func cellWants(toPlayAudioFile fileParameter: NCMessageFileParameter)
func cellWants(toPlayAudioFile message: NCChatMessage)
func cellWants(toPauseAudioFile fileParameter: NCMessageFileParameter)
func cellWants(toChangeProgress progress: CGFloat, fromAudioFile fileParameter: NCMessageFileParameter)

Expand Down
169 changes: 127 additions & 42 deletions NextcloudTalk/BaseChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ import QuickLook

// MARK: - Temporary messages

internal func createTemporaryMessage(message: String, replyTo parentMessage: NCChatMessage?, messageParameters: String, silently: Bool) -> NCChatMessage {
internal func createTemporaryMessage(message: String, replyTo parentMessage: NCChatMessage?, messageParameters: String, silently: Bool, isVoiceMessage: Bool) -> NCChatMessage {
let temporaryMessage = NCChatMessage()
let activeAccount = NCDatabaseManager.sharedInstance().activeAccount()

Expand All @@ -475,14 +475,41 @@ import QuickLook
temporaryMessage.actorType = "users"
temporaryMessage.timestamp = Int(Date().timeIntervalSince1970)
temporaryMessage.token = room.token
temporaryMessage.message = self.replaceMentionsDisplayNamesWithMentionsKeysInMessage(message: message, parameters: messageParameters)

let referenceId = "temp-\(Date().timeIntervalSince1970 * 1000)"
temporaryMessage.referenceId = NCUtils.sha1(fromString: referenceId)
temporaryMessage.internalId = referenceId
temporaryMessage.isTemporary = true
temporaryMessage.parentId = parentMessage?.internalId
temporaryMessage.messageParametersJSONString = messageParameters
DanielStandfest marked this conversation as resolved.
Show resolved Hide resolved

if isVoiceMessage {
var messageParametersDict = [String: Any]()
let parameterId = UUID().uuidString

temporaryMessage.message = message
temporaryMessage.messageType = kMessageTypeVoiceMessage

let fileParameterDict: [String: Any] = [
"id": parameterId,
"type": "file",
"name": message,
"path": messageParameters,
"fileId": parameterId,
"fileName": message,
"filePath": messageParameters,
"fileLocalPath": messageParameters
]

messageParametersDict[parameterId] = fileParameterDict
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why using a UUID here? Should it be the file dictionary? I don't see it used anywhere? (Maybe I missed it, not yet through everything).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I guess I had a problem with the file parameter not being set when putting the fileParameters in no dictionary.
What's your suggestion?


if let jsonData = try? JSONSerialization.data(withJSONObject: messageParametersDict, options: []) {
let messageParametersJSONString = String(data: jsonData, encoding: .utf8) ?? ""
temporaryMessage.messageParametersJSONString = messageParametersJSONString
}
} else {
temporaryMessage.messageParametersJSONString = messageParameters
temporaryMessage.message = self.replaceMentionsDisplayNamesWithMentionsKeysInMessage(message: message, parameters: messageParameters)
}
temporaryMessage.isSilent = silently
temporaryMessage.isMarkdownMessage = NCDatabaseManager.sharedInstance().roomHasTalkCapability(kCapabilityMarkdownMessages, for: self.room)

Expand Down Expand Up @@ -954,8 +981,25 @@ import QuickLook
self.removeUnreadMessagesSeparator()

self.removePermanentlyTemporaryMessage(temporaryMessage: message)
let originalMessage = self.replaceMessageMentionsKeysWithMentionsDisplayNames(message: message.message, parameters: message.messageParametersJSONString ?? "")
self.sendChatMessage(message: originalMessage, withParentMessage: message.parent, messageParameters: message.messageParametersJSONString ?? "", silently: message.isSilent)
guard var originalMessage = message.message else { return }
if message.messageType != kMessageTypeVoiceMessage {
originalMessage = self.replaceMessageMentionsKeysWithMentionsDisplayNames(message: message.message, parameters: message.messageParametersJSONString ?? "")
self.sendChatMessage(message: originalMessage, withParentMessage: message.parent, messageParameters: message.messageParametersJSONString ?? "", silently: message.isSilent)
} else {
let activeAccount = NCDatabaseManager.sharedInstance().activeAccount()
if NCDatabaseManager.sharedInstance().roomHasTalkCapability(kCapabilityChatReferenceId, for: room) {
self.appendTemporaryMessage(temporaryMessage: message)
}
NCAPIController.sharedInstance().uniqueNameForFileUpload(withName: originalMessage, originalName: true, for: activeAccount, withCompletionBlock: { fileServerURL, fileServerPath, _, _ in
if let fileServerURL, let fileServerPath {
let talkMetaData: [String: String] = ["messageType": "voice-message"]

self.uploadFileAtPath(localPath: message.file().fileStatus!.fileLocalPath!, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: talkMetaData, temporaryMessage: message)
} else {
NSLog("Could not find unique name for voice message file.")
}
})
}
}

func didPressCopy(for message: NCChatMessage) {
Expand Down Expand Up @@ -1461,7 +1505,7 @@ import QuickLook

NCAPIController.sharedInstance().uniqueNameForFileUpload(withName: contactFileName, originalName: true, for: activeAccount) { fileServerURL, fileServerPath, _, _ in
if let fileServerURL, let fileServerPath {
self.uploadFileAtPath(localPath: url.path, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: nil)
self.uploadFileAtPath(localPath: url.path, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: nil, temporaryMessage: nil)
} else {
print("Could not find unique name for contact file")
}
Expand Down Expand Up @@ -1590,52 +1634,83 @@ import QuickLook
audioFileName += ".mp3"

let activeAccount = NCDatabaseManager.sharedInstance().activeAccount()
NCAPIController.sharedInstance().setupNCCommunication(for: activeAccount)
let chatFileController = NCChatFileController()
chatFileController.initDownloadDirectory(for: activeAccount)

let tempDirectoryURL = URL(fileURLWithPath: chatFileController.tempDirectoryPath)
let destinationFilePath = tempDirectoryURL.appendingPathComponent(audioFileName).path

let temporaryMessage = self.createTemporaryMessage(
message: audioFileName,
replyTo: nil,
messageParameters: "\(destinationFilePath)",
silently: false,
isVoiceMessage: true
)

chatFileController.setFileStatusFrom(temporaryMessage.file())

let movedFileToTemporaryDirectory = chatFileController.moveFileToTemporaryDirectory(
fromSourcePath: self.recorder!.url.path,
destinationPath: destinationFilePath
)

if movedFileToTemporaryDirectory, NCDatabaseManager.sharedInstance().roomHasTalkCapability(kCapabilityChatReferenceId, for: room) {
self.appendTemporaryMessage(temporaryMessage: temporaryMessage)
}

NCAPIController.sharedInstance().uniqueNameForFileUpload(withName: audioFileName, originalName: true, for: activeAccount, withCompletionBlock: { fileServerURL, fileServerPath, _, _ in
if let fileServerURL, let fileServerPath, let recorder = self.recorder {
let talkMetaData: [String: String] = ["messageType": "voice-message"]
self.uploadFileAtPath(localPath: recorder.url.path, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: talkMetaData)

self.uploadFileAtPath(localPath: recorder.url.path, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: talkMetaData, temporaryMessage: temporaryMessage)
} else {
NSLog("Could not find unique name for voice message file.")
}
})
}

func uploadFileAtPath(localPath: String, withFileServerURL fileServerURL: String, andFileServerPath fileServerPath: String, withMetaData talkMetaData: [String: String]?) {
let activeAccount = NCDatabaseManager.sharedInstance().activeAccount()
NCAPIController.sharedInstance().setupNCCommunication(for: activeAccount)
func uploadFileAtPath(localPath: String, withFileServerURL fileServerURL: String, andFileServerPath fileServerPath: String, withMetaData talkMetaData: [String: String]?, temporaryMessage: NCChatMessage?) {

NextcloudKit.shared.upload(serverUrlFileName: fileServerURL, fileNameLocalPath: localPath, taskHandler: { _ in
NSLog("Upload task")
}, progressHandler: { progress in
NSLog("Progress:%f", progress.fractionCompleted)
}, completionHandler: { _, _, _, _, _, _, _, error in
NSLog("Upload completed with error code: %ld", error.errorCode)

if error.errorCode == 0 {
NCAPIController.sharedInstance().shareFileOrFolder(for: activeAccount, atPath: fileServerPath, toRoom: self.room.token, talkMetaData: talkMetaData, withCompletionBlock: { error in
if error != nil {
NSLog("Failed to share voice message")
}
})
} else if error.errorCode == 404 || error.errorCode == 409 {
NCAPIController.sharedInstance().checkOrCreateAttachmentFolder(for: activeAccount, withCompletionBlock: { created, _ in
if created {
self.uploadFileAtPath(localPath: localPath, withFileServerURL: fileServerURL, andFileServerPath: fileServerPath, withMetaData: talkMetaData)
} else {
NSLog("Failed to check or create attachment folder")
}
})
} else if error.errorCode == 507 {
let alert = UIAlertController(title: NSLocalizedString("Upload failed", comment: ""),
message: error.errorDescription,
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default))
self.present(alert, animated: true)
NSLog("Failed to upload voice message due to missing user storage quota")
} else {
NSLog("Failed upload voice message")
ChatFileUploader.uploadFile(localPath: localPath,
fileServerURL: fileServerURL,
fileServerPath: fileServerPath,
talkMetaData: talkMetaData,
temporaryMessage: temporaryMessage,
room: self.room) { statusCode, errorMessage in
DispatchQueue.main.async {
switch statusCode {
case 200:
NSLog("Successfully uploaded and shared voice message")
case 401:
NSLog("No active account found")
self.showAlert(title: NSLocalizedString("Upload failed", comment: ""), message: NSLocalizedString("No active account found", comment: ""))
case 403:
NSLog("Failed to share voice message")
self.showAlert(title: NSLocalizedString("Upload failed", comment: ""), message: NSLocalizedString("Failed to share recording", comment: ""))
case 404:
NSLog("Failed to check or create attachment folder")
self.showAlert(title: NSLocalizedString("Upload failed", comment: ""), message: NSLocalizedString("Failed to check or create attachment folder", comment: ""))
case 507:
NSLog("User storage quota exceeded")
let alert = UIAlertController(title: NSLocalizedString("Upload failed", comment: ""),
message: NSLocalizedString("User storage quota exceeded", comment: ""),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default))
self.present(alert, animated: true)
default:
NSLog("Failed upload voice message with error code \(statusCode)")
self.showAlert(title: NSLocalizedString("Upload failed", comment: ""), message: NSLocalizedString("Unknown error occurred", comment: ""))
}
}
})
}
}

func showAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default))
self.present(alert, animated: true)
}

// MARK: - AVAudioRecorder Delegate
Expand Down Expand Up @@ -3236,12 +3311,22 @@ import QuickLook

// MARK: - VoiceMessageTableViewCellDelegate

public func cellWants(toPlayAudioFile fileParameter: NCMessageFileParameter) {
public func cellWants(toPlayAudioFile message: NCChatMessage) {
guard let fileParameter = message.file() else {
print("No file for message found")
return
}

if fileParameter.fileStatus != nil && fileParameter.fileStatus?.isDownloading ?? false {
print("File already downloading -> skipping new download")
return
}

if fileParameter.fileStatus?.fileLocalPath != nil && FileManager.default.fileExists(atPath: fileParameter.fileStatus?.fileLocalPath ?? "") {
self.setupVoiceMessagePlayer(with: fileParameter.fileStatus!)
return
}

if let voiceMessagesPlayer = self.voiceMessagesPlayer,
let playerAudioFileStatus = self.playerAudioFileStatus,
!voiceMessagesPlayer.isPlaying,
Expand Down
Loading