Skip to content

Commit cfb52c6

Browse files
authored
Trending search (#8750)
1 parent 73f43ae commit cfb52c6

File tree

7 files changed

+34
-0
lines changed

7 files changed

+34
-0
lines changed

app/lib/frontend/handlers/experimental.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ typedef PublicFlag = ({String name, String description});
1010

1111
const _publicFlags = <PublicFlag>{
1212
(name: 'example', description: 'Short description'),
13+
(
14+
name: 'trending-search',
15+
description: 'Show trending packages and search by trending scores'
16+
),
1317
};
1418

1519
final _allFlags = <String>{
@@ -88,6 +92,8 @@ class ExperimentalFlags {
8892

8993
bool get isDarkModeDefault => isEnabled('dark-as-default');
9094

95+
bool get showTrending => isEnabled('trending-search');
96+
9197
String encodedAsCookie() => _enabled.join(':');
9298

9399
@override

app/lib/frontend/templates/_consts.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:_pub_shared/search/tags.dart';
6+
import 'package:pub_dev/frontend/request_context.dart';
67

78
import '../dom/dom.dart' as d;
89

@@ -124,5 +125,10 @@ List<SortDict> getSortDicts(bool isSearch) {
124125
final removeId = isSearch ? 'listing_relevance' : 'search_relevance';
125126
return <SortDict>[
126127
..._sortDicts.where((d) => d.id != removeId),
128+
if (requestContext.experimentalFlags.showTrending)
129+
SortDict(
130+
id: 'trending',
131+
label: 'trending',
132+
tooltip: 'Packages are sorted by trending.'),
127133
];
128134
}

app/lib/search/backend.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ class SearchBackend {
372372
updated: p.lastVersionPublished!,
373373
readme: compactReadme(readmeAsset?.textContent),
374374
downloadCount: downloadCountsBackend.lookup30DaysTotalCounts(pv.package),
375+
trendScore: downloadCountsBackend.lookupTrendScore(pv.package),
375376
likeCount: p.likes,
376377
grantedPoints: scoreCard.grantedPubPoints,
377378
maxPoints: scoreCard.maxPubPoints,

app/lib/search/mem_index.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class InMemoryPackageIndex {
4343
late final List<IndexedPackageHit> _downloadsOrderedHits;
4444
late final List<IndexedPackageHit> _likesOrderedHits;
4545
late final List<IndexedPackageHit> _pointsOrderedHits;
46+
late final List<IndexedPackageHit> _trendingOrderedHits;
4647

4748
// Contains all of the topics the index had seen so far.
4849
// TODO: consider moving this into a separate index
@@ -121,6 +122,8 @@ class InMemoryPackageIndex {
121122
score: (doc) => doc.likeCount.toDouble());
122123
_pointsOrderedHits = _rankWithComparator(_comparePoints,
123124
score: (doc) => doc.grantedPoints.toDouble());
125+
_trendingOrderedHits = _rankWithComparator(_compareTrending,
126+
score: (doc) => doc.trendScore.toDouble());
124127
}
125128

126129
IndexInfo indexInfo() {
@@ -289,6 +292,9 @@ class InMemoryPackageIndex {
289292
case SearchOrder.points:
290293
indexedHits = _pointsOrderedHits.whereInScores(packageScores);
291294
break;
295+
case SearchOrder.trending:
296+
indexedHits = _trendingOrderedHits.whereInScores(packageScores);
297+
break;
292298
}
293299

294300
// bound by offset and limit (or randomize items)
@@ -532,6 +538,12 @@ class InMemoryPackageIndex {
532538
if (x != 0) return x;
533539
return _compareUpdated(a, b);
534540
}
541+
542+
int _compareTrending(PackageDocument a, PackageDocument b) {
543+
final x = -a.trendScore.compareTo(b.trendScore);
544+
if (x != 0) return x;
545+
return _compareUpdated(a, b);
546+
}
535547
}
536548

537549
class _TextResults {

app/lib/search/search_service.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class PackageDocument {
7979
/// The normalized score between [0.0-1.0] (1.0 being the most downloaded package).
8080
double? downloadScore;
8181

82+
final int trendScore;
83+
8284
final int likeCount;
8385

8486
/// The normalized score between [0.0-1.0] (1.0 being the most liked package).
@@ -110,6 +112,7 @@ class PackageDocument {
110112
List<String>? tags,
111113
int? downloadCount,
112114
this.downloadScore,
115+
int? trendScore,
113116
int? likeCount,
114117
this.likeScore,
115118
int? grantedPoints,
@@ -121,6 +124,7 @@ class PackageDocument {
121124
}) : created = created ?? clock.now(),
122125
updated = updated ?? clock.now(),
123126
downloadCount = downloadCount ?? 0,
127+
trendScore = trendScore ?? 0,
124128
likeCount = likeCount ?? 0,
125129
grantedPoints = grantedPoints ?? 0,
126130
maxPoints = maxPoints ?? 0,

app/lib/search/search_service.g.dart

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/_pub_shared/lib/search/search_form.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ enum SearchOrder {
6464

6565
/// Search order should be in decreasing pub points.
6666
points,
67+
68+
/// Search order should be in decreasing trend score.
69+
trending,
6770
}
6871

6972
/// Returns null if [value] is not a recognized search order.

0 commit comments

Comments
 (0)