Initial commit
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import '../contracts/danmaku.dart';
|
||||
|
||||
const defaultDuplicateDanmakuMergeWindowSeconds = 1.0;
|
||||
|
||||
final _whitespacePattern = RegExp(r'\s+');
|
||||
|
||||
List<DanmakuComment> mergeDuplicateDanmakuComments(
|
||||
Iterable<DanmakuComment> comments, {
|
||||
double windowSeconds = defaultDuplicateDanmakuMergeWindowSeconds,
|
||||
}) {
|
||||
if (windowSeconds < 0) {
|
||||
throw ArgumentError.value(
|
||||
windowSeconds,
|
||||
'windowSeconds',
|
||||
'must be non-negative',
|
||||
);
|
||||
}
|
||||
|
||||
final sorted = comments.toList()..sort(_compareDanmakuComments);
|
||||
if (sorted.length < 2) return sorted;
|
||||
|
||||
|
||||
final keptByText = <String, List<DanmakuComment>>{};
|
||||
final passthrough = <DanmakuComment>[];
|
||||
|
||||
for (final comment in sorted) {
|
||||
final key = _mergeKey(comment);
|
||||
if (key.isEmpty) {
|
||||
passthrough.add(comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
final kept = keptByText.putIfAbsent(key, () => []);
|
||||
final windowStart = kept.isEmpty ? null : kept.last.time;
|
||||
if (windowStart == null || comment.time - windowStart > windowSeconds) {
|
||||
kept.add(comment);
|
||||
}
|
||||
}
|
||||
|
||||
return <DanmakuComment>[
|
||||
...passthrough,
|
||||
for (final kept in keptByText.values) ...kept,
|
||||
]..sort(_compareDanmakuComments);
|
||||
}
|
||||
|
||||
int _compareDanmakuComments(DanmakuComment a, DanmakuComment b) {
|
||||
final timeOrder = a.time.compareTo(b.time);
|
||||
if (timeOrder != 0) return timeOrder;
|
||||
return a.cid.compareTo(b.cid);
|
||||
}
|
||||
|
||||
String _mergeKey(DanmakuComment comment) {
|
||||
return comment.text.trim().replaceAll(_whitespacePattern, ' ');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user