diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts
index 7317d03d..7ad8c450 100644
--- a/src/lib/components/inventory/selected_item_info.ts
+++ b/src/lib/components/inventory/selected_item_info.ts
@@ -18,6 +18,7 @@ import {Observe} from '../../utils/observers';
import {FetchStallResponse} from '../../bridge/handlers/fetch_stall';
import {gStallFetcher} from '../../services/stall_fetcher';
import {Contract} from '../../types/float_market';
+import '../../ui/floatbar';
/**
* Why do we bind to iteminfo0 AND iteminfo1?
@@ -101,6 +102,7 @@ export class SelectedItemInfo extends FloatElement {
const containerChildren: TemplateResult[] = [];
if (isSkin(this.asset.description) && this.itemInfo) {
+ containerChildren.push(this.renderFloatBar());
containerChildren.push(
html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
`
);
@@ -130,6 +132,17 @@ export class SelectedItemInfo extends FloatElement {
return html`
- Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
+ ${this.renderFloatBar()}
+
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
+
Paint Seed:
${formatSeed(this.itemInfo)}${fadePercentage !== undefined
? html`
@@ -178,4 +182,15 @@ export class ItemRowWrapper extends FloatElement {
return html`
Loading...
`;
}
}
+
+ renderFloatBar(): TemplateResult<1> {
+ if (!this.itemInfo) {
+ return html``;
+ }
+
+ return html`
+
+
+ `;
+ }
}
diff --git a/src/lib/ui/floatbar.ts b/src/lib/ui/floatbar.ts
new file mode 100644
index 00000000..2862282d
--- /dev/null
+++ b/src/lib/ui/floatbar.ts
@@ -0,0 +1,91 @@
+import {LitElement, html, css} from 'lit';
+import {customElement, property} from 'lit/decorators.js';
+
+@customElement('float-bar')
+export class FloatBar extends LitElement {
+ @property({type: Number}) float!: number;
+ @property({type: Number}) minFloat = 0;
+ @property({type: Number}) maxFloat = 1;
+
+ static styles = css`
+ .market-float-bar-container {
+ position: relative;
+ width: 100%;
+ height: 8px;
+ margin: 5px 0;
+ }
+
+ .market-float-bar-marker {
+ position: absolute;
+ background-color: #d9d9d9;
+ width: 3px;
+ top: -3px;
+ height: 14px;
+ border-radius: 4px;
+ }
+
+ .market-float-bar {
+ display: inline-block;
+ vertical-align: top;
+ height: 100%;
+ opacity: 0.8;
+ }
+
+ .market-float-bar:first-of-type {
+ border-radius: 4px 0 0 4px;
+ }
+ .market-float-bar:last-of-type {
+ border-radius: 0 4px 4px 0;
+ }
+ `;
+
+ private readonly floatConditions = [
+ {min: 0, max: 7, color: 'green'},
+ {min: 7, max: 15, color: '#18a518'},
+ {min: 15, max: 38, color: '#9acd32'},
+ {min: 38, max: 45, color: '#cd5c5c'},
+ {min: 45, max: 100, color: '#f92424'},
+ ];
+
+ get minFloatPercentage(): number {
+ return this.minFloat * 100;
+ }
+
+ get maxFloatPercentage(): number {
+ return this.maxFloat * 100;
+ }
+
+ render() {
+ const left = this.minFloatPercentage.toFixed(0);
+ const markerLeft = (((this.float - this.minFloat) * 100) / (this.maxFloat - this.minFloat)).toFixed(3);
+ const dynamicWidth = this.maxFloatPercentage - this.minFloatPercentage;
+
+ const getConditionWidth = (condMin: number, condMax: number) => {
+ return (
+ Math.max(
+ 0,
+ (Math.min(condMax, this.maxFloatPercentage) - Math.max(condMin, this.minFloatPercentage)) * 100
+ ) / dynamicWidth
+ );
+ };
+
+ return html`
+
+
+ ${this.floatConditions.map(
+ (cond) => html`
+
+ `
+ )}
+
+
+
+ `;
+ }
+}