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: External link handling in dexc-desktop #2541

Merged
merged 3 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
21 changes: 21 additions & 0 deletions client/cmd/dexc-desktop/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,26 @@ func closeAllWindows() {
}
}

// bindJSFunctions exports functions callable in the frontend
func bindJSFunctions(w webview.WebView) {
w.Bind("isWebview", func() bool {
return true
})

w.Bind("openUrl", func(url string) {
var err error
switch runtime.GOOS {
case "linux":
err = exec.Command("xdg-open", url).Start()
case "windows":
err = exec.Command("rundll32", "url.dll", "FileProtocolHandler", url).Start()
}
if err != nil {
log.Errorf("unable to run URL handler: %s", err.Error())
}
})
}

func runWebview(url string) {
w := webview.New(true)
defer w.Destroy()
Expand All @@ -389,6 +409,7 @@ func runWebview(url string) {

w.SetSize(width, height, webview.HintNone)
w.Navigate(url)
bindJSFunctions(w)
w.Run()
}

Expand Down
2 changes: 1 addition & 1 deletion client/webserver/site/src/html/order.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</div>
<div class="order-datum">
<div>[[[Offering]]]</div>
<div>{{$ord.OfferString}} {{$ord.FromTicker}} {{template "microIcon" $ord.FromTicker}}</div>
<div>{{$ord.OfferString}} {{$ord.FromTicker}} {{template "microIcon" $ord.FromSymbol}}</div>
</div>
<div class="order-datum">
<div>[[[Asking]]]</div>
Expand Down
4 changes: 2 additions & 2 deletions client/webserver/site/src/html/wallets.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@
<td data-tmpl="status"></td>
<td data-tmpl="detailsLink" class="pointer hoverbg">
<span class="mono">
<span data-tmpl="hashStart"></span>…<span data-tmpl="hashEnd"></span>
<a href="" data-tmpl="detailsLinkUrl" target="_blank"><span data-tmpl="hashStart"></span>…<span data-tmpl="hashEnd"></span></a>
</span>
<span class="ico-open ms-1"></span>
</td>
Expand Down Expand Up @@ -828,7 +828,7 @@
<div class="flex-center flex-grow-1 pe-3">
<div data-tmpl="value" class="flex-center fs16 p-2"></div>
<div data-tmpl="hash" class="hashwrap fs14 p-1"></div>
<div data-tmpl="explorerLink" class="p-2 hoverbg pointer"><span class="fs16 ico-open"></span></div>
<a href="" target="_blank" data-tmpl="explorerLink" class="p-2 hoverbg pointer"><span class="fs16 ico-open"></span></a>
</div>
<div class="d-flex align-items-stretch">
<div class="flex-center flex-column pe-2">
Expand Down
14 changes: 14 additions & 0 deletions client/webserver/site/src/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ export default class Application {

// Bind the tooltips.
this.bindTooltips(this.main)

if (window.isWebview) {
// Bind webview URL handlers
this.bindUrlHandlers(this.main)
}
}

bindTooltips (ancestor: HTMLElement) {
Expand All @@ -313,6 +318,15 @@ export default class Application {
})
}

bindUrlHandlers (ancestor: HTMLElement) {
for (const link of Doc.applySelector(ancestor, 'a[target=_blank]')) {
Doc.bind(link, 'click', (e: MouseEvent) => {
e.preventDefault()
window.openUrl(link.href ?? '')
})
}
}

/* attachHeader attaches the header element, which unlike the main element,
* isn't replaced during page navigation.
*/
Expand Down
1 change: 1 addition & 0 deletions client/webserver/site/src/js/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ export default class OrderPage extends BasePage {
addNewMatchCard (match: Match) {
const page = this.page
const matchCard = page.matchCardTmpl.cloneNode(true) as HTMLElement
app().bindUrlHandlers(matchCard)
matchCard.dataset.matchID = match.matchID
this.setImmutableMatchCardElements(matchCard, match)
this.setMutableMatchCardElements(matchCard, match)
Expand Down
3 changes: 3 additions & 0 deletions client/webserver/site/src/js/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ declare global {
testFormatFourSigFigs: () => void
testFormatRateFullPrecision: () => void
user: () => void
isWebview?: () => boolean
openUrl: (url: string) => void
}
}

Expand Down Expand Up @@ -808,6 +810,7 @@ export interface Application {
loadPage (page: string, data?: any, skipPush?: boolean): Promise<boolean>
attach (data: any): void
bindTooltips (ancestor: HTMLElement): void
bindUrlHandlers (ancestor: HTMLElement): void
attachHeader (): void
showDropdown (icon: HTMLElement, dialog: HTMLElement): void
ackNotes (): void
Expand Down
6 changes: 4 additions & 2 deletions client/webserver/site/src/js/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1073,13 +1073,14 @@ export default class WalletsPage extends BasePage {
for (const { tx, status } of pageOfTickets) {
const tr = page.ticketHistoryRowTmpl.cloneNode(true) as PageElement
page.ticketHistoryRows.appendChild(tr)
app().bindUrlHandlers(tr)
const tmpl = Doc.parseTemplate(tr)
tmpl.age.textContent = Doc.timeSince(tx.stamp * 1000)
tmpl.price.textContent = Doc.formatFullPrecision(tx.ticketPrice, ui)
tmpl.status.textContent = intl.prep(ticketStatusTranslationKeys[status])
tmpl.hashStart.textContent = tx.hash.slice(0, 6)
tmpl.hashEnd.textContent = tx.hash.slice(-6)
Doc.bind(tmpl.detailsLink, 'click', () => window.open(coinLink(tx.hash), '_blank'))
tmpl.detailsLinkUrl.setAttribute('href', coinLink(tx.hash))
}
}

Expand Down Expand Up @@ -1192,6 +1193,7 @@ export default class WalletsPage extends BasePage {
for (const tspend of stakeStatus.stances.tspends) {
const div = page.tspendTmpl.cloneNode(true) as PageElement
page.votingTspends.appendChild(div)
app().bindUrlHandlers(div)
const tmpl = Doc.parseTemplate(div)
for (const opt of [tmpl.yes, tmpl.no]) {
opt.name = tspend.hash
Expand All @@ -1204,7 +1206,7 @@ export default class WalletsPage extends BasePage {
if (tspend.value > 0) tmpl.value.textContent = Doc.formatFourSigFigs(tspend.value / ui.conventional.conversionFactor)
else Doc.hide(tmpl.value)
tmpl.hash.textContent = tspend.hash
Doc.bind(tmpl.explorerLink, 'click', () => window.open(coinLink(tspend.hash), '_blank'))
tmpl.explorerLink.setAttribute('href', coinLink(tspend.hash))
}

const setTKeyPolicy = async (key: string, policy: string) => {
Expand Down
Loading