Merge branch 'pr/2' into main

This commit is contained in:
Nye Evans 2021-02-11 17:52:07 +00:00
commit 7be6148337
15 changed files with 7783 additions and 33080 deletions

3
.gitignore vendored
View file

@ -1 +1,2 @@
node_modules/
node_modules/
dist/

3
.vscode/launch.json vendored
View file

@ -5,7 +5,8 @@
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"type": "pwa-chrome",
"targetSelection": "pick",
"request": "attach",
"name": "Attach to aardvark_renderer",
"sourceMaps": true,

13
dist/index.html vendored
View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>referenceImageVR</title>
<link href="styles.css?1612951302669" rel="stylesheet">
</head>
<body>
<div id="root" class="FullPage"></div>
<script type="text/javascript" src="main.js?68dbbfe09f76aed88278"></script></body>
</html>

1
dist/main.d.ts vendored
View file

@ -1 +0,0 @@
export {};

32742
dist/main.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,18 +0,0 @@
{
"xr_type": "aardvark-gadget@^1.5.1",
"name": "referenceImageVR",
"icons": [
{
"src": "models/Icon.glb",
"type": "model/gltf-binary"
}
],
"aardvark": {
"permissions": [
"scenegraph"
],
"browserWidth": 1024,
"browserHeight": 1024,
"startAutomatically": false
}
}

Binary file not shown.

BIN
dist/models/Icon.glb vendored

Binary file not shown.

Binary file not shown.

99
dist/styles.css vendored
View file

@ -1,99 +0,0 @@
body, html
{
background-color: transparent;
height: 100%;
overflow: hidden;
}
button{
background-color: transparent;
border: 3px solid black;
}
.Button
{
background-color: lightgray;
font-size: 4rem;
}
.Label
{
font-size: 4rem;
}
.Button:hover
{
background-color: gray;
}
.FullPage
{
width: 100%;
height: 100%;
}
.NoGrabHighlight
{
background-color: white;
}
.InRangeHighlight
{
background-color: lightblue;
}
.GrabbedHighlight
{
background-color: blue;
}
.imageMenuButton{
height: 100%;
width: 100%; /*things to try: max width?*/
box-sizing:border-box;
}
.imageMenuButtonContainer{
width : 100%;
height: 100%;
}
.imageMenuDeleteButton{
font-size: 2rem;
}
.imageMenuImage{
object-fit: cover;
width: 100%;
height: 100%;
}
.imageMenuContainer{
display: grid;
grid-template-columns: 20vw 20vw 20vw 20vw;
gap: 4vw;
margin-left: 4vw;
}
.displayedImage{
width: 90%;
height: auto;
bottom: 0px;
text-align: center;
}
.imageDisplayButton{
font-size: 3rem;
}
#noImageText{
font-size: 3rem;
color: grey;
background-color: white;
margin: 0 auto;
}
#uploadButton{
font-size: 3rem;
margin-top: 5vh;
}

7766
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,7 @@
"style-loader": "^1.2.1",
"ts-loader": "^6.0.4",
"tslib": "^1.10.0",
"typescript": "^3.5.2",
"typescript": "^4.1.4",
"webpack": "^4.34.0",
"webpack-cli": "^3.3.6"
},
@ -36,7 +36,9 @@
"@aardvarkxr/aardvark-react": "^1.5.1",
"@aardvarkxr/aardvark-shared": "^1.5.1",
"bind-decorator": "^1.0.11",
"ipfs": "^0.54.2",
"react": "^16.13.1",
"react-dom": "^16.13.1"
"react-dom": "^16.13.1",
"react-dropzone": "^11.3.1"
}
}

118
src/imageadder.tsx Normal file
View file

@ -0,0 +1,118 @@
import bind from 'bind-decorator';
import * as React from 'react';
import * as IPFS from 'ipfs';
import Dropzone from 'react-dropzone';
interface ImageAddedProps
{
addImageCallback: ( url: string ) => void;
validateUrlCallback: ( url: string ) => boolean;
}
interface ImageAdderState
{
url: string;
message: string;
}
export class ImageAdder extends React.Component< ImageAddedProps, ImageAdderState >
{
private ipfsNode: IPFS.IPFS = null;
constructor( props: any )
{
super( props );
this.state = {
url: "",
message: "Add image url here:",
};
IPFS.create().
then( async ( newNode: any ) =>
{
this.ipfsNode = newNode;
const version = await newNode.version()
console.log('IPFS Version:', version.version );
} );
}
@bind
private handleChange( event: React.ChangeEvent<HTMLInputElement> )
{
this.setState( { url: event.target.value });
}
@bind
private handleSubmit(event: React.FormEvent< HTMLFormElement > )
{
if (this.props.validateUrlCallback(this.state.url))
{
this.props.addImageCallback( this.state.url );
event.preventDefault();
}
else
{
this.setState({message: "this image is either already in the list or not an image"});
event.preventDefault();
}
this.setState({url: ""});
}
@bind
private async onFileLoad( file: File, result: ArrayBuffer ) //we add the binaries to the ipfs node then convert it into a blob we can display, when accessing this from a remote gadget you'll need to create a blob since we havent uploaded this as one
{
let res = await this.ipfsNode.add( new Uint8Array( result ) );
const url = "/ipfs/" + res.cid;
console.log( `Adding ${ file.name } as ${ url }` );
const blobData: ArrayBuffer[] = [result];
const imageBlob = new Blob(blobData);
this.props.addImageCallback( URL.createObjectURL(imageBlob) );
}
@bind
private onDrop( acceptedFiles: File[] )
{
for( let file of acceptedFiles )
{
const reader = new FileReader();
reader.onabort = () => { console.log( "file reading was aborted for", file.name ); }
reader.onerror = () => { console.log( "file reading has failed for", file.name ); }
reader.onload = () => this.onFileLoad( file, reader.result as ArrayBuffer );
reader.readAsArrayBuffer( file );
}
}
render()
{
return (
<div>
<form onSubmit={ this.handleSubmit }>
<label>
{this.state.message}
<br/>
<input type="text" value={this.state.url} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
<Dropzone onDrop={ this.onDrop }>
{({getRootProps, getInputProps}) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
</section>
)}
</Dropzone>
</div> );
}
}

View file

@ -3,27 +3,22 @@ import { EAction, EHand, g_builtinModelBox, InitialInterfaceLock, Av } from '@aa
import bind from 'bind-decorator';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ImageAdder } from './imageadder';
import * as IPFS from 'ipfs';
class MenuItem extends React.Component< {displayImage, onClick, deleteSelfCallback}, {}> //class for items on the menu, basically just a button
class MenuItem extends React.Component< {displayImage, onClick}, {}> //class for items on the menu, basically just a button
{
constructor(props)
{
super(props);
}
static defaultProps = {
displayImage: "https://cdn.pixabay.com/photo/2013/07/12/17/47/test-pattern-152459_960_720.png"
}
public render()
{
return(
<div className = "imageMenuButtonContainer">
<button className = "imageMenuButton" onClick = {this.props.onClick}>
<img src = {this.props.displayImage} className = "imageMenuImage"/>
</button>
<button className = "imageMenuDeleteButton" onClick = {this.props.deleteSelfCallback}>X</button>
</div>
);
}
}
@ -78,13 +73,6 @@ class ImageMenu extends React.Component< {}, ImageMenuState> //class for the who
this.forceUpdate();
}
public deleteListItem(item: string)
{
this.state.imageUrls.splice(this.state.imageUrls.indexOf(item), 1);
this.forceUpdate();
console.log(this.state.imageUrls)
}
public render()
{
if (this.imageToDisplay){ //if theres an image then show that, and also a back button
@ -107,7 +95,7 @@ class ImageMenu extends React.Component< {}, ImageMenuState> //class for the who
};
return(
<div style = {itemStyle}>
<MenuItem displayImage = {image} onClick = {() => this.displayImage(image)} deleteSelfCallback = {() => this.deleteListItem(image)}/>
<MenuItem displayImage = {image} onClick = {() => this.displayImage(image)}/>
</div>
);
});
@ -136,62 +124,6 @@ class ImageMenu extends React.Component< {}, ImageMenuState> //class for the who
}
interface ImageAddedProps
{
addImageCallback: ( url: string ) => void;
validateUrlCallback: ( url: string ) => boolean;
}
interface ImageAdderState
{
url: string;
}
class ImageAdder extends React.Component< ImageAddedProps, ImageAdderState >
{
constructor( props: any )
{
super( props );
this.state = { url: "" };
}
@bind
private handleChange( event: React.ChangeEvent<HTMLInputElement> )
{
this.setState( { url: event.target.value });
}
@bind
private handleSubmit(event: React.FormEvent< HTMLFormElement > )
{
if (this.props.validateUrlCallback(this.state.url))
{
this.props.addImageCallback( this.state.url );
event.preventDefault();
}
else
{
alert("given image is invalid"); //could eventually replace this with something on the render
event.preventDefault();
}
}
render()
{
return (
<form onSubmit={ this.handleSubmit }>
<label>
Image URL to add:
<input type="text" value={this.state.url } onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form> );
}
}
const k_popupHtml =
`
<!DOCTYPE html>
@ -214,22 +146,17 @@ class MyGadget extends React.Component< {}, {} >
private addImagePopup: Window = null;
private imageMenuRef = React.createRef<ImageMenu>();
constructor( props: any )
{
super( props );
}
public openWindow(){
if (!this.addImagePopup || this.addImagePopup.closed)
{
this.addImagePopup = window.open("", "popup", "", true );
this.addImagePopup.document.write( k_popupHtml );
this.addImagePopup = window.open("", "popup", "", true );
this.addImagePopup.document.write( k_popupHtml );
ReactDOM.render( <ImageAdder addImageCallback={ this.imageMenuRef?.current.onAddImage } validateUrlCallback={this.imageMenuRef.current.validateUrl}/>,
this.addImagePopup.document.getElementById( "root" ) );
}
ReactDOM.render( <ImageAdder addImageCallback={ this.imageMenuRef?.current.onAddImage } validateUrlCallback={this.imageMenuRef.current.validateUrl}/>,
this.addImagePopup.document.getElementById( "root" ) );
}
@ -256,9 +183,10 @@ renderAardvarkRoot( "root", <MyGadget/> );
//DONT FORGET TO RUN NPM START AAAAAAAAAAAAAAAAAAAA YOU ALWAYS FORGETTT
/*
todo:
look into using ipfs for this^^
look into using ipfs for images
look into using avmodel to create pop-up images
useful links:
http://localhost:23842/gadgets/aardvark_monitor/index.html
http://localhost:8042/

View file

@ -31,7 +31,7 @@ module.exports =
[
{ from: './src/styles.css', to: 'styles.css' },
{ from: './src/manifest.webmanifest', to: 'manifest.webmanifest' },
{ from: './src/models/placeholder.glb', to: 'models/placeholder.glb' },
{ from: './src/models', to: 'models' },
]
),
],