Skip to content

Commit ed85db9

Browse files
committed
chore: make ratings request on client side
1 parent 479b955 commit ed85db9

7 files changed

Lines changed: 324 additions & 152 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
interface RatingsData {
2+
snap_id: string;
3+
total_votes: number;
4+
ratings_band: string;
5+
}
6+
7+
async function fetchSnapRatings(snapId: string): Promise<RatingsData | null> {
8+
try {
9+
const response = await fetch(`/api/snap/${snapId}/ratings`);
10+
11+
if (!response.ok) {
12+
console.error(
13+
`Failed to fetch ratings for snap ${snapId}:`,
14+
response.status,
15+
);
16+
return null;
17+
}
18+
19+
const data = await response.json();
20+
21+
return data;
22+
} catch (error) {
23+
console.error(`Error fetching ratings for snap ${snapId}:`, error);
24+
return null;
25+
}
26+
}
27+
28+
function renderRatingsInfo(
29+
ratingsData: RatingsData | null,
30+
containerSelector: string,
31+
): void {
32+
const container = document.querySelector(containerSelector) as HTMLElement;
33+
34+
if (!container) {
35+
return;
36+
}
37+
38+
if (!ratingsData) {
39+
return;
40+
}
41+
42+
const ratingsBand = ratingsData.ratings_band;
43+
let icon = "";
44+
let text = "";
45+
46+
switch (ratingsBand) {
47+
case "very-good":
48+
icon = "p-icon--thumbs-up";
49+
text = "Very good";
50+
break;
51+
case "good":
52+
icon = "p-icon--thumbs-up";
53+
text = "Good";
54+
break;
55+
case "neutral":
56+
icon = "p-icon--minus";
57+
text = "Neutral";
58+
break;
59+
case "poor":
60+
icon = "p-icon--thumbs-down";
61+
text = "Poor";
62+
break;
63+
case "very-poor":
64+
icon = "p-icon--thumbs-down";
65+
text = "Very poor";
66+
break;
67+
default:
68+
return;
69+
}
70+
71+
const title = text.charAt(0).toUpperCase() + text.slice(1) + " rating";
72+
const html = `
73+
<span class="p-snap-ratings">
74+
<span title="${title}"><i class="${icon}"></i> ${text}</span>
75+
<span> (${ratingsData.total_votes} votes)</span>
76+
</span>
77+
`;
78+
79+
const list = document.querySelector(containerSelector);
80+
if (list) {
81+
const li = document.createElement("li");
82+
li.className = "p-inline-list__item";
83+
li.innerHTML = html;
84+
list.appendChild(li);
85+
}
86+
}
87+
88+
export default function initSnapRatings(
89+
snapId: string,
90+
containerSelectors: string[],
91+
): void {
92+
if (!snapId) {
93+
return;
94+
}
95+
96+
fetchSnapRatings(snapId).then((ratingsData) => {
97+
containerSelectors.forEach((selector) => {
98+
renderRatingsInfo(ratingsData, selector);
99+
});
100+
});
101+
}
102+
103+
export { fetchSnapRatings, renderRatingsInfo, RatingsData };

static/js/public/store-details.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import initEmbeddedCardModal from "./snap-details/embeddedCard";
77
import { snapDetailsPosts } from "./snap-details/blog-posts";
88
import initExpandableArea from "./expandable-area";
99
import initCopyCommand from "./snap-details/copyCommand";
10+
import initSnapRatings from "./snap-details/ratings";
1011
import declareGlobal from "../libs/declare";
1112
import { trackPageView } from "@canonical/analytics-events";
1213

@@ -25,4 +26,5 @@ declareGlobal("snapcraft.public.storeDetails", {
2526
initExpandableArea,
2627
initReportSnap,
2728
videos,
29+
initSnapRatings,
2830
});

templates/store/package_header/_package_header_data.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ <h1 class="u-sv-1" data-live="title">{{ package_title }}</h1>
4747
{{ developer_info(name=developer[0], url=developer[1]) }}
4848
{% endif %}
4949
{{ publisher_info(publisher, username, developer_validation, display_name, VERIFIED_PUBLISHER, STAR_DEVELOPER) }}
50-
{{ ratings_info(ratings) }}
5150
</div>
52-
<ul class="p-inline-list--vertical-divider">
51+
<ul class="p-inline-list--vertical-divider" id="js-snap-details-list">
5352
{% if developer %}
5453
<li class="p-inline-list__item u-hide--small">{{ developer_info(name=developer[0], url=developer[1]) }}</li>
5554
{% endif %}
@@ -59,9 +58,6 @@ <h1 class="u-sv-1" data-live="title">{{ package_title }}</h1>
5958
<a href="/search?categories={{ category.slug }}">{{ category.name }}</a>
6059
</li>
6160
{% endfor %}
62-
{% if ratings and ratings.total_votes > 0 %}
63-
<li class="p-inline-list__item u-hide--small">{{ ratings_info(ratings) }}</li>
64-
{% endif %}
6561
</ul>
6662
</div>
6763
{%- endmacro -%}

templates/store/snap-details.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ <h5 class="p-notification__title">Error</h5>
368368
Sentry.captureException(e);
369369
}
370370

371+
try {
372+
snapcraft.public.storeDetails.initSnapRatings('{{ snap_id }}', ['#js-snap-details-list']);
373+
} catch(e) {
374+
Sentry.captureException(e);
375+
}
376+
371377
{% if not is_preview %}
372378
try {
373379
snapcraft.public.storeDetails.initReportSnap(

0 commit comments

Comments
 (0)