-
Notifications
You must be signed in to change notification settings - Fork 54
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
Lightbeam in VR using A-Frame #230
base: master
Are you sure you want to change the base?
Conversation
This comment is outdated. We don't require the two repos approach anymore. Initially I followed the following approach: The above method didn't work for the following reasons:
The existing solution that I have in this PR requires two repos, please let me know of any other inputs to make it possible from within the web-extension without using an additional repo. Thanks. |
We should just fix that I think. I don't know enough why that restriction is in place at the moment. However we can't merge this like it is. This is looking really great as a demo though. |
@jonathanKingston i think the restriction is due to serving content across cross origin issues and that's why there is a hard requirement to serve A-Frame via a server. @cvan @caseyyee shed some light? |
@princiya why does it need to be from a server at all though? Can't the files be hosted via the add-on? |
yeah, that's approach I'd recommend (if it works). there's a section in the A-Frame FAQ docs that briefly addresses this. the CORS requirement isn't the case for every type of media. like images should load fine, for example, but if you're trying to load a local file (that's not over a I can take a look at it - should be pretty quick to fix (but could be a non-obvious change). |
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.
nice work! I have some questions here. but hopefully your answers will help me understand this a bit better. thanks for doing this 👍
src/js/lightbeamVR.js
Outdated
if (site.thirdParties) { | ||
const thirdPartyLinks = site.thirdParties.map((thirdParty) => { | ||
return { | ||
source: website, |
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 could be off here, and I likely don't understand the structure of the data just yet. but would it be helpful to key this off site.hostname
?
src/js/lightbeamVR.js
Outdated
async getData() { | ||
const data = await storeChild.getAll(); | ||
const transformedData = this.transformData(data); | ||
const blob = new Blob([JSON.stringify(transformedData ,' ' , 2)], |
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.
nit: " ," -> ", "
src/js/lightbeamVR.js
Outdated
url : url, | ||
filename : 'data.json', | ||
conflictAction : 'overwrite', | ||
saveAs: true |
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.
should probably change " : " to ": " above
src/js/lightbeamVR.js
Outdated
const fullUrl = 'http://localhost:3000/'; | ||
async function isOpen() { | ||
const tabs = await browser.tabs.query({}); | ||
const lightbeamTabs = tabs.filter((tab) => { |
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.
could use Array#find
:
tabs.find(tab => tab.url === fullUrl);
src/js/lightbeamVR.js
Outdated
const lightbeamTab = await isOpen(); | ||
if (!lightbeamTab) { | ||
// only open a new LightbeamVR instance if one isn't already open. | ||
browser.tabs.create({ url: fullUrl}); |
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.
nit: the space after the {
|
||
loadLightbeamVR() { | ||
const vrView = document.getElementById('vr-view-button'); | ||
vrView.addEventListener('click', async () => { |
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 would also listen for the vrdisplaypresentchange
event which fires on window
: https://developer.mozilla.org/en-US/docs/Web/Events/vrdisplaypresentchange
src/js/lightbeamVR.js
Outdated
const blob = new Blob([JSON.stringify(transformedData ,' ' , 2)], | ||
{type : 'application/json'}); | ||
const url = window.URL.createObjectURL(blob); | ||
const downloading = browser.downloads.download({ |
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 it'd likely be much more convoluted, but this seems like a pretty good use case for a Service Worker, using the Cache API.
some basic Service Workers of how to do that:
- https://serviceworke.rs/json-cache_service-worker_doc.html
- https://googlechrome.github.io/samples/service-worker/mock-responses/service-worker.js
- https://googlechrome.github.io/samples/service-worker/post-message/index.html
- https://serviceworke.rs/virtual-server_index_doc.html
you'd just postMessage
some data to the worker, stringify it, and have it be returned upon 'fetch'
events whenever requesting /data.json
.
I could be misunderstanding the flow here, but I think that would enable storing, serving, and updating the JSON file just fine.
let me know if I ought to file a separate issue to elaborate on this. don't want to suggest too much additional work here 💻
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.
Lets make this a separate issue, we have this downloading elsewhere in Lightbeam too anyway even if we remove the need here. The data will change a lot. Is there likely to be an advantage on caching this if it might change per minute?
We could cache the JSON some other form of storage too perhaps if Service Workers don't work correctly in web extensions (I have never tried and I know there are some bugs).
src/index.html
Outdated
@@ -14,6 +14,7 @@ | |||
<script src="ext-libs/dialog-polyfill.js"></script> | |||
<script src="js/viz.js" type="text/javascript"></script> | |||
<script src="js/lightbeam.js" type="text/javascript"></script> | |||
<script src="js/lightbeamVR.js" type="text/javascript"></script> |
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.
nit: can remove the type="text/javascript"
from the past three (for consistency)
this seems like an A-Frame bug. which part didn't work exactly? were there any console errors? I assume if I just pull the repo, I can reproduce that? |
I would work on fixing the issue with the server being required when hosting from the web extension and remove the need for a JSON file, instead updating the nodes as we do for the main diagram. Perhaps we should just call this "3d view" and leave the goggles icon for people that have a headset. If the extension can host the code itself then we can just make it a different page that the browser action filters for, so the code to check for "localhost:3000" in the |
@cvan thanks for the nits 👍 will update the code based on your feedback.
|
@jonathanKingston agree on your feedback about fixing this PR to solve the issue of having a server from web-extension. Any inputs on how to go about this? |
@princiya I think you should be able to just host the files yourself in the addon like we do for dexie, we might need to compile them (I don't know enough about a-frame to know if that is the case) either way just ignore their example and load the scripts into an extension page like we do for d3 for the main lightbeam page. |
src/js/aframe/aframeForcegraph.js
Outdated
}); | ||
} */ | ||
// Auto add color to uncolored nodes | ||
const { nodes, links } = await aframeHelper.getData(); |
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.
@jonathanKingston as a quick hack, I decided to pass nodes, links
into this aframe-component.
Because we weren't using a local server, the above qwest
code didn't work for json file. The qwest
library uses XMLHTTPRequest
by default.
I shall think about submitting a patch for this aframe-component itself :)
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.
looking good! thanks for taking this on 👍
src/js/aframe/aframeHelper.js
Outdated
if (site.thirdParties) { | ||
const thirdPartyLinks = site.thirdParties.map((thirdParty) => { | ||
return { | ||
source: website, |
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.
is it possible that there will be duplicate link items? do we want to make the list contain only unique values - or is this fine?
src/js/aframe/aframeHelper.js
Outdated
} | ||
}; | ||
|
||
aframeHelper.init(); |
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.
without reading through aframeForcegraph.js
, how is this used externally from this file? this module ought to export something, I’d think?
src/indexVR.html
Outdated
<script src="js/storeChild.js"></script> | ||
<script src="js/aframe/aframeHelper.js"></script> | ||
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script> | ||
<script src="js/aframe/aframeForcegraph.js"></script> |
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.
this file looks like it’s autogenerated from Webpack? did you write this or is it a vendor, third-party lib? in other words, how could one modify the source and regenerate it?
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.
@cvan Here is the main source.
- I was trying to load
forcegraph
components by passingnodes
andlinks
and it kept complaining about wrongJSON
syntax.
<a-entity forcegraph="nodes:[{id: 1, name: 'first'}, {id: 2, name: 'second'}]; links: [{source: 1, target: 2}]"</a-entity>
- The
jsonUrl
property forforcegraph
component worked while running on a local server, but as you pointed out earlier, when I was trying to loadindexVR.html
viamoz-extension://
it failed.
<a-entity forcegraph="jsonUrl: data/data.json"></a-entity>
- The
forcegraph
component usesqwest
here which usesXMLHttpRequest
and doesn't seem to work without a local server. - Keeping MozFest in priority, the next task was to quickly look into
forcegraph
's source code and I decided to use this hack. - This is off-course temporary, and I will consider submitting a patch to this
forcegraph
component itself to make it work without requiring a local server forqwest
(to fetch theJSON
file). - I attempted my hack directly on the
Webpack
generated file because I am running short on time (MozFest is this week) and I didn't have to worry about theforcegraph
component failing to build etc. - Considering this is a 1-2 week hack solution, can we leave it this way or are we violating any license rules?
cc @jonathanKingston
src/js/aframe/aframeHelper.js
Outdated
@@ -0,0 +1,42 @@ | |||
const aframeHelper = { |
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 name this something more descriptive
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.
is it possible to write this as an A-Frame component?
src/js/aframe/aframeHelper.js
Outdated
|
||
async getData() { | ||
const data = await storeChild.getAll(); | ||
const { nodes, links } = this.transformData(data); |
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.
could you just return this here (instead of creating these intermediate constant variables)?
const lightbeamTabs = tabs.filter((tab) => { | ||
return (tab.url === fullUrl); | ||
}); | ||
return lightbeamTabs[0] || false; |
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 would make sure that this returns a Boolean. so: !!lightbeamTabs[0]
src/js/lightbeamVR.js
Outdated
// only open a new LightbeamVR instance if one isn't already open. | ||
browser.tabs.create({ url: fullUrl }); | ||
} else if (!lightbeamTab.active) { | ||
// re-focus LightbeamVR if it is already open but lost focus |
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.
nit: remove trailing white space (one space) and add a period
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.
@cvan surely, a hard-core nit picker ;) beats @jonathanKingston just kidding!
thanks for reviewing and I shall fix these.
src/js/lightbeamVR.js
Outdated
} else if (!lightbeamTab.active) { | ||
// re-focus LightbeamVR if it is already open but lost focus | ||
browser.tabs.reload(lightbeamTab.id); | ||
browser.tabs.update(lightbeamTab.id, {active: true}); |
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.
are these methods async? if so, should use Promise callback
@@ -40,5 +40,7 @@ | |||
"js/capture.js", | |||
"js/background.js" | |||
] | |||
} | |||
}, | |||
|
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.
can remove this newline
} | ||
}, | ||
|
||
"content_security_policy": "script-src 'self' 'unsafe-eval' https://aframe.io/releases/0.5.0/aframe.min.js; object-src 'self';" |
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.
unrelated: can you bump the A-Frame version to 0.7.1 (can be in separate PR; I can file an issue)
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.
for some reasons, in the latest version I get the following error:
THREE.Raycaster: Unsupported camera type.
from three.js
.
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.
oof, is that with 0.7.0
or 0.7.1
?
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.
both 0.7.0 and 0.7.1
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 really would prefer to install the module locally than remotely load it, is this not possible through npm?
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.
possible, but I get the same error for newer versions. but will load the code via npm 👍
@cvan Here is the main source.
|
Can you pass in a fully qualified URL by using: browser.extesion.getUrl("data.json") or similar?
I assume you used |
}); | ||
}, | ||
|
||
async runLightbeam() { |
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 would prefer not to have this code at all. The background script that currently checks for "index.html" could also check for indexVR.
I would load the url in the same page rather than create another tab.
This is the patch (and a couple of other things) I was talking about submitting to the Because of time constraints, I decided to put the tiny hack solution into the webpack generated file from the above component. At this point, the |
friendly ping: @princiya would you or someone on your team happen to have some spare cycles to resurrect some of the work on this? let me know if you need a hand. I or someone on my team might be able to. thanks - and, again, great work here! |
@cvan certainly I would love to see this PR merged. I shall try to clean-up (and recall :)) things this weekend and will ping you. Thank you for writing :) |
@cvan to be clear @princiya is a contributor at the moment and I'm not actively working on Lightbeam at the moment. I can review PRs and help out where possible though. Maybe @princiya should clean the code up and we could pass some of the visualisation work off to your team. I know the 2D could really merit from having someone with real visualisation perf knowledge look at it. |
@jonathanKingston: @princiya: completely understand! you have already gone way above and beyond. I do not want to set any expectations (you have already exceeded them 😄), and I want to make sure it is okay with you both that we build on top of and extend the great work you have done already. we have some spare cycles and can work on the art assets. @caseyyee in particular can help with any perf analysis. @princiya: no pressure, really. do not feel obligated to work on this over the weekend. I will check back next week, and let me just know the roadmap, processes, and potential other folks I ought to rope in in conversations if I we want to add the VR visualisations mode properly into the extension. thanks! |
@cvan It would be great if you could extend Lightbeam for A-Frame. I am happy to talk about the work done so far, roadmap etc. I have NDA volunteer access to Mozilla's slack and I am in the #lightbeam channel. Also, princiya dot marina at gmail dot com is my email address. Thank you. |
Issue #202
Launch Lightbeam web-extension and click the
VR
button [below gif] to see Lightbeam in VR.@jonathanKingston @cvan @caseyyee let me know what you think.