add getVisitsPaginated; disable onScrollChange
This commit is contained in:
+70
-5
@@ -26,8 +26,9 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
endMillis: Long,
|
endMillis: Long,
|
||||||
): List<VisitInfo> =
|
): List<VisitInfo> =
|
||||||
values
|
values
|
||||||
.filter { isDisplayableItem(it.status) &&
|
.filter {
|
||||||
it.createdTime >= startMillis && it.createdTime <= endMillis
|
isDisplayableItem(it.status) &&
|
||||||
|
it.createdTime >= startMillis && it.createdTime <= endMillis
|
||||||
}
|
}
|
||||||
.distinctBy { Pair(it.fileName, it.status) }
|
.distinctBy { Pair(it.fileName, it.status) }
|
||||||
.sortedByDescending { it.createdTime } // sort from newest to oldest
|
.sortedByDescending { it.createdTime } // sort from newest to oldest
|
||||||
@@ -92,11 +93,75 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!excludeTypes.contains(VisitType.DOWNLOAD)) {
|
if (!excludeTypes.contains(VisitType.DOWNLOAD)) {
|
||||||
visits = visits + components.core.store.state.downloads.toVisitInfoList(startMillis, endMillis)
|
visits = visits + components.core.store.state.downloads.toVisitInfoList(
|
||||||
|
startMillis,
|
||||||
|
endMillis
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(Result.success(visits
|
callback(
|
||||||
))
|
Result.success(
|
||||||
|
visits
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getVisitsPaginated(
|
||||||
|
offset: Long,
|
||||||
|
count: Long,
|
||||||
|
excludeTypes: List<VisitType>,
|
||||||
|
callback: (Result<List<VisitInfo>>) -> Unit
|
||||||
|
) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
var visits = components.core.historyStorage.getVisitsPaginated(
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
excludeTypes.map {
|
||||||
|
when (it) {
|
||||||
|
VisitType.LINK -> mozilla.components.concept.storage.VisitType.LINK
|
||||||
|
VisitType.TYPED -> mozilla.components.concept.storage.VisitType.TYPED
|
||||||
|
VisitType.BOOKMARK -> mozilla.components.concept.storage.VisitType.BOOKMARK
|
||||||
|
VisitType.EMBED -> mozilla.components.concept.storage.VisitType.EMBED
|
||||||
|
VisitType.REDIRECT_PERMANENT -> mozilla.components.concept.storage.VisitType.REDIRECT_PERMANENT
|
||||||
|
VisitType.REDIRECT_TEMPORARY -> mozilla.components.concept.storage.VisitType.REDIRECT_TEMPORARY
|
||||||
|
VisitType.DOWNLOAD -> mozilla.components.concept.storage.VisitType.DOWNLOAD
|
||||||
|
VisitType.FRAMED_LINK -> mozilla.components.concept.storage.VisitType.FRAMED_LINK
|
||||||
|
VisitType.RELOAD -> mozilla.components.concept.storage.VisitType.RELOAD
|
||||||
|
}
|
||||||
|
}).map {
|
||||||
|
VisitInfo(
|
||||||
|
url = it.url,
|
||||||
|
title = it.title,
|
||||||
|
visitTime = it.visitTime,
|
||||||
|
visitType = when (it.visitType) {
|
||||||
|
mozilla.components.concept.storage.VisitType.LINK -> VisitType.LINK
|
||||||
|
mozilla.components.concept.storage.VisitType.TYPED -> VisitType.TYPED
|
||||||
|
mozilla.components.concept.storage.VisitType.BOOKMARK -> VisitType.BOOKMARK
|
||||||
|
mozilla.components.concept.storage.VisitType.EMBED -> VisitType.EMBED
|
||||||
|
mozilla.components.concept.storage.VisitType.REDIRECT_PERMANENT -> VisitType.REDIRECT_PERMANENT
|
||||||
|
mozilla.components.concept.storage.VisitType.REDIRECT_TEMPORARY -> VisitType.REDIRECT_TEMPORARY
|
||||||
|
mozilla.components.concept.storage.VisitType.DOWNLOAD -> VisitType.DOWNLOAD
|
||||||
|
mozilla.components.concept.storage.VisitType.FRAMED_LINK -> VisitType.FRAMED_LINK
|
||||||
|
mozilla.components.concept.storage.VisitType.RELOAD -> VisitType.RELOAD
|
||||||
|
},
|
||||||
|
previewImageUrl = it.previewImageUrl,
|
||||||
|
isRemote = it.isRemote
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!excludeTypes.contains(VisitType.DOWNLOAD)) {
|
||||||
|
callback(Result.failure(Throwable("Downloads not supported yet")))
|
||||||
|
// visits = visits + components.core.store.state.downloads.toVisitInfoList(startMillis, endMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(
|
||||||
|
Result.success(
|
||||||
|
visits
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -133,15 +133,15 @@ class FlutterEventMiddleware(private val flutterEvents: GeckoStateEvents) : Midd
|
|||||||
) { _ -> }
|
) { _ -> }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ReaderAction.UpdateReaderScrollYAction -> {
|
// is ReaderAction.UpdateReaderScrollYAction -> {
|
||||||
runOnUiThread {
|
// runOnUiThread {
|
||||||
flutterEvents.onScrollChange(
|
// flutterEvents.onScrollChange(
|
||||||
System.currentTimeMillis(),
|
// System.currentTimeMillis(),
|
||||||
action.tabId,
|
// action.tabId,
|
||||||
action.scrollY.toLong()
|
// action.scrollY.toLong()
|
||||||
) { _ -> }
|
// ) { _ -> }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else -> {
|
else -> {
|
||||||
//logger.debug("Event fired: " + action.javaClass.name)
|
//logger.debug("Event fired: " + action.javaClass.name)
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-17
@@ -4911,23 +4911,6 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun onScrollChange(timestampArg: Long, tabIdArg: String, scrollYArg: Long, callback: (Result<Unit>) -> Unit)
|
|
||||||
{
|
|
||||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
|
||||||
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange$separatedMessageChannelSuffix"
|
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
|
||||||
channel.send(listOf(timestampArg, tabIdArg, scrollYArg)) {
|
|
||||||
if (it is List<*>) {
|
|
||||||
if (it.size > 1) {
|
|
||||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
|
||||||
} else {
|
|
||||||
callback(Result.success(Unit))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(Result.failure(GeckoPigeonUtils.createConnectionError(channelName)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun onPreferenceChange(timestampArg: Long, valueArg: GeckoPref, callback: (Result<Unit>) -> Unit)
|
fun onPreferenceChange(timestampArg: Long, valueArg: GeckoPref, callback: (Result<Unit>) -> Unit)
|
||||||
{
|
{
|
||||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
@@ -5492,6 +5475,7 @@ interface GeckoDeleteBrowsingDataController {
|
|||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
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 getVisitsPaginated(offset: Long, count: 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 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)
|
||||||
@@ -5527,6 +5511,28 @@ interface GeckoHistoryApi {
|
|||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.getVisitsPaginated$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val offsetArg = args[0] as Long
|
||||||
|
val countArg = args[1] as Long
|
||||||
|
val excludeTypesArg = args[2] as List<VisitType>
|
||||||
|
api.getVisitsPaginated(offsetArg, countArg, excludeTypesArg) { result: Result<List<VisitInfo>> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(GeckoPigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
val data = result.getOrNull()
|
||||||
|
reply.reply(GeckoPigeonUtils.wrapResult(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
run {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisit$separatedMessageChannelSuffix", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisit$separatedMessageChannelSuffix", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
final _thumbnailSubject = PublishSubject<ThumbnailEvent>();
|
final _thumbnailSubject = PublishSubject<ThumbnailEvent>();
|
||||||
final _findResultsSubject = PublishSubject<FindResultsEvent>();
|
final _findResultsSubject = PublishSubject<FindResultsEvent>();
|
||||||
final _longPressSubject = PublishSubject<LongPressEvent>();
|
final _longPressSubject = PublishSubject<LongPressEvent>();
|
||||||
final _scrollEventSubject = PublishSubject<ScrollEvent>();
|
// final _scrollEventSubject = PublishSubject<ScrollEvent>();
|
||||||
final _prefUpdateSubject = PublishSubject<GeckoPref>();
|
final _prefUpdateSubject = PublishSubject<GeckoPref>();
|
||||||
final _siteAssignementSubject = PublishSubject<ContainerSiteAssignment>();
|
final _siteAssignementSubject = PublishSubject<ContainerSiteAssignment>();
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
||||||
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
||||||
Stream<LongPressEvent> get longPressEvent => _longPressSubject.stream;
|
Stream<LongPressEvent> get longPressEvent => _longPressSubject.stream;
|
||||||
Stream<ScrollEvent> get scrollEvent => _scrollEventSubject.stream;
|
// Stream<ScrollEvent> get scrollEvent => _scrollEventSubject.stream;
|
||||||
Stream<GeckoPref> get prefUpdateEvent => _prefUpdateSubject.stream;
|
Stream<GeckoPref> get prefUpdateEvent => _prefUpdateSubject.stream;
|
||||||
Stream<ContainerSiteAssignment> get siteAssignementEvent =>
|
Stream<ContainerSiteAssignment> get siteAssignementEvent =>
|
||||||
_siteAssignementSubject.stream;
|
_siteAssignementSubject.stream;
|
||||||
@@ -174,13 +174,13 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
_tabAddedSubject.addWhenMoreRecent(timestamp, null, tabId);
|
_tabAddedSubject.addWhenMoreRecent(timestamp, null, tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
void onScrollChange(int timestamp, String tabId, int scrollY) {
|
// void onScrollChange(int timestamp, String tabId, int scrollY) {
|
||||||
_scrollEventSubject.addWhenMoreRecent(timestamp, tabId, (
|
// _scrollEventSubject.addWhenMoreRecent(timestamp, tabId, (
|
||||||
tabId: tabId,
|
// tabId: tabId,
|
||||||
scrollY: scrollY,
|
// scrollY: scrollY,
|
||||||
));
|
// ));
|
||||||
}
|
// }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onPreferenceChange(int timestamp, GeckoPref value) {
|
void onPreferenceChange(int timestamp, GeckoPref value) {
|
||||||
@@ -224,7 +224,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
await _thumbnailSubject.close();
|
await _thumbnailSubject.close();
|
||||||
await _findResultsSubject.close();
|
await _findResultsSubject.close();
|
||||||
await _longPressSubject.close();
|
await _longPressSubject.close();
|
||||||
await _scrollEventSubject.close();
|
// await _scrollEventSubject.close();
|
||||||
await _tabAddedSubject.close();
|
await _tabAddedSubject.close();
|
||||||
await _prefUpdateSubject.close();
|
await _prefUpdateSubject.close();
|
||||||
await _siteAssignementSubject.close();
|
await _siteAssignementSubject.close();
|
||||||
|
|||||||
@@ -25,6 +25,18 @@ class GeckoHistoryService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<VisitInfo>> getVisitsPaginated(
|
||||||
|
int offset,
|
||||||
|
int count,
|
||||||
|
Set<VisitType> types,
|
||||||
|
) {
|
||||||
|
return _api.getVisitsPaginated(
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
VisitType.values.toSet().difference(types).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> deleteVisit(VisitInfo info) {
|
Future<void> deleteVisit(VisitInfo info) {
|
||||||
switch (info.visitType) {
|
switch (info.visitType) {
|
||||||
case VisitType.link:
|
case VisitType.link:
|
||||||
|
|||||||
@@ -5352,8 +5352,6 @@ abstract class GeckoStateEvents {
|
|||||||
|
|
||||||
void onLongPress(int timestamp, String id, HitResult hitResult);
|
void onLongPress(int timestamp, String id, HitResult hitResult);
|
||||||
|
|
||||||
void onScrollChange(int timestamp, String tabId, int scrollY);
|
|
||||||
|
|
||||||
void onPreferenceChange(int timestamp, GeckoPref value);
|
void onPreferenceChange(int timestamp, GeckoPref value);
|
||||||
|
|
||||||
void onContainerSiteAssignment(int timestamp, ContainerSiteAssignment details);
|
void onContainerSiteAssignment(int timestamp, ContainerSiteAssignment details);
|
||||||
@@ -5770,37 +5768,6 @@ abstract class GeckoStateEvents {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
|
||||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange$messageChannelSuffix', pigeonChannelCodec,
|
|
||||||
binaryMessenger: binaryMessenger);
|
|
||||||
if (api == null) {
|
|
||||||
pigeonVar_channel.setMessageHandler(null);
|
|
||||||
} else {
|
|
||||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
|
||||||
assert(message != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange was null.');
|
|
||||||
final List<Object?> args = (message as List<Object?>?)!;
|
|
||||||
final int? arg_timestamp = (args[0] as int?);
|
|
||||||
assert(arg_timestamp != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange was null, expected non-null int.');
|
|
||||||
final String? arg_tabId = (args[1] as String?);
|
|
||||||
assert(arg_tabId != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange was null, expected non-null String.');
|
|
||||||
final int? arg_scrollY = (args[2] as int?);
|
|
||||||
assert(arg_scrollY != null,
|
|
||||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onScrollChange was null, expected non-null int.');
|
|
||||||
try {
|
|
||||||
api.onScrollChange(arg_timestamp!, arg_tabId!, arg_scrollY!);
|
|
||||||
return wrapResponse(empty: true);
|
|
||||||
} on PlatformException catch (e) {
|
|
||||||
return wrapResponse(error: e);
|
|
||||||
} catch (e) {
|
|
||||||
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onPreferenceChange$messageChannelSuffix', pigeonChannelCodec,
|
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onPreferenceChange$messageChannelSuffix', pigeonChannelCodec,
|
||||||
@@ -6584,6 +6551,33 @@ class GeckoHistoryApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<VisitInfo>> getVisitsPaginated(int offset, int count, List<VisitType> excludeTypes) async {
|
||||||
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.getVisitsPaginated$pigeonVar_messageChannelSuffix';
|
||||||
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[offset, count, excludeTypes]);
|
||||||
|
final 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 if (pigeonVar_replyList[0] == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'null-error',
|
||||||
|
message: 'Host platform returned null value for non-null return value.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (pigeonVar_replyList[0] as List<Object?>?)!.cast<VisitInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> deleteVisit(String url, int timestamp) async {
|
Future<void> deleteVisit(String url, int timestamp) async {
|
||||||
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisit$pigeonVar_messageChannelSuffix';
|
final pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoHistoryApi.deleteVisit$pigeonVar_messageChannelSuffix';
|
||||||
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
|||||||
@@ -1226,7 +1226,7 @@ abstract class GeckoStateEvents {
|
|||||||
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
||||||
void onLongPress(int timestamp, String id, HitResult hitResult);
|
void onLongPress(int timestamp, String id, HitResult hitResult);
|
||||||
|
|
||||||
void onScrollChange(int timestamp, String tabId, int scrollY);
|
// void onScrollChange(int timestamp, String tabId, int scrollY);
|
||||||
void onPreferenceChange(int timestamp, GeckoPref value);
|
void onPreferenceChange(int timestamp, GeckoPref value);
|
||||||
|
|
||||||
void onContainerSiteAssignment(
|
void onContainerSiteAssignment(
|
||||||
@@ -1340,6 +1340,13 @@ abstract class GeckoHistoryApi {
|
|||||||
List<VisitType> excludeTypes,
|
List<VisitType> excludeTypes,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@async
|
||||||
|
List<VisitInfo> getVisitsPaginated(
|
||||||
|
int offset,
|
||||||
|
int count,
|
||||||
|
List<VisitType> excludeTypes,
|
||||||
|
);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
void deleteVisit(String url, int timestamp);
|
void deleteVisit(String url, int timestamp);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user