chore: style grid
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/asset.interface.dart';
|
||||
import 'package:immich_mobile/domain/models/asset.model.dart';
|
||||
import 'package:immich_mobile/domain/models/render_list_element.model.dart';
|
||||
import 'package:immich_mobile/service_locator.dart';
|
||||
|
||||
class RenderList {
|
||||
final List<RenderListElement> elements;
|
||||
final int totalCount;
|
||||
|
||||
/// global offset of assets in [_buf]
|
||||
int _bufOffset = 0;
|
||||
|
||||
/// reference to batch of assets loaded from DB with offset [_bufOffset]
|
||||
List<Asset> _buf = [];
|
||||
|
||||
RenderList({required this.elements, required this.totalCount});
|
||||
|
||||
/// Loads the requested assets from the database to an internal buffer if not cached
|
||||
/// and returns a slice of that buffer
|
||||
Future<List<Asset>> loadAssets(int offset, int count) async {
|
||||
assert(offset >= 0);
|
||||
assert(count > 0);
|
||||
assert(offset + count <= totalCount);
|
||||
|
||||
// general case: we have the query to load assets via offset from the DB on demand
|
||||
if (offset < _bufOffset || offset + count > _bufOffset + _buf.length) {
|
||||
// the requested slice (offset:offset+count) is not contained in the cache buffer `_buf`
|
||||
// thus, fill the buffer with a new batch of assets that at least contains the requested
|
||||
// assets and some more
|
||||
|
||||
final bool forward = _bufOffset < offset;
|
||||
// if the requested offset is greater than the cached offset, the user scrolls forward "down"
|
||||
const batchSize = 256;
|
||||
const oppositeSize = 64;
|
||||
|
||||
// make sure to load a meaningful amount of data (and not only the requested slice)
|
||||
// otherwise, each call to [loadAssets] would result in DB call trashing performance
|
||||
// fills small requests to [batchSize], adds some legroom into the opposite scroll direction for large requests
|
||||
final len = math.max(batchSize, count + oppositeSize);
|
||||
// when scrolling forward, start shortly before the requested offset...
|
||||
// when scrolling backward, end shortly after the requested offset...
|
||||
// ... to guard against the user scrolling in the other direction
|
||||
// a tiny bit resulting in a another required load from the DB
|
||||
final start = math.max(
|
||||
0,
|
||||
forward
|
||||
? offset - oppositeSize
|
||||
: (len > batchSize ? offset : offset + count - len),
|
||||
);
|
||||
// load the calculated batch (start:start+len) from the DB and put it into the buffer
|
||||
_buf =
|
||||
await di<IAssetRepository>().fetchAssets(offset: start, limit: len);
|
||||
_bufOffset = start;
|
||||
|
||||
assert(_bufOffset <= offset);
|
||||
assert(_bufOffset + _buf.length >= offset + count);
|
||||
}
|
||||
// return the requested slice from the buffer (we made sure before that the assets are loaded!)
|
||||
return _buf.slice(offset - _bufOffset, offset - _bufOffset + count);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,70 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
enum RenderListGroupBy { month, day }
|
||||
|
||||
sealed class RenderListElement {
|
||||
const RenderListElement();
|
||||
const RenderListElement({required this.date});
|
||||
|
||||
final DateTime date;
|
||||
|
||||
@override
|
||||
bool operator ==(covariant RenderListElement other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return date == other.date;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => date.hashCode;
|
||||
}
|
||||
|
||||
class RenderListMonthHeaderElement extends RenderListElement {
|
||||
final String header;
|
||||
late final String header;
|
||||
|
||||
const RenderListMonthHeaderElement({required this.header});
|
||||
RenderListMonthHeaderElement({required super.date}) {
|
||||
final formatter = DateTime.now().year == date.year
|
||||
? DateFormat.MMMM()
|
||||
: DateFormat.yMMMM();
|
||||
header = formatter.format(date);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant RenderListMonthHeaderElement other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return super == other && header == other.header;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => super.hashCode ^ date.hashCode;
|
||||
}
|
||||
|
||||
class RenderListDayHeaderElement extends RenderListElement {
|
||||
final String header;
|
||||
|
||||
const RenderListDayHeaderElement({required this.header});
|
||||
const RenderListDayHeaderElement({required super.date, required this.header});
|
||||
|
||||
@override
|
||||
bool operator ==(covariant RenderListDayHeaderElement other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return super == other && header == other.header;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => super.hashCode ^ date.hashCode;
|
||||
}
|
||||
|
||||
class RenderListAssetElement extends RenderListElement {
|
||||
final DateTime date;
|
||||
final int assetCount;
|
||||
final int assetOffset;
|
||||
|
||||
const RenderListAssetElement({
|
||||
required this.date,
|
||||
required super.date,
|
||||
required this.assetCount,
|
||||
required this.assetOffset,
|
||||
});
|
||||
|
||||
RenderListAssetElement copyWith({
|
||||
DateTime? date,
|
||||
int? assetCount,
|
||||
int? assetOffset,
|
||||
}) {
|
||||
return RenderListAssetElement(
|
||||
date: date ?? this.date,
|
||||
assetCount: assetCount ?? this.assetCount,
|
||||
assetOffset: assetOffset ?? this.assetOffset,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'RenderListAssetElement(date: $date, assetCount: $assetCount, assetOffset: $assetOffset)';
|
||||
@@ -45,12 +73,12 @@ class RenderListAssetElement extends RenderListElement {
|
||||
bool operator ==(covariant RenderListAssetElement other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.date == date &&
|
||||
return super == other &&
|
||||
other.assetCount == assetCount &&
|
||||
other.assetOffset == assetOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
date.hashCode ^ assetCount.hashCode ^ assetOffset.hashCode;
|
||||
super.hashCode ^ assetCount.hashCode ^ assetOffset.hashCode;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user