Merge branch 'master' into wallet-encryption

This commit is contained in:
Shawn Khameneh 2018-07-25 14:30:24 -05:00 committed by GitHub
commit 2ccf40b18e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 263 additions and 152 deletions

3
.gitignore vendored
View file

@ -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

View file

@ -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";

View file

@ -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

View file

@ -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();
};

View file

@ -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;

View file

@ -73,6 +73,5 @@
} }
] ]
}, },
"artifactName": "${productName}_${version}.${ext}", "artifactName": "${productName}_${version}.${ext}"
"beforeBuild": "./build/checkDaemonPlatform.js"
} }

View file

@ -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",

View file

@ -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
} }

View file

@ -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() {

View file

@ -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>

View file

@ -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();

View 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;

View file

@ -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;
}; };

View file

@ -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;
}; };

View file

@ -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;

View file

@ -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"

View file

@ -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),

View file

@ -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 {

View file

@ -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;
} }
} }

View file

View file

@ -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"