Skip to content

New like button markup with class selectors + also updating other labels on the page. #8888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/lib/frontend/dom/material.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,22 @@ d.Node raisedButton({

/// Renders a two-state material icon button
d.Node iconButton({
required String id,
String? id,
required bool isOn,
Map<String, String>? attributes,
required d.Image onIcon,
required d.Image offIcon,
bool disabled = false,
String? title,
List<String>? classes,
}) {
return d.element(
'button',
id: id,
classes: [
'mdc-icon-button',
if (isOn) 'mdc-icon-button--on',
...?classes,
],
attributes: {
...?attributes,
Expand Down
8 changes: 2 additions & 6 deletions app/lib/frontend/templates/detail_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ import 'views/shared/detail/tabs.dart';
final wideHeaderDetailPageClassName = '-wide-header-detail-page';

/// Renders the detail page's header template.
///
/// The like button in the header will not be displayed when [isLiked] is null.
d.Node renderDetailHeader({
required d.Node titleNode,
d.Image? image,
int? packageLikes,
bool? isLiked,
bool isFlutterFavorite = false,
d.Node? metadataNode,
d.Node? tagsNode,
d.Node? likeNode,

/// Set true for more whitespace in the header.
bool isLoose = false,
Expand All @@ -28,10 +25,9 @@ d.Node renderDetailHeader({
titleNode: titleNode,
metadataNode: metadataNode,
tagsNode: tagsNode,
likeNode: likeNode,
image: image,
isLoose: isLoose,
isLiked: isLiked == true,
likeCount: packageLikes,
isFlutterFavorite: isFlutterFavorite,
);
}
Expand Down
9 changes: 6 additions & 3 deletions app/lib/frontend/templates/package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:_pub_shared/data/page_data.dart';
import 'package:_pub_shared/search/tags.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:pub_dev/frontend/templates/views/pkg/liked_package_list.dart';

import '../../package/models.dart';
import '../../package/overrides.dart' show devDependencyPackages;
Expand Down Expand Up @@ -129,8 +130,11 @@ d.Node renderPkgHeader(PackagePageData data) {
package: package.name!,
version: data.version.version!,
),
packageLikes: package.likes,
isLiked: data.isLiked,
likeNode: renderLikeButtonAndLabel(
package: package.name!,
likeCount: package.likes,
isLiked: data.isLiked,
),
isFlutterFavorite:
(package.assignedTags ?? []).contains(PackageTags.isFlutterFavorite),
metadataNode: metadataNode,
Expand Down Expand Up @@ -307,7 +311,6 @@ PageData pkgPageData(
version: selectedVersion.version!,
publisherId: package.publisherId,
isDiscontinued: package.isDiscontinued,
likes: package.likes,
isLatest: package.latestVersion == selectedVersion.version,
),
sessionAware: editable,
Expand Down
1 change: 1 addition & 0 deletions app/lib/frontend/templates/package_misc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ d.Node replacedByLink(String replacedBy) {
/// Renders the labeled scores widget (the score values in a compact layout).
d.Node labeledScoresNodeFromPackageView(PackageView view, {String? version}) {
return labeledScoresNode(
package: view.name,
pkgScorePageUrl: urls.pkgScoreUrl(view.name, version: version),
likeCount: view.likes,
grantedPubPoints: view.grantedPubPoints,
Expand Down
14 changes: 9 additions & 5 deletions app/lib/frontend/templates/views/pkg/labeled_scores.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import 'package:_pub_shared/format/number_format.dart';
import '../../../dom/dom.dart' as d;

d.Node labeledScoresNode({
required String package,
required String pkgScorePageUrl,
required int likeCount,
required int? grantedPubPoints,
required int? thirtyDaysDownloads,
}) {
final formattedLikes = compactFormat(likeCount);
final formattedDownloads =
thirtyDaysDownloads == null ? null : compactFormat(thirtyDaysDownloads);
return d.a(
classes: ['packages-scores'],
href: pkgScorePageUrl,
Expand All @@ -20,9 +24,10 @@ d.Node labeledScoresNode({
classes: ['packages-score', 'packages-score-like'],
child: _labeledScore(
'likes',
'${compactFormat(likeCount).value}'
'${compactFormat(likeCount).suffix}',
// keep in-sync with pkg/web_app/lib/src/likes.dart
'${formattedLikes.value}${formattedLikes.suffix}',
sign: ''),
attributes: {'data-package': package},
),
d.div(
classes: ['packages-score', 'packages-score-health'],
Expand All @@ -35,9 +40,8 @@ d.Node labeledScoresNode({
classes: ['packages-score', 'packages-score-downloads'],
child: _labeledScore(
'downloads',
thirtyDaysDownloads != null
? '${compactFormat(thirtyDaysDownloads).value}'
'${compactFormat(thirtyDaysDownloads).suffix}'
formattedDownloads != null
? '${formattedDownloads.value}${formattedDownloads.suffix}'
: null,
sign: '',
),
Expand Down
49 changes: 49 additions & 0 deletions app/lib/frontend/templates/views/pkg/liked_package_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:_pub_shared/format/number_format.dart';

import '../../../../account/models.dart';
import '../../../../shared/urls.dart' as urls;

Expand Down Expand Up @@ -64,3 +66,50 @@ d.Node likedPackageListNode(List<LikeData> likes) {
),
);
}

d.Node renderLikeButtonAndLabel(
{required String package, required int likeCount, required bool isLiked}) {
return d.div(
classes: ['like-button-and-label'],
children: [
material.iconButton(
classes: ['like-button-and-label--button'],
isOn: isLiked,
onIcon: d.Image(
src: staticUrls.getAssetUrl('/static/img/like-active.svg'),
alt: 'liked status: active',
width: 18,
height: 18,
),
offIcon: d.Image(
src: staticUrls.getAssetUrl('/static/img/like-inactive.svg'),
alt: 'liked status: inactive',
width: 18,
height: 18,
),
title: isLiked ? 'Unlike this package' : 'Like this package',
attributes: {
'data-ga-click-event': 'toggle-like',
'aria-pressed': isLiked ? 'true' : 'false',
},
),
d.span(
classes: ['like-button-and-label--count-wrapper'],
child: d.span(
classes: ['like-button-and-label--count'],
text: _formatPackageLikes(likeCount),
attributes: {
'data-package': package,
'data-value': likeCount.toString(),
},
),
),
],
);
}

// keep in-sync with pkg/web_app/lib/src/likes.dart
String? _formatPackageLikes(int? likesCount) {
if (likesCount == null) return null;
return formatWithSuffix(likesCount);
}
9 changes: 6 additions & 3 deletions app/lib/frontend/templates/views/pkg/score_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,13 @@ d.Node _likeKeyFigureNode(int? likeCount) {
label: 'likes',
);
}
final formatted = compactFormat(likeCount);
// keep in-sync with pkg/web_app/lib/src/likes.dart
return _keyFigureNode(
value: '${compactFormat(likeCount).value}'
'${compactFormat(likeCount).suffix}',
value: '${formatted.value}${formatted.suffix}',
supplemental: '',
label: 'likes',
classes: ['score-key-figure--likes'],
);
}

Expand Down Expand Up @@ -367,9 +369,10 @@ d.Node _keyFigureNode({
required String value,
required String supplemental,
required String label,
List<String>? classes,
}) {
return d.div(
classes: ['score-key-figure'],
classes: ['score-key-figure', ...?classes],
children: [
d.div(
classes: ['score-key-figure-title'],
Expand Down
53 changes: 3 additions & 50 deletions app/lib/frontend/templates/views/shared/detail/header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:_pub_shared/format/number_format.dart';

import '../../../../dom/dom.dart' as d;
import '../../../../dom/material.dart' as material;
import '../../../../static_files.dart';

d.Node detailHeaderNode({
required d.Node titleNode,
required d.Node? metadataNode,
required d.Node? tagsNode,
required d.Image? image,
required bool isLiked,
required int? likeCount,
required d.Node? likeNode,
required bool isFlutterFavorite,

/// Set true for more whitespace in the header.
Expand Down Expand Up @@ -116,50 +112,13 @@ d.Node detailHeaderNode({
child: titleNode,
),
d.div(classes: ['metadata'], child: metadataNode),
if (tagsNode != null || likeCount != null)
if (tagsNode != null || likeNode != null)
d.div(
classes: ['detail-tags-and-like'],
children: [
if (tagsNode != null)
d.div(classes: ['detail-tags'], child: tagsNode),
if (likeCount != null)
d.div(
classes: ['detail-like'],
children: [
material.iconButton(
id: '-pub-like-icon-button',
isOn: isLiked,
onIcon: d.Image(
src: staticUrls
.getAssetUrl('/static/img/like-active.svg'),
alt: 'liked status: active',
width: 18,
height: 18,
),
offIcon: d.Image(
src: staticUrls.getAssetUrl(
'/static/img/like-inactive.svg'),
alt: 'liked status: inactive',
width: 18,
height: 18,
),
title: isLiked
? 'Unlike this package'
: 'Like this package',
attributes: {
'data-ga-click-event': 'toggle-like',
'aria-pressed': isLiked ? 'true' : 'false',
},
),
d.span(
classes: ['likes-count'],
child: d.span(
id: 'likes-count',
text: _formatPackageLikes(likeCount),
),
),
],
),
if (likeNode != null) likeNode,
],
),
],
Expand All @@ -170,9 +129,3 @@ d.Node detailHeaderNode({
),
]);
}

// keep in-sync with pkg/web_app/lib/src/likes.dart
String? _formatPackageLikes(int? likesCount) {
if (likesCount == null) return null;
return formatWithSuffix(likesCount);
}
4 changes: 2 additions & 2 deletions app/test/frontend/golden/my_packages.html
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ <h3 class="packages-title pub-monochrome-icon-hoverable">
<b>%%x-ago%%</b>
</div>
<a class="packages-scores" href="/packages/oxygen/score">
<div class="packages-score packages-score-like">
<div class="packages-score packages-score-like" data-package="oxygen">
<div class="packages-score-value -has-value">
<span class="packages-score-value-number">0</span>
<span class="packages-score-value-sign"></span>
Expand Down Expand Up @@ -284,7 +284,7 @@ <h3 class="packages-title pub-monochrome-icon-hoverable">
<b>%%x-ago%%</b>
</div>
<a class="packages-scores" href="/packages/neon/score">
<div class="packages-score packages-score-like">
<div class="packages-score packages-score-like" data-package="neon">
<div class="packages-score-value -has-value">
<span class="packages-score-value-number">0</span>
<span class="packages-score-value-sign"></span>
Expand Down
14 changes: 7 additions & 7 deletions app/test/frontend/golden/pkg_activity_log_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<script src="/static/hash-%%etag%%/js/script.dart.js" defer="defer"></script>
<script src="https://www.gstatic.com/brandstudio/kato/cookie_choice_component/cookie_consent_bar.v3.js" defer="defer" data-autoload-cookie-consent-bar="true"></script>
<meta name="csrf-token" content="%%csrf-token%%"/>
<meta name="pub-page-data" content="eyJwa2dEYXRhIjp7InBhY2thZ2UiOiJveHlnZW4iLCJ2ZXJzaW9uIjoiMS4yLjAiLCJsaWtlcyI6MCwiaXNEaXNjb250aW51ZWQiOmZhbHNlLCJpc0xhdGVzdCI6dHJ1ZX19"/>
<meta name="pub-page-data" content="eyJwa2dEYXRhIjp7InBhY2thZ2UiOiJveHlnZW4iLCJ2ZXJzaW9uIjoiMS4yLjAiLCJpc0Rpc2NvbnRpbnVlZCI6ZmFsc2UsImlzTGF0ZXN0Ijp0cnVlfX0="/>
<link rel="preload" href="/static/hash-%%etag%%/highlight/highlight-with-init.js" as="script"/>
</head>
<body class="light-theme">
Expand Down Expand Up @@ -185,13 +185,13 @@ <h1 class="title pub-monochrome-icon-hoverable">
<a class="tag-badge-sub" href="/packages?q=platform%3Awindows" rel="nofollow" title="Packages compatible with Windows platform">Windows</a>
</div>
</div>
<div class="detail-like">
<button id="-pub-like-icon-button" class="mdc-icon-button" data-ga-click-event="toggle-like" aria-pressed="false" title="Like this package">
<div class="like-button-and-label">
<button class="mdc-icon-button like-button-and-label--button" data-ga-click-event="toggle-like" aria-pressed="false" title="Like this package">
<img class="mdc-icon-button__icon" src="/static/hash-%%etag%%/img/like-inactive.svg" alt="liked status: inactive" width="18" height="18"/>
<img class="mdc-icon-button__icon mdc-icon-button__icon--on" src="/static/hash-%%etag%%/img/like-active.svg" alt="liked status: active" width="18" height="18"/>
</button>
<span class="likes-count">
<span id="likes-count">0</span>
<span class="like-button-and-label--count-wrapper">
<span class="like-button-and-label--count" data-package="oxygen" data-value="0">0</span>
</span>
</div>
</div>
Expand Down Expand Up @@ -359,7 +359,7 @@ <h3 class="detail-lead-title">Metadata</h3>
</div>
<aside class="detail-info-box">
<a class="packages-scores" href="/packages/oxygen/score">
<div class="packages-score packages-score-like">
<div class="packages-score packages-score-like" data-package="oxygen">
<div class="packages-score-value -has-value">
<span class="packages-score-value-number">0</span>
<span class="packages-score-value-sign"></span>
Expand Down Expand Up @@ -435,7 +435,7 @@ <h3 class="detail-metadata-title">
</h3>
<div class="detail-info-box">
<a class="packages-scores" href="/packages/oxygen/score">
<div class="packages-score packages-score-like">
<div class="packages-score packages-score-like" data-package="oxygen">
<div class="packages-score-value -has-value">
<span class="packages-score-value-number">0</span>
<span class="packages-score-value-sign"></span>
Expand Down
Loading