mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-09-01 09:45:10 +00:00
Merge branch 'master' into wallet-encryption
This commit is contained in:
commit
2ccf40b18e
21 changed files with 263 additions and 152 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,4 +4,5 @@
|
||||||
/static/locales
|
/static/locales
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.idea/
|
.idea/
|
||||||
|
/build/daemon.ver
|
|
@ -33,7 +33,7 @@ script:
|
||||||
- |
|
- |
|
||||||
if [ "$TARGET" == "windows" ]; then
|
if [ "$TARGET" == "windows" ]; then
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
--env-file <(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \
|
--env-file <(env | grep -iE 'DEBUG|TARGET|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \
|
||||||
-v ${PWD}:/project \
|
-v ${PWD}:/project \
|
||||||
electronuserland/builder:wine \
|
electronuserland/builder:wine \
|
||||||
/bin/bash -c "yarn --link-duplicates --pure-lockfile && yarn build --win --publish onTag";
|
/bin/bash -c "yarn --link-duplicates --pure-lockfile && yarn build --win --publish onTag";
|
||||||
|
|
33
CHANGELOG.md
33
CHANGELOG.md
|
@ -5,23 +5,36 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Edit option missing from certain published claims ([#175](https://github.com/lbryio/lbry-desktop/issues/1756))
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
* Wallet Encryption/Decryption user flows ([#1785](https://github.com/lbryio/lbry-desktop/pull/1785))
|
||||||
* Added 3D file viewer for OBJ & STL file types ([#1558](https://github.com/lbryio/lbry-desktop/pull/1558))
|
|
||||||
* Added thumbnail preview on publish page ([#1755](https://github.com/lbryio/lbry-desktop/pull/1755))
|
|
||||||
* Wallet Encryption/Decryption user flows ([#1785](https://github.com/lbryio/lbry-desktop/pull/1785))
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* Rename the Github repo to lbry-desktop ([#1765](https://github.com/lbryio/lbry-desktop/pull/1765))
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
|
## [0.23.0] - 2018-07-25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
* 3D file viewer for OBJ & STL file types ([#1558](https://github.com/lbryio/lbry-desktop/pull/1558))
|
||||||
|
* Thumbnail preview on publish page ([#1755](https://github.com/lbryio/lbry-desktop/pull/1755))
|
||||||
|
* Abandoned claim transactions now show in wallet history ([#1769](https://github.com/lbryio/lbry-desktop/pull/1769))
|
||||||
|
* Emoji support in the claim description ([#1800](https://github.com/lbryio/lbry-desktop/pull/1800))
|
||||||
|
* PDF preview ([#1576](https://github.com/lbryio/lbry-desktop/pull/1576))
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* Upgraded LBRY Protocol to [version 0.20.4](https://github.com/lbryio/lbry/releases/tag/v0.20.4) to assist with download availability and lower CPU usage on idle.
|
||||||
|
* Upgraded Electron-Builder and Updater to support signing the daemon and improving the auto update process ([#1784](https://github.com/lbryio/lbry-desktop/pull/1784))
|
||||||
|
* Channel page now uses caching, faster switching between channels/claims ([#1750](https://github.com/lbryio/lbry-desktop/pull/1750))
|
||||||
* Only show video error modal if you are on the video page & don't retry to play failed videos ([#1768](https://github.com/lbryio/lbry-desktop/pull/1768))
|
* Only show video error modal if you are on the video page & don't retry to play failed videos ([#1768](https://github.com/lbryio/lbry-desktop/pull/1768))
|
||||||
* Actually hide NSFW files if a user chooses to hide NSFW content via the settings page ([#1748](https://github.com/lbryio/lbry-desktop/pull/1748))
|
* Actually hide NSFW files if a user chooses to hide NSFW content via the settings page ([#1748](https://github.com/lbryio/lbry-desktop/pull/1748))
|
||||||
* Hide the "Community top bids" section if user chooses to hide NSFW content ([#1760](https://github.com/lbryio/lbry-desktop/pull/1760))
|
* Hide the "Community top bids" section if user chooses to hide NSFW content ([#1760](https://github.com/lbryio/lbry-desktop/pull/1760))
|
||||||
* Add a more descriptive error message when Shapeshift is unavailable ([#1771](https://github.com/lbryio/lbry-desktop/pull/1771))
|
* More descriptive error message when Shapeshift is unavailable ([#1771](https://github.com/lbryio/lbry-desktop/pull/1771))
|
||||||
|
* Rename the Github repo to lbry-desktop ([#1765](https://github.com/lbryio/lbry-desktop/pull/1765))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* Edit option missing from certain published claims ([#1756](https://github.com/lbryio/lbry-desktop/issues/1756))
|
||||||
|
* Fix navigation issue with channels that have more than one page ([#1797](https://github.com/lbryio/lbry-desktop/pull/1797))
|
||||||
|
|
||||||
|
|
||||||
## [0.22.2] - 2018-07-09
|
## [0.22.2] - 2018-07-09
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* eslint-disable no-console,import/no-extraneous-dependencies,import/no-commonjs */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This script is necessary for checking that the daemon that has been downloaded during the
|
|
||||||
* yarn installing process is the one for the building target. For example, on Travis the
|
|
||||||
* Windows package is built on Linux, thus yarn will download the daemon for Linux instead of
|
|
||||||
* Windows. The script will test that and then download the right daemon for the targeted platform.
|
|
||||||
*/
|
|
||||||
const os = require('os');
|
|
||||||
const downloadDaemon = require('./downloadDaemon');
|
|
||||||
|
|
||||||
module.exports = context => {
|
|
||||||
|
|
||||||
let currentPlatform = os.platform();
|
|
||||||
if (currentPlatform === 'darwin') currentPlatform = 'macoss';
|
|
||||||
if (currentPlatform === 'win32') currentPlatform = 'windows';
|
|
||||||
|
|
||||||
let buildingPlatformTarget = context.platform.toString();
|
|
||||||
if (buildingPlatformTarget === 'mac') buildingPlatformTarget = 'macos';
|
|
||||||
|
|
||||||
if (buildingPlatformTarget !== currentPlatform) {
|
|
||||||
console.log(
|
|
||||||
"\x1b[34minfo\x1b[0m Daemon platform doesn't match target platform. Redownloading the daemon."
|
|
||||||
);
|
|
||||||
|
|
||||||
return downloadDaemon(buildingPlatformTarget);
|
|
||||||
}
|
|
||||||
return Promise.resolve();
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable no-console,import/no-extraneous-dependencies,import/no-commonjs */
|
/* eslint-disable no-console,import/no-extraneous-dependencies,import/no-commonjs */
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs-path');
|
const fs = require('fs');
|
||||||
const packageJSON = require('../package.json');
|
const packageJSON = require('../package.json');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const decompress = require('decompress');
|
const decompress = require('decompress');
|
||||||
|
@ -11,56 +11,84 @@ const downloadDaemon = targetPlatform =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const daemonURLTemplate = packageJSON.lbrySettings.lbrynetDaemonUrlTemplate;
|
const daemonURLTemplate = packageJSON.lbrySettings.lbrynetDaemonUrlTemplate;
|
||||||
const daemonVersion = packageJSON.lbrySettings.lbrynetDaemonVersion;
|
const daemonVersion = packageJSON.lbrySettings.lbrynetDaemonVersion;
|
||||||
const daemonDir = packageJSON.lbrySettings.lbrynetDaemonDir;
|
const daemonDir = path.join(__dirname,'..',packageJSON.lbrySettings.lbrynetDaemonDir);
|
||||||
const daemonFileName = packageJSON.lbrySettings.lbrynetDaemonFileName;
|
let daemonFileName = packageJSON.lbrySettings.lbrynetDaemonFileName;
|
||||||
|
|
||||||
let currentPlatform = os.platform();
|
let currentPlatform = os.platform();
|
||||||
if (currentPlatform === 'darwin') currentPlatform = 'macos';
|
|
||||||
if (currentPlatform === 'win32') currentPlatform = 'windows';
|
|
||||||
|
|
||||||
const daemonPlatform = targetPlatform || currentPlatform;
|
|
||||||
|
|
||||||
|
var daemonPlatform = process.env.TARGET || targetPlatform || currentPlatform;
|
||||||
|
if (daemonPlatform === 'mac' || daemonPlatform === 'darwin') daemonPlatform = 'macos';
|
||||||
|
if (daemonPlatform === 'win32' || daemonPlatform === 'windows') {
|
||||||
|
daemonPlatform = 'windows';
|
||||||
|
daemonFileName = daemonFileName + '.exe';
|
||||||
|
}
|
||||||
|
const daemonFilePath = path.join(daemonDir, daemonFileName);
|
||||||
|
const daemonVersionPath = path.join(__dirname, 'daemon.ver');
|
||||||
|
const tmpZipPath = path.join(__dirname, '..', 'dist', 'daemon.zip');
|
||||||
const daemonURL = daemonURLTemplate
|
const daemonURL = daemonURLTemplate
|
||||||
.replace(/DAEMONVER/g, daemonVersion)
|
.replace(/DAEMONVER/g, daemonVersion)
|
||||||
.replace(/OSNAME/g, daemonPlatform);
|
.replace(/OSNAME/g, daemonPlatform);
|
||||||
const tmpZipPath = 'dist/daemon.zip';
|
|
||||||
|
|
||||||
console.log('\x1b[34minfo\x1b[0m Downloading daemon...');
|
// If a daemon and daemon.ver exists, check to see if it matches the current daemon version
|
||||||
axios
|
const hasDaemonDownloaded = fs.existsSync(daemonFilePath);
|
||||||
.request({
|
const hasDaemonVersion = fs.existsSync(daemonVersionPath);
|
||||||
responseType: 'arraybuffer',
|
let downloadedDaemonVersion;
|
||||||
url: daemonURL,
|
if (hasDaemonVersion) {
|
||||||
method: 'get',
|
downloadedDaemonVersion = fs.readFileSync(daemonVersionPath, "utf8");
|
||||||
headers: {
|
}
|
||||||
'Content-Type': 'application/zip',
|
|
||||||
},
|
if (hasDaemonDownloaded && hasDaemonVersion && downloadedDaemonVersion === daemonVersion) {
|
||||||
})
|
console.log('\x1b[34minfo\x1b[0m Daemon already downloaded');
|
||||||
.then(
|
resolve('Done');
|
||||||
result =>
|
return;
|
||||||
new Promise((newResolve, newReject) => {
|
} else {
|
||||||
fs.writeFile(tmpZipPath, result.data, error => {
|
console.log('\x1b[34minfo\x1b[0m Downloading daemon...');
|
||||||
if (error) return newReject(error);
|
axios
|
||||||
return newResolve();
|
.request({
|
||||||
});
|
responseType: 'arraybuffer',
|
||||||
})
|
url: daemonURL,
|
||||||
)
|
method: 'get',
|
||||||
.then(() => del(`${daemonDir}/${daemonFileName}*`))
|
headers: {
|
||||||
.then(() =>
|
'Content-Type': 'application/zip',
|
||||||
decompress(tmpZipPath, daemonDir, {
|
},
|
||||||
filter: file =>
|
|
||||||
path.basename(file.path).replace(path.extname(file.path), '') === daemonFileName,
|
|
||||||
})
|
})
|
||||||
)
|
.then(
|
||||||
.then(() => {
|
result =>
|
||||||
console.log('\x1b[32msuccess\x1b[0m Daemon downloaded!');
|
new Promise((newResolve, newReject) => {
|
||||||
resolve(true);
|
const distPath = path.join(__dirname, '..', 'dist');
|
||||||
})
|
const hasDistFolder = fs.existsSync(distPath);
|
||||||
.catch(error => {
|
|
||||||
console.error(
|
if (!hasDistFolder) {
|
||||||
`\x1b[31merror\x1b[0m Daemon download failed due to: \x1b[35m${error}\x1b[0m`
|
fs.mkdirSync(distPath);
|
||||||
);
|
}
|
||||||
reject(error);
|
|
||||||
});
|
fs.writeFile(tmpZipPath, result.data, error => {
|
||||||
|
if (error) return newReject(error);
|
||||||
|
return newResolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then(() => del(`${daemonFilePath}*`))
|
||||||
|
.then(() => decompress(tmpZipPath, daemonDir, {
|
||||||
|
filter: file =>
|
||||||
|
path.basename(file.path) === daemonFileName,
|
||||||
|
}))
|
||||||
|
.then(() => {
|
||||||
|
console.log('\x1b[32msuccess\x1b[0m Daemon downloaded!');
|
||||||
|
if (hasDaemonVersion) {
|
||||||
|
del(daemonVersionPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(daemonVersionPath, daemonVersion, "utf8")
|
||||||
|
resolve('Done');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(
|
||||||
|
`\x1b[31merror\x1b[0m Daemon download failed due to: \x1b[35m${error}\x1b[0m`
|
||||||
|
);
|
||||||
|
reject(error);
|
||||||
|
})
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = downloadDaemon;
|
module.exports = downloadDaemon;
|
||||||
|
|
|
@ -73,6 +73,5 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"artifactName": "${productName}_${version}.${ext}",
|
"artifactName": "${productName}_${version}.${ext}"
|
||||||
"beforeBuild": "./build/checkDaemonPlatform.js"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "LBRY",
|
"name": "LBRY",
|
||||||
"version": "0.22.2",
|
"version": "0.23.0",
|
||||||
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"lbry"
|
"lbry"
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
"release": "yarn compile && electron-builder build",
|
"release": "yarn compile && electron-builder build",
|
||||||
"precommit": "lint-staged",
|
"precommit": "lint-staged",
|
||||||
"preinstall": "yarn cache clean lbry-redux",
|
"preinstall": "yarn cache clean lbry-redux",
|
||||||
"postinstall": "electron-builder install-app-deps & node build/downloadDaemon.js"
|
"postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bluebird": "^3.5.1",
|
"bluebird": "^3.5.1",
|
||||||
|
@ -71,6 +71,7 @@
|
||||||
"redux-persist-transform-filter": "0.0.16",
|
"redux-persist-transform-filter": "0.0.16",
|
||||||
"redux-thunk": "^2.2.0",
|
"redux-thunk": "^2.2.0",
|
||||||
"remark": "^9.0.0",
|
"remark": "^9.0.0",
|
||||||
|
"remark-emoji": "^2.0.1",
|
||||||
"remark-react": "^4.0.3",
|
"remark-react": "^4.0.3",
|
||||||
"render-media": "^3.1.0",
|
"render-media": "^3.1.0",
|
||||||
"reselect": "^3.0.0",
|
"reselect": "^3.0.0",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import remark from 'remark';
|
import remark from 'remark';
|
||||||
import reactRenderer from 'remark-react';
|
import reactRenderer from 'remark-react';
|
||||||
|
import remarkEmoji from 'remark-emoji';
|
||||||
import ExternalLink from 'component/externalLink';
|
import ExternalLink from 'component/externalLink';
|
||||||
import defaultSchema from 'hast-util-sanitize/lib/github.json';
|
import defaultSchema from 'hast-util-sanitize/lib/github.json';
|
||||||
|
|
||||||
|
@ -16,7 +17,11 @@ type MarkdownProps = {
|
||||||
promptLinks?: boolean,
|
promptLinks?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SimpleLink = ({ href, title, children }) => (<a href={href} title={title}>{children}</a>);
|
const SimpleLink = ({ href, title, children }) => (
|
||||||
|
<a href={href} title={title}>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
const MarkdownPreview = (props: MarkdownProps) => {
|
const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
const { content, externalLinks, promptLinks } = props;
|
const { content, externalLinks, promptLinks } = props;
|
||||||
|
@ -30,6 +35,7 @@ const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
<div className="markdown-preview">
|
<div className="markdown-preview">
|
||||||
{
|
{
|
||||||
remark()
|
remark()
|
||||||
|
.use(remarkEmoji)
|
||||||
.use(reactRenderer, remarkOptions)
|
.use(reactRenderer, remarkOptions)
|
||||||
.processSync(content).contents
|
.processSync(content).contents
|
||||||
}
|
}
|
|
@ -39,8 +39,16 @@ class Page extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Props) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
const { loading } = this.props;
|
const { loading } = this.props;
|
||||||
|
const { showLoader } = this.state;
|
||||||
|
|
||||||
if (!this.loaderTimeout && !prevProps.loading && loading) {
|
if (!this.loaderTimeout && !prevProps.loading && loading) {
|
||||||
this.beginLoadingTimeout();
|
this.beginLoadingTimeout();
|
||||||
|
} else if (!loading && this.loaderTimeout) {
|
||||||
|
clearTimeout(this.loaderTimeout);
|
||||||
|
|
||||||
|
if (showLoader) {
|
||||||
|
this.removeLoader();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +64,10 @@ class Page extends React.PureComponent<Props, State> {
|
||||||
}, LOADER_TIMEOUT);
|
}, LOADER_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeLoader() {
|
||||||
|
this.setState({ showLoader: false });
|
||||||
|
}
|
||||||
|
|
||||||
loaderTimeout: ?TimeoutID;
|
loaderTimeout: ?TimeoutID;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ class UriIndicator extends React.PureComponent<Props> {
|
||||||
noPadding
|
noPadding
|
||||||
className="btn--uri-indicator"
|
className="btn--uri-indicator"
|
||||||
navigate="/show"
|
navigate="/show"
|
||||||
navigateParams={{ uri: channelLink }}
|
navigateParams={{ uri: channelLink, page: 1 }}
|
||||||
>
|
>
|
||||||
{inner}
|
{inner}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import LoadingScreen from 'component/common/loading-screen';
|
||||||
// ThreeJS
|
// ThreeJS
|
||||||
import * as THREE from './internal/three';
|
import * as THREE from './internal/three';
|
||||||
import detectWebGL from './internal/detector';
|
import detectWebGL from './internal/detector';
|
||||||
|
import ThreeGrid from './internal/grid';
|
||||||
import ThreeScene from './internal/scene';
|
import ThreeScene from './internal/scene';
|
||||||
import ThreeLoader from './internal/loader';
|
import ThreeLoader from './internal/loader';
|
||||||
import ThreeRenderer from './internal/renderer';
|
import ThreeRenderer from './internal/renderer';
|
||||||
|
@ -77,6 +78,12 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
window.removeEventListener('resize', this.handleResize, false);
|
window.removeEventListener('resize', this.handleResize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transformGroup(group) {
|
||||||
|
this.fitMeshToCamera(group);
|
||||||
|
this.createWireFrame(group);
|
||||||
|
this.updateControlsTarget(group.position);
|
||||||
|
}
|
||||||
|
|
||||||
createOrbitControls(camera, canvas) {
|
createOrbitControls(camera, canvas) {
|
||||||
const { autoRotate } = this.props;
|
const { autoRotate } = this.props;
|
||||||
const controls = new THREE.OrbitControls(camera, canvas);
|
const controls = new THREE.OrbitControls(camera, canvas);
|
||||||
|
@ -87,6 +94,7 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
controls.minDistance = 1;
|
controls.minDistance = 1;
|
||||||
controls.maxDistance = 50;
|
controls.maxDistance = 50;
|
||||||
controls.autoRotate = autoRotate;
|
controls.autoRotate = autoRotate;
|
||||||
|
controls.enablePan = false;
|
||||||
return controls;
|
return controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,32 +122,6 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
group.add(this.wireframe);
|
group.add(this.wireframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
createMesh(geometry) {
|
|
||||||
const material = new THREE.MeshPhongMaterial({
|
|
||||||
opacity: 1,
|
|
||||||
transparent: true,
|
|
||||||
depthWrite: true,
|
|
||||||
vertexColors: THREE.FaceColors,
|
|
||||||
// Positive value pushes polygon further away
|
|
||||||
polygonOffsetFactor: 1,
|
|
||||||
polygonOffsetUnits: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set material color
|
|
||||||
material.color.set(this.materialColors.green);
|
|
||||||
|
|
||||||
const mesh = new THREE.Mesh(geometry, material);
|
|
||||||
|
|
||||||
// Assign name
|
|
||||||
mesh.name = 'objectGroup';
|
|
||||||
|
|
||||||
this.scene.add(mesh);
|
|
||||||
this.fitMeshToCamera(mesh);
|
|
||||||
this.createWireFrame(mesh);
|
|
||||||
this.updateControlsTarget(mesh.position);
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleWireFrame(show = false) {
|
toggleWireFrame(show = false) {
|
||||||
this.wireframe.opacity = show ? 1 : 0;
|
this.wireframe.opacity = show ? 1 : 0;
|
||||||
this.mesh.material.opacity = show ? 0 : 1;
|
this.mesh.material.opacity = show ? 0 : 1;
|
||||||
|
@ -151,7 +133,7 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
|
|
||||||
group.traverse(child => {
|
group.traverse(child => {
|
||||||
if (child instanceof THREE.Mesh) {
|
if (child instanceof THREE.Mesh) {
|
||||||
const box = new THREE.Box3().setFromObject(group);
|
const box = new THREE.Box3().setFromObject(child);
|
||||||
// Max
|
// Max
|
||||||
max.x = box.max.x > max.x ? box.max.x : max.x;
|
max.x = box.max.x > max.x ? box.max.x : max.x;
|
||||||
max.y = box.max.y > max.y ? box.max.y : max.y;
|
max.y = box.max.y > max.y ? box.max.y : max.y;
|
||||||
|
@ -165,12 +147,18 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
|
|
||||||
const meshY = Math.abs(max.y - min.y);
|
const meshY = Math.abs(max.y - min.y);
|
||||||
const meshX = Math.abs(max.x - min.x);
|
const meshX = Math.abs(max.x - min.x);
|
||||||
const scaleFactor = 15 / Math.max(meshX, meshY);
|
|
||||||
|
const scaleFactor = 10 / Math.max(meshX, meshY);
|
||||||
|
|
||||||
group.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
group.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
||||||
group.position.setY((meshY / 2) * scaleFactor);
|
group.position.setY((meshY / 2) * scaleFactor);
|
||||||
|
|
||||||
|
// Reset object position
|
||||||
|
const box = new THREE.Box3().setFromObject(group);
|
||||||
|
box.getCenter(group.position);
|
||||||
|
|
||||||
group.position.multiplyScalar(-1);
|
group.position.multiplyScalar(-1);
|
||||||
group.position.setY((meshY * scaleFactor) / 2);
|
group.position.setY(group.position.y + meshY * scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
startLoader() {
|
startLoader() {
|
||||||
|
@ -217,12 +205,52 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
this.controls.update();
|
this.controls.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModel(fileType, data) {
|
renderStl(data) {
|
||||||
const geometry = this.createGeometry(data);
|
const geometry = this.createGeometry(data);
|
||||||
this.mesh = this.createMesh(geometry);
|
const group = new THREE.Mesh(geometry, this.material);
|
||||||
|
// Assign name
|
||||||
|
group.name = 'objectGroup';
|
||||||
|
this.scene.add(group);
|
||||||
|
this.transformGroup(group);
|
||||||
|
this.mesh = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderObj(event) {
|
||||||
|
const mesh = event.detail.loaderRootNode;
|
||||||
|
const group = new THREE.Group();
|
||||||
|
group.name = 'objGroup';
|
||||||
|
|
||||||
|
// Assign new material
|
||||||
|
mesh.traverse(child => {
|
||||||
|
if (child instanceof THREE.Mesh) {
|
||||||
|
// Get geometry from child
|
||||||
|
const geometry = new THREE.Geometry();
|
||||||
|
geometry.fromBufferGeometry(child.geometry);
|
||||||
|
// Create and regroup inner objects
|
||||||
|
const innerObj = new THREE.Mesh(geometry, this.material);
|
||||||
|
group.add(innerObj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scene.add(group);
|
||||||
|
this.transformGroup(group);
|
||||||
|
this.mesh = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderModel(fileType, parsedData) {
|
||||||
|
const renderTypes = {
|
||||||
|
stl: data => this.renderStl(data),
|
||||||
|
obj: data => this.renderObj(data),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (renderTypes[fileType]) {
|
||||||
|
renderTypes[fileType](parsedData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderScene() {
|
renderScene() {
|
||||||
|
const { gridColor, centerLineColor } = this.theme;
|
||||||
|
|
||||||
this.renderer = ThreeRenderer({
|
this.renderer = ThreeRenderer({
|
||||||
antialias: true,
|
antialias: true,
|
||||||
shadowMap: true,
|
shadowMap: true,
|
||||||
|
@ -230,20 +258,40 @@ class ThreeViewer extends React.PureComponent<Props> {
|
||||||
|
|
||||||
this.scene = ThreeScene({
|
this.scene = ThreeScene({
|
||||||
showFog: true,
|
showFog: true,
|
||||||
showGrid: true,
|
|
||||||
...this.theme,
|
...this.theme,
|
||||||
});
|
});
|
||||||
|
|
||||||
const viewer = this.viewer.current;
|
const viewer = this.viewer.current;
|
||||||
const canvas = this.renderer.domElement;
|
const canvas = this.renderer.domElement;
|
||||||
const { offsetWidth: width, offsetHeight: height } = viewer;
|
const { offsetWidth: width, offsetHeight: height } = viewer;
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
this.grid = ThreeGrid({ size: 100, gridColor, centerLineColor });
|
||||||
|
this.scene.add(this.grid);
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
this.camera = new THREE.PerspectiveCamera(80, width / height, 0.1, 1000);
|
this.camera = new THREE.PerspectiveCamera(80, width / height, 0.1, 1000);
|
||||||
this.camera.position.set(-9.5, 14, 11);
|
this.camera.position.set(-9.5, 14, 11);
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
this.controls = this.createOrbitControls(this.camera, canvas);
|
this.controls = this.createOrbitControls(this.camera, canvas);
|
||||||
|
|
||||||
// Set viewer size
|
// Set viewer size
|
||||||
this.renderer.setSize(width, height);
|
this.renderer.setSize(width, height);
|
||||||
|
|
||||||
|
// Create model material
|
||||||
|
this.material = new THREE.MeshPhongMaterial({
|
||||||
|
opacity: 1,
|
||||||
|
transparent: true,
|
||||||
|
// depthWrite: true,
|
||||||
|
vertexColors: THREE.FaceColors,
|
||||||
|
// Positive value pushes polygon further away
|
||||||
|
// polygonOffsetFactor: 1,
|
||||||
|
// polygonOffsetUnits: 1,
|
||||||
|
});
|
||||||
|
// Set material color
|
||||||
|
this.material.color.set(this.materialColors.green);
|
||||||
|
|
||||||
// Load file and render mesh
|
// Load file and render mesh
|
||||||
this.startLoader();
|
this.startLoader();
|
||||||
|
|
||||||
|
|
13
src/renderer/component/viewers/threeViewer/internal/grid.js
Normal file
13
src/renderer/component/viewers/threeViewer/internal/grid.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { GridHelper, Color } from './three';
|
||||||
|
|
||||||
|
const ThreeGrid = ({ size, gridColor, centerLineColor }) => {
|
||||||
|
const divisions = size / 2;
|
||||||
|
const grid = new GridHelper(size, divisions, new Color(centerLineColor), new Color(gridColor));
|
||||||
|
|
||||||
|
grid.material.opacity = 0.4;
|
||||||
|
grid.material.transparent = true;
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ThreeGrid;
|
|
@ -1,4 +1,4 @@
|
||||||
import { LoadingManager, STLLoader, OBJLoader } from './three';
|
import { LoadingManager, STLLoader, OBJLoader2 } from './three';
|
||||||
|
|
||||||
const Manager = ({ onLoad, onStart, onError }) => {
|
const Manager = ({ onLoad, onStart, onError }) => {
|
||||||
const manager = new LoadingManager();
|
const manager = new LoadingManager();
|
||||||
|
@ -12,7 +12,7 @@ const Manager = ({ onLoad, onStart, onError }) => {
|
||||||
const Loader = (fileType, manager) => {
|
const Loader = (fileType, manager) => {
|
||||||
const fileTypes = {
|
const fileTypes = {
|
||||||
stl: () => new STLLoader(manager),
|
stl: () => new STLLoader(manager),
|
||||||
obj: () => new OBJLoader(manager),
|
obj: () => new OBJLoader2(manager),
|
||||||
};
|
};
|
||||||
return fileTypes[fileType] ? fileTypes[fileType]() : null;
|
return fileTypes[fileType] ? fileTypes[fileType]() : null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
import * as THREE from './three';
|
import * as THREE from './three';
|
||||||
|
|
||||||
const addGrid = (scene, { gridColor, centerLineColor, size }) => {
|
|
||||||
const divisions = size / 2;
|
|
||||||
const grid = new THREE.GridHelper(
|
|
||||||
size,
|
|
||||||
divisions,
|
|
||||||
new THREE.Color(centerLineColor),
|
|
||||||
new THREE.Color(gridColor)
|
|
||||||
);
|
|
||||||
grid.material.opacity = 0.4;
|
|
||||||
grid.material.transparent = true;
|
|
||||||
scene.add(grid);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addLights = (scene, color, groundColor) => {
|
const addLights = (scene, color, groundColor) => {
|
||||||
// Light color
|
// Light color
|
||||||
const lightColor = new THREE.Color(color);
|
const lightColor = new THREE.Color(color);
|
||||||
|
@ -30,7 +17,7 @@ const addLights = (scene, color, groundColor) => {
|
||||||
scene.add(shadowLight);
|
scene.add(shadowLight);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, centerLineColor }) => {
|
const Scene = ({ backgroundColor, groundColor, showFog }) => {
|
||||||
// Convert color
|
// Convert color
|
||||||
const bgColor = new THREE.Color(backgroundColor);
|
const bgColor = new THREE.Color(backgroundColor);
|
||||||
// New scene
|
// New scene
|
||||||
|
@ -39,17 +26,8 @@ const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, cen
|
||||||
scene.background = bgColor;
|
scene.background = bgColor;
|
||||||
// Fog effect
|
// Fog effect
|
||||||
scene.fog = showFog === true ? new THREE.Fog(bgColor, 1, 95) : null;
|
scene.fog = showFog === true ? new THREE.Fog(bgColor, 1, 95) : null;
|
||||||
// Add grid
|
|
||||||
if (showGrid) {
|
|
||||||
addGrid(scene, {
|
|
||||||
size: 100,
|
|
||||||
gridColor,
|
|
||||||
centerLineColor,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Add basic lights
|
// Add basic lights
|
||||||
addLights(scene, '#FFFFFF', groundColor);
|
addLights(scene, '#FFFFFF', groundColor);
|
||||||
|
|
||||||
// Return new three scene
|
// Return new three scene
|
||||||
return scene;
|
return scene;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,8 @@ import * as THREE from 'three';
|
||||||
// Fix: https://github.com/mrdoob/three.js/issues/9562#issuecomment-383390251
|
// Fix: https://github.com/mrdoob/three.js/issues/9562#issuecomment-383390251
|
||||||
global.THREE = THREE;
|
global.THREE = THREE;
|
||||||
require('three/examples/js/controls/OrbitControls');
|
require('three/examples/js/controls/OrbitControls');
|
||||||
require('three/examples/js/loaders/OBJLoader');
|
require('three/examples/js/loaders/LoaderSupport');
|
||||||
|
require('three/examples/js/loaders/OBJLoader2');
|
||||||
require('three/examples/js/loaders/STLLoader');
|
require('three/examples/js/loaders/STLLoader');
|
||||||
|
|
||||||
module.exports = global.THREE;
|
module.exports = global.THREE;
|
||||||
|
|
|
@ -23,7 +23,7 @@ class ModalIncompatibleDaemon extends React.PureComponent<Props> {
|
||||||
onAborted={quit}
|
onAborted={quit}
|
||||||
>
|
>
|
||||||
{__(
|
{__(
|
||||||
'This browser is running with an incompatible version of the LBRY protocol, please close the LBRY app and rerun the installation package to repair it'
|
'This browser is running with an incompatible version of the LBRY protocol, please close the LBRY app and rerun the installation package to repair it. '
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
|
|
|
@ -13,7 +13,7 @@ import SubscriptionsPage from './view';
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
loading:
|
loading:
|
||||||
selectIsFetchingSubscriptions(state) ||
|
selectIsFetchingSubscriptions(state) ||
|
||||||
Object.keys(selectSubscriptionsBeingFetched(state)).length,
|
Boolean(Object.keys(selectSubscriptionsBeingFetched(state)).length),
|
||||||
subscriptionsBeingFetched: selectSubscriptionsBeingFetched(state),
|
subscriptionsBeingFetched: selectSubscriptionsBeingFetched(state),
|
||||||
subscriptions: selectSubscriptions(state),
|
subscriptions: selectSubscriptions(state),
|
||||||
subscriptionClaims: selectSubscriptionClaims(state),
|
subscriptionClaims: selectSubscriptionClaims(state),
|
||||||
|
|
|
@ -184,6 +184,7 @@ p {
|
||||||
.main {
|
.main {
|
||||||
padding: $spacing-width $spacing-width;
|
padding: $spacing-width $spacing-width;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main--contained {
|
.main--contained {
|
||||||
|
|
|
@ -80,9 +80,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
color: var(--btn-external-color);
|
color: var(--btn-external-color);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-left: 2em;
|
||||||
|
p {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol > li,
|
||||||
|
ul > li {
|
||||||
|
list-style-position: outside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -5446,6 +5446,10 @@ lodash.tail@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
|
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
|
||||||
|
|
||||||
|
lodash.toarray@^4.4.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
|
||||||
|
|
||||||
lodash.uniq@^4.5.0:
|
lodash.uniq@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
|
@ -5952,6 +5956,12 @@ node-abi@^2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver "^5.4.1"
|
semver "^5.4.1"
|
||||||
|
|
||||||
|
node-emoji@^1.4.1:
|
||||||
|
version "1.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.8.1.tgz#6eec6bfb07421e2148c75c6bba72421f8530a826"
|
||||||
|
dependencies:
|
||||||
|
lodash.toarray "^4.4.0"
|
||||||
|
|
||||||
node-fetch@^1.0.1:
|
node-fetch@^1.0.1:
|
||||||
version "1.7.3"
|
version "1.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||||
|
@ -7454,6 +7464,13 @@ relateurl@0.2.x:
|
||||||
version "0.2.7"
|
version "0.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||||
|
|
||||||
|
remark-emoji@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.0.1.tgz#6de4be7acb05b8534b6bad679d56eab24fba5e06"
|
||||||
|
dependencies:
|
||||||
|
node-emoji "^1.4.1"
|
||||||
|
unist-util-visit "^1.1.0"
|
||||||
|
|
||||||
remark-parse@^5.0.0:
|
remark-parse@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
|
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
|
||||||
|
|
Loading…
Add table
Reference in a new issue