Skip to content
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

ui: fix a number of minor ui issues #2968

Merged
merged 2 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 7 additions & 9 deletions client/webserver/site/src/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1052,21 +1052,19 @@ export default class Application {

// Updates given order in market's orders list if it finds it.
// Returns a bool which indicates if order was found.
mkt.orders = mkt.orders || []
const updateOrder = (mkt: Market, ord: Order) => {
for (const i in mkt.orders || []) {
if (mkt.orders[i].id === ord.id) {
mkt.orders[i] = ord
return true
}
}
return false
const i = mkt.orders.findIndex((o: Order) => o.id === ord.id)
if (i === -1) return false
if (note.topic === 'OrderRetired') mkt.orders.splice(i, 1)
else mkt.orders[i] = ord
return true
}
// If the notification order already exists we update it.
// In case market's orders list is empty or the notification order isn't
// part of it we add it manually as this means the order was
// just placed.
if (!mkt.orders) mkt.orders = [order]
else if (!updateOrder(mkt, order)) mkt.orders.push(order)
if (!updateOrder(mkt, order)) mkt.orders.push(order)
break
}
case 'balance': {
Expand Down
75 changes: 38 additions & 37 deletions client/webserver/site/src/js/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,21 @@ export class CandleChart extends Chart {
}
this.dataExtents = dataExtents

let mouseCandle: Candle | null = null
if (mousePos) {
this.plotRegion.plot(new Extents(dataExtents.x.min, dataExtents.x.max, 0, 1), (ctx, tools) => {
const selectedStartStamp = truncate(tools.unx(mousePos.x), candleWidth)
for (const c of candles) {
if (start(c) === selectedStartStamp) {
mouseCandle = c
ctx.fillStyle = this.theme.gridLines
ctx.fillRect(tools.x(start(c)), tools.y(0), tools.w(candleWidth), tools.h(1))
break
}
}
})
}

// Draw the grid
const rFactor = this.rateConversionFactor
const baseUnit = app().assets[this.market.baseid]?.unitInfo.conventional.unit || this.market.basesymbol.toUpperCase()
Expand Down Expand Up @@ -987,44 +1002,30 @@ export class CandleChart extends Chart {
this.plotYLabels(yLabels, this.dataExtents.y.min, this.dataExtents.y.max, baseUnit)

// Highlight the candle if the user mouse is over the canvas.
let mouseCandle: Candle | null = null
if (mousePos) {
this.plotRegion.plot(new Extents(dataExtents.x.min, dataExtents.x.max, 0, 1), (ctx, tools) => {
const selectedStartStamp = truncate(tools.unx(mousePos.x), candleWidth)
for (const c of candles) {
if (start(c) === selectedStartStamp) {
mouseCandle = c
ctx.fillStyle = this.theme.gridLines
ctx.fillRect(tools.x(start(c)), tools.y(0), tools.w(candleWidth), tools.h(1))
break
}
}
if (mouseCandle) {
const yExt = this.xRegion.extents.y
this.xRegion.plot(new Extents(dataExtents.x.min, dataExtents.x.max, yExt.min, yExt.max), (ctx, tools) => {
if (!mouseCandle) return // For TypeScript. Duh.
this.applyLabelStyle()
const rangeTxt = `${new Date(start(mouseCandle)).toLocaleString()} - ${new Date(end(mouseCandle)).toLocaleString()}`
const [xPad, yPad] = [25, 2]
const rangeWidth = ctx.measureText(rangeTxt).width + 2 * xPad
const rangeHeight = 16
let centerX = tools.x((start(mouseCandle) + end(mouseCandle)) / 2)
let left = centerX - rangeWidth / 2
const xExt = this.xRegion.extents.x
if (left < xExt.min) left = xExt.min
else if (left + rangeWidth > xExt.max) left = xExt.max - rangeWidth
centerX = left + rangeWidth / 2
const top = yExt.min + (this.xRegion.height() - rangeHeight) / 2
ctx.fillStyle = this.theme.legendFill
ctx.strokeStyle = this.theme.gridBorder
const rectArgs: [number, number, number, number] = [left - xPad, top - yPad, rangeWidth + 2 * xPad, rangeHeight + 2 * yPad]
ctx.fillRect(...rectArgs)
ctx.strokeRect(...rectArgs)
this.applyLabelStyle()
ctx.fillText(rangeTxt, centerX, this.xRegion.extents.midY, rangeWidth)
})
if (mouseCandle) {
const yExt = this.xRegion.extents.y
this.xRegion.plot(new Extents(dataExtents.x.min, dataExtents.x.max, yExt.min, yExt.max), (ctx, tools) => {
if (!mouseCandle) return // For TypeScript. Duh.
this.applyLabelStyle()
const rangeTxt = `${new Date(start(mouseCandle)).toLocaleString()} - ${new Date(end(mouseCandle)).toLocaleString()}`
const [xPad, yPad] = [25, 2]
const rangeWidth = ctx.measureText(rangeTxt).width + 2 * xPad
const rangeHeight = 16
let centerX = tools.x((start(mouseCandle) + end(mouseCandle)) / 2)
let left = centerX - rangeWidth / 2
const xExt = this.xRegion.extents.x
if (left < xExt.min) left = xExt.min
else if (left + rangeWidth > xExt.max) left = xExt.max - rangeWidth
centerX = left + rangeWidth / 2
const top = yExt.min + (this.xRegion.height() - rangeHeight) / 2
ctx.fillStyle = this.theme.legendFill
ctx.strokeStyle = this.theme.gridBorder
const rectArgs: [number, number, number, number] = [left - xPad, top - yPad, rangeWidth + 2 * xPad, rangeHeight + 2 * yPad]
ctx.fillRect(...rectArgs)
ctx.strokeRect(...rectArgs)
this.applyLabelStyle()
ctx.fillText(rangeTxt, centerX, this.xRegion.extents.midY, rangeWidth)
})
}
}

// Report the mouse candle.
Expand Down
29 changes: 19 additions & 10 deletions client/webserver/site/src/js/markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ import {
MatchNote,
ApprovalStatus,
OrderFilter,
RunStatsNote
RunStatsNote,
RunEventNote
} from './registry'
import { setOptionTemplates } from './opts'
import { RunningMarketMakerDisplay } from './mmutil'
Expand Down Expand Up @@ -128,6 +129,7 @@ interface CurrentMarket {
baseCfg: Asset
quoteCfg: Asset
rateConversionFactor: number
bookLoaded: boolean
}

interface LoadTracker {
Expand Down Expand Up @@ -270,7 +272,7 @@ export default class MarketsPage extends BasePage {
this.depositAddrForm = new DepositAddress(page.deposit)
}

this.mm = new RunningMarketMakerDisplay(page.mmRunning)
this.mm = new RunningMarketMakerDisplay(page.mmRunning, 'markets')

this.reputationMeter = new ReputationMeter(page.reputationMeter)

Expand Down Expand Up @@ -522,7 +524,10 @@ export default class MarketsPage extends BasePage {
this.resolveOrderFormVisibility()
}
},
runevent: (/* note: RunEventNote */) => { this.mm.update() }
runevent: (note: RunEventNote) => {
if (note.baseID !== this.market.base.id || note.quoteID !== this.market.quote.id || note.host !== this.market.dex.host) return
this.mm.update()
}
})

this.loadingAnimations = {}
Expand Down Expand Up @@ -1131,7 +1136,8 @@ export default class MarketsPage extends BasePage {
quoteCfg,
rateConversionFactor,
sellBalance: 0,
buyBalance: 0
buyBalance: 0,
bookLoaded: false
}

this.market = mkt
Expand Down Expand Up @@ -1854,9 +1860,10 @@ export default class MarketsPage extends BasePage {
handleBookRoute (note: BookUpdate) {
app().log('book', 'handleBookRoute:', note)
const mktBook = note.payload
const { baseCfg: b, quoteCfg: q } = this.market
if (mktBook.base !== b.id || mktBook.quote !== q.id) return // user already changed markets
const { baseCfg: b, quoteCfg: q, dex: { host } } = this.market
if (mktBook.base !== b.id || mktBook.quote !== q.id || note.host !== host) return // user already changed markets
this.handleBook(mktBook)
this.market.bookLoaded = true
this.updateTitle()
this.setMarketBuyOrderEstimate()
}
Expand Down Expand Up @@ -2477,7 +2484,7 @@ export default class MarketsPage extends BasePage {
const conversionRate = this.anyRate()[1]
if (conversionRate) {
const quoteLot = mkt.lotsize * conversionRate
page.marketLimitQuote.textContent = Doc.formatFourSigFigs(quoteLot / qui.conventional.conversionFactor)
page.marketLimitQuote.textContent = Doc.formatFourSigFigs(mkt.parcelsize * quoteLot / qui.conventional.conversionFactor)
} else page.marketLimitQuote.textContent = '-'

const tier = strongTier(auth)
Expand All @@ -2499,9 +2506,11 @@ export default class MarketsPage extends BasePage {
* rate is generated.
*/
anyRate (): [number, number, number] {
const { cfg: { spot }, baseCfg: { id: baseID }, quoteCfg: { id: quoteID }, rateConversionFactor } = this.market
const midGap = this.midGap()
if (midGap) return [midGap * OrderUtil.RateEncodingFactor, midGap, this.midGapConventional() || 0]
const { cfg: { spot }, baseCfg: { id: baseID }, quoteCfg: { id: quoteID }, rateConversionFactor, bookLoaded } = this.market
if (bookLoaded) {
const midGap = this.midGap()
if (midGap) return [midGap * OrderUtil.RateEncodingFactor, midGap, this.midGapConventional() || 0]
}
if (spot && spot.rate) return [spot.rate, spot.rate / OrderUtil.RateEncodingFactor, spot.rate / rateConversionFactor]
const [baseUSD, quoteUSD] = [app().fiatRatesMap[baseID], app().fiatRatesMap[quoteID]]
if (baseUSD && quoteUSD) {
Expand Down
10 changes: 5 additions & 5 deletions client/webserver/site/src/js/mm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ class Bot extends BotMarket {
const div = this.div = pg.page.botTmpl.cloneNode(true) as PageElement
const page = this.page = Doc.parseTemplate(div)

this.runDisplay = new RunningMarketMakerDisplay(page.onBox)
this.runDisplay = new RunningMarketMakerDisplay(page.onBox, 'mm')

setMarketElements(div, baseID, quoteID, host)
if (cexName) setCexElements(div, cexName)
Expand Down Expand Up @@ -670,8 +670,8 @@ class Bot extends BotMarket {
this.baseAllocSlider.changed = (r: number) => {
const dexAlloc = baseSlider.left.dex + r * dexRange
const cexAlloc = baseSlider.left.cex + r * cexRange
alloc.dex[baseID] = dexAlloc * baseFeeFactor
alloc.cex[baseID] = cexAlloc * baseFeeFactor
alloc.dex[baseID] = dexAlloc * baseFactor
alloc.cex[baseID] = cexAlloc * baseFactor
setBaseProposal(dexAlloc, cexAlloc)
}
}
Expand All @@ -692,8 +692,8 @@ class Bot extends BotMarket {
this.quoteAllocSlider.changed = (r: number) => {
const dexAlloc = quoteSlider.left.dex + r * dexRange
const cexAlloc = quoteSlider.left.cex + r * cexRange
alloc.dex[quoteID] = dexAlloc * quoteFeeFactor
alloc.cex[quoteID] = cexAlloc * quoteFeeFactor
alloc.dex[quoteID] = dexAlloc * quoteFactor
alloc.cex[quoteID] = cexAlloc * quoteFactor
setQuoteProposal(dexAlloc, cexAlloc)
}
}
Expand Down
2 changes: 1 addition & 1 deletion client/webserver/site/src/js/mmarchives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default class MarketMakerArchivesPage extends BasePage {
setMarketElements(row, baseID, quoteID, host)

Doc.bind(tmpl.logs, 'click', () => {
app().loadPage('mmlogs', { baseID, quoteID, host, startTime })
app().loadPage('mmlogs', { baseID, quoteID, host, startTime, returnPage: 'mmarchives' })
})

Doc.bind(tmpl.settings, 'click', () => {
Expand Down
3 changes: 2 additions & 1 deletion client/webserver/site/src/js/mmlogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface LogsPageParams {
quoteID: number
baseID: number
startTime: number
returnPage: string
}

let net = 0
Expand Down Expand Up @@ -81,7 +82,7 @@ export default class MarketMakerLogsPage extends BasePage {
const page = this.page = Doc.idDescendants(main)
net = app().user.net
Doc.cleanTemplates(page.eventTableRowTmpl, page.dexOrderTxRowTmpl, page.performanceTableRowTmpl)
Doc.bind(this.page.backButton, 'click', () => { app().loadPage(this.liveBot ? 'mm' : 'mmarchives') })
Doc.bind(this.page.backButton, 'click', () => { app().loadPage(params.returnPage ?? 'mm') })
Doc.bind(this.page.filterButton, 'click', () => { this.applyFilters() })
if (params?.host) {
const url = new URL(window.location.href)
Expand Down
4 changes: 2 additions & 2 deletions client/webserver/site/src/js/mmutil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,13 +758,13 @@ export class RunningMarketMakerDisplay {
startTime: number
ticker: any

constructor (div: PageElement) {
constructor (div: PageElement, page: string) {
this.div = div
this.page = Doc.parseTemplate(div)
Doc.bind(this.page.stopBttn, 'click', () => this.stop())
Doc.bind(this.page.runLogsBttn, 'click', () => {
const { mkt: { baseID, quoteID, host }, startTime } = this
app().loadPage('mmlogs', { baseID, quoteID, host, startTime })
app().loadPage('mmlogs', { baseID, quoteID, host, startTime, returnPage: page })
})
}

Expand Down
Loading