Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

fix(actions): disable the save action if there is a save operation in progress. #1470

Merged
merged 5 commits into from
Nov 17, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import com.itsaky.androidide.projects.ProjectManagerImpl
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.flashError
import com.itsaky.androidide.utils.flashInfo
import com.itsaky.androidide.utils.flashSuccess
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

/** @author Akash Yadav */
Expand Down Expand Up @@ -54,16 +56,20 @@ class SaveFileAction(context: Context, override val order: Int) : EditorRelatedA
}

visible = context.editorViewModel.getOpenedFiles().isNotEmpty()
enabled = context.areFilesModified()
enabled = context.areFilesModified() && !context.areFilesSaving()
}

override suspend fun execAction(data: ActionData): ResultWrapper {
val context = data.getActivity() ?: return ResultWrapper()

if (context.areFilesSaving()) {
return ResultWrapper(isAlreadySaving = true)
}

return try {
// Cannot use context.saveAll() because this.execAction is called on non-UI thread
// and saveAll call will result in UI actions
ResultWrapper(runBlocking { context.saveAllResult() })
ResultWrapper(result = runBlocking { context.saveAllResult() })
} catch (error: Throwable) {
log.error("Failed to save file", error)
ResultWrapper()
Expand All @@ -74,9 +80,14 @@ class SaveFileAction(context: Context, override val order: Int) : EditorRelatedA
if (result is ResultWrapper && result.result != null) {
val context = data.requireActivity()

if (result.isAlreadySaving) {
context.flashError(R.string.msg_files_being_saved)
return
}

// show save notification before calling 'notifySyncNeeded' so that the file save notification
// does not overlap the sync notification
flashSuccess(R.string.all_saved)
context.flashSuccess(R.string.all_saved)

val saveResult = result.result
if (saveResult.xmlSaved) {
Expand All @@ -94,5 +105,5 @@ class SaveFileAction(context: Context, override val order: Int) : EditorRelatedA
}
}

inner class ResultWrapper(val result: SaveResult? = null)
inner class ResultWrapper(val isAlreadySaving: Boolean = false, val result: SaveResult? = null)
}
Original file line number Diff line number Diff line change
Expand Up @@ -413,27 +413,40 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
}

override suspend fun saveAllResult(progressConsumer: ((Int, Int) -> Unit)?): SaveResult {
setFilesSaving(true)
val result = SaveResult()
for (i in 0 until editorViewModel.getOpenedFileCount()) {
saveResult(i, result)
saveResultInternal(i, result, false)
progressConsumer?.invoke(i + 1, editorViewModel.getOpenedFileCount())
}
setFilesSaving(false)
return result
}

override suspend fun saveResult(index: Int, result: SaveResult) {
saveResultInternal(index, result, true)
}

private suspend fun saveResultInternal(index: Int, result: SaveResult, updateSaving: Boolean) {
if (index < 0 || index >= editorViewModel.getOpenedFileCount()) {
return
}

val frag = getEditorAtIndex(index) ?: return
val fileName = frag.file?.name ?: return

if (updateSaving) {
setFilesSaving(true)
}

run {
// Must be called before frag.save()
// Otherwise, it'll always return false
val modified = frag.isModified
if (!frag.save()) {
if (updateSaving) {
setFilesSaving(false)
}
return
}

Expand All @@ -457,7 +470,13 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
val finalModified = modified

withContext(Dispatchers.Main) {
editorViewModel.setFilesModified(finalModified)
editorViewModel.apply {
setFilesModified(finalModified)
}

if (updateSaving) {
setFilesSaving(false)
}

// set tab as unmodified
val tab = binding.tabs.getTabAt(index) ?: return@withContext
Expand All @@ -467,6 +486,13 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
}
}

private suspend fun setFilesSaving(saving: Boolean) {
withContext(Dispatchers.Main.immediate) {
invalidateOptionsMenu()
editorViewModel.setFilesSaving(saving)
}
}

private fun onEditorContentChanged() {
editorViewModel.setFilesModified(true)
invalidateOptionsMenu()
Expand All @@ -476,6 +502,10 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
return editorViewModel.areFilesModified()
}

override fun areFilesSaving(): Boolean {
return editorViewModel.areFilesSaving()
}

override fun closeFile(index: Int, runAfter: () -> Unit) {
if (index >= 0 && index < editorViewModel.getOpenedFileCount()) {
val opened: File = editorViewModel.getOpenedFile(index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ interface IEditorHandler {
fun openFileAndGetIndex(file: File, selection: Range?) : Int

fun areFilesModified(): Boolean
fun areFilesSaving(): Boolean

/**
* Save all files.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class EditorViewModel : ViewModel() {
private val _isBoundToBuildService = MutableLiveData(false)
private val files = MutableLiveData<MutableList<File>>(ArrayList())

private val fileModified = MutableLiveData(false)
private val fileModified = MutableLiveData(false)
private val fileSaving = MutableLiveData(false)

/**
* Holds information about the currently selected editor fragment. First value in the pair is the
Expand Down Expand Up @@ -201,6 +202,14 @@ class EditorViewModel : ViewModel() {
fun areFilesModified(): Boolean {
val modified = fileModified.value
return modified != null && modified
}

fun setFilesSaving(saving: Boolean) {
fileSaving.value = saving
}

fun areFilesSaving(): Boolean {
return fileSaving.value ?: false
}

fun readOpenedFiles(result: (OpenedFilesCache?) -> Unit) {
Expand Down
1 change: 1 addition & 0 deletions resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -623,4 +623,5 @@
<string name="msg_project_dir_inaccessible">Project directory is not accessible</string>
<string name="msg_file_is_not_dir">Selected file is not a directory</string>
<string name="msg_project_dir_doesnt_exist">Project directory does not exist</string>
<string name="msg_files_being_saved">A file save operation is already in progress!</string>
</resources>
Loading