Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
GODrums authored Oct 19, 2023
2 parents 2a4eea8 + 9907fa3 commit d1e5042
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 35 deletions.
41 changes: 41 additions & 0 deletions css/csfloat_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,45 @@ button.betterfloat-top-button:hover {
.bf-table td, .bf-table th {
text-align: center!important;
padding: 0px 10px;
}

.bf-fade {
font-weight: 600;
font-size: 20px;
transition: all .2s ease-in-out;
padding: 2px;
border-radius: 7px;
display: flex;
align-items: center;
justify-content: center;
background-size: 170%;
}

.bf-fade-tooltip {
/* Positioning the tooltip text */
position: absolute;
z-index: 1;
translate: 0 40px;

display: flex;
flex-direction: column;
visibility: hidden;
color: #fff;
text-align: center;
background-color: #5c5c5c;
padding: 5px 3px;
border-radius: 5px;
font-size: 12px;
font-weight: 400;
width: 100px;

/* Fade in tooltip */
opacity: 0;
transition: opacity 0.1s;
}

.bf-fade:hover .bf-fade-tooltip {
visibility: visible;
opacity: 1;
transition: visibility 0s, opacity 0.2s linear;
}
12 changes: 12 additions & 0 deletions html/changelog.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<div class="Group">
<div class="VersionHeader">1.10.1</div>
<div class="VersionBox">
<p class="VersionSubHeader">
What's new?
</p>
<ul class="VersionText">
<li><b>FEATURE:</b> Both Acid and Amber Fade skins now display a fade badge, similar to CSFloat's Fade skins. This badge displays both the fade percentage as well as their ranking from 1 to 500 best/worst fade. For more details, refer to chescos's csgo-fade-percentage-calculator on Github.</li>
<li><b>BUG-FIX:</b> Fixed a bug where the newly introduced "Buff Pattern"-tab made it impossible to switch back to the table or graph.</li>
</ul>
</div>
</div>
<div class="Group">
<div class="VersionHeader">1.10.0</div>
<div class="VersionBox">
Expand Down
6 changes: 3 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "BetterFloat",
"author": "Rums",
"version": "1.10.0",
"version_name": "1.10.0",
"version": "1.10.1",
"version_name": "1.10.1",
"description": "Enhance your experience on CSFloat.com, Skinport.com & Skinbid.com!",
"manifest_version": 3,
"host_permissions": ["*://prices.csgotrader.app/*", "*://*.csfloat.com/*", "*://*.skinport.com/*", "*://*.skinbid.com/*"],
Expand Down Expand Up @@ -49,7 +49,7 @@
},
{
"matches": ["https://csfloat.com/*"],
"resources": ["public/clock-solid.svg", "public/chevron-up-solid.svg", "public/arrow-up-right-from-square-solid.svg", "public/gear-solid.svg", "public/icon-diamond.svg"]
"resources": ["public/clock-solid.svg", "public/chevron-up-solid.svg", "public/arrow-up-right-from-square-solid.svg", "public/gear-solid.svg", "public/icon-diamond.svg", "public/ban-solid.svg"]
},
{
"matches": ["*://*.skinport.com/*"],
Expand Down
2 changes: 1 addition & 1 deletion manifest_firefox.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "BetterFloat",
"author": "Rums",
"version": "1.10.0",
"version": "1.10.1",
"description": "Enhance your experience on CSFloat.com, Skinport.com & Skinbid.com!",
"manifest_version": 3,
"host_permissions": ["*://prices.csgotrader.app/*", "*://*.csfloat.com/*", "*://*.skinport.com/*", "*://*.skinbid.com/*"],
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"dependencies": {
"@babel/runtime": "^7.18.6",
"csgo-fade-percentage-calculator": "^1.1.3",
"rimraf": "^5.0.5"
}
}
1 change: 1 addition & 0 deletions public/ban-solid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/@typings/ExtensionTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,9 @@ export namespace BlueGem {

export type Response = [PatternElement, PastSale[]] | [PastSale[]];
}

export interface FadePercentage {
seed: number,
percentage: number,
ranking: number,
}
1 change: 1 addition & 0 deletions src/@typings/SkinportTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export namespace Skinport {
style: ItemStyle;
wear: number;
wear_name: string;
currency: string;
};

export type Item = {
Expand Down
68 changes: 59 additions & 9 deletions src/csfloat/content_script.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Official documentation: https://developer.chrome.com/docs/extensions/mv3/content_scripts/

import { CSFloat, ItemStyle, ItemCondition } from '../@typings/FloatTypes';
import { BlueGem, Extension } from '../@typings/ExtensionTypes';
import { BlueGem, Extension, FadePercentage } from '../@typings/ExtensionTypes';
import { activateHandler } from '../eventhandler';
import { getBuffMapping, getCSFPopupItem, getFirstCSFItem, getFirstHistorySale, getItemPrice, getPriceMapping, getStallData, getWholeHistory, loadBuffMapping, loadMapping } from '../mappinghandler';
import { initSettings } from '../util/extensionsettings';
import { calculateTime, getSPBackgroundColor, handleSpecialStickerNames, parseHTMLString, waitForElement } from '../util/helperfunctions';
import { genRefreshButton } from '../util/uigeneration';
import { AmberFadeCalculator, AcidFadeCalculator } from 'csgo-fade-percentage-calculator';

type PriceResult = {
price_difference: number;
Expand Down Expand Up @@ -630,10 +631,10 @@ async function adjustItem(container: Element, isPopout = false) {
storeApiItem(container, cachedItem);

if (extensionSettings.csBlueGem) {
caseHardenedDetection(container, cachedItem, false);
await caseHardenedDetection(container, cachedItem, false);
}
}
if (isPopout) {
await addFadePercentages(container, cachedItem);
} else if (isPopout) {
// need timeout as request is only sent after popout is loaded
setTimeout(async () => {
await addItemHistory(container.parentElement!.parentElement!);
Expand All @@ -649,11 +650,53 @@ async function adjustItem(container: Element, isPopout = false) {
await addStickerInfo(container, apiItem, priceResult.price_difference);
await addListingAge(container, apiItem);
await caseHardenedDetection(container, apiItem, true);
await addFadePercentages(container, apiItem);
}
}, 500);
}
}

async function addFadePercentages(container: Element, item: CSFloat.ListingData) {
const itemName = item.item.item_name;
const paintSeed = item.item.paint_seed;
if (!itemName.includes('Fade')) return;
const weapon = itemName.split(' | ')[0];
let fadePercentage: FadePercentage & {background: string} | null = null;
if (itemName.includes('Amber Fade')) {
fadePercentage = {...AmberFadeCalculator.getFadePercentage(weapon, paintSeed), background: 'linear-gradient(to right,#627d66,#896944,#3b2814)'};
} else if (itemName.includes('Acid Fade')) {
fadePercentage = {...AcidFadeCalculator.getFadePercentage(weapon, paintSeed), background: 'linear-gradient(to right,#6d5f55,#76c788, #574828)'};
}
if (fadePercentage != null) {
let fadeTooltip = document.createElement('div');
fadeTooltip.className = 'bf-fade-tooltip';
let fadePercentageSpan = document.createElement('span');
fadePercentageSpan.textContent = `Fade: ${fadePercentage.percentage.toFixed(5)}%`;
let fadeRankingSpan = document.createElement('span');
fadeRankingSpan.textContent = `Rank #${fadePercentage.ranking}`;
fadeTooltip.appendChild(fadePercentageSpan);
fadeTooltip.appendChild(fadeRankingSpan);
let fadeBadge = document.createElement('div');
fadeBadge.className = 'bf-fade';
fadeBadge.setAttribute('style', `background-position-x: 10.7842%; background-image: ${fadePercentage.background};`);
let fadeBadgePercentageSpan = document.createElement('span');
fadeBadgePercentageSpan.style.color = '#00000080';
fadeBadgePercentageSpan.textContent = fadePercentage.percentage.toFixed(1);
fadeBadge.appendChild(fadeBadgePercentageSpan);
fadeBadge.appendChild(fadeTooltip);
let badgeContainer = container.querySelector('.badge-container');
if (!badgeContainer) {
badgeContainer = document.createElement('div');
badgeContainer.setAttribute('style', 'position: absolute; top: 5px; left: 5px;');
container.querySelector('.item-img')?.after(badgeContainer);
} else {
badgeContainer = badgeContainer.querySelector('.container') ?? badgeContainer;
badgeContainer.setAttribute('style', 'gap: 5px;');
}
badgeContainer.appendChild(fadeBadge);
}
}

async function caseHardenedDetection(container: Element, listing: CSFloat.ListingData, isPopout: boolean) {
const item = listing.item;
if (!item.item_name.includes('Case Hardened')) return;
Expand All @@ -665,6 +708,7 @@ async function caseHardenedDetection(container: Element, listing: CSFloat.Listin
} else {
type = item.item_name.split(' | ')[0];
}
// retrieve the stored data instead of fetching newly
if (isPopout) {
const itemPreview = document.getElementsByClassName('item-' + location.pathname.split('/').pop())[0];
const csbluegem = itemPreview?.getAttribute('data-csbluegem');
Expand All @@ -674,6 +718,7 @@ async function caseHardenedDetection(container: Element, listing: CSFloat.Listin
patternElement = csbluegemData.patternElement;
}
}
// if there is no cached data, fetch it and store it
if (pastSales.length == 0 && !patternElement) {
await fetchCSBlueGem(type, item.paint_seed).then((data) => {
pastSales = data.pastSales;
Expand Down Expand Up @@ -759,17 +804,23 @@ async function caseHardenedDetection(container: Element, listing: CSFloat.Listin
sale.price * 0.14
).toFixed(0)})</td><td role="cell" mat-cell class="mat-cell cdk-cell ng-star-inserted">${sale.float}</td><td role="cell" mat-cell class="mat-cell cdk-cell ng-star-inserted">${
sale.pattern
}</td><td role="cell" mat-cell class="mat-cell cdk-cell ng-star-inserted"><a href=${
sale.url
} target="_blank"><i _ngcontent-mua-c199="" class="material-icons" style="translate: 0px 3px;">camera_alt</i></a></td></tr>`;
}</td><td role="cell" mat-cell class="mat-cell cdk-cell ng-star-inserted"><a ${
sale.url == 'No Link Available'
? 'style="pointer-events: none;cursor: default;"><img src="' +
runtimePublicURL +
'/ban-solid.svg" style="height: 20px; translate: 0px 3px; filter: brightness(0) saturate(100%) invert(11%) sepia(8%) saturate(633%) hue-rotate(325deg) brightness(95%) contrast(89%);"> </img>'
: 'href=' + sale.url + 'target="_blank"><i _ngcontent-mua-c199="" class="material-icons" style="translate: 0px 3px;">camera_alt</i></a>'
}</td></tr>`;
});
let tableHTML = `<div style="max-height: 260px;overflow: auto;background-color: #424242;"><table class="mat-table cdk-table bf-table" role="table" style="width: 100%;"><thead role="rowgroup"><tr class="mat-header-row cdk-header-row ng-star-inserted"><th role="columnheader" mat-header-cell class="mat-header-cell cdk-header-cell ng-star-inserted">Date</th><th role="columnheader" mat-header-cell class="mat-header-cell cdk-header-cell ng-star-inserted">Price</th><th role="columnheader" mat-header-cell class="mat-header-cell cdk-header-cell ng-star-inserted">Float Value</th><th role="columnheader" mat-header-cell class="mat-header-cell cdk-header-cell ng-star-inserted">Paint Seed</th><th role="columnheader" mat-header-cell class="mat-header-cell cdk-header-cell ng-star-inserted"><a href="https://csbluegem.com/search?skin=${type}&pattern=${
item.paint_seed
}&currency=CNY&filter=date&sort=descending" target="_blank"><img src="${
runtimePublicURL + '/arrow-up-right-from-square-solid.svg'
}" style="height: 18px; filter: brightness(0) saturate(100%) invert(100%) sepia(0%) saturate(7461%) hue-rotate(14deg) brightness(94%) contrast(106%);"></a></th></tr></thead><tbody>${tableBody}</tbody></table></div>`;

const historyComponent = gridHistory?.querySelector('.history-component');

// has to be the first child as they are associated with the tab change listeners
const historyComponent = gridHistory?.querySelector('.history-component')?.firstElementChild;
if (historyComponent) {
historyComponent.innerHTML = tableHTML;
}
Expand Down Expand Up @@ -802,7 +853,6 @@ function adjustExistingSP(container: Element) {
}
const backgroundImageColor = getSPBackgroundColor(Number(spValue) / 100);
(<HTMLElement>spContainer).style.backgroundColor = backgroundImageColor;
(<HTMLElement>spContainer).style.marginBottom = '5px';
}

function storeApiItem(container: Element, item: CSFloat.ListingData) {
Expand Down
36 changes: 14 additions & 22 deletions src/skinport/content_script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,9 @@ async function adjustItemPage(container: Element) {
newGroup.appendChild(buffButton);
btnGroup.after(newGroup);

const tooltipLink = container.querySelector('.ItemPage-value .Tooltip-link');
if (!tooltipLink) return;
const currencySymbol = getCurrencySymbol(tooltipLink);
const suggestedContainer = container.querySelector('.ItemPage-suggested');
if (suggestedContainer) {
generateBuffContainer(suggestedContainer as HTMLElement, priceListing, priceOrder, currencySymbol ?? '$', true);
generateBuffContainer(suggestedContainer as HTMLElement, priceListing, priceOrder, item.currency, true);
}
// HERE
const buffContainer = container.querySelector('.betterfloat-buff-container');
Expand All @@ -415,7 +412,7 @@ async function adjustItemPage(container: Element) {
newContainer.style.paddingTop = '2px';
saleTag.style.margin = '5px';
saleTag.style.fontWeight = '700';
saleTag.textContent = difference == 0 ? `-${currencySymbol}0` : (difference > 0 ? '+' : '-') + currencySymbol + Math.abs(difference).toFixed(2);
saleTag.textContent = difference == 0 ? `-${item.currency}0` : (difference > 0 ? '+' : '-') + item.currency + Math.abs(difference).toFixed(2);
newContainer.appendChild(saleTag);
priceContainer.appendChild(newContainer);
}
Expand Down Expand Up @@ -541,17 +538,21 @@ function getSkinportItem(container: Element, selector: ItemSelectors): Skinport.
return null;
}

let priceText = container.querySelector(selector.price + ' .Tooltip-link')?.textContent ?? '';
let priceText = container.querySelector(selector.price + ' .Tooltip-link')?.textContent?.trim() ?? '';
let currency = '';
if (priceText.split(' ').length > 1) {
priceText = priceText.split(' ')[0].replace('.', '').replace(',', '.');
let parts = priceText.replace(',', '').replace('.', '').split(' ');
priceText = String(Number(parts.filter((x) => !isNaN(+x))[0]) / 100);
currency = parts.filter((x) => isNaN(+x))[0];
} else {
priceText = priceText.replace(',', '').substring(1);
currency = priceText.charAt(0);
priceText = String(Number(priceText.replace(',', '').replace('.', '').substring(1)) / 100);
}
let price = Number(priceText) ?? 0;

const type = container.querySelector(selector.title)?.textContent ?? '';
const text = container.querySelector(selector.text)?.innerHTML ?? '';
// Skinport uses more detailed item types than Buff163, they are called cateogiories here
// Skinport uses more detailed item types than Buff163, they are called categories here
const lastWord = text.split(' ').pop() ?? '';
let category = '';
if (lastWord == 'Knife' || lastWord == 'Gloves' || lastWord == 'Agent') {
Expand Down Expand Up @@ -612,6 +613,7 @@ function getSkinportItem(container: Element, selector: ItemSelectors): Skinport.
style: style,
wear: Number(wearDiv?.innerHTML),
wear_name: wear,
currency: currency,
};
}

Expand Down Expand Up @@ -704,25 +706,15 @@ async function generateBuffContainer(container: HTMLElement, priceListing: numbe
}
}

function getCurrencySymbol(tooltipLink: Element) {
let currencySymbol = tooltipLink.textContent?.charAt(0);
if (!isNaN(+(currencySymbol ?? ''))) {
// in some instances skinport displays the currency at the end of the price
currencySymbol = tooltipLink.textContent?.charAt(tooltipLink.textContent?.length - 1);
}
return currencySymbol;
}

async function addBuffPrice(item: Skinport.Listing, container: Element) {
await loadMapping();
const { buff_name, priceListing, priceOrder } = await getBuffPrice(item);
const buff_id = await getBuffMapping(buff_name);

const tooltipLink = <HTMLElement>container.querySelector('.ItemPreview-priceValue')?.firstChild;
const currencySymbol = getCurrencySymbol(tooltipLink);
const priceDiv = container.querySelector('.ItemPreview-oldPrice');
if (priceDiv && !container.querySelector('.betterfloat-buffprice')) {
generateBuffContainer(priceDiv as HTMLElement, priceListing, priceOrder, currencySymbol ?? '$');
generateBuffContainer(priceDiv as HTMLElement, priceListing, priceOrder, item.currency);
}

const buffHref = buff_id > 0 ? `https://buff.163.com/goods/${buff_id}` : `https://buff.163.com/market/csgo#tab=selling&page_num=1&search=${encodeURIComponent(buff_name)}`;
Expand Down Expand Up @@ -761,10 +753,10 @@ async function addBuffPrice(item: Skinport.Listing, container: Element) {
container.querySelector('.ItemPreview-priceValue')?.appendChild(discountContainer);
}
const saleTag = <HTMLElement>discountContainer.firstChild;
if (item.price !== 0 && saleTag && tooltipLink && !discountContainer.querySelector('.betterfloat-sale-tag')) {
if (item.price !== 0 && !isNaN(item.price) && saleTag && tooltipLink && !discountContainer.querySelector('.betterfloat-sale-tag')) {
saleTag.className = 'sale-tag betterfloat-sale-tag';
discountContainer.style.background = `linear-gradient(135deg,#0073d5,${difference == 0 ? extensionSettings.colors.skinport.neutral : difference < 0 ? extensionSettings.colors.skinport.profit : extensionSettings.colors.skinport.loss})`;
saleTag.textContent = difference == 0 ? `-${currencySymbol}0` : (difference > 0 ? '+' : '-') + currencySymbol + Math.abs(difference).toFixed(2);
saleTag.textContent = difference == 0 ? `-${item.currency}0` : (difference > 0 ? '+' : '-') + item.currency + Math.abs(difference).toFixed(2);
}
} else {
if (container.querySelector('.sale-tag')) {
Expand Down

0 comments on commit d1e5042

Please sign in to comment.