mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-09-14 14:29:47 +00:00
channel and file selector fixes
This commit is contained in:
parent
bb16156034
commit
951190bf96
15 changed files with 127 additions and 79 deletions
|
@ -26,6 +26,8 @@ import {
|
||||||
export function doResolveUri(uri) {
|
export function doResolveUri(uri) {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
|
|
||||||
|
uri = lbryuri.normalize(uri)
|
||||||
|
|
||||||
const state = getState()
|
const state = getState()
|
||||||
const alreadyResolving = selectResolvingUris(state).indexOf(uri) !== -1
|
const alreadyResolving = selectResolvingUris(state).indexOf(uri) !== -1
|
||||||
|
|
||||||
|
@ -81,14 +83,6 @@ export function doFetchFeaturedUris() {
|
||||||
featuredUris[category] = Uris[category]
|
featuredUris[category] = Uris[category]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//
|
|
||||||
// dispatch({
|
|
||||||
// type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
|
||||||
// data: {
|
|
||||||
// categories: ["FOO"],
|
|
||||||
// uris: { FOO: ["lbry://gtasoc"]},
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as types from 'constants/action_types'
|
import * as types from 'constants/action_types'
|
||||||
import lbry from 'lbry'
|
import lbry from 'lbry'
|
||||||
import lbryio from 'lbryio'
|
import lbryio from 'lbryio'
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -118,7 +118,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.closeModal.bind(this)}>
|
contentLabel="Confirm Purchase" onConfirmed={this.onAffirmPurchase.bind(this)} onAborted={this.props.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"
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class FormField extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) {
|
if (['text', 'number', 'radio', 'checkbox'].includes(this.props.type)) {
|
||||||
this._element = 'input';
|
this._element = 'input';
|
||||||
this._type = this.props.type;
|
this._type = this.props.type;
|
||||||
} else if (this.props.type == 'text-number') {
|
} else if (this.props.type == 'text-number') {
|
||||||
|
@ -118,7 +118,7 @@ export class FormField extends React.Component {
|
||||||
</label> :
|
</label> :
|
||||||
element }
|
element }
|
||||||
{ formFieldFileSelectorTypes.includes(this.props.type) ?
|
{ formFieldFileSelectorTypes.includes(this.props.type) ?
|
||||||
<FileSelector type={this.props.type} onFileChosen={this.handleFileChosen}
|
<FileSelector type={this.props.type} onFileChosen={this.handleFileChosen.bind(this)}
|
||||||
{... this.props.defaultValue ? {initPath: this.props.defaultValue} : {}} /> :
|
{... this.props.defaultValue ? {initPath: this.props.defaultValue} : {}} /> :
|
||||||
null }
|
null }
|
||||||
{ this.props.postfix ? <span className="form-field__postfix">{this.props.postfix}</span> : '' }
|
{ this.props.postfix ? <span className="form-field__postfix">{this.props.postfix}</span> : '' }
|
||||||
|
|
|
@ -30,11 +30,11 @@ export class RewardLink extends React.Component {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'first_publish':
|
case 'first_publish':
|
||||||
lbry.claim_list_mine().then(function(list) {
|
lbry.claim_list_mine().then((list) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
claimable: list.length > 0
|
claimable: list.length > 0
|
||||||
})
|
})
|
||||||
}.bind(this));
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,31 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import lbryuri from 'lbryuri';
|
||||||
import {
|
import {
|
||||||
connect,
|
connect,
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
makeSelectIsResolvingForUri
|
||||||
|
} from 'selectors/content'
|
||||||
import {
|
import {
|
||||||
makeSelectClaimForUri,
|
makeSelectClaimForUri,
|
||||||
} from 'selectors/claims'
|
} from 'selectors/claims'
|
||||||
import UriIndicator from './view'
|
import UriIndicator from './view'
|
||||||
|
|
||||||
const makeSelect = () => {
|
const makeSelect = () => {
|
||||||
const selectClaimForUri = makeSelectClaimForUri()
|
const selectClaim = makeSelectClaimForUri(),
|
||||||
|
selectIsResolving = makeSelectIsResolvingForUri();
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
claim: selectClaimForUri(state, props),
|
claim: selectClaim(state, props),
|
||||||
|
isResolvingUri: selectIsResolving(state, props),
|
||||||
|
uri: lbryuri.normalize(props.uri),
|
||||||
})
|
})
|
||||||
|
|
||||||
return select
|
return select
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(makeSelect, null)(UriIndicator)
|
const perform = (dispatch) => ({
|
||||||
|
resolveUri: (uri) => dispatch(doResolveUri(uri))
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(makeSelect, perform)(UriIndicator)
|
||||||
|
|
|
@ -1,50 +1,74 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbry from 'lbry';
|
|
||||||
import lbryuri from 'lbryuri';
|
|
||||||
import {Icon} from 'component/common';
|
import {Icon} from 'component/common';
|
||||||
|
|
||||||
const UriIndicator = (props) => {
|
class UriIndicator extends React.Component{
|
||||||
const {
|
componentWillMount() {
|
||||||
uri,
|
this.resolve(this.props)
|
||||||
claim
|
|
||||||
} = props
|
|
||||||
|
|
||||||
const uriObj = lbryuri.parse(uri);
|
|
||||||
|
|
||||||
if (!claim) {
|
|
||||||
return <span className="empty">Unused</span>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
componentWillReceiveProps(nextProps) {
|
||||||
has_signature: hasSignature,
|
this.resolve(nextProps)
|
||||||
signature_is_valid: signatureIsValid
|
|
||||||
} = claim
|
|
||||||
|
|
||||||
if (!hasSignature || !uriObj.isChannel) {
|
|
||||||
return <span className="empty">Anonymous</span>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const channelUriObj = Object.assign({}, uriObj);
|
resolve(props) {
|
||||||
delete channelUriObj.path;
|
const {
|
||||||
delete channelUriObj.contentName;
|
isResolvingUri,
|
||||||
const channelUri = lbryuri.build(channelUriObj, false);
|
resolveUri,
|
||||||
|
claim,
|
||||||
|
uri,
|
||||||
|
} = props
|
||||||
|
|
||||||
let icon, modifier;
|
if(!isResolvingUri && claim === undefined && uri) {
|
||||||
if (signatureIsValid) {
|
resolveUri(uri)
|
||||||
modifier = 'valid';
|
}
|
||||||
} else {
|
|
||||||
icon = 'icon-times-circle';
|
|
||||||
modifier = 'invalid';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
render() {
|
||||||
<span>
|
const {
|
||||||
{channelUri} {' '}
|
claim,
|
||||||
{ !signatureIsValid ?
|
uri,
|
||||||
<Icon icon={icon} className={`channel-indicator__icon channel-indicator__icon--${modifier}`} /> :
|
isResolvingUri
|
||||||
'' }
|
} = this.props
|
||||||
</span>
|
|
||||||
)
|
if (isResolvingUri) {
|
||||||
|
return <span className="empty">Validating...</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!claim) {
|
||||||
|
return <span className="empty">Unused</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
channel_name: channelName,
|
||||||
|
has_signature: hasSignature,
|
||||||
|
signature_is_valid: signatureIsValid,
|
||||||
|
} = claim
|
||||||
|
|
||||||
|
console.log('uri indicator render')
|
||||||
|
console.log(uri)
|
||||||
|
console.log(claim)
|
||||||
|
|
||||||
|
if (!hasSignature || !channelName) {
|
||||||
|
return <span className="empty">Anonymous</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon, modifier;
|
||||||
|
if (signatureIsValid) {
|
||||||
|
modifier = 'valid';
|
||||||
|
} else {
|
||||||
|
icon = 'icon-times-circle';
|
||||||
|
modifier = 'invalid';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{channelName} {' '}
|
||||||
|
{ !signatureIsValid ?
|
||||||
|
<Icon icon={icon} className={`channel-indicator__icon channel-indicator__icon--${modifier}`} /> :
|
||||||
|
'' }
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UriIndicator;
|
export default UriIndicator;
|
|
@ -11,8 +11,6 @@ import {
|
||||||
} from 'selectors/claims'
|
} from 'selectors/claims'
|
||||||
import ChannelPage from './view'
|
import ChannelPage from './view'
|
||||||
|
|
||||||
import FilePage from './view'
|
|
||||||
|
|
||||||
const makeSelect = () => {
|
const makeSelect = () => {
|
||||||
const selectClaim = makeSelectClaimForUri(),
|
const selectClaim = makeSelectClaimForUri(),
|
||||||
selectClaimsInChannel = makeSelectClaimsInChannelForUri()
|
selectClaimsInChannel = makeSelectClaimsInChannelForUri()
|
||||||
|
@ -26,7 +24,6 @@ const makeSelect = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
// fetchClaims: () => { console.log('fetch claims') }
|
|
||||||
fetchClaims: (uri) => dispatch(doFetchClaimsByChannel(uri))
|
fetchClaims: (uri) => dispatch(doFetchClaimsByChannel(uri))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbryuri from 'lbryuri'
|
import lbryuri from 'lbryuri'
|
||||||
|
import {BusyMessage} from 'component/common'
|
||||||
|
import FileTile from 'component/fileTile'
|
||||||
|
|
||||||
class ChannelPage extends React.Component{
|
class ChannelPage extends React.Component{
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -23,7 +25,15 @@ class ChannelPage extends React.Component{
|
||||||
uri
|
uri
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
console.log(claimsInChannel);
|
let contentList
|
||||||
|
if (claimsInChannel === undefined) {
|
||||||
|
contentList = <BusyMessage message="Fetching content" />
|
||||||
|
} else if (claimsInChannel) {
|
||||||
|
contentList = claimsInChannel.length ?
|
||||||
|
claimsInChannel.map((claim) => <FileTile key={claim.claim_id} uri={lbryuri.build({name: claim.name, claimId: claim.claim_id})} />) :
|
||||||
|
<span className="empty">No content found.</span>
|
||||||
|
}
|
||||||
|
|
||||||
return <main className="main--single-column">
|
return <main className="main--single-column">
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="card__inner">
|
<div className="card__inner">
|
||||||
|
@ -35,13 +45,8 @@ class ChannelPage extends React.Component{
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="card">
|
<h3 className="card-row__header">Published Content</h3>
|
||||||
<div className="card__content">
|
{contentList}
|
||||||
{claimsInChannel ?
|
|
||||||
claimsInChannel.map((claim) => <FileTile uri={lbryuri.build({name: claim.name, claimId: claim.claim_id})} /> )
|
|
||||||
: ''}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</main>
|
</main>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@ import React from 'react'
|
||||||
import {
|
import {
|
||||||
connect
|
connect
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
doNavigate,
|
||||||
|
} from 'actions/app'
|
||||||
import {
|
import {
|
||||||
doFetchFileInfo,
|
doFetchFileInfo,
|
||||||
} from 'actions/file_info'
|
} from 'actions/file_info'
|
||||||
|
@ -37,6 +40,7 @@ const makeSelect = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
||||||
fetchFileInfo: (uri) => dispatch(doFetchFileInfo(uri))
|
fetchFileInfo: (uri) => dispatch(doFetchFileInfo(uri))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class FilePage extends React.Component{
|
||||||
const {
|
const {
|
||||||
txid,
|
txid,
|
||||||
nout,
|
nout,
|
||||||
|
channel_name: channelName,
|
||||||
has_signature: hasSignature,
|
has_signature: hasSignature,
|
||||||
signature_is_valid: signatureIsValid,
|
signature_is_valid: signatureIsValid,
|
||||||
value
|
value
|
||||||
|
@ -81,10 +82,8 @@ class FilePage extends React.Component{
|
||||||
|
|
||||||
const outpoint = txid + ':' + nout
|
const outpoint = txid + ':' + nout
|
||||||
const title = metadata.title
|
const title = metadata.title
|
||||||
const channelUriObj = lbryuri.parse(uri)
|
const channelClaimId = claim.value && claim.value.publisherSignature ? claim.value.publisherSignature.certificateId : null;
|
||||||
delete channelUriObj.path;
|
const channelUri = signatureIsValid && hasSignature && channelName ? lbryuri.build({channelName, claimId: channelClaimId}, false) : null
|
||||||
delete channelUriObj.contentName;
|
|
||||||
const channelUri = signatureIsValid && hasSignature && channelUriObj.isChannel ? lbryuri.build(channelUriObj, false) : null
|
|
||||||
const uriIndicator = <UriIndicator uri={uri} />
|
const uriIndicator = <UriIndicator uri={uri} />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -102,7 +101,7 @@ class FilePage extends React.Component{
|
||||||
: null}<h1>{title}</h1>
|
: null}<h1>{title}</h1>
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
{ channelUri ?
|
{ channelUri ?
|
||||||
<Link href={"?show=" + channelUri }>{uriIndicator}</Link> :
|
<Link onClick={() => this.props.navigate('/show', { uri: channelUri })}>{uriIndicator}</Link> :
|
||||||
uriIndicator}
|
uriIndicator}
|
||||||
</div>
|
</div>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
|
|
|
@ -8,8 +8,6 @@ import {BusyMessage} from 'component/common.js';
|
||||||
|
|
||||||
class SearchPage extends React.Component{
|
class SearchPage extends React.Component{
|
||||||
render() {
|
render() {
|
||||||
console.log('render search page')
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
query,
|
query,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
|
@ -105,7 +105,7 @@ class SettingsPage extends React.Component {
|
||||||
name="download_directory"
|
name="download_directory"
|
||||||
defaultValue={daemonSettings.download_directory}
|
defaultValue={daemonSettings.download_directory}
|
||||||
helper="LBRY downloads will be saved here."
|
helper="LBRY downloads will be saved here."
|
||||||
onChange={this.onDownloadDirChange} />
|
onChange={this.onDownloadDirChange.bind(this)} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
|
@ -132,7 +132,7 @@ class SettingsPage extends React.Component {
|
||||||
defaultValue={daemonSettings.max_upload}
|
defaultValue={daemonSettings.max_upload}
|
||||||
placeholder="10"
|
placeholder="10"
|
||||||
className="form-field__input--inline"
|
className="form-field__input--inline"
|
||||||
onChange={this.onMaxUploadFieldChange}
|
onChange={this.onMaxUploadFieldChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ class SettingsPage extends React.Component {
|
||||||
defaultValue={daemonSettings.max_download}
|
defaultValue={daemonSettings.max_download}
|
||||||
placeholder="10"
|
placeholder="10"
|
||||||
className="form-field__input--inline"
|
className="form-field__input--inline"
|
||||||
onChange={this.onMaxDownloadFieldChange}
|
onChange={this.onMaxDownloadFieldChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
|
@ -175,13 +175,13 @@ class SettingsPage extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<FormRow type="checkbox"
|
<FormRow type="checkbox"
|
||||||
onChange={this.onShowUnavailableChange}
|
onChange={this.onShowUnavailableChange.bind(this)}
|
||||||
defaultChecked={this.state.showUnavailable}
|
defaultChecked={this.state.showUnavailable}
|
||||||
label="Show unavailable content in search results" />
|
label="Show unavailable content in search results" />
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<FormRow label="Show NSFW content" type="checkbox"
|
<FormRow label="Show NSFW content" type="checkbox"
|
||||||
onChange={this.onShowNsfwChange} defaultChecked={this.state.showNsfw}
|
onChange={this.onShowNsfwChange.bind(this)} defaultChecked={this.state.showNsfw}
|
||||||
helper="NSFW content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. " />
|
helper="NSFW content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. " />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -191,7 +191,7 @@ class SettingsPage extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<FormRow type="checkbox"
|
<FormRow type="checkbox"
|
||||||
onChange={this.onShareDataChange}
|
onChange={this.onShareDataChange.bind(this)}
|
||||||
defaultChecked={daemonSettings.share_usage_data}
|
defaultChecked={daemonSettings.share_usage_data}
|
||||||
label="Help make LBRY better by contributing diagnostic data about my usage" />
|
label="Help make LBRY better by contributing diagnostic data about my usage" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -49,7 +49,7 @@ class ShowPage extends React.Component{
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
else if (claim.name.length && claim.name[0] === '@') {
|
else if (claim.name.length && claim.name[0] === '@') {
|
||||||
innerContent = <ChannelPage uri={lbryuri.build({ name: claim.name, claimId: claim.claim_id })} />
|
innerContent = <ChannelPage uri={uri} />
|
||||||
}
|
}
|
||||||
else if (claim) {
|
else if (claim) {
|
||||||
innerContent = <FilePage uri={uri} />
|
innerContent = <FilePage uri={uri} />
|
||||||
|
|
|
@ -57,6 +57,22 @@ reducers[types.CLAIM_LIST_MINE_COMPLETED] = function(state, action) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) {
|
||||||
|
// const {
|
||||||
|
// uri,
|
||||||
|
// } = action.data
|
||||||
|
//
|
||||||
|
// const newClaims = Object.assign({}, state.claimsByChannel)
|
||||||
|
//
|
||||||
|
// if (claims !== undefined) {
|
||||||
|
// newClaims[uri] = claims
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return Object.assign({}, state, {
|
||||||
|
// claimsByChannel: newClaims
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
|
|
Loading…
Add table
Reference in a new issue