Improved events notifications. Removed GIt dir changes detection temporarily

This commit is contained in:
Abdelilah El Aissaoui 2022-10-16 16:00:42 +02:00
parent 453df1b6d4
commit f293e9428c
13 changed files with 41 additions and 114 deletions

View File

@ -23,7 +23,6 @@ class FileChangesWatcher @Inject constructor() {
val keys = mutableMapOf<WatchKey, Path>()
suspend fun watchDirectoryPath(pathStr: String, ignoredDirsPath: List<String>) = withContext(Dispatchers.IO) {
println(ignoredDirsPath)
val watchService = FileSystems.getDefault().newWatchService()
val path = Paths.get(pathStr)
@ -41,7 +40,7 @@ class FileChangesWatcher @Inject constructor() {
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
val isIgnoredDirectory = ignoredDirsPath.any { "$pathStr/$it" == dir.toString() }
return if (!isIgnoredDirectory) {
return if (!isIgnoredDirectory && !isGitDir(dir, pathStr)) {
val watchKey = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY)
keys[watchKey] = dir
FileVisitResult.CONTINUE
@ -57,8 +56,6 @@ class FileChangesWatcher @Inject constructor() {
val dir = keys[key] ?: return@withContext
val hasGitDirectoryChanged = dir.startsWith("$pathStr$systemSeparator.git$systemSeparator")
if (events.count() == 1) {
val fileChanged = events.first().context().toString()
val fullPathOfFileChanged = "$pathStr$systemSeparator.git$systemSeparator$fileChanged"
@ -70,9 +67,7 @@ class FileChangesWatcher @Inject constructor() {
}
}
printLog(TAG, "Has git dir changed: $hasGitDirectoryChanged")
_changesNotifier.emit(hasGitDirectoryChanged)
_changesNotifier.emit(false)
// Check if new directories have been added to add them to the watchService
launch(Dispatchers.IO) {
@ -99,6 +94,10 @@ class FileChangesWatcher @Inject constructor() {
}
}
private fun isGitDir(dir: Path, pathStr: String): Boolean {
return dir.startsWith("$pathStr$systemSeparator.git$systemSeparator")
}
private fun isGitMessageFile(repoPath: String, fullPathOfFileChanged: String): Boolean {
val gitDir = "$repoPath$systemSeparator.git$systemSeparator"
return fullPathOfFileChanged == "${gitDir}COMMIT_EDITMSG" ||

View File

@ -26,14 +26,14 @@ class TabState @Inject constructor(
private val _taskEvent = MutableSharedFlow<TaskEvent>()
val taskEvent: SharedFlow<TaskEvent> = _taskEvent
var git: Git? = null
private val safeGit: Git
private var unsafeGit: Git? = null
val git: Git
get() {
val git = this.git
if (git == null) {
throw CancellationException("Null git object")
val unsafeGit = this.unsafeGit
if (unsafeGit == null) {
throw CancellationException("Repository not available")
} else
return git
return unsafeGit
}
private val _refreshData = MutableSharedFlow<RefreshType>()
@ -48,6 +48,10 @@ class TabState @Inject constructor(
private val _processing = MutableStateFlow(false)
val processing: StateFlow<Boolean> = _processing
fun initGit(git: Git) {
this.unsafeGit = git
}
fun safeProcessing(
showError: Boolean = true,
refreshType: RefreshType,
@ -65,7 +69,7 @@ class TabState @Inject constructor(
_processing.value = true
}
) {
callback(safeGit)
callback(git)
}
} catch (ex: Exception) {
hasProcessFailed = true
@ -112,7 +116,7 @@ class TabState @Inject constructor(
operationRunning = true
try {
block(safeGit)
block(git)
} catch (ex: Exception) {
ex.printStackTrace()
@ -121,52 +125,10 @@ class TabState @Inject constructor(
if (showError)
errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
} finally {
launch {
// Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the
// filesystem, therefore notifying late and being operationRunning already false (which leads to a full
// refresh because there have been changes in the git dir). This can be easily triggered by interactive
// rebase.
delay(500)
operationRunning = false
}
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
}
}
suspend fun coRunOperation(
showError: Boolean = false,
refreshType: RefreshType,
refreshEvenIfCrashes: Boolean = false,
block: suspend (git: Git) -> Unit
) = withContext(Dispatchers.IO) {
var hasProcessFailed = false
operationRunning = true
try {
block(safeGit)
} catch (ex: Exception) {
ex.printStackTrace()
hasProcessFailed = true
if (showError)
errorsManager.addError(newErrorNow(ex, ex.localizedMessage))
} finally {
launch {
// Add a slight delay because sometimes the file watcher takes a few moments to notify a change in the
// filesystem, therefore notifying late and being operationRunning already false (which leads to a full
// refresh because there have been changes in the git dir). This can be easily triggered by interactive
// rebase.
delay(500)
operationRunning = false
}
if (refreshType != RefreshType.NONE && (!hasProcessFailed || refreshEvenIfCrashes))
_refreshData.emit(refreshType)
}
}
@ -211,9 +173,9 @@ class TabState @Inject constructor(
_taskEvent.emit(taskEvent)
}
@OptIn(ExperimentalCoroutinesApi::class)
fun refreshFlowFiltered(vararg filters: RefreshType) = refreshData
.filter { refreshType ->
printLog(TAG, "Filters: ${filters.joinToString()}. Refresh type $refreshType")
filters.contains(refreshType)
}
}

View File

@ -48,7 +48,6 @@ fun AppTab(
val repositorySelectionStatusValue = repositorySelectionStatus.value
val isProcessing by tabViewModel.processing.collectAsState()
println("Tab name from scope = ${LocalTabScope.current.tabName.value}")
LocalTabScope.current.appStateManager
Box {
Column(

View File

@ -43,9 +43,7 @@ class BranchesViewModel @Inject constructor(
tabScope.launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}
@ -62,7 +60,6 @@ class BranchesViewModel @Inject constructor(
branchesList.add(0, selectedBranch)
}
_branches.value = branchesList
}

View File

@ -60,11 +60,9 @@ class DiffViewModel @Inject constructor(
RefreshType.UNCOMMITED_CHANGES,
RefreshType.UNCOMMITED_CHANGES_AND_LOG,
).collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) {
val diffResultValue = diffResult.value
if(diffResultValue is ViewDiffResult.Loaded) {
updateDiff(diffResultValue.diffEntryType)
}
val diffResultValue = diffResult.value
if (diffResultValue is ViewDiffResult.Loaded) {
updateDiff(diffResultValue.diffEntryType)
}
}
}

View File

@ -116,9 +116,7 @@ class LogViewModel @Inject constructor(
RefreshType.ONLY_LOG,
RefreshType.UNCOMMITED_CHANGES_AND_LOG,
).collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}

View File

@ -39,11 +39,9 @@ class RebaseInteractiveViewModel @Inject constructor(
println("prepareSteps started")
tabState.refreshData(RefreshType.REPO_STATE)
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
val messages = getRebaseLinesFullMessageUseCase(git, steps)
val messages = getRebaseLinesFullMessageUseCase(tabState.git, steps)
_rebaseState.value = RebaseInteractiveState.Loaded(steps, messages)
}
_rebaseState.value = RebaseInteractiveState.Loaded(steps, messages)
println("prepareSteps mutex lock")
rebaseInteractiveMutex.lock()

View File

@ -38,9 +38,7 @@ class RemotesViewModel @Inject constructor(
tabScope.launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.REMOTES)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}

View File

@ -30,22 +30,10 @@ class StashesViewModel @Inject constructor(
get() = _stashStatus
init {
tabScope.launch {
tabState.refreshData
.filter { refreshType -> refreshType == RefreshType.ALL_DATA }
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
}
}
tabScope.launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.STASHES)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}

View File

@ -70,9 +70,7 @@ class StatusViewModel @Inject constructor(
RefreshType.UNCOMMITED_CHANGES,
RefreshType.UNCOMMITED_CHANGES_AND_LOG,
).collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}
@ -120,13 +118,13 @@ class StatusViewModel @Inject constructor(
}
fun resetStaged(statusEntry: StatusEntry) = tabState.runOperation(
refreshType = RefreshType.UNCOMMITED_CHANGES,
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git ->
resetEntryUseCase(git, statusEntry, staged = true)
}
fun resetUnstaged(statusEntry: StatusEntry) = tabState.runOperation(
refreshType = RefreshType.UNCOMMITED_CHANGES,
refreshType = RefreshType.UNCOMMITED_CHANGES_AND_LOG,
) { git ->
resetEntryUseCase(git, statusEntry, staged = false)
}

View File

@ -28,9 +28,7 @@ class SubmodulesViewModel @Inject constructor(
tabScope.launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.SUBMODULES)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}

View File

@ -112,8 +112,6 @@ class TabViewModel @Inject constructor(
when (refreshType) {
RefreshType.NONE -> printLog(TAG, "Not refreshing...")
RefreshType.REPO_STATE -> refreshRepositoryState()
RefreshType.UNCOMMITED_CHANGES -> checkUncommitedChanges()
RefreshType.UNCOMMITED_CHANGES_AND_LOG -> checkUncommitedChanges()
else -> {}
}
}
@ -131,11 +129,8 @@ class TabViewModel @Inject constructor(
launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.REPO_STATE)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
loadRepositoryState(git)
}
loadRepositoryState(tabState.git)
}
}
}
}
@ -166,7 +161,7 @@ class TabViewModel @Inject constructor(
repository.workTree // test if repository is valid
_repositorySelectionStatus.value = RepositorySelectionStatus.Open(repository)
val git = Git(repository)
tabState.git = git
tabState.initGit(git)
onRepositoryChanged(repository.directory.parent)
refreshRepositoryInfo()
@ -289,6 +284,7 @@ class TabViewModel @Inject constructor(
refreshType = RefreshType.NONE,
) {
updateDiffEntry()
tabState.refreshData(RefreshType.UNCOMMITED_CHANGES_AND_LOG)
//
// // Stashes list should only be updated if we are doing a stash operation, however it's a small operation
// // that we can afford to do when doing other operations
@ -296,9 +292,9 @@ class TabViewModel @Inject constructor(
// loadRepositoryState(git)
}
private fun refreshRepositoryInfo() = tabState.safeProcessing(
refreshType = RefreshType.ALL_DATA,
) {}
private suspend fun refreshRepositoryInfo() {
tabState.refreshData(RefreshType.ALL_DATA)
}
fun credentialsDenied() {
credentialsStateManager.updateState(CredentialsState.CredentialsDenied)
@ -413,8 +409,8 @@ class TabViewModel @Inject constructor(
historyViewModel = null
}
fun refreshAll() {
printLog(TAG, "Manual refresh triggered")
fun refreshAll() = tabScope.launch {
printLog(TAG, "Manual refresh triggered. IS OPERATION RUNNING ${tabState.operationRunning}")
if (!tabState.operationRunning) {
refreshRepositoryInfo()
}

View File

@ -30,9 +30,7 @@ class TagsViewModel @Inject constructor(
tabScope.launch {
tabState.refreshFlowFiltered(RefreshType.ALL_DATA, RefreshType.STASHES)
.collect {
tabState.coRunOperation(refreshType = RefreshType.NONE) { git ->
refresh(git)
}
refresh(tabState.git)
}
}
}