Skip to content

Commit

Permalink
feat: added protondb ratings to hover boxes (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxgic1337 authored Jan 9, 2025
1 parent bac8d78 commit 9ec6bee
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "protonfox",
"version": "0.3.1",
"version": "0.4.0",
"description": "Extension that displays information about game compatibility with Proton on Steam.",
"type": "module",
"scripts": {
Expand Down
5 changes: 4 additions & 1 deletion src/game_page.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {createSpan, getGameID, getProtonDBRating, ProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";
import {createElement, getGameID, getProtonDBRating, ProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";
import {addStoreRatingBadge, addSystemRequirementsRating} from "./utils/store";
import './styles/steam.less'

/**
* Adds rating tags to the game page
*/
export function checkGamePage() {
const gameId = getGameID();

Expand Down
28 changes: 28 additions & 0 deletions src/hover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {createElement, getProtonDBRating, upperCase} from "./utils/utils";

/**
* Adds rating text to the hover box
*/
export function checkHover() {
const hoverDiv = document.getElementById('global_hover_content');
const mutationObserver = new window.MutationObserver(() => {
if (!hoverDiv) return
const games = hoverDiv.children;
for (const game of games) {
if (!game.id.startsWith('hover_app_')) continue;
const reviews = game.getElementsByClassName('hover_review_summary')[0]
const hasRating = reviews.getElementsByClassName('protonfox-rating-bright').length !== 0;
if (!hasRating) {
const gameId = game.id.substring('hover_app_'.length);
getProtonDBRating(gameId).then(async (rating) => {
const protonDBRatingTitle = createElement('ProtonDB rating: ', ['title'], 'div');
protonDBRatingTitle.appendChild(createElement(upperCase(rating), [`protonfox-rating-${rating}`, 'protonfox-rating-bright']))
reviews.prepend(protonDBRatingTitle)
})
}
}
});
if (hoverDiv) {
mutationObserver.observe(hoverDiv, {childList: true});
}
}
13 changes: 8 additions & 5 deletions src/search_page.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createSpan, getGameID, getProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";
import {createElement, getGameID, getProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";

export function checkSearchPage() {
const searchResults = document.getElementById('search_resultsRows');
Expand All @@ -11,15 +11,18 @@ export function checkSearchPage() {
}
}

/**
* Adds rating tags to the search results
*/
function checkSearchResults() {
const games = document.getElementsByClassName('search_result_row')
for (const game of games) {
if (game.getElementsByClassName('tag').length > 0) { continue; }
const name = game.getElementsByClassName('title')[0]
if (game.getElementsByClassName('protonfox-tag').length > 0) { continue; }
const name = game.getElementsByClassName('platform_img')[0].parentElement || game.getElementsByClassName('title')[0]
const gameId = getGameID(game.getAttribute('href') || "10");
getProtonDBRating(gameId).then(async (rating) => {
if (game.getElementsByClassName('tag').length > 0) { return; }
name.appendChild(createSpan(upperCase(rating), ['tag', rating, 'search']))
if (game.getElementsByClassName('protonfox-tag').length > 0) { return; }
name.prepend(createElement(upperCase(rating), ['protonfox-tag', `protonfox-rating-${rating}`, 'protonfox-search']))
})
}
}
14 changes: 12 additions & 2 deletions src/steam.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {checkGamePage} from "./game_page";
import {checkSearch} from "./store_search";
import {checkNavSearch} from "./store_search";
import {checkSearchPage} from "./search_page";
import {ProtonDBRating} from "./utils/utils";
import {checkHover} from "./hover";

export const ratings: {[key: string]: ProtonDBRating} = {}

Expand All @@ -12,4 +13,13 @@ if (window.location.href.startsWith('https://store.steampowered.com/search')) {
checkSearchPage()
}

checkSearch()
/* Check if the global hover div appeared */
const mutationObserver = new window.MutationObserver(()=> {
if (document.getElementById('global_hover')) {
checkHover()
mutationObserver.disconnect();
}
});
mutationObserver.observe(document.getElementsByTagName("body")[0], {childList: true, subtree: false});

checkNavSearch()
9 changes: 6 additions & 3 deletions src/store_search.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {createSpan, getGameID, getProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";
import {createElement, getGameID, getProtonDBRating, ProtonDBSummary, upperCase} from "./utils/utils";

export function checkSearch() {
/**
* Adds rating tags to the search results in the navbar
*/
export function checkNavSearch() {
const searchResults = document.getElementById('search_suggestion_contents');
const mutationObserver = new window.MutationObserver(()=>{
const games = document.getElementsByClassName('match_app')
for (const game of games) {
const name = game.getElementsByClassName('match_name')[0]
const gameId = getGameID(game.getAttribute('href') || "10");
getProtonDBRating(gameId).then(async (rating) => {
name.appendChild(createSpan(upperCase(rating), ['tag', rating]))
name.appendChild(createElement(upperCase(rating), ['protonfox-tag', `protonfox-rating-${rating}`]))
})
}
});
Expand Down
33 changes: 19 additions & 14 deletions src/styles/steam.less
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@bronze: rgb(205, 127, 50);
@borked: rgb(255, 80, 80);

.badge {
.protonfox-badge {
padding: 1px;
cursor: pointer;
display: inline-block;
Expand All @@ -21,10 +21,14 @@
}
}

.rating(@color) {
.protonfox-rating-mixin(@color) {
color: @color;

&.badge {
&.protonfox-rating-bright {
color: lighten(@color, 15%);
}

&.protonfox-badge {
background-color: fade(@color, 20%) !important;

&:hover {
Expand All @@ -33,22 +37,23 @@
}
}

&.tag {
&.protonfox-tag {
background-color: fade(@color, 20%) !important;

&.search {
&.protonfox-search {
position: relative;
top: -5px;
padding: 0 6px;
border-radius: 4px;
margin-left: 6px;
}
}
}

.native { .rating(@native) }
.unknown { .rating(@unknown) }
.pending { .rating(@pending) }
.platinum { .rating(@platinum) }
.gold { .rating(@gold) }
.silver { .rating(@silver) }
.bronze { .rating(@bronze) }
.borked { .rating(@borked) }
.protonfox-rating-native { .protonfox-rating-mixin(@native) }
.protonfox-rating-unknown { .protonfox-rating-mixin(@unknown) }
.protonfox-rating-pending { .protonfox-rating-mixin(@pending) }
.protonfox-rating-platinum { .protonfox-rating-mixin(@platinum) }
.protonfox-rating-gold { .protonfox-rating-mixin(@gold) }
.protonfox-rating-silver { .protonfox-rating-mixin(@silver) }
.protonfox-rating-bronze { .protonfox-rating-mixin(@bronze) }
.protonfox-rating-borked { .protonfox-rating-mixin(@borked) }
10 changes: 5 additions & 5 deletions src/utils/store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {createSpan, ProtonDBRating, upperCase} from "./utils";
import {createElement, ProtonDBRating, upperCase} from "./utils";

export function addStoreRatingBadge(gameId: string, rating: ProtonDBRating) {
const appInfo = document.getElementsByClassName('apphub_OtherSiteInfo')[0]
const element = document.createElement("a");
element.appendChild(rating === ProtonDBRating.NATIVE ? createSpan("Native") : createSpan("ProtonDB: " + upperCase(rating)));
element.appendChild(rating === ProtonDBRating.NATIVE ? createElement("Native") : createElement("ProtonDB: " + upperCase(rating)));

element.classList.add('badge')
element.classList.add(rating)
element.classList.add('protonfox-badge')
element.classList.add(`protonfox-rating-${rating}`)
element.classList.add('btn_medium')

element.href = `https://protondb.com/app/${gameId}`
Expand All @@ -22,7 +22,7 @@ export function addSystemRequirementsRating(gameId: string, rating: ProtonDBRati
element.href = `https://protondb.com/app/${gameId}`
element.target = '_blank'

element.classList.add(rating)
element.classList.add(`protonfox-rating-${rating}`)
element.style.fontSize = '12px'
element.style.marginBottom = '6px'
element.style.fontWeight = 'bold'
Expand Down
4 changes: 2 additions & 2 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export interface ProtonDBSummary {
tier: ProtonDBRating
}

export function createSpan(text: string, classes?: string[]) {
const element = document.createElement("span");
export function createElement(text: string, classes?: string[], elementName?: string) {
const element = document.createElement(elementName || "span");

if (classes) {
for (const prop of classes) {
Expand Down

0 comments on commit 9ec6bee

Please sign in to comment.