diff --git a/app/lib/account/like_backend.dart b/app/lib/account/like_backend.dart
index 3d33de72ef..902c0eeacc 100644
--- a/app/lib/account/like_backend.dart
+++ b/app/lib/account/like_backend.dart
@@ -75,6 +75,7 @@ class LikeBackend {
tx.queueMutations(inserts: [p, newLike]);
return newLike;
});
+ await cache.packageView(package).purge();
await purgeAccountCache(userId: user.userId);
return res;
}
@@ -100,6 +101,7 @@ class LikeBackend {
p.likes--;
tx.queueMutations(inserts: [p], deletes: [likeKey]);
});
+ await cache.packageView(package).purge();
await cache.userPackageLikes(user.userId).purge();
}
}
diff --git a/app/lib/frontend/templates/views/pkg/liked_package_list.dart b/app/lib/frontend/templates/views/pkg/liked_package_list.dart
index dec1249cc5..19cc4ccd42 100644
--- a/app/lib/frontend/templates/views/pkg/liked_package_list.dart
+++ b/app/lib/frontend/templates/views/pkg/liked_package_list.dart
@@ -72,22 +72,20 @@ d.Node renderLikeButtonAndLabel(
return d.div(
classes: ['like-button-and-label'],
children: [
- _renderLikeButton(package, isLiked),
+ renderLikeButton(package, likeCount: likeCount, isLiked: isLiked),
d.span(
classes: ['like-button-and-label--count-wrapper'],
child: d.span(
classes: ['like-button-and-label--count'],
text: _formatPackageLikes(likeCount),
- attributes: {
- 'data-value': likeCount.toString(),
- },
),
),
],
);
}
-d.Node _renderLikeButton(String package, bool isLiked) {
+d.Node renderLikeButton(String package,
+ {required int likeCount, required bool isLiked}) {
return material.iconButton(
classes: ['like-button-and-label--button'],
isOn: isLiked,
@@ -108,6 +106,7 @@ d.Node _renderLikeButton(String package, bool isLiked) {
'data-ga-click-event': 'toggle-like',
'aria-pressed': isLiked ? 'true' : 'false',
'data-package': package,
+ 'data-value': likeCount.toString(),
},
);
}
diff --git a/app/lib/frontend/templates/views/pkg/package_list.dart b/app/lib/frontend/templates/views/pkg/package_list.dart
index e3e5cd070e..12f869dcd3 100644
--- a/app/lib/frontend/templates/views/pkg/package_list.dart
+++ b/app/lib/frontend/templates/views/pkg/package_list.dart
@@ -6,6 +6,8 @@ import 'package:_pub_shared/format/x_ago_format.dart';
import 'package:_pub_shared/search/search_form.dart';
import 'package:_pub_shared/search/tags.dart';
import 'package:clock/clock.dart';
+import 'package:pub_dev/frontend/request_context.dart';
+import 'package:pub_dev/frontend/templates/views/pkg/liked_package_list.dart';
import '../../../../package/models.dart';
import '../../../../package/screenshots/backend.dart';
@@ -31,6 +33,11 @@ d.Node listOfPackagesNode({
}) {
final bestNameMatch =
(nameMatches == null || nameMatches.isEmpty) ? null : nameMatches.first;
+ final listingPackagesLikedByMe =
+ requestContext.experimentalFlags.useMyLikedSearch &&
+ (searchForm?.parsedQuery.tagsPredicate
+ .isRequiredTag(AccountTag.isLikedByMe) ??
+ false);
return d.div(
classes: ['packages'],
children: [
@@ -39,6 +46,7 @@ d.Node listOfPackagesNode({
hit,
searchForm: searchForm,
isNameMatch: hit.name == bestNameMatch,
+ isLiked: listingPackagesLikedByMe,
)),
imageCarousel(),
],
@@ -77,6 +85,7 @@ d.Node _packageItem(
PackageView view, {
required SearchForm? searchForm,
required bool isNameMatch,
+ required bool isLiked,
}) {
final isFlutterFavorite = view.tags.contains(PackageTags.isFlutterFavorite);
final isNullSafe = view.tags.contains(PackageVersionTags.isNullSafe);
@@ -188,6 +197,9 @@ d.Node _packageItem(
labeledScoresNode: labeledScoresNodeFromPackageView(view),
description: view.ellipsizedDescription ?? '',
metadataNode: metadataNode,
+ likeIcon: isLiked
+ ? renderLikeButton(view.name, likeCount: view.likes, isLiked: isLiked)
+ : null,
copyIcon:
copyIcon(package: view.name, version: view.releases.stable.version),
tagsNode: tagsNodeFromPackageView(searchForm: searchForm, package: view),
@@ -220,6 +232,7 @@ d.Node _item({
required String description,
required d.Node metadataNode,
required d.Node? tagsNode,
+ d.Node? likeIcon,
d.Node? copyIcon,
required String? replacedBy,
required List<_ApiPageUrl>? apiPages,
@@ -237,6 +250,7 @@ d.Node _item({
'pub-monochrome-icon-hoverable',
], children: [
d.a(href: url, text: name),
+ if (likeIcon != null) ...[d.text(' '), likeIcon],
if (copyIcon != null) copyIcon,
d.text(' '),
if (isNameMatch) nameMatchBadgeNode,
diff --git a/app/test/frontend/golden/pkg_activity_log_page.html b/app/test/frontend/golden/pkg_activity_log_page.html
index 269e732a29..b4960f90d9 100644
--- a/app/test/frontend/golden/pkg_activity_log_page.html
+++ b/app/test/frontend/golden/pkg_activity_log_page.html
@@ -186,12 +186,12 @@
diff --git a/app/test/frontend/golden/pkg_admin_page.html b/app/test/frontend/golden/pkg_admin_page.html
index 00595e346d..042e02fde1 100644
--- a/app/test/frontend/golden/pkg_admin_page.html
+++ b/app/test/frontend/golden/pkg_admin_page.html
@@ -186,12 +186,12 @@
diff --git a/app/test/frontend/golden/pkg_changelog_page.html b/app/test/frontend/golden/pkg_changelog_page.html
index dbd5e7559d..9fa751533c 100644
--- a/app/test/frontend/golden/pkg_changelog_page.html
+++ b/app/test/frontend/golden/pkg_changelog_page.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_example_page.html b/app/test/frontend/golden/pkg_example_page.html
index 37263ca75f..9d6e649250 100644
--- a/app/test/frontend/golden/pkg_example_page.html
+++ b/app/test/frontend/golden/pkg_example_page.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_install_page.html b/app/test/frontend/golden/pkg_install_page.html
index 13a25c95da..8bb63acedb 100644
--- a/app/test/frontend/golden/pkg_install_page.html
+++ b/app/test/frontend/golden/pkg_install_page.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_score_page.html b/app/test/frontend/golden/pkg_score_page.html
index be2c1a29b6..96549ca7e8 100644
--- a/app/test/frontend/golden/pkg_score_page.html
+++ b/app/test/frontend/golden/pkg_score_page.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_score_page_with_downloads_chart.html b/app/test/frontend/golden/pkg_score_page_with_downloads_chart.html
index be2c1a29b6..96549ca7e8 100644
--- a/app/test/frontend/golden/pkg_score_page_with_downloads_chart.html
+++ b/app/test/frontend/golden/pkg_score_page_with_downloads_chart.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_show_page.html b/app/test/frontend/golden/pkg_show_page.html
index af68a92d5d..f6ba2049f8 100644
--- a/app/test/frontend/golden/pkg_show_page.html
+++ b/app/test/frontend/golden/pkg_show_page.html
@@ -152,12 +152,12 @@
diff --git a/app/test/frontend/golden/pkg_show_page_discontinued.html b/app/test/frontend/golden/pkg_show_page_discontinued.html
index e736343abf..06754b1f37 100644
--- a/app/test/frontend/golden/pkg_show_page_discontinued.html
+++ b/app/test/frontend/golden/pkg_show_page_discontinued.html
@@ -160,12 +160,12 @@
diff --git a/app/test/frontend/golden/pkg_show_page_flutter_plugin.html b/app/test/frontend/golden/pkg_show_page_flutter_plugin.html
index 975fba5106..74053bf0e9 100644
--- a/app/test/frontend/golden/pkg_show_page_flutter_plugin.html
+++ b/app/test/frontend/golden/pkg_show_page_flutter_plugin.html
@@ -150,12 +150,12 @@
diff --git a/app/test/frontend/golden/pkg_show_page_publisher.html b/app/test/frontend/golden/pkg_show_page_publisher.html
index 4c53104a61..677c1d5f8b 100644
--- a/app/test/frontend/golden/pkg_show_page_publisher.html
+++ b/app/test/frontend/golden/pkg_show_page_publisher.html
@@ -155,12 +155,12 @@
diff --git a/app/test/frontend/golden/pkg_show_page_retracted.html b/app/test/frontend/golden/pkg_show_page_retracted.html
index cdd3716100..069d0b2360 100644
--- a/app/test/frontend/golden/pkg_show_page_retracted.html
+++ b/app/test/frontend/golden/pkg_show_page_retracted.html
@@ -143,12 +143,12 @@
retracted
diff --git a/app/test/frontend/golden/pkg_show_page_retracted_non_retracted_version.html b/app/test/frontend/golden/pkg_show_page_retracted_non_retracted_version.html
index 24ee2e3fc5..36a593d4c0 100644
--- a/app/test/frontend/golden/pkg_show_page_retracted_non_retracted_version.html
+++ b/app/test/frontend/golden/pkg_show_page_retracted_non_retracted_version.html
@@ -151,12 +151,12 @@
diff --git a/app/test/frontend/golden/pkg_show_version_page.html b/app/test/frontend/golden/pkg_show_version_page.html
index 1281df1116..18c786cd46 100644
--- a/app/test/frontend/golden/pkg_show_version_page.html
+++ b/app/test/frontend/golden/pkg_show_version_page.html
@@ -161,12 +161,12 @@
diff --git a/app/test/frontend/golden/pkg_versions_page.html b/app/test/frontend/golden/pkg_versions_page.html
index 5c375e6bb4..f3e51ffe3e 100644
--- a/app/test/frontend/golden/pkg_versions_page.html
+++ b/app/test/frontend/golden/pkg_versions_page.html
@@ -160,12 +160,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen.html b/app/test/task/testdata/goldens/packages/oxygen.html
index f8ed0f947b..6245c89564 100644
--- a/app/test/task/testdata/goldens/packages/oxygen.html
+++ b/app/test/task/testdata/goldens/packages/oxygen.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/changelog.html b/app/test/task/testdata/goldens/packages/oxygen/changelog.html
index 1c3f7c7afd..68a6c5213e 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/changelog.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/changelog.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/example.html b/app/test/task/testdata/goldens/packages/oxygen/example.html
index a3e6788e33..9b24bf9544 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/example.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/example.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/install.html b/app/test/task/testdata/goldens/packages/oxygen/install.html
index 7e5cbe8c87..a261d4bd6d 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/install.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/install.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/license.html b/app/test/task/testdata/goldens/packages/oxygen/license.html
index 58ed2570e9..96b2aa6f0e 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/license.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/license.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/score.html b/app/test/task/testdata/goldens/packages/oxygen/score.html
index 80b6748411..3f362ac2d6 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/score.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/score.html
@@ -153,12 +153,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions.html b/app/test/task/testdata/goldens/packages/oxygen/versions.html
index bd17e6b3e6..39ccd3a3d7 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions.html
@@ -152,12 +152,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0.html
index 684ad631a6..5460275eea 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/changelog.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/changelog.html
index a3cbc11b47..fcc3637be1 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/changelog.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/changelog.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/example.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/example.html
index 0aa62eef7d..098fbcc61b 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/example.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/example.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/install.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/install.html
index f8a380a489..53783e83e0 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/install.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/install.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/license.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/license.html
index 8914894695..f2007604e8 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/license.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/license.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/score.html b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/score.html
index 3c367dd540..6c1a0b95c7 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/score.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/1.0.0/score.html
@@ -157,12 +157,12 @@
diff --git a/app/test/task/testdata/goldens/packages/oxygen/versions/2.0.0.html b/app/test/task/testdata/goldens/packages/oxygen/versions/2.0.0.html
index f8ed0f947b..6245c89564 100644
--- a/app/test/task/testdata/goldens/packages/oxygen/versions/2.0.0.html
+++ b/app/test/task/testdata/goldens/packages/oxygen/versions/2.0.0.html
@@ -153,12 +153,12 @@
diff --git a/pkg/pub_integration/test/like_test.dart b/pkg/pub_integration/test/like_test.dart
index a19899e48b..ac1a442c78 100644
--- a/pkg/pub_integration/test/like_test.dart
+++ b/pkg/pub_integration/test/like_test.dart
@@ -60,14 +60,15 @@ void main() {
await user.withBrowserPage((page) async {
Future> getCountLabels() async {
- final buttonLabel = await page.$('.like-button-and-label--count');
- final viewLabel =
- await page.$('.packages-score-like .packages-score-value-number');
+ final buttonLabel =
+ await page.$OrNull('.like-button-and-label--count');
+ final viewLabel = await page
+ .$OrNull('.packages-score-like .packages-score-value-number');
final keyScoreLabel = await page
.$OrNull('.score-key-figure--likes .score-key-figure-value');
return [
- await buttonLabel.textContent(),
- await viewLabel.textContent(),
+ (await buttonLabel?.textContent()) ?? '',
+ (await viewLabel?.textContent()) ?? '',
(await keyScoreLabel?.textContent()) ?? '',
];
}
@@ -83,7 +84,7 @@ void main() {
expect(await getCountLabels(), ['0', '0', '']);
await page.click('.like-button-and-label--button');
- await Future.delayed(Duration(seconds: 1));
+ await Future.delayed(Duration(milliseconds: 200));
expect(await getCountLabels(), ['1', '1', '']);
// checking search with my-liked packages - with the one liked package
@@ -96,12 +97,32 @@ void main() {
expect(await getCountLabels(), ['1', '1', '1']);
await page.click('.like-button-and-label--button');
- await Future.delayed(Duration(seconds: 1));
+ await Future.delayed(Duration(milliseconds: 200));
// checking it on the main package page too
expect(await getCountLabels(), ['0', '0', '0']);
await page.gotoOrigin('/packages/test_pkg');
expect(await getCountLabels(), ['0', '0', '']);
+
+ // unlike on the is:liked-by-me page
+ {
+ await page.gotoOrigin('/packages/test_pkg');
+ await page.click('.like-button-and-label--button');
+ await Future.delayed(Duration(milliseconds: 200));
+ expect(await getCountLabels(), ['1', '1', '']);
+
+ await page.gotoOrigin('/packages?q=pkg+is:liked-by-me');
+ final info = await listingPageInfo(page);
+ expect(info.packageNames.toSet(), {'test_pkg'});
+ expect(await getCountLabels(), ['', '1', '']);
+
+ await page.click('.like-button-and-label--button');
+ await Future.delayed(Duration(milliseconds: 200));
+ expect(await getCountLabels(), ['', '0', '']);
+
+ await page.gotoOrigin('/packages/test_pkg');
+ expect(await getCountLabels(), ['0', '0', '']);
+ }
});
});
});
diff --git a/pkg/web_app/lib/src/likes.dart b/pkg/web_app/lib/src/likes.dart
index 6e775dddec..53642d1049 100644
--- a/pkg/web_app/lib/src/likes.dart
+++ b/pkg/web_app/lib/src/likes.dart
@@ -48,21 +48,22 @@ void setupLikes() {
for (final likeButton
in document.querySelectorAll('.like-button-and-label--button')) {
final package = likeButton.dataset['package'];
- if (package == null || package.isEmpty) continue;
+ final originalCount = int.tryParse(likeButton.dataset['value'] ?? '');
- final countLabel =
- likeButton.parent?.querySelector('.like-button-and-label--count');
- final originalCount = int.tryParse(countLabel?.dataset['value'] ?? '');
+ if (package == null || package.isEmpty || originalCount == null) {
+ continue;
+ }
var likesDelta = 0;
void updateLabels() {
- if (countLabel == null || originalCount == null) {
- return;
- }
final likesCount = originalCount + likesDelta;
- // keep in-sync with app/lib/frontend/templates/views/pkg/liked_package_list.dart
- countLabel.innerText = formatWithSuffix(likesCount);
+ final countLabel =
+ likeButton.parent?.querySelector('.like-button-and-label--count');
+ if (countLabel != null) {
+ // keep in-sync with app/lib/frontend/templates/views/pkg/liked_package_list.dart
+ countLabel.innerText = formatWithSuffix(likesCount);
+ }
// keep in-sync with app/lib/frontend/templates/views/pkg/labeled_scores.dart
final formatted = compactFormat(likesCount);
diff --git a/pkg/web_css/lib/src/_list.scss b/pkg/web_css/lib/src/_list.scss
index 7b9cde7f0d..f667841185 100644
--- a/pkg/web_css/lib/src/_list.scss
+++ b/pkg/web_css/lib/src/_list.scss
@@ -234,6 +234,11 @@
font-weight: 500;
margin: 0;
overflow-wrap: anywhere;
+
+ .like-button-and-label--button img {
+ width: 18px;
+ height: 18px;
+ }
}
.packages-recent {