@@ -130,13 +130,14 @@ import com.ichi2.anki.dialogs.EmptyCardsDialogFragment
130130import com.ichi2.anki.dialogs.ImportDialog.ImportDialogListener
131131import com.ichi2.anki.dialogs.ImportFileSelectionFragment.ApkgImportResultLauncherProvider
132132import com.ichi2.anki.dialogs.ImportFileSelectionFragment.CsvImportResultLauncherProvider
133- import com.ichi2.anki.dialogs.MediaCheckDialog
134- import com.ichi2.anki.dialogs.MediaCheckDialog.MediaCheckDialogListener
135133import com.ichi2.anki.dialogs.SyncErrorDialog
136134import com.ichi2.anki.dialogs.SyncErrorDialog.Companion.newInstance
137135import com.ichi2.anki.dialogs.SyncErrorDialog.SyncErrorDialogListener
138136import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog
139137import com.ichi2.anki.dialogs.customstudy.CustomStudyDialog.CustomStudyAction
138+ import com.ichi2.anki.dialogs.mediacheck.ConfirmMediaCheckDialog
139+ import com.ichi2.anki.dialogs.mediacheck.MediaCheckResultDialog
140+ import com.ichi2.anki.dialogs.viewmodel.MediaCheckViewModel
140141import com.ichi2.anki.export.ActivityExportingDelegate
141142import com.ichi2.anki.export.ExportDialogFragment
142143import com.ichi2.anki.export.ExportDialogsFactory
@@ -153,7 +154,6 @@ import com.ichi2.anki.preferences.PreferencesActivity
153154import com.ichi2.anki.preferences.sharedPrefs
154155import com.ichi2.anki.receiver.SdCardReceiver
155156import com.ichi2.anki.servicelayer.ScopedStorageService
156- import com.ichi2.anki.servicelayer.checkMedia
157157import com.ichi2.anki.settings.Prefs
158158import com.ichi2.anki.snackbar.BaseSnackbarBuilderProvider
159159import com.ichi2.anki.snackbar.SnackbarBuilder
@@ -171,7 +171,6 @@ import com.ichi2.compat.CompatHelper.Companion.sdkVersion
171171import com.ichi2.libanki.ChangeManager
172172import com.ichi2.libanki.DeckId
173173import com.ichi2.libanki.Decks
174- import com.ichi2.libanki.MediaCheckResult
175174import com.ichi2.libanki.exception.ConfirmModSchemaException
176175import com.ichi2.libanki.sched.DeckNode
177176import com.ichi2.libanki.utils.TimeManager
@@ -244,7 +243,6 @@ open class DeckPicker :
244243 StudyOptionsListener ,
245244 SyncErrorDialogListener ,
246245 ImportDialogListener ,
247- MediaCheckDialogListener ,
248246 OnRequestPermissionsResultCallback ,
249247 ChangeManager .Subscriber ,
250248 SyncCompletionListener ,
@@ -256,6 +254,8 @@ open class DeckPicker :
256254 ExportDialogsFactoryProvider {
257255 val viewModel: DeckPickerViewModel by viewModels()
258256
257+ private val mediaCheckViewModel: MediaCheckViewModel by viewModels()
258+
259259 // Short animation duration from system
260260 private var shortAnimDuration = 0
261261 private lateinit var deckPickerContent: RelativeLayout
@@ -636,6 +636,8 @@ open class DeckPicker :
636636 }
637637 }
638638
639+ observeMediaCheck()
640+
639641 pullToSyncWrapper.configureView(
640642 this ,
641643 IMPORT_MIME_TYPES ,
@@ -1181,7 +1183,7 @@ open class DeckPicker :
11811183 }
11821184 R .id.action_check_media -> {
11831185 Timber .i(" DeckPicker:: Check media button pressed" )
1184- showMediaCheckDialog( MediaCheckDialog . Type . DIALOG_CONFIRM_MEDIA_CHECK )
1186+ ConfirmMediaCheckDialog ().show(supportFragmentManager, " ConfirmMediaCheckDialog " )
11851187 return true
11861188 }
11871189 R .id.action_empty_cards -> {
@@ -1495,7 +1497,7 @@ open class DeckPicker :
14951497 }
14961498 KeyEvent .KEYCODE_M -> {
14971499 Timber .i(" Check media from keypress" )
1498- showMediaCheckDialog( MediaCheckDialog . Type . DIALOG_CONFIRM_MEDIA_CHECK )
1500+ ConfirmMediaCheckDialog ().show(supportFragmentManager, " ConfirmMediaCheckDialog " )
14991501 return true
15001502 }
15011503 KeyEvent .KEYCODE_E -> {
@@ -1812,17 +1814,6 @@ open class DeckPicker :
18121814 }
18131815 }
18141816
1815- override fun showMediaCheckDialog (dialogType : MediaCheckDialog .Type ) {
1816- showAsyncDialogFragment(MediaCheckDialog .newInstance(dialogType))
1817- }
1818-
1819- override fun showMediaCheckDialog (
1820- dialogType : MediaCheckDialog .Type ,
1821- checkList : MediaCheckResult ,
1822- ) {
1823- showAsyncDialogFragment(MediaCheckDialog .newInstance(dialogType, checkList))
1824- }
1825-
18261817 /* *
18271818 * Show a specific sync error dialog
18281819 * @param dialogType id of dialog to show
@@ -1895,21 +1886,58 @@ open class DeckPicker :
18951886 handleDatabaseCheck()
18961887 }
18971888
1898- /* *
1899- * Schedules a background job to find missing, unused and invalid media files.
1900- * Shows a progress dialog while operation is running.
1901- * When check is finished a dialog box shows number of missing, unused and invalid media files.
1902- *
1903- * If has the storage permission, job is scheduled, otherwise storage permission is asked first.
1904- */
1905- override fun mediaCheck () {
1906- launchCatchingTask {
1907- val mediaCheckResult = checkMedia()
1908- showMediaCheckDialog(MediaCheckDialog .Type .DIALOG_MEDIA_CHECK_RESULTS , mediaCheckResult)
1889+ private fun observeMediaCheck () {
1890+ lifecycleScope.launch {
1891+ launch {
1892+ mediaCheckViewModel.startMediaCheck.collectLatest { shouldCheck ->
1893+ Timber .d(" Starting media check" )
1894+ if (shouldCheck) {
1895+ launchCatchingTask {
1896+ /* *
1897+ * Schedules a background job to find missing, unused and invalid media files.
1898+ * Shows a progress dialog while operation is running.
1899+ * When check is finished a dialog box shows number of missing, unused and invalid media files.
1900+ *
1901+ * If has the storage permission, job is scheduled, otherwise storage permission is asked first.
1902+ */
1903+ val mediaCheckResult =
1904+ withProgress(R .string.check_media_message) {
1905+ withCol { media.check() }
1906+ }
1907+ mediaCheckViewModel.updateMediaCheckResult(mediaCheckResult)
1908+
1909+ MediaCheckResultDialog ().show(
1910+ supportFragmentManager,
1911+ " MediaCheckResultDialog" ,
1912+ )
1913+ }
1914+ }
1915+ }
1916+ }
1917+
1918+ launch {
1919+ mediaCheckViewModel.deleteUnused.collectLatest { unused ->
1920+ Timber .d(" Deleting unused media" )
1921+ if (unused != null ) {
1922+ deleteUnused(unused)
1923+ }
1924+ }
1925+ }
1926+
1927+ launch {
1928+ mediaCheckViewModel.tagMissing.collectLatest { missingMediaNotes ->
1929+ Timber .d(" DeckPicker:: Adding missing media tag" )
1930+ tagMissing(missingMediaNotes)
1931+ }
1932+ }
19091933 }
19101934 }
19111935
1912- override fun deleteUnused (unused : List <String >) {
1936+ override fun mediaCheck () {
1937+ ConfirmMediaCheckDialog ().show(supportFragmentManager, " ConfirmMediaCheckDialog" )
1938+ }
1939+
1940+ private fun deleteUnused (unused : List <String >) {
19131941 launchCatchingTask {
19141942 // Number of deleted files
19151943 val noOfDeletedFiles =
@@ -1923,13 +1951,13 @@ open class DeckPicker :
19231951 }
19241952 }
19251953
1926- override fun tagMissing (missingMediaNotes : List <Long >? ) {
1954+ private fun tagMissing (missingMediaNotes : List <Long >? ) {
19271955 if (missingMediaNotes == null ) return
19281956
19291957 Timber .d(" DeckPicker:: Adding missing media tag" )
19301958 launchCatchingTask {
1931- withCol {
1932- tags.bulkAdd (missingMediaNotes, TR .mediaCheckMissingMediaTag())
1959+ withProgress(getString( R .string.adding_missing_tag)) {
1960+ mediaCheckViewModel.tagMissing (missingMediaNotes, TR .mediaCheckMissingMediaTag()).join( )
19331961 }
19341962 }
19351963 }
0 commit comments