support for downloads in history
This commit is contained in:
+6
-2
@@ -45,6 +45,11 @@ object GlobalComponents {
|
|||||||
.whenSessionsChange()
|
.whenSessionsChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DelicateCoroutinesApi
|
||||||
|
private fun restoreDownloads(newComponents: Components) = GlobalScope.launch(Dispatchers.Main) {
|
||||||
|
newComponents.useCases.downloadsUseCases.restoreDownloads()
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
fun setUp(
|
fun setUp(
|
||||||
applicationContext: Context,
|
applicationContext: Context,
|
||||||
@@ -82,8 +87,7 @@ object GlobalComponents {
|
|||||||
newComponents.core.engine.warmUp()
|
newComponents.core.engine.warmUp()
|
||||||
|
|
||||||
restoreBrowserState(newComponents)
|
restoreBrowserState(newComponents)
|
||||||
|
restoreDownloads(newComponents)
|
||||||
//newComponents.useCases.downloadsUseCases.restoreDownloads()
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GlobalPlacesDependencyProvider.initialize(newComponents.core.historyStorage)
|
GlobalPlacesDependencyProvider.initialize(newComponents.core.historyStorage)
|
||||||
|
|||||||
+49
-5
@@ -1,7 +1,6 @@
|
|||||||
package eu.weblibre.flutter_mozilla_components.api
|
package eu.weblibre.flutter_mozilla_components.api
|
||||||
|
|
||||||
import eu.weblibre.flutter_mozilla_components.GlobalComponents
|
import eu.weblibre.flutter_mozilla_components.GlobalComponents
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.AutocompleteResult
|
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHistoryApi
|
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHistoryApi
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.VisitInfo
|
import eu.weblibre.flutter_mozilla_components.pigeons.VisitInfo
|
||||||
import eu.weblibre.flutter_mozilla_components.pigeons.VisitType
|
import eu.weblibre.flutter_mozilla_components.pigeons.VisitType
|
||||||
@@ -10,6 +9,8 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import mozilla.components.browser.state.state.content.DownloadState
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -20,6 +21,32 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
requireNotNull(GlobalComponents.components) { "Components not initialized" }
|
requireNotNull(GlobalComponents.components) { "Components not initialized" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Map<String, DownloadState>.toVisitInfoList(
|
||||||
|
startMillis: Long,
|
||||||
|
endMillis: Long,
|
||||||
|
): List<VisitInfo> =
|
||||||
|
values
|
||||||
|
.filter { isDisplayableItem(it.status) &&
|
||||||
|
it.createdTime >= startMillis && it.createdTime <= endMillis
|
||||||
|
}
|
||||||
|
.distinctBy { Pair(it.fileName, it.status) }
|
||||||
|
.sortedByDescending { it.createdTime } // sort from newest to oldest
|
||||||
|
.map { it.toVisitInfo() }
|
||||||
|
|
||||||
|
private fun isDisplayableItem(status: DownloadState.Status) =
|
||||||
|
status != DownloadState.Status.CANCELLED
|
||||||
|
|
||||||
|
private fun DownloadState.toVisitInfo() =
|
||||||
|
VisitInfo(
|
||||||
|
url = url,
|
||||||
|
visitType = VisitType.DOWNLOAD,
|
||||||
|
visitTime = createdTime,
|
||||||
|
title = filePath,
|
||||||
|
previewImageUrl = contentType,
|
||||||
|
isRemote = false,
|
||||||
|
contentId = id
|
||||||
|
)
|
||||||
|
|
||||||
override fun getDetailedVisits(
|
override fun getDetailedVisits(
|
||||||
startMillis: Long,
|
startMillis: Long,
|
||||||
endMillis: Long,
|
endMillis: Long,
|
||||||
@@ -28,7 +55,7 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
) {
|
) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val visits = components.core.historyStorage.getDetailedVisits(
|
var visits = components.core.historyStorage.getDetailedVisits(
|
||||||
startMillis,
|
startMillis,
|
||||||
endMillis,
|
endMillis,
|
||||||
excludeTypes.map {
|
excludeTypes.map {
|
||||||
@@ -43,9 +70,7 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
VisitType.FRAMED_LINK -> mozilla.components.concept.storage.VisitType.FRAMED_LINK
|
VisitType.FRAMED_LINK -> mozilla.components.concept.storage.VisitType.FRAMED_LINK
|
||||||
VisitType.RELOAD -> mozilla.components.concept.storage.VisitType.RELOAD
|
VisitType.RELOAD -> mozilla.components.concept.storage.VisitType.RELOAD
|
||||||
}
|
}
|
||||||
})
|
}).map {
|
||||||
|
|
||||||
callback(Result.success(visits.map {
|
|
||||||
VisitInfo(
|
VisitInfo(
|
||||||
url = it.url,
|
url = it.url,
|
||||||
title = it.title,
|
title = it.title,
|
||||||
@@ -65,6 +90,12 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
isRemote = it.isRemote
|
isRemote = it.isRemote
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!excludeTypes.contains(VisitType.DOWNLOAD)) {
|
||||||
|
visits = visits + components.core.store.state.downloads.toVisitInfoList(startMillis, endMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(Result.success(visits
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,6 +115,19 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun deleteDownload(
|
||||||
|
id: String,
|
||||||
|
callback: (Result<Unit>) -> Unit
|
||||||
|
) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
components.useCases.downloadsUseCases.removeDownload(id)
|
||||||
|
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun deleteVisitsBetween(
|
override fun deleteVisitsBetween(
|
||||||
startMillis: Long,
|
startMillis: Long,
|
||||||
endMillis: Long,
|
endMillis: Long,
|
||||||
|
|||||||
+25
-2
@@ -1146,7 +1146,8 @@ data class VisitInfo (
|
|||||||
val visitTime: Long,
|
val visitTime: Long,
|
||||||
val visitType: VisitType,
|
val visitType: VisitType,
|
||||||
val previewImageUrl: String? = null,
|
val previewImageUrl: String? = null,
|
||||||
val isRemote: Boolean
|
val isRemote: Boolean,
|
||||||
|
val contentId: String? = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
companion object {
|
companion object {
|
||||||
@@ -1157,7 +1158,8 @@ data class VisitInfo (
|
|||||||
val visitType = pigeonVar_list[3] as VisitType
|
val visitType = pigeonVar_list[3] as VisitType
|
||||||
val previewImageUrl = pigeonVar_list[4] as String?
|
val previewImageUrl = pigeonVar_list[4] as String?
|
||||||
val isRemote = pigeonVar_list[5] as Boolean
|
val isRemote = pigeonVar_list[5] as Boolean
|
||||||
return VisitInfo(url, title, visitTime, visitType, previewImageUrl, isRemote)
|
val contentId = pigeonVar_list[6] as String?
|
||||||
|
return VisitInfo(url, title, visitTime, visitType, previewImageUrl, isRemote, contentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun toList(): List<Any?> {
|
fun toList(): List<Any?> {
|
||||||
@@ -1168,6 +1170,7 @@ data class VisitInfo (
|
|||||||
visitType,
|
visitType,
|
||||||
previewImageUrl,
|
previewImageUrl,
|
||||||
isRemote,
|
isRemote,
|
||||||
|
contentId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@@ -4767,6 +4770,7 @@ interface GeckoDeleteBrowsingDataController {
|
|||||||
interface GeckoHistoryApi {
|
interface GeckoHistoryApi {
|
||||||
fun getDetailedVisits(startMillis: Long, endMillis: Long, excludeTypes: List<VisitType>, callback: (Result<List<VisitInfo>>) -> Unit)
|
fun getDetailedVisits(startMillis: Long, endMillis: Long, excludeTypes: List<VisitType>, callback: (Result<List<VisitInfo>>) -> Unit)
|
||||||
fun deleteVisit(url: String, timestamp: Long, callback: (Result<Unit>) -> Unit)
|
fun deleteVisit(url: String, timestamp: Long, callback: (Result<Unit>) -> Unit)
|
||||||
|
fun deleteDownload(id: String, callback: (Result<Unit>) -> Unit)
|
||||||
fun deleteVisitsBetween(startMillis: Long, endMillis: Long, callback: (Result<Unit>) -> Unit)
|
fun deleteVisitsBetween(startMillis: Long, endMillis: Long, callback: (Result<Unit>) -> Unit)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -4820,6 +4824,25 @@ interface GeckoHistoryApi {
|
|||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteDownload$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val idArg = args[0] as String
|
||||||
|
api.deleteDownload(idArg) { result: Result<Unit> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(GeckoPigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
reply.reply(GeckoPigeonUtils.wrapResult(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
run {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisitsBetween$separatedMessageChannelSuffix", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisitsBetween$separatedMessageChannelSuffix", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
|
|||||||
@@ -26,7 +26,20 @@ class GeckoHistoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteVisit(VisitInfo info) {
|
Future<void> deleteVisit(VisitInfo info) {
|
||||||
return _api.deleteVisit(info.url, info.visitTime);
|
switch (info.visitType) {
|
||||||
|
case VisitType.link:
|
||||||
|
case VisitType.typed:
|
||||||
|
case VisitType.embed:
|
||||||
|
case VisitType.redirectPermanent:
|
||||||
|
case VisitType.redirectTemporary:
|
||||||
|
case VisitType.framedLink:
|
||||||
|
case VisitType.reload:
|
||||||
|
return _api.deleteVisit(info.url, info.visitTime);
|
||||||
|
case VisitType.download:
|
||||||
|
return _api.deleteDownload(info.contentId!);
|
||||||
|
case VisitType.bookmark:
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteVisitsBetween(DateTime start, DateTime end) {
|
Future<void> deleteVisitsBetween(DateTime start, DateTime end) {
|
||||||
|
|||||||
@@ -1257,6 +1257,7 @@ class VisitInfo {
|
|||||||
required this.visitType,
|
required this.visitType,
|
||||||
this.previewImageUrl,
|
this.previewImageUrl,
|
||||||
required this.isRemote,
|
required this.isRemote,
|
||||||
|
this.contentId,
|
||||||
});
|
});
|
||||||
|
|
||||||
String url;
|
String url;
|
||||||
@@ -1271,6 +1272,8 @@ class VisitInfo {
|
|||||||
|
|
||||||
bool isRemote;
|
bool isRemote;
|
||||||
|
|
||||||
|
String? contentId;
|
||||||
|
|
||||||
List<Object?> _toList() {
|
List<Object?> _toList() {
|
||||||
return <Object?>[
|
return <Object?>[
|
||||||
url,
|
url,
|
||||||
@@ -1279,6 +1282,7 @@ class VisitInfo {
|
|||||||
visitType,
|
visitType,
|
||||||
previewImageUrl,
|
previewImageUrl,
|
||||||
isRemote,
|
isRemote,
|
||||||
|
contentId,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1294,6 +1298,7 @@ class VisitInfo {
|
|||||||
visitType: result[3]! as VisitType,
|
visitType: result[3]! as VisitType,
|
||||||
previewImageUrl: result[4] as String?,
|
previewImageUrl: result[4] as String?,
|
||||||
isRemote: result[5]! as bool,
|
isRemote: result[5]! as bool,
|
||||||
|
contentId: result[6] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5783,6 +5788,29 @@ class GeckoHistoryApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteDownload(String id) async {
|
||||||
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteDownload$pigeonVar_messageChannelSuffix';
|
||||||
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[id]);
|
||||||
|
final List<Object?>? pigeonVar_replyList =
|
||||||
|
await pigeonVar_sendFuture as List<Object?>?;
|
||||||
|
if (pigeonVar_replyList == null) {
|
||||||
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
} else if (pigeonVar_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: pigeonVar_replyList[0]! as String,
|
||||||
|
message: pigeonVar_replyList[1] as String?,
|
||||||
|
details: pigeonVar_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> deleteVisitsBetween(int startMillis, int endMillis) async {
|
Future<void> deleteVisitsBetween(int startMillis, int endMillis) async {
|
||||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisitsBetween$pigeonVar_messageChannelSuffix';
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisitsBetween$pigeonVar_messageChannelSuffix';
|
||||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
|||||||
@@ -425,6 +425,8 @@ class VisitInfo {
|
|||||||
final String? previewImageUrl;
|
final String? previewImageUrl;
|
||||||
final bool isRemote;
|
final bool isRemote;
|
||||||
|
|
||||||
|
final String? contentId;
|
||||||
|
|
||||||
VisitInfo(
|
VisitInfo(
|
||||||
this.url,
|
this.url,
|
||||||
this.title,
|
this.title,
|
||||||
@@ -432,6 +434,7 @@ class VisitInfo {
|
|||||||
this.visitType,
|
this.visitType,
|
||||||
this.previewImageUrl,
|
this.previewImageUrl,
|
||||||
this.isRemote,
|
this.isRemote,
|
||||||
|
this.contentId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1253,6 +1256,9 @@ abstract class GeckoHistoryApi {
|
|||||||
@async
|
@async
|
||||||
void deleteVisit(String url, int timestamp);
|
void deleteVisit(String url, int timestamp);
|
||||||
|
|
||||||
|
@async
|
||||||
|
void deleteDownload(String id);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
void deleteVisitsBetween(int startMillis, int endMillis);
|
void deleteVisitsBetween(int startMillis, int endMillis);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user