0
0
mirror of https://github.com/ankidroid/Anki-Android.git synced 2024-09-19 19:42:17 +02:00

Notify the UI that a sync was done

In this case, I really don't think it's realistic to expect an
OpChange from the backend. The backend already sends informations that
are relevant for the sync process. Given that "sync" does not uses the
processes uses for undoable change (indeed, it should not be
undoable), no OpChange is generated.

It seems reasonable in this place at least to directly notify the
observers.

Given that the observers expect an OpChanges, I create one, and simply
assume everything may be changed. This seems reasonable in case of
sync, and it's sufficiently rare that the cost won't be prohibitive
anyway.

Fixed: #16943
Fixed: #16942
This commit is contained in:
Arthur Milchior 2024-08-26 04:08:30 +02:00 committed by lukstbit
parent fa53c16fc2
commit 25d7246251
3 changed files with 89 additions and 0 deletions

View File

@ -33,6 +33,7 @@ import com.ichi2.anki.dialogs.SyncErrorDialog
import com.ichi2.anki.preferences.sharedPrefs
import com.ichi2.anki.snackbar.showSnackbar
import com.ichi2.anki.worker.SyncMediaWorker
import com.ichi2.libanki.ChangeManager.notifySubscribersAllValuesChanged
import com.ichi2.libanki.createBackup
import com.ichi2.libanki.fullUploadOrDownload
import com.ichi2.libanki.syncCollection
@ -161,6 +162,7 @@ fun DeckPicker.handleNewSync(
throw exc
}
withCol { notetypes.clearCache() }
notifySubscribersAllValuesChanged(deckPicker)
setLastSyncTimeToNow()
refreshState()
}

View File

@ -33,6 +33,7 @@ import anki.collection.OpChangesAfterUndo
import anki.collection.OpChangesOnly
import anki.collection.OpChangesWithCount
import anki.collection.OpChangesWithId
import anki.collection.opChanges
import anki.import_export.ImportResponse
import com.ichi2.anki.CollectionManager.withCol
import com.ichi2.anki.CrashReportService
@ -103,6 +104,29 @@ object ChangeManager {
}
notifySubscribers(opChanges, initiator)
}
fun notifySubscribersAllValuesChanged(handler: Any? = null) {
notifySubscribers(ALL, handler)
}
/**
* An OpChanges that ensures that all data should be considered as potentially changed.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal val ALL = opChanges {
card = true
note = true
deck = true
tag = true
notetype = true
config = true
deckConfig = true
mtime = true
browserTable = true
browserSidebar = true
noteText = true
studyQueues = true
}
}
/** Wrap a routine that returns OpChanges* or similar undo info with this

View File

@ -0,0 +1,63 @@
/*
Copyright (c) 2024 David Allison <davidallisongithub@gmail.com>
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.ichi2.libanki
import anki.collection.OpChanges
import com.ichi2.testutils.JvmTest
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.greaterThan
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import kotlin.collections.Collection
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties
import kotlin.reflect.javaType
import kotlin.reflect.jvm.isAccessible
@RunWith(Parameterized::class)
class ChangeManagerTest : JvmTest() {
@JvmField // required for Parameter
@Parameterized.Parameter
var property: KProperty1<OpChanges, *>? = null
@JvmField // required for Parameter
@Parameterized.Parameter(1)
var name: String? = null
@Test
fun `Property is set in ALL object`() {
assertThat(name, property!!.call(ChangeManager.ALL), equalTo(true))
}
companion object {
@Parameterized.Parameters(name = "{1}")
@OptIn(ExperimentalStdlibApi::class)
@JvmStatic // required for initParameters
fun initParameters(): Collection<Array<out Any>> {
val props =
OpChanges::class.memberProperties.filter { it.returnType.javaType == Boolean::class.java }
assertThat(props.size, greaterThan(0))
props.forEach { it.isAccessible = true }
return props.map {
arrayOf(it, it.name)
}
}
}
}