Skip to content

Commit

Permalink
Refactor file attachment repositories
Browse files Browse the repository at this point in the history
Remove SecureFileAttachmentRepository and some SC use cases that duplicated the logic.
Refactor FileAttachmentRepository and the file upload use cases. FileAttachmentRepository is used for both SC and Live Engagement.

MOB-3791
  • Loading branch information
AndriiHorishniiMOC authored and gugalo committed Dec 16, 2024
1 parent c55758d commit 057d576
Show file tree
Hide file tree
Showing 36 changed files with 214 additions and 600 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import com.glia.widgets.core.engagement.domain.UpdateOperatorDefaultImageUrlUseC
import com.glia.widgets.core.fileupload.domain.AddFileAttachmentsObserverUseCase
import com.glia.widgets.core.fileupload.domain.AddFileToAttachmentAndUploadUseCase
import com.glia.widgets.core.fileupload.domain.GetFileAttachmentsUseCase
import com.glia.widgets.core.fileupload.domain.RemoveFileAttachmentObserverUseCase
import com.glia.widgets.core.fileupload.domain.RemoveFileAttachmentUseCase
import com.glia.widgets.core.fileupload.domain.SupportedFileCountCheckUseCase
import com.glia.widgets.core.fileupload.model.LocalAttachment
Expand Down Expand Up @@ -89,8 +88,8 @@ import com.glia.widgets.view.MinimizeHandler
import com.glia.widgets.webbrowser.domain.GetUrlFromLinkUseCase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.Observer

internal class ChatController(
private val callTimer: TimeCounter,
Expand All @@ -104,7 +103,6 @@ internal class ChatController(
private val endEngagementUseCase: EndEngagementUseCase,
private val addFileToAttachmentAndUploadUseCase: AddFileToAttachmentAndUploadUseCase,
private val addFileAttachmentsObserverUseCase: AddFileAttachmentsObserverUseCase,
private val removeFileAttachmentObserverUseCase: RemoveFileAttachmentObserverUseCase,
private val getFileAttachmentsUseCase: GetFileAttachmentsUseCase,
private val removeFileAttachmentUseCase: RemoveFileAttachmentUseCase,
private val supportedFileCountCheckUseCase: SupportedFileCountCheckUseCase,
Expand Down Expand Up @@ -183,10 +181,10 @@ internal class ChatController(
@Volatile
private var isChatViewPaused = false

private val fileAttachmentObserver = Observer { _, _ ->
private val fileAttachmentCallback = Consumer<List<LocalAttachment>> { attachments ->
view?.apply {
emitUploadAttachments(getFileAttachmentsUseCase())
emitViewState {
emitUploadAttachments(attachments)
chatState.setShowSendButton(isShowSendButtonUseCase(chatState.lastTypedText))
.setIsAttachmentButtonEnabled(supportedFileCountCheckUseCase())
}
Expand Down Expand Up @@ -313,7 +311,9 @@ internal class ChatController(
}

private fun prepareChatComponents() {
addFileAttachmentsObserverUseCase.execute(fileAttachmentObserver)
disposable.add(
addFileAttachmentsObserverUseCase().subscribe(fileAttachmentCallback)
)
minimizeHandler.addListener { minimizeView() }
timerStatusListener?.also { callTimer.removeFormattedValueListener(it) }
val newTimerListener = createNewTimerCallback()
Expand Down Expand Up @@ -376,7 +376,6 @@ internal class ChatController(
timerStatusListener = null
callTimer.clear()
minimizeHandler.clear()
removeFileAttachmentObserverUseCase(fileAttachmentObserver)
chatManager.reset()
}
}
Expand Down Expand Up @@ -855,7 +854,7 @@ internal class ChatController(
}

private fun onAttachmentReceived(file: LocalAttachment) {
addFileToAttachmentAndUploadUseCase.execute(file, object : AddFileToAttachmentAndUploadUseCase.Listener {
addFileToAttachmentAndUploadUseCase(file, object : AddFileToAttachmentAndUploadUseCase.Listener {
override fun onFinished() {
Logger.d(TAG, "fileUploadFinished")
//We need this file locally, so clearing only file uri reference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal class GliaSendMessageUseCase(

fun execute(message: String, listener: Listener) {
val localAttachments: List<LocalAttachment>? = fileAttachmentRepository
.readyToSendLocalAttachments
.getReadyToSendFileAttachments()
.filter { it.engagementFile != null }
.takeIf { it.isNotEmpty() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class IsShowSendButtonUseCase(
}

private fun hadReadyToSendUnsentAttachments(): Boolean {
return fileAttachmentRepository.readyToSendLocalAttachments.isNotEmpty()
return fileAttachmentRepository.getReadyToSendFileAttachments().isNotEmpty()
}

private fun hasEngagementOngoingAndReadyToSendUnsentAttachments(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,75 @@ import com.glia.widgets.core.engagement.exception.EngagementMissingException
import com.glia.widgets.core.fileupload.domain.AddFileToAttachmentAndUploadUseCase
import com.glia.widgets.core.fileupload.model.LocalAttachment
import com.glia.widgets.di.GliaCore
import java.util.Observable
import java.util.Observer
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.subjects.BehaviorSubject
import kotlin.jvm.optionals.getOrNull

internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
internal interface FileAttachmentRepository {
val observable: Observable<List<LocalAttachment>>

fun getFileAttachments(): List<LocalAttachment>
fun getReadyToSendFileAttachments(): List<LocalAttachment>
fun getAttachedFilesCount(): Int
fun isFileAttached(uri: Uri): Boolean
fun attachFile(file: LocalAttachment)
fun uploadFile(shouldUseSecureMessagingEndpoints: Boolean, file: LocalAttachment, listener: AddFileToAttachmentAndUploadUseCase.Listener)
fun detachFile(attachment: LocalAttachment)
fun detachFiles(attachments: List<LocalAttachment>)
fun detachAllFiles()
fun setFileAttachmentTooLarge(uri: Uri)
fun setSupportedFileAttachmentCountExceeded(uri: Uri)
fun setFileAttachmentEngagementMissing(uri: Uri)
}

internal class FileAttachmentRepositoryImpl(
private val gliaCore: GliaCore
) : FileAttachmentRepository {
private val secureConversations: SecureConversations by lazy {
gliaCore.secureConversations
}

private val observable = ObservableFileAttachmentList()
private val _observable = BehaviorSubject.createDefault(emptyList<LocalAttachment>())

override val observable: Observable<List<LocalAttachment>> = _observable

val localAttachments: List<LocalAttachment>
get() = observable.localAttachments
override fun getFileAttachments(): List<LocalAttachment> {
return _observable.value ?: emptyList()
}

val readyToSendLocalAttachments: List<LocalAttachment>
get() = observable.localAttachments
override fun getReadyToSendFileAttachments(): List<LocalAttachment> {
return getFileAttachments()
.filter { obj: LocalAttachment -> obj.isReadyToSend }
}

val attachedFilesCount: Long
get() = observable.localAttachments.size.toLong()
override fun getAttachedFilesCount(): Int {
return getFileAttachments().size
}

fun isFileAttached(uri: Uri): Boolean {
return observable.localAttachments
override fun isFileAttached(uri: Uri): Boolean {
return getFileAttachments()
.any { it.uri == uri }
}

fun attachFile(file: LocalAttachment) {
observable.notifyUpdate(
observable.localAttachments + file
)
override fun attachFile(file: LocalAttachment) {
_observable.onNext(getFileAttachments() + file)
}

fun uploadFile(shouldUseSecureMessagingEndpoints: Boolean, file: LocalAttachment, listener: AddFileToAttachmentAndUploadUseCase.Listener) {
val engagement = gliaCore.currentEngagement.getOrNull()
when {
override fun uploadFile(shouldUseSecureMessagingEndpoints: Boolean, file: LocalAttachment, listener: AddFileToAttachmentAndUploadUseCase.Listener) {
if (shouldUseSecureMessagingEndpoints) {
uploadFileForSecureConversation(file, listener)
} else {
uploadFileForLiveEngagement(file, listener)
}
}

shouldUseSecureMessagingEndpoints -> {
secureConversations.uploadFile(file.uri, handleFileUpload(file, listener))
}
private fun uploadFileForSecureConversation(file: LocalAttachment, listener: AddFileToAttachmentAndUploadUseCase.Listener) {
secureConversations.uploadFile(file.uri, handleFileUpload(file, listener))
}

private fun uploadFileForLiveEngagement(file: LocalAttachment, listener: AddFileToAttachmentAndUploadUseCase.Listener) {
val engagement = gliaCore.currentEngagement.getOrNull()
when {
engagement != null -> {
engagement.uploadFile(file.uri, handleFileUpload(file, listener))
}
Expand Down Expand Up @@ -76,51 +105,26 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
}
}

fun setFileAttachmentTooLarge(uri: Uri) {
setFileAttachmentStatus(uri, LocalAttachment.Status.ERROR_FILE_TOO_LARGE)
}

fun setSupportedFileAttachmentCountExceeded(uri: Uri) {
setFileAttachmentStatus(
uri,
LocalAttachment.Status.ERROR_SUPPORTED_FILE_ATTACHMENT_COUNT_EXCEEDED
)
}

fun setFileAttachmentEngagementMissing(uri: Uri) {
setFileAttachmentStatus(uri, LocalAttachment.Status.ERROR_ENGAGEMENT_MISSING)
}

fun detachFile(attachment: LocalAttachment?) {
observable.notifyUpdate(
observable.localAttachments
.filter { it.uri !== attachment?.uri }
override fun detachFile(attachment: LocalAttachment) {
_observable.onNext(
getFileAttachments()
.filter { it.uri !== attachment.uri }
)
}

fun detachFiles(attachments: List<LocalAttachment?>) {
observable.notifyUpdate(
observable.localAttachments
override fun detachFiles(attachments: List<LocalAttachment>) {
_observable.onNext(
getFileAttachments()
.filter { attachment: LocalAttachment? ->
!attachments.contains(attachment)
!attachments.contains(
attachment
)
}
)
}

fun detachAllFiles() {
observable.notifyUpdate(ArrayList())
}

fun addObserver(observer: Observer?) {
observable.addObserver(observer)
}

fun removeObserver(observer: Observer?) {
observable.deleteObserver(observer)
}

fun clearObservers() {
observable.deleteObservers()
override fun detachAllFiles() {
_observable.onNext(emptyList())
}

private fun onUploadFileSecurityScanRequired(
Expand All @@ -130,7 +134,7 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
) {
setFileAttachmentStatus(uri, LocalAttachment.Status.SECURITY_SCAN)
listener.onSecurityCheckStarted()
engagementFile.on(EngagementFile.Events.SCAN_RESULT) { scanResult: EngagementFile.ScanResult ->
engagementFile.on(EngagementFile.Events.SCAN_RESULT) { scanResult: EngagementFile.ScanResult? ->
engagementFile.off(EngagementFile.Events.SCAN_RESULT)
listener.onSecurityCheckFinished(scanResult)
onUploadFileSecurityScanReceived(uri, engagementFile, scanResult, listener)
Expand All @@ -140,7 +144,7 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
private fun onUploadFileSecurityScanReceived(
uri: Uri,
engagementFile: EngagementFile?,
scanResult: EngagementFile.ScanResult,
scanResult: EngagementFile.ScanResult?,
listener: AddFileToAttachmentAndUploadUseCase.Listener
) {
if (scanResult == EngagementFile.ScanResult.CLEAN && engagementFile != null) {
Expand All @@ -161,8 +165,8 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
}

private fun setFileAttachmentStatus(uri: Uri, status: LocalAttachment.Status) {
observable.notifyUpdate(
observable.localAttachments
_observable.onNext(
getFileAttachments()
.map { localAttachment: LocalAttachment ->
if (localAttachment.uri === uri) {
localAttachment.copy(attachmentStatus = status)
Expand All @@ -174,18 +178,30 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
}

private fun onEngagementFileReceived(uri: Uri, engagementFile: EngagementFile) {
observable.notifyUpdate(
observable.localAttachments
_observable.onNext(
getFileAttachments()
.map { attachment: LocalAttachment ->
if (attachment.uri == uri) {
attachment.copy(attachmentStatus = LocalAttachment.Status.READY_TO_SEND, engagementFile = engagementFile)
attachment.copy(engagementFile = engagementFile, attachmentStatus = LocalAttachment.Status.READY_TO_SEND)
} else {
attachment
}
}
)
}

override fun setFileAttachmentTooLarge(uri: Uri) {
setFileAttachmentStatus(uri, LocalAttachment.Status.ERROR_FILE_TOO_LARGE)
}

override fun setSupportedFileAttachmentCountExceeded(uri: Uri) {
setFileAttachmentStatus(uri, LocalAttachment.Status.ERROR_SUPPORTED_FILE_ATTACHMENT_COUNT_EXCEEDED)
}

override fun setFileAttachmentEngagementMissing(uri: Uri) {
setFileAttachmentStatus(uri, LocalAttachment.Status.ERROR_ENGAGEMENT_MISSING)
}

private fun getAttachmentStatus(exception: GliaException): LocalAttachment.Status {
return when (exception.cause) {
GliaException.Cause.FILE_UPLOAD_FORBIDDEN -> LocalAttachment.Status.ERROR_FILE_UPLOAD_FORBIDDEN
Expand All @@ -198,14 +214,4 @@ internal class FileAttachmentRepository(private val gliaCore: GliaCore) {
else -> LocalAttachment.Status.ERROR_UNKNOWN
}
}

class ObservableFileAttachmentList : Observable() {
var localAttachments: List<LocalAttachment> = ArrayList()

fun notifyUpdate(newObject: List<LocalAttachment>) {
localAttachments = newObject
setChanged()
notifyObservers()
}
}
}
Loading

0 comments on commit 057d576

Please sign in to comment.