diff --git a/dist/bundle.es.js b/dist/bundle.es.js new file mode 100644 index 0000000..ae3251f --- /dev/null +++ b/dist/bundle.es.js @@ -0,0 +1,3473 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +require('proxy-polyfill'); +var reselect = require('reselect'); +var uuid = _interopDefault(require('uuid/v4')); + +const WINDOW_FOCUSED = 'WINDOW_FOCUSED'; +const DAEMON_READY = 'DAEMON_READY'; +const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; +const DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; +const VOLUME_CHANGED = 'VOLUME_CHANGED'; + +// Navigation +const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; +const WINDOW_SCROLLED = 'WINDOW_SCROLLED'; +const HISTORY_NAVIGATE = 'HISTORY_NAVIGATE'; + +// Upgrades +const UPGRADE_CANCELLED = 'UPGRADE_CANCELLED'; +const DOWNLOAD_UPGRADE = 'DOWNLOAD_UPGRADE'; +const UPGRADE_DOWNLOAD_STARTED = 'UPGRADE_DOWNLOAD_STARTED'; +const UPGRADE_DOWNLOAD_COMPLETED = 'UPGRADE_DOWNLOAD_COMPLETED'; +const UPGRADE_DOWNLOAD_PROGRESSED = 'UPGRADE_DOWNLOAD_PROGRESSED'; +const CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE'; +const CHECK_UPGRADE_START = 'CHECK_UPGRADE_START'; +const CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS'; +const CHECK_UPGRADE_FAIL = 'CHECK_UPGRADE_FAIL'; +const CHECK_UPGRADE_SUBSCRIBE = 'CHECK_UPGRADE_SUBSCRIBE'; +const UPDATE_VERSION = 'UPDATE_VERSION'; +const UPDATE_REMOTE_VERSION = 'UPDATE_REMOTE_VERSION'; +const SKIP_UPGRADE = 'SKIP_UPGRADE'; +const START_UPGRADE = 'START_UPGRADE'; +const AUTO_UPDATE_DECLINED = 'AUTO_UPDATE_DECLINED'; +const AUTO_UPDATE_DOWNLOADED = 'AUTO_UPDATE_DOWNLOADED'; +const CLEAR_UPGRADE_TIMER = 'CLEAR_UPGRADE_TIMER'; + +// Wallet +const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; +const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; +const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; +const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +const UPDATE_BALANCE = 'UPDATE_BALANCE'; +const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; +const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'; +const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; +const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; +const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; +const FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; +const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; +const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; +const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; +const WALLET_ENCRYPT_START = 'WALLET_ENCRYPT_START'; +const WALLET_ENCRYPT_COMPLETED = 'WALLET_ENCRYPT_COMPLETED'; +const WALLET_ENCRYPT_FAILED = 'WALLET_ENCRYPT_FAILED'; +const WALLET_UNLOCK_START = 'WALLET_UNLOCK_START'; +const WALLET_UNLOCK_COMPLETED = 'WALLET_UNLOCK_COMPLETED'; +const WALLET_UNLOCK_FAILED = 'WALLET_UNLOCK_FAILED'; +const WALLET_DECRYPT_START = 'WALLET_DECRYPT_START'; +const WALLET_DECRYPT_COMPLETED = 'WALLET_DECRYPT_COMPLETED'; +const WALLET_DECRYPT_FAILED = 'WALLET_DECRYPT_FAILED'; +const WALLET_LOCK_START = 'WALLET_LOCK_START'; +const WALLET_LOCK_COMPLETED = 'WALLET_LOCK_COMPLETED'; +const WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; +const WALLET_STATUS_START = 'WALLET_STATUS_START'; +const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; +const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; +const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; + +// Claims +const RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED'; +const RESOLVE_URIS_COMPLETED = 'RESOLVE_URIS_COMPLETED'; +const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'; +const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'; +const FETCH_CHANNEL_CLAIM_COUNT_STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED'; +const FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED'; +const FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED'; +const FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED'; +const ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; +const ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; +const FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED'; +const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; +const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; +const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; +const PUBLISH_STARTED = 'PUBLISH_STARTED'; +const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; +const PUBLISH_FAILED = 'PUBLISH_FAILED'; +const SET_PLAYING_URI = 'SET_PLAYING_URI'; +const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; +const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; +const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; +const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; + +// Files +const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; +const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; +const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; +const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; +const LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; +const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; +const LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; +const DOWNLOADING_STARTED = 'DOWNLOADING_STARTED'; +const DOWNLOADING_PROGRESSED = 'DOWNLOADING_PROGRESSED'; +const DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED'; +const DOWNLOADING_CANCELED = 'DOWNLOADING_CANCELED'; +const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'; +const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; +const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; +const FILE_DELETE = 'FILE_DELETE'; +const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; + +// Search +const SEARCH_START = 'SEARCH_START'; +const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; +const SEARCH_FAIL = 'SEARCH_FAIL'; +const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'; +const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; +const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; +const SEARCH_FOCUS = 'SEARCH_FOCUS'; +const SEARCH_BLUR = 'SEARCH_BLUR'; + +// Settings +const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; +const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; + +// User +const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'; +const AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS'; +const AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE'; +const USER_EMAIL_DECLINE = 'USER_EMAIL_DECLINE'; +const USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'; +const USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'; +const USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'; +const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'; +const USER_EMAIL_VERIFY_SET = 'USER_EMAIL_VERIFY_SET'; +const USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED'; +const USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS'; +const USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE'; +const USER_EMAIL_VERIFY_RETRY = 'USER_EMAIL_VERIFY_RETRY'; +const USER_PHONE_RESET = 'USER_PHONE_RESET'; +const USER_PHONE_NEW_STARTED = 'USER_PHONE_NEW_STARTED'; +const USER_PHONE_NEW_SUCCESS = 'USER_PHONE_NEW_SUCCESS'; +const USER_PHONE_NEW_FAILURE = 'USER_PHONE_NEW_FAILURE'; +const USER_PHONE_VERIFY_STARTED = 'USER_PHONE_VERIFY_STARTED'; +const USER_PHONE_VERIFY_SUCCESS = 'USER_PHONE_VERIFY_SUCCESS'; +const USER_PHONE_VERIFY_FAILURE = 'USER_PHONE_VERIFY_FAILURE'; +const USER_IDENTITY_VERIFY_STARTED = 'USER_IDENTITY_VERIFY_STARTED'; +const USER_IDENTITY_VERIFY_SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS'; +const USER_IDENTITY_VERIFY_FAILURE = 'USER_IDENTITY_VERIFY_FAILURE'; +const USER_FETCH_STARTED = 'USER_FETCH_STARTED'; +const USER_FETCH_SUCCESS = 'USER_FETCH_SUCCESS'; +const USER_FETCH_FAILURE = 'USER_FETCH_FAILURE'; +const USER_INVITE_STATUS_FETCH_STARTED = 'USER_INVITE_STATUS_FETCH_STARTED'; +const USER_INVITE_STATUS_FETCH_SUCCESS = 'USER_INVITE_STATUS_FETCH_SUCCESS'; +const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; +const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; +const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; +const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; +const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; + +// Rewards +const FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'; +const FETCH_REWARDS_COMPLETED = 'FETCH_REWARDS_COMPLETED'; +const CLAIM_REWARD_STARTED = 'CLAIM_REWARD_STARTED'; +const CLAIM_REWARD_SUCCESS = 'CLAIM_REWARD_SUCCESS'; +const CLAIM_REWARD_FAILURE = 'CLAIM_REWARD_FAILURE'; +const CLAIM_REWARD_CLEAR_ERROR = 'CLAIM_REWARD_CLEAR_ERROR'; +const FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; + +// Language +const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; +const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; + +// ShapeShift +const GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; +const GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; +const GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; +const GET_COIN_STATS_START = 'GET_COIN_STATS_START'; +const GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; +const GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; +const PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; +const PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; +const PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; +const GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; +const GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; +const GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; +const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; + +// Subscriptions +const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; +const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; +const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; +const SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST'; +const SET_SUBSCRIPTION_NOTIFICATION = 'SET_SUBSCRIPTION_NOTIFICATION'; +const SET_SUBSCRIPTION_NOTIFICATIONS = 'SET_SUBSCRIPTION_NOTIFICATIONS'; +const CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED'; +const CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED'; +const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE'; + +// Publishing +const CLEAR_PUBLISH = 'CLEAR_PUBLISH'; +const UPDATE_PUBLISH_FORM = 'UPDATE_PUBLISH_FORM'; +const PUBLISH_START = 'PUBLISH_START'; +const PUBLISH_SUCCESS = 'PUBLISH_SUCCESS'; +const PUBLISH_FAIL = 'PUBLISH_FAIL'; +const CLEAR_PUBLISH_ERROR = 'CLEAR_PUBLISH_ERROR'; +const REMOVE_PENDING_PUBLISH = 'REMOVE_PENDING_PUBLISH'; +const DO_PREPARE_EDIT = 'DO_PREPARE_EDIT'; + +// Notifications +const CREATE_NOTIFICATION = 'CREATE_NOTIFICATION'; +const EDIT_NOTIFICATION = 'EDIT_NOTIFICATION'; +const DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'; +const CREATE_TOAST = 'CREATE_TOAST'; +const DISMISS_TOAST = 'DISMISS_TOAST'; +const CREATE_ERROR = 'CREATE_ERROR'; +const DISMISS_ERROR = 'DISMISS_ERROR'; + +const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; +const SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; +const FETCH_DATE = 'FETCH_DATE'; +const DISMISS_NOTIFICATION = 'DISMISS_NOTIFICATION'; + +var action_types = /*#__PURE__*/Object.freeze({ + WINDOW_FOCUSED: WINDOW_FOCUSED, + DAEMON_READY: DAEMON_READY, + DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, + DAEMON_VERSION_MISMATCH: DAEMON_VERSION_MISMATCH, + VOLUME_CHANGED: VOLUME_CHANGED, + CHANGE_AFTER_AUTH_PATH: CHANGE_AFTER_AUTH_PATH, + WINDOW_SCROLLED: WINDOW_SCROLLED, + HISTORY_NAVIGATE: HISTORY_NAVIGATE, + UPGRADE_CANCELLED: UPGRADE_CANCELLED, + DOWNLOAD_UPGRADE: DOWNLOAD_UPGRADE, + UPGRADE_DOWNLOAD_STARTED: UPGRADE_DOWNLOAD_STARTED, + UPGRADE_DOWNLOAD_COMPLETED: UPGRADE_DOWNLOAD_COMPLETED, + UPGRADE_DOWNLOAD_PROGRESSED: UPGRADE_DOWNLOAD_PROGRESSED, + CHECK_UPGRADE_AVAILABLE: CHECK_UPGRADE_AVAILABLE, + CHECK_UPGRADE_START: CHECK_UPGRADE_START, + CHECK_UPGRADE_SUCCESS: CHECK_UPGRADE_SUCCESS, + CHECK_UPGRADE_FAIL: CHECK_UPGRADE_FAIL, + CHECK_UPGRADE_SUBSCRIBE: CHECK_UPGRADE_SUBSCRIBE, + UPDATE_VERSION: UPDATE_VERSION, + UPDATE_REMOTE_VERSION: UPDATE_REMOTE_VERSION, + SKIP_UPGRADE: SKIP_UPGRADE, + START_UPGRADE: START_UPGRADE, + AUTO_UPDATE_DECLINED: AUTO_UPDATE_DECLINED, + AUTO_UPDATE_DOWNLOADED: AUTO_UPDATE_DOWNLOADED, + CLEAR_UPGRADE_TIMER: CLEAR_UPGRADE_TIMER, + GET_NEW_ADDRESS_STARTED: GET_NEW_ADDRESS_STARTED, + GET_NEW_ADDRESS_COMPLETED: GET_NEW_ADDRESS_COMPLETED, + FETCH_TRANSACTIONS_STARTED: FETCH_TRANSACTIONS_STARTED, + FETCH_TRANSACTIONS_COMPLETED: FETCH_TRANSACTIONS_COMPLETED, + UPDATE_BALANCE: UPDATE_BALANCE, + CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, + CHECK_ADDRESS_IS_MINE_COMPLETED: CHECK_ADDRESS_IS_MINE_COMPLETED, + SEND_TRANSACTION_STARTED: SEND_TRANSACTION_STARTED, + SEND_TRANSACTION_COMPLETED: SEND_TRANSACTION_COMPLETED, + SEND_TRANSACTION_FAILED: SEND_TRANSACTION_FAILED, + FETCH_BLOCK_SUCCESS: FETCH_BLOCK_SUCCESS, + SUPPORT_TRANSACTION_STARTED: SUPPORT_TRANSACTION_STARTED, + SUPPORT_TRANSACTION_COMPLETED: SUPPORT_TRANSACTION_COMPLETED, + SUPPORT_TRANSACTION_FAILED: SUPPORT_TRANSACTION_FAILED, + WALLET_ENCRYPT_START: WALLET_ENCRYPT_START, + WALLET_ENCRYPT_COMPLETED: WALLET_ENCRYPT_COMPLETED, + WALLET_ENCRYPT_FAILED: WALLET_ENCRYPT_FAILED, + WALLET_UNLOCK_START: WALLET_UNLOCK_START, + WALLET_UNLOCK_COMPLETED: WALLET_UNLOCK_COMPLETED, + WALLET_UNLOCK_FAILED: WALLET_UNLOCK_FAILED, + WALLET_DECRYPT_START: WALLET_DECRYPT_START, + WALLET_DECRYPT_COMPLETED: WALLET_DECRYPT_COMPLETED, + WALLET_DECRYPT_FAILED: WALLET_DECRYPT_FAILED, + WALLET_LOCK_START: WALLET_LOCK_START, + WALLET_LOCK_COMPLETED: WALLET_LOCK_COMPLETED, + WALLET_LOCK_FAILED: WALLET_LOCK_FAILED, + WALLET_STATUS_START: WALLET_STATUS_START, + WALLET_STATUS_COMPLETED: WALLET_STATUS_COMPLETED, + SET_TRANSACTION_LIST_FILTER: SET_TRANSACTION_LIST_FILTER, + UPDATE_CURRENT_HEIGHT: UPDATE_CURRENT_HEIGHT, + RESOLVE_URIS_STARTED: RESOLVE_URIS_STARTED, + RESOLVE_URIS_COMPLETED: RESOLVE_URIS_COMPLETED, + FETCH_CHANNEL_CLAIMS_STARTED: FETCH_CHANNEL_CLAIMS_STARTED, + FETCH_CHANNEL_CLAIMS_COMPLETED: FETCH_CHANNEL_CLAIMS_COMPLETED, + FETCH_CHANNEL_CLAIM_COUNT_STARTED: FETCH_CHANNEL_CLAIM_COUNT_STARTED, + FETCH_CHANNEL_CLAIM_COUNT_COMPLETED: FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, + FETCH_CLAIM_LIST_MINE_STARTED: FETCH_CLAIM_LIST_MINE_STARTED, + FETCH_CLAIM_LIST_MINE_COMPLETED: FETCH_CLAIM_LIST_MINE_COMPLETED, + ABANDON_CLAIM_STARTED: ABANDON_CLAIM_STARTED, + ABANDON_CLAIM_SUCCEEDED: ABANDON_CLAIM_SUCCEEDED, + FETCH_CHANNEL_LIST_STARTED: FETCH_CHANNEL_LIST_STARTED, + FETCH_CHANNEL_LIST_COMPLETED: FETCH_CHANNEL_LIST_COMPLETED, + CREATE_CHANNEL_STARTED: CREATE_CHANNEL_STARTED, + CREATE_CHANNEL_COMPLETED: CREATE_CHANNEL_COMPLETED, + PUBLISH_STARTED: PUBLISH_STARTED, + PUBLISH_COMPLETED: PUBLISH_COMPLETED, + PUBLISH_FAILED: PUBLISH_FAILED, + SET_PLAYING_URI: SET_PLAYING_URI, + SET_CONTENT_POSITION: SET_CONTENT_POSITION, + SET_CONTENT_LAST_VIEWED: SET_CONTENT_LAST_VIEWED, + CLEAR_CONTENT_HISTORY_URI: CLEAR_CONTENT_HISTORY_URI, + CLEAR_CONTENT_HISTORY_ALL: CLEAR_CONTENT_HISTORY_ALL, + FILE_LIST_STARTED: FILE_LIST_STARTED, + FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, + FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, + FETCH_FILE_INFO_COMPLETED: FETCH_FILE_INFO_COMPLETED, + LOADING_VIDEO_STARTED: LOADING_VIDEO_STARTED, + LOADING_VIDEO_COMPLETED: LOADING_VIDEO_COMPLETED, + LOADING_VIDEO_FAILED: LOADING_VIDEO_FAILED, + DOWNLOADING_STARTED: DOWNLOADING_STARTED, + DOWNLOADING_PROGRESSED: DOWNLOADING_PROGRESSED, + DOWNLOADING_COMPLETED: DOWNLOADING_COMPLETED, + DOWNLOADING_CANCELED: DOWNLOADING_CANCELED, + PLAY_VIDEO_STARTED: PLAY_VIDEO_STARTED, + FETCH_AVAILABILITY_STARTED: FETCH_AVAILABILITY_STARTED, + FETCH_AVAILABILITY_COMPLETED: FETCH_AVAILABILITY_COMPLETED, + FILE_DELETE: FILE_DELETE, + SET_FILE_LIST_SORT: SET_FILE_LIST_SORT, + SEARCH_START: SEARCH_START, + SEARCH_SUCCESS: SEARCH_SUCCESS, + SEARCH_FAIL: SEARCH_FAIL, + UPDATE_SEARCH_QUERY: UPDATE_SEARCH_QUERY, + UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS, + UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS, + SEARCH_FOCUS: SEARCH_FOCUS, + SEARCH_BLUR: SEARCH_BLUR, + DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, + CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, + UPDATE_IS_NIGHT: UPDATE_IS_NIGHT, + AUTHENTICATION_STARTED: AUTHENTICATION_STARTED, + AUTHENTICATION_SUCCESS: AUTHENTICATION_SUCCESS, + AUTHENTICATION_FAILURE: AUTHENTICATION_FAILURE, + USER_EMAIL_DECLINE: USER_EMAIL_DECLINE, + USER_EMAIL_NEW_STARTED: USER_EMAIL_NEW_STARTED, + USER_EMAIL_NEW_SUCCESS: USER_EMAIL_NEW_SUCCESS, + USER_EMAIL_NEW_EXISTS: USER_EMAIL_NEW_EXISTS, + USER_EMAIL_NEW_FAILURE: USER_EMAIL_NEW_FAILURE, + USER_EMAIL_VERIFY_SET: USER_EMAIL_VERIFY_SET, + USER_EMAIL_VERIFY_STARTED: USER_EMAIL_VERIFY_STARTED, + USER_EMAIL_VERIFY_SUCCESS: USER_EMAIL_VERIFY_SUCCESS, + USER_EMAIL_VERIFY_FAILURE: USER_EMAIL_VERIFY_FAILURE, + USER_EMAIL_VERIFY_RETRY: USER_EMAIL_VERIFY_RETRY, + USER_PHONE_RESET: USER_PHONE_RESET, + USER_PHONE_NEW_STARTED: USER_PHONE_NEW_STARTED, + USER_PHONE_NEW_SUCCESS: USER_PHONE_NEW_SUCCESS, + USER_PHONE_NEW_FAILURE: USER_PHONE_NEW_FAILURE, + USER_PHONE_VERIFY_STARTED: USER_PHONE_VERIFY_STARTED, + USER_PHONE_VERIFY_SUCCESS: USER_PHONE_VERIFY_SUCCESS, + USER_PHONE_VERIFY_FAILURE: USER_PHONE_VERIFY_FAILURE, + USER_IDENTITY_VERIFY_STARTED: USER_IDENTITY_VERIFY_STARTED, + USER_IDENTITY_VERIFY_SUCCESS: USER_IDENTITY_VERIFY_SUCCESS, + USER_IDENTITY_VERIFY_FAILURE: USER_IDENTITY_VERIFY_FAILURE, + USER_FETCH_STARTED: USER_FETCH_STARTED, + USER_FETCH_SUCCESS: USER_FETCH_SUCCESS, + USER_FETCH_FAILURE: USER_FETCH_FAILURE, + USER_INVITE_STATUS_FETCH_STARTED: USER_INVITE_STATUS_FETCH_STARTED, + USER_INVITE_STATUS_FETCH_SUCCESS: USER_INVITE_STATUS_FETCH_SUCCESS, + USER_INVITE_STATUS_FETCH_FAILURE: USER_INVITE_STATUS_FETCH_FAILURE, + USER_INVITE_NEW_STARTED: USER_INVITE_NEW_STARTED, + USER_INVITE_NEW_SUCCESS: USER_INVITE_NEW_SUCCESS, + USER_INVITE_NEW_FAILURE: USER_INVITE_NEW_FAILURE, + FETCH_ACCESS_TOKEN_SUCCESS: FETCH_ACCESS_TOKEN_SUCCESS, + FETCH_REWARDS_STARTED: FETCH_REWARDS_STARTED, + FETCH_REWARDS_COMPLETED: FETCH_REWARDS_COMPLETED, + CLAIM_REWARD_STARTED: CLAIM_REWARD_STARTED, + CLAIM_REWARD_SUCCESS: CLAIM_REWARD_SUCCESS, + CLAIM_REWARD_FAILURE: CLAIM_REWARD_FAILURE, + CLAIM_REWARD_CLEAR_ERROR: CLAIM_REWARD_CLEAR_ERROR, + FETCH_REWARD_CONTENT_COMPLETED: FETCH_REWARD_CONTENT_COMPLETED, + DOWNLOAD_LANGUAGE_SUCCEEDED: DOWNLOAD_LANGUAGE_SUCCEEDED, + DOWNLOAD_LANGUAGE_FAILED: DOWNLOAD_LANGUAGE_FAILED, + GET_SUPPORTED_COINS_START: GET_SUPPORTED_COINS_START, + GET_SUPPORTED_COINS_SUCCESS: GET_SUPPORTED_COINS_SUCCESS, + GET_SUPPORTED_COINS_FAIL: GET_SUPPORTED_COINS_FAIL, + GET_COIN_STATS_START: GET_COIN_STATS_START, + GET_COIN_STATS_SUCCESS: GET_COIN_STATS_SUCCESS, + GET_COIN_STATS_FAIL: GET_COIN_STATS_FAIL, + PREPARE_SHAPE_SHIFT_START: PREPARE_SHAPE_SHIFT_START, + PREPARE_SHAPE_SHIFT_SUCCESS: PREPARE_SHAPE_SHIFT_SUCCESS, + PREPARE_SHAPE_SHIFT_FAIL: PREPARE_SHAPE_SHIFT_FAIL, + GET_ACTIVE_SHIFT_START: GET_ACTIVE_SHIFT_START, + GET_ACTIVE_SHIFT_SUCCESS: GET_ACTIVE_SHIFT_SUCCESS, + GET_ACTIVE_SHIFT_FAIL: GET_ACTIVE_SHIFT_FAIL, + CLEAR_SHAPE_SHIFT: CLEAR_SHAPE_SHIFT, + CHANNEL_SUBSCRIBE: CHANNEL_SUBSCRIBE, + CHANNEL_UNSUBSCRIBE: CHANNEL_UNSUBSCRIBE, + HAS_FETCHED_SUBSCRIPTIONS: HAS_FETCHED_SUBSCRIPTIONS, + SET_SUBSCRIPTION_LATEST: SET_SUBSCRIPTION_LATEST, + SET_SUBSCRIPTION_NOTIFICATION: SET_SUBSCRIPTION_NOTIFICATION, + SET_SUBSCRIPTION_NOTIFICATIONS: SET_SUBSCRIPTION_NOTIFICATIONS, + CHECK_SUBSCRIPTION_STARTED: CHECK_SUBSCRIPTION_STARTED, + CHECK_SUBSCRIPTION_COMPLETED: CHECK_SUBSCRIPTION_COMPLETED, + CHECK_SUBSCRIPTIONS_SUBSCRIBE: CHECK_SUBSCRIPTIONS_SUBSCRIBE, + CLEAR_PUBLISH: CLEAR_PUBLISH, + UPDATE_PUBLISH_FORM: UPDATE_PUBLISH_FORM, + PUBLISH_START: PUBLISH_START, + PUBLISH_SUCCESS: PUBLISH_SUCCESS, + PUBLISH_FAIL: PUBLISH_FAIL, + CLEAR_PUBLISH_ERROR: CLEAR_PUBLISH_ERROR, + REMOVE_PENDING_PUBLISH: REMOVE_PENDING_PUBLISH, + DO_PREPARE_EDIT: DO_PREPARE_EDIT, + CREATE_NOTIFICATION: CREATE_NOTIFICATION, + EDIT_NOTIFICATION: EDIT_NOTIFICATION, + DELETE_NOTIFICATION: DELETE_NOTIFICATION, + CREATE_TOAST: CREATE_TOAST, + DISMISS_TOAST: DISMISS_TOAST, + CREATE_ERROR: CREATE_ERROR, + DISMISS_ERROR: DISMISS_ERROR, + SET_DRAFT_TRANSACTION_AMOUNT: SET_DRAFT_TRANSACTION_AMOUNT, + SET_DRAFT_TRANSACTION_ADDRESS: SET_DRAFT_TRANSACTION_ADDRESS, + FETCH_DATE: FETCH_DATE, + DISMISS_NOTIFICATION: DISMISS_NOTIFICATION +}); + +const API_DOWN = 'apiDown'; +const READY = 'ready'; +const IN_PROGRESS = 'inProgress'; +const COMPLETE = 'complete'; +const MANUAL = 'manual'; + +var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + API_DOWN: API_DOWN, + READY: READY, + IN_PROGRESS: IN_PROGRESS, + COMPLETE: COMPLETE, + MANUAL: MANUAL +}); + +/* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ +/* Many SETTINGS are stored in the localStorage by their name - + be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ +const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; +const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; +const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; +const LANGUAGE = 'language'; +const SHOW_NSFW = 'showNsfw'; +const SHOW_UNAVAILABLE = 'showUnavailable'; +const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; +const INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; +const THEME = 'theme'; +const THEMES = 'themes'; +const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; + +// mobile settings +const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; +const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; +const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; + +var settings = /*#__PURE__*/Object.freeze({ + CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, + NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, + EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, + LANGUAGE: LANGUAGE, + SHOW_NSFW: SHOW_NSFW, + SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, + INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, + INSTANT_PURCHASE_MAX: INSTANT_PURCHASE_MAX, + THEME: THEME, + THEMES: THEMES, + AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED, + BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, + FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, + KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING +}); + +// eslint-disable-next-line import/prefer-default-export +const ALL = 'all'; +const SPEND = 'spend'; +const RECEIVE = 'receive'; +const PUBLISH = 'publish'; +const CHANNEL = 'channel'; +const TIP = 'tip'; +const SUPPORT = 'support'; +const UPDATE = 'update'; +const ABANDON = 'abandon'; + +var transaction_types = /*#__PURE__*/Object.freeze({ + ALL: ALL, + SPEND: SPEND, + RECEIVE: RECEIVE, + PUBLISH: PUBLISH, + CHANNEL: CHANNEL, + TIP: TIP, + SUPPORT: SUPPORT, + UPDATE: UPDATE, + ABANDON: ABANDON +}); + +const DATE_NEW = 'dateNew'; +const DATE_OLD = 'dateOld'; +const TITLE = 'title'; +const FILENAME = 'filename'; + +var sort_options = /*#__PURE__*/Object.freeze({ + DATE_NEW: DATE_NEW, + DATE_OLD: DATE_OLD, + TITLE: TITLE, + FILENAME: FILENAME +}); + +const AUTH = 'auth'; +const BACKUP = 'backup'; +const CHANNEL$1 = 'channel'; +const DISCOVER = 'discover'; +const FILE = 'file'; +const DOWNLOADED = 'downloaded'; +const PUBLISHED = 'published'; +const GET_CREDITS = 'getcredits'; +const HELP = 'help'; +const INVITE = 'invite'; +const PUBLISH$1 = 'publish'; +const REPORT = 'report'; +const REWARDS = 'rewards'; +const SEARCH = 'search'; +const SEND_CREDITS = 'send'; +const SETTINGS = 'settings'; +const SHOW = 'show'; +const SUBSCRIPTIONS = 'subscriptions'; +const TRANSACTION_HISTORY = 'history'; +const HISTORY = 'user_history'; +const WALLET = 'wallet'; + +var pages = /*#__PURE__*/Object.freeze({ + AUTH: AUTH, + BACKUP: BACKUP, + CHANNEL: CHANNEL$1, + DISCOVER: DISCOVER, + FILE: FILE, + DOWNLOADED: DOWNLOADED, + PUBLISHED: PUBLISHED, + GET_CREDITS: GET_CREDITS, + HELP: HELP, + INVITE: INVITE, + PUBLISH: PUBLISH$1, + REPORT: REPORT, + REWARDS: REWARDS, + SEARCH: SEARCH, + SEND_CREDITS: SEND_CREDITS, + SETTINGS: SETTINGS, + SHOW: SHOW, + SUBSCRIPTIONS: SUBSCRIPTIONS, + TRANSACTION_HISTORY: TRANSACTION_HISTORY, + HISTORY: HISTORY, + WALLET: WALLET +}); + +const SEARCH_TYPES = { + FILE: 'file', + CHANNEL: 'channel', + SEARCH: 'search' +}; + +const SEARCH_OPTIONS = { + RESULT_COUNT: 'size', + CLAIM_TYPE: 'claimType', + INCLUDE_FILES: 'file', + INCLUDE_CHANNELS: 'channel', + INCLUDE_FILES_AND_CHANNELS: 'file,channel', + MEDIA_AUDIO: 'audio', + MEDIA_VIDEO: 'video', + MEDIA_TEXT: 'text', + MEDIA_IMAGE: 'image', + MEDIA_APPLICATION: 'application' +}; + +// + +const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; + +const Lbry = { + isConnected: false, + daemonConnectionString: 'http://localhost:5279', + pendingPublishTimeout: 20 * 60 * 1000 +}; + +function checkAndParse(response) { + if (response.status >= 200 && response.status < 300) { + return response.json(); + } + return response.json().then(json => { + let error; + if (json.error) { + const errorMessage = typeof json.error === 'object' ? json.error.message : json.error; + error = new Error(errorMessage); + } else { + error = new Error('Protocol error with unknown response signature'); + } + return Promise.reject(error); + }); +} + +function apiCall(method, params, resolve, reject) { + const counter = new Date().getTime(); + const options = { + method: 'POST', + body: JSON.stringify({ + jsonrpc: '2.0', + method, + params, + id: counter + }) + }; + + return fetch(Lbry.daemonConnectionString, options).then(checkAndParse).then(response => { + const error = response.error || response.result && response.result.error; + + if (error) { + return reject(error); + } + return resolve(response.result); + }).catch(reject); +} + +const daemonCallWithResult = (name, params = {}) => new Promise((resolve, reject) => { + apiCall(name, params, result => { + resolve(result); + }, reject); +}); + +// blobs +Lbry.blob_delete = (params = {}) => daemonCallWithResult('blob_delete', params); +Lbry.blob_list = (params = {}) => daemonCallWithResult('blob_list', params); + +// core +Lbry.status = (params = {}) => daemonCallWithResult('status', params); +Lbry.version = () => daemonCallWithResult('version', {}); +Lbry.file_delete = (params = {}) => daemonCallWithResult('file_delete', params); +Lbry.file_set_status = (params = {}) => daemonCallWithResult('file_set_status', params); +Lbry.stop = () => daemonCallWithResult('stop', {}); + +// claims +Lbry.claim_list_by_channel = (params = {}) => daemonCallWithResult('claim_list_by_channel', params); + +// wallet +Lbry.account_balance = (params = {}) => daemonCallWithResult('account_balance', params); +Lbry.account_decrypt = () => daemonCallWithResult('account_decrypt', {}); +Lbry.account_encrypt = (params = {}) => daemonCallWithResult('account_encrypt', params); +Lbry.account_list = (params = {}) => daemonCallWithResult('account_list', params); +Lbry.address_is_mine = (params = {}) => daemonCallWithResult('address_is_mine', params); +Lbry.wallet_lock = () => daemonCallWithResult('wallet_lock', {}); +Lbry.address_unused = (params = {}) => daemonCallWithResult('address_unused', params); +Lbry.wallet_send = (params = {}) => daemonCallWithResult('wallet_send', params); +Lbry.account_unlock = (params = {}) => daemonCallWithResult('account_unlock', params); +Lbry.address_unused = () => daemonCallWithResult('address_unused', {}); +Lbry.claim_tip = (params = {}) => daemonCallWithResult('claim_tip', params); + +// transactions +Lbry.transaction_list = (params = {}) => daemonCallWithResult('transaction_list', params); +Lbry.utxo_release = (params = {}) => daemonCallWithResult('utxo_release', params); + +Lbry.connectPromise = null; +Lbry.connect = () => { + if (Lbry.connectPromise === null) { + Lbry.connectPromise = new Promise((resolve, reject) => { + let tryNum = 0; + // Check every half second to see if the daemon is accepting connections + function checkDaemonStarted() { + tryNum += 1; + Lbry.status().then(resolve).catch(() => { + if (tryNum <= CHECK_DAEMON_STARTED_TRY_NUMBER) { + setTimeout(checkDaemonStarted, tryNum < 50 ? 400 : 1000); + } else { + reject(new Error('Unable to connect to LBRY')); + } + }); + } + + checkDaemonStarted(); + }); + } + + return Lbry.connectPromise; +}; + +Lbry.getMediaType = (contentType, extname) => { + if (extname) { + const formats = [[/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/^(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/^(stl|obj|fbx|gcode)$/i, '3D-file']]; + const res = formats.reduce((ret, testpair) => { + switch (testpair[0].test(ret)) { + case true: + return testpair[1]; + default: + return ret; + } + }, extname); + return res === extname ? 'unknown' : res; + } else if (contentType) { + return (/^[^/]+/.exec(contentType)[0] + ); + } + return 'unknown'; +}; + +/** + * Wrappers for API methods to simulate missing or future behavior. Unlike the old-style stubs, + * these are designed to be transparent wrappers around the corresponding API methods. + */ + +/** + * Returns results from the file_list API method, plus dummy entries for pending publishes. + * (If a real publish with the same name is found, the pending publish will be ignored and removed.) + */ +Lbry.file_list = (params = {}) => new Promise((resolve, reject) => { + apiCall('file_list', params, fileInfos => { + resolve(fileInfos); + }, reject); +}); + +Lbry.claim_list_mine = (params = {}) => new Promise((resolve, reject) => { + apiCall('claim_list_mine', params, claims => { + resolve(claims); + }, reject); +}); + +Lbry.get = (params = {}) => new Promise((resolve, reject) => { + apiCall('get', params, streamInfo => { + resolve(streamInfo); + }, reject); +}); + +Lbry.resolve = (params = {}) => new Promise((resolve, reject) => { + apiCall('resolve', params, data => { + resolve(data || {}); + }, reject); +}); + +Lbry.publish = (params = {}) => new Promise((resolve, reject) => { + if (Lbry.overrides.publish) { + Lbry.overrides.publish(params).then(resolve, reject); + } else { + apiCall('publish', params, resolve, reject); + } +}); + +// Allow overriding Lbry methods +Lbry.overrides = {}; +Lbry.setOverride = (methodName, newMethod) => { + Lbry.overrides[methodName] = newMethod; +}; + +// Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) +Lbry.setDaemonConnectionString = value => { + Lbry.daemonConnectionString = value; +}; + +const lbryProxy = new Proxy(Lbry, { + get(target, name) { + if (name in target) { + return target[name]; + } + + return (params = {}) => new Promise((resolve, reject) => { + apiCall(name, params, resolve, reject); + }); + } +}); + +// + +const DEFAULT_SEARCH_RESULT_FROM = 0; +const DEFAULT_SEARCH_SIZE = 20; + +function parseQueryParams(queryString) { + if (queryString === '') return {}; + const parts = queryString.split('?').pop().split('&').map(p => p.split('=')); + + const params = {}; + parts.forEach(array => { + const [first, second] = array; + params[first] = second; + }); + return params; +} + +function toQueryString(params) { + if (!params) return ''; + + const parts = []; + Object.keys(params).forEach(key => { + if (Object.prototype.hasOwnProperty.call(params, key) && params[key]) { + parts.push(`${key}=${params[key]}`); + } + }); + + return parts.join('&'); +} + +const getSearchQueryString = (query, options = {}, includeUserOptions = false) => { + const encodedQuery = encodeURIComponent(query); + const queryParams = [`s=${encodedQuery}`, `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`]; + + if (includeUserOptions) { + queryParams.push(`claimType=${options[SEARCH_OPTIONS.CLAIM_TYPE]}`); + + // If they are only searching for channels, strip out the media info + if (options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_CHANNELS) { + queryParams.push(`mediaType=${[SEARCH_OPTIONS.MEDIA_FILE, SEARCH_OPTIONS.MEDIA_AUDIO, SEARCH_OPTIONS.MEDIA_VIDEO, SEARCH_OPTIONS.MEDIA_TEXT, SEARCH_OPTIONS.MEDIA_IMAGE, SEARCH_OPTIONS.MEDIA_APPLICATION].reduce((acc, currentOption) => options[currentOption] ? `${acc}${currentOption},` : acc, '')}`); + } + } + + return queryParams.join('&'); +}; + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const channelNameMinLength = 1; +const claimIdMaxLength = 40; + +const regexInvalidURI = /[^A-Za-z0-9-]/g; +const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; + +/** + * Parses a LBRY name into its component parts. Throws errors with user-friendly + * messages for invalid names. + * + * N.B. that "name" indicates the value in the name position of the URI. For + * claims for channel content, this will actually be the channel name, and + * the content name is in the path (e.g. lbry://@channel/content) + * + * In most situations, you'll want to use the contentName and channelName keys + * and ignore the name key. + * + * Returns a dictionary with keys: + * - name (string): The value in the "name" position in the URI. Note that this + * could be either content name or channel name; see above. + * - path (string, if persent) + * - claimSequence (int, if present) + * - bidPosition (int, if present) + * - claimId (string, if present) + * - isChannel (boolean) + * - contentName (string): For anon claims, the name; for channel claims, the path + * - channelName (string, if present): Channel name without @ + */ +function parseURI(URI, requireProto = false) { + // Break into components. Empty sub-matches are converted to null + const componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol + '([^:$#/]*)' + // claim name (stops at the first separator or end) + '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) + '(/?)(.*)' // path separator, path + ); + const [proto, claimName, modSep, modVal, pathSep, path] = componentsRegex.exec(URI).slice(1).map(match => match || null); + + let contentName; + + // Validate protocol + if (requireProto && !proto) { + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + } + + // Validate and process name + if (!claimName) { + throw new Error(__('URI does not include name.')); + } + + const isChannel = claimName.startsWith('@'); + const channelName = isChannel ? claimName.slice(1) : claimName; + + if (isChannel) { + if (!channelName) { + throw new Error(__('No channel name after @.')); + } + + if (channelName.length < channelNameMinLength) { + throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + } + + contentName = path; + } + + const nameBadChars = (channelName || claimName).match(regexInvalidURI); + if (nameBadChars) { + throw new Error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); + } + + // Validate and process modifier (claim ID, bid position or claim sequence) + let claimId; + let claimSequence; + let bidPosition; + if (modSep) { + if (!modVal) { + throw new Error(__(`No modifier provided after separator %s.`, modSep)); + } + + if (modSep === '#') { + claimId = modVal; + } else if (modSep === ':') { + claimSequence = modVal; + } else if (modSep === '$') { + bidPosition = modVal; + } + } + + if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { + throw new Error(__(`Invalid claim ID %s.`, claimId)); + } + + if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Claim sequence must be a number.')); + } + + if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Bid position must be a number.')); + } + + // Validate and process path + if (path) { + if (!isChannel) { + throw new Error(__('Only channel URIs may have a path.')); + } + + const pathBadChars = path.match(regexInvalidURI); + if (pathBadChars) { + throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); + } + + contentName = path; + } else if (pathSep) { + throw new Error(__('No path provided after /')); + } + + return _extends({ + claimName, + path, + isChannel + }, contentName ? { contentName } : {}, channelName ? { channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId } : {}, path ? { path } : {}); +} + +/** + * Takes an object in the same format returned by parse() and builds a URI. + * + * The channelName key will accept names with or without the @ prefix. + */ +function buildURI(URIObj, includeProto = true, protoDefault = 'lbry://') { + const { claimId, claimSequence, bidPosition, contentName, channelName } = URIObj; + + let { claimName, path } = URIObj; + + if (channelName) { + const channelNameFormatted = channelName.startsWith('@') ? channelName : `@${channelName}`; + if (!claimName) { + claimName = channelNameFormatted; + } else if (claimName !== channelNameFormatted) { + throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); + } + } + + if (contentName) { + if (!claimName) { + claimName = contentName; + } else if (!path) { + path = contentName; + } + if (path && path !== contentName) { + throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); + } + } + + return (includeProto ? protoDefault : '') + claimName + (claimId ? `#${claimId}` : '') + (claimSequence ? `:${claimSequence}` : '') + (bidPosition ? `${bidPosition}` : '') + (path ? `/${path}` : ''); +} + +/* Takes a parseable LBRY URI and converts it to standard, canonical format */ +function normalizeURI(URI) { + const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); + return buildURI({ claimName, path, claimSequence, bidPosition, claimId }); +} + +function isURIValid(URI) { + let parts; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.claimName; +} + +function isNameValid(claimName, checkCase = true) { + const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); + return regexp.test(claimName); +} + +function isURIClaimable(URI) { + let parts; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; +} + +function convertToShareLink(URI) { + const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); + return buildURI({ claimName, path, claimSequence, bidPosition, claimId }, true, 'https://open.lbry.io/'); +} + +var _extends$1 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const selectState = state => state.search; + +const selectSearchValue = reselect.createSelector(selectState, state => state.searchQuery); + +const selectSearchOptions = reselect.createSelector(selectState, state => state.options); + +const selectSuggestions = reselect.createSelector(selectState, state => state.suggestions); + +const selectIsSearching = reselect.createSelector(selectState, state => state.searching); + +const selectSearchUrisByQuery = reselect.createSelector(selectState, state => state.urisByQuery); + +const makeSelectSearchUris = query => +// replace statement below is kind of ugly, and repeated in doSearch action +reselect.createSelector(selectSearchUrisByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]); + +const selectSearchBarFocused = reselect.createSelector(selectState, state => state.focused); + +const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selectSuggestions, (query, suggestions) => { + if (!query) { + return []; + } + + const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://'; + + if (query.startsWith('lbry://') && query !== 'lbry://') { + // If it starts with a prefix, don't show any autocomplete results + // They are probably typing/pasting in a lbry uri + return [{ + value: query, + type: SEARCH_TYPES.FILE + }]; + } else if (queryIsPrefix) { + // If it is a prefix, wait until something else comes to figure out what to do + return []; + } + + let searchSuggestions = []; + try { + const uri = normalizeURI(query); + const { claimName, isChannel } = parseURI(uri); + searchSuggestions.push({ + value: claimName, + type: SEARCH_TYPES.SEARCH + }, { + value: uri, + shorthand: isChannel ? claimName.slice(1) : claimName, + type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE + }); + } catch (e) { + searchSuggestions.push({ + value: query, + type: SEARCH_TYPES.SEARCH + }); + } + + const apiSuggestions = suggestions[query] || []; + if (apiSuggestions.length) { + searchSuggestions = searchSuggestions.concat(apiSuggestions.filter(suggestion => suggestion !== query).map(suggestion => { + // determine if it's a channel + try { + const uri = normalizeURI(suggestion); + const { claimName, isChannel } = parseURI(uri); + + return { + value: uri, + shorthand: isChannel ? claimName.slice(1) : claimName, + type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE + }; + } catch (e) { + // search result includes some character that isn't valid in claim names + return { + value: suggestion, + type: SEARCH_TYPES.SEARCH + }; + } + })); + } + + return searchSuggestions; +}); + +// Creates a query string based on the state in the search reducer +// Can be overrided by passing in custom sizes/from values for other areas pagination +const makeSelectQueryWithOptions = (customQuery, customSize, customFrom, isBackgroundSearch = false // If it's a background search, don't use the users settings +) => reselect.createSelector(selectSearchValue, selectSearchOptions, (query, options) => { + const size = customSize || options[SEARCH_OPTIONS.RESULT_COUNT]; + + const queryString = getSearchQueryString(customQuery || query, _extends$1({}, options, { size, from: customFrom }), !isBackgroundSearch); + + return queryString; +}); + +// + +function doToast(params) { + if (!params) { + throw Error("'params' object is required to create a toast notification"); + } + + return { + type: CREATE_TOAST, + data: { + id: uuid(), + params + } + }; +} + +function doDismissToast() { + return { + type: DISMISS_TOAST + }; +} + +function doError(error) { + return { + type: CREATE_ERROR, + data: { + error + } + }; +} + +function doDismissError() { + return { + type: DISMISS_ERROR + }; +} + +const isClaimNsfw = claim => claim && claim.value && claim.value.stream && claim.value.stream.metadata.nsfw; + +const selectState$1 = state => state.claims || {}; + +const selectClaimsById = reselect.createSelector(selectState$1, state => state.byId || {}); + +const selectCurrentChannelPage = reselect.createSelector(selectState$1, state => state.currentChannelPage || 1); + +const selectClaimsByUri = reselect.createSelector(selectState$1, selectClaimsById, (state, byId) => { + const byUri = state.claimsByUri || {}; + const claims = {}; + + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; + + // NOTE returning a null claim allows us to differentiate between an + // undefined (never fetched claim) and one which just doesn't exist. Not + // the cleanest solution but couldn't think of anything better right now + if (claimId === null) { + claims[uri] = null; + } else { + claims[uri] = byId[claimId]; + } + }); + + return claims; +}); + +const selectAllClaimsByChannel = reselect.createSelector(selectState$1, state => state.claimsByChannel || {}); + +const selectPendingById = reselect.createSelector(selectState$1, state => state.pendingById || {}); + +const selectPendingClaims = reselect.createSelector(selectState$1, state => Object.values(state.pendingById || [])); + +const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { + const { claimId } = parseURI(uri); + return Boolean(pendingById[claimId]); +}); + +const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { + const { claimId } = parseURI(uri); + return pendingById[claimId]; +}); + +const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { + // Check if a claim is pending first + // It won't be in claimsByUri because resolving it will return nothing + const { claimId } = parseURI(uri); + const pendingClaim = pendingById[claimId]; + if (pendingClaim) { + return pendingClaim; + } + + return byUri && byUri[normalizeURI(uri)]; +}); + +const selectMyClaimsRaw = reselect.createSelector(selectState$1, state => state.myClaims); + +const selectAbandoningIds = reselect.createSelector(selectState$1, state => Object.keys(state.abandoningById || {})); + +const selectMyActiveClaims = reselect.createSelector(selectMyClaimsRaw, selectAbandoningIds, (claims, abandoningIds) => new Set(claims && claims.map(claim => claim.claim_id).filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1))); + +const makeSelectClaimIsMine = rawUri => { + const uri = normalizeURI(rawUri); + return reselect.createSelector(selectClaimsByUri, selectMyActiveClaims, (claims, myClaims) => claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id)); +}; + +const selectAllFetchingChannelClaims = reselect.createSelector(selectState$1, state => state.fetchingChannelClaims || {}); + +const makeSelectFetchingChannelClaims = uri => reselect.createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); + +const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { + const byChannel = allClaims[uri] || {}; + const claimIds = byChannel[page || 1]; + + if (!claimIds) return claimIds; + + return claimIds.map(claimId => byId[claimId]); +}); + +const makeSelectClaimsInChannelForCurrentPageState = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, (byId, allClaims, page) => { + const byChannel = allClaims[uri] || {}; + const claimIds = byChannel[page || 1]; + + if (!claimIds) return claimIds; + + return claimIds.map(claimId => byId[claimId]); +}); + +const makeSelectMetadataForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; + + return metadata || (claim === undefined ? undefined : null); +}); + +const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); + +const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + const source = claim && claim.value && claim.value.stream && claim.value.stream.source; + return source ? source.contentType : undefined; +}); + +const selectIsFetchingClaimListMine = reselect.createSelector(selectState$1, state => state.isFetchingClaimListMine); + +const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { + const claims = []; + + myClaimIds.forEach(id => { + const claim = byId[id]; + + if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); + }); + + return [...claims, ...pendingClaims]; +}); + +const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/))); + +const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); + +const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims => { + const outpoints = []; + + myClaims.forEach(claim => outpoints.push(`${claim.txid}:${claim.nout}`)); + + return outpoints; +}); + +const selectFetchingMyChannels = reselect.createSelector(selectState$1, state => state.fetchingMyChannels); + +const selectMyChannelClaims = reselect.createSelector(selectState$1, selectClaimsById, (state, byId) => { + const ids = state.myChannelClaims || []; + const claims = []; + + ids.forEach(id => { + if (byId[id]) { + // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 + claims.push(byId[id]); + } + }); + + return claims; +}); + +const selectResolvingUris = reselect.createSelector(selectState$1, state => state.resolvingUris || []); + +const makeSelectIsUriResolving = uri => reselect.createSelector(selectResolvingUris, resolvingUris => resolvingUris && resolvingUris.indexOf(uri) !== -1); + +const selectPlayingUri = reselect.createSelector(selectState$1, state => state.playingUri); + +const selectChannelClaimCounts = reselect.createSelector(selectState$1, state => state.channelClaimCounts || {}); + +const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]); + +const makeSelectTotalPagesForChannel = (uri, pageSize = 10) => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize)); + +const makeSelectNsfwCountFromUris = uris => reselect.createSelector(selectClaimsByUri, claims => uris.reduce((acc, uri) => { + const claim = claims[uri]; + if (isClaimNsfw(claim)) { + return acc + 1; + } + return acc; +}, 0)); + +const makeSelectNsfwCountForChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, (byId, allClaims, page) => { + const byChannel = allClaims[uri] || {}; + const claimIds = byChannel[page || 1]; + + if (!claimIds) return 0; + + return claimIds.reduce((acc, claimId) => { + const claim = byId[claimId]; + if (isClaimNsfw(claim)) { + return acc + 1; + } + return acc; + }, 0); +}); + +const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectSearchUrisByQuery, (claim, searchUrisByQuery) => { + const atVanityURI = !uri.includes('#'); + + let recommendedContent; + if (claim) { + // If we are at a vanity uri, build the full uri so we can properly filter + const currentUri = atVanityURI ? buildURI({ claimId: claim.claim_id, claimName: claim.name }) : uri; + + const { title } = claim.value.stream.metadata; + + const searchQuery = getSearchQueryString(title.replace(/\//, ' ')); + + let searchUris = searchUrisByQuery[searchQuery]; + if (searchUris) { + searchUris = searchUris.filter(searchUri => searchUri !== currentUri); + recommendedContent = searchUris; + } + } + + return recommendedContent; +}); + +const makeSelectFirstRecommendedFileForUri = uri => reselect.createSelector(makeSelectRecommendedContentForUri(uri), recommendedContent => recommendedContent ? recommendedContent[0] : null); + +// Returns the associated channel uri for a given claim uri +const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + if (!claim) { + return null; + } + + const { channel_name: channelName, value } = claim; + const channelClaimId = value && value.publisherSignature && value.publisherSignature.certificateId; + + return channelName && channelClaimId ? buildURI({ channelName, claimId: channelClaimId }, includePrefix) : null; +}); + +const selectState$2 = state => state.wallet || {}; + +const selectWalletState = selectState$2; + +const selectWalletIsEncrypted = reselect.createSelector(selectState$2, state => state.walletIsEncrypted); + +const selectWalletEncryptPending = reselect.createSelector(selectState$2, state => state.walletEncryptPending); + +const selectWalletEncryptSucceeded = reselect.createSelector(selectState$2, state => state.walletEncryptSucceded); + +const selectWalletEncryptResult = reselect.createSelector(selectState$2, state => state.walletEncryptResult); + +const selectWalletDecryptPending = reselect.createSelector(selectState$2, state => state.walletDecryptPending); + +const selectWalletDecryptSucceeded = reselect.createSelector(selectState$2, state => state.walletDecryptSucceded); + +const selectWalletDecryptResult = reselect.createSelector(selectState$2, state => state.walletDecryptResult); + +const selectWalletUnlockPending = reselect.createSelector(selectState$2, state => state.walletUnlockPending); + +const selectWalletUnlockSucceeded = reselect.createSelector(selectState$2, state => state.walletUnlockSucceded); + +const selectWalletUnlockResult = reselect.createSelector(selectState$2, state => state.walletUnlockResult); + +const selectWalletLockPending = reselect.createSelector(selectState$2, state => state.walletLockPending); + +const selectWalletLockSucceeded = reselect.createSelector(selectState$2, state => state.walletLockSucceded); + +const selectWalletLockResult = reselect.createSelector(selectState$2, state => state.walletLockResult); + +const selectBalance = reselect.createSelector(selectState$2, state => state.balance); + +const selectTransactionsById = reselect.createSelector(selectState$2, state => state.transactions); + +const selectTransactionItems = reselect.createSelector(selectTransactionsById, byId => { + const items = []; + + Object.keys(byId).forEach(txid => { + const tx = byId[txid]; + + // ignore dust/fees + // it is fee only txn if all infos are also empty + if (Math.abs(tx.value) === Math.abs(tx.fee) && tx.claim_info.length === 0 && tx.support_info.length === 0 && tx.update_info.length === 0 && tx.abandon_info.length === 0) { + return; + } + + const append = []; + + append.push(...tx.claim_info.map(item => Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? CHANNEL : PUBLISH + }))); + append.push(...tx.support_info.map(item => Object.assign({}, tx, item, { + type: !item.is_tip ? SUPPORT : TIP + }))); + append.push(...tx.update_info.map(item => Object.assign({}, tx, item, { type: UPDATE }))); + append.push(...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: ABANDON }))); + + if (!append.length) { + append.push(Object.assign({}, tx, { + type: tx.value < 0 ? SPEND : RECEIVE + })); + } + + items.push(...append.map(item => { + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value + const balanceDelta = parseFloat(item.balance_delta); + const value = parseFloat(item.value); + const amount = balanceDelta || value; + const fee = parseFloat(tx.fee); + + return { + txid, + timestamp: tx.timestamp, + date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, + amount, + fee, + claim_id: item.claim_id, + claim_name: item.claim_name, + type: item.type || SPEND, + nout: item.nout, + confirmations: tx.confirmations + }; + })); + }); + + return items.sort((tx1, tx2) => { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } + + return tx2.timestamp - tx1.timestamp; + }); +}); + +const selectRecentTransactions = reselect.createSelector(selectTransactionItems, transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } + + return transaction.date > threshold; + }); +}); + +const selectHasTransactions = reselect.createSelector(selectTransactionItems, transactions => transactions && transactions.length > 0); + +const selectIsFetchingTransactions = reselect.createSelector(selectState$2, state => state.fetchingTransactions); + +const selectIsSendingSupport = reselect.createSelector(selectState$2, state => state.sendingSupport); + +const selectReceiveAddress = reselect.createSelector(selectState$2, state => state.receiveAddress); + +const selectGettingNewAddress = reselect.createSelector(selectState$2, state => state.gettingNewAddress); + +const selectDraftTransaction = reselect.createSelector(selectState$2, state => state.draftTransaction || {}); + +const selectDraftTransactionAmount = reselect.createSelector(selectDraftTransaction, draft => draft.amount); + +const selectDraftTransactionAddress = reselect.createSelector(selectDraftTransaction, draft => draft.address); + +const selectDraftTransactionError = reselect.createSelector(selectDraftTransaction, draft => draft.error); + +const selectBlocks = reselect.createSelector(selectState$2, state => state.blocks); + +const selectCurrentHeight = reselect.createSelector(selectState$2, state => state.latestBlock); + +const makeSelectBlockDate = block => reselect.createSelector(selectBlocks, selectCurrentHeight, (blocks, latestBlock) => { + // If we have the block data, look at the actual date, + // If not, try to simulate it based on 2.5 minute blocks + // Adding this on 11/7/2018 because caling block_show for every claim is causing + // performance issues. + if (blocks && blocks[block]) { + return new Date(blocks[block].time * 1000); + } + + // Pending claim + if (block < 1) { + return null; + } + + const difference = latestBlock - block; + const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms + const publishDate = Date.now() - msSincePublish; + return new Date(publishDate); +}); + +const selectTransactionListFilter = reselect.createSelector(selectState$2, state => state.transactionListFilter || ''); + +function formatCredits(amount, precision) { + if (Number.isNaN(parseFloat(amount))) return '0'; + return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); +} + +function formatFullPrice(amount, precision = 1) { + let formated = ''; + + const quantity = amount.toString().split('.'); + const fraction = quantity[1]; + + if (fraction) { + const decimals = fraction.split(''); + const first = decimals.filter(number => number !== '0')[0]; + const index = decimals.indexOf(first); + + // Set format fraction + formated = `.${fraction.substring(0, index + precision)}`; + } + + return parseFloat(quantity[0] + formated); +} + +function creditsToString(amount) { + const creditString = parseFloat(amount).toFixed(8); + return creditString; +} + +function doUpdateBalance() { + return (dispatch, getState) => { + const { + wallet: { balance: balanceInStore } + } = getState(); + lbryProxy.account_balance().then(balanceAsString => { + const balance = parseFloat(balanceAsString); + + if (balanceInStore !== balance) { + dispatch({ + type: UPDATE_BALANCE, + data: { + balance + } + }); + } + }); + }; +} + +function doBalanceSubscribe() { + return dispatch => { + dispatch(doUpdateBalance()); + setInterval(() => dispatch(doUpdateBalance()), 5000); + }; +} + +function doFetchTransactions() { + return dispatch => { + dispatch({ + type: FETCH_TRANSACTIONS_STARTED + }); + + lbryProxy.utxo_release().then(() => lbryProxy.transaction_list()).then(results => { + dispatch({ + type: FETCH_TRANSACTIONS_COMPLETED, + data: { + transactions: results + } + }); + }); + }; +} + +function doFetchBlock(height) { + return dispatch => { + lbryProxy.block_show({ height }).then(block => { + dispatch({ + type: FETCH_BLOCK_SUCCESS, + data: { block } + }); + }); + }; +} + +function doGetNewAddress() { + return dispatch => { + dispatch({ + type: GET_NEW_ADDRESS_STARTED + }); + + // Removed localStorage use, since address is expected to be stored in redux store + lbryProxy.address_unused().then(address => { + dispatch({ + type: GET_NEW_ADDRESS_COMPLETED, + data: { address } + }); + }); + }; +} + +function doCheckAddressIsMine(address) { + return dispatch => { + dispatch({ + type: CHECK_ADDRESS_IS_MINE_STARTED + }); + + lbryProxy.address_is_mine({ address }).then(isMine => { + if (!isMine) dispatch(doGetNewAddress()); + + dispatch({ + type: CHECK_ADDRESS_IS_MINE_COMPLETED + }); + }); + }; +} + +function doSendDraftTransaction(address, amount) { + return (dispatch, getState) => { + const state = getState(); + const balance = selectBalance(state); + + if (balance - amount <= 0) { + dispatch(doToast({ + title: 'Insufficient credits', + message: 'Insufficient credits' + })); + return; + } + + dispatch({ + type: SEND_TRANSACTION_STARTED + }); + + const successCallback = response => { + if (response.txid) { + dispatch({ + type: SEND_TRANSACTION_COMPLETED + }); + dispatch(doToast({ + message: `You sent ${amount} LBC`, + linkText: 'History', + linkTarget: '/wallet' + })); + } else { + dispatch({ + type: SEND_TRANSACTION_FAILED, + data: { error: response } + }); + dispatch(doToast({ + message: 'Transaction failed', + isError: true + })); + } + }; + + const errorCallback = error => { + dispatch({ + type: SEND_TRANSACTION_FAILED, + data: { error: error.message } + }); + dispatch(doToast({ + message: 'Transaction failed', + isError: true + })); + }; + + lbryProxy.wallet_send({ + address, + amount: creditsToString(amount) + }).then(successCallback, errorCallback); + }; +} + +function doSetDraftTransactionAmount(amount) { + return { + type: SET_DRAFT_TRANSACTION_AMOUNT, + data: { amount } + }; +} + +function doSetDraftTransactionAddress(address) { + return { + type: SET_DRAFT_TRANSACTION_ADDRESS, + data: { address } + }; +} + +function doSendTip(amount, claimId, uri, successCallback, errorCallback) { + return (dispatch, getState) => { + const state = getState(); + const balance = selectBalance(state); + + if (balance - amount <= 0) { + dispatch(doToast({ + message: 'Insufficient credits', + isError: true + })); + return; + } + + const success = () => { + dispatch(doToast({ + message: __(`You sent ${amount} LBC as a tip, Mahalo!`), + linkText: __('History'), + linkTarget: __('/wallet') + })); + + dispatch({ + type: SUPPORT_TRANSACTION_COMPLETED + }); + + if (successCallback) { + successCallback(); + } + }; + + const error = err => { + dispatch(doToast({ + message: __(`There was an error sending support funds.`), + isError: true + })); + + dispatch({ + type: SUPPORT_TRANSACTION_FAILED, + data: { + error: err + } + }); + + if (errorCallback) { + errorCallback(); + } + }; + + dispatch({ + type: SUPPORT_TRANSACTION_STARTED + }); + + lbryProxy.claim_tip({ + claim_id: claimId, + amount: creditsToString(amount) + }).then(success, error); + }; +} + +function doWalletEncrypt(newPassword) { + return dispatch => { + dispatch({ + type: WALLET_ENCRYPT_START + }); + + lbryProxy.account_encrypt({ new_password: newPassword }).then(result => { + if (result === true) { + dispatch({ + type: WALLET_ENCRYPT_COMPLETED, + result + }); + } else { + dispatch({ + type: WALLET_ENCRYPT_FAILED, + result + }); + } + }); + }; +} + +function doWalletUnlock(password) { + return dispatch => { + dispatch({ + type: WALLET_UNLOCK_START + }); + + lbryProxy.account_unlock({ password }).then(result => { + if (result === true) { + dispatch({ + type: WALLET_UNLOCK_COMPLETED, + result + }); + } else { + dispatch({ + type: WALLET_UNLOCK_FAILED, + result + }); + } + }); + }; +} + +function doWalletDecrypt() { + return dispatch => { + dispatch({ + type: WALLET_DECRYPT_START + }); + + lbryProxy.account_decrypt().then(result => { + if (result === true) { + dispatch({ + type: WALLET_DECRYPT_COMPLETED, + result + }); + } else { + dispatch({ + type: WALLET_DECRYPT_FAILED, + result + }); + } + }); + }; +} + +function doWalletStatus() { + return dispatch => { + dispatch({ + type: WALLET_STATUS_START + }); + + lbryProxy.status().then(status => { + if (status && status.wallet) { + dispatch({ + type: WALLET_STATUS_COMPLETED, + result: status.wallet.is_encrypted + }); + } + }); + }; +} + +function doSetTransactionListFilter(filterOption) { + return { + type: SET_TRANSACTION_LIST_FILTER, + data: filterOption + }; +} + +function doUpdateBlockHeight() { + return dispatch => lbryProxy.status().then(status => { + if (status.wallet) { + dispatch({ + type: UPDATE_CURRENT_HEIGHT, + data: status.wallet.blocks + }); + } + }); +} + +function doResolveUris(uris, returnCachedClaims = false) { + return (dispatch, getState) => { + const normalizedUris = uris.map(normalizeURI); + const state = getState(); + + const resolvingUris = selectResolvingUris(state); + const claimsByUri = selectClaimsByUri(state); + const urisToResolve = normalizedUris.filter(uri => { + if (resolvingUris.includes(uri)) { + return false; + } + + return returnCachedClaims ? !claimsByUri[uri] : true; + }); + + if (urisToResolve.length === 0) { + return; + } + + dispatch({ + type: RESOLVE_URIS_STARTED, + data: { uris: normalizedUris } + }); + + const resolveInfo = {}; + lbryProxy.resolve({ urls: urisToResolve }).then(result => { + Object.entries(result).forEach(([uri, uriResolveInfo]) => { + const fallbackResolveInfo = { + claim: null, + claimsInChannel: null, + certificate: null + }; + + const { claim, certificate, claims_in_channel: claimsInChannel } = uriResolveInfo && !uriResolveInfo.error ? uriResolveInfo : fallbackResolveInfo; + + resolveInfo[uri] = { claim, certificate, claimsInChannel }; + }); + + dispatch({ + type: RESOLVE_URIS_COMPLETED, + data: { resolveInfo } + }); + }); + }; +} + +function doResolveUri(uri) { + return doResolveUris([uri]); +} + +function doFetchClaimListMine() { + return dispatch => { + dispatch({ + type: FETCH_CLAIM_LIST_MINE_STARTED + }); + + lbryProxy.claim_list_mine().then(claims => { + dispatch({ + type: FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims + } + }); + }); + }; +} + +function doAbandonClaim(txid, nout) { + return (dispatch, getState) => { + const state = getState(); + const myClaims = selectMyClaimsRaw(state); + const { claim_id: claimId } = myClaims.find(claim => claim.txid === txid && claim.nout === nout); + + dispatch({ + type: ABANDON_CLAIM_STARTED, + data: { + claimId + } + }); + + const errorCallback = () => { + dispatch(doToast({ + message: 'Transaction failed', + isError: true + })); + }; + + const successCallback = results => { + if (results.success === true) { + dispatch({ + type: ABANDON_CLAIM_SUCCEEDED, + data: { + claimId + } + }); + dispatch(doToast({ + message: 'Successfully abandoned your claim' + })); + + // After abandoning, call claim_list_mine to show the claim as abandoned + // Also fetch transactions to show the new abandon transaction + dispatch(doFetchClaimListMine()); + dispatch(doFetchTransactions()); + } else { + dispatch(doToast({ + message: 'Error abandoning claim', + isError: true + })); + } + }; + + lbryProxy.claim_abandon({ + txid, + nout + }).then(successCallback, errorCallback); + }; +} + +function doFetchClaimsByChannel(uri, page) { + return dispatch => { + dispatch({ + type: FETCH_CHANNEL_CLAIMS_STARTED, + data: { uri, page } + }); + + lbryProxy.claim_list_by_channel({ uri, page: page || 1 }).then(result => { + const claimResult = result[uri] || {}; + const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; + + dispatch({ + type: FETCH_CHANNEL_CLAIMS_COMPLETED, + data: { + uri, + claims: claimsInChannel || [], + page: returnedPage || undefined + } + }); + }); + }; +} + +function doFetchClaimCountByChannel(uri) { + return dispatch => { + dispatch({ + type: FETCH_CHANNEL_CLAIM_COUNT_STARTED, + data: { uri } + }); + + lbryProxy.claim_list_by_channel({ uri }).then(result => { + const claimResult = result[uri]; + const totalClaims = claimResult ? claimResult.claims_in_channel : 0; + + dispatch({ + type: FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, + data: { + uri, + totalClaims + } + }); + }); + }; +} + +const selectState$3 = state => state.fileInfo || {}; + +const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); + +const selectIsFetchingFileList = reselect.createSelector(selectState$3, state => state.isFetchingFileList); + +const selectIsFetchingFileListDownloadedOrPublished = reselect.createSelector(selectIsFetchingFileList, selectIsFetchingClaimListMine, (isFetchingFileList, isFetchingClaimListMine) => isFetchingFileList || isFetchingClaimListMine); + +const makeSelectFileInfoForUri = uri => reselect.createSelector(selectClaimsByUri, selectFileInfosByOutpoint, (claims, byOutpoint) => { + const claim = claims[uri]; + const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; + return outpoint ? byOutpoint[outpoint] : undefined; +}); + +const selectDownloadingByOutpoint = reselect.createSelector(selectState$3, state => state.downloadingByOutpoint || {}); + +const makeSelectDownloadingForUri = uri => reselect.createSelector(selectDownloadingByOutpoint, makeSelectFileInfoForUri(uri), (byOutpoint, fileInfo) => { + if (!fileInfo) return false; + return byOutpoint[fileInfo.outpoint]; +}); + +const selectUrisLoading = reselect.createSelector(selectState$3, state => state.urisLoading || {}); + +const makeSelectLoadingForUri = uri => reselect.createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); + +const selectFileInfosDownloaded = reselect.createSelector(selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => Object.values(byOutpoint).filter(fileInfo => { + const myClaimIds = myClaims.map(claim => claim.claim_id); + + return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes); +})); + +// export const selectFileInfoForUri = (state, props) => { +// const claims = selectClaimsByUri(state), +// claim = claims[props.uri], +// fileInfos = selectAllFileInfos(state), +// outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; + +// return outpoint && fileInfos ? fileInfos[outpoint] : undefined; +// }; + +const selectDownloadingFileInfos = reselect.createSelector(selectDownloadingByOutpoint, selectFileInfosByOutpoint, (downloadingByOutpoint, fileInfosByOutpoint) => { + const outpoints = Object.keys(downloadingByOutpoint); + const fileInfos = []; + + outpoints.forEach(outpoint => { + const fileInfo = fileInfosByOutpoint[outpoint]; + + if (fileInfo) fileInfos.push(fileInfo); + }); + + return fileInfos; +}); + +const selectTotalDownloadProgress = reselect.createSelector(selectDownloadingFileInfos, fileInfos => { + const progress = []; + + fileInfos.forEach(fileInfo => { + progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100); + }); + + const totalProgress = progress.reduce((a, b) => a + b, 0); + + if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; + return -1; +}); + +const selectSearchDownloadUris = query => reselect.createSelector(selectFileInfosDownloaded, selectClaimsById, (fileInfos, claimsById) => { + if (!query || !fileInfos.length) { + return null; + } + + const queryParts = query.toLowerCase().split(' '); + const searchQueryDictionary = {}; + queryParts.forEach(subQuery => { + searchQueryDictionary[subQuery] = subQuery; + }); + + const arrayContainsQueryPart = array => { + for (let i = 0; i < array.length; i += 1) { + const subQuery = array[i]; + if (searchQueryDictionary[subQuery]) { + return true; + } + } + return false; + }; + + const downloadResultsFromQuery = []; + fileInfos.forEach(fileInfo => { + const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; + const { author, description, title } = metadata; + + if (channelName) { + const lowerCaseChannel = channelName.toLowerCase(); + const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ + if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { + downloadResultsFromQuery.push(fileInfo); + return; + } + } + + const nameParts = claimName.toLowerCase().split('-'); + if (arrayContainsQueryPart(nameParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } + + const titleParts = title.toLowerCase().split(' '); + if (arrayContainsQueryPart(titleParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } + + if (author) { + const authorParts = author.toLowerCase().split(' '); + if (arrayContainsQueryPart(authorParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } + } + + if (description) { + const descriptionParts = description.toLowerCase().split(' '); + if (arrayContainsQueryPart(descriptionParts)) { + downloadResultsFromQuery.push(fileInfo); + } + } + }); + + return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { + const { channel_name: channelName, claim_id: claimId, claim_name: claimName } = fileInfo; + + const uriParams = {}; + + if (channelName) { + const claim = claimsById[claimId]; + if (claim && claim.value) { + uriParams.claimId = claim.value.publisherSignature.certificateId; + } else { + uriParams.claimId = claimId; + } + uriParams.channelName = channelName; + uriParams.contentName = claimName; + } else { + uriParams.claimId = claimId; + uriParams.claimName = claimName; + } + + const uri = buildURI(uriParams); + return uri; + }) : null; +}); + +const selectFileListPublishedSort = reselect.createSelector(selectState$3, state => state.fileListPublishedSort); + +const selectFileListDownloadedSort = reselect.createSelector(selectState$3, state => state.fileListDownloadedSort); + +function doFetchFileInfo(uri) { + return (dispatch, getState) => { + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; + const outpoint = claim ? `${claim.txid}:${claim.nout}` : null; + const alreadyFetching = !!selectUrisLoading(state)[uri]; + + if (!alreadyFetching) { + dispatch({ + type: FETCH_FILE_INFO_STARTED, + data: { + outpoint + } + }); + + lbryProxy.file_list({ outpoint, full_status: true }).then(fileInfos => { + dispatch({ + type: FETCH_FILE_INFO_COMPLETED, + data: { + outpoint, + fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null + } + }); + }); + } + }; +} + +function doFileList() { + return (dispatch, getState) => { + const state = getState(); + const isFetching = selectIsFetchingFileList(state); + + if (!isFetching) { + dispatch({ + type: FILE_LIST_STARTED + }); + + lbryProxy.file_list().then(fileInfos => { + dispatch({ + type: FILE_LIST_SUCCEEDED, + data: { + fileInfos + } + }); + }); + } + }; +} + +function doFetchFileInfosAndPublishedClaims() { + return (dispatch, getState) => { + const state = getState(); + const isFetchingClaimListMine = selectIsFetchingClaimListMine(state); + const isFetchingFileInfo = selectIsFetchingFileList(state); + + if (!isFetchingClaimListMine) dispatch(doFetchClaimListMine()); + if (!isFetchingFileInfo) dispatch(doFileList()); + }; +} + +function doSetFileListSort(page, value) { + return { + type: SET_FILE_LIST_SORT, + data: { page, value } + }; +} + +// https://github.com/reactjs/redux/issues/911 +function batchActions(...actions) { + return { + type: 'BATCH_ACTIONS', + actions + }; +} + +// Returns a function, that, as long as it continues to be invoked, will not +// be triggered. The function will be called after it stops being called for +// N milliseconds. If `immediate` is passed, trigger the function on the +// leading edge, instead of the trailing. +function debouce(func, wait, immediate) { + let timeout; + + return function () { + const context = this; + const args = arguments; + const later = () => { + timeout = null; + if (!immediate) func.apply(context, args); + }; + + const callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} + +function handleFetchResponse(response) { + return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); +} + +// + +const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; + +// We can't use env's because they aren't passed into node_modules +let CONNECTION_STRING = 'https://lighthouse.lbry.io/'; + +const setSearchApi = endpoint => { + CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end; +}; + +const getSearchSuggestions = value => (dispatch, getState) => { + const query = value.trim(); + + // strip out any basic stuff for more accurate search results + let searchValue = query.replace(/lbry:\/\//g, '').replace(/-/g, ' '); + if (searchValue.includes('#')) { + // This should probably be more robust, but I think it's fine for now + // Remove everything after # to get rid of the claim id + searchValue = searchValue.substring(0, searchValue.indexOf('#')); + } + + const suggestions = selectSuggestions(getState()); + if (suggestions[searchValue]) { + return; + } + + fetch(`${CONNECTION_STRING}autocomplete?s=${searchValue}`).then(handleFetchResponse).then(apiSuggestions => { + dispatch({ + type: UPDATE_SEARCH_SUGGESTIONS, + data: { + query: searchValue, + suggestions: apiSuggestions + } + }); + }).catch(() => { + // If the fetch fails, do nothing + // Basic search suggestions are already populated at this point + }); +}; + +const throttledSearchSuggestions = debouce((dispatch, query) => { + dispatch(getSearchSuggestions(query)); +}, DEBOUNCED_SEARCH_SUGGESTION_MS); + +const doUpdateSearchQuery = (query, shouldSkipSuggestions) => dispatch => { + dispatch({ + type: UPDATE_SEARCH_QUERY, + data: { query } + }); + + // Don't fetch new suggestions if the user just added a space + if (!query.endsWith(' ') || !shouldSkipSuggestions) { + throttledSearchSuggestions(dispatch, query); + } +}; + +const doSearch = (rawQuery, // pass in a query if you don't want to search for what's in the search bar +size, // only pass in if you don't want to use the users setting (ex: related content) +from, isBackgroundSearch = false) => (dispatch, getState) => { + const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + + if (!query) { + dispatch({ + type: SEARCH_FAIL + }); + return; + } + + const state = getState(); + const queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch)(state); + + // If we have already searched for something, we don't need to do anything + const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); + if (urisForQuery && !!urisForQuery.length) { + return; + } + + dispatch({ + type: SEARCH_START + }); + + // If the user is on the file page with a pre-populated uri and they select + // the search option without typing anything, searchQuery will be empty + // We need to populate it so the input is filled on the search page + // isBackgroundSearch means the search is happening in the background, don't update the search query + if (!state.search.searchQuery && !isBackgroundSearch) { + dispatch(doUpdateSearchQuery(query)); + } + + fetch(`${CONNECTION_STRING}search?${queryWithOptions}`).then(handleFetchResponse).then(data => { + const uris = []; + const actions = []; + + data.forEach(result => { + const uri = buildURI({ + claimName: result.name, + claimId: result.claimId + }); + actions.push(doResolveUri(uri)); + uris.push(uri); + }); + + actions.push({ + type: SEARCH_SUCCESS, + data: { + query: queryWithOptions, + uris + } + }); + dispatch(batchActions(...actions)); + }).catch(() => { + dispatch({ + type: SEARCH_FAIL + }); + }); +}; + +const doFocusSearchInput = () => dispatch => dispatch({ + type: SEARCH_FOCUS +}); + +const doBlurSearchInput = () => dispatch => dispatch({ + type: SEARCH_BLUR +}); + +const doUpdateSearchOptions = newOptions => (dispatch, getState) => { + const state = getState(); + const searchValue = selectSearchValue(state); + + dispatch({ + type: UPDATE_SEARCH_OPTIONS, + data: newOptions + }); + + if (searchValue) { + // After updating, perform a search with the new options + dispatch(doSearch(searchValue)); + } +}; + +function savePosition(claimId, outpoint, position) { + return dispatch => { + dispatch({ + type: SET_CONTENT_POSITION, + data: { claimId, outpoint, position } + }); + }; +} + +const reducers = {}; + +const defaultState = { + channelClaimCounts: {} +}; + +reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { + const { resolveInfo } = action.data; + const byUri = Object.assign({}, state.claimsByUri); + const byId = Object.assign({}, state.byId); + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + + Object.entries(resolveInfo).forEach(([uri, { certificate, claimsInChannel }]) => { + if (certificate && !Number.isNaN(claimsInChannel)) { + channelClaimCounts[uri] = claimsInChannel; + } + }); + + Object.entries(resolveInfo).forEach(([uri, { certificate, claim }]) => { + if (claim) { + byId[claim.claim_id] = claim; + byUri[uri] = claim.claim_id; + } else if (claim === undefined && certificate !== undefined) { + byId[certificate.claim_id] = certificate; + // Don't point URI at the channel certificate unless it actually is + // a channel URI. This is brittle. + if (!uri.split(certificate.name)[1].match(/\//)) { + byUri[uri] = certificate.claim_id; + } else { + byUri[uri] = null; + } + } else { + byUri[uri] = null; + } + }); + + return Object.assign({}, state, { + byId, + claimsByUri: byUri, + channelClaimCounts, + resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]) + }); +}; + +reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { + isFetchingClaimListMine: true +}); + +reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { + const { claims } = action.data; + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const pendingById = Object.assign({}, state.pendingById); + + claims.forEach(claim => { + const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id }); + + if (claim.type && claim.type.match(/claim|update/)) { + if (claim.confirmations < 1) { + pendingById[claim.claim_id] = claim; + delete byId[claim.claim_id]; + delete byUri[claim.claim_id]; + } else { + byId[claim.claim_id] = claim; + byUri[uri] = claim.claim_id; + } + } + }); + + // Remove old pending publishes + Object.values(pendingById).filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { + delete pendingById[pendingClaim.claim_id]; + }); + + return Object.assign({}, state, { + isFetchingClaimListMine: false, + myClaims: claims, + byId, + claimsByUri: byUri, + pendingById + }); +}; + +reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetchingMyChannels: true }); + +reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { + const { claims } = action.data; + const myChannelClaims = new Set(state.myChannelClaims); + const byId = Object.assign({}, state.byId); + + claims.forEach(claim => { + myChannelClaims.add(claim.claim_id); + byId[claim.claim_id] = claim; + }); + + return Object.assign({}, state, { + byId, + fetchingMyChannels: false, + myChannelClaims + }); +}; + +reducers[FETCH_CHANNEL_CLAIMS_STARTED] = (state, action) => { + const { uri, page } = action.data; + const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); + + fetchingChannelClaims[uri] = page; + + return Object.assign({}, state, { + fetchingChannelClaims, + currentChannelPage: page + }); +}; + +reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { + const { uri, claims, page } = action.data; + + const claimsByChannel = Object.assign({}, state.claimsByChannel); + const byChannel = Object.assign({}, claimsByChannel[uri]); + const allClaimIds = new Set(byChannel.all); + const currentPageClaimIds = []; + const byId = Object.assign({}, state.byId); + const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); + const claimsByUri = Object.assign({}, state.claimsByUri); + + if (claims !== undefined) { + claims.forEach(claim => { + allClaimIds.add(claim.claim_id); + currentPageClaimIds.push(claim.claim_id); + byId[claim.claim_id] = claim; + claimsByUri[`lbry://${claim.name}#${claim.claim_id}`] = claim.claim_id; + }); + } + + byChannel.all = allClaimIds; + byChannel[page] = currentPageClaimIds; + claimsByChannel[uri] = byChannel; + delete fetchingChannelClaims[uri]; + + return Object.assign({}, state, { + claimsByChannel, + byId, + fetchingChannelClaims, + claimsByUri, + currentChannelPage: page + }); +}; + +reducers[ABANDON_CLAIM_STARTED] = (state, action) => { + const { claimId } = action.data; + const abandoningById = Object.assign({}, state.abandoningById); + + abandoningById[claimId] = true; + + return Object.assign({}, state, { + abandoningById + }); +}; + +reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { + const { claimId } = action.data; + const byId = Object.assign({}, state.byId); + const claimsByUri = Object.assign({}, state.claimsByUri); + + Object.keys(claimsByUri).forEach(uri => { + if (claimsByUri[uri] === claimId) { + delete claimsByUri[uri]; + } + }); + + delete byId[claimId]; + + return Object.assign({}, state, { + byId, + claimsByUri + }); +}; + +reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { + const { channelClaim } = action.data; + const byId = Object.assign({}, state.byId); + const myChannelClaims = new Set(state.myChannelClaims); + + byId[channelClaim.claim_id] = channelClaim; + myChannelClaims.add(channelClaim.claim_id); + + return Object.assign({}, state, { + byId, + myChannelClaims + }); +}; + +reducers[RESOLVE_URIS_STARTED] = (state, action) => { + const { uris } = action.data; + + const oldResolving = state.resolvingUris || []; + const newResolving = Object.assign([], oldResolving); + + uris.forEach(uri => { + if (!newResolving.includes(uri)) { + newResolving.push(uri); + } + }); + + return Object.assign({}, state, { + resolvingUris: newResolving + }); +}; + +reducers[FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = (state, action) => { + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const { uri, totalClaims } = action.data; + + channelClaimCounts[uri] = totalClaims; + + return Object.assign({}, state, { + channelClaimCounts + }); +}; + +function claimsReducer(state = defaultState, action) { + const handler = reducers[action.type]; + if (handler) return handler(state, action); + return state; +} + +var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const reducers$1 = {}; +const defaultState$1 = { + fileListPublishedSort: DATE_NEW, + fileListDownloadedSort: DATE_NEW +}; + +reducers$1[FILE_LIST_STARTED] = state => Object.assign({}, state, { + isFetchingFileList: true +}); + +reducers$1[FILE_LIST_SUCCEEDED] = (state, action) => { + const { fileInfos } = action.data; + const newByOutpoint = Object.assign({}, state.byOutpoint); + const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint); + + fileInfos.forEach(fileInfo => { + const { outpoint } = fileInfo; + + if (outpoint) newByOutpoint[fileInfo.outpoint] = fileInfo; + }); + + return Object.assign({}, state, { + isFetchingFileList: false, + byOutpoint: newByOutpoint, + pendingByOutpoint + }); +}; + +reducers$1[FETCH_FILE_INFO_STARTED] = (state, action) => { + const { outpoint } = action.data; + const newFetching = Object.assign({}, state.fetching); + + newFetching[outpoint] = true; + + return Object.assign({}, state, { + fetching: newFetching + }); +}; + +reducers$1[FETCH_FILE_INFO_COMPLETED] = (state, action) => { + const { fileInfo, outpoint } = action.data; + + const newByOutpoint = Object.assign({}, state.byOutpoint); + const newFetching = Object.assign({}, state.fetching); + + newByOutpoint[outpoint] = fileInfo; + delete newFetching[outpoint]; + + return Object.assign({}, state, { + byOutpoint: newByOutpoint, + fetching: newFetching + }); +}; + +reducers$1[DOWNLOADING_STARTED] = (state, action) => { + const { uri, outpoint, fileInfo } = action.data; + + const newByOutpoint = Object.assign({}, state.byOutpoint); + const newDownloading = Object.assign({}, state.downloadingByOutpoint); + const newLoading = Object.assign({}, state.urisLoading); + + newDownloading[outpoint] = true; + newByOutpoint[outpoint] = fileInfo; + delete newLoading[uri]; + + return Object.assign({}, state, { + downloadingByOutpoint: newDownloading, + urisLoading: newLoading, + byOutpoint: newByOutpoint + }); +}; + +reducers$1[DOWNLOADING_PROGRESSED] = (state, action) => { + const { outpoint, fileInfo } = action.data; + + const newByOutpoint = Object.assign({}, state.byOutpoint); + const newDownloading = Object.assign({}, state.downloadingByOutpoint); + + newByOutpoint[outpoint] = fileInfo; + newDownloading[outpoint] = true; + + return Object.assign({}, state, { + byOutpoint: newByOutpoint, + downloadingByOutpoint: newDownloading + }); +}; + +reducers$1[DOWNLOADING_CANCELED] = (state, action) => { + const { outpoint } = action.data; + + const newDownloading = Object.assign({}, state.downloadingByOutpoint); + delete newDownloading[outpoint]; + + return Object.assign({}, state, { + downloadingByOutpoint: newDownloading + }); +}; + +reducers$1[DOWNLOADING_COMPLETED] = (state, action) => { + const { outpoint, fileInfo } = action.data; + + const newByOutpoint = Object.assign({}, state.byOutpoint); + const newDownloading = Object.assign({}, state.downloadingByOutpoint); + + newByOutpoint[outpoint] = fileInfo; + delete newDownloading[outpoint]; + + return Object.assign({}, state, { + byOutpoint: newByOutpoint, + downloadingByOutpoint: newDownloading + }); +}; + +reducers$1[FILE_DELETE] = (state, action) => { + const { outpoint } = action.data; + + const newByOutpoint = Object.assign({}, state.byOutpoint); + const downloadingByOutpoint = Object.assign({}, state.downloadingByOutpoint); + + delete newByOutpoint[outpoint]; + delete downloadingByOutpoint[outpoint]; + + return Object.assign({}, state, { + byOutpoint: newByOutpoint, + downloadingByOutpoint + }); +}; + +reducers$1[LOADING_VIDEO_STARTED] = (state, action) => { + const { uri } = action.data; + + const newLoading = Object.assign({}, state.urisLoading); + newLoading[uri] = true; + + const newErrors = _extends$2({}, state.errors); + if (uri in newErrors) delete newErrors[uri]; + + return Object.assign({}, state, { + urisLoading: newLoading, + errors: _extends$2({}, newErrors) + }); +}; + +reducers$1[LOADING_VIDEO_FAILED] = (state, action) => { + const { uri } = action.data; + + const newLoading = Object.assign({}, state.urisLoading); + delete newLoading[uri]; + + const newErrors = _extends$2({}, state.errors); + newErrors[uri] = true; + + return Object.assign({}, state, { + urisLoading: newLoading, + errors: _extends$2({}, newErrors) + }); +}; + +reducers$1[FETCH_DATE] = (state, action) => { + const { time } = action.data; + if (time) { + return Object.assign({}, state, { + publishedDate: time + }); + } + return null; +}; + +reducers$1[SET_FILE_LIST_SORT] = (state, action) => { + const pageSortStates = { + [PUBLISHED]: 'fileListPublishedSort', + [DOWNLOADED]: 'fileListDownloadedSort' + }; + const pageSortState = pageSortStates[action.data.page]; + const { value } = action.data; + + return Object.assign({}, state, { + [pageSortState]: value + }); +}; + +function fileInfoReducer(state = defaultState$1, action) { + const handler = reducers$1[action.type]; + if (handler) return handler(state, action); + return state; +} + +// util for creating reducers +// based off of redux-actions +// https://redux-actions.js.org/docs/api/handleAction.html#handleactions + +// eslint-disable-next-line import/prefer-default-export +const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { + const handler = actionMap[action.type]; + + if (handler) { + const newState = handler(state, action); + return Object.assign({}, state, newState); + } + + // just return the original state if no handler + // returning a copy here breaks redux-persist + return state; +}; + +var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const defaultState$2 = { + notifications: [], + toasts: [], + errors: [] +}; + +const notificationsReducer = handleActions({ + // Toasts + [CREATE_TOAST]: (state, action) => { + const toast = action.data; + const newToasts = state.toasts.slice(); + newToasts.push(toast); + + return _extends$3({}, state, { + toasts: newToasts + }); + }, + [DISMISS_TOAST]: state => { + const newToasts = state.toasts.slice(); + newToasts.shift(); + + return _extends$3({}, state, { + toasts: newToasts + }); + }, + + // Notifications + [CREATE_NOTIFICATION]: (state, action) => { + const notification = action.data; + const newNotifications = state.notifications.slice(); + newNotifications.push(notification); + + return _extends$3({}, state, { + notifications: newNotifications + }); + }, + // Used to mark notifications as read/dismissed + [EDIT_NOTIFICATION]: (state, action) => { + const { notification } = action.data; + let notifications = state.notifications.slice(); + + notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); + + return _extends$3({}, state, { + notifications + }); + }, + [DELETE_NOTIFICATION]: (state, action) => { + const { id } = action.data; + let newNotifications = state.notifications.slice(); + newNotifications = newNotifications.filter(notification => notification.id !== id); + + return _extends$3({}, state, { + notifications: newNotifications + }); + }, + + // Errors + [CREATE_ERROR]: (state, action) => { + const error = action.data; + const newErrors = state.errors.slice(); + newErrors.push(error); + + return _extends$3({}, state, { + errors: newErrors + }); + }, + [DISMISS_ERROR]: state => { + const newErrors = state.errors.slice(); + newErrors.shift(); + + return _extends$3({}, state, { + errors: newErrors + }); + } +}, defaultState$2); + +var _extends$4 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const defaultState$3 = { + isActive: false, // does the user have any typed text in the search input + focused: false, // is the search input focused + searchQuery: '', // needs to be an empty string for input focusing + options: { + [SEARCH_OPTIONS.RESULT_COUNT]: 30, + [SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS, + [SEARCH_OPTIONS.MEDIA_AUDIO]: true, + [SEARCH_OPTIONS.MEDIA_VIDEO]: true, + [SEARCH_OPTIONS.MEDIA_TEXT]: true, + [SEARCH_OPTIONS.MEDIA_IMAGE]: true, + [SEARCH_OPTIONS.MEDIA_APPLICATION]: true + }, + suggestions: {}, + urisByQuery: {} +}; + +const searchReducer = handleActions({ + [SEARCH_START]: state => _extends$4({}, state, { + searching: true + }), + [SEARCH_SUCCESS]: (state, action) => { + const { query, uris } = action.data; + + return _extends$4({}, state, { + searching: false, + urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) + }); + }, + + [SEARCH_FAIL]: state => _extends$4({}, state, { + searching: false + }), + + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$4({}, state, { + searchQuery: action.data.query, + isActive: true + }), + + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$4({}, state, { + suggestions: _extends$4({}, state.suggestions, { + [action.data.query]: action.data.suggestions + }) + }), + + // clear the searchQuery on back/forward unless to search page + [HISTORY_NAVIGATE]: (state, action) => { + const { url } = action.data; + return _extends$4({}, state, { + searchQuery: url.indexOf('/search') === 0 ? url.slice(14) : '', + isActive: url.indexOf('/search') === 0, + suggestions: {} + }); + }, + + // sets isActive to false so the uri will be populated correctly if the + // user is on a file page. The search query will still be present on any + // other page + [DISMISS_NOTIFICATION]: state => _extends$4({}, state, { + isActive: false + }), + + [SEARCH_FOCUS]: state => _extends$4({}, state, { + focused: true + }), + [SEARCH_BLUR]: state => _extends$4({}, state, { + focused: false + }), + [UPDATE_SEARCH_OPTIONS]: (state, action) => { + const { options: oldOptions } = state; + const newOptions = action.data; + const options = _extends$4({}, oldOptions, newOptions); + return _extends$4({}, state, { + options + }); + } +}, defaultState$3); + +// + +const reducers$2 = {}; +const buildDraftTransaction = () => ({ + amount: undefined, + address: undefined +}); + +// TODO: Split into common success and failure types +// See details in https://github.com/lbryio/lbry/issues/1307 + + +const defaultState$4 = { + balance: undefined, + blocks: {}, + latestBlock: undefined, + transactions: {}, + fetchingTransactions: false, + gettingNewAddress: false, + draftTransaction: buildDraftTransaction(), + sendingSupport: false, + walletIsEncrypted: false, + walletEncryptPending: false, + walletEncryptSucceded: null, + walletEncryptResult: null, + walletDecryptPending: false, + walletDecryptSucceded: null, + walletDecryptResult: null, + walletUnlockPending: false, + walletUnlockSucceded: null, + walletUnlockResult: null, + walletLockPending: false, + walletLockSucceded: null, + walletLockResult: null, + transactionListFilter: 'all' +}; + +reducers$2[FETCH_TRANSACTIONS_STARTED] = state => Object.assign({}, state, { + fetchingTransactions: true +}); + +reducers$2[FETCH_TRANSACTIONS_COMPLETED] = (state, action) => { + const byId = Object.assign({}, state.transactions); + + const { transactions } = action.data; + + transactions.forEach(transaction => { + byId[transaction.txid] = transaction; + }); + + return Object.assign({}, state, { + transactions: byId, + fetchingTransactions: false + }); +}; + +reducers$2[GET_NEW_ADDRESS_STARTED] = state => Object.assign({}, state, { + gettingNewAddress: true +}); + +reducers$2[GET_NEW_ADDRESS_COMPLETED] = (state, action) => { + const { address } = action.data; + + // Say no to localStorage! + return Object.assign({}, state, { + gettingNewAddress: false, + receiveAddress: address + }); +}; + +reducers$2[UPDATE_BALANCE] = (state, action) => Object.assign({}, state, { + balance: action.data.balance +}); + +reducers$2[CHECK_ADDRESS_IS_MINE_STARTED] = state => Object.assign({}, state, { + checkingAddressOwnership: true +}); + +reducers$2[CHECK_ADDRESS_IS_MINE_COMPLETED] = state => Object.assign({}, state, { + checkingAddressOwnership: false +}); + +reducers$2[SET_DRAFT_TRANSACTION_AMOUNT] = (state, action) => { + const oldDraft = state.draftTransaction; + const newDraft = Object.assign({}, oldDraft, { + amount: parseFloat(action.data.amount) + }); + + return Object.assign({}, state, { + draftTransaction: newDraft + }); +}; + +reducers$2[SET_DRAFT_TRANSACTION_ADDRESS] = (state, action) => { + const oldDraft = state.draftTransaction; + const newDraft = Object.assign({}, oldDraft, { + address: action.data.address + }); + + return Object.assign({}, state, { + draftTransaction: newDraft + }); +}; + +reducers$2[SEND_TRANSACTION_STARTED] = state => { + const newDraftTransaction = Object.assign({}, state.draftTransaction, { + sending: true + }); + + return Object.assign({}, state, { + draftTransaction: newDraftTransaction + }); +}; + +reducers$2[SEND_TRANSACTION_COMPLETED] = state => Object.assign({}, state, { + draftTransaction: buildDraftTransaction() +}); + +reducers$2[SEND_TRANSACTION_FAILED] = (state, action) => { + const newDraftTransaction = Object.assign({}, state.draftTransaction, { + sending: false, + error: action.data.error + }); + + return Object.assign({}, state, { + draftTransaction: newDraftTransaction + }); +}; + +reducers$2[SUPPORT_TRANSACTION_STARTED] = state => Object.assign({}, state, { + sendingSupport: true +}); + +reducers$2[SUPPORT_TRANSACTION_COMPLETED] = state => Object.assign({}, state, { + sendingSupport: false +}); + +reducers$2[SUPPORT_TRANSACTION_FAILED] = (state, action) => Object.assign({}, state, { + error: action.data.error, + sendingSupport: false +}); + +reducers$2[FETCH_BLOCK_SUCCESS] = (state, action) => { + const { + block, + block: { height } + } = action.data; + const blocks = Object.assign({}, state.blocks); + + blocks[height] = block; + + return Object.assign({}, state, { blocks }); +}; + +reducers$2[WALLET_STATUS_COMPLETED] = (state, action) => Object.assign({}, state, { + walletIsEncrypted: action.result +}); + +reducers$2[WALLET_ENCRYPT_START] = state => Object.assign({}, state, { + walletEncryptPending: true, + walletEncryptSucceded: null, + walletEncryptResult: null +}); + +reducers$2[WALLET_ENCRYPT_COMPLETED] = (state, action) => Object.assign({}, state, { + walletEncryptPending: false, + walletEncryptSucceded: true, + walletEncryptResult: action.result +}); + +reducers$2[WALLET_ENCRYPT_FAILED] = (state, action) => Object.assign({}, state, { + walletEncryptPending: false, + walletEncryptSucceded: false, + walletEncryptResult: action.result +}); + +reducers$2[WALLET_DECRYPT_START] = state => Object.assign({}, state, { + walletDecryptPending: true, + walletDecryptSucceded: null, + walletDecryptResult: null +}); + +reducers$2[WALLET_DECRYPT_COMPLETED] = (state, action) => Object.assign({}, state, { + walletDecryptPending: false, + walletDecryptSucceded: true, + walletDecryptResult: action.result +}); + +reducers$2[WALLET_DECRYPT_FAILED] = (state, action) => Object.assign({}, state, { + walletDecryptPending: false, + walletDecryptSucceded: false, + walletDecryptResult: action.result +}); + +reducers$2[WALLET_UNLOCK_START] = state => Object.assign({}, state, { + walletUnlockPending: true, + walletUnlockSucceded: null, + walletUnlockResult: null +}); + +reducers$2[WALLET_UNLOCK_COMPLETED] = (state, action) => Object.assign({}, state, { + walletUnlockPending: false, + walletUnlockSucceded: true, + walletUnlockResult: action.result +}); + +reducers$2[WALLET_UNLOCK_FAILED] = (state, action) => Object.assign({}, state, { + walletUnlockPending: false, + walletUnlockSucceded: false, + walletUnlockResult: action.result +}); + +reducers$2[WALLET_LOCK_START] = state => Object.assign({}, state, { + walletLockPending: false, + walletLockSucceded: null, + walletLockResult: null +}); + +reducers$2[WALLET_LOCK_COMPLETED] = (state, action) => Object.assign({}, state, { + walletLockPending: false, + walletLockSucceded: true, + walletLockResult: action.result +}); + +reducers$2[WALLET_LOCK_FAILED] = (state, action) => Object.assign({}, state, { + walletLockPending: false, + walletLockSucceded: false, + walletLockResult: action.result +}); + +reducers$2[SET_TRANSACTION_LIST_FILTER] = (state, action) => Object.assign({}, state, { + transactionListFilter: action.data +}); + +reducers$2[UPDATE_CURRENT_HEIGHT] = (state, action) => Object.assign({}, state, { + latestBlock: action.data +}); + +function walletReducer(state = defaultState$4, action) { + const handler = reducers$2[action.type]; + if (handler) return handler(state, action); + return state; +} + +var _extends$5 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const reducers$3 = {}; +const defaultState$5 = { + positions: {} +}; + +reducers$3[SET_CONTENT_POSITION] = (state, action) => { + const { claimId, outpoint, position } = action.data; + return _extends$5({}, state, { + positions: _extends$5({}, state.positions, { + [claimId]: _extends$5({}, state.positions[claimId], { + [outpoint]: position + }) + }) + }); +}; + +function contentReducer(state = defaultState$5, action) { + const handler = reducers$3[action.type]; + if (handler) return handler(state, action); + return state; +} + +const selectState$4 = state => state.content || {}; + +const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$4, makeSelectClaimForUri(uri), (state, claim) => { + if (!claim) { + return null; + } + const outpoint = `${claim.txid}:${claim.nout}`; + const id = claim.claim_id; + return state.positions[id] ? state.positions[id][outpoint] : null; +}); + +var _extends$6 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +const selectState$5 = state => state.notifications || {}; + +const selectToast = reselect.createSelector(selectState$5, state => { + if (state.toasts.length) { + const { id, params } = state.toasts[0]; + return _extends$6({ + id + }, params); + } + + return null; +}); + +const selectError = reselect.createSelector(selectState$5, state => { + if (state.errors.length) { + const { error } = state.errors[0]; + return { + error + }; + } + + return null; +}); + +exports.ACTIONS = action_types; +exports.Lbry = lbryProxy; +exports.PAGES = pages; +exports.SEARCH_OPTIONS = SEARCH_OPTIONS; +exports.SEARCH_TYPES = SEARCH_TYPES; +exports.SETTINGS = settings; +exports.SORT_OPTIONS = sort_options; +exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; +exports.TRANSACTIONS = transaction_types; +exports.batchActions = batchActions; +exports.buildURI = buildURI; +exports.claimsReducer = claimsReducer; +exports.contentReducer = contentReducer; +exports.convertToShareLink = convertToShareLink; +exports.creditsToString = creditsToString; +exports.doAbandonClaim = doAbandonClaim; +exports.doBalanceSubscribe = doBalanceSubscribe; +exports.doBlurSearchInput = doBlurSearchInput; +exports.doCheckAddressIsMine = doCheckAddressIsMine; +exports.doDismissError = doDismissError; +exports.doDismissToast = doDismissToast; +exports.doError = doError; +exports.doFetchBlock = doFetchBlock; +exports.doFetchClaimCountByChannel = doFetchClaimCountByChannel; +exports.doFetchClaimListMine = doFetchClaimListMine; +exports.doFetchClaimsByChannel = doFetchClaimsByChannel; +exports.doFetchFileInfo = doFetchFileInfo; +exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; +exports.doFetchTransactions = doFetchTransactions; +exports.doFileList = doFileList; +exports.doFocusSearchInput = doFocusSearchInput; +exports.doGetNewAddress = doGetNewAddress; +exports.doResolveUri = doResolveUri; +exports.doResolveUris = doResolveUris; +exports.doSearch = doSearch; +exports.doSendDraftTransaction = doSendDraftTransaction; +exports.doSendTip = doSendTip; +exports.doSetDraftTransactionAddress = doSetDraftTransactionAddress; +exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; +exports.doSetFileListSort = doSetFileListSort; +exports.doSetTransactionListFilter = doSetTransactionListFilter; +exports.doToast = doToast; +exports.doUpdateBalance = doUpdateBalance; +exports.doUpdateBlockHeight = doUpdateBlockHeight; +exports.doUpdateSearchOptions = doUpdateSearchOptions; +exports.doUpdateSearchQuery = doUpdateSearchQuery; +exports.doWalletDecrypt = doWalletDecrypt; +exports.doWalletEncrypt = doWalletEncrypt; +exports.doWalletStatus = doWalletStatus; +exports.doWalletUnlock = doWalletUnlock; +exports.fileInfoReducer = fileInfoReducer; +exports.formatCredits = formatCredits; +exports.formatFullPrice = formatFullPrice; +exports.isNameValid = isNameValid; +exports.isURIClaimable = isURIClaimable; +exports.isURIValid = isURIValid; +exports.makeSelectBlockDate = makeSelectBlockDate; +exports.makeSelectChannelForClaimUri = makeSelectChannelForClaimUri; +exports.makeSelectClaimForUri = makeSelectClaimForUri; +exports.makeSelectClaimIsMine = makeSelectClaimIsMine; +exports.makeSelectClaimIsPending = makeSelectClaimIsPending; +exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; +exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; +exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; +exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; +exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; +exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; +exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; +exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; +exports.makeSelectIsUriResolving = makeSelectIsUriResolving; +exports.makeSelectLoadingForUri = makeSelectLoadingForUri; +exports.makeSelectMetadataForUri = makeSelectMetadataForUri; +exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; +exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; +exports.makeSelectPendingByUri = makeSelectPendingByUri; +exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; +exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; +exports.makeSelectSearchUris = makeSelectSearchUris; +exports.makeSelectTitleForUri = makeSelectTitleForUri; +exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; +exports.makeSelectTotalPagesForChannel = makeSelectTotalPagesForChannel; +exports.normalizeURI = normalizeURI; +exports.notificationsReducer = notificationsReducer; +exports.parseQueryParams = parseQueryParams; +exports.parseURI = parseURI; +exports.regexAddress = regexAddress; +exports.regexInvalidURI = regexInvalidURI; +exports.savePosition = savePosition; +exports.searchReducer = searchReducer; +exports.selectAbandoningIds = selectAbandoningIds; +exports.selectAllClaimsByChannel = selectAllClaimsByChannel; +exports.selectAllFetchingChannelClaims = selectAllFetchingChannelClaims; +exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; +exports.selectBalance = selectBalance; +exports.selectBlocks = selectBlocks; +exports.selectChannelClaimCounts = selectChannelClaimCounts; +exports.selectClaimsById = selectClaimsById; +exports.selectClaimsByUri = selectClaimsByUri; +exports.selectCurrentChannelPage = selectCurrentChannelPage; +exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; +exports.selectDownloadingFileInfos = selectDownloadingFileInfos; +exports.selectDraftTransaction = selectDraftTransaction; +exports.selectDraftTransactionAddress = selectDraftTransactionAddress; +exports.selectDraftTransactionAmount = selectDraftTransactionAmount; +exports.selectDraftTransactionError = selectDraftTransactionError; +exports.selectError = selectError; +exports.selectFetchingMyChannels = selectFetchingMyChannels; +exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; +exports.selectFileInfosDownloaded = selectFileInfosDownloaded; +exports.selectFileListDownloadedSort = selectFileListDownloadedSort; +exports.selectFileListPublishedSort = selectFileListPublishedSort; +exports.selectGettingNewAddress = selectGettingNewAddress; +exports.selectHasTransactions = selectHasTransactions; +exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; +exports.selectIsFetchingFileList = selectIsFetchingFileList; +exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; +exports.selectIsFetchingTransactions = selectIsFetchingTransactions; +exports.selectIsSearching = selectIsSearching; +exports.selectIsSendingSupport = selectIsSendingSupport; +exports.selectMyActiveClaims = selectMyActiveClaims; +exports.selectMyChannelClaims = selectMyChannelClaims; +exports.selectMyClaims = selectMyClaims; +exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; +exports.selectMyClaimsRaw = selectMyClaimsRaw; +exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; +exports.selectPendingById = selectPendingById; +exports.selectPendingClaims = selectPendingClaims; +exports.selectPlayingUri = selectPlayingUri; +exports.selectReceiveAddress = selectReceiveAddress; +exports.selectRecentTransactions = selectRecentTransactions; +exports.selectResolvingUris = selectResolvingUris; +exports.selectSearchBarFocused = selectSearchBarFocused; +exports.selectSearchDownloadUris = selectSearchDownloadUris; +exports.selectSearchOptions = selectSearchOptions; +exports.selectSearchState = selectState; +exports.selectSearchSuggestions = selectSearchSuggestions; +exports.selectSearchUrisByQuery = selectSearchUrisByQuery; +exports.selectSearchValue = selectSearchValue; +exports.selectToast = selectToast; +exports.selectTotalDownloadProgress = selectTotalDownloadProgress; +exports.selectTransactionItems = selectTransactionItems; +exports.selectTransactionListFilter = selectTransactionListFilter; +exports.selectTransactionsById = selectTransactionsById; +exports.selectUrisLoading = selectUrisLoading; +exports.selectWalletDecryptPending = selectWalletDecryptPending; +exports.selectWalletDecryptResult = selectWalletDecryptResult; +exports.selectWalletDecryptSucceeded = selectWalletDecryptSucceeded; +exports.selectWalletEncryptPending = selectWalletEncryptPending; +exports.selectWalletEncryptResult = selectWalletEncryptResult; +exports.selectWalletEncryptSucceeded = selectWalletEncryptSucceeded; +exports.selectWalletIsEncrypted = selectWalletIsEncrypted; +exports.selectWalletState = selectWalletState; +exports.selectWalletUnlockPending = selectWalletUnlockPending; +exports.selectWalletUnlockResult = selectWalletUnlockResult; +exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; +exports.setSearchApi = setSearchApi; +exports.toQueryString = toQueryString; +exports.walletReducer = walletReducer; diff --git a/dist/bundle.js b/dist/bundle.js index cd2e934..3608960 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -89,19 +89,10 @@ return /******/ (function(modules) { // webpackBootstrap Object.defineProperty(exports, "__esModule", { value: true }); -exports.selectTransactionListFilter = exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletState = exports.selectWalletIsEncrypted = exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectWunderBarAddress = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchOptions = exports.selectSearchValue = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectFileListPublishedSort = exports.selectFileListDownloadedSort = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectCurrentChannelPage = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectFetchingTrendingUris = exports.selectTrendingUris = exports.selectFetchingFeaturedUris = exports.selectFeaturedUris = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = undefined; -exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.selectPendingById = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.selectError = exports.selectToast = exports.makeSelectContentPositionForUri = exports.contentReducer = exports.walletReducer = exports.searchReducer = exports.notificationsReducer = exports.fileInfoReducer = exports.claimsReducer = exports.creditsToString = exports.formatFullPrice = exports.formatCredits = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doUpdateBlockHeight = exports.doSetTransactionListFilter = exports.doWalletStatus = exports.doWalletUnlock = exports.doWalletDecrypt = exports.doWalletEncrypt = exports.doSendTip = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.savePosition = exports.doUpdateSearchOptions = exports.setSearchApi = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doUpdateSearchQuery = exports.doSearch = exports.doSetFileListSort = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doFetchClaimCountByChannel = exports.doFetchClaimsByChannel = exports.doDismissError = exports.doError = exports.doDismissToast = exports.doToast = exports.convertToShareLink = exports.isNameValid = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbry = exports.PAGES = exports.SORT_OPTIONS = exports.TRANSACTIONS = exports.SETTINGS = exports.SEARCH_OPTIONS = exports.SEARCH_TYPES = exports.THUMBNAIL_STATUSES = exports.ACTIONS = exports.Toast = undefined; +exports.selectTransactionListFilter = exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletState = exports.selectWalletIsEncrypted = exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchOptions = exports.selectSearchValue = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectFileListPublishedSort = exports.selectFileListDownloadedSort = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectCurrentChannelPage = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = undefined; +exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.selectPendingById = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.selectError = exports.selectToast = exports.makeSelectContentPositionForUri = exports.contentReducer = exports.walletReducer = exports.searchReducer = exports.notificationsReducer = exports.fileInfoReducer = exports.claimsReducer = exports.creditsToString = exports.formatFullPrice = exports.formatCredits = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doUpdateBlockHeight = exports.doSetTransactionListFilter = exports.doWalletStatus = exports.doWalletUnlock = exports.doWalletDecrypt = exports.doWalletEncrypt = exports.doSendTip = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.savePosition = exports.doUpdateSearchOptions = exports.setSearchApi = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doUpdateSearchQuery = exports.doSearch = exports.doSetFileListSort = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doFetchClaimCountByChannel = exports.doFetchClaimsByChannel = exports.doDismissError = exports.doError = exports.doDismissToast = exports.doToast = exports.convertToShareLink = exports.isNameValid = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbry = exports.PAGES = exports.SORT_OPTIONS = exports.TRANSACTIONS = exports.SETTINGS = exports.SEARCH_OPTIONS = exports.SEARCH_TYPES = exports.THUMBNAIL_STATUSES = exports.ACTIONS = undefined; -var _Notification = __webpack_require__(1); - -Object.defineProperty(exports, 'Toast', { - enumerable: true, - get: function get() { - return _Notification.Toast; - } -}); - -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); Object.defineProperty(exports, 'regexInvalidURI', { enumerable: true, @@ -158,7 +149,7 @@ Object.defineProperty(exports, 'convertToShareLink', { } }); -var _notifications = __webpack_require__(4); +var _notifications = __webpack_require__(2); Object.defineProperty(exports, 'doToast', { enumerable: true, @@ -185,7 +176,7 @@ Object.defineProperty(exports, 'doDismissError', { } }); -var _claims = __webpack_require__(8); +var _claims = __webpack_require__(7); Object.defineProperty(exports, 'doFetchClaimsByChannel', { enumerable: true, @@ -224,7 +215,7 @@ Object.defineProperty(exports, 'doResolveUri', { } }); -var _file_info = __webpack_require__(22); +var _file_info = __webpack_require__(21); Object.defineProperty(exports, 'doFetchFileInfo', { enumerable: true, @@ -251,7 +242,7 @@ Object.defineProperty(exports, 'doSetFileListSort', { } }); -var _search = __webpack_require__(24); +var _search = __webpack_require__(23); Object.defineProperty(exports, 'doSearch', { enumerable: true, @@ -290,7 +281,7 @@ Object.defineProperty(exports, 'doUpdateSearchOptions', { } }); -var _content = __webpack_require__(28); +var _content = __webpack_require__(27); Object.defineProperty(exports, 'savePosition', { enumerable: true, @@ -299,7 +290,7 @@ Object.defineProperty(exports, 'savePosition', { } }); -var _wallet = __webpack_require__(18); +var _wallet = __webpack_require__(17); Object.defineProperty(exports, 'doUpdateBalance', { enumerable: true, @@ -398,7 +389,7 @@ Object.defineProperty(exports, 'doUpdateBlockHeight', { } }); -var _batchActions = __webpack_require__(25); +var _batchActions = __webpack_require__(24); Object.defineProperty(exports, 'batchActions', { enumerable: true, @@ -407,7 +398,7 @@ Object.defineProperty(exports, 'batchActions', { } }); -var _query_params = __webpack_require__(15); +var _query_params = __webpack_require__(14); Object.defineProperty(exports, 'parseQueryParams', { enumerable: true, @@ -422,7 +413,7 @@ Object.defineProperty(exports, 'toQueryString', { } }); -var _formatCredits = __webpack_require__(21); +var _formatCredits = __webpack_require__(20); Object.defineProperty(exports, 'formatCredits', { enumerable: true, @@ -443,7 +434,7 @@ Object.defineProperty(exports, 'creditsToString', { } }); -var _claims2 = __webpack_require__(29); +var _claims2 = __webpack_require__(28); Object.defineProperty(exports, 'claimsReducer', { enumerable: true, @@ -452,7 +443,7 @@ Object.defineProperty(exports, 'claimsReducer', { } }); -var _file_info2 = __webpack_require__(30); +var _file_info2 = __webpack_require__(29); Object.defineProperty(exports, 'fileInfoReducer', { enumerable: true, @@ -461,7 +452,7 @@ Object.defineProperty(exports, 'fileInfoReducer', { } }); -var _notifications2 = __webpack_require__(33); +var _notifications2 = __webpack_require__(32); Object.defineProperty(exports, 'notificationsReducer', { enumerable: true, @@ -470,7 +461,7 @@ Object.defineProperty(exports, 'notificationsReducer', { } }); -var _search2 = __webpack_require__(35); +var _search2 = __webpack_require__(34); Object.defineProperty(exports, 'searchReducer', { enumerable: true, @@ -479,7 +470,7 @@ Object.defineProperty(exports, 'searchReducer', { } }); -var _wallet2 = __webpack_require__(36); +var _wallet2 = __webpack_require__(35); Object.defineProperty(exports, 'walletReducer', { enumerable: true, @@ -488,7 +479,7 @@ Object.defineProperty(exports, 'walletReducer', { } }); -var _content2 = __webpack_require__(37); +var _content2 = __webpack_require__(36); Object.defineProperty(exports, 'contentReducer', { enumerable: true, @@ -497,7 +488,7 @@ Object.defineProperty(exports, 'contentReducer', { } }); -var _content3 = __webpack_require__(38); +var _content3 = __webpack_require__(37); Object.defineProperty(exports, 'makeSelectContentPositionForUri', { enumerable: true, @@ -506,7 +497,7 @@ Object.defineProperty(exports, 'makeSelectContentPositionForUri', { } }); -var _notifications3 = __webpack_require__(39); +var _notifications3 = __webpack_require__(38); Object.defineProperty(exports, 'selectToast', { enumerable: true, @@ -521,7 +512,7 @@ Object.defineProperty(exports, 'selectError', { } }); -var _claims3 = __webpack_require__(12); +var _claims3 = __webpack_require__(11); Object.defineProperty(exports, 'makeSelectClaimForUri', { enumerable: true, @@ -733,30 +724,6 @@ Object.defineProperty(exports, 'selectResolvingUris', { return _claims3.selectResolvingUris; } }); -Object.defineProperty(exports, 'selectFeaturedUris', { - enumerable: true, - get: function get() { - return _claims3.selectFeaturedUris; - } -}); -Object.defineProperty(exports, 'selectFetchingFeaturedUris', { - enumerable: true, - get: function get() { - return _claims3.selectFetchingFeaturedUris; - } -}); -Object.defineProperty(exports, 'selectTrendingUris', { - enumerable: true, - get: function get() { - return _claims3.selectTrendingUris; - } -}); -Object.defineProperty(exports, 'selectFetchingTrendingUris', { - enumerable: true, - get: function get() { - return _claims3.selectFetchingTrendingUris; - } -}); Object.defineProperty(exports, 'selectPlayingUri', { enumerable: true, get: function get() { @@ -776,7 +743,7 @@ Object.defineProperty(exports, 'selectCurrentChannelPage', { } }); -var _file_info3 = __webpack_require__(23); +var _file_info3 = __webpack_require__(22); Object.defineProperty(exports, 'makeSelectFileInfoForUri', { enumerable: true, @@ -863,7 +830,7 @@ Object.defineProperty(exports, 'selectFileListPublishedSort', { } }); -var _search3 = __webpack_require__(13); +var _search3 = __webpack_require__(12); Object.defineProperty(exports, 'makeSelectSearchUris', { enumerable: true, @@ -895,12 +862,6 @@ Object.defineProperty(exports, 'selectSearchUrisByQuery', { return _search3.selectSearchUrisByQuery; } }); -Object.defineProperty(exports, 'selectWunderBarAddress', { - enumerable: true, - get: function get() { - return _search3.selectWunderBarAddress; - } -}); Object.defineProperty(exports, 'selectSearchBarFocused', { enumerable: true, get: function get() { @@ -920,7 +881,7 @@ Object.defineProperty(exports, 'makeSelectQueryWithOptions', { } }); -var _wallet3 = __webpack_require__(19); +var _wallet3 = __webpack_require__(18); Object.defineProperty(exports, 'makeSelectBlockDate', { enumerable: true, @@ -1085,33 +1046,33 @@ Object.defineProperty(exports, 'selectTransactionListFilter', { } }); -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _thumbnail_upload_statuses = __webpack_require__(40); +var _thumbnail_upload_statuses = __webpack_require__(39); var THUMBNAIL_STATUSES = _interopRequireWildcard(_thumbnail_upload_statuses); -var _settings = __webpack_require__(41); +var _settings = __webpack_require__(40); var SETTINGS = _interopRequireWildcard(_settings); -var _transaction_types = __webpack_require__(20); +var _transaction_types = __webpack_require__(19); var TRANSACTIONS = _interopRequireWildcard(_transaction_types); -var _sort_options = __webpack_require__(31); +var _sort_options = __webpack_require__(30); var SORT_OPTIONS = _interopRequireWildcard(_sort_options); -var _pages = __webpack_require__(32); +var _pages = __webpack_require__(31); var PAGES = _interopRequireWildcard(_pages); -var _search4 = __webpack_require__(14); +var _search4 = __webpack_require__(13); -var _lbry = __webpack_require__(9); +var _lbry = __webpack_require__(8); var _lbry2 = _interopRequireDefault(_lbry); @@ -1119,6 +1080,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +// types +//export { Toast } from 'types/Notification'; + // constants exports.ACTIONS = ACTIONS; exports.THUMBNAIL_STATUSES = THUMBNAIL_STATUSES; @@ -1141,103 +1105,244 @@ exports.selectSearchState = _search3.selectState; "use strict"; -var _action_types = __webpack_require__(2); +Object.defineProperty(exports, "__esModule", { + value: true +}); -var ACTIONS = _interopRequireWildcard(_action_types); +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); -/* - Toasts: - - First-in, first-out queue - - Simple messages that are shown in response to user interactions - - Never saved - - If they are the result of errors, use the isError flag when creating - - For errors that should interrupt user behavior, use Error -*/ -/*:: export type ToastParams = { - message: string, - title?: string, - linkText?: string, - linkTarget?: string, - isError?: boolean, -};*/ // @flow +exports.parseURI = parseURI; +exports.buildURI = buildURI; +exports.normalizeURI = normalizeURI; +exports.isURIValid = isURIValid; +exports.isNameValid = isNameValid; +exports.isURIClaimable = isURIClaimable; +exports.convertToShareLink = convertToShareLink; +var channelNameMinLength = 1; +var claimIdMaxLength = 40; -/*:: export type Toast = { - id: string, - params: ToastParams, -};*/ +var regexInvalidURI = exports.regexInvalidURI = /[^A-Za-z0-9-]/g; +var regexAddress = exports.regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; + +/** + * Parses a LBRY name into its component parts. Throws errors with user-friendly + * messages for invalid names. + * + * N.B. that "name" indicates the value in the name position of the URI. For + * claims for channel content, this will actually be the channel name, and + * the content name is in the path (e.g. lbry://@channel/content) + * + * In most situations, you'll want to use the contentName and channelName keys + * and ignore the name key. + * + * Returns a dictionary with keys: + * - name (string): The value in the "name" position in the URI. Note that this + * could be either content name or channel name; see above. + * - path (string, if persent) + * - claimSequence (int, if present) + * - bidPosition (int, if present) + * - claimId (string, if present) + * - isChannel (boolean) + * - contentName (string): For anon claims, the name; for channel claims, the path + * - channelName (string, if present): Channel name without @ + */ +function parseURI(URI) { + var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + // Break into components. Empty sub-matches are converted to null + var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol + '([^:$#/]*)' + // claim name (stops at the first separator or end) + '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) + '(/?)(.*)' // path separator, path + ); + + var _componentsRegex$exec = componentsRegex.exec(URI).slice(1).map(function (match) { + return match || null; + }), + _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), + proto = _componentsRegex$exec2[0], + claimName = _componentsRegex$exec2[1], + modSep = _componentsRegex$exec2[2], + modVal = _componentsRegex$exec2[3], + pathSep = _componentsRegex$exec2[4], + path = _componentsRegex$exec2[5]; + + var contentName = void 0; + + // Validate protocol + if (requireProto && !proto) { + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + } + + // Validate and process name + if (!claimName) { + throw new Error(__('URI does not include name.')); + } + + var isChannel = claimName.startsWith('@'); + var channelName = isChannel ? claimName.slice(1) : claimName; + + if (isChannel) { + if (!channelName) { + throw new Error(__('No channel name after @.')); + } + + if (channelName.length < channelNameMinLength) { + throw new Error(__('Channel names must be at least %s characters.', channelNameMinLength)); + } + + contentName = path; + } + + var nameBadChars = (channelName || claimName).match(regexInvalidURI); + if (nameBadChars) { + throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); + } + + // Validate and process modifier (claim ID, bid position or claim sequence) + var claimId = void 0; + var claimSequence = void 0; + var bidPosition = void 0; + if (modSep) { + if (!modVal) { + throw new Error(__('No modifier provided after separator %s.', modSep)); + } + + if (modSep === '#') { + claimId = modVal; + } else if (modSep === ':') { + claimSequence = modVal; + } else if (modSep === '$') { + bidPosition = modVal; + } + } + + if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { + throw new Error(__('Invalid claim ID %s.', claimId)); + } + + if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Claim sequence must be a number.')); + } + + if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { + throw new Error(__('Bid position must be a number.')); + } + + // Validate and process path + if (path) { + if (!isChannel) { + throw new Error(__('Only channel URIs may have a path.')); + } + + var pathBadChars = path.match(regexInvalidURI); + if (pathBadChars) { + throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); + } + + contentName = path; + } else if (pathSep) { + throw new Error(__('No path provided after /')); + } + + return _extends({ + claimName: claimName, + path: path, + isChannel: isChannel + }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); +} + +/** + * Takes an object in the same format returned by parse() and builds a URI. + * + * The channelName key will accept names with or without the @ prefix. + */ +function buildURI(URIObj) { + var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var protoDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'lbry://'; + var claimId = URIObj.claimId, + claimSequence = URIObj.claimSequence, + bidPosition = URIObj.bidPosition, + contentName = URIObj.contentName, + channelName = URIObj.channelName; + var claimName = URIObj.claimName, + path = URIObj.path; -/* - Notifications: - - List of notifications based on user interactions/app notifications - - Always saved, but can be manually deleted - - Can happen in the background, or because of user interaction (ex: publish confirmed) -*/ -/*:: export type DoToast = { - type: ACTIONS.CREATE_TOAST, - data: Toast, -};*/ -/*:: export type Notification = { - id: string, // Unique id - dateCreated: number, - isRead: boolean, // Used to display "new" notifications that a user hasn't seen yet - source?: string, // The type/area an notification is from. Used for sorting (ex: publishes, transactions) - // We may want to use priority/isDismissed in the future to specify how urgent a notification is - // and if the user should see it immediately - // isDissmied: boolean, - // priority?: number -};*/ -/*:: export type DoNotification = { - type: ACTIONS.CREATE_NOTIFICATION, - data: Notification, -};*/ -/*:: export type DoEditNotification = { - type: ACTIONS.EDIT_NOTIFICATION, - data: { - id: string, - isRead: boolean, - // In the future we can add `isDismissed` if we decide to show notifications as they come in - // Similar to Facebook's notifications in the corner of the screen - // isDismissed: boolean, - }, -};*/ + if (channelName) { + var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; + if (!claimName) { + claimName = channelNameFormatted; + } else if (claimName !== channelNameFormatted) { + throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); + } + } + if (contentName) { + if (!claimName) { + claimName = contentName; + } else if (!path) { + path = contentName; + } + if (path && path !== contentName) { + throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); + } + } -/* - Errors: - - First-in, first-out queue - - Errors that should interupt user behavior - - For errors that can be shown without interrupting a user, use Toast with the isError flag -*/ -/*:: export type DoDeleteNotification = { - type: ACTIONS.DELETE_NOTIFICATION, - data: { - id: string, // The id to delete - }, -};*/ -/*:: export type Error = { - title: string, - text: string, -};*/ -/*:: export type DoError = { - type: ACTIONS.CREATE_ERROR, - data: Error, -};*/ + return (includeProto ? protoDefault : '') + claimName + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); +} +/* Takes a parseable LBRY URI and converts it to standard, canonical format */ +function normalizeURI(URI) { + var _parseURI = parseURI(URI), + claimName = _parseURI.claimName, + path = _parseURI.path, + bidPosition = _parseURI.bidPosition, + claimSequence = _parseURI.claimSequence, + claimId = _parseURI.claimId; -/* - NotificationState -*/ -/*:: export type DoDismissError = { - type: ACTIONS.DISMISS_ERROR, -};*/ -/*:: export type NotificationState = { - notifications: Array, - errors: Array, - toasts: Array, -};*/ + return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); +} + +function isURIValid(URI) { + var parts = void 0; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.claimName; +} + +function isNameValid(claimName) { + var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); + return regexp.test(claimName); +} + +function isURIClaimable(URI) { + var parts = void 0; + try { + parts = parseURI(normalizeURI(URI)); + } catch (error) { + return false; + } + return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; +} + +function convertToShareLink(URI) { + var _parseURI2 = parseURI(URI), + claimName = _parseURI2.claimName, + path = _parseURI2.path, + bidPosition = _parseURI2.bidPosition, + claimSequence = _parseURI2.claimSequence, + claimId = _parseURI2.claimId; + + return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }, true, 'https://open.lbry.io/'); +} /***/ }), /* 2 */ @@ -1246,6 +1351,70 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; "use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.doToast = doToast; +exports.doDismissToast = doDismissToast; +exports.doError = doError; +exports.doDismissError = doDismissError; + +var _action_types = __webpack_require__(3); + +var ACTIONS = _interopRequireWildcard(_action_types); + +var _v = __webpack_require__(4); + +var _v2 = _interopRequireDefault(_v); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +// @flow +/*:: import type { ToastParams } from 'types/Notification';*/ +function doToast(params /*: ToastParams*/) { + if (!params) { + throw Error("'params' object is required to create a toast notification"); + } + + return { + type: ACTIONS.CREATE_TOAST, + data: { + id: (0, _v2.default)(), + params: params + } + }; +} + +function doDismissToast() { + return { + type: ACTIONS.DISMISS_TOAST + }; +} + +function doError(error /*: string | {}*/) { + return { + type: ACTIONS.CREATE_ERROR, + data: { + error: error + } + }; +} + +function doDismissError() { + return { + type: ACTIONS.DISMISS_ERROR + }; +} + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + Object.defineProperty(exports, "__esModule", { value: true }); @@ -1461,322 +1630,17 @@ var DISMISS_TOAST = exports.DISMISS_TOAST = 'DISMISS_TOAST'; var CREATE_ERROR = exports.CREATE_ERROR = 'CREATE_ERROR'; var DISMISS_ERROR = exports.DISMISS_ERROR = 'DISMISS_ERROR'; -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.parseURI = parseURI; -exports.buildURI = buildURI; -exports.normalizeURI = normalizeURI; -exports.isURIValid = isURIValid; -exports.isNameValid = isNameValid; -exports.isURIClaimable = isURIClaimable; -exports.convertToShareLink = convertToShareLink; -var channelNameMinLength = 1; -var claimIdMaxLength = 40; - -var regexInvalidURI = exports.regexInvalidURI = /[^A-Za-z0-9-]/g; -var regexAddress = exports.regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; - -/** - * Parses a LBRY name into its component parts. Throws errors with user-friendly - * messages for invalid names. - * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * - * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) - * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ - */ -function parseURI(URI) { - var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Break into components. Empty sub-matches are converted to null - var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // claim name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path - ); - - var _componentsRegex$exec = componentsRegex.exec(URI).slice(1).map(function (match) { - return match || null; - }), - _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), - proto = _componentsRegex$exec2[0], - claimName = _componentsRegex$exec2[1], - modSep = _componentsRegex$exec2[2], - modVal = _componentsRegex$exec2[3], - pathSep = _componentsRegex$exec2[4], - path = _componentsRegex$exec2[5]; - - var contentName = void 0; - - // Validate protocol - if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); - } - - // Validate and process name - if (!claimName) { - throw new Error(__('URI does not include name.')); - } - - var isChannel = claimName.startsWith('@'); - var channelName = isChannel ? claimName.slice(1) : claimName; - - if (isChannel) { - if (!channelName) { - throw new Error(__('No channel name after @.')); - } - - if (channelName.length < channelNameMinLength) { - throw new Error(__('Channel names must be at least %s characters.', channelNameMinLength)); - } - - contentName = path; - } - - var nameBadChars = (channelName || claimName).match(regexInvalidURI); - if (nameBadChars) { - throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - } - - // Validate and process modifier (claim ID, bid position or claim sequence) - var claimId = void 0; - var claimSequence = void 0; - var bidPosition = void 0; - if (modSep) { - if (!modVal) { - throw new Error(__('No modifier provided after separator %s.', modSep)); - } - - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; - } - } - - if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__('Invalid claim ID %s.', claimId)); - } - - if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); - } - - if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); - } - - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - var pathBadChars = path.match(regexInvalidURI); - if (pathBadChars) { - throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return _extends({ - claimName: claimName, - path: path, - isChannel: isChannel - }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); -} - -/** - * Takes an object in the same format returned by parse() and builds a URI. - * - * The channelName key will accept names with or without the @ prefix. - */ -function buildURI(URIObj) { - var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var protoDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'lbry://'; - var claimId = URIObj.claimId, - claimSequence = URIObj.claimSequence, - bidPosition = URIObj.bidPosition, - contentName = URIObj.contentName, - channelName = URIObj.channelName; - var claimName = URIObj.claimName, - path = URIObj.path; - - - if (channelName) { - var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; - if (!claimName) { - claimName = channelNameFormatted; - } else if (claimName !== channelNameFormatted) { - throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); - } - } - - if (contentName) { - if (!claimName) { - claimName = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); - } - } - - return (includeProto ? protoDefault : '') + claimName + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); -} - -/* Takes a parseable LBRY URI and converts it to standard, canonical format */ -function normalizeURI(URI) { - var _parseURI = parseURI(URI), - claimName = _parseURI.claimName, - path = _parseURI.path, - bidPosition = _parseURI.bidPosition, - claimSequence = _parseURI.claimSequence, - claimId = _parseURI.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); -} - -function isURIValid(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName; -} - -function isNameValid(claimName) { - var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - - var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(claimName); -} - -function isURIClaimable(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; -} - -function convertToShareLink(URI) { - var _parseURI2 = parseURI(URI), - claimName = _parseURI2.claimName, - path = _parseURI2.path, - bidPosition = _parseURI2.bidPosition, - claimSequence = _parseURI2.claimSequence, - claimId = _parseURI2.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }, true, 'https://open.lbry.io/'); -} +var SET_DRAFT_TRANSACTION_AMOUNT = exports.SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; +var SET_DRAFT_TRANSACTION_ADDRESS = exports.SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; +var FETCH_DATE = exports.FETCH_DATE = 'FETCH_DATE'; +var DISMISS_NOTIFICATION = exports.DISMISS_NOTIFICATION = 'DISMISS_NOTIFICATION'; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doToast = doToast; -exports.doDismissToast = doDismissToast; -exports.doError = doError; -exports.doDismissError = doDismissError; - -var _action_types = __webpack_require__(2); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _v = __webpack_require__(5); - -var _v2 = _interopRequireDefault(_v); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -// @flow -/*:: import type { ToastParams } from 'types/Notification';*/ -function doToast(params /*: ToastParams*/) { - if (!params) { - throw Error("'params' object is required to create a toast notification"); - } - - return { - type: ACTIONS.CREATE_TOAST, - data: { - id: (0, _v2.default)(), - params: params - } - }; -} - -function doDismissToast() { - return { - type: ACTIONS.DISMISS_TOAST - }; -} - -function doError(error /*: string | {}*/) { - return { - type: ACTIONS.CREATE_ERROR, - data: { - error: error - } - }; -} - -function doDismissError() { - return { - type: ACTIONS.DISMISS_ERROR - }; -} - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(6); -var bytesToUuid = __webpack_require__(7); +var rng = __webpack_require__(5); +var bytesToUuid = __webpack_require__(6); function v4(options, buf, offset) { var i = buf && offset || 0; @@ -1807,7 +1671,7 @@ module.exports = v4; /***/ }), -/* 6 */ +/* 5 */ /***/ (function(module, exports) { // Unique ID creation requires a high quality random # generator. In the @@ -1847,7 +1711,7 @@ if (getRandomValues) { /***/ }), -/* 7 */ +/* 6 */ /***/ (function(module, exports) { /** @@ -1877,7 +1741,7 @@ module.exports = bytesToUuid; /***/ }), -/* 8 */ +/* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -1896,21 +1760,21 @@ exports.doAbandonClaim = doAbandonClaim; exports.doFetchClaimsByChannel = doFetchClaimsByChannel; exports.doFetchClaimCountByChannel = doFetchClaimCountByChannel; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbry = __webpack_require__(9); +var _lbry = __webpack_require__(8); var _lbry2 = _interopRequireDefault(_lbry); -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); -var _notifications = __webpack_require__(4); +var _notifications = __webpack_require__(2); -var _claims = __webpack_require__(12); +var _claims = __webpack_require__(11); -var _wallet = __webpack_require__(18); +var _wallet = __webpack_require__(17); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -2095,7 +1959,7 @@ function doFetchClaimCountByChannel(uri) { } /***/ }), -/* 9 */ +/* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2108,7 +1972,7 @@ Object.defineProperty(exports, "__esModule", { var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // @flow -__webpack_require__(10); +__webpack_require__(9); var CHECK_DAEMON_STARTED_TRY_NUMBER = 200; @@ -2297,14 +2161,14 @@ Lbry.getMediaType = function (contentType, extname) { return 'unknown'; }; -/** - * Wrappers for API methods to simulate missing or future behavior. Unlike the old-style stubs, - * these are designed to be transparent wrappers around the corresponding API methods. +/** + * Wrappers for API methods to simulate missing or future behavior. Unlike the old-style stubs, + * these are designed to be transparent wrappers around the corresponding API methods. */ -/** - * Returns results from the file_list API method, plus dummy entries for pending publishes. - * (If a real publish with the same name is found, the pending publish will be ignored and removed.) +/** + * Returns results from the file_list API method, plus dummy entries for pending publishes. + * (If a real publish with the same name is found, the pending publish will be ignored and removed.) */ Lbry.file_list = function () { var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; @@ -2382,7 +2246,7 @@ var lbryProxy = new Proxy(Lbry, { exports.default = lbryProxy; /***/ }), -/* 10 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2561,10 +2425,10 @@ exports.default = lbryProxy; scope['Proxy'] = scope.Proxy; })(typeof module !== 'undefined' && module['exports'] ? global : window); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10))) /***/ }), -/* 11 */ +/* 10 */ /***/ (function(module, exports) { var g; @@ -2590,7 +2454,7 @@ module.exports = g; /***/ }), -/* 12 */ +/* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2601,15 +2465,15 @@ Object.defineProperty(exports, "__esModule", { }); exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.makeSelectIsUriResolving = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectIsFetchingClaimListMine = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.selectAllFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.makeSelectClaimForUri = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.selectPendingClaims = exports.selectPendingById = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectCurrentChannelPage = exports.selectClaimsById = undefined; -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); -var _search = __webpack_require__(13); +var _search = __webpack_require__(12); -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); -var _claim = __webpack_require__(17); +var _claim = __webpack_require__(16); -var _query_params = __webpack_require__(15); +var _query_params = __webpack_require__(14); function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } @@ -2938,7 +2802,7 @@ var makeSelectChannelForClaimUri = exports.makeSelectChannelForClaimUri = functi }; /***/ }), -/* 13 */ +/* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -2951,13 +2815,13 @@ exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.s var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _search = __webpack_require__(14); +var _search = __webpack_require__(13); -var _query_params = __webpack_require__(15); +var _query_params = __webpack_require__(14); -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); // @flow /*:: import type { SearchState, SearchOptions, SearchSuggestion } from 'types/Search';*/ @@ -2974,8 +2838,8 @@ var selectSearchOptions /*: (state: State) => SearchOptions*/ = exports.selectSe return state.options; }); -var selectSuggestions /*: ( - state: State +var selectSuggestions /*: ( + state: State ) => { [string]: Array }*/ = exports.selectSuggestions = (0, _reselect.createSelector)(selectState, function (state) { return state.suggestions; }); @@ -2984,8 +2848,8 @@ var selectIsSearching /*: (state: State) => boolean*/ = exports.selectIsSearchin return state.searching; }); -var selectSearchUrisByQuery /*: ( - state: State +var selectSearchUrisByQuery /*: ( + state: State ) => { [string]: Array }*/ = exports.selectSearchUrisByQuery = (0, _reselect.createSelector)(selectState, function (state) { return state.urisByQuery; }); @@ -3090,7 +2954,7 @@ var makeSelectQueryWithOptions = exports.makeSelectQueryWithOptions = function m }; /***/ }), -/* 14 */ +/* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3119,7 +2983,7 @@ var SEARCH_OPTIONS = exports.SEARCH_OPTIONS = { }; /***/ }), -/* 15 */ +/* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3136,7 +3000,7 @@ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = [ exports.parseQueryParams = parseQueryParams; exports.toQueryString = toQueryString; -var _search = __webpack_require__(14); +var _search = __webpack_require__(13); var DEFAULT_SEARCH_RESULT_FROM = 0; var DEFAULT_SEARCH_SIZE = 20; @@ -3193,7 +3057,7 @@ var getSearchQueryString = exports.getSearchQueryString = function getSearchQuer }; /***/ }), -/* 16 */ +/* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3324,7 +3188,7 @@ function createStructuredSelector(selectors) { } /***/ }), -/* 17 */ +/* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3338,7 +3202,7 @@ var isClaimNsfw = exports.isClaimNsfw = function isClaimNsfw(claim) { }; /***/ }), -/* 18 */ +/* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3365,19 +3229,19 @@ exports.doWalletStatus = doWalletStatus; exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doUpdateBlockHeight = doUpdateBlockHeight; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbry = __webpack_require__(9); +var _lbry = __webpack_require__(8); var _lbry2 = _interopRequireDefault(_lbry); -var _notifications = __webpack_require__(4); +var _notifications = __webpack_require__(2); -var _wallet = __webpack_require__(19); +var _wallet = __webpack_require__(18); -var _formatCredits = __webpack_require__(21); +var _formatCredits = __webpack_require__(20); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -3729,7 +3593,7 @@ function doUpdateBlockHeight() { } /***/ }), -/* 19 */ +/* 18 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3740,9 +3604,9 @@ Object.defineProperty(exports, "__esModule", { }); exports.selectTransactionListFilter = exports.makeSelectBlockDate = exports.selectCurrentHeight = exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.selectWalletLockResult = exports.selectWalletLockSucceeded = exports.selectWalletLockPending = exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletIsEncrypted = exports.selectWalletState = exports.selectState = undefined; -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); -var _transaction_types = __webpack_require__(20); +var _transaction_types = __webpack_require__(19); var TRANSACTIONS = _interopRequireWildcard(_transaction_types); @@ -3972,7 +3836,7 @@ var selectTransactionListFilter = exports.selectTransactionListFilter = (0, _res }); /***/ }), -/* 20 */ +/* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3993,7 +3857,7 @@ var UPDATE = exports.UPDATE = 'update'; var ABANDON = exports.ABANDON = 'abandon'; /***/ }), -/* 21 */ +/* 20 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4038,7 +3902,7 @@ function creditsToString(amount) { } /***/ }), -/* 22 */ +/* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4052,19 +3916,19 @@ exports.doFileList = doFileList; exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; exports.doSetFileListSort = doSetFileListSort; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbry = __webpack_require__(9); +var _lbry = __webpack_require__(8); var _lbry2 = _interopRequireDefault(_lbry); -var _claims = __webpack_require__(8); +var _claims = __webpack_require__(7); -var _claims2 = __webpack_require__(12); +var _claims2 = __webpack_require__(11); -var _file_info = __webpack_require__(23); +var _file_info = __webpack_require__(22); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -4139,7 +4003,7 @@ function doSetFileListSort(page, value) { } /***/ }), -/* 23 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4150,11 +4014,11 @@ Object.defineProperty(exports, "__esModule", { }); exports.selectFileListDownloadedSort = exports.selectFileListPublishedSort = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.makeSelectLoadingForUri = exports.selectUrisLoading = exports.makeSelectDownloadingForUri = exports.selectDownloadingByOutpoint = exports.makeSelectFileInfoForUri = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.selectState = undefined; -var _claims = __webpack_require__(12); +var _claims = __webpack_require__(11); -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); var selectState = exports.selectState = function selectState(state) { return state.fileInfo || {}; @@ -4354,7 +4218,7 @@ var selectFileListDownloadedSort = exports.selectFileListDownloadedSort = (0, _r }); /***/ }), -/* 24 */ +/* 23 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4365,23 +4229,23 @@ Object.defineProperty(exports, "__esModule", { }); exports.doUpdateSearchOptions = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doSearch = exports.doUpdateSearchQuery = exports.getSearchSuggestions = exports.setSearchApi = undefined; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); -var _claims = __webpack_require__(8); +var _claims = __webpack_require__(7); -var _search = __webpack_require__(13); +var _search = __webpack_require__(12); -var _batchActions = __webpack_require__(25); +var _batchActions = __webpack_require__(24); -var _debounce = __webpack_require__(26); +var _debounce = __webpack_require__(25); var _debounce2 = _interopRequireDefault(_debounce); -var _handleFetch = __webpack_require__(27); +var _handleFetch = __webpack_require__(26); var _handleFetch2 = _interopRequireDefault(_handleFetch); @@ -4551,7 +4415,7 @@ var doUpdateSearchOptions = exports.doUpdateSearchOptions = function doUpdateSea }; /***/ }), -/* 25 */ +/* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4574,7 +4438,7 @@ function batchActions() { } /***/ }), -/* 26 */ +/* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4607,7 +4471,7 @@ function debouce(func, wait, immediate) { } /***/ }), -/* 27 */ +/* 26 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4622,7 +4486,7 @@ function handleFetchResponse(response) { } /***/ }), -/* 28 */ +/* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4633,7 +4497,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.savePosition = savePosition; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); @@ -4649,7 +4513,7 @@ function savePosition(claimId /*: string*/, outpoint /*: string*/, position /*: } /***/ }), -/* 29 */ +/* 28 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4663,11 +4527,11 @@ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = [ exports.claimsReducer = claimsReducer; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _lbryURI = __webpack_require__(3); +var _lbryURI = __webpack_require__(1); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } @@ -4938,7 +4802,7 @@ function claimsReducer() { } /***/ }), -/* 30 */ +/* 29 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -4952,15 +4816,15 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument exports.fileInfoReducer = fileInfoReducer; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _sort_options = __webpack_require__(31); +var _sort_options = __webpack_require__(30); var SORT_OPTIONS = _interopRequireWildcard(_sort_options); -var _pages = __webpack_require__(32); +var _pages = __webpack_require__(31); var PAGES = _interopRequireWildcard(_pages); @@ -5180,7 +5044,7 @@ function fileInfoReducer() { } /***/ }), -/* 31 */ +/* 30 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5195,7 +5059,7 @@ var TITLE = exports.TITLE = 'title'; var FILENAME = exports.FILENAME = 'filename'; /***/ }), -/* 32 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5227,7 +5091,7 @@ var HISTORY = exports.HISTORY = 'user_history'; var WALLET = exports.WALLET = 'wallet'; /***/ }), -/* 33 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5242,24 +5106,24 @@ var _handleActions; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _reduxUtils = __webpack_require__(34); +var _reduxUtils = __webpack_require__(33); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // @flow -/*:: import type { - NotificationState, - DoToast, - DoError, - DoNotification, - DoEditNotification, - DoDeleteNotification, +/*:: import type { + NotificationState, + DoToast, + DoError, + DoNotification, + DoEditNotification, + DoDeleteNotification, } from 'types/Notification';*/ @@ -5335,7 +5199,7 @@ var notificationsReducer = (0, _reduxUtils.handleActions)((_handleActions = {}, exports.notificationsReducer = notificationsReducer; /***/ }), -/* 34 */ +/* 33 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5368,7 +5232,7 @@ var handleActions = exports.handleActions = function handleActions(actionMap, de }; /***/ }), -/* 35 */ +/* 34 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5383,26 +5247,26 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument var _options, _handleActions; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); -var _reduxUtils = __webpack_require__(34); +var _reduxUtils = __webpack_require__(33); -var _search = __webpack_require__(14); +var _search = __webpack_require__(13); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // @flow -/*:: import type { - SearchState, - SearchSuccess, - UpdateSearchQuery, - UpdateSearchSuggestions, - HistoryNavigate, - UpdateSearchOptions, +/*:: import type { + SearchState, + SearchSuccess, + UpdateSearchQuery, + UpdateSearchSuggestions, + HistoryNavigate, + UpdateSearchOptions, } from 'types/Search';*/ @@ -5473,7 +5337,7 @@ var searchReducer = exports.searchReducer = (0, _reduxUtils.handleActions)((_han }), _handleActions), defaultState); /***/ }), -/* 36 */ +/* 35 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5484,7 +5348,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.walletReducer = walletReducer; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); @@ -5501,32 +5365,32 @@ var buildDraftTransaction = function buildDraftTransaction() { // TODO: Split into common success and failure types // See details in https://github.com/lbryio/lbry/issues/1307 -/*:: type ActionResult = { - type: any, - result: any, +/*:: type ActionResult = { + type: any, + result: any, };*/ -/*:: type WalletState = { - balance: any, - blocks: any, - latestBlock: ?number, - transactions: any, - fetchingTransactions: boolean, - gettingNewAddress: boolean, - draftTransaction: any, - sendingSupport: boolean, - walletIsEncrypted: boolean, - walletEncryptPending: boolean, - walletEncryptSucceded: ?boolean, - walletEncryptResult: ?boolean, - walletDecryptPending: boolean, - walletDecryptSucceded: ?boolean, - walletDecryptResult: ?boolean, - walletUnlockPending: boolean, - walletUnlockSucceded: ?boolean, - walletUnlockResult: ?boolean, - walletLockPending: boolean, - walletLockSucceded: ?boolean, - walletLockResult: ?boolean, +/*:: type WalletState = { + balance: any, + blocks: any, + latestBlock: ?number, + transactions: any, + fetchingTransactions: boolean, + gettingNewAddress: boolean, + draftTransaction: any, + sendingSupport: boolean, + walletIsEncrypted: boolean, + walletEncryptPending: boolean, + walletEncryptSucceded: ?boolean, + walletEncryptResult: ?boolean, + walletDecryptPending: boolean, + walletDecryptSucceded: ?boolean, + walletDecryptResult: ?boolean, + walletUnlockPending: boolean, + walletUnlockSucceded: ?boolean, + walletUnlockResult: ?boolean, + walletLockPending: boolean, + walletLockSucceded: ?boolean, + walletLockResult: ?boolean, };*/ @@ -5816,7 +5680,7 @@ function walletReducer() { } /***/ }), -/* 37 */ +/* 36 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5830,7 +5694,7 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument exports.contentReducer = contentReducer; -var _action_types = __webpack_require__(2); +var _action_types = __webpack_require__(3); var ACTIONS = _interopRequireWildcard(_action_types); @@ -5864,7 +5728,7 @@ function contentReducer() { } /***/ }), -/* 38 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5875,9 +5739,9 @@ Object.defineProperty(exports, "__esModule", { }); exports.makeSelectContentPositionForUri = exports.selectState = undefined; -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); -var _claims = __webpack_require__(12); +var _claims = __webpack_require__(11); var selectState = exports.selectState = function selectState(state /*: any*/) { return state.content || {}; @@ -5895,7 +5759,7 @@ var makeSelectContentPositionForUri = exports.makeSelectContentPositionForUri = }; /***/ }), -/* 39 */ +/* 38 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5908,7 +5772,7 @@ exports.selectError = exports.selectToast = exports.selectState = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -var _reselect = __webpack_require__(16); +var _reselect = __webpack_require__(15); var selectState = exports.selectState = function selectState(state) { return state.notifications || {}; @@ -5941,7 +5805,7 @@ var selectError = exports.selectError = (0, _reselect.createSelector)(selectStat }); /***/ }), -/* 40 */ +/* 39 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5957,7 +5821,7 @@ var COMPLETE = exports.COMPLETE = 'complete'; var MANUAL = exports.MANUAL = 'manual'; /***/ }), -/* 41 */ +/* 40 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -5967,7 +5831,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); /* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ -/* Many SETTINGS are stored in the localStorage by their name - +/* Many SETTINGS are stored in the localStorage by their name - be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ var CREDIT_REQUIRED_ACKNOWLEDGED = exports.CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; var NEW_USER_ACKNOWLEDGED = exports.NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; diff --git a/package.json b/package.json index 1c050bc..e1e2b54 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,9 @@ "name": "lbry-redux", "version": "0.0.1", "description": "Common shared components for desktop and mobile.", - "keywords": ["lbry"], + "keywords": [ + "lbry" + ], "license": "MIT", "homepage": "https://lbry.io/", "bugs": { @@ -17,8 +19,9 @@ "email": "hello@lbry.io" }, "main": "dist/bundle.js", + "module": "dist/bundle.es.js", "scripts": { - "build": "webpack", + "build": "rollup --config && webpack", "dev": "webpack --watch", "precommit": "lint-staged", "lint": "eslint 'src/**/*.js' --fix", @@ -50,6 +53,10 @@ "husky": "^0.14.3", "lint-staged": "^7.0.4", "prettier": "^1.4.2", + "rollup": "^1.8.0", + "rollup-plugin-babel": "3", + "rollup-plugin-flow": "^1.1.1", + "rollup-plugin-includepaths": "^0.2.3", "webpack": "^4.5.0", "webpack-cli": "^2.0.14" }, diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..6927f98 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,26 @@ +import babel from 'rollup-plugin-babel'; +import flow from 'rollup-plugin-flow'; +import includePaths from 'rollup-plugin-includepaths'; + +let includePathOptions = { + include: {}, + paths: ['src'], + external: [], + extensions: ['.js'] +}; + +export default { + input: 'src/index.js', + output: { + file: 'dist/bundle.es.js', + format: 'cjs' + }, + plugins: [ + flow({all: true}), + includePaths(includePathOptions), + babel({ + babelrc: false, + presets: ['stage-2'], + }), + ], +} diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 8a5132d..3800f87 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -59,6 +59,8 @@ export const WALLET_STATUS_START = 'WALLET_STATUS_START'; export const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; export const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; export const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; +export const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; +export const SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; // Claims export const RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED'; @@ -205,7 +207,10 @@ export const DO_PREPARE_EDIT = 'DO_PREPARE_EDIT'; export const CREATE_NOTIFICATION = 'CREATE_NOTIFICATION'; export const EDIT_NOTIFICATION = 'EDIT_NOTIFICATION'; export const DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'; +export const DISMISS_NOTIFICATION = 'DISMISS_NOTIFICATION'; export const CREATE_TOAST = 'CREATE_TOAST'; export const DISMISS_TOAST = 'DISMISS_TOAST'; export const CREATE_ERROR = 'CREATE_ERROR'; export const DISMISS_ERROR = 'DISMISS_ERROR'; + +export const FETCH_DATE = 'FETCH_DATE'; diff --git a/src/index.js b/src/index.js index ce2fdef..9efcbc7 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,7 @@ import Lbry from 'lbry'; import { selectState as selectSearchState } from 'redux/selectors/search'; // types -export { Toast } from 'types/Notification'; +// export { Toast } from 'types/Notification'; // constants export { @@ -141,10 +141,6 @@ export { selectFetchingMyChannels, selectMyChannelClaims, selectResolvingUris, - selectFeaturedUris, - selectFetchingFeaturedUris, - selectTrendingUris, - selectFetchingTrendingUris, selectPlayingUri, selectChannelClaimCounts, selectCurrentChannelPage, @@ -174,7 +170,6 @@ export { selectSearchOptions, selectIsSearching, selectSearchUrisByQuery, - selectWunderBarAddress, selectSearchBarFocused, selectSearchSuggestions, makeSelectQueryWithOptions, diff --git a/yarn.lock b/yarn.lock index f9ecac7..fe7a666 100644 --- a/yarn.lock +++ b/yarn.lock @@ -130,6 +130,16 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@^11.11.6": + version "11.13.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.0.tgz#b0df8d6ef9b5001b2be3a94d909ce3c29a80f9e1" + integrity sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng== + "@webassemblyjs/ast@1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.3.1.tgz#3081b4b3ff0af733aa5ba573af998f33711293f8" @@ -297,6 +307,11 @@ acorn@^5.0.0, acorn@^5.3.0, acorn@^5.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" integrity sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ== +acorn@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + agent-base@4, agent-base@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -1298,7 +1313,7 @@ babylon@7.0.0-beta.44: resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" integrity sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g== -babylon@^6.17.3, babylon@^6.18.0: +babylon@^6.15.0, babylon@^6.17.3, babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== @@ -2624,6 +2639,11 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estree-walker@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" + integrity sha1-va/oCVOD2EFNXcLs9MkXO225QS4= + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2933,6 +2953,14 @@ flow-parser@^0.*: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.72.0.tgz#6c8041e76ac7d0be1a71ce29c00cd1435fb6013c" integrity sha512-kFaDtviKlD/rHi6NRp42KTbnPgz/nKcWUJQhqDnLDeKA8uGcRVSy0YlQjaf9M3pFo5PgC3SNFnCPpQGLtHjH2w== +flow-remove-types@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-1.2.3.tgz#6131aefc7da43364bb8b479758c9dec7735d1a18" + integrity sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q== + dependencies: + babylon "^6.15.0" + vlq "^0.2.1" + flow-typed@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.1.tgz#0ff565cc94d2af8c557744ba364b6f14726a6b9f" @@ -6036,6 +6064,43 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup-plugin-babel@3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.7.tgz#5b13611f1ab8922497e9d15197ae5d8a23fe3b1e" + integrity sha512-bVe2y0z/V5Ax1qU8NX/0idmzIwJPdUGu8Xx3vXH73h0yGjxfv2gkFI82MBVg49SlsFlLTBadBHb67zy4TWM3hA== + dependencies: + rollup-pluginutils "^1.5.0" + +rollup-plugin-flow@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-flow/-/rollup-plugin-flow-1.1.1.tgz#6ce568f1dd559666b77ab76b4bae251407528db6" + integrity sha1-bOVo8d1Vlma3erdrS64lFAdSjbY= + dependencies: + flow-remove-types "^1.1.0" + rollup-pluginutils "^1.5.1" + +rollup-plugin-includepaths@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-includepaths/-/rollup-plugin-includepaths-0.2.3.tgz#244d21b9669a0debe476d825e4a02ed08c06b258" + integrity sha512-4QbSIZPDT+FL4SViEVCRi4cGCA64zQJu7u5qmCkO3ecHy+l9EQBsue15KfCpddfb6Br0q47V/v2+E2YUiqts9g== + +rollup-pluginutils@^1.5.0, rollup-pluginutils@^1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" + integrity sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg= + dependencies: + estree-walker "^0.2.1" + minimatch "^3.0.2" + +rollup@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.8.0.tgz#e3ce8b708ad4325166717f74f244f691595d35e2" + integrity sha512-dKxL6ihUZ9YrVySKf/LBz5joW2sqwWkiuki34279Ppr2cL+O6Za6Ujovk+rtTX0AFCIsH1rs6y8LYKdZZ/7C5A== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "^11.11.6" + acorn "^6.1.1" + run-async@^2.0.0, run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -6972,6 +7037,11 @@ vinyl@^2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" +vlq@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" + integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow== + vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"