Merge branch 'i18n' of github.com:intnick/lbry-app into i18n

This commit is contained in:
Intnick 2017-06-01 17:02:16 +02:00
commit 02ed8145ca
29 changed files with 178 additions and 136 deletions

View file

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.11.5rc1 current_version = 0.11.7
commit = True commit = True
tag = True tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<release>[a-z]+)(?P<candidate>\d+))? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<release>[a-z]+)(?P<candidate>\d+))?

View file

@ -16,10 +16,8 @@ Web UI version numbers should always match the corresponding version of LBRY App
* *
### Fixed ### Fixed
* Eliminated instance of costs being double fetched *
* Fixed issue preventing file re-download *
* Fixed race condition that could prevent file playbac
* Fixed issue with batch actions and thunk
### Deprecated ### Deprecated
* *
@ -29,6 +27,43 @@ Web UI version numbers should always match the corresponding version of LBRY App
* *
* *
## [0.11.7] - 2017-05-30
### Changed
* Video player switched from plyr to render-media
### Fixed
* Video player should behave better on streaming
* Daemon times out more quickly when it cannot start
* Connection should fail more cleanly, rather than get stuck entirely
* Closing modal dialogs was broken on some download and stream errors
* Discover landing page improperly showed loading error when it was loading correctly
## [0.11.6] - 2017-05-29
### Changed
* Do not use a separate claim cache for publishes
### Fixed
* Upgrade process should now works on Windows
* Crudely handle failed publishes missing outpoints
## [0.11.5] - 2017-05-28
### Fixed
* Eliminated instance of costs being double fetched
* Fixed issue preventing file re-download
* Fixed race condition that could prevent file playbac
* Fixed issue with batch actions and thunk
## [0.11.4] - 2017-05-26 ## [0.11.4] - 2017-05-26
### Added ### Added

View file

@ -48,3 +48,7 @@ to create distributable packages, which is run by calling:
This project has currently only been worked on in Linux and macOS. If you are on Windows, you can This project has currently only been worked on in Linux and macOS. If you are on Windows, you can
checkout out the build steps in [appveyor.yml](https://github.com/lbryio/lbry-app/blob/master/.appveyor.yml) and probably figure out something from there. checkout out the build steps in [appveyor.yml](https://github.com/lbryio/lbry-app/blob/master/.appveyor.yml) and probably figure out something from there.
## Internationalization
If you want to help translating the lbry-app, you can copy the en.json file in /app/locales and modify the values while leaving the keys as their original English strings. An example for this would be: `"Skip": "Überspringen",` Translations should automatically show up in options.

View file

@ -309,5 +309,10 @@
"Wallet": "Wallet", "Wallet": "Wallet",
"Looking up version info": "Looking up version info", "Looking up version info": "Looking up version info",
"It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds.": "It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds.", "It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds.": "It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds.",
"Fetching cost info": "Fetching cost info" "Fetching cost info": "Fetching cost info",
} "Testing network": "Testing network",
"Connection Failure": "Connection Failure",
"Try closing all LBRY processes and starting again. If this still happpens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug.": "Try closing all LBRY processes and starting again. If this still happpens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug.",
"Timed Out": "Timed Out",
"Testing Network": "Testing Network"
}

View file

@ -1,6 +1,6 @@
{ {
"name": "LBRY", "name": "LBRY",
"version": "0.11.5rc1", "version": "0.11.7",
"main": "main.js", "main": "main.js",
"description": "LBRY is a fully decentralized, open-source protocol facilitating the discovery, access, and (sometimes) purchase of data.", "description": "LBRY is a fully decentralized, open-source protocol facilitating the discovery, access, and (sometimes) purchase of data.",
"author": { "author": {

View file

@ -1,5 +0,0 @@
start /min %~dp0node_modules\.bin\electron app
pause

View file

@ -209,7 +209,7 @@ export function doLoadVideo(uri) {
} }
} }
export function doPurchaseUri(uri) { export function doPurchaseUri(uri, purchaseModalName) {
return function(dispatch, getState) { return function(dispatch, getState) {
const state = getState() const state = getState()
const balance = selectBalance(state) const balance = selectBalance(state)
@ -244,7 +244,7 @@ export function doPurchaseUri(uri) {
if (cost > balance) { if (cost > balance) {
dispatch(doOpenModal('notEnoughCredits')) dispatch(doOpenModal('notEnoughCredits'))
} else { } else {
dispatch(doOpenModal('affirmPurchase')) dispatch(doOpenModal(purchaseModalName))
} }
return Promise.resolve() return Promise.resolve()
@ -274,16 +274,16 @@ export function doFetchClaimsByChannel(uri) {
} }
} }
export function doClaimListMine() { export function doFetchClaimListMine() {
return function(dispatch, getState) { return function(dispatch, getState) {
dispatch({ dispatch({
type: types.CLAIM_LIST_MINE_STARTED type: types.FETCH_CLAIM_LIST_MINE_STARTED
}) })
lbry.claim_list_mine().then((claims) => { lbry.claim_list_mine().then((claims) => {
dispatch({ dispatch({
type: types.CLAIM_LIST_MINE_COMPLETED, type: types.FETCH_CLAIM_LIST_MINE_COMPLETED,
data: { data: {
claims claims
} }

View file

@ -1,7 +1,7 @@
import * as types from 'constants/action_types' import * as types from 'constants/action_types'
import lbry from 'lbry' import lbry from 'lbry'
import { import {
doClaimListMine doFetchClaimListMine
} from 'actions/content' } from 'actions/content'
import { import {
selectClaimsByUri, selectClaimsByUri,
@ -110,7 +110,7 @@ export function doFetchFileInfosAndPublishedClaims() {
isFileInfoListPending = selectFileListIsPending(state) isFileInfoListPending = selectFileListIsPending(state)
if (isClaimListMinePending === undefined) { if (isClaimListMinePending === undefined) {
dispatch(doClaimListMine()) dispatch(doFetchClaimListMine())
} }
if (isFileInfoListPending === undefined) { if (isFileInfoListPending === undefined) {

View file

@ -66,7 +66,7 @@ const perform = (dispatch) => ({
dispatch(doDeleteFile(fileInfo, deleteFromComputer)) dispatch(doDeleteFile(fileInfo, deleteFromComputer))
}, },
openModal: (modal) => dispatch(doOpenModal(modal)), openModal: (modal) => dispatch(doOpenModal(modal)),
startDownload: (uri) => dispatch(doPurchaseUri(uri)), startDownload: (uri) => dispatch(doPurchaseUri(uri, 'affirmPurchase')),
loadVideo: (uri) => dispatch(doLoadVideo(uri)), loadVideo: (uri) => dispatch(doLoadVideo(uri)),
}) })

View file

@ -122,7 +122,7 @@ class FileActions extends React.Component {
<DropDownMenuItem key={1} onClick={() => openModal('confirmRemove')} label={__("Remove...")} /> <DropDownMenuItem key={1} onClick={() => openModal('confirmRemove')} label={__("Remove...")} />
</DropDownMenu> : '' } </DropDownMenu> : '' }
<Modal type="confirm" isOpen={modal == 'affirmPurchase'} <Modal type="confirm" isOpen={modal == 'affirmPurchase'}
contentLabel={__("Confirm Purchase")} onConfirmed={this.onAffirmPurchase.bind(this)} onAborted={this.props.closeModal}> contentLabel={__("Confirm Purchase")} onConfirmed={this.onAffirmPurchase.bind(this)} onAborted={closeModal}>
{__("This will purchase")} <strong>{title}</strong> {__("for")} <strong><FilePrice uri={uri} look="plain" /></strong> {__("credits")}. {__("This will purchase")} <strong>{title}</strong> {__("for")} <strong><FilePrice uri={uri} look="plain" /></strong> {__("credits")}.
</Modal> </Modal>
<Modal isOpen={modal == 'notEnoughCredits'} contentLabel={__("Not enough credits")} <Modal isOpen={modal == 'notEnoughCredits'} contentLabel={__("Not enough credits")}

View file

@ -31,9 +31,11 @@ class LoadScreen extends React.Component {
<img src={imgSrc} alt="LBRY"/> <img src={imgSrc} alt="LBRY"/>
<div className="load-screen__message"> <div className="load-screen__message">
<h3> <h3>
<BusyMessage message={this.props.message} /> {!this.props.isWarning ?
<BusyMessage message={this.props.message} /> :
<span><Icon icon="icon-warning" />{' ' + this.props.message}</span> }
</h3> </h3>
{this.props.isWarning ? <Icon icon="icon-warning" /> : null} <span className={'load-screen__details ' + (this.props.isWarning ? 'load-screen__details--warning' : '')}>{this.props.details}</span> <span className={'load-screen__details ' + (this.props.isWarning ? 'load-screen__details--warning' : '')}>{this.props.details}</span>
</div> </div>
</div> </div>
); );

View file

@ -13,6 +13,7 @@ export class SplashScreen extends React.Component {
this.state = { this.state = {
details: __('Starting daemon'), details: __('Starting daemon'),
message: __("Connecting"),
isLagging: false, isLagging: false,
}; };
} }
@ -29,11 +30,12 @@ export class SplashScreen extends React.Component {
// TODO: This is a hack, and the logic should live in the daemon // TODO: This is a hack, and the logic should live in the daemon
// to give us a better sense of when we are actually started // to give us a better sense of when we are actually started
this.setState({ this.setState({
details: __('Waiting for name resolution'), message: __("Testing Network"),
details: __("Waiting for name resolution"),
isLagging: false isLagging: false
}); });
lbry.resolve({uri: 'lbry://one'}).then(() => { lbry.resolve({uri: "lbry://one"}).then(() => {
this.props.onLoadDone(); this.props.onLoadDone();
}); });
return; return;
@ -48,21 +50,19 @@ export class SplashScreen extends React.Component {
} }
componentDidMount() { componentDidMount() {
lbry.connect().then((isConnected) => { lbry.connect()
if (isConnected) { .then(() => { this.updateStatus() })
this.updateStatus(); .catch(() => {
} else {
this.setState({ this.setState({
isLagging: true, isLagging: true,
message: __("Failed to connect to LBRY"), message: __("Connection Failure"),
details: __("LBRY was unable to start and connect properly.") details: __("Try closing all LBRY processes and starting again. If this still happpens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug.")
}) })
} })
})
} }
render() { render() {
return <LoadScreen message={this.props.message} details={this.state.details} isWarning={this.state.isLagging} /> return <LoadScreen message={this.state.message} details={this.state.details} isWarning={this.state.isLagging} />
} }
} }

View file

@ -47,7 +47,7 @@ const makeSelect = () => {
const perform = (dispatch) => ({ const perform = (dispatch) => ({
loadVideo: (uri) => dispatch(doLoadVideo(uri)), loadVideo: (uri) => dispatch(doLoadVideo(uri)),
purchaseUri: (uri) => dispatch(doPurchaseUri(uri)), purchaseUri: (uri) => dispatch(doPurchaseUri(uri, 'affirmPurchaseAndPlay')),
closeModal: () => dispatch(doCloseModal()), closeModal: () => dispatch(doCloseModal()),
}) })

View file

@ -52,28 +52,25 @@ class VideoPlayButton extends React.Component {
className="video__play-button" className="video__play-button"
icon="icon-play" icon="icon-play"
onClick={this.onWatchClick.bind(this)} /> onClick={this.onWatchClick.bind(this)} />
{modal} <Modal contentLabel={__("Not enough credits")} isOpen={modal == 'notEnoughCredits'} onConfirmed={closeModal}>
<Modal contentLabel={__("Not enough credits")} isOpen={modal == 'notEnoughCredits'} onConfirmed={() => { this.closeModal() }}>
{__("You don't have enough LBRY credits to pay for this stream.")} {__("You don't have enough LBRY credits to pay for this stream.")}
</Modal> </Modal>
<Modal <Modal
type="confirm" type="confirm"
isOpen={modal == 'affirmPurchase'} isOpen={modal == 'affirmPurchaseAndPlay'}
contentLabel={__("Confirm Purchase")} contentLabel={__("Confirm Purchase")}
onConfirmed={this.onPurchaseConfirmed.bind(this)} onConfirmed={this.onPurchaseConfirmed.bind(this)}
onAborted={closeModal}> onAborted={closeModal}>
{__("This will purchase")} <strong>{title}</strong> {__("for")} <strong><FilePrice uri={uri} look="plain" /></strong> {__("credits")}. {__("This will purchase")} <strong>{title}</strong> {__("for")} <strong><FilePrice uri={uri} look="plain" /></strong> {__("credits")}.
</Modal> </Modal>
<Modal <Modal
isOpen={modal == 'timedOut'} onConfirmed={() => { this.closeModal() }} contentLabel="Timed Out"> isOpen={modal == 'timedOut'} onConfirmed={closeModal} contentLabel={__("Timed Out")}>
{__("Sorry, your download timed out :(")} {__("Sorry, your download timed out :(")}
</Modal> </Modal>
</div>); </div>);
} }
} }
const plyr = require('plyr')
class Video extends React.Component { class Video extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
@ -114,7 +111,7 @@ class Video extends React.Component {
isPlaying || isLoading ? isPlaying || isLoading ?
(!isReadyToPlay ? (!isReadyToPlay ?
<span>{__("this is the world's worst loading screen and we shipped our software with it anyway...")} <br /><br />{loadStatusMessage}</span> : <span>{__("this is the world's worst loading screen and we shipped our software with it anyway...")} <br /><br />{loadStatusMessage}</span> :
<VideoPlayer poster={metadata.thumbnail} autoplay={isPlaying} downloadPath={fileInfo.download_path} />) : <VideoPlayer filename={fileInfo.file_name} poster={metadata.thumbnail} downloadPath={fileInfo.download_path} />) :
<div className="video__cover" style={{backgroundImage: 'url("' + metadata.thumbnail + '")'}}> <div className="video__cover" style={{backgroundImage: 'url("' + metadata.thumbnail + '")'}}>
<VideoPlayButton startPlaying={this.startPlaying.bind(this)} {...this.props} /> <VideoPlayButton startPlaying={this.startPlaying.bind(this)} {...this.props} />
</div> </div>
@ -123,18 +120,28 @@ class Video extends React.Component {
} }
} }
const from = require('from2')
const player = require('render-media')
const fs = require('fs')
class VideoPlayer extends React.Component { class VideoPlayer extends React.Component {
componentDidMount() { componentDidMount() {
const elem = this.refs.video const elem = this.refs.video
const { const {
autoplay,
downloadPath, downloadPath,
contentType, contentType,
filename,
} = this.props } = this.props
const players = plyr.setup(elem) const file = {
if (autoplay) { name: filename,
players[0].play() createReadStream: (opts) => {
return fs.createReadStream(downloadPath, opts)
}
} }
player.render(file, elem, {
autoplay: true,
controls: true,
})
} }
render() { render() {
@ -145,7 +152,7 @@ class VideoPlayer extends React.Component {
} = this.props } = this.props
return ( return (
<video controls id="video" ref="video" style={{backgroundImage: "url('" + poster + "')"}} > <video controls ref="video" style={{backgroundImage: "url('" + poster + "')"}} >
<source src={downloadPath} type={contentType} /> <source src={downloadPath} type={contentType} />
</video> </video>
) )

View file

@ -151,7 +151,7 @@ class WunderBar extends React.PureComponent {
onChange={this.onChange} onChange={this.onChange}
onKeyPress={this.onKeyPress} onKeyPress={this.onKeyPress}
value={this.state.address} value={this.state.address}
placeholder="Find movies, music, games, and more" /> placeholder={__("Find movies, music, games, and more")} />
</div> </div>
); );
} }

View file

@ -40,8 +40,8 @@ export const RESOLVE_URI_COMPLETED = 'RESOLVE_URI_COMPLETED'
export const RESOLVE_URI_CANCELED = 'RESOLVE_URI_CANCELED' export const RESOLVE_URI_CANCELED = 'RESOLVE_URI_CANCELED'
export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED' export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'
export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED' export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'
export const CLAIM_LIST_MINE_STARTED = 'CLAIM_LIST_MINE_STARTED' export const FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED'
export const CLAIM_LIST_MINE_COMPLETED = 'CLAIM_LIST_MINE_COMPLETED' export const FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED'
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED' export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'
export const FILE_LIST_COMPLETED = 'FILE_LIST_COMPLETED' export const FILE_LIST_COMPLETED = 'FILE_LIST_COMPLETED'
export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED' export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'

View file

@ -96,26 +96,27 @@ lbry.call = function (method, params, callback, errorCallback, connectFailedCall
lbry._connectPromise = null; lbry._connectPromise = null;
lbry.connect = function() { lbry.connect = function() {
if (lbry._connectPromise === null) { if (lbry._connectPromise === null) {
lbry._connectPromise = new Promise((resolve, reject) => { lbry._connectPromise = new Promise((resolve, reject) => {
let tryNum = 0
function checkDaemonStartedFailed() {
console.log('status error try num ' + tryNum)
if (tryNum <= 100) { // Move # of tries into constant or config option
setTimeout(() => {
tryNum++
checkDaemonStarted();
}, tryNum < 50 ? 400 : 1000);
}
else {
reject(new Error("Unable to connect to LBRY"));
}
}
// Check every half second to see if the daemon is accepting connections // Check every half second to see if the daemon is accepting connections
function checkDaemonStarted(tryNum = 0) { function checkDaemonStarted() {
lbry.isDaemonAcceptingConnections(function (runningStatus) { console.log('check daemon started try ' + tryNum)
if (runningStatus) { lbry.call('status', {}, resolve, checkDaemonStartedFailed, checkDaemonStartedFailed)
resolve(true);
}
else {
if (tryNum <= 600) { // Move # of tries into constant or config option
setTimeout(function () {
checkDaemonStarted(tryNum + 1);
}, tryNum < 100 ? 200 : 1000);
}
else {
reject(new Error(__("Unable to connect to LBRY")));
}
}
});
} }
checkDaemonStarted(); checkDaemonStarted();
@ -125,11 +126,6 @@ lbry.connect = function() {
return lbry._connectPromise; return lbry._connectPromise;
} }
lbry.isDaemonAcceptingConnections = function (callback) {
// Returns true/false whether the daemon is at a point it will start returning status
lbry.call('status', {}, () => callback(true), null, () => callback(false))
};
lbry.checkAddressIsMine = function(address, callback) { lbry.checkAddressIsMine = function(address, callback) {
lbry.call('address_is_mine', {address: address}, callback); lbry.call('address_is_mine', {address: address}, callback);
} }

View file

@ -90,7 +90,7 @@ var init = function() {
if (window.sessionStorage.getItem('loaded') == 'y') { if (window.sessionStorage.getItem('loaded') == 'y') {
onDaemonReady(); onDaemonReady();
} else { } else {
ReactDOM.render(<SplashScreen message={__("Connecting")} onLoadDone={onDaemonReady} />, canvas); ReactDOM.render(<SplashScreen onLoadDone={onDaemonReady} />, canvas);
} }
}; };

View file

@ -33,6 +33,10 @@ class DiscoverPage extends React.Component{
featuredUris, featuredUris,
fetchingFeaturedUris, fetchingFeaturedUris,
} = this.props } = this.props
const failedToLoad = !fetchingFeaturedUris && (
featuredUris === undefined ||
(featuredUris !== undefined && Object.keys(featuredUris).length === 0)
)
return ( return (
<main> <main>
@ -47,7 +51,7 @@ class DiscoverPage extends React.Component{
)) ))
} }
{ {
typeof featuredUris !== undefined && failedToLoad &&
<div className="empty">{__("Failed to load landing content.")}</div> <div className="empty">{__("Failed to load landing content.")}</div>
} }
</main> </main>

View file

@ -99,7 +99,7 @@ class HelpPage extends React.Component {
<div className="card__content"> <div className="card__content">
{this.state.appVersionInfo ? {this.state.appVersionInfo ?
(ver.lbrynet_update_available || ver.lbryum_update_available ? (ver.lbrynet_update_available || ver.lbryum_update_available ?
<p>{__("A newer version of LBRY is available.")} <Link href={newVerLink} label={__("Download LBRY %s now!"), ver.remote_lbrynet} /></p> <p>{__("A newer version of LBRY is available.")} <Link href={newVerLink} label={__("Download LBRY %s now!", ver.remote_lbrynet)} /></p>
: <p>{__("Your copy of LBRY is up to date.")}</p>) : null} : <p>{__("Your copy of LBRY is up to date.")}</p>) : null}
{ ver ? { ver ?
<table className="table-standard"> <table className="table-standard">

View file

@ -40,20 +40,33 @@ reducers[types.RESOLVE_URI_CANCELED] = function(state, action) {
} }
reducers[types.CLAIM_LIST_MINE_STARTED] = function(state, action) { reducers[types.FETCH_CLAIM_LIST_MINE_STARTED] = function(state, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
isClaimListMinePending: true isClaimListMinePending: true
}) })
} }
reducers[types.CLAIM_LIST_MINE_COMPLETED] = function(state, action) { reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
const myClaims = Object.assign({}, state.myClaims) const {
action.data.claims.forEach((claim) => { claims,
myClaims[claim.claim_id] = claim } = action.data
const myClaims = new Set(state.myClaims)
const byUri = Object.assign({}, state.claimsByUri)
claims.forEach(claim => {
const uri = lbryuri.build({
contentName: claim.name,
claimId: claim.claim_id,
claimSequence: claim.nout,
})
myClaims.add(uri)
byUri[uri] = claim
}) })
return Object.assign({}, state, { return Object.assign({}, state, {
isClaimListMinePending: false, isClaimListMinePending: false,
myClaims: myClaims myClaims: myClaims,
claimsByUri: byUri,
}) })
} }

View file

@ -18,7 +18,9 @@ reducers[types.FILE_LIST_COMPLETED] = function(state, action) {
const newFileInfos = Object.assign({}, state.fileInfos) const newFileInfos = Object.assign({}, state.fileInfos)
fileInfos.forEach((fileInfo) => { fileInfos.forEach((fileInfo) => {
newFileInfos[fileInfo.outpoint] = fileInfo const { outpoint } = fileInfo
if (outpoint) newFileInfos[fileInfo.outpoint] = fileInfo
}) })
return Object.assign({}, state, { return Object.assign({}, state, {

View file

@ -7,13 +7,13 @@ import {
function rewardMessage(type, amount) { function rewardMessage(type, amount) {
return { return {
new_developer: __(`You earned %s for registering as a new developer.`, amount), new_developer: __("You earned %s for registering as a new developer.", amount),
new_user: __(`You earned %s LBC new user reward.`, amount), new_user: __("You earned %s LBC new user reward.", amount),
confirm_email: __(`You earned %s LBC for verifying your email address.`, amount), confirm_email: __("You earned %s LBC for verifying your email address.", amount),
new_channel: __(`You earned %s LBC for creating a publisher identity.`, amount), new_channel: __("You earned %s LBC for creating a publisher identity.", amount),
first_stream: __(`You earned %s LBC for streaming your first video.`, amount), first_stream: __("You earned %s LBC for streaming your first video.", amount),
many_downloads: __(`You earned %s LBC for downloading some of the things.`, amount), many_downloads: __("You earned %s LBC for downloading some of the things.", amount),
first_publish: __(`You earned %s LBC for making your first publication.`, amount), first_publish: __("You earned %s LBC for making your first publication.", amount),
}[type]; }[type];
} }

View file

@ -103,7 +103,7 @@ export const selectUpgradeFilename = createSelector(
return `LBRY-${version}.dmg`; return `LBRY-${version}.dmg`;
case 'linux': case 'linux':
return `LBRY_${version}_amd64.deb`; return `LBRY_${version}_amd64.deb`;
case 'windows': case 'win32':
return `LBRY.Setup.${version}.exe`; return `LBRY.Setup.${version}.exe`;
default: default:
throw 'Unknown platform'; throw 'Unknown platform';

View file

@ -42,7 +42,8 @@ const selectMetadataForUri = (state, props) => {
const claim = selectClaimForUri(state, props) const claim = selectClaimForUri(state, props)
const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata
return metadata ? metadata : (claim === undefined ? undefined : null) const value = metadata ? metadata : (claim === undefined ? undefined : null)
return value
} }
export const makeSelectMetadataForUri = () => { export const makeSelectMetadataForUri = () => {
@ -80,18 +81,20 @@ export const selectClaimListMineIsPending = createSelector(
export const selectMyClaims = createSelector( export const selectMyClaims = createSelector(
_selectState, _selectState,
(state) => state.myClaims || {} (state) => state.myClaims || new Set()
) )
export const selectMyClaimsOutpoints = createSelector( export const selectMyClaimsOutpoints = createSelector(
selectMyClaims, selectMyClaims,
(claims) => { selectClaimsByUri,
if (!claims) { (claimIds, byUri) => {
return [] const outpoints = []
}
return Object.values(claims).map((claim) => { claimIds.forEach(claimId => {
return `${claim.txid}:${claim.nout}` const claim = byUri[claimId]
if (claim) outpoints.push(`${claim.txid}:${claim.nout}`)
}) })
return outpoints
} }
) )

View file

@ -1,6 +1,6 @@
{ {
"name": "lbry-web-ui", "name": "lbry-web-ui",
"version": "0.11.5rc1", "version": "0.11.7",
"description": "LBRY UI", "description": "LBRY UI",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
@ -22,9 +22,9 @@
"babel-cli": "^6.11.4", "babel-cli": "^6.11.4",
"babel-preset-es2015": "^6.13.2", "babel-preset-es2015": "^6.13.2",
"babel-preset-react": "^6.11.1", "babel-preset-react": "^6.11.1",
"from2": "^2.3.0",
"jshashes": "^1.0.6", "jshashes": "^1.0.6",
"node-sass": "^3.8.0", "node-sass": "^3.8.0",
"plyr": "^2.0.12",
"rc-progress": "^2.0.6", "rc-progress": "^2.0.6",
"react": "^15.4.0", "react": "^15.4.0",
"react-dom": "^15.4.0", "react-dom": "^15.4.0",
@ -33,6 +33,7 @@
"redux": "^3.6.0", "redux": "^3.6.0",
"redux-logger": "^3.0.1", "redux-logger": "^3.0.1",
"redux-thunk": "^2.2.0", "redux-thunk": "^2.2.0",
"render-media": "^2.10.0",
"reselect": "^3.0.0" "reselect": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,33 +0,0 @@
rmdir %~dp0node_modules /s /q
rmdir %~dp0..\node_modules /s /q
rmdir %~dp0..\app\node_modules /s /q
call yarn install
echo f | xcopy /s /y %~dp0dist %~dp0..\app\dist
call %~dp0node_modules\.bin\node-sass --output %~dp0..\app\dist\css --sourcemap=none %~dp0scss\
start /min %~dp0node_modules\.bin\node-sass --output %~dp0..\app\dist\css --sourcemap=none --watch %~dp0scss\ &
call %~dp0node_modules\.bin\webpack --config webpack.dev.config.js --progress --colors
start /min %~dp0node_modules\.bin\webpack --config webpack.dev.config.js --progress --colors --watch
call yarn build:langs
cp %~dp0build\lang\en.json %~dp0..\app\dist\lang\en.json
cd %~dp0..\app
call yarn install
cd ..\
call yarn install
start /min %~dp0..\node_modules\.bin\electron app
exit 0

View file

@ -42,7 +42,11 @@ module.exports = {
cacheDirectory: true, cacheDirectory: true,
presets:[ 'es2015', 'react', 'stage-2' ] presets:[ 'es2015', 'react', 'stage-2' ]
} }
} },
{
test: /mime\.json$/,
loader: 'json',
},
] ]
}, },
target: 'electron-main', target: 'electron-main',

View file

@ -48,7 +48,11 @@ module.exports = {
cacheDirectory: true, cacheDirectory: true,
presets:[ 'es2015', 'react', 'stage-2' ] presets:[ 'es2015', 'react', 'stage-2' ]
} }
} },
{
test: /mime\.json$/,
loader: 'json',
},
] ]
}, },
target: 'electron-main', target: 'electron-main',