fix merge conflict
This commit is contained in:
commit
24f57f9e01
27 changed files with 1512 additions and 661 deletions
|
@ -10,6 +10,7 @@
|
||||||
"__": true
|
"__": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"camelcase": 0,
|
||||||
"no-multi-spaces": 0,
|
"no-multi-spaces": 0,
|
||||||
"new-cap": 0,
|
"new-cap": 0,
|
||||||
"prefer-promise-reject-errors": 0,
|
"prefer-promise-reject-errors": 0,
|
||||||
|
|
1341
dist/bundle.es.js
vendored
1341
dist/bundle.es.js
vendored
File diff suppressed because it is too large
Load diff
47
dist/flow-typed/Claim.js
vendored
47
dist/flow-typed/Claim.js
vendored
|
@ -1,49 +1,51 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
declare type ClaimWithPossibleCertificate = {
|
declare type Claim = StreamClaim | ChannelClaim;
|
||||||
certificate?: ChannelClaim,
|
|
||||||
claim: StreamClaim,
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type ChannelClaim = GenericClaim & {
|
declare type ChannelClaim = GenericClaim & {
|
||||||
|
is_channel_signature_valid?: boolean, // we may have signed channels in the future
|
||||||
value: ChannelMetadata,
|
value: ChannelMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type StreamClaim = GenericClaim & {
|
declare type StreamClaim = GenericClaim & {
|
||||||
is_channel_signature_valid?: boolean,
|
is_channel_signature_valid?: boolean,
|
||||||
signing_channel?: {
|
|
||||||
claim_id: string,
|
|
||||||
name: string,
|
|
||||||
value: {
|
|
||||||
public_key: string,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
value: StreamMetadata,
|
value: StreamMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GenericClaim = {
|
declare type GenericClaim = {
|
||||||
address: string, // address associated with tx
|
address: string, // address associated with tx
|
||||||
amount: number, // bid amount at time of tx
|
amount: string, // bid amount at time of tx
|
||||||
|
canonical_url: string, // URL with short id, includes channel with short id
|
||||||
claim_id: string, // unique claim identifier
|
claim_id: string, // unique claim identifier
|
||||||
claim_sequence: number,
|
claim_sequence: number, // not being used currently
|
||||||
claim_op: 'create' | 'update',
|
claim_op: 'create' | 'update',
|
||||||
confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000
|
confirmations: number,
|
||||||
decoded_claim: boolean, // claim made in accordance with sdk protobuf types
|
decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044
|
||||||
effective_amount: number, // bid amount + supports
|
timestamp?: number, // date of last transaction
|
||||||
timestamp?: number, // date of transaction
|
|
||||||
has_signature: boolean,
|
|
||||||
height: number, // block height the tx was confirmed
|
height: number, // block height the tx was confirmed
|
||||||
hex: string, // `value` hex encoded
|
|
||||||
name: string,
|
name: string,
|
||||||
channel_name?: string,
|
|
||||||
normalized_name: string, // `name` normalized via unicode NFD spec,
|
normalized_name: string, // `name` normalized via unicode NFD spec,
|
||||||
nout: number, // index number for an output of a tx
|
nout: number, // index number for an output of a tx
|
||||||
permanent_url: string, // name + claim_id
|
permanent_url: string, // name + claim_id
|
||||||
supports: Array<{}>, // TODO: add support type once we start using it
|
short_url: string, // permanent_url with short id, no channel
|
||||||
txid: string, // unique tx id
|
txid: string, // unique tx id
|
||||||
type: 'claim' | 'update' | 'support',
|
type: 'claim' | 'update' | 'support',
|
||||||
valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728
|
|
||||||
value_type: 'stream' | 'channel',
|
value_type: 'stream' | 'channel',
|
||||||
|
signing_channel?: ChannelClaim,
|
||||||
|
meta: {
|
||||||
|
activation_height: number,
|
||||||
|
claims_in_channel?: number,
|
||||||
|
creation_height: number,
|
||||||
|
creation_timestamp: number,
|
||||||
|
effective_amount: string,
|
||||||
|
expiration_height: number,
|
||||||
|
is_controlling: boolean,
|
||||||
|
support_amount: string,
|
||||||
|
trending_global: number,
|
||||||
|
trending_group: number,
|
||||||
|
trending_local: number,
|
||||||
|
trending_mixed: number,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GenericMetadata = {
|
declare type GenericMetadata = {
|
||||||
|
@ -59,6 +61,7 @@ declare type GenericMetadata = {
|
||||||
|
|
||||||
declare type ChannelMetadata = GenericMetadata & {
|
declare type ChannelMetadata = GenericMetadata & {
|
||||||
public_key: string,
|
public_key: string,
|
||||||
|
public_key_id: string,
|
||||||
cover_url?: string,
|
cover_url?: string,
|
||||||
email?: string,
|
email?: string,
|
||||||
website_url?: string,
|
website_url?: string,
|
||||||
|
|
18
dist/flow-typed/Comment.js
vendored
Normal file
18
dist/flow-typed/Comment.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
declare type Comment = {
|
||||||
|
author: string,
|
||||||
|
claim_index?: number,
|
||||||
|
comment_id?: number,
|
||||||
|
downvotes?: number,
|
||||||
|
message: string,
|
||||||
|
omitted?: number,
|
||||||
|
reply_count?: number,
|
||||||
|
time_posted?: number,
|
||||||
|
upvotes?: number,
|
||||||
|
parent_id?: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type CommentsState = {
|
||||||
|
byId: {},
|
||||||
|
isLoading: boolean,
|
||||||
|
commentsByUri: { [string]: string },
|
||||||
|
}
|
19
dist/flow-typed/Lbry.js
vendored
19
dist/flow-typed/Lbry.js
vendored
|
@ -66,8 +66,8 @@ declare type VersionResponse = {
|
||||||
declare type ResolveResponse = {
|
declare type ResolveResponse = {
|
||||||
// Keys are the url(s) passed to resolve
|
// Keys are the url(s) passed to resolve
|
||||||
[string]:
|
[string]:
|
||||||
| { error: {}, certificate: ChannelClaim, claims_in_channel: number }
|
| Claim
|
||||||
| { error?: {}, claim: StreamClaim, certificate?: ChannelClaim },
|
| { error?: {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GetResponse = FileListItem;
|
declare type GetResponse = FileListItem;
|
||||||
|
@ -86,24 +86,28 @@ declare type GenericTxResponse = {
|
||||||
declare type PublishResponse = GenericTxResponse & {
|
declare type PublishResponse = GenericTxResponse & {
|
||||||
// Only first value in outputs is a claim
|
// Only first value in outputs is a claim
|
||||||
// That's the only value we care about
|
// That's the only value we care about
|
||||||
outputs: Array<StreamClaim>,
|
outputs: Array<Claim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ClaimSearchResponse = {
|
declare type ClaimSearchResponse = {
|
||||||
items: Array<StreamClaim>,
|
items: Array<Claim>,
|
||||||
page: number,
|
page: number,
|
||||||
page_size: number,
|
page_size: number,
|
||||||
page_number: number,
|
total_items: number,
|
||||||
|
total_pages: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ClaimListResponse = {
|
declare type ClaimListResponse = {
|
||||||
claims: Array<ChannelClaim | StreamClaim>,
|
claims: Array<ChannelClaim | Claim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ChannelCreateResponse = GenericTxResponse & {
|
declare type ChannelCreateResponse = GenericTxResponse & {
|
||||||
outputs: Array<ChannelClaim>,
|
outputs: Array<ChannelClaim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare type CommentCreateResponse = Comment;
|
||||||
|
declare type CommentListResponse = Array<Comment>;
|
||||||
|
|
||||||
declare type ChannelListResponse = Array<ChannelClaim>;
|
declare type ChannelListResponse = Array<ChannelClaim>;
|
||||||
|
|
||||||
declare type FileListResponse = Array<FileListItem>;
|
declare type FileListResponse = Array<FileListItem>;
|
||||||
|
@ -183,6 +187,9 @@ declare type LbryTypes = {
|
||||||
blob_delete: (params: {}) => Promise<string>,
|
blob_delete: (params: {}) => Promise<string>,
|
||||||
blob_list: (params: {}) => Promise<BlobListResponse>,
|
blob_list: (params: {}) => Promise<BlobListResponse>,
|
||||||
|
|
||||||
|
// Commenting
|
||||||
|
comment_list: (params: {}) => Promise<CommentListResponse>,
|
||||||
|
comment_create: (params: {}) => Promise<CommentCreateResponse>,
|
||||||
// Wallet utilities
|
// Wallet utilities
|
||||||
account_balance: (params: {}) => Promise<string>,
|
account_balance: (params: {}) => Promise<string>,
|
||||||
account_decrypt: (prams: {}) => Promise<boolean>,
|
account_decrypt: (prams: {}) => Promise<boolean>,
|
||||||
|
|
21
dist/flow-typed/Tags.js
vendored
Normal file
21
dist/flow-typed/Tags.js
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
declare type TagState = {
|
||||||
|
followedTags: FollowedTags,
|
||||||
|
knownTags: KnownTags,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type Tag = {
|
||||||
|
name: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type KnownTags = {
|
||||||
|
[string]: Tag,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type FollowedTags = Array<string>;
|
||||||
|
|
||||||
|
declare type TagAction = {
|
||||||
|
type: string,
|
||||||
|
data: {
|
||||||
|
name: string,
|
||||||
|
},
|
||||||
|
};
|
47
flow-typed/Claim.js
vendored
47
flow-typed/Claim.js
vendored
|
@ -1,49 +1,51 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
declare type ClaimWithPossibleCertificate = {
|
declare type Claim = StreamClaim | ChannelClaim;
|
||||||
certificate?: ChannelClaim,
|
|
||||||
claim: StreamClaim,
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type ChannelClaim = GenericClaim & {
|
declare type ChannelClaim = GenericClaim & {
|
||||||
|
is_channel_signature_valid?: boolean, // we may have signed channels in the future
|
||||||
value: ChannelMetadata,
|
value: ChannelMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type StreamClaim = GenericClaim & {
|
declare type StreamClaim = GenericClaim & {
|
||||||
is_channel_signature_valid?: boolean,
|
is_channel_signature_valid?: boolean,
|
||||||
signing_channel?: {
|
|
||||||
claim_id: string,
|
|
||||||
name: string,
|
|
||||||
value: {
|
|
||||||
public_key: string,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
value: StreamMetadata,
|
value: StreamMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GenericClaim = {
|
declare type GenericClaim = {
|
||||||
address: string, // address associated with tx
|
address: string, // address associated with tx
|
||||||
amount: number, // bid amount at time of tx
|
amount: string, // bid amount at time of tx
|
||||||
|
canonical_url: string, // URL with short id, includes channel with short id
|
||||||
claim_id: string, // unique claim identifier
|
claim_id: string, // unique claim identifier
|
||||||
claim_sequence: number,
|
claim_sequence: number, // not being used currently
|
||||||
claim_op: 'create' | 'update',
|
claim_op: 'create' | 'update',
|
||||||
confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000
|
confirmations: number,
|
||||||
decoded_claim: boolean, // claim made in accordance with sdk protobuf types
|
decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044
|
||||||
effective_amount: number, // bid amount + supports
|
timestamp?: number, // date of last transaction
|
||||||
timestamp?: number, // date of transaction
|
|
||||||
has_signature: boolean,
|
|
||||||
height: number, // block height the tx was confirmed
|
height: number, // block height the tx was confirmed
|
||||||
hex: string, // `value` hex encoded
|
|
||||||
name: string,
|
name: string,
|
||||||
channel_name?: string,
|
|
||||||
normalized_name: string, // `name` normalized via unicode NFD spec,
|
normalized_name: string, // `name` normalized via unicode NFD spec,
|
||||||
nout: number, // index number for an output of a tx
|
nout: number, // index number for an output of a tx
|
||||||
permanent_url: string, // name + claim_id
|
permanent_url: string, // name + claim_id
|
||||||
supports: Array<{}>, // TODO: add support type once we start using it
|
short_url: string, // permanent_url with short id, no channel
|
||||||
txid: string, // unique tx id
|
txid: string, // unique tx id
|
||||||
type: 'claim' | 'update' | 'support',
|
type: 'claim' | 'update' | 'support',
|
||||||
valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728
|
|
||||||
value_type: 'stream' | 'channel',
|
value_type: 'stream' | 'channel',
|
||||||
|
signing_channel?: ChannelClaim,
|
||||||
|
meta: {
|
||||||
|
activation_height: number,
|
||||||
|
claims_in_channel?: number,
|
||||||
|
creation_height: number,
|
||||||
|
creation_timestamp: number,
|
||||||
|
effective_amount: string,
|
||||||
|
expiration_height: number,
|
||||||
|
is_controlling: boolean,
|
||||||
|
support_amount: string,
|
||||||
|
trending_global: number,
|
||||||
|
trending_group: number,
|
||||||
|
trending_local: number,
|
||||||
|
trending_mixed: number,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GenericMetadata = {
|
declare type GenericMetadata = {
|
||||||
|
@ -59,6 +61,7 @@ declare type GenericMetadata = {
|
||||||
|
|
||||||
declare type ChannelMetadata = GenericMetadata & {
|
declare type ChannelMetadata = GenericMetadata & {
|
||||||
public_key: string,
|
public_key: string,
|
||||||
|
public_key_id: string,
|
||||||
cover_url?: string,
|
cover_url?: string,
|
||||||
email?: string,
|
email?: string,
|
||||||
website_url?: string,
|
website_url?: string,
|
||||||
|
|
18
flow-typed/Comment.js
vendored
Normal file
18
flow-typed/Comment.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
declare type Comment = {
|
||||||
|
author: string,
|
||||||
|
claim_index?: number,
|
||||||
|
comment_id?: number,
|
||||||
|
downvotes?: number,
|
||||||
|
message: string,
|
||||||
|
omitted?: number,
|
||||||
|
reply_count?: number,
|
||||||
|
time_posted?: number,
|
||||||
|
upvotes?: number,
|
||||||
|
parent_id?: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type CommentsState = {
|
||||||
|
byId: {},
|
||||||
|
isLoading: boolean,
|
||||||
|
commentsByUri: { [string]: string },
|
||||||
|
}
|
19
flow-typed/Lbry.js
vendored
19
flow-typed/Lbry.js
vendored
|
@ -66,8 +66,8 @@ declare type VersionResponse = {
|
||||||
declare type ResolveResponse = {
|
declare type ResolveResponse = {
|
||||||
// Keys are the url(s) passed to resolve
|
// Keys are the url(s) passed to resolve
|
||||||
[string]:
|
[string]:
|
||||||
| { error: {}, certificate: ChannelClaim, claims_in_channel: number }
|
| Claim
|
||||||
| { error?: {}, claim: StreamClaim, certificate?: ChannelClaim },
|
| { error?: {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type GetResponse = FileListItem;
|
declare type GetResponse = FileListItem;
|
||||||
|
@ -86,24 +86,28 @@ declare type GenericTxResponse = {
|
||||||
declare type PublishResponse = GenericTxResponse & {
|
declare type PublishResponse = GenericTxResponse & {
|
||||||
// Only first value in outputs is a claim
|
// Only first value in outputs is a claim
|
||||||
// That's the only value we care about
|
// That's the only value we care about
|
||||||
outputs: Array<StreamClaim>,
|
outputs: Array<Claim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ClaimSearchResponse = {
|
declare type ClaimSearchResponse = {
|
||||||
items: Array<StreamClaim>,
|
items: Array<Claim>,
|
||||||
page: number,
|
page: number,
|
||||||
page_size: number,
|
page_size: number,
|
||||||
page_number: number,
|
total_items: number,
|
||||||
|
total_pages: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ClaimListResponse = {
|
declare type ClaimListResponse = {
|
||||||
claims: Array<ChannelClaim | StreamClaim>,
|
claims: Array<ChannelClaim | Claim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type ChannelCreateResponse = GenericTxResponse & {
|
declare type ChannelCreateResponse = GenericTxResponse & {
|
||||||
outputs: Array<ChannelClaim>,
|
outputs: Array<ChannelClaim>,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare type CommentCreateResponse = Comment;
|
||||||
|
declare type CommentListResponse = Array<Comment>;
|
||||||
|
|
||||||
declare type ChannelListResponse = Array<ChannelClaim>;
|
declare type ChannelListResponse = Array<ChannelClaim>;
|
||||||
|
|
||||||
declare type FileListResponse = Array<FileListItem>;
|
declare type FileListResponse = Array<FileListItem>;
|
||||||
|
@ -183,6 +187,9 @@ declare type LbryTypes = {
|
||||||
blob_delete: (params: {}) => Promise<string>,
|
blob_delete: (params: {}) => Promise<string>,
|
||||||
blob_list: (params: {}) => Promise<BlobListResponse>,
|
blob_list: (params: {}) => Promise<BlobListResponse>,
|
||||||
|
|
||||||
|
// Commenting
|
||||||
|
comment_list: (params: {}) => Promise<CommentListResponse>,
|
||||||
|
comment_create: (params: {}) => Promise<CommentCreateResponse>,
|
||||||
// Wallet utilities
|
// Wallet utilities
|
||||||
account_balance: (params: {}) => Promise<string>,
|
account_balance: (params: {}) => Promise<string>,
|
||||||
account_decrypt: (prams: {}) => Promise<boolean>,
|
account_decrypt: (prams: {}) => Promise<boolean>,
|
||||||
|
|
21
flow-typed/Tags.js
vendored
Normal file
21
flow-typed/Tags.js
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
declare type TagState = {
|
||||||
|
followedTags: FollowedTags,
|
||||||
|
knownTags: KnownTags,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type Tag = {
|
||||||
|
name: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type KnownTags = {
|
||||||
|
[string]: Tag,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare type FollowedTags = Array<string>;
|
||||||
|
|
||||||
|
declare type TagAction = {
|
||||||
|
type: string,
|
||||||
|
data: {
|
||||||
|
name: string,
|
||||||
|
},
|
||||||
|
};
|
|
@ -88,6 +88,17 @@ export const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION';
|
||||||
export const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED';
|
export const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED';
|
||||||
export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI';
|
export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI';
|
||||||
export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL';
|
export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL';
|
||||||
|
export const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED';
|
||||||
|
export const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED';
|
||||||
|
export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED';
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED';
|
||||||
|
export const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED';
|
||||||
|
export const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED';
|
||||||
|
export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED';
|
||||||
|
export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED';
|
||||||
|
export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED';
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED';
|
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED';
|
||||||
|
@ -177,21 +188,6 @@ export const FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED';
|
||||||
export const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED';
|
export const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED';
|
||||||
export const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED';
|
export const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED';
|
||||||
|
|
||||||
// ShapeShift
|
|
||||||
export const GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START';
|
|
||||||
export const GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS';
|
|
||||||
export const GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL';
|
|
||||||
export const GET_COIN_STATS_START = 'GET_COIN_STATS_START';
|
|
||||||
export const GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS';
|
|
||||||
export const GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL';
|
|
||||||
export const PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START';
|
|
||||||
export const PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS';
|
|
||||||
export const PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL';
|
|
||||||
export const GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START';
|
|
||||||
export const GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS';
|
|
||||||
export const GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL';
|
|
||||||
export const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT';
|
|
||||||
|
|
||||||
// Subscriptions
|
// Subscriptions
|
||||||
export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE';
|
export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE';
|
||||||
export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE';
|
export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE';
|
||||||
|
@ -229,3 +225,7 @@ export const FETCH_DATE = 'FETCH_DATE';
|
||||||
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED';
|
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED';
|
||||||
export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED';
|
export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED';
|
||||||
export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED';
|
export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED';
|
||||||
|
// Tags
|
||||||
|
export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW';
|
||||||
|
export const TAG_ADD = 'TAG_ADD';
|
||||||
|
export const TAG_DELETE = 'TAG_DELETE';
|
||||||
|
|
20
src/index.js
20
src/index.js
|
@ -49,6 +49,7 @@ export {
|
||||||
doResolveUri,
|
doResolveUri,
|
||||||
doFetchChannelListMine,
|
doFetchChannelListMine,
|
||||||
doCreateChannel,
|
doCreateChannel,
|
||||||
|
doClaimSearch,
|
||||||
} from 'redux/actions/claims';
|
} from 'redux/actions/claims';
|
||||||
|
|
||||||
export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file';
|
export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file';
|
||||||
|
@ -101,6 +102,10 @@ export {
|
||||||
doUpdateBlockHeight,
|
doUpdateBlockHeight,
|
||||||
} from 'redux/actions/wallet';
|
} from 'redux/actions/wallet';
|
||||||
|
|
||||||
|
export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags';
|
||||||
|
|
||||||
|
export { doCommentList, doCommentCreate } from 'redux/actions/comments';
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
export { batchActions } from 'util/batchActions';
|
export { batchActions } from 'util/batchActions';
|
||||||
export { parseQueryParams, toQueryString } from 'util/query_params';
|
export { parseQueryParams, toQueryString } from 'util/query_params';
|
||||||
|
@ -109,12 +114,14 @@ export { isClaimNsfw } from 'util/claim';
|
||||||
|
|
||||||
// reducers
|
// reducers
|
||||||
export { claimsReducer } from 'redux/reducers/claims';
|
export { claimsReducer } from 'redux/reducers/claims';
|
||||||
|
export { commentReducer } from 'redux/reducers/comments';
|
||||||
export { contentReducer } from 'redux/reducers/content';
|
export { contentReducer } from 'redux/reducers/content';
|
||||||
export { fileReducer } from 'redux/reducers/file';
|
|
||||||
export { fileInfoReducer } from 'redux/reducers/file_info';
|
export { fileInfoReducer } from 'redux/reducers/file_info';
|
||||||
|
export { fileReducer } from 'redux/reducers/file';
|
||||||
export { notificationsReducer } from 'redux/reducers/notifications';
|
export { notificationsReducer } from 'redux/reducers/notifications';
|
||||||
export { searchReducer } from 'redux/reducers/search';
|
|
||||||
export { publishReducer } from 'redux/reducers/publish';
|
export { publishReducer } from 'redux/reducers/publish';
|
||||||
|
export { searchReducer } from 'redux/reducers/search';
|
||||||
|
export { tagsReducerBuilder } from 'redux/reducers/tags';
|
||||||
export { walletReducer } from 'redux/reducers/wallet';
|
export { walletReducer } from 'redux/reducers/wallet';
|
||||||
|
|
||||||
// selectors
|
// selectors
|
||||||
|
@ -142,6 +149,7 @@ export {
|
||||||
makeSelectCoverForUri,
|
makeSelectCoverForUri,
|
||||||
makeSelectTitleForUri,
|
makeSelectTitleForUri,
|
||||||
makeSelectDateForUri,
|
makeSelectDateForUri,
|
||||||
|
makeSelectTagsForUri,
|
||||||
makeSelectContentTypeForUri,
|
makeSelectContentTypeForUri,
|
||||||
makeSelectIsUriResolving,
|
makeSelectIsUriResolving,
|
||||||
makeSelectTotalItemsForChannel,
|
makeSelectTotalItemsForChannel,
|
||||||
|
@ -167,6 +175,7 @@ export {
|
||||||
selectPendingClaims,
|
selectPendingClaims,
|
||||||
selectMyClaims,
|
selectMyClaims,
|
||||||
selectMyClaimsWithoutChannels,
|
selectMyClaimsWithoutChannels,
|
||||||
|
selectMyClaimUrisWithoutChannels,
|
||||||
selectAllMyClaimsByOutpoint,
|
selectAllMyClaimsByOutpoint,
|
||||||
selectMyClaimsOutpoints,
|
selectMyClaimsOutpoints,
|
||||||
selectFetchingMyChannels,
|
selectFetchingMyChannels,
|
||||||
|
@ -175,8 +184,12 @@ export {
|
||||||
selectPlayingUri,
|
selectPlayingUri,
|
||||||
selectChannelClaimCounts,
|
selectChannelClaimCounts,
|
||||||
selectCurrentChannelPage,
|
selectCurrentChannelPage,
|
||||||
|
selectFetchingClaimSearch,
|
||||||
|
selectLastClaimSearchUris,
|
||||||
} from 'redux/selectors/claims';
|
} from 'redux/selectors/claims';
|
||||||
|
|
||||||
|
export { makeSelectCommentsForUri } from 'redux/selectors/comments';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
makeSelectFileInfoForUri,
|
makeSelectFileInfoForUri,
|
||||||
makeSelectDownloadingForUri,
|
makeSelectDownloadingForUri,
|
||||||
|
@ -192,6 +205,7 @@ export {
|
||||||
selectSearchDownloadUris,
|
selectSearchDownloadUris,
|
||||||
selectFileListDownloadedSort,
|
selectFileListDownloadedSort,
|
||||||
selectFileListPublishedSort,
|
selectFileListPublishedSort,
|
||||||
|
selectDownloadedUris,
|
||||||
} from 'redux/selectors/file_info';
|
} from 'redux/selectors/file_info';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -244,3 +258,5 @@ export {
|
||||||
selectWalletUnlockResult,
|
selectWalletUnlockResult,
|
||||||
selectTransactionListFilter,
|
selectTransactionListFilter,
|
||||||
} from 'redux/selectors/wallet';
|
} from 'redux/selectors/wallet';
|
||||||
|
|
||||||
|
export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags';
|
||||||
|
|
|
@ -100,6 +100,9 @@ const Lbry: LbryTypes = {
|
||||||
sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params),
|
sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params),
|
||||||
sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params),
|
sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params),
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
comment_list: (params = {}) => daemonCallWithResult('comment_list', params),
|
||||||
|
comment_create: (params = {}) => daemonCallWithResult('comment_create', params),
|
||||||
// Connect to the sdk
|
// Connect to the sdk
|
||||||
connect: () => {
|
connect: () => {
|
||||||
if (Lbry.connectPromise === null) {
|
if (Lbry.connectPromise === null) {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
const channelNameMinLength = 1;
|
const channelNameMinLength = 1;
|
||||||
const claimIdMaxLength = 40;
|
const claimIdMaxLength = 40;
|
||||||
|
|
||||||
export const regexInvalidURI = /[^A-Za-z0-9-]/g;
|
// see https://spec.lbry.com/#urls
|
||||||
|
export const regexInvalidURI = (exports.regexInvalidURI = /[=&#:$@%?\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu);
|
||||||
export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/;
|
export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,9 +201,8 @@ export function isURIValid(URI) {
|
||||||
return parts && parts.claimName;
|
return parts && parts.claimName;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNameValid(claimName, checkCase = true) {
|
export function isNameValid(claimName) {
|
||||||
const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i');
|
return !regexInvalidURI.test(claimName);
|
||||||
return regexp.test(claimName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isURIClaimable(URI) {
|
export function isURIClaimable(URI) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux
|
||||||
import { doFetchTransactions } from 'redux/actions/wallet';
|
import { doFetchTransactions } from 'redux/actions/wallet';
|
||||||
import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
|
import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
|
||||||
import { creditsToString } from 'util/formatCredits';
|
import { creditsToString } from 'util/formatCredits';
|
||||||
|
import { batchActions } from 'util/batchActions';
|
||||||
|
|
||||||
export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean = false) {
|
export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean = false) {
|
||||||
return (dispatch: Dispatch, getState: GetState) => {
|
return (dispatch: Dispatch, getState: GetState) => {
|
||||||
|
@ -34,8 +35,8 @@ export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean =
|
||||||
|
|
||||||
const resolveInfo: {
|
const resolveInfo: {
|
||||||
[string]: {
|
[string]: {
|
||||||
claim: ?StreamClaim,
|
stream: ?StreamClaim,
|
||||||
certificate: ?ChannelClaim,
|
channel: ?ChannelClaim,
|
||||||
claimsInChannel: ?number,
|
claimsInChannel: ?number,
|
||||||
},
|
},
|
||||||
} = {};
|
} = {};
|
||||||
|
@ -43,20 +44,35 @@ export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean =
|
||||||
Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => {
|
Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => {
|
||||||
Object.entries(result).forEach(([uri, uriResolveInfo]) => {
|
Object.entries(result).forEach(([uri, uriResolveInfo]) => {
|
||||||
const fallbackResolveInfo = {
|
const fallbackResolveInfo = {
|
||||||
claim: null,
|
stream: null,
|
||||||
claimsInChannel: null,
|
claimsInChannel: null,
|
||||||
certificate: null,
|
channel: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flow has terrible Object.entries support
|
// Flow has terrible Object.entries support
|
||||||
// https://github.com/facebook/flow/issues/2221
|
// https://github.com/facebook/flow/issues/2221
|
||||||
// $FlowFixMe
|
if (uriResolveInfo) {
|
||||||
if (uriResolveInfo.error) {
|
if (uriResolveInfo.error) {
|
||||||
resolveInfo[uri] = { ...fallbackResolveInfo };
|
resolveInfo[uri] = { ...fallbackResolveInfo };
|
||||||
} else {
|
} else {
|
||||||
// $FlowFixMe
|
let result = {};
|
||||||
const { claim, certificate, claims_in_channel: claimsInChannel } = uriResolveInfo;
|
if (uriResolveInfo.value_type === 'channel') {
|
||||||
resolveInfo[uri] = { claim, certificate, claimsInChannel };
|
result.channel = uriResolveInfo;
|
||||||
|
// $FlowFixMe
|
||||||
|
result.claimsInChannel = uriResolveInfo.meta.claims_in_channel;
|
||||||
|
} else {
|
||||||
|
result.stream = uriResolveInfo;
|
||||||
|
if (uriResolveInfo.signing_channel) {
|
||||||
|
result.channel = uriResolveInfo.signing_channel;
|
||||||
|
result.claimsInChannel =
|
||||||
|
(uriResolveInfo.signing_channel.meta &&
|
||||||
|
uriResolveInfo.signing_channel.meta.claims_in_channel) ||
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// $FlowFixMe
|
||||||
|
resolveInfo[uri] = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -94,7 +110,7 @@ export function doAbandonClaim(txid: string, nout: number) {
|
||||||
|
|
||||||
return (dispatch: Dispatch, getState: GetState) => {
|
return (dispatch: Dispatch, getState: GetState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const myClaims: Array<ChannelClaim | StreamClaim> = selectMyClaimsRaw(state);
|
const myClaims: Array<Claim> = selectMyClaimsRaw(state);
|
||||||
const mySupports: { [string]: Support } = selectSupportsByOutpoint(state);
|
const mySupports: { [string]: Support } = selectSupportsByOutpoint(state);
|
||||||
|
|
||||||
// A user could be trying to abandon a support or one of their claims
|
// A user could be trying to abandon a support or one of their claims
|
||||||
|
@ -182,20 +198,23 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) {
|
||||||
data: { uri, page },
|
data: { uri, page },
|
||||||
});
|
});
|
||||||
|
|
||||||
Lbry.claim_search({ channel_name: uri, page: page || 1, winning: true }).then(
|
Lbry.claim_search({
|
||||||
(result: ClaimSearchResponse) => {
|
channel: uri,
|
||||||
const { items: claimsInChannel, page: returnedPage } = result;
|
valid_channel_signature: true,
|
||||||
|
page: page || 1,
|
||||||
|
order_by: ['release_time'],
|
||||||
|
}).then((result: ClaimSearchResponse) => {
|
||||||
|
const { items: claimsInChannel, page: returnedPage } = result;
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED,
|
type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
uri,
|
uri,
|
||||||
claims: claimsInChannel || [],
|
claims: claimsInChannel || [],
|
||||||
page: returnedPage || undefined,
|
page: returnedPage || undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,3 +264,37 @@ export function doFetchChannelListMine() {
|
||||||
Lbry.channel_list().then(callback);
|
Lbry.channel_list().then(callback);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doClaimSearch(amount: number = 20, options: {} = {}) {
|
||||||
|
return (dispatch: Dispatch) => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.CLAIM_SEARCH_STARTED,
|
||||||
|
});
|
||||||
|
|
||||||
|
const success = (data: ClaimSearchResponse) => {
|
||||||
|
const resolveInfo = {};
|
||||||
|
const uris = [];
|
||||||
|
data.items.forEach((stream: Claim) => {
|
||||||
|
resolveInfo[stream.permanent_url] = { stream };
|
||||||
|
uris.push(stream.permanent_url);
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.CLAIM_SEARCH_COMPLETED,
|
||||||
|
data: { resolveInfo, uris },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const failure = err => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.CLAIM_SEARCH_FAILED,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Lbry.claim_search({
|
||||||
|
page_size: amount,
|
||||||
|
...options,
|
||||||
|
}).then(success, failure);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
80
src/redux/actions/comments.js
Normal file
80
src/redux/actions/comments.js
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// @flow
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import Lbry from 'lbry';
|
||||||
|
import { selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims';
|
||||||
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
|
||||||
|
export function doCommentList(uri: string) {
|
||||||
|
return (dispatch: Dispatch, getState: GetState) => {
|
||||||
|
const state = getState();
|
||||||
|
const claim = selectClaimsByUri(state)[uri];
|
||||||
|
const claimId = claim ? claim.claim_id : null;
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_LIST_STARTED,
|
||||||
|
});
|
||||||
|
Lbry.comment_list({
|
||||||
|
claim_id: claimId,
|
||||||
|
})
|
||||||
|
.then((results: CommentListResponse) => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_LIST_COMPLETED,
|
||||||
|
data: {
|
||||||
|
comments: results,
|
||||||
|
claimId: claimId,
|
||||||
|
uri: uri,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_LIST_FAILED,
|
||||||
|
data: error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doCommentCreate(
|
||||||
|
comment: string = '',
|
||||||
|
claim_id: string = '',
|
||||||
|
channel: ?string,
|
||||||
|
parent_id?: number
|
||||||
|
) {
|
||||||
|
return (dispatch: Dispatch, getState: GetState) => {
|
||||||
|
const state = getState();
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_CREATE_STARTED,
|
||||||
|
});
|
||||||
|
const myChannels = selectMyChannelClaims(state);
|
||||||
|
const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel);
|
||||||
|
const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null;
|
||||||
|
return Lbry.comment_create({
|
||||||
|
comment,
|
||||||
|
claim_id,
|
||||||
|
channel_id,
|
||||||
|
})
|
||||||
|
.then((result: Comment) => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_CREATE_COMPLETED,
|
||||||
|
data: {
|
||||||
|
comment: result,
|
||||||
|
claimId: claim_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.COMMENT_CREATE_FAILED,
|
||||||
|
data: error,
|
||||||
|
});
|
||||||
|
dispatch(
|
||||||
|
doToast({
|
||||||
|
message: 'Oops, someone broke comments.',
|
||||||
|
isError: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
24
src/redux/actions/tags.js
Normal file
24
src/redux/actions/tags.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// @flow
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import Lbry from 'lbry';
|
||||||
|
|
||||||
|
export const doToggleTagFollow = (name: string) => ({
|
||||||
|
type: ACTIONS.TOGGLE_TAG_FOLLOW,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const doAddTag = (name: string) => ({
|
||||||
|
type: ACTIONS.TAG_ADD,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const doDeleteTag = (name: string) => ({
|
||||||
|
type: ACTIONS.TAG_DELETE,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
|
@ -14,9 +14,9 @@ import { buildURI, parseURI } from 'lbryURI';
|
||||||
type State = {
|
type State = {
|
||||||
channelClaimCounts: { [string]: number },
|
channelClaimCounts: { [string]: number },
|
||||||
claimsByUri: { [string]: string },
|
claimsByUri: { [string]: string },
|
||||||
byId: { [string]: StreamClaim | ChannelClaim },
|
byId: { [string]: Claim },
|
||||||
resolvingUris: Array<string>,
|
resolvingUris: Array<string>,
|
||||||
pendingById: { [string]: StreamClaim | ChannelClaim },
|
pendingById: { [string]: Claim },
|
||||||
myChannelClaims: Set<string>,
|
myChannelClaims: Set<string>,
|
||||||
abandoningById: { [string]: boolean },
|
abandoningById: { [string]: boolean },
|
||||||
fetchingChannelClaims: { [string]: number },
|
fetchingChannelClaims: { [string]: number },
|
||||||
|
@ -43,40 +43,43 @@ const defaultState = {
|
||||||
fetchingMyChannels: false,
|
fetchingMyChannels: false,
|
||||||
abandoningById: {},
|
abandoningById: {},
|
||||||
pendingById: {},
|
pendingById: {},
|
||||||
|
fetchingClaimSearch: false,
|
||||||
|
lastClaimSearchUris: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => {
|
function handleClaimAction(state: State, action: any): State {
|
||||||
const { resolveInfo }: { [string]: ClaimWithPossibleCertificate } = action.data;
|
const {
|
||||||
|
resolveInfo,
|
||||||
|
}: {
|
||||||
|
[string]: {
|
||||||
|
stream: ?StreamClaim,
|
||||||
|
channel: ?ChannelClaim,
|
||||||
|
claimsInChannel: ?number,
|
||||||
|
},
|
||||||
|
} = action.data;
|
||||||
const byUri = Object.assign({}, state.claimsByUri);
|
const byUri = Object.assign({}, state.claimsByUri);
|
||||||
const byId = Object.assign({}, state.byId);
|
const byId = Object.assign({}, state.byId);
|
||||||
const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
|
const channelClaimCounts = Object.assign({}, state.channelClaimCounts);
|
||||||
|
|
||||||
Object.entries(resolveInfo).forEach(
|
Object.entries(resolveInfo).forEach(([uri: string, resolveResponse: Claim]) => {
|
||||||
([uri: string, resolveResponse: ClaimWithPossibleCertificate]) => {
|
// $FlowFixMe
|
||||||
|
if (resolveResponse.claimsInChannel) {
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
if (resolveResponse.certificate && !Number.isNaN(resolveResponse.claimsInChannel)) {
|
channelClaimCounts[uri] = resolveResponse.claimsInChannel;
|
||||||
// $FlowFixMe
|
|
||||||
channelClaimCounts[uri] = resolveResponse.claimsInChannel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
Object.entries(resolveInfo).forEach(([uri, { certificate, claim }]) => {
|
Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => {
|
||||||
if (claim && !certificate) {
|
if (stream) {
|
||||||
byId[claim.claim_id] = claim;
|
byId[stream.claim_id] = stream;
|
||||||
byUri[uri] = claim.claim_id;
|
byUri[uri] = stream.claim_id;
|
||||||
} else if (claim && certificate) {
|
}
|
||||||
byId[claim.claim_id] = claim;
|
if (channel) {
|
||||||
byUri[uri] = claim.claim_id;
|
byId[channel.claim_id] = channel;
|
||||||
|
byUri[stream ? channel.permanent_url : uri] = channel.claim_id;
|
||||||
byId[certificate.claim_id] = certificate;
|
}
|
||||||
const channelUri = `lbry://${certificate.name}#${certificate.claim_id}`;
|
if (!stream && !channel) {
|
||||||
byUri[channelUri] = certificate.claim_id;
|
|
||||||
} else if (!claim && certificate) {
|
|
||||||
byId[certificate.claim_id] = certificate;
|
|
||||||
byUri[uri] = certificate.claim_id;
|
|
||||||
} else {
|
|
||||||
byUri[uri] = null;
|
byUri[uri] = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -87,6 +90,12 @@ reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State =>
|
||||||
channelClaimCounts,
|
channelClaimCounts,
|
||||||
resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]),
|
resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => {
|
||||||
|
return {
|
||||||
|
...handleClaimAction(state, action),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State =>
|
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State =>
|
||||||
|
@ -95,15 +104,12 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State =>
|
||||||
});
|
});
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => {
|
reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => {
|
||||||
const { claims }: { claims: Array<StreamClaim | ChannelClaim> } = action.data;
|
const { claims }: { claims: Array<Claim> } = action.data;
|
||||||
const byId = Object.assign({}, state.byId);
|
const byId = Object.assign({}, state.byId);
|
||||||
const byUri = Object.assign({}, state.claimsByUri);
|
const byUri = Object.assign({}, state.claimsByUri);
|
||||||
const pendingById: { [string]: StreamClaim | ChannelClaim } = Object.assign(
|
const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById);
|
||||||
{},
|
|
||||||
state.pendingById
|
|
||||||
);
|
|
||||||
|
|
||||||
claims.forEach((claim: StreamClaim | ChannelClaim) => {
|
claims.forEach((claim: Claim) => {
|
||||||
const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id });
|
const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id });
|
||||||
|
|
||||||
if (claim.type && claim.type.match(/claim|update/)) {
|
if (claim.type && claim.type.match(/claim|update/)) {
|
||||||
|
@ -267,6 +273,24 @@ reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
fetchingClaimSearch: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => {
|
||||||
|
return {
|
||||||
|
...handleClaimAction(state, action),
|
||||||
|
fetchingClaimSearch: false,
|
||||||
|
lastClaimSearchUris: action.data.uris,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
fetchingClaimSearch: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export function claimsReducer(state: State = defaultState, action: any) {
|
export function claimsReducer(state: State = defaultState, action: any) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
63
src/redux/reducers/comments.js
Normal file
63
src/redux/reducers/comments.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// @flow
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { handleActions } from 'util/redux-utils';
|
||||||
|
|
||||||
|
const defaultState: CommentsState = {
|
||||||
|
byId: {},
|
||||||
|
commentsByUri: {},
|
||||||
|
isLoading: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const commentReducer = handleActions(
|
||||||
|
{
|
||||||
|
[ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({
|
||||||
|
...state,
|
||||||
|
isLoading: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
[ACTIONS.COMMENT_CREATE_FAILED]: (state: CommentsState, action: any) => ({
|
||||||
|
...state,
|
||||||
|
isLoading: false,
|
||||||
|
}),
|
||||||
|
|
||||||
|
[ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => {
|
||||||
|
const { comment, claimId }: any = action.data;
|
||||||
|
const byId = Object.assign({}, state.byId);
|
||||||
|
const comments = byId[claimId];
|
||||||
|
const newComments = comments.slice();
|
||||||
|
|
||||||
|
newComments.unshift(comment);
|
||||||
|
byId[claimId] = newComments;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
byId,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.COMMENT_LIST_STARTED]: state => ({ ...state, isLoading: true }),
|
||||||
|
|
||||||
|
[ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => {
|
||||||
|
const { comments, claimId, uri } = action.data;
|
||||||
|
const byId = Object.assign({}, state.byId);
|
||||||
|
const commentsByUri = Object.assign({}, state.commentsByUri);
|
||||||
|
|
||||||
|
if (comments['items']) {
|
||||||
|
byId[claimId] = comments['items'];
|
||||||
|
commentsByUri[uri] = claimId;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
byId,
|
||||||
|
commentsByUri,
|
||||||
|
isLoading: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.COMMENT_LIST_FAILED]: (state: CommentsState, action: any) => ({
|
||||||
|
...state,
|
||||||
|
isLoading: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
defaultState
|
||||||
|
);
|
|
@ -161,16 +161,6 @@ reducers[ACTIONS.LOADING_VIDEO_FAILED] = (state, action) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[ACTIONS.FETCH_DATE] = (state, action) => {
|
|
||||||
const { time } = action.data;
|
|
||||||
if (time) {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
publishedDate: time,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[ACTIONS.SET_FILE_LIST_SORT] = (state, action) => {
|
reducers[ACTIONS.SET_FILE_LIST_SORT] = (state, action) => {
|
||||||
const pageSortStates = {
|
const pageSortStates = {
|
||||||
[PAGES.PUBLISHED]: 'fileListPublishedSort',
|
[PAGES.PUBLISHED]: 'fileListPublishedSort',
|
||||||
|
|
55
src/redux/reducers/tags.js
Normal file
55
src/redux/reducers/tags.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// @flow
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { handleActions } from 'util/redux-utils';
|
||||||
|
|
||||||
|
export const tagsReducerBuilder = (defaultState: TagState) =>
|
||||||
|
handleActions(
|
||||||
|
{
|
||||||
|
[ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => {
|
||||||
|
const { followedTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newFollowedTags = followedTags.slice();
|
||||||
|
|
||||||
|
if (newFollowedTags.includes(name)) {
|
||||||
|
newFollowedTags = newFollowedTags.filter(tag => tag !== name);
|
||||||
|
} else {
|
||||||
|
newFollowedTags.push(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
followedTags: newFollowedTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => {
|
||||||
|
const { knownTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newKnownTags = { ...knownTags };
|
||||||
|
newKnownTags[name] = { name };
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
knownTags: newKnownTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => {
|
||||||
|
const { knownTags, followedTags } = state;
|
||||||
|
const { name } = action.data;
|
||||||
|
|
||||||
|
let newKnownTags = { ...knownTags };
|
||||||
|
delete newKnownTags[name];
|
||||||
|
const newFollowedTags = followedTags.filter(tag => tag !== name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
knownTags: newKnownTags,
|
||||||
|
followedTags: newFollowedTags,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultState
|
||||||
|
);
|
|
@ -190,7 +190,12 @@ export const makeSelectDateForUri = (uri: string) =>
|
||||||
createSelector(
|
createSelector(
|
||||||
makeSelectClaimForUri(uri),
|
makeSelectClaimForUri(uri),
|
||||||
claim => {
|
claim => {
|
||||||
const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined;
|
const timestamp =
|
||||||
|
claim &&
|
||||||
|
claim.value &&
|
||||||
|
(claim.value.release_time
|
||||||
|
? claim.value.release_time * 1000
|
||||||
|
: claim.meta.creation_timestamp * 1000);
|
||||||
if (!timestamp) {
|
if (!timestamp) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +259,11 @@ export const selectMyClaimsWithoutChannels = createSelector(
|
||||||
myClaims => myClaims.filter(claim => !claim.name.match(/^@/))
|
myClaims => myClaims.filter(claim => !claim.name.match(/^@/))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectMyClaimUrisWithoutChannels = createSelector(
|
||||||
|
selectMyClaimsWithoutChannels,
|
||||||
|
myClaims => myClaims.map(claim => `lbry://${claim.name}#${claim.claim_id}`)
|
||||||
|
);
|
||||||
|
|
||||||
export const selectAllMyClaimsByOutpoint = createSelector(
|
export const selectAllMyClaimsByOutpoint = createSelector(
|
||||||
selectMyClaimsRaw,
|
selectMyClaimsRaw,
|
||||||
claims =>
|
claims =>
|
||||||
|
@ -368,7 +378,7 @@ export const makeSelectClaimIsNsfw = (uri: string): boolean =>
|
||||||
// Or possibly come from users settings of what tags they want to hide
|
// Or possibly come from users settings of what tags they want to hide
|
||||||
// For now, there is just a hard coded list of tags inside `isClaimNsfw`
|
// For now, there is just a hard coded list of tags inside `isClaimNsfw`
|
||||||
// selectNaughtyTags(),
|
// selectNaughtyTags(),
|
||||||
(claim: StreamClaim) => {
|
(claim: Claim) => {
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -428,3 +438,21 @@ export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean
|
||||||
return includePrefix ? `lbry://${channel}` : channel;
|
return includePrefix ? `lbry://${channel}` : channel;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const makeSelectTagsForUri = (uri: string) =>
|
||||||
|
createSelector(
|
||||||
|
makeSelectMetadataForUri(uri),
|
||||||
|
(metadata: ?GenericMetadata) => {
|
||||||
|
return (metadata && metadata.tags) || [];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectFetchingClaimSearch = createSelector(
|
||||||
|
selectState,
|
||||||
|
state => state.fetchingClaimSearch
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectLastClaimSearchUris = createSelector(
|
||||||
|
selectState,
|
||||||
|
state => state.lastClaimSearchUris
|
||||||
|
);
|
||||||
|
|
36
src/redux/selectors/comments.js
Normal file
36
src/redux/selectors/comments.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// @flow
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
const selectState = state => state.comments || {};
|
||||||
|
|
||||||
|
export const selectCommentsById = createSelector(
|
||||||
|
selectState,
|
||||||
|
state => state.byId || {}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectCommentsByUri = createSelector(
|
||||||
|
selectState,
|
||||||
|
state => {
|
||||||
|
const byUri = state.commentsByUri || {};
|
||||||
|
const comments = {};
|
||||||
|
Object.keys(byUri).forEach(uri => {
|
||||||
|
const claimId = byUri[uri];
|
||||||
|
if (claimId === null) {
|
||||||
|
comments[uri] = null;
|
||||||
|
} else {
|
||||||
|
comments[uri] = claimId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const makeSelectCommentsForUri = (uri: string) =>
|
||||||
|
createSelector(
|
||||||
|
selectCommentsById,
|
||||||
|
selectCommentsByUri,
|
||||||
|
(byId, byUri) => {
|
||||||
|
const claimId = byUri[uri];
|
||||||
|
return byId && byId[claimId];
|
||||||
|
}
|
||||||
|
);
|
|
@ -164,10 +164,12 @@ export const selectSearchDownloadUris = query =>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const titleParts = title.toLowerCase().split(' ');
|
if (title) {
|
||||||
if (arrayContainsQueryPart(titleParts)) {
|
const titleParts = title.toLowerCase().split(' ');
|
||||||
downloadResultsFromQuery.push(fileInfo);
|
if (arrayContainsQueryPart(titleParts)) {
|
||||||
return;
|
downloadResultsFromQuery.push(fileInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (author) {
|
if (author) {
|
||||||
|
@ -226,3 +228,9 @@ export const selectFileListDownloadedSort = createSelector(
|
||||||
selectState,
|
selectState,
|
||||||
state => state.fileListDownloadedSort
|
state => state.fileListDownloadedSort
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectDownloadedUris = createSelector(
|
||||||
|
selectFileInfosDownloaded,
|
||||||
|
// We should use permament_url but it doesn't exist in file_list
|
||||||
|
info => info.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)
|
||||||
|
);
|
||||||
|
|
|
@ -57,20 +57,21 @@ export const selectSearchSuggestions: Array<SearchSuggestion> = createSelector(
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://';
|
const queryIsPrefix =
|
||||||
|
query === 'lbry:' || query === 'lbry:/' || query === 'lbry://' || query === 'lbry://@';
|
||||||
|
|
||||||
if (query.startsWith('lbry://') && query !== 'lbry://') {
|
if (queryIsPrefix) {
|
||||||
|
// If it is a prefix, wait until something else comes to figure out what to do
|
||||||
|
return [];
|
||||||
|
} else if (query.startsWith('lbry://')) {
|
||||||
// If it starts with a prefix, don't show any autocomplete results
|
// If it starts with a prefix, don't show any autocomplete results
|
||||||
// They are probably typing/pasting in a lbry uri
|
// They are probably typing/pasting in a lbry uri
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
value: query,
|
value: query,
|
||||||
type: SEARCH_TYPES.FILE,
|
type: query[7] === '@' ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (queryIsPrefix) {
|
|
||||||
// If it is a prefix, wait until something else comes to figure out what to do
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let searchSuggestions = [];
|
let searchSuggestions = [];
|
||||||
|
|
38
src/redux/selectors/tags.js
Normal file
38
src/redux/selectors/tags.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// @flow
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
const selectState = (state: { tags: TagState }) => state.tags || {};
|
||||||
|
|
||||||
|
export const selectKnownTagsByName = createSelector(
|
||||||
|
selectState,
|
||||||
|
(state: TagState): KnownTags => state.knownTags
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectFollowedTagsList = createSelector(
|
||||||
|
selectState,
|
||||||
|
(state: TagState): Array<string> => state.followedTags
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectFollowedTags = createSelector(
|
||||||
|
selectFollowedTagsList,
|
||||||
|
(followedTags: Array<string>): Array<Tag> =>
|
||||||
|
followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name))
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectUnfollowedTags = createSelector(
|
||||||
|
selectKnownTagsByName,
|
||||||
|
selectFollowedTagsList,
|
||||||
|
(tagsByName: KnownTags, followedTags: Array<string>): Array<Tag> => {
|
||||||
|
const followedTagsSet = new Set(followedTags);
|
||||||
|
let tagsToReturn = [];
|
||||||
|
|
||||||
|
Object.keys(tagsByName).forEach(key => {
|
||||||
|
if (!followedTagsSet.has(key)) {
|
||||||
|
const { name } = tagsByName[key];
|
||||||
|
tagsToReturn.push({ name });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return tagsToReturn;
|
||||||
|
}
|
||||||
|
);
|
|
@ -5,7 +5,7 @@ const naughtyTags = ['porn', 'nsfw', 'mature', 'xxx'].reduce(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isClaimNsfw = (claim: StreamClaim): boolean => {
|
export const isClaimNsfw = (claim: Claim): boolean => {
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
throw new Error('No claim passed to isClaimNsfw()');
|
throw new Error('No claim passed to isClaimNsfw()');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue