-
Notifications
You must be signed in to change notification settings - Fork 128
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
Turbolinks-integrated query parameters and stimulus integration on address page #845
Conversation
We'll still need a simple solution to the dcrdata/public/js/controllers/charts.js Line 201 in 4b99577
Removing it would of course mean the anchors don't go to the URL when changing the view/chart, but at least forward/back nav should work, right? |
Yep. Removing it will be fine, though the url fragment will no longer change when you change the view or chart type. If you want to change the fragment, use can replace
|
Yeah the basic navigation in the browser should always work. I'm still waiting for my dcrdata VM to finish syncing. Once it's done I'll take a closer look at these issues. |
Thanks, @ZeroASIC. Be sure to get postgres tuned up to save tons of time. There's some tips in a conf file in db/dcrpg. |
Okay, looking this over you did get the navigation working correctly, but you've duplicated functionality that already exists in Javascript URLSearchParams so you can use anchors. Anchors weren't really meant to be used this way anyhow so I think it would be best if the anchors were removed from this page completely and replaced with URL Parameters. Also think about storing settings in the cookie and the url so they can be retrieved on page load if they're not in the URL already or the cookie can be rebuilt off of the URL. Edit: That link says it might not work in Safari, but Apple says it has partial support: https://developer.apple.com/documentation/webkitjs/urlsearchparams |
I agree that things would be easier if we use the query parameters. Please note that we do have two different things happening though. Right now, the query parameters are used for list pagination, which causes a Turbolinks visit. Changing chart parameters does not cause a Turbolinks visit, so maybe that's why the chart parameter was put in the anchor to begin with. I'd very much prefer to use query parameters, though, so if nobody objects, I'll work in that direction. |
I get ya. So |
That plan sounds good @buck54321. Please keep 3.1 in mind though since it has to backport smoothly. |
Switched everything to query parameters and moved the inline JS to stimulus. @chappjc This is a rather large change that would probably be difficult to cherry pick to 3.1-stable. Can I do a separate limited PR on that branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is still WIP, but just a few issues I noticed:
- This doesn't matter too much, but when clicking "Chart". then back to "List", the
&bin=all
query part that is added for the Chart view stays in the URL. - When in the Chart view for an address with few transactions, clicking the "All Blocks" grouping (the only enabled grouping button) shows the List view. The Charts button is still highlighted, but the grouping buttons are gone. EDIT: this happens for any address actually.
- Then after the previous point, the page freezes up and browser CPU goes high (testing with chrome). I might have clicked the List Button at this point since the Charts button was incorrectly highlighted. The associated message in the console after the browser recovers:
Active resource loading counts reached a per-frame limit while the tab was in background. Network requests will be delayed until a previous loading finishes, or the tab is brought to the foreground. See https://www.chromestatus.com/feature/5527160148197376 for more details
- The sent/received/net check boxes are not working right. They ended up on the Transaction Types view at some point, and they wouldn't work there of course. This might have been fallout from the previous issue though.
- I got this while clicking around. Sorry I don't know what triggered it:
at u.computeCombinedSeriesAndLimits_ (<anonymous>:5:25502)
at u.drawMiniPlot_ (<anonymous>:5:24051)
at u.drawStaticLayer_ (<anonymous>:5:23450)
at u.renderStaticLayer_ (<anonymous>:5:17362)
at Q.cascadeEvents_ (<anonymous>:3:25195)
at Q.predraw_ (<anonymous>:4:12117)
at Q.setVisibility (<anonymous>:4:27111)
at e.updateFlow (app.bundle.js:1)
at e.processData (app.bundle.js:1)
at e.drawGraph (app.bundle.js:1)
- The chart type drop down list box does not get set to the right value when loading/reloading a URL with a specific view (e.g.
?view=unspent
loads the page with the correct chart, but "Transaction Types" selected).
When looking at this for 3.1, we should consider the simplest possible fix. If that means removing the pushState entirely and not introducing TurboQuery, then we should do that. However, if there are small tweaks that will at least make the navigation arrows not broken in 3.1, then we should make those changes. |
} | ||
|
||
initialize () { | ||
var _this = this | ||
var controller = this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of setting this
onto a variable to pass it into new scope, we can just use fat arrow functions. ( since their function bodies have lexical scoping of this
, see https://toddmotto.com/es6-arrow-functions-syntaxes-and-lexical-scoping/#functionality-lexical-scoping-this )
So by using fat arrow function in the BLOCK_RECIEVED handler below, this
would be the controller and the alias variable not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly do the controller
thing for semantics (which is why _this
just wasn't working for me), but arrow functions are definitely appropriate in many places.
Just so I know, now that you have the ability, were we planning on using a babel plugin to translate arrow functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Production builds already transpile =>
to function
via https://babeljs.io/docs/en/babel-preset-env being set in our webpack prod configuration.
https://github.com/decred/dcrdata/blob/master/webpack.prod.js#L27
This preset essentially says to transpile everything to ES5 that can be transpiled without polyfills.
Some things can't be transpiled, like async
/await
, so we need to import a polyfill for those https://github.com/decred/dcrdata/blob/master/public/index.js#L1 ( regenerator-runtime is the polyfill for async await )
A set of optimizations for the address page. Page load times reduced from > 14 to ~ 2.25 seconds on my server.
Other than the project treasury, check out these addresses of varying activity level.
Resolves #835, #643. Also part of #843. There is one weird bug (also on master) that I have yet to resolve. When loading the project treasury "all blocks" data, Dygraph hangs and the page becomes unresponsive. That alone might not be too unexpected. It is hundreds of thousands of data points. But sometimes, for some reason, the websocket connection is lost in the process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No major issues, just some concerns about a few explorer -> dbtypes moves. Nice job slaying inline JS!
@@ -1586,6 +1420,8 @@ func (exp *explorerUI) Search(w http.ResponseWriter, r *http.Request) { | |||
|
|||
// Try aux DB if in full mode. | |||
if !exp.liteMode { | |||
// This is be unnecessarily duplicative and possible very | |||
// slow for a very active addresss. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to personally follow up on this PR because the call to exp.blockData.GetExplorerAddress
several lines up is no longer appropriate above. It was simply used to validate the address, but since adding txhelpers.AddressValidation
, that's what should be done above (avoiding the expensive SearchRawTransactoinVerbose RPC).
The purpose of this "Try aux DB if in full mode" when the RPC was just used above was because transactions for orphaned blocks may not show up in the output of searchrawtransactions, but PostgreSQL may have recorded data for the transaction and associated addresses. This is the same reasoning for checking PostgreSQL for transactions with exp.explorerSource.Transaction
on this line below.
However, Search does not need to do the address queries at all. That is the job of the address page. Here we only need to do txhelpers.AddressValidation
(as done in GetExplorerAddress
and elsewhere) and redirect to the appropriate /address URL.
Anyway, I can pick this up after your PR since it's a Search page issue.
'flow', 'zoom', 'interval', 'numUnconfirmed', 'formattedTime', | ||
'pagesize', 'txntype', 'txnCount', 'qricon', 'qrimg', 'qrbox', | ||
'paginator', 'pageplus', 'pageminus', 'listbox', 'table', | ||
'range', 'chartbox', 'noconfirms', 'chart', 'pagebuttons'] | ||
} | ||
|
||
initialize () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the code inside initialize
seems like it should be in connect
instead so that for example if you navigate from one address to another via search bar, the state is wiped and rebuilt from scratch.
hotwired/stimulus#75
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In our case, because we are not re-inserting controller elements, the effect is the same. The stimulus docs are a little confusing around that point, though, so I'm just going to move everything to connect
so that nobody has to wonder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
@@ -711,23 +720,23 @@ func (pgb *ChainDB) HeightHashDB() (uint64, string, error) { | |||
} | |||
|
|||
// Height uses the last stored height. | |||
func (pgb *ChainDB) Height() uint64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised losing (*ChainDB).Height/Hash didn't affect more code, namely callers from other packages.
To stabilize the ChainDB
API a bit, we could add some wrappers for the removed functions, but losing Height and Hash might be a good thing since it wasn't completely clear when to use Height vs. HeightDB, and Hash vs. HashDB. So anyway, this looks good.
I would expect the x-axis to stay the same if possible. |
method. Moves heavy lifting to data source and opens up some optimization possibilities
This was more involved than you would think it would be, so I want to motivate some of the changes here.
Another potential issue related to @chappjc's comment is that the "unspent" data returned from the api (see |
Yeah, I agree re: "for a bar graph, the expected behavior is that the bar width will correspond to the bin size." I think it's OK to make style changes along with these changes, especially if they facilitate addressing the issues the PR is meant to address, but depending on the change (is it self-contained and potentially applicable to 3.1, will it be easier to rebase with a separate commit, etc.) it might be good to have those as a separate commit in this PR. I'll leave that up to you. |
The style changes only apply to the address chart, and are not necessary or important to back port. I'd love to leave them here. |
Cool. Works for me then.
…On Mon, Dec 17, 2018, 1:13 PM buck54321 ***@***.*** wrote:
The style changes only apply to the address chart, and are not necessary
or important to back port. I'd love to leave them here.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#845 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AI8HSQzmxIQhecp6Cj6dLceKJJslPe7oks5u5-zUgaJpZM4Y4N6e>
.
|
I reworked the |
Would be awesome to get this in asap, so I'll give it another spin tonight. |
The issue with disappearing elements that I mentioned in this comment still exists for me (production build with npm run build vs watch): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue in my previous comment is resolved.
This PR tests out perfectly. It's a great improvement to the address page.
@gozart1 This is a g2g from my perspective. Wanna have another look before merge? |
Final commit message Front- and back-end fixes and tweaks for the address page. Fix browser arrow navigation. Move list pagination to stimulus/ajax. Give buttons a more modern style. Store all list and chart settings as part of the url query parameters. Rework "Unspent Total" chart into "Balance" chart (balance v. time). Add padding to chart x range to improve data display. Load chart data silently to improve page load times. Cache chart data to reduce api calls. Moved all inline scripts from address.tmpl to a stimulus controller. Skipped repeated Dygraph script loads, i.e on second+ Turbolinks visit. Skip AddessMetrics collection in favor of on-the-fly button disabling in the browser, based on downloaded data range. Relocate a few associated explorer types and data processing to db. Expect some of these performance and style changes to be propagated to other pages, specifically charts. |
Addresses #814, #815.
The primary issue is that
history.replaceState
is not compatible with Turbolinks' hijacked browser navigation. This started as an attempt to simply replace the history in a way that Turbolinks could understand, but after seeing some deficiencies in the way the anchor text was being handled, it has expanded beyond that a little bit. I've tried to make the solution portable for inclusion in other pages as well.What this solves
What's not working
@gozart and @ZeroASIC. If you could find time to fiddle with this a little, I would appreciate it.