├── .env.defaults ├── .eslintignore ├── .eslintrc ├── .flowconfig ├── .github ├── ISSUE_TEMPLATE │ ├── --bug-report.md │ ├── --feature-request.md │ └── --say-thank-you.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── deploy.yml ├── .gitignore ├── .lintstagedrc.json ├── .prettierrc.json ├── .sentryclirc ├── .tx └── config ├── .yarn ├── plugins │ └── @yarnpkg │ │ └── plugin-version.cjs ├── releases │ └── yarn-3.2.0.cjs └── versions │ ├── 17d7e90d.yml │ ├── 33178102.yml │ ├── 35f2125e.yml │ ├── 4f9fb046.yml │ ├── 5bc94294.yml │ ├── 5f1212ad.yml │ ├── 5f4cac99.yml │ ├── 6b35c994.yml │ ├── 6be5ab70.yml │ ├── 86ac1afd.yml │ ├── 8e384637.yml │ ├── 909c3734.yml │ ├── 951a8d12.yml │ ├── 97e7141a.yml │ ├── ac69bc5f.yml │ ├── c6e2b914.yml │ ├── d1a18cef.yml │ ├── ec3a9ddf.yml │ ├── fc1fde84.yml │ └── fc597c00.yml ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── build ├── afterAllArtifactBuild.js ├── afterSignHook.js ├── background.png ├── cert-2021-2022.pfx ├── cert2023.pfx ├── downloadDaemon.js ├── downloadLBRYFirst.js ├── entitlements.mac.plist ├── icon.icns ├── icon.ico ├── icons │ ├── 128x128.png │ ├── 256x256.png │ ├── 32x32.png │ ├── 48x48.png │ ├── 96x96.png │ ├── lbry128.ico │ ├── lbry16.ico │ ├── lbry256.ico │ ├── lbry32.ico │ ├── lbry48.ico │ └── lbry96.ico └── signBuildFiles.js ├── config.js ├── custom ├── homepage.example.js ├── homepages │ └── .gitkeep ├── robots.allowall └── robots.disallowall ├── electron-builder.json ├── electron ├── Daemon.js ├── LbryFirstInstance.js ├── createTray.js ├── createWindow.js ├── devServer.js ├── index.js ├── installDevtools.js ├── menu │ └── setupBarMenu.js ├── sandboxTest.js └── startSandbox.js ├── extras ├── lbry-first │ └── lbry-first.js ├── lbryinc │ ├── constants │ │ ├── action_types.js │ │ ├── claim.js │ │ ├── errors.js │ │ └── youtube.js │ ├── index.js │ ├── lbryio.js │ ├── redux │ │ ├── actions │ │ │ ├── auth.js │ │ │ ├── blacklist.js │ │ │ ├── cost_info.js │ │ │ ├── filtered.js │ │ │ ├── stats.js │ │ │ └── sync.js │ │ ├── reducers │ │ │ ├── auth.js │ │ │ ├── blacklist.js │ │ │ ├── cost_info.js │ │ │ ├── filtered.js │ │ │ ├── stats.js │ │ │ └── sync.js │ │ └── selectors │ │ │ ├── auth.js │ │ │ ├── ban.js │ │ │ ├── blacklist.js │ │ │ ├── cost_info.js │ │ │ ├── filtered.js │ │ │ ├── stats.js │ │ │ └── sync.js │ └── util │ │ ├── redux-utils-delete-me.js │ │ ├── swap-json.js │ │ └── transifex-upload.js └── recsys │ ├── index.js │ └── recsys.js ├── flow-typed ├── 18nj.js ├── Blocklist.js ├── Claim.js ├── CoinSwap.js ├── Collections.js ├── Comment.js ├── File.js ├── Lbry.js ├── LbryFirst.js ├── Notification.js ├── Publish.js ├── Redux.js ├── Reflector.js ├── Settings.js ├── Tags.js ├── Transaction.js ├── Txo.js ├── bluebird.js ├── classnames.js ├── content.js ├── electron.js ├── file-data.js ├── file-with-path.js ├── formik.js ├── homepage.js ├── i18n.js ├── lbryURI.js ├── livestream.js ├── location.js ├── npm │ ├── @babel │ │ ├── core_vx.x.x.js │ │ ├── plugin-proposal-class-properties_vx.x.x.js │ │ ├── plugin-proposal-decorators_vx.x.x.js │ │ ├── plugin-transform-flow-strip-types_vx.x.x.js │ │ ├── polyfill_v7.x.x.js │ │ ├── preset-flow_vx.x.x.js │ │ ├── preset-react_vx.x.x.js │ │ └── register_v7.x.x.js │ ├── @hot-loader │ │ └── react-dom_vx.x.x.js │ ├── @lbry │ │ ├── color_vx.x.x.js │ │ └── components_vx.x.x.js │ ├── @types │ │ └── three_vx.x.x.js │ ├── async-exit-hook_vx.x.x.js │ ├── babel-eslint_vx.x.x.js │ ├── babel-loader_vx.x.x.js │ ├── babel-plugin-add-module-exports_vx.x.x.js │ ├── babel-plugin-transform-imports_vx.x.x.js │ ├── bluebird_v3.x.x.js │ ├── chalk_v2.x.x.js │ ├── classnames_v2.x.x.js │ ├── codemirror_vx.x.x.js │ ├── copy-webpack-plugin_vx.x.x.js │ ├── country-data_vx.x.x.js │ ├── cross-env_vx.x.x.js │ ├── css-loader_vx.x.x.js │ ├── dat.gui_vx.x.x.js │ ├── decompress_vx.x.x.js │ ├── del_v3.x.x.js │ ├── devtron_vx.x.x.js │ ├── dom-scroll-into-view_vx.x.x.js │ ├── electron-builder_vx.x.x.js │ ├── electron-devtools-installer_vx.x.x.js │ ├── electron-dl_vx.x.x.js │ ├── electron-is-dev_vx.x.x.js │ ├── electron-log_vx.x.x.js │ ├── electron-publisher-s3_vx.x.x.js │ ├── electron-updater_vx.x.x.js │ ├── electron-webpack_vx.x.x.js │ ├── electron-window-state_vx.x.x.js │ ├── electron_vx.x.x.js │ ├── eslint-config-airbnb_vx.x.x.js │ ├── eslint-config-prettier_vx.x.x.js │ ├── eslint-config-standard-jsx_vx.x.x.js │ ├── eslint-config-standard_vx.x.x.js │ ├── eslint-import-resolver-webpack_vx.x.x.js │ ├── eslint-plugin-flowtype_vx.x.x.js │ ├── eslint-plugin-import_vx.x.x.js │ ├── eslint-plugin-jsx-a11y_vx.x.x.js │ ├── eslint-plugin-node_vx.x.x.js │ ├── eslint-plugin-prettier_vx.x.x.js │ ├── eslint-plugin-promise_vx.x.x.js │ ├── eslint-plugin-react_vx.x.x.js │ ├── eslint-plugin-standard_vx.x.x.js │ ├── eslint_vx.x.x.js │ ├── express_v4.16.x.js │ ├── flow-bin_v0.x.x.js │ ├── flow-typed_vx.x.x.js │ ├── formik_vx.x.x.js │ ├── hast-util-sanitize_vx.x.x.js │ ├── husky_vx.x.x.js │ ├── json-loader_vx.x.x.js │ ├── lbry-format_vx.x.x.js │ ├── lbry-redux_vx.x.x.js │ ├── lbryinc_vx.x.x.js │ ├── lint-staged_vx.x.x.js │ ├── localforage_v1.5.x.js │ ├── make-runnable_vx.x.x.js │ ├── mammoth_vx.x.x.js │ ├── mixpanel-browser_v2.11.x.js │ ├── moment_v2.x.x.js │ ├── node-abi_vx.x.x.js │ ├── node-fetch_vx.x.x.js │ ├── node-libs-browser_vx.x.x.js │ ├── node-loader_vx.x.x.js │ ├── preprocess-loader_vx.x.x.js │ ├── prettier_v1.x.x.js │ ├── prop-types_v15.x.x.js │ ├── qrcode.react_vx.x.x.js │ ├── raw-loader_vx.x.x.js │ ├── rc-progress_vx.x.x.js │ ├── react-hot-loader_v4.6.x.js │ ├── react-modal_v3.1.x.js │ ├── react-paginate_vx.x.x.js │ ├── react-redux_v5.x.x.js │ ├── react-simplemde-editor_vx.x.x.js │ ├── react-toggle_v4.0.x.js │ ├── redux-persist-transform-compress_vx.x.x.js │ ├── redux-persist-transform-filter_vx.x.x.js │ ├── redux-thunk_vx.x.x.js │ ├── remark-emoji_vx.x.x.js │ ├── remark-react_vx.x.x.js │ ├── remark_vx.x.x.js │ ├── render-media_vx.x.x.js │ ├── reselect_v3.x.x.js │ ├── sass-loader_vx.x.x.js │ ├── semver_v5.1.x.js │ ├── stream-to-blob-url_vx.x.x.js │ ├── style-loader_vx.x.x.js │ ├── three-full_vx.x.x.js │ ├── three_vx.x.x.js │ ├── tree-kill_vx.x.x.js │ ├── video.js_vx.x.x.js │ ├── webpack-config-utils_vx.x.x.js │ ├── webpack-dev-middleware_vx.x.x.js │ ├── webpack-dev-server_vx.x.x.js │ ├── webpack-hot-middleware_vx.x.x.js │ ├── webpack-merge_vx.x.x.js │ ├── webpack-node-externals_vx.x.x.js │ ├── webpack_v4.x.x.js │ ├── y18n_vx.x.x.js │ └── yarnhook_vx.x.x.js ├── qrcode.react.js ├── react-markdown.js ├── react-modal.js ├── react-paginate.js ├── react-simplemde-editor.js ├── react-transition-group.js ├── reportContent.js ├── reselect.js ├── reward.js ├── search.js ├── shapeshift.io.js ├── subscription.js ├── user.js └── web.js ├── homepages ├── homepage.js ├── index.js └── meme │ └── index.js ├── package.json ├── postcss.config.js ├── static ├── app-strings.json ├── app-update.yml ├── font │ └── v1 │ │ ├── 300.woff │ │ ├── 300i.woff │ │ ├── 400.woff │ │ ├── 400i.woff │ │ ├── 700.woff │ │ └── 700i.woff ├── img │ ├── busy.gif │ ├── favicon-spaceman.png │ ├── favicon.png │ ├── fileRenderPlaceholder.png │ ├── freespch.png │ ├── placeholderTx.gif │ ├── tray │ │ ├── default │ │ │ └── tray.png │ │ ├── mac │ │ │ ├── trayTemplate.png │ │ │ ├── trayTemplate@2x copy.png │ │ │ └── trayTemplate@2x.png │ │ └── windows │ │ │ └── tray.ico │ ├── unlocklbry.svg │ ├── v2-og.png │ ├── yrblhappy.svg │ ├── yrblsad.svg │ └── yrblsec.svg ├── index-electron.html ├── index-web.html ├── opensearch.xml ├── robots.txt └── webworkers │ ├── wasm-gen │ ├── libarchive.js │ └── libarchive.wasm │ └── worker-bundle.js ├── ui ├── analytics.js ├── app.js ├── comments.js ├── component │ ├── IframeReact │ │ ├── index.js │ │ └── view.jsx │ ├── abandonedChannelPreview │ │ ├── index.js │ │ └── view.jsx │ ├── app │ │ ├── index.js │ │ └── view.jsx │ ├── appStorageVisualization │ │ ├── index.js │ │ └── view.jsx │ ├── autoplayCountdown │ │ ├── index.js │ │ └── view.jsx │ ├── blockList │ │ ├── index.js │ │ └── view.jsx │ ├── button │ │ ├── index.js │ │ └── view.jsx │ ├── cardVerify │ │ ├── index.js │ │ └── view.jsx │ ├── channelAbout │ │ ├── index.js │ │ └── view.jsx │ ├── channelBlockButton │ │ ├── index.js │ │ └── view.jsx │ ├── channelContent │ │ ├── index.js │ │ └── view.jsx │ ├── channelDiscussion │ │ ├── index.js │ │ └── view.jsx │ ├── channelForm │ │ ├── index.js │ │ └── view.jsx │ ├── channelMuteButton │ │ ├── index.js │ │ └── view.jsx │ ├── channelSelector │ │ ├── index.js │ │ └── view.jsx │ ├── channelStakedIndicator │ │ ├── index.js │ │ └── view.jsx │ ├── channelThumbnail │ │ ├── gerbil.png │ │ ├── index.js │ │ └── view.jsx │ ├── channelTitle │ │ ├── index.js │ │ └── view.jsx │ ├── claimAbandonButton │ │ ├── index.js │ │ └── view.jsx │ ├── claimAuthor │ │ ├── index.js │ │ └── view.jsx │ ├── claimCollectionAdd │ │ ├── index.js │ │ └── view.jsx │ ├── claimCollectionAddButton │ │ ├── index.js │ │ └── view.jsx │ ├── claimEffectiveAmount │ │ ├── index.js │ │ └── view.jsx │ ├── claimInsufficientCredits │ │ ├── index.js │ │ └── view.jsx │ ├── claimLink │ │ ├── index.js │ │ └── view.jsx │ ├── claimList │ │ ├── index.js │ │ └── view.jsx │ ├── claimListDiscover │ │ ├── index.js │ │ └── view.jsx │ ├── claimListHeader │ │ ├── index.js │ │ └── view.jsx │ ├── claimMenuList │ │ ├── index.js │ │ └── view.jsx │ ├── claimPreview │ │ ├── claim-preview-loading.jsx │ │ ├── claim-preview-no-content.jsx │ │ ├── claim-preview-no-mature.jsx │ │ ├── collection-buttons.jsx │ │ ├── index.js │ │ └── view.jsx │ ├── claimPreviewSubtitle │ │ ├── index.js │ │ └── view.jsx │ ├── claimPreviewTile │ │ ├── index.js │ │ └── view.jsx │ ├── claimPreviewTitle │ │ ├── index.js │ │ └── view.jsx │ ├── claimProperties │ │ ├── index.js │ │ └── view.jsx │ ├── claimRepostAuthor │ │ ├── index.js │ │ └── view.jsx │ ├── claimRepostButton │ │ ├── index.js │ │ └── view.jsx │ ├── claimSupportButton │ │ ├── index.js │ │ └── view.jsx │ ├── claimTags │ │ ├── index.js │ │ └── view.jsx │ ├── claimTilesDiscover │ │ ├── index.js │ │ └── view.jsx │ ├── claimType │ │ ├── index.js │ │ └── view.jsx │ ├── claimUri │ │ ├── index.js │ │ └── view.jsx │ ├── collectionActions │ │ ├── index.js │ │ └── view.jsx │ ├── collectionContentSidebar │ │ ├── index.js │ │ └── view.jsx │ ├── collectionEdit │ │ ├── index.js │ │ └── view.jsx │ ├── collectionEditButtons │ │ ├── index.js │ │ └── view.jsx │ ├── collectionMenuList │ │ ├── index.js │ │ └── view.jsx │ ├── collectionPreviewOverlay │ │ ├── index.js │ │ └── view.jsx │ ├── collectionPreviewTile │ │ ├── collectionCount.jsx │ │ ├── collectionPrivate.jsx │ │ ├── index.js │ │ └── view.jsx │ ├── collectionSelectItem │ │ ├── index.js │ │ └── view.jsx │ ├── collectionsListMine │ │ ├── index.js │ │ └── view.jsx │ ├── comment │ │ ├── index.js │ │ └── view.jsx │ ├── commentCreate │ │ ├── comment-create-header.jsx │ │ ├── emote-selector.jsx │ │ ├── index.js │ │ ├── sticker-selector.jsx │ │ └── view.jsx │ ├── commentMenuList │ │ ├── index.js │ │ └── view.jsx │ ├── commentReactions │ │ ├── index.js │ │ └── view.jsx │ ├── commentsList │ │ ├── index.js │ │ └── view.jsx │ ├── commentsReplies │ │ ├── index.js │ │ └── view.jsx │ ├── common │ │ ├── busy-indicator.jsx │ │ ├── card.jsx │ │ ├── comment-badge.jsx │ │ ├── credit-amount.jsx │ │ ├── debounced-input.jsx │ │ ├── empty.jsx │ │ ├── error-text.jsx │ │ ├── file-exporter.jsx │ │ ├── file-list.jsx │ │ ├── file-selector.jsx │ │ ├── form-components │ │ │ ├── form-field-area-advanced.jsx │ │ │ ├── form-field-price.jsx │ │ │ ├── form-field.jsx │ │ │ ├── form-row.jsx │ │ │ ├── form.jsx │ │ │ └── submit.jsx │ │ ├── form.jsx │ │ ├── header-menu-link.jsx │ │ ├── help-link.jsx │ │ ├── hidden-nsfw.jsx │ │ ├── icon-custom.jsx │ │ ├── icon.jsx │ │ ├── lbc-message.jsx │ │ ├── lbc-symbol.jsx │ │ ├── loading-screen.jsx │ │ ├── markdown-preview.jsx │ │ ├── nag.jsx │ │ ├── paginate.jsx │ │ ├── qr-code.jsx │ │ ├── status-bar.jsx │ │ ├── tabs.jsx │ │ ├── thumbnail.jsx │ │ ├── tooltip.jsx │ │ ├── transaction-link.jsx │ │ ├── truncated-text.jsx │ │ └── wait-until-on-page.jsx │ ├── copyableText │ │ ├── index.js │ │ └── view.jsx │ ├── creatorAnalytics │ │ ├── index.js │ │ └── view.jsx │ ├── dateTime │ │ ├── index.js │ │ └── view.jsx │ ├── emailCollection │ │ ├── index.js │ │ └── view.jsx │ ├── embedPlayButton │ │ ├── index.js │ │ └── view.jsx │ ├── embedTextArea │ │ ├── index.js │ │ └── view.jsx │ ├── errorBoundary │ │ ├── index.js │ │ └── view.jsx │ ├── expandable │ │ ├── index.js │ │ └── view.jsx │ ├── fileActions │ │ ├── index.js │ │ └── view.jsx │ ├── fileDescription │ │ ├── index.js │ │ └── view.jsx │ ├── fileDetails │ │ ├── index.js │ │ └── view.jsx │ ├── fileDownloadLink │ │ ├── index.js │ │ └── view.jsx │ ├── fileDrop │ │ ├── index.js │ │ └── view.jsx │ ├── filePrice │ │ ├── index.js │ │ └── view.jsx │ ├── fileReactions │ │ ├── index.js │ │ └── view.jsx │ ├── fileRender │ │ ├── index.js │ │ └── view.jsx │ ├── fileRenderDownload │ │ ├── index.js │ │ └── view.jsx │ ├── fileRenderFloating │ │ ├── index.js │ │ └── view.jsx │ ├── fileRenderInitiator │ │ ├── index.js │ │ └── view.jsx │ ├── fileRenderInline │ │ ├── index.js │ │ └── view.jsx │ ├── fileSubtitle │ │ ├── index.js │ │ └── view.jsx │ ├── fileThumbnail │ │ ├── FreezeframeLite │ │ │ ├── classes.js │ │ │ ├── index.js │ │ │ ├── styles.scss │ │ │ ├── templates.js │ │ │ └── utils.js │ │ ├── FreezeframeWrapper.jsx │ │ ├── index.js │ │ ├── placeholder.png │ │ ├── thumb.jsx │ │ └── view.jsx │ ├── fileTitle │ │ ├── index.js │ │ └── view.jsx │ ├── fileTitleSection │ │ ├── index.js │ │ └── view.jsx │ ├── fileType │ │ ├── index.js │ │ └── view.jsx │ ├── fileValues │ │ ├── index.js │ │ └── view.jsx │ ├── fileViewCount │ │ ├── index.js │ │ └── view.jsx │ ├── fileViewCountInline │ │ ├── index.js │ │ └── view.jsx │ ├── fileViewerEmbeddedTitle │ │ ├── index.js │ │ └── view.jsx │ ├── fileWatchLaterLink │ │ ├── index.js │ │ └── view.jsx │ ├── formFieldPrice │ │ ├── index.js │ │ └── view.jsx │ ├── header │ │ ├── index.js │ │ ├── odysee.png │ │ ├── odysee_logo.png │ │ ├── odysee_white.png │ │ └── view.jsx │ ├── headerMenuButtons │ │ ├── index.js │ │ └── view.jsx │ ├── headerNotificationButton │ │ ├── index.js │ │ └── view.jsx │ ├── headerProfileMenuButton │ │ ├── index.js │ │ └── view.jsx │ ├── hiddenNsfwClaims │ │ ├── index.js │ │ └── view.jsx │ ├── homepageSelector │ │ ├── index.js │ │ └── view.jsx │ ├── hostingSplash │ │ ├── index.js │ │ └── view.jsx │ ├── hostingSplashCustom │ │ ├── index.js │ │ └── view.jsx │ ├── i18nMessage │ │ ├── index.js │ │ └── view.jsx │ ├── lastReleaseChanges │ │ ├── index.js │ │ └── view.jsx │ ├── loginGraphic │ │ └── index.jsx │ ├── logo │ │ ├── index.js │ │ └── view.jsx │ ├── markdownLink │ │ ├── index.js │ │ └── view.jsx │ ├── maxPurchasePrice │ │ ├── index.js │ │ └── view.jsx │ ├── nagContinueFirstRun │ │ ├── index.js │ │ └── view.jsx │ ├── navigationButton │ │ ├── index.js │ │ └── view.jsx │ ├── navigationHistory │ │ ├── index.js │ │ └── view.jsx │ ├── navigationHistoryItem │ │ ├── index.js │ │ └── view.jsx │ ├── navigationHistoryRecent │ │ ├── index.js │ │ └── view.jsx │ ├── notification │ │ ├── index.js │ │ └── view.jsx │ ├── notificationBubble │ │ ├── index.js │ │ └── view.jsx │ ├── notificationContentChannelMenu │ │ ├── index.js │ │ └── view.jsx │ ├── nudgeFloating │ │ ├── index.js │ │ └── view.jsx │ ├── optimizedImage │ │ ├── index.js │ │ └── view.jsx │ ├── page │ │ ├── index.js │ │ └── view.jsx │ ├── playlistsMine │ │ ├── index.js │ │ └── view.jsx │ ├── postEditor │ │ ├── index.js │ │ └── view.jsx │ ├── postViewer │ │ ├── index.js │ │ └── view.jsx │ ├── previewLink │ │ ├── index.js │ │ └── view.jsx │ ├── previewOverlayProperties │ │ ├── index.js │ │ └── view.jsx │ ├── privacyAgreement │ │ ├── index.js │ │ └── view.jsx │ ├── publishAdditionalOptions │ │ ├── index.js │ │ ├── license-type.jsx │ │ └── view.jsx │ ├── publishBid │ │ ├── bid-help-text.jsx │ │ ├── index.js │ │ └── view.jsx │ ├── publishDescription │ │ ├── index.js │ │ └── view.jsx │ ├── publishFile │ │ ├── index.js │ │ └── view.jsx │ ├── publishForm │ │ ├── index.js │ │ └── view.jsx │ ├── publishFormErrors │ │ ├── index.js │ │ └── view.jsx │ ├── publishName │ │ ├── bid-help-text.jsx │ │ ├── index.js │ │ ├── name-help-text.jsx │ │ └── view.jsx │ ├── publishPending │ │ ├── index.js │ │ └── view.jsx │ ├── publishPrice │ │ ├── index.js │ │ └── view.jsx │ ├── publishReleaseDate │ │ ├── index.js │ │ └── view.jsx │ ├── ratioBar │ │ ├── index.js │ │ └── view.jsx │ ├── recommendedContent │ │ ├── index.js │ │ └── view.jsx │ ├── reportContent │ │ ├── index.js │ │ └── view.jsx │ ├── repostCreate │ │ ├── index.js │ │ └── view.jsx │ ├── router │ │ ├── index.js │ │ └── view.jsx │ ├── searchChannelField │ │ ├── index.js │ │ └── view.jsx │ ├── searchOptions │ │ ├── index.js │ │ └── view.jsx │ ├── searchTopClaim │ │ ├── index.js │ │ └── view.jsx │ ├── selectAsset │ │ ├── index.js │ │ ├── thumbnail-broken.png │ │ ├── thumbnail-missing.png │ │ └── view.jsx │ ├── selectChannel │ │ ├── index.js │ │ └── view.jsx │ ├── selectThumbnail │ │ ├── index.js │ │ ├── thumbnail-broken.png │ │ ├── thumbnail-missing.png │ │ └── view.jsx │ ├── settingAccount │ │ ├── index.js │ │ └── view.jsx │ ├── settingAccountPassword │ │ ├── index.js │ │ └── view.jsx │ ├── settingAppearance │ │ ├── index.js │ │ └── view.jsx │ ├── settingAutoLaunch │ │ ├── index.js │ │ └── view.jsx │ ├── settingClosingBehavior │ │ ├── index.js │ │ └── view.jsx │ ├── settingCommentsServer │ │ ├── index.js │ │ ├── internal │ │ │ └── input-radio-panel-addCommentServer.jsx │ │ └── view.jsx │ ├── settingContent │ │ ├── index.js │ │ └── view.jsx │ ├── settingDataHosting │ │ ├── index.js │ │ └── view.jsx │ ├── settingDisableAutoUpdates │ │ ├── index.js │ │ └── view.jsx │ ├── settingEnablePrereleases │ │ ├── index.js │ │ └── view.jsx │ ├── settingLanguage │ │ ├── index.js │ │ └── view.jsx │ ├── settingSaveBlobs │ │ ├── index.js │ │ └── view.jsx │ ├── settingShareUrl │ │ ├── index.js │ │ └── view.jsx │ ├── settingStorage │ │ ├── index.js │ │ └── view.jsx │ ├── settingSystem │ │ ├── index.js │ │ └── view.jsx │ ├── settingUnauthenticated │ │ ├── index.js │ │ └── view.jsx │ ├── settingViewHosting │ │ ├── index.js │ │ └── view.jsx │ ├── settingWalletServer │ │ ├── index.js │ │ ├── internal │ │ │ └── inputRow.jsx │ │ └── view.jsx │ ├── settingsRow │ │ ├── index.js │ │ └── view.jsx │ ├── settingsSideNavigation │ │ ├── index.js │ │ └── view.jsx │ ├── shareButton │ │ ├── index.js │ │ └── view.jsx │ ├── sideNavigation │ │ ├── index.js │ │ └── view.jsx │ ├── skipNavigationButton │ │ └── index.jsx │ ├── snackBar │ │ ├── index.js │ │ └── view.jsx │ ├── socialShare │ │ ├── index.js │ │ └── view.jsx │ ├── spinner │ │ ├── index.js │ │ └── view.jsx │ ├── splash │ │ ├── index.js │ │ └── view.jsx │ ├── subscribeButton │ │ ├── index.js │ │ └── view.jsx │ ├── supportsLiquidate │ │ ├── index.js │ │ └── view.jsx │ ├── syncEnableFlow │ │ ├── index.js │ │ └── view.jsx │ ├── syncFatalError │ │ ├── index.js │ │ └── view.jsx │ ├── syncPassword │ │ ├── index.js │ │ └── view.jsx │ ├── syncToggle │ │ ├── index.js │ │ └── view.jsx │ ├── tag │ │ ├── index.js │ │ └── view.jsx │ ├── tagsSearch │ │ ├── index.js │ │ └── view.jsx │ ├── tagsSelect │ │ ├── index.js │ │ └── view.jsx │ ├── textareaSuggestionsItem │ │ ├── index.js │ │ └── view.jsx │ ├── textareaWithSuggestions │ │ ├── index.js │ │ └── view.jsx │ ├── theme │ │ ├── index.js │ │ └── view.jsx │ ├── themeSelector │ │ ├── index.js │ │ └── view.jsx │ ├── transactionListTable │ │ ├── index.js │ │ └── view.jsx │ ├── transactionListTableItem │ │ ├── index.js │ │ └── view.jsx │ ├── txoList │ │ ├── index.js │ │ └── view.jsx │ ├── uriIndicator │ │ ├── index.js │ │ └── view.jsx │ ├── userChannelFollowIntro │ │ ├── index.js │ │ └── view.jsx │ ├── userEmail │ │ ├── index.js │ │ └── view.jsx │ ├── userEmailNew │ │ ├── index.js │ │ └── view.jsx │ ├── userEmailReturning │ │ ├── index.js │ │ └── view.jsx │ ├── userEmailVerify │ │ ├── index.js │ │ └── view.jsx │ ├── userFirstChannel │ │ ├── index.js │ │ └── view.jsx │ ├── userPasswordReset │ │ ├── index.js │ │ └── view.jsx │ ├── userPasswordSet │ │ ├── index.js │ │ └── view.jsx │ ├── userSignIn │ │ ├── index.js │ │ └── view.jsx │ ├── userSignInPassword │ │ ├── index.js │ │ └── view.jsx │ ├── userSignOutButton │ │ ├── index.js │ │ └── view.jsx │ ├── userSignUp │ │ ├── index.js │ │ └── view.jsx │ ├── userTagFollowIntro │ │ ├── index.js │ │ └── view.jsx │ ├── videoDuration │ │ ├── index.js │ │ └── view.jsx │ ├── viewers │ │ ├── appViewer │ │ │ ├── index.js │ │ │ └── view.jsx │ │ ├── codeViewer.jsx │ │ ├── comicBookViewer.jsx │ │ ├── documentViewer.jsx │ │ ├── docxViewer.jsx │ │ ├── htmlViewer.jsx │ │ ├── imageViewer.jsx │ │ ├── pdfViewer.jsx │ │ ├── threeViewer │ │ │ ├── index.jsx │ │ │ └── internal │ │ │ │ ├── detector.js │ │ │ │ ├── grid.js │ │ │ │ ├── renderer.js │ │ │ │ └── scene.js │ │ └── videoViewer │ │ │ ├── index.js │ │ │ ├── internal │ │ │ ├── autoplay-next.js │ │ │ ├── lbry-volume-bar.js │ │ │ ├── overlays.js │ │ │ ├── play-next.js │ │ │ ├── play-previous.js │ │ │ ├── plugins │ │ │ │ ├── videojs-hls-quality-selector │ │ │ │ │ ├── ConcreteButton.js │ │ │ │ │ ├── ConcreteMenuItem.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── plugin.js │ │ │ │ │ └── plugin.scss │ │ │ │ ├── videojs-mobile-ui │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── plugin.js │ │ │ │ │ ├── plugin.scss │ │ │ │ │ └── touchOverlay.js │ │ │ │ ├── videojs-overlay │ │ │ │ │ ├── plugin.js │ │ │ │ │ └── plugin.scss │ │ │ │ └── videojs-recsys │ │ │ │ │ └── plugin.js │ │ │ ├── theater-mode.js │ │ │ ├── videojs-events.jsx │ │ │ ├── videojs-functions.jsx │ │ │ ├── videojs-keyboard-shortcuts.jsx │ │ │ └── videojs.jsx │ │ │ └── view.jsx │ ├── walletAddress │ │ ├── index.js │ │ └── view.jsx │ ├── walletBackup │ │ ├── index.js │ │ └── view.jsx │ ├── walletBalance │ │ ├── index.js │ │ └── view.jsx │ ├── walletSend │ │ ├── index.js │ │ └── view.jsx │ ├── walletSendTip │ │ ├── index.js │ │ └── view.jsx │ ├── walletSpendableBalanceHelp │ │ ├── index.js │ │ └── view.jsx │ ├── walletTipAmountSelector │ │ ├── index.js │ │ └── view.jsx │ ├── wallpaper │ │ ├── index.js │ │ └── view.jsx │ ├── welcomeSplash │ │ ├── index.js │ │ └── view.jsx │ ├── wunderbar │ │ ├── index.js │ │ └── view.jsx │ ├── wunderbarSuggestion │ │ ├── index.js │ │ └── view.jsx │ ├── wunderbarSuggestions │ │ ├── index.js │ │ └── view.jsx │ ├── wunderbarTopSuggestion │ │ ├── index.js │ │ └── view.jsx │ ├── youtubeBadge │ │ ├── index.js │ │ └── view.jsx │ ├── youtubeTransferStatus │ │ ├── index.js │ │ └── view.jsx │ ├── yrbl │ │ └── index.jsx │ ├── yrblWalletEmpty │ │ ├── index.js │ │ └── view.jsx │ └── zoomableImage │ │ ├── index.js │ │ └── view.jsx ├── constants │ ├── abandon_states.js │ ├── action_types.js │ ├── claim.js │ ├── claim_search.js │ ├── classnames.js │ ├── collections.js │ ├── comment.js │ ├── daemon_settings.js │ ├── email.js │ ├── emotes.js │ ├── errors.js │ ├── file_render_modes.js │ ├── form-field.js │ ├── icons.js │ ├── keycodes.js │ ├── language-migrations.js │ ├── languages.js │ ├── licenses.js │ ├── modal_types.js │ ├── moonpay.js │ ├── navigation.js │ ├── notifications.js │ ├── pageTitles.js │ ├── pages.js │ ├── protocol_regex.js │ ├── publish_types.js │ ├── reactions.js │ ├── report_content.js │ ├── search.js │ ├── searchable_languages.js │ ├── settings.js │ ├── shape_shift.js │ ├── shared_preferences.js │ ├── sort_options.js │ ├── speech_urls.js │ ├── stickers.js │ ├── stripe.js │ ├── subscriptions.js │ ├── supported_browser_languages.js │ ├── supported_languages.js │ ├── supported_sub_languages.js │ ├── tags.js │ ├── themes.js │ ├── thumbnail_upload_statuses.js │ ├── token.js │ ├── transaction_list.js │ ├── transaction_types.js │ ├── txo_list.js │ ├── user.js │ └── youtube.js ├── effects │ ├── use-active-element.js │ ├── use-combined-refs.js │ ├── use-debounce.js │ ├── use-drag-drop.js │ ├── use-fetch-view-count.js │ ├── use-fetched.js │ ├── use-get-thumbnail.js │ ├── use-history-nav.js │ ├── use-hover.js │ ├── use-is-mounted.js │ ├── use-lazy-loading.js │ ├── use-lighthouse.js │ ├── use-persisted-state.js │ ├── use-previous.js │ ├── use-screensize.js │ ├── use-stream-file.js │ ├── use-stream.js │ ├── use-throttle.js │ ├── use-tween.js │ └── use-zoom.js ├── i18n.js ├── index.jsx ├── lbry.js ├── logWarningConsoleMessage.js ├── modal │ ├── modal.jsx │ ├── modalAffirmPurchase │ │ ├── index.js │ │ └── view.jsx │ ├── modalAutoGenerateThumbnail │ │ ├── index.js │ │ └── view.jsx │ ├── modalAutoUpdateDownloaded │ │ ├── index.js │ │ └── view.jsx │ ├── modalBlockChannel │ │ ├── index.js │ │ └── view.jsx │ ├── modalClaimCollectionAdd │ │ ├── index.js │ │ └── view.jsx │ ├── modalCommentAcknowledgement │ │ ├── index.js │ │ └── view.jsx │ ├── modalConfirmThumbnailUpload │ │ ├── index.js │ │ └── view.jsx │ ├── modalConfirmTransaction │ │ ├── index.js │ │ └── view.jsx │ ├── modalDownloading │ │ ├── index.js │ │ └── view.jsx │ ├── modalError │ │ ├── index.js │ │ └── view.jsx │ ├── modalFileSelection │ │ ├── index.js │ │ └── view.jsx │ ├── modalFileTimeout │ │ ├── index.js │ │ └── view.jsx │ ├── modalFirstReward │ │ ├── index.js │ │ └── view.jsx │ ├── modalFirstSubscription │ │ ├── index.js │ │ └── view.jsx │ ├── modalImageUpload │ │ ├── index.js │ │ └── view.jsx │ ├── modalIncompatibleDaemon │ │ ├── index.js │ │ └── view.jsx │ ├── modalMassTipUnlock │ │ ├── index.js │ │ └── view.jsx │ ├── modalMobileSearch │ │ ├── index.js │ │ └── view.jsx │ ├── modalOpenExternalResource │ │ ├── index.js │ │ └── view.jsx │ ├── modalPasswordUnsave │ │ ├── index.js │ │ └── view.jsx │ ├── modalPublish │ │ ├── index.js │ │ └── view.jsx │ ├── modalPublishPreview │ │ ├── index.js │ │ └── view.jsx │ ├── modalRemoveCard │ │ ├── index.js │ │ └── view.jsx │ ├── modalRemoveCollection │ │ ├── index.js │ │ └── view.jsx │ ├── modalRemoveComment │ │ ├── index.js │ │ └── view.jsx │ ├── modalRemoveFile │ │ ├── index.js │ │ └── view.jsx │ ├── modalRepost │ │ ├── index.js │ │ └── view.jsx │ ├── modalRevokeClaim │ │ ├── index.js │ │ └── view.jsx │ ├── modalRewardCode │ │ ├── index.js │ │ └── view.jsx │ ├── modalRouter │ │ ├── index.js │ │ └── view.jsx │ ├── modalSendTip │ │ ├── index.js │ │ └── view.jsx │ ├── modalSignOut │ │ ├── index.js │ │ └── view.jsx │ ├── modalSocialShare │ │ ├── index.js │ │ └── view.jsx │ ├── modalSupportsLiquidate │ │ ├── index.js │ │ └── view.jsx │ ├── modalSyncEnable │ │ ├── index.js │ │ └── view.jsx │ ├── modalTransactionFailed │ │ ├── index.js │ │ └── view.jsx │ ├── modalUpgrade │ │ ├── index.js │ │ └── view.jsx │ ├── modalViewImage │ │ ├── index.js │ │ └── view.jsx │ ├── modalWalletDecrypt │ │ ├── index.js │ │ └── view.jsx │ ├── modalWalletEncrypt │ │ ├── index.js │ │ └── view.jsx │ └── modalWalletUnlock │ │ ├── index.js │ │ └── view.jsx ├── native.js ├── page │ ├── backup │ │ ├── index.js │ │ └── view.jsx │ ├── buy │ │ ├── index.js │ │ └── view.jsx │ ├── channel │ │ ├── index.js │ │ └── view.jsx │ ├── channelNew │ │ ├── index.js │ │ └── view.jsx │ ├── channels │ │ ├── index.js │ │ └── view.jsx │ ├── channelsFollowing │ │ ├── index.js │ │ └── view.jsx │ ├── channelsFollowingDiscover │ │ ├── index.js │ │ └── view.jsx │ ├── collection │ │ ├── index.js │ │ └── view.jsx │ ├── creatorDashboard │ │ ├── index.js │ │ └── view.jsx │ ├── discover │ │ ├── index.js │ │ └── view.jsx │ ├── file │ │ ├── index.js │ │ └── view.jsx │ ├── fileListDownloaded │ │ ├── index.js │ │ └── view.jsx │ ├── fileListPublished │ │ ├── index.js │ │ └── view.jsx │ ├── help │ │ ├── index.js │ │ └── view.jsx │ ├── home │ │ ├── index.js │ │ └── view.jsx │ ├── library │ │ ├── index.js │ │ └── view.jsx │ ├── listBlocked │ │ ├── index.js │ │ └── view.jsx │ ├── lists │ │ ├── index.js │ │ └── view.jsx │ ├── navigationHistory │ │ ├── index.js │ │ └── view.jsx │ ├── notifications │ │ ├── index.js │ │ └── view.jsx │ ├── ownComments │ │ ├── index.js │ │ └── view.jsx │ ├── passwordReset │ │ ├── index.js │ │ └── view.jsx │ ├── passwordSet │ │ ├── index.js │ │ └── view.jsx │ ├── passwordUpdate │ │ ├── index.js │ │ └── view.jsx │ ├── playlists │ │ ├── index.js │ │ └── view.jsx │ ├── publish │ │ ├── index.js │ │ └── view.jsx │ ├── receive │ │ ├── index.js │ │ └── view.jsx │ ├── report │ │ ├── index.js │ │ └── view.jsx │ ├── reportContent │ │ ├── index.js │ │ └── view.jsx │ ├── repost │ │ ├── index.js │ │ └── view.jsx │ ├── search │ │ ├── index.js │ │ └── view.jsx │ ├── send │ │ ├── index.js │ │ └── view.jsx │ ├── settings │ │ ├── index.js │ │ └── view.jsx │ ├── settingsCreator │ │ ├── index.js │ │ └── view.jsx │ ├── settingsNotifications │ │ ├── index.js │ │ └── view.jsx │ ├── show │ │ ├── index.js │ │ └── view.jsx │ ├── signIn │ │ ├── index.js │ │ └── view.jsx │ ├── signInVerify │ │ ├── index.js │ │ └── view.jsx │ ├── signInWalletPassword │ │ ├── index.js │ │ └── view.jsx │ ├── signUp │ │ ├── index.js │ │ └── view.jsx │ ├── tagsFollowing │ │ ├── index.js │ │ └── view.jsx │ ├── tagsFollowingManage │ │ ├── index.js │ │ └── view.jsx │ ├── top │ │ ├── index.js │ │ └── view.jsx │ ├── wallet │ │ ├── index.js │ │ └── view.jsx │ └── welcome │ │ ├── index.js │ │ └── view.jsx ├── reducers.js ├── redux │ ├── actions │ │ ├── app.js │ │ ├── blocked.js │ │ ├── claims.js │ │ ├── collections.js │ │ ├── comments.js │ │ ├── content.js │ │ ├── file.js │ │ ├── file_info.js │ │ ├── notifications.js │ │ ├── publish.js │ │ ├── reactions.js │ │ ├── reportContent.js │ │ ├── rewards.js │ │ ├── search.js │ │ ├── settings.js │ │ ├── subscriptions.js │ │ ├── sync.js │ │ ├── tags.js │ │ ├── user.js │ │ ├── wallet.js │ │ └── websocket.js │ ├── middleware │ │ └── shared-state.js │ ├── reducers │ │ ├── app.js │ │ ├── blocked.js │ │ ├── claims.js │ │ ├── collections.js │ │ ├── comments.js │ │ ├── content.js │ │ ├── file_info.js │ │ ├── notifications.js │ │ ├── publish.js │ │ ├── reactions.js │ │ ├── reportContent.js │ │ ├── rewards.js │ │ ├── search.js │ │ ├── settings.js │ │ ├── subscriptions.js │ │ ├── sync.js │ │ ├── tags.js │ │ ├── user.js │ │ └── wallet.js │ └── selectors │ │ ├── app.js │ │ ├── blocked.js │ │ ├── claims.js │ │ ├── collections.js │ │ ├── comments.js │ │ ├── content.js │ │ ├── file_info.js │ │ ├── notifications.js │ │ ├── publish.js │ │ ├── reactions.js │ │ ├── reportContent.js │ │ ├── rewards.js │ │ ├── search.js │ │ ├── settings.js │ │ ├── subscriptions.js │ │ ├── sync.js │ │ ├── tags.js │ │ ├── user.js │ │ └── wallet.js ├── rewards.js ├── scss │ ├── all.scss │ ├── component │ │ ├── _ads.scss │ │ ├── _animation.scss │ │ ├── _badge.scss │ │ ├── _block-list.scss │ │ ├── _button.scss │ │ ├── _calendar.scss │ │ ├── _card.scss │ │ ├── _channel-mention.scss │ │ ├── _channel.scss │ │ ├── _claim-list.scss │ │ ├── _claim-search.scss │ │ ├── _collection.scss │ │ ├── _color-picker.scss │ │ ├── _comment-badge.scss │ │ ├── _comment-create.scss │ │ ├── _comment-selectors.scss │ │ ├── _comments.scss │ │ ├── _content.scss │ │ ├── _dat-gui.scss │ │ ├── _embed-player.scss │ │ ├── _emote-selector.scss │ │ ├── _empty.scss │ │ ├── _expandable.scss │ │ ├── _file-drop.scss │ │ ├── _file-list.scss │ │ ├── _file-price.scss │ │ ├── _file-properties.scss │ │ ├── _file-render.scss │ │ ├── _file-thumbnail.scss │ │ ├── _first-run.scss │ │ ├── _footer.scss │ │ ├── _form-field.scss │ │ ├── _form-row.scss │ │ ├── _header.scss │ │ ├── _icon.scss │ │ ├── _item-list.scss │ │ ├── _main.scss │ │ ├── _markdown-editor.scss │ │ ├── _markdown-preview.scss │ │ ├── _media.scss │ │ ├── _meme.scss │ │ ├── _modal.scss │ │ ├── _navigation.scss │ │ ├── _notification.scss │ │ ├── _nudge.scss │ │ ├── _pagination.scss │ │ ├── _placeholder.scss │ │ ├── _post.scss │ │ ├── _progress.scss │ │ ├── _purchase.scss │ │ ├── _search.scss │ │ ├── _settings.scss │ │ ├── _share.scss │ │ ├── _snack-bar.scss │ │ ├── _spinner.scss │ │ ├── _splash.scss │ │ ├── _status-bar.scss │ │ ├── _sticker-selector.scss │ │ ├── _stripe-card.scss │ │ ├── _superchat.scss │ │ ├── _swipe-list.scss │ │ ├── _swipeable-drawer.scss │ │ ├── _syntax-highlighter.scss │ │ ├── _table.scss │ │ ├── _tags.scss │ │ ├── _textarea-suggestions.scss │ │ ├── _tooltip.scss │ │ ├── _txo-list.scss │ │ ├── _utils.scss │ │ ├── _videojs.scss │ │ ├── _view_count.scss │ │ ├── _wallet-tip-selector.scss │ │ ├── _wallet-tip-send.scss │ │ ├── _wunderbar.scss │ │ ├── _yrbl.scss │ │ ├── expanding-details.scss │ │ ├── menu-button.scss │ │ ├── nag.scss │ │ ├── section.scss │ │ └── tabs.scss │ ├── init │ │ ├── _base-theme.scss │ │ ├── _breakpoints.scss │ │ ├── _color.scss │ │ ├── _gui.scss │ │ ├── _mixins.scss │ │ ├── _reset.scss │ │ └── _vars.scss │ ├── themes │ │ ├── dark.scss │ │ └── light.scss │ └── third-party.scss ├── store.js └── util │ ├── autoLaunch.js │ ├── batch-actions.js │ ├── buildHomepage.js │ ├── claim.js │ ├── comments.js │ ├── context-menu.js │ ├── country.js │ ├── debounce.js │ ├── deep-equal.js │ ├── default-languages.js │ ├── detect-typing.js │ ├── detect-user-bandwidth.js │ ├── diskspace.js │ ├── downloadClaim.js │ ├── enhanced-layout.js │ ├── fetch.js │ ├── form-validation.js │ ├── format-bytes.js │ ├── format-credits.js │ ├── formatAriaLabel.js │ ├── formatMediaDuration.js │ ├── full-screen.js │ ├── generate-thumbnail-name.js │ ├── handle-fetch.js │ ├── hex.js │ ├── hosting.js │ ├── intlNumberFormat.js │ ├── lazyImport.js │ ├── lbryURI.js │ ├── merge-claim.js │ ├── number.js │ ├── object.js │ ├── parse-data.js │ ├── publish.js │ ├── query-params.js │ ├── redux-utils.js │ ├── remark-emote.js │ ├── remark-lbry.js │ ├── remark-timestamp.js │ ├── saved-passwords.js │ ├── search.js │ ├── set-operations.js │ ├── shuffle-array.js │ ├── string.js │ ├── stripe.js │ ├── swap-json.js │ ├── sync-settings.js │ ├── throttle.js │ ├── thumbnail.js │ ├── time.js │ ├── transifex-upload.js │ ├── url.js │ ├── web-file-system.js │ ├── web.js │ └── zoomWindow.js ├── webpack.base.config.js ├── webpack.electron.config.js └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | ./node_modules/** 3 | **/node_modules/** 4 | web/dist/** 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680Feature request" 3 | about: "I have a suggestion (and might want to implement it \U0001F60A)" 4 | title: '' 5 | labels: 'type: new feature' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--say-thank-you.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❤️Say thank you" 3 | about: If you enjoy using the LBRY app, let us know! 4 | title: LBRY rocks! 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | If you are using the LBRY app - please let us know. We'd love to hear from you! 11 | 12 | If you would like to help Nock - any of the following is greatly appreciated. 13 | 14 | - Give the repository a star ⭐️ 15 | - Help out with issues 16 | - Blog about LBRY 17 | - Make tutorials 18 | - Give talks 19 | - Convince other people to use LBRY 20 | - Anything your heart desires 21 | 22 | Thank you! 💐 23 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "linters": { 3 | "ui/**/*.{js,jsx,scss,json}": ["prettier --write", "git add"], 4 | "ui/**/*.{js,jsx}": ["eslint", "flow focus-check --color always", "git add"] 5 | }, 6 | "ignore": ["node_modules", "dist/**/*", "package-lock.json"] 7 | } 8 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "printWidth": 120, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /.sentryclirc: -------------------------------------------------------------------------------- 1 | [defaults] 2 | url = https://sentry.lbry.tech/ 3 | org = lbry 4 | project = lbry-desktop-web -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [lbry-desktop.app-strings] 5 | source_file = static/app-strings.json 6 | source_lang = en 7 | type = KEYVALUEJSON 8 | -------------------------------------------------------------------------------- /.yarn/versions/17d7e90d.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/17d7e90d.yml -------------------------------------------------------------------------------- /.yarn/versions/33178102.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/33178102.yml -------------------------------------------------------------------------------- /.yarn/versions/35f2125e.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/35f2125e.yml -------------------------------------------------------------------------------- /.yarn/versions/4f9fb046.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/4f9fb046.yml -------------------------------------------------------------------------------- /.yarn/versions/5bc94294.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/5bc94294.yml -------------------------------------------------------------------------------- /.yarn/versions/5f1212ad.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/5f1212ad.yml -------------------------------------------------------------------------------- /.yarn/versions/5f4cac99.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/5f4cac99.yml -------------------------------------------------------------------------------- /.yarn/versions/6b35c994.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/6b35c994.yml -------------------------------------------------------------------------------- /.yarn/versions/6be5ab70.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/6be5ab70.yml -------------------------------------------------------------------------------- /.yarn/versions/86ac1afd.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/86ac1afd.yml -------------------------------------------------------------------------------- /.yarn/versions/8e384637.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/8e384637.yml -------------------------------------------------------------------------------- /.yarn/versions/909c3734.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/909c3734.yml -------------------------------------------------------------------------------- /.yarn/versions/951a8d12.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/951a8d12.yml -------------------------------------------------------------------------------- /.yarn/versions/97e7141a.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/97e7141a.yml -------------------------------------------------------------------------------- /.yarn/versions/ac69bc5f.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/ac69bc5f.yml -------------------------------------------------------------------------------- /.yarn/versions/c6e2b914.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/c6e2b914.yml -------------------------------------------------------------------------------- /.yarn/versions/d1a18cef.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/d1a18cef.yml -------------------------------------------------------------------------------- /.yarn/versions/ec3a9ddf.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/ec3a9ddf.yml -------------------------------------------------------------------------------- /.yarn/versions/fc1fde84.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/fc1fde84.yml -------------------------------------------------------------------------------- /.yarn/versions/fc597c00.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/.yarn/versions/fc597c00.yml -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-version.cjs 5 | spec: "@yarnpkg/plugin-version" 6 | 7 | yarnPath: .yarn/releases/yarn-3.2.0.cjs 8 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = api => { 2 | api.cache(false); 3 | 4 | return { 5 | presets: [['@babel/env', { loose: true, modules: false }], '@babel/react', '@babel/flow'], 6 | plugins: [ 7 | 'import-glob', 8 | '@babel/plugin-transform-runtime', 9 | ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }], 10 | ['@babel/plugin-proposal-private-methods', { 'loose': false }], 11 | ['@babel/plugin-proposal-private-property-in-object', { 'loose': false }], 12 | '@babel/plugin-transform-flow-strip-types', 13 | '@babel/plugin-proposal-class-properties', 14 | 'react-hot-loader/babel', 15 | ], 16 | ignore: [/node_modules/], 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /build/afterAllArtifactBuild.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | module.exports = async function(params) { 4 | const { artifactPaths } = params; 5 | 6 | for (var i = 0; i < artifactPaths.length; i++) { 7 | const artifactPath = artifactPaths[i]; 8 | if (artifactPath.includes('.blockmap') || artifactPath.includes('.zip')) { 9 | fs.unlinkSync(artifactPath); 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /build/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/background.png -------------------------------------------------------------------------------- /build/cert-2021-2022.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/cert-2021-2022.pfx -------------------------------------------------------------------------------- /build/cert2023.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/cert2023.pfx -------------------------------------------------------------------------------- /build/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | com.apple.security.cs.disable-library-validation 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /build/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icon.icns -------------------------------------------------------------------------------- /build/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icon.ico -------------------------------------------------------------------------------- /build/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/128x128.png -------------------------------------------------------------------------------- /build/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/256x256.png -------------------------------------------------------------------------------- /build/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/32x32.png -------------------------------------------------------------------------------- /build/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/48x48.png -------------------------------------------------------------------------------- /build/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/96x96.png -------------------------------------------------------------------------------- /build/icons/lbry128.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry128.ico -------------------------------------------------------------------------------- /build/icons/lbry16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry16.ico -------------------------------------------------------------------------------- /build/icons/lbry256.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry256.ico -------------------------------------------------------------------------------- /build/icons/lbry32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry32.ico -------------------------------------------------------------------------------- /build/icons/lbry48.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry48.ico -------------------------------------------------------------------------------- /build/icons/lbry96.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/build/icons/lbry96.ico -------------------------------------------------------------------------------- /custom/homepages/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/custom/homepages/.gitkeep -------------------------------------------------------------------------------- /custom/robots.allowall: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /custom/robots.disallowall: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /electron/installDevtools.js: -------------------------------------------------------------------------------- 1 | export default async function installDevtools() { 2 | const { default: installExtension, REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } = require('electron-devtools-installer'); 3 | 4 | await installExtension(REACT_DEVELOPER_TOOLS) 5 | .then(name => console.log(`Added Extension: ${name}`)) 6 | .catch(err => console.log('An error occurred: ', err)); 7 | 8 | await installExtension(REDUX_DEVTOOLS) 9 | .then(name => console.log(`Added Extension: ${name}`)) 10 | .catch(err => console.log('An error occurred: ', err)); 11 | } 12 | -------------------------------------------------------------------------------- /electron/sandboxTest.js: -------------------------------------------------------------------------------- 1 | require('@babel/register'); 2 | require('@babel/polyfill'); 3 | 4 | require('./startSandbox.js')(); 5 | -------------------------------------------------------------------------------- /extras/lbryinc/constants/claim.js: -------------------------------------------------------------------------------- 1 | export const MINIMUM_PUBLISH_BID = 0.00000001; 2 | 3 | export const CHANNEL_ANONYMOUS = 'anonymous'; 4 | export const CHANNEL_NEW = 'new'; 5 | export const PAGE_SIZE = 20; 6 | -------------------------------------------------------------------------------- /extras/lbryinc/constants/errors.js: -------------------------------------------------------------------------------- 1 | export const ALREADY_CLAIMED = 2 | 'once the invite reward has been claimed the referrer cannot be changed'; 3 | export const REFERRER_NOT_FOUND = 4 | 'A lbry.tv account could not be found for the referrer you provided.'; 5 | -------------------------------------------------------------------------------- /extras/lbryinc/constants/youtube.js: -------------------------------------------------------------------------------- 1 | export const YOUTUBE_SYNC_NOT_TRANSFERRED = 'not_transferred'; 2 | export const YOUTUBE_SYNC_PENDING = 'pending'; 3 | export const YOUTUBE_SYNC_PENDING_EMAIL = 'pendingemail'; 4 | export const YOUTUBE_SYNC_PENDING_TRANSFER = 'pending_transfer'; 5 | export const YOUTUBE_SYNC_COMPLETED_TRANSFER = 'completed_transfer'; 6 | export const YOUTUBE_SYNC_QUEUED = 'queued'; 7 | export const YOUTUBE_SYNC_SYNCING = 'syncing'; 8 | export const YOUTUBE_SYNC_SYNCED = 'synced'; 9 | export const YOUTUBE_SYNC_FAILED = 'failed'; 10 | export const YOUTUBE_SYNC_PENDINGUPGRADE = 'pendingupgrade'; 11 | export const YOUTUBE_SYNC_ABANDONDED = 'abandoned'; 12 | -------------------------------------------------------------------------------- /extras/lbryinc/redux/selectors/auth.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | 3 | const selectState = state => state.auth || {}; 4 | 5 | export const selectAuthToken = createSelector(selectState, state => state.authToken); 6 | 7 | export const selectIsAuthenticating = createSelector(selectState, state => state.authenticating); 8 | -------------------------------------------------------------------------------- /extras/lbryinc/redux/selectors/blacklist.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | 3 | export const selectState = state => state.blacklist || {}; 4 | 5 | export const selectBlackListedOutpoints = createSelector( 6 | selectState, 7 | state => state.blackListedOutpoints 8 | ); 9 | 10 | export const selectBlacklistedOutpointMap = createSelector( 11 | selectBlackListedOutpoints, 12 | outpoints => 13 | outpoints 14 | ? outpoints.reduce((acc, val) => { 15 | const outpoint = `${val.txid}:${val.nout}`; 16 | acc[outpoint] = 1; 17 | return acc; 18 | }, {}) 19 | : {} 20 | ); 21 | -------------------------------------------------------------------------------- /extras/lbryinc/redux/selectors/cost_info.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | type State = { costInfo: any }; 3 | 4 | export const selectState = (state: State) => state.costInfo || {}; 5 | export const selectAllCostInfoByUri = (state: State) => selectState(state).byUri; 6 | export const selectFetchingCostInfo = (state: State) => selectState(state).fetching; 7 | 8 | export const selectCostInfoForUri = (state: State, uri: string) => { 9 | const costInfos = selectAllCostInfoByUri(state); 10 | return costInfos && costInfos[uri]; 11 | }; 12 | 13 | export const selectFetchingCostInfoForUri = (state: State, uri: string) => { 14 | const fetchingByUri = selectFetchingCostInfo(state); 15 | return fetchingByUri && fetchingByUri[uri]; 16 | }; 17 | -------------------------------------------------------------------------------- /extras/lbryinc/redux/selectors/filtered.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | 3 | export const selectState = state => state.filtered || {}; 4 | 5 | export const selectFilteredOutpoints = createSelector( 6 | selectState, 7 | state => state.filteredOutpoints 8 | ); 9 | 10 | export const selectFilteredOutpointMap = createSelector( 11 | selectFilteredOutpoints, 12 | outpoints => 13 | outpoints 14 | ? outpoints.reduce((acc, val) => { 15 | const outpoint = `${val.txid}:${val.nout}`; 16 | acc[outpoint] = 1; 17 | return acc; 18 | }, {}) 19 | : {} 20 | ); 21 | -------------------------------------------------------------------------------- /extras/lbryinc/util/redux-utils-delete-me.js: -------------------------------------------------------------------------------- 1 | // util for creating reducers 2 | // based off of redux-actions 3 | // https://redux-actions.js.org/docs/api/handleAction.html#handleactions 4 | 5 | // eslint-disable-next-line import/prefer-default-export 6 | export const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { 7 | const handler = actionMap[action.type]; 8 | 9 | if (handler) { 10 | const newState = handler(state, action); 11 | return Object.assign({}, state, newState); 12 | } 13 | 14 | // just return the original state if no handler 15 | // returning a copy here breaks redux-persist 16 | return state; 17 | }; 18 | -------------------------------------------------------------------------------- /extras/lbryinc/util/swap-json.js: -------------------------------------------------------------------------------- 1 | export function swapKeyAndValue(dict) { 2 | const ret = {}; 3 | // eslint-disable-next-line no-restricted-syntax 4 | for (const key in dict) { 5 | if (dict.hasOwnProperty(key)) { 6 | ret[dict[key]] = key; 7 | } 8 | } 9 | return ret; 10 | } 11 | -------------------------------------------------------------------------------- /extras/recsys/index.js: -------------------------------------------------------------------------------- 1 | import Recsys from './recsys'; 2 | 3 | export default Recsys; 4 | -------------------------------------------------------------------------------- /flow-typed/18nj.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | declare function __(a: string, b?: {}): string; 3 | -------------------------------------------------------------------------------- /flow-typed/Blocklist.js: -------------------------------------------------------------------------------- 1 | declare type BlocklistState = { 2 | blockedChannels: Array 3 | }; 4 | 5 | declare type BlocklistAction = { 6 | type: string, 7 | data: { 8 | uri: string, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /flow-typed/CoinSwap.js: -------------------------------------------------------------------------------- 1 | declare type CoinSwapInfo = { 2 | chargeCode: string, 3 | coins: Array, 4 | sendAddresses: { [string]: string}, 5 | sendAmounts: { [string]: any }, 6 | lbcAmount: number, 7 | status?: { 8 | status: string, 9 | receiptCurrency: string, 10 | receiptTxid: string, 11 | lbcTxid: string, 12 | }, 13 | } 14 | 15 | declare type CoinSwapState = { 16 | coinSwaps: Array, 17 | }; 18 | 19 | declare type CoinSwapAddAction = { 20 | type: string, 21 | data: CoinSwapInfo, 22 | }; 23 | 24 | declare type CoinSwapRemoveAction = { 25 | type: string, 26 | data: { 27 | chargeCode: string, 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /flow-typed/Redux.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | /* eslint-disable no-use-before-define */ 3 | declare type GetState = () => any; 4 | declare type ThunkAction = (dispatch: Dispatch, getState: GetState) => any; 5 | declare type Dispatch = (action: {} | Promise<*> | Array<{}> | ThunkAction) => any; // Need to refer to ThunkAction 6 | /* eslint-enable */ 7 | -------------------------------------------------------------------------------- /flow-typed/Reflector.js: -------------------------------------------------------------------------------- 1 | declare type ReflectingUpdate = { 2 | fileListItem: FileListItem, 3 | progress: number | boolean, 4 | stalled: boolean, 5 | }; 6 | -------------------------------------------------------------------------------- /flow-typed/Settings.js: -------------------------------------------------------------------------------- 1 | declare type CommentServerDetails = { 2 | name: string, 3 | url: string, 4 | } 5 | 6 | declare type WalletServerDetails = { 7 | 8 | }; 9 | 10 | declare type DiskSpace = { 11 | total: number, 12 | free: number, 13 | }; 14 | -------------------------------------------------------------------------------- /flow-typed/Tags.js: -------------------------------------------------------------------------------- 1 | declare type TagState = { 2 | followedTags: FollowedTags, 3 | knownTags: KnownTags, 4 | }; 5 | 6 | declare type Tag = { 7 | name: string, 8 | }; 9 | 10 | declare type KnownTags = { 11 | [string]: Tag, 12 | }; 13 | 14 | declare type FollowedTags = Array; 15 | 16 | declare type TagAction = { 17 | type: string, 18 | data: { 19 | name: string, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /flow-typed/Transaction.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | declare type Transaction = { 3 | amount: number, 4 | claim_id: string, 5 | claim_name: string, 6 | fee: number, 7 | nout: number, 8 | txid: string, 9 | type: string, 10 | date: Date, 11 | }; 12 | 13 | declare type Support = { 14 | address: string, 15 | amount: string, 16 | claim_id: string, 17 | confirmations: number, 18 | height: string, 19 | is_change: string, 20 | is_mine: string, 21 | name: string, 22 | normalized_name: string, 23 | nout: string, 24 | permanent_url: string, 25 | timestamp: number, 26 | txid: string, 27 | type: string, 28 | }; 29 | -------------------------------------------------------------------------------- /flow-typed/Txo.js: -------------------------------------------------------------------------------- 1 | declare type Txo = { 2 | amount: number, 3 | claim_id: string, 4 | normalized_name: string, 5 | nout: number, 6 | txid: string, 7 | type: string, 8 | value_type: string, 9 | timestamp: number, 10 | is_my_output: boolean, 11 | is_my_input: boolean, 12 | is_spent: boolean, 13 | signing_channel?: { 14 | channel_id: string, 15 | }, 16 | }; 17 | 18 | declare type TxoListParams = { 19 | page: number, 20 | page_size: number, 21 | type: string, 22 | is_my_input?: boolean, 23 | is_my_output?: boolean, 24 | is_not_my_input?: boolean, 25 | is_not_my_output?: boolean, 26 | is_spent?: boolean, 27 | }; 28 | -------------------------------------------------------------------------------- /flow-typed/bluebird.js: -------------------------------------------------------------------------------- 1 | declare module 'bluebird' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/classnames.js: -------------------------------------------------------------------------------- 1 | declare module 'classnames' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/content.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type PlayingUri = { 4 | uri: string, 5 | primaryUri: string, 6 | pathname: string, 7 | commentId?: string, 8 | source?: string, 9 | }; 10 | -------------------------------------------------------------------------------- /flow-typed/electron.js: -------------------------------------------------------------------------------- 1 | declare module 'electron' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/file-data.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type FileData = { 4 | file?: Blob, 5 | path: string, 6 | duration?: number, 7 | size?: number, 8 | mimeType: string, 9 | error?: string, 10 | } 11 | -------------------------------------------------------------------------------- /flow-typed/file-with-path.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type FileWithPath = { 4 | file: File, 5 | // The full path will only be available in 6 | // the application. For browser, the name 7 | // of the file will be used. 8 | path: string, 9 | } 10 | -------------------------------------------------------------------------------- /flow-typed/formik.js: -------------------------------------------------------------------------------- 1 | declare module 'formik' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/homepage.js: -------------------------------------------------------------------------------- 1 | declare type HomepageObject = { 2 | icon: string, 3 | link: string, 4 | options: any, 5 | route: string, 6 | title: string, 7 | }; 8 | 9 | declare type HomepageData = { 10 | [string]: HomepageObject, 11 | default: any => any, 12 | }; 13 | 14 | declare type RowDataItem = { 15 | title: any, 16 | link?: string, 17 | help?: any, 18 | icon?: string, 19 | extra?: any, 20 | pinnedUrls?: Array, 21 | options?: { 22 | channelIds?: Array, 23 | limitClaimsPerChannel?: number, 24 | pageSize?: number, 25 | languages?: Array, 26 | }, 27 | route?: string, 28 | hideForUnauth?: boolean, 29 | }; 30 | -------------------------------------------------------------------------------- /flow-typed/i18n.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | declare function __(a: string, b?: {}): string; 3 | -------------------------------------------------------------------------------- /flow-typed/lbryURI.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | declare type LbryUrlObj = { 3 | // Path and channel will always exist when calling parseURI 4 | // But they may not exist when code calls buildURI 5 | isChannel?: boolean, 6 | path?: string, 7 | streamName?: string, 8 | streamClaimId?: string, 9 | channelName?: string, 10 | channelClaimId?: string, 11 | primaryClaimSequence?: number, 12 | secondaryClaimSequence?: number, 13 | primaryBidPosition?: number, 14 | secondaryBidPosition?: number, 15 | startTime?: number, 16 | 17 | // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url 18 | claimName?: string, 19 | claimId?: string, 20 | contentName?: string, 21 | }; 22 | -------------------------------------------------------------------------------- /flow-typed/location.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type UrlLocation = { 4 | search: string, 5 | hash: string, 6 | host: string, 7 | hostname: string, 8 | href: string, 9 | key: string, 10 | origin: string, 11 | pathname: string, 12 | port: string, 13 | protocol: string, 14 | reload: () => void, 15 | replace: string => void, 16 | search: string, 17 | state: {}, 18 | }; 19 | -------------------------------------------------------------------------------- /flow-typed/npm/@babel/polyfill_v7.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ebc6e7724cd1da0d1a8b10de36bd7a94 2 | // flow-typed version: 7b122e75af/@babel/polyfill_v7.x.x/flow_>=v0.30.x 3 | 4 | declare module '@babel/polyfill' {} 5 | -------------------------------------------------------------------------------- /flow-typed/npm/@lbry/color_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 3213370d53d43337e039b1f99b90ad98 2 | // flow-typed version: <>/@lbry/color_v^1.0.2/flow_v0.94.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@lbry/color' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@lbry/color' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/@lbry/components_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8b77537ae4d6c835866e04a70a0ad6f3 2 | // flow-typed version: <>/@lbry/components_v^2.2.4/flow_v0.94.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@lbry/components' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@lbry/components' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/@types/three_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: e85a840886c4c445a0e0d1b1c1b20fef 2 | // flow-typed version: <>/@types/three_v^0.93.1/flow_v0.94.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@types/three' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@types/three' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/classnames_v2.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: cf86673cc32d185bdab1d2ea90578d37 2 | // flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x 3 | 4 | type $npm$classnames$Classes = 5 | | string 6 | | { [className: string]: * } 7 | | false 8 | | void 9 | | null; 10 | 11 | declare module "classnames" { 12 | declare module.exports: ( 13 | ...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]> 14 | ) => string; 15 | } 16 | 17 | declare module "classnames/bind" { 18 | declare module.exports: $Exports<"classnames">; 19 | } 20 | 21 | declare module "classnames/dedupe" { 22 | declare module.exports: $Exports<"classnames">; 23 | } 24 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-bin_v0.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 2 | // flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x 3 | 4 | declare module "flow-bin" { 5 | declare module.exports: string; 6 | } 7 | -------------------------------------------------------------------------------- /flow-typed/qrcode.react.js: -------------------------------------------------------------------------------- 1 | declare module 'qrcode.react' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/react-markdown.js: -------------------------------------------------------------------------------- 1 | declare module 'react-markdown' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/react-modal.js: -------------------------------------------------------------------------------- 1 | declare module 'react-modal' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/react-paginate.js: -------------------------------------------------------------------------------- 1 | declare module 'react-paginate' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/react-simplemde-editor.js: -------------------------------------------------------------------------------- 1 | declare module 'react-simplemde-editor' { 2 | declare module.exports: any; 3 | } 4 | 5 | declare module 'react-simplemde-editor/dist/simplemde.min.css' { 6 | declare module.exports: any; 7 | } 8 | -------------------------------------------------------------------------------- /flow-typed/react-transition-group.js: -------------------------------------------------------------------------------- 1 | declare module 'react-transition-group' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/reportContent.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as ACTIONS from 'constants/action_types'; 3 | 4 | declare type ReportContentState = { 5 | isReporting: boolean, 6 | error: string, 7 | }; 8 | 9 | 10 | -------------------------------------------------------------------------------- /flow-typed/reselect.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare module 'reselect' { 4 | declare module.exports: any; 5 | } 6 | -------------------------------------------------------------------------------- /flow-typed/reward.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type Reward = { 4 | created_at: string, 5 | id: number, 6 | reward_amount: number, 7 | reward_range?: string, 8 | reward_description: string, 9 | reward_notification: string, 10 | reward_title: string, 11 | reward_type: string, 12 | reward_version: ?string, 13 | transaction_id: ?string, 14 | updated_at: ?string, 15 | claim_code: string, 16 | }; 17 | -------------------------------------------------------------------------------- /flow-typed/shapeshift.io.js: -------------------------------------------------------------------------------- 1 | declare module 'shapeshift.io' { 2 | declare module.exports: any; 3 | } 4 | -------------------------------------------------------------------------------- /flow-typed/subscription.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare type Subscription = { 4 | channelName: string, // @CryptoCandor, 5 | uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6 6 | notificationsDisabled?: boolean, 7 | }; 8 | 9 | declare type Following = { 10 | uri: string, // lbry://@CryptoCandor#9152f3b054f692076a6882d1b58a30e8781cc8e6 11 | notificationsDisabled: boolean, 12 | }; 13 | 14 | declare type SubscriptionState = { 15 | subscriptions: Array, 16 | following: Array, 17 | loading: boolean, 18 | firstRunCompleted: boolean, 19 | }; 20 | -------------------------------------------------------------------------------- /flow-typed/web.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare var IS_WEB: boolean; 4 | -------------------------------------------------------------------------------- /homepages/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | en: {}, 3 | }; 4 | -------------------------------------------------------------------------------- /homepages/meme/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | text: `This is LBRY`, 3 | url: 'https://odysee.com/@Odysee:8?view=discussion', 4 | }; 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ file, options, env }) => { 2 | env = env || {}; 3 | file = file || {}; 4 | options = options || {}; 5 | options.cssnext = options.cssnext || null; 6 | options.autoprefixer = options.autoprefixer || null; 7 | options.cssnano = options.cssnano || null; 8 | 9 | return { 10 | parser: file.extname === '.sss' ? 'sugarss' : false, 11 | plugins: { 12 | 'postcss-import': { root: file.dirname }, 13 | cssnano: env === 'production' ? options.cssnano : false, 14 | }, 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /static/app-update.yml: -------------------------------------------------------------------------------- 1 | owner: lbryio 2 | repo: lbry-desktop 3 | provider: github -------------------------------------------------------------------------------- /static/font/v1/300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/300.woff -------------------------------------------------------------------------------- /static/font/v1/300i.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/300i.woff -------------------------------------------------------------------------------- /static/font/v1/400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/400.woff -------------------------------------------------------------------------------- /static/font/v1/400i.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/400i.woff -------------------------------------------------------------------------------- /static/font/v1/700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/700.woff -------------------------------------------------------------------------------- /static/font/v1/700i.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/font/v1/700i.woff -------------------------------------------------------------------------------- /static/img/busy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/busy.gif -------------------------------------------------------------------------------- /static/img/favicon-spaceman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/favicon-spaceman.png -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/favicon.png -------------------------------------------------------------------------------- /static/img/fileRenderPlaceholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/fileRenderPlaceholder.png -------------------------------------------------------------------------------- /static/img/freespch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/freespch.png -------------------------------------------------------------------------------- /static/img/placeholderTx.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/placeholderTx.gif -------------------------------------------------------------------------------- /static/img/tray/default/tray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/tray/default/tray.png -------------------------------------------------------------------------------- /static/img/tray/mac/trayTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/tray/mac/trayTemplate.png -------------------------------------------------------------------------------- /static/img/tray/mac/trayTemplate@2x copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/tray/mac/trayTemplate@2x copy.png -------------------------------------------------------------------------------- /static/img/tray/mac/trayTemplate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/tray/mac/trayTemplate@2x.png -------------------------------------------------------------------------------- /static/img/tray/windows/tray.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/tray/windows/tray.ico -------------------------------------------------------------------------------- /static/img/v2-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/img/v2-og.png -------------------------------------------------------------------------------- /static/opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /static/webworkers/wasm-gen/libarchive.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/static/webworkers/wasm-gen/libarchive.wasm -------------------------------------------------------------------------------- /ui/app.js: -------------------------------------------------------------------------------- 1 | import { store } from 'store'; 2 | 3 | const env = process.env.NODE_ENV || 'production'; 4 | 5 | const logs = []; 6 | const app = { 7 | env, 8 | store, 9 | logs, 10 | log(message) { 11 | logs.push(message); 12 | }, 13 | }; 14 | 15 | global.app = app; 16 | 17 | // Lbryinc needs access to the redux store for dispatching auth-releated actions 18 | global.store = app.store; 19 | 20 | export default app; 21 | -------------------------------------------------------------------------------- /ui/component/IframeReact/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import IframeReact from './view'; 3 | 4 | const select = state => ({}); 5 | 6 | const perform = () => ({}); 7 | 8 | export default connect(select, perform)(IframeReact); 9 | -------------------------------------------------------------------------------- /ui/component/abandonedChannelPreview/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import AbandonedChannelPreview from './view'; 3 | 4 | const select = (state, props) => ({}); 5 | 6 | export default connect(select)(AbandonedChannelPreview); 7 | -------------------------------------------------------------------------------- /ui/component/appStorageVisualization/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import StorageViz from './view'; 3 | import { 4 | selectViewBlobSpace, 5 | selectViewHostingLimit, 6 | selectAutoBlobSpace, 7 | selectPrivateBlobSpace, 8 | selectAutoHostingLimit, 9 | } from 'redux/selectors/settings'; 10 | import { selectDiskSpace } from 'redux/selectors/app'; 11 | 12 | const select = (state) => ({ 13 | diskSpace: selectDiskSpace(state), 14 | viewHostingLimit: selectViewHostingLimit(state), 15 | autoHostingLimit: selectAutoHostingLimit(state), 16 | viewBlobSpace: selectViewBlobSpace(state), 17 | autoBlobSpace: selectAutoBlobSpace(state), 18 | privateBlobSpace: selectPrivateBlobSpace(state), 19 | }); 20 | 21 | export default connect(select)(StorageViz); 22 | -------------------------------------------------------------------------------- /ui/component/autoplayCountdown/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 3 | import { withRouter } from 'react-router'; 4 | import AutoplayCountdown from './view'; 5 | import { selectModal } from 'redux/selectors/app'; 6 | 7 | /* 8 | AutoplayCountdown does not fetch it's own next content to play, it relies on being rendered. 9 | This is dumb but I'm just the guy who noticed -kj 10 | */ 11 | const select = (state, props) => ({ 12 | nextRecommendedClaim: makeSelectClaimForUri(props.nextRecommendedUri)(state), 13 | modal: selectModal(state), 14 | }); 15 | 16 | export default withRouter(connect(select, null)(AutoplayCountdown)); 17 | -------------------------------------------------------------------------------- /ui/component/blockList/index.js: -------------------------------------------------------------------------------- 1 | import BlockList from './view'; 2 | export default BlockList; 3 | -------------------------------------------------------------------------------- /ui/component/button/index.js: -------------------------------------------------------------------------------- 1 | import Button from './view'; 2 | import React, { forwardRef } from 'react'; 3 | import { connect } from 'react-redux'; 4 | import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user'; 5 | 6 | const mapStateToProps = (state) => ({ 7 | pathname: state.router.location.pathname, 8 | emailVerified: selectUserVerifiedEmail(state), 9 | user: selectUser(state), 10 | }); 11 | 12 | const ConnectedButton = connect(mapStateToProps)(Button); 13 | 14 | export default forwardRef((props, ref) => ); 15 | -------------------------------------------------------------------------------- /ui/component/cardVerify/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectUserEmail } from 'redux/selectors/user'; 3 | import CardVerify from './view'; 4 | 5 | const select = state => ({ 6 | email: selectUserEmail(state), 7 | }); 8 | 9 | const perform = () => ({}); 10 | 11 | export default connect(select, perform)(CardVerify); 12 | -------------------------------------------------------------------------------- /ui/component/channelAbout/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectMetadataItemForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; 3 | import ChannelAbout from './view'; 4 | 5 | const select = (state, props) => ({ 6 | claim: makeSelectClaimForUri(props.uri)(state), 7 | description: makeSelectMetadataItemForUri(props.uri, 'description')(state), 8 | website: makeSelectMetadataItemForUri(props.uri, 'website_url')(state), 9 | email: makeSelectMetadataItemForUri(props.uri, 'email')(state), 10 | languages: makeSelectMetadataItemForUri(props.uri, 'languages')(state), 11 | }); 12 | 13 | export default connect(select, null)(ChannelAbout); 14 | -------------------------------------------------------------------------------- /ui/component/channelDiscussion/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { withRouter } from 'react-router'; 3 | import { DISABLE_COMMENTS_TAG } from 'constants/tags'; 4 | import ChannelDiscussion from './view'; 5 | import { makeSelectTagInClaimOrChannelForUri } from 'redux/selectors/claims'; 6 | 7 | const select = (state, props) => { 8 | const { search } = props.location; 9 | const urlParams = new URLSearchParams(search); 10 | 11 | return { 12 | linkedCommentId: urlParams.get('lc'), 13 | commentsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state), 14 | }; 15 | }; 16 | 17 | export default withRouter(connect(select)(ChannelDiscussion)); 18 | -------------------------------------------------------------------------------- /ui/component/channelDiscussion/view.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import CommentsList from 'component/commentsList'; 4 | import Empty from 'component/common/empty'; 5 | 6 | type Props = { 7 | uri: string, 8 | linkedCommentId?: string, 9 | commentsDisabled: boolean, 10 | }; 11 | 12 | function ChannelDiscussion(props: Props) { 13 | const { uri, linkedCommentId, commentsDisabled } = props; 14 | 15 | if (commentsDisabled) { 16 | return ; 17 | } 18 | return ( 19 |
20 | 21 |
22 | ); 23 | } 24 | 25 | export default ChannelDiscussion; 26 | -------------------------------------------------------------------------------- /ui/component/channelMuteButton/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { doChannelMute, doChannelUnmute } from 'redux/actions/blocked'; 3 | import { makeSelectChannelIsMuted } from 'redux/selectors/blocked'; 4 | import ChannelMuteButton from './view'; 5 | 6 | const select = (state, props) => ({ 7 | isMuted: makeSelectChannelIsMuted(props.uri)(state), 8 | }); 9 | 10 | export default connect(select, { 11 | doChannelMute, 12 | doChannelUnmute, 13 | })(ChannelMuteButton); 14 | -------------------------------------------------------------------------------- /ui/component/channelSelector/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectMyChannelClaims } from 'redux/selectors/claims'; 3 | import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app'; 4 | import { doSetActiveChannel, doSetIncognito } from 'redux/actions/app'; 5 | import ChannelSelector from './view'; 6 | 7 | const select = (state) => ({ 8 | channels: selectMyChannelClaims(state), 9 | activeChannelClaim: selectActiveChannelClaim(state), 10 | incognito: selectIncognito(state), 11 | }); 12 | 13 | export default connect(select, { 14 | doSetActiveChannel, 15 | doSetIncognito, 16 | })(ChannelSelector); 17 | -------------------------------------------------------------------------------- /ui/component/channelStakedIndicator/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { 3 | makeSelectClaimForUri, 4 | selectTotalStakedAmountForChannelUri, 5 | selectStakedLevelForChannelUri, 6 | } from 'redux/selectors/claims'; 7 | import ChannelStakedIndicator from './view'; 8 | 9 | const select = (state, props) => ({ 10 | channelClaim: makeSelectClaimForUri(props.uri)(state), 11 | amount: selectTotalStakedAmountForChannelUri(state, props.uri), 12 | level: selectStakedLevelForChannelUri(state, props.uri), 13 | }); 14 | 15 | export default connect(select)(ChannelStakedIndicator); 16 | -------------------------------------------------------------------------------- /ui/component/channelThumbnail/gerbil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lbryio/lbry-desktop/d14c9141db0bfa2db9b5dcf78fcaa72912cc767a/ui/component/channelThumbnail/gerbil.png -------------------------------------------------------------------------------- /ui/component/channelThumbnail/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectThumbnailForUri, selectClaimForUri, selectIsUriResolving } from 'redux/selectors/claims'; 3 | import { doResolveUri } from 'redux/actions/claims'; 4 | import ChannelThumbnail from './view'; 5 | 6 | const select = (state, props) => ({ 7 | thumbnail: selectThumbnailForUri(state, props.uri), 8 | claim: selectClaimForUri(state, props.uri), 9 | isResolving: selectIsUriResolving(state, props.uri), 10 | }); 11 | 12 | export default connect(select, { 13 | doResolveUri, 14 | })(ChannelThumbnail); 15 | -------------------------------------------------------------------------------- /ui/component/channelTitle/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims'; 3 | import ChannelTitle from './view'; 4 | 5 | const select = (state, props) => ({ 6 | title: selectTitleForUri(state, props.uri), 7 | claim: makeSelectClaimForUri(props.uri)(state), 8 | }); 9 | 10 | export default connect(select)(ChannelTitle); 11 | -------------------------------------------------------------------------------- /ui/component/channelTitle/view.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | 4 | type Props = { 5 | claim: ?ChannelClaim, 6 | title: ?string, 7 | }; 8 | 9 | function ChannelTitle(props: Props) { 10 | const { title, claim } = props; 11 | 12 | if (!claim) { 13 | return null; 14 | } 15 | 16 | return
{title || claim.name}
; 17 | } 18 | 19 | export default ChannelTitle; 20 | -------------------------------------------------------------------------------- /ui/component/claimAbandonButton/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { doOpenModal } from 'redux/actions/app'; 3 | import ClaimAbandonButton from './view'; 4 | 5 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 6 | 7 | const select = (state, props) => ({ 8 | claim: props.uri && makeSelectClaimForUri(props.uri)(state), 9 | }); 10 | 11 | export default connect(select, { 12 | doOpenModal, 13 | })(ClaimAbandonButton); 14 | -------------------------------------------------------------------------------- /ui/component/claimAuthor/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectChannelForClaimUri } from 'redux/selectors/claims'; 3 | import ClaimAuthor from './view'; 4 | 5 | const select = (state, props) => ({ 6 | channelUri: makeSelectChannelForClaimUri(props.uri)(state), 7 | }); 8 | 9 | export default connect(select)(ClaimAuthor); 10 | -------------------------------------------------------------------------------- /ui/component/claimAuthor/view.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import ClaimPreview from 'component/claimPreview'; 4 | 5 | type Props = { 6 | channelUri: string, 7 | hideActions?: boolean, 8 | channelSubCount?: number, 9 | }; 10 | 11 | function ClaimAuthor(props: Props) { 12 | const { channelUri, hideActions, channelSubCount } = props; 13 | 14 | return channelUri ? ( 15 | 23 | ) : ( 24 |
{__('Anonymous')}
25 | ); 26 | } 27 | 28 | export default ClaimAuthor; 29 | -------------------------------------------------------------------------------- /ui/component/claimCollectionAddButton/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { doOpenModal } from 'redux/actions/app'; 3 | import CollectionAddButton from './view'; 4 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 5 | import { makeSelectClaimUrlInCollection } from 'redux/selectors/collections'; 6 | 7 | const select = (state, props) => { 8 | const claim = makeSelectClaimForUri(props.uri)(state); 9 | const permanentUrl = claim && claim.permanent_url; 10 | 11 | return { 12 | claim, 13 | isSaved: makeSelectClaimUrlInCollection(permanentUrl)(state), 14 | }; 15 | }; 16 | 17 | export default connect(select, { 18 | doOpenModal, 19 | })(CollectionAddButton); 20 | -------------------------------------------------------------------------------- /ui/component/claimEffectiveAmount/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 3 | import ClaimEffectiveAmount from './view'; 4 | 5 | const select = (state, props) => ({ 6 | claim: makeSelectClaimForUri(props.uri, true)(state), 7 | }); 8 | 9 | export default connect(select)(ClaimEffectiveAmount); 10 | -------------------------------------------------------------------------------- /ui/component/claimEffectiveAmount/view.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import CreditAmount from 'component/common/credit-amount'; 4 | 5 | type Props = { 6 | uri: string, 7 | claim: ?Claim, 8 | }; 9 | 10 | function ClaimEffectiveAmount(props: Props) { 11 | const { claim } = props; 12 | 13 | if (!claim) { 14 | return null; 15 | } 16 | 17 | return ; 18 | } 19 | 20 | export default ClaimEffectiveAmount; 21 | -------------------------------------------------------------------------------- /ui/component/claimInsufficientCredits/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectInsufficientCreditsForUri } from 'redux/selectors/content'; 3 | import { makeSelectClaimWasPurchased } from 'redux/selectors/claims'; 4 | import ClaimInsufficientCredits from './view'; 5 | 6 | const select = (state, props) => ({ 7 | isInsufficientCredits: selectInsufficientCreditsForUri(state, props.uri), 8 | claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state), 9 | }); 10 | 11 | export default connect(select)(ClaimInsufficientCredits); 12 | -------------------------------------------------------------------------------- /ui/component/claimList/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import ClaimList from './view'; 3 | import * as SETTINGS from 'constants/settings'; 4 | 5 | import { makeSelectClientSetting } from 'redux/selectors/settings'; 6 | 7 | const select = (state) => ({ 8 | searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state), 9 | }); 10 | 11 | export default connect(select)(ClaimList); 12 | -------------------------------------------------------------------------------- /ui/component/claimPreviewTitle/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri, selectTitleForUri } from 'redux/selectors/claims'; 3 | import ClaimPreviewTitle from './view'; 4 | 5 | const select = (state, props) => ({ 6 | claim: makeSelectClaimForUri(props.uri)(state), 7 | title: selectTitleForUri(state, props.uri), 8 | }); 9 | 10 | export default connect(select)(ClaimPreviewTitle); 11 | -------------------------------------------------------------------------------- /ui/component/claimPreviewTitle/view.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import TruncatedText from 'component/common/truncated-text'; 4 | 5 | type Props = { 6 | uri: string, 7 | claim: ?Claim, 8 | title: string, 9 | }; 10 | 11 | function ClaimPreviewTitle(props: Props) { 12 | const { title, claim } = props; 13 | 14 | return ( 15 |
16 | {claim ? : {__('Nothing here')}} 17 |
18 | ); 19 | } 20 | 21 | export default ClaimPreviewTitle; 22 | -------------------------------------------------------------------------------- /ui/component/claimProperties/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims'; 3 | import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions'; 4 | import ClaimProperties from './view'; 5 | 6 | const select = (state, props) => { 7 | const claim = selectClaimForUri(state, props.uri); 8 | 9 | return { 10 | claim, 11 | isSubscribed: selectIsSubscribedForUri(state, props.uri), 12 | claimIsMine: selectClaimIsMine(state, claim), 13 | }; 14 | }; 15 | 16 | export default connect(select, null)(ClaimProperties); 17 | -------------------------------------------------------------------------------- /ui/component/claimRepostAuthor/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 3 | import ClaimRepostAuthor from './view'; 4 | 5 | const select = (state, props) => ({ 6 | claim: makeSelectClaimForUri(props.uri)(state), 7 | }); 8 | 9 | export default connect(select)(ClaimRepostAuthor); 10 | -------------------------------------------------------------------------------- /ui/component/claimRepostButton/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { doOpenModal } from 'redux/actions/app'; 3 | import { doToast } from 'redux/actions/notifications'; 4 | import ClaimReportButton from './view'; 5 | 6 | export default connect(null, { doOpenModal, doToast })(ClaimReportButton); 7 | -------------------------------------------------------------------------------- /ui/component/claimSupportButton/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { doOpenModal } from 'redux/actions/app'; 3 | import { makeSelectTagInClaimOrChannelForUri, makeSelectClaimForUri } from 'redux/selectors/claims'; 4 | import ClaimSupportButton from './view'; 5 | 6 | const DISABLE_SUPPORT_TAG = 'disable-support'; 7 | const select = (state, props) => ({ 8 | disableSupport: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_SUPPORT_TAG)(state), 9 | claim: makeSelectClaimForUri(props.uri)(state), 10 | }); 11 | 12 | export default connect(select, { 13 | doOpenModal, 14 | })(ClaimSupportButton); 15 | -------------------------------------------------------------------------------- /ui/component/claimTags/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { selectTagsForUri } from 'redux/selectors/claims'; 3 | import { selectFollowedTags } from 'redux/selectors/tags'; 4 | import ClaimTags from './view'; 5 | 6 | const select = (state, props) => ({ 7 | tags: selectTagsForUri(state, props.uri), 8 | followedTags: selectFollowedTags(state), 9 | }); 10 | 11 | export default connect(select, null)(ClaimTags); 12 | -------------------------------------------------------------------------------- /ui/component/claimType/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectClaimForUri } from 'redux/selectors/claims'; 3 | import FileType from './view'; 4 | 5 | const select = (state, props) => ({ 6 | claim: makeSelectClaimForUri(props.uri)(state), 7 | }); 8 | 9 | export default connect(select)(FileType); 10 | -------------------------------------------------------------------------------- /ui/component/claimUri/index.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { makeSelectCanonicalUrlForUri } from 'redux/selectors/claims'; 3 | import { doToast } from 'redux/actions/notifications'; 4 | import ClaimUri from './view'; 5 | 6 | const select = (state, props) => ({ 7 | shortUrl: makeSelectCanonicalUrlForUri(props.uri)(state), 8 | }); 9 | 10 | export default connect(select, { 11 | doToast, 12 | })(ClaimUri); 13 | -------------------------------------------------------------------------------- /ui/component/collectionPreviewTile/collectionCount.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import classnames from 'classnames'; 4 | import * as ICONS from 'constants/icons'; 5 | import Icon from 'component/common/icon'; 6 | type Props = { 7 | count: number, 8 | }; 9 | 10 | export default function collectionCount(props: Props) { 11 | const { count = 0 } = props; 12 | 13 | return ( 14 |
15 | 16 |
{count}
17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /ui/component/collectionPreviewTile/collectionPrivate.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import classnames from 'classnames'; 4 | import * as ICONS from 'constants/icons'; 5 | import Icon from 'component/common/icon'; 6 | 7 | export default function collectionCount() { 8 | return ( 9 |
10 | 11 |
{__('Private')}
12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /ui/component/common/busy-indicator.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | 4 | type Props = { 5 | message: ?string, 6 | }; 7 | 8 | class BusyIndicator extends React.PureComponent { 9 | static defaultProps = { 10 | message: '', 11 | }; 12 | 13 | render() { 14 | const { message } = this.props; 15 | 16 | return ( 17 | 18 | {message} 19 | 20 | ); 21 | } 22 | } 23 | 24 | export default BusyIndicator; 25 | -------------------------------------------------------------------------------- /ui/component/common/empty.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import classnames from 'classnames'; 4 | 5 | type Props = { 6 | text: string, 7 | padded?: boolean, 8 | }; 9 | 10 | export default function Empty(props: Props) { 11 | const { text = '', padded = false } = props; 12 | 13 | return ( 14 |
15 |
16 | {text && ( 17 |
18 |

{text}

19 |
20 | )} 21 |
22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /ui/component/common/error-text.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | 4 | type Props = { 5 | children: string, 6 | }; 7 | 8 | export default function ErrorText(props: Props) { 9 | const { children } = props; 10 | 11 | if (!children) { 12 | return null; 13 | } 14 | 15 | // Add a period to the end of error messages 16 | let errorMessage = children[0].toUpperCase() + children.slice(1); 17 | errorMessage = errorMessage.endsWith('.') ? errorMessage : `${errorMessage}.`; 18 | 19 | return {errorMessage}; 20 | } 21 | -------------------------------------------------------------------------------- /ui/component/common/form-components/form.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | 4 | type Props = { 5 | children: React.Node, 6 | onSubmit: any => any, 7 | }; 8 | 9 | export class Form extends React.PureComponent { 10 | render() { 11 | const { children, onSubmit, ...otherProps } = this.props; 12 | return ( 13 |
{ 17 | event.preventDefault(); 18 | onSubmit(event); 19 | }} 20 | {...otherProps} 21 | > 22 | {children} 23 |
24 | ); 25 | } 26 | } 27 | 28 | export default Form; 29 | -------------------------------------------------------------------------------- /ui/component/common/form-components/submit.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import Button from 'component/button'; 4 | 5 | type Props = { 6 | label: string, 7 | disabled: boolean, 8 | }; 9 | 10 | export class Submit extends React.PureComponent { 11 | static defaultProps = { 12 | label: 'Submit', 13 | }; 14 | 15 | render() { 16 | const { label, disabled, ...otherProps } = this.props; 17 | return