@@ -43,6 +43,7 @@ class DownloadPostsRepositoryImpl(
4343
4444 private val _reservingPosts = MutableStateFlow (emptyList<FanboxDownloadItems >())
4545 private val _downloadState = MutableStateFlow <DownloadState >(DownloadState .None )
46+ private val _downloadedItems = MutableStateFlow (emptyList<DownloadedItems >())
4647
4748 override val reservingPosts: StateFlow <List <FanboxDownloadItems >> = _reservingPosts .asStateFlow()
4849 override val downloadState: StateFlow <DownloadState > = _downloadState .asStateFlow()
@@ -53,7 +54,6 @@ class DownloadPostsRepositoryImpl(
5354 delay(500 )
5455
5556 val downloadItems = _reservingPosts .getAndUpdate { it.drop(1 ) }.firstOrNull()
56-
5757 if (downloadItems == null ) {
5858 _downloadState .value = DownloadState .None
5959 continue
@@ -74,39 +74,20 @@ class DownloadPostsRepositoryImpl(
7474 }
7575 }
7676
77- val results = items.awaitAll()
78- val pathAndMime = mutableListOf<Pair <String , String >>()
79-
80- for ((item, tmpFile) in results.filterNotNull()) {
81- runCatching {
82- val mime = MimeTypeMap .getSingleton().getMimeTypeFromExtension(item.extension)
83- val parent = getParentFile(downloadItems.requestType) ? : getOldParentFile(downloadItems.requestType)
84- val file = parent.createFile(" ${item.name} .${item.extension} " )
85-
86- context.contentResolver.openOutputStream(file!! .uri)!! .use {
87- tmpFile.inputStream().use { input ->
88- input.copyTo(it)
89- }
90- }
91-
92- tmpFile.delete()
93- pathAndMime.add(file.uri.path.orEmpty() to mime.orEmpty())
94-
95- delay(100 )
96- }.onFailure {
97- Napier .e(it) { " Failed to download item: ${item.name} " }
98- }
99- }
77+ _downloadedItems .update { it + DownloadedItems (downloadItems, items.awaitAll()) }
78+ downloadItems.callback.invoke()
79+ }
80+ }
10081
101- MediaScannerConnection .scanFile(
102- context,
103- pathAndMime.map { it.first }.toTypedArray(),
104- pathAndMime.map { it.second }.toTypedArray(),
105- ) { _, uri ->
106- Napier .d { " MediaScannerConnection: $uri " }
82+ scope.launch {
83+ while (isActive) {
84+ val downloadedItems = _downloadedItems .getAndUpdate { it.drop( 1 ) }.firstOrNull()
85+ if (downloadedItems == null ) {
86+ delay( 1000 )
87+ continue
10788 }
10889
109- downloadItems.callback.invoke( )
90+ saveFiles(downloadedItems. downloadItems, downloadedItems.results )
11091 }
11192 }
11293 }
@@ -258,4 +239,46 @@ class DownloadPostsRepositoryImpl(
258239 }
259240 }
260241 }
242+
243+ private suspend fun saveFiles (downloadItems : FanboxDownloadItems , results : List <Pair <FanboxDownloadItems .Item , File >? >) {
244+ val pathAndMime = mutableListOf<Pair <String , String >>()
245+
246+ for ((item, tmpFile) in results.filterNotNull()) {
247+ runCatching {
248+ val mime = MimeTypeMap .getSingleton().getMimeTypeFromExtension(item.extension)
249+ val parent = getParentFile(downloadItems.requestType) ? : getOldParentFile(downloadItems.requestType)
250+ val file = parent.createFile(" ${item.name} .${item.extension} " )
251+ val modifiedTime = System .currentTimeMillis()
252+
253+ tmpFile.setLastModified(modifiedTime)
254+ file.filePath?.let { File (it).setLastModified(modifiedTime) }
255+
256+ context.contentResolver.openOutputStream(file!! .uri)!! .use {
257+ tmpFile.inputStream().use { input ->
258+ input.copyTo(it)
259+ }
260+ }
261+
262+ tmpFile.delete()
263+ pathAndMime.add(file.uri.path.orEmpty() to mime.orEmpty())
264+
265+ delay(1000 )
266+ }.onFailure {
267+ Napier .e(it) { " Failed to download item: ${item.name} " }
268+ }
269+ }
270+
271+ MediaScannerConnection .scanFile(
272+ context,
273+ pathAndMime.map { it.first }.toTypedArray(),
274+ pathAndMime.map { it.second }.toTypedArray(),
275+ ) { _, uri ->
276+ Napier .d { " MediaScannerConnection: $uri " }
277+ }
278+ }
279+
280+ private data class DownloadedItems (
281+ val downloadItems : FanboxDownloadItems ,
282+ val results : List <Pair <FanboxDownloadItems .Item , File >? >,
283+ )
261284}
0 commit comments