From 7ab5a0c9785a4be93620fc4c57ed319ee93cb49f Mon Sep 17 00:00:00 2001 From: zeppi Date: Sun, 7 Aug 2022 16:37:51 -0400 Subject: [PATCH] remove redux user and rewards selectors, reducers, actions --- build/downloadLBRYFirst.js | 91 --- electron/LbryFirstInstance.js | 59 -- electron/index.js | 60 -- extras/lbry-first/lbry-first.js | 184 ------ extras/recsys/index.js | 3 - extras/recsys/recsys.js | 257 -------- ui/analytics.js | 4 - ui/component/app/index.js | 11 +- ui/component/app/view.jsx | 116 +--- ui/component/button/index.js | 3 - ui/component/button/view.jsx | 4 - ui/component/cardVerify/index.js | 11 - ui/component/cardVerify/view.jsx | 185 ------ ui/component/channelContent/index.js | 2 - ui/component/channelContent/view.jsx | 1 - ui/component/channelForm/index.js | 5 - ui/component/channelForm/view.jsx | 28 +- ui/component/comment/index.js | 2 - ui/component/comment/view.jsx | 4 +- ui/component/creatorAnalytics/view.jsx | 25 - ui/component/emailCollection/index.js | 20 - ui/component/emailCollection/view.jsx | 40 -- ui/component/fileDetails/index.js | 2 - ui/component/fileDetails/view.jsx | 1 - ui/component/fileRenderInline/index.js | 2 - ui/component/fileRenderInline/view.jsx | 17 +- ui/component/header/index.js | 6 - ui/component/header/view.jsx | 12 +- ui/component/headerMenuButtons/index.js | 2 - ui/component/headerMenuButtons/view.jsx | 5 +- .../headerNotificationButton/index.js | 2 - .../headerNotificationButton/view.jsx | 5 +- ui/component/headerProfileMenuButton/index.js | 11 +- ui/component/headerProfileMenuButton/view.jsx | 14 +- ui/component/notificationBubble/index.js | 2 - ui/component/notificationBubble/view.jsx | 5 +- ui/component/nudgeFloating/index.js | 8 +- ui/component/nudgeFloating/view.jsx | 8 +- ui/component/privacyAgreement/index.js | 14 +- ui/component/privacyAgreement/view.jsx | 23 +- .../publishAdditionalOptions/index.js | 5 - .../publishAdditionalOptions/view.jsx | 120 +--- ui/component/publishForm/index.js | 12 - ui/component/publishForm/view.jsx | 27 +- ui/component/recommendedContent/view.jsx | 32 +- ui/component/router/index.js | 6 - ui/component/router/view.jsx | 39 +- ui/component/selectChannel/index.js | 2 - ui/component/settingAccount/index.js | 3 - ui/component/settingAccount/view.jsx | 25 +- ui/component/settingAccountPassword/index.js | 17 - ui/component/settingAccountPassword/view.jsx | 81 --- ui/component/settingContent/index.js | 2 - ui/component/settingContent/view.jsx | 9 +- ui/component/settingSystem/index.js | 2 - ui/component/settingSystem/view.jsx | 9 +- ui/component/sideNavigation/index.js | 3 - ui/component/sideNavigation/view.jsx | 25 +- ui/component/socialShare/view.jsx | 2 - ui/component/subscribeButton/index.js | 2 - ui/component/subscribeButton/view.jsx | 4 +- ui/component/syncEnableFlow/index.js | 2 - ui/component/syncPassword/index.js | 7 +- ui/component/syncPassword/view.jsx | 4 +- ui/component/syncToggle/index.js | 2 - ui/component/syncToggle/view.jsx | 22 +- ui/component/tagsSearch/index.js | 2 - ui/component/tagsSearch/view.jsx | 5 +- ui/component/transactionListTable/index.js | 2 - ui/component/transactionListTable/view.jsx | 4 +- ui/component/userEmail/index.js | 18 - ui/component/userEmail/view.jsx | 73 --- ui/component/userEmailNew/index.js | 14 +- ui/component/userEmailNew/view.jsx | 139 +---- ui/component/userEmailReturning/index.js | 27 - ui/component/userEmailReturning/view.jsx | 147 ----- ui/component/userEmailVerify/index.js | 25 - ui/component/userEmailVerify/view.jsx | 121 ---- ui/component/userFirstChannel/index.js | 3 - ui/component/userFirstChannel/view.jsx | 14 +- ui/component/userPasswordReset/index.js | 24 - ui/component/userPasswordReset/view.jsx | 112 ---- ui/component/userPasswordSet/index.js | 16 - ui/component/userPasswordSet/view.jsx | 108 ---- ui/component/userSignIn/index.js | 15 - ui/component/userSignIn/view.jsx | 58 -- ui/component/userSignInPassword/index.js | 23 - ui/component/userSignInPassword/view.jsx | 67 -- ui/component/userSignOutButton/index.js | 12 - ui/component/userSignOutButton/view.jsx | 29 - ui/component/userSignUp/index.js | 65 -- ui/component/userSignUp/view.jsx | 232 ------- ui/component/viewers/videoViewer/index.js | 14 +- .../internal/plugins/videojs-recsys/plugin.js | 178 ------ .../viewers/videoViewer/internal/videojs.jsx | 23 +- ui/component/viewers/videoViewer/view.jsx | 47 +- ui/component/walletBalance/index.js | 2 - ui/component/youtubeTransferStatus/index.js | 24 - ui/component/youtubeTransferStatus/view.jsx | 235 ------- ui/constants/modal_types.js | 6 - ui/index.jsx | 14 - ui/modal/modalFirstReward/index.js | 19 - ui/modal/modalFirstReward/view.jsx | 38 -- ui/modal/modalFirstSubscription/index.js | 17 - ui/modal/modalFirstSubscription/view.jsx | 73 --- ui/modal/modalPublish/view.jsx | 19 +- ui/modal/modalRewardCode/index.js | 21 - ui/modal/modalRewardCode/view.jsx | 91 --- ui/modal/modalRouter/view.jsx | 9 - ui/page/buy/index.js | 18 - ui/page/buy/view.jsx | 197 ------ ui/page/channel/index.js | 2 - ui/page/channel/view.jsx | 23 - ui/page/channelNew/index.js | 13 +- ui/page/channelNew/view.jsx | 10 +- ui/page/channels/index.js | 16 +- ui/page/channels/view.jsx | 52 +- ui/page/collection/index.js | 2 - ui/page/collection/view.jsx | 1 - ui/page/help/index.js | 14 +- ui/page/help/view.jsx | 71 +-- ui/page/passwordReset/index.js | 3 - ui/page/passwordReset/view.jsx | 12 - ui/page/passwordSet/index.js | 3 - ui/page/passwordSet/view.jsx | 12 - ui/page/passwordUpdate/view.jsx | 11 +- ui/page/publish/index.js | 2 - ui/page/settingsNotifications/index.js | 2 - ui/page/settingsNotifications/view.jsx | 199 +----- ui/page/signIn/index.js | 3 - ui/page/signIn/view.jsx | 12 - ui/page/signInVerify/index.js | 10 - ui/page/signInVerify/view.jsx | 138 ----- ui/page/signUp/index.js | 3 - ui/page/signUp/view.jsx | 12 - ui/reducers.js | 4 - ui/redux/actions/app.js | 118 +--- ui/redux/actions/publish.js | 11 +- ui/redux/actions/rewards.js | 182 ------ ui/redux/actions/subscriptions.js | 27 - ui/redux/actions/sync.js | 7 +- ui/redux/actions/user.js | 575 ------------------ ui/redux/actions/websocket.js | 23 - ui/redux/middleware/shared-state.js | 90 ++- ui/redux/reducers/publish.js | 2 - ui/redux/reducers/rewards.js | 111 ---- ui/redux/reducers/user.js | 381 ------------ ui/redux/selectors/search.js | 32 +- ui/redux/selectors/user.js | 127 ---- ui/rewards.js | 126 ---- ui/store.js | 35 +- ui/util/saved-passwords.js | 3 +- ui/util/url.js | 13 +- webpack.base.config.js | 1 - 154 files changed, 201 insertions(+), 6411 deletions(-) delete mode 100644 build/downloadLBRYFirst.js delete mode 100644 electron/LbryFirstInstance.js delete mode 100644 extras/lbry-first/lbry-first.js delete mode 100644 extras/recsys/index.js delete mode 100644 extras/recsys/recsys.js delete mode 100644 ui/component/cardVerify/index.js delete mode 100644 ui/component/cardVerify/view.jsx delete mode 100644 ui/component/emailCollection/index.js delete mode 100644 ui/component/emailCollection/view.jsx delete mode 100644 ui/component/settingAccountPassword/index.js delete mode 100644 ui/component/settingAccountPassword/view.jsx delete mode 100644 ui/component/userEmail/index.js delete mode 100644 ui/component/userEmail/view.jsx delete mode 100644 ui/component/userEmailReturning/index.js delete mode 100644 ui/component/userEmailReturning/view.jsx delete mode 100644 ui/component/userEmailVerify/index.js delete mode 100644 ui/component/userEmailVerify/view.jsx delete mode 100644 ui/component/userPasswordReset/index.js delete mode 100644 ui/component/userPasswordReset/view.jsx delete mode 100644 ui/component/userPasswordSet/index.js delete mode 100644 ui/component/userPasswordSet/view.jsx delete mode 100644 ui/component/userSignIn/index.js delete mode 100644 ui/component/userSignIn/view.jsx delete mode 100644 ui/component/userSignInPassword/index.js delete mode 100644 ui/component/userSignInPassword/view.jsx delete mode 100644 ui/component/userSignOutButton/index.js delete mode 100644 ui/component/userSignOutButton/view.jsx delete mode 100644 ui/component/userSignUp/index.js delete mode 100644 ui/component/userSignUp/view.jsx delete mode 100644 ui/component/viewers/videoViewer/internal/plugins/videojs-recsys/plugin.js delete mode 100644 ui/component/youtubeTransferStatus/index.js delete mode 100644 ui/component/youtubeTransferStatus/view.jsx delete mode 100644 ui/modal/modalFirstReward/index.js delete mode 100644 ui/modal/modalFirstReward/view.jsx delete mode 100644 ui/modal/modalFirstSubscription/index.js delete mode 100644 ui/modal/modalFirstSubscription/view.jsx delete mode 100644 ui/modal/modalRewardCode/index.js delete mode 100644 ui/modal/modalRewardCode/view.jsx delete mode 100644 ui/page/buy/index.js delete mode 100644 ui/page/buy/view.jsx delete mode 100644 ui/page/passwordReset/index.js delete mode 100644 ui/page/passwordReset/view.jsx delete mode 100644 ui/page/passwordSet/index.js delete mode 100644 ui/page/passwordSet/view.jsx delete mode 100644 ui/page/signIn/index.js delete mode 100644 ui/page/signIn/view.jsx delete mode 100644 ui/page/signInVerify/index.js delete mode 100644 ui/page/signInVerify/view.jsx delete mode 100644 ui/page/signUp/index.js delete mode 100644 ui/page/signUp/view.jsx delete mode 100644 ui/redux/actions/rewards.js delete mode 100644 ui/redux/actions/user.js delete mode 100644 ui/redux/reducers/rewards.js delete mode 100644 ui/redux/reducers/user.js delete mode 100644 ui/redux/selectors/user.js delete mode 100644 ui/rewards.js diff --git a/build/downloadLBRYFirst.js b/build/downloadLBRYFirst.js deleted file mode 100644 index 2c36dd736..000000000 --- a/build/downloadLBRYFirst.js +++ /dev/null @@ -1,91 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const packageJSON = require('../package.json'); -const fetch = require('node-fetch'); -const decompress = require('decompress'); -const os = require('os'); -const del = require('del'); - -const downloadLBRYFirst = targetPlatform => - new Promise((resolve, reject) => { - const lbryFirstURLTemplate = packageJSON.lbrySettings.LBRYFirstUrlTemplate; - const lbryFirstVersion = packageJSON.lbrySettings.LBRYFirstVersion; - const lbryFirstDir = path.join(__dirname, '..', packageJSON.lbrySettings.LBRYFirstDir); - let lbryFirstFileName = packageJSON.lbrySettings.LBRYFirstFileName; - - const currentPlatform = os.platform(); - - let lbryFirstPlatform = process.env.TARGET || targetPlatform || currentPlatform; - if (lbryFirstPlatform === 'linux') lbryFirstPlatform = 'Linux'; - if (lbryFirstPlatform === 'mac' || lbryFirstPlatform === 'darwin') lbryFirstPlatform = 'Darwin'; - if (lbryFirstPlatform === 'win32' || lbryFirstPlatform === 'windows') { - lbryFirstPlatform = 'Windows'; - lbryFirstFileName += '.exe'; - } - const lbryFirstFilePath = path.join(lbryFirstDir, lbryFirstFileName); - const lbryFirstVersionPath = path.join(__dirname, 'lbryFirst.ver'); - const tmpZipPath = path.join(__dirname, '..', 'dist', 'lbryFirst.zip'); - const lbryFirstURL = lbryFirstURLTemplate.replace(/LBRYFIRSTVER/g, lbryFirstVersion).replace(/OSNAME/g, lbryFirstPlatform); - console.log('URL:', lbryFirstURL); - - // If a lbryFirst and lbryFirst.ver exists, check to see if it matches the current lbryFirst version - const hasLbryFirstDownloaded = fs.existsSync(lbryFirstFilePath); - const hasLbryFirstVersion = fs.existsSync(lbryFirstVersionPath); - let downloadedLbryFirstVersion; - - if (hasLbryFirstVersion) { - downloadedLbryFirstVersion = fs.readFileSync(lbryFirstVersionPath, 'utf8'); - } - - if (hasLbryFirstDownloaded && hasLbryFirstVersion && downloadedLbryFirstVersion === lbryFirstVersion) { - console.log('\x1b[34minfo\x1b[0m LbryFirst already downloaded'); - resolve('Done'); - } else { - console.log('\x1b[34minfo\x1b[0m Downloading lbryFirst...'); - fetch(lbryFirstURL, { - method: 'GET', - headers: { - 'Content-Type': 'application/zip', - }, - }) - .then(response => response.buffer()) - .then( - result => - new Promise((newResolve, newReject) => { - const distPath = path.join(__dirname, '..', 'dist'); - const hasDistFolder = fs.existsSync(distPath); - - if (!hasDistFolder) { - fs.mkdirSync(distPath); - } - - fs.writeFile(tmpZipPath, result, error => { - if (error) return newReject(error); - return newResolve(); - }); - }) - ) - .then(() => del(`${lbryFirstFilePath}*`)) - .then() - .then(() => - decompress(tmpZipPath, lbryFirstDir, { - filter: file => path.basename(file.path) === lbryFirstFileName, - }) - ) - .then(() => { - console.log('\x1b[32msuccess\x1b[0m LbryFirst downloaded!'); - if (hasLbryFirstVersion) { - del(lbryFirstVersionPath); - } - - fs.writeFileSync(lbryFirstVersionPath, lbryFirstVersion, 'utf8'); - resolve('Done'); - }) - .catch(error => { - console.error(`\x1b[31merror\x1b[0m LbryFirst download failed due to: \x1b[35m${error}\x1b[0m`); - reject(error); - }); - } - }); - -downloadLBRYFirst(); diff --git a/electron/LbryFirstInstance.js b/electron/LbryFirstInstance.js deleted file mode 100644 index 191d81ef4..000000000 --- a/electron/LbryFirstInstance.js +++ /dev/null @@ -1,59 +0,0 @@ -import path from 'path'; -import { spawn, execSync } from 'child_process'; - -export default class LbryFirstInstance { - static lbryFirstPath = - process.env.LBRY_FIRST_DAEMON || - (process.env.NODE_ENV === 'production' - ? path.join(process.resourcesPath, 'static/lbry-first', 'lbry-first') - : path.join(__static, 'lbry-first/lbry-first')); - - static headersPath = - process.env.LBRY_FIRST_DAEMON || - (process.env.NODE_ENV === 'production' - ? path.join(process.resourcesPath, 'static/lbry-first', 'headers') - : path.join(__static, 'lbry-first/headers')); - - subprocess; - handlers; - - constructor() { - this.handlers = []; - } - - launch() { - let flags = ['serve']; - console.log(`LbryFirst: ${LbryFirstInstance.lbryFirstPath}`); - this.subprocess = spawn(LbryFirstInstance.lbryFirstPath, flags); - this.subprocess.stdout.on('data', data => console.log(`LbryFirst: ${data}`)); - this.subprocess.stderr.on('data', data => console.error(`LbryFirst: ${data}`)); - this.subprocess.on('exit', () => this.fire('exit')); - this.subprocess.on('error', error => console.error(`LbryFirst error: ${error}`)); - } - - quit() { - if (process.platform === 'win32') { - try { - execSync(`taskkill /pid ${this.subprocess.pid} /t /f`); - } catch (error) { - console.error(error.message); - } - } else { - this.subprocess.kill(); - } - } - - // Follows the publish/subscribe pattern - - // Subscribe method - on(event, handler, context = handler) { - this.handlers.push({ event, handler: handler.bind(context) }); - } - - // Publish method - fire(event, args) { - this.handlers.forEach(topic => { - if (topic.event === event) topic.handler(args); - }); - } -} diff --git a/electron/index.js b/electron/index.js index da43fdc6c..db0a27cb8 100644 --- a/electron/index.js +++ b/electron/index.js @@ -7,7 +7,6 @@ import https from 'https'; import { app, dialog, ipcMain, session, shell, BrowserWindow } from 'electron'; import { autoUpdater } from 'electron-updater'; import Lbry from 'lbry'; -import LbryFirstInstance from './LbryFirstInstance'; import Daemon from './Daemon'; import isDev from 'electron-is-dev'; import createTray from './createTray'; @@ -58,7 +57,6 @@ let rendererWindow; let tray; // eslint-disable-line let daemon; -let lbryFirst; const appState = {}; const PROTOCOL = 'lbry'; @@ -115,51 +113,6 @@ const startDaemon = async () => { } }; -let isLbryFirstRunning = false; -const startLbryFirst = async () => { - if (isLbryFirstRunning) { - console.log('LbryFirst already running'); - handleLbryFirstLaunched(); - return; - } - - console.log('LbryFirst: Starting...'); - - try { - lbryFirst = new LbryFirstInstance(); - lbryFirst.on('exit', e => { - if (!isDev) { - lbryFirst = null; - isLbryFirstRunning = false; - if (!appState.isQuitting) { - dialog.showErrorBox( - 'LbryFirst has Exited', - 'The lbryFirst may have encountered an unexpected error, or another lbryFirst instance is already running. \n\n', - e - ); - } - app.quit(); - } - }); - } catch (e) { - console.log('LbryFirst: Failed to create new instance\n\n', e); - } - - console.log('LbryFirst: Running...'); - - try { - await lbryFirst.launch(); - handleLbryFirstLaunched(); - } catch (e) { - isLbryFirstRunning = false; - console.log('LbryFirst: Failed to start\n', e); - } -}; - -const handleLbryFirstLaunched = () => { - isLbryFirstRunning = true; - rendererWindow.webContents.send('lbry-first-launched'); -}; // When we are starting the app, ensure there are no other apps already running const gotSingleInstanceLock = app.requestSingleInstanceLock(); @@ -271,10 +224,6 @@ app.on('will-quit', event => { daemon.quit(); event.preventDefault(); } - if (lbryFirst) { - lbryFirst.quit(); - event.preventDefault(); - } if (rendererWindow) { tray.destroy(); @@ -453,15 +402,6 @@ ipcMain.on('version-info-requested', () => { requestLatestRelease(); }); -ipcMain.on('launch-lbry-first', async () => { - try { - await startLbryFirst(); - } catch (e) { - console.log('Failed to start LbryFirst'); - console.log(e); - } -}); - process.on('uncaughtException', error => { console.log(error); dialog.showErrorBox('Error Encountered', `Caught error: ${error}`); diff --git a/extras/lbry-first/lbry-first.js b/extras/lbry-first/lbry-first.js deleted file mode 100644 index a6025b753..000000000 --- a/extras/lbry-first/lbry-first.js +++ /dev/null @@ -1,184 +0,0 @@ -// @flow -/* - LBRY FIRST does not work due to api changes - */ -import 'proxy-polyfill'; - -const CHECK_LBRYFIRST_STARTED_TRY_NUMBER = 200; -// -// Basic LBRYFIRST connection config -// Offers a proxy to call LBRYFIRST methods - -// -const LbryFirst: LbryFirstTypes = { - isConnected: false, - connectPromise: null, - lbryFirstConnectionString: 'http://localhost:1337/rpc', - apiRequestHeaders: { 'Content-Type': 'application/json' }, - - // Allow overriding lbryFirst connection string (e.g. to `/api/proxy` for lbryweb) - setLbryFirstConnectionString: (value: string) => { - LbryFirst.lbryFirstConnectionString = value; - }, - - setApiHeader: (key: string, value: string) => { - LbryFirst.apiRequestHeaders = Object.assign(LbryFirst.apiRequestHeaders, { [key]: value }); - }, - - unsetApiHeader: key => { - Object.keys(LbryFirst.apiRequestHeaders).includes(key) && - delete LbryFirst.apiRequestHeaders['key']; - }, - // Allow overriding Lbry methods - overrides: {}, - setOverride: (methodName, newMethod) => { - LbryFirst.overrides[methodName] = newMethod; - }, - getApiRequestHeaders: () => LbryFirst.apiRequestHeaders, - - // LbryFirst Methods - status: (params = {}) => lbryFirstCallWithResult('status', params), - stop: () => lbryFirstCallWithResult('stop', {}), - version: () => lbryFirstCallWithResult('version', {}), - - // Upload to youtube - upload: (params: { title: string, description: string, file_path: ?string } = {}) => { - // Only upload when originally publishing for now - if (!params.file_path) { - return Promise.resolve(); - } - - const uploadParams: { - Title: string, - Description: string, - FilePath: string, - Category: string, - Keywords: string, - } = { - Title: params.title, - Description: params.description, - FilePath: params.file_path, - Category: '', - Keywords: '', - }; - - return lbryFirstCallWithResult('youtube.Upload', uploadParams); - }, - - hasYTAuth: (token: string) => { - const hasYTAuthParams = {}; - hasYTAuthParams.AuthToken = token; - return lbryFirstCallWithResult('youtube.HasAuth', hasYTAuthParams); - }, - - ytSignup: () => { - const emptyParams = {}; - return lbryFirstCallWithResult('youtube.Signup', emptyParams); - }, - - remove: () => { - const emptyParams = {}; - return lbryFirstCallWithResult('youtube.Remove', emptyParams); - }, - - // Connect to lbry-first - connect: () => { - if (LbryFirst.connectPromise === null) { - LbryFirst.connectPromise = new Promise((resolve, reject) => { - let tryNum = 0; - // Check every half second to see if the lbryFirst is accepting connections - function checkLbryFirstStarted() { - tryNum += 1; - LbryFirst.status() - .then(resolve) - .catch(() => { - if (tryNum <= CHECK_LBRYFIRST_STARTED_TRY_NUMBER) { - setTimeout(checkLbryFirstStarted, tryNum < 50 ? 400 : 1000); - } else { - reject(new Error('Unable to connect to LBRY')); - } - }); - } - - checkLbryFirstStarted(); - }); - } - - // Flow thinks this could be empty, but it will always return a promise - // $FlowFixMe - return LbryFirst.connectPromise; - }, -}; - -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); - }); -} - -export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { - const counter = new Date().getTime(); - const paramsArray = [params]; - const options = { - method: 'POST', - headers: LbryFirst.apiRequestHeaders, - body: JSON.stringify({ - jsonrpc: '2.0', - method, - params: paramsArray, - id: counter, - }), - }; - - return fetch(LbryFirst.lbryFirstConnectionString, 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); -} - -function lbryFirstCallWithResult(name: string, params: ?{} = {}) { - return new Promise((resolve, reject) => { - apiCall( - name, - params, - result => { - resolve(result); - }, - reject - ); - }); -} - -// This is only for a fallback -// If there is a LbryFirst method that is being called by an app, it should be added to /flow-typed/LbryFirst.js -const lbryFirstProxy = new Proxy(LbryFirst, { - get(target: LbryFirstTypes, name: string) { - if (name in target) { - return target[name]; - } - - return (params = {}) => - new Promise((resolve, reject) => { - apiCall(name, params, resolve, reject); - }); - }, -}); - -export default lbryFirstProxy; diff --git a/extras/recsys/index.js b/extras/recsys/index.js deleted file mode 100644 index 26572300d..000000000 --- a/extras/recsys/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Recsys from './recsys'; - -export default Recsys; diff --git a/extras/recsys/recsys.js b/extras/recsys/recsys.js deleted file mode 100644 index 9a8811332..000000000 --- a/extras/recsys/recsys.js +++ /dev/null @@ -1,257 +0,0 @@ -import { selectUser } from 'redux/selectors/user'; -import { makeSelectRecommendedRecsysIdForClaimId } from 'redux/selectors/search'; -import { v4 as Uuidv4 } from 'uuid'; -import { parseURI } from 'util/lbryURI'; -import * as SETTINGS from 'constants/settings'; -import { makeSelectClaimForUri } from 'redux/selectors/claims'; -import { selectPlayingUri, selectPrimaryUri } from 'redux/selectors/content'; -import { makeSelectClientSetting, selectDaemonSettings } from 'redux/selectors/settings'; -import { history } from 'ui/store'; - -const recsysEndpoint = 'https://clickstream.odysee.com/log/video/view'; -const recsysId = 'lighthouse-v0'; - -const getClaimIdsFromUris = (uris) => { - return uris - ? uris.map((uri) => { - try { - const { claimId } = parseURI(uri); - return claimId; - } catch (e) { - return []; - } - }) - : []; -}; - -const recsys = { - entries: {}, - debug: false, - /** - * Provides for creating, updating, and sending Clickstream data object Entries. - * Entries are Created either when recommendedContent loads, or when recommendedContent is clicked. - * If recommended content is clicked, An Entry with parentUuid is created. - * On page load, find an empty entry with your claimId, or create a new entry and record to it. - * The entry will be populated with the following: - * - parentUuid // optional - * - Uuid - * - claimId - * - recommendedClaims [] // optionally empty - * - playerEvents [] // optionally empty - * - recommendedClaimsIndexClicked [] // optionally empty - * - UserId - * - pageLoadedAt - * - isEmbed - * - pageExitedAt - * - recsysId // optional - */ - - /** - * Function: onClickedRecommended() - * Called when RecommendedContent was clicked. - * Adds index of clicked recommendation to parent entry - * Adds new Entry with parentUuid for destination page - * @param parentClaimId: string, - * @param newClaimId: string, - */ - onClickedRecommended: function (parentClaimId, newClaimId) { - const parentEntry = recsys.entries[parentClaimId] ? recsys.entries[parentClaimId] : null; - const parentUuid = parentEntry['uuid']; - const parentRecommendedClaims = parentEntry['recClaimIds'] || []; - const parentClickedIndexes = parentEntry['recClickedVideoIdx'] || []; - const indexClicked = parentRecommendedClaims.indexOf(newClaimId); - - if (parentUuid) { - recsys.createRecsysEntry(newClaimId, parentUuid); - } - parentClickedIndexes.push(indexClicked); - recsys.log('onClickedRecommended', { parentClaimId, newClaimId }); - }, - - /** - * Page was loaded. Get or Create entry and populate it with default data, plus recommended content, recsysId, etc. - * Called from recommendedContent component - */ - onRecsLoaded: function (claimId, uris) { - if (window.store) { - const state = window.store.getState(); - if (!recsys.entries[claimId]) { - recsys.createRecsysEntry(claimId); - } - const claimIds = getClaimIdsFromUris(uris); - recsys.entries[claimId]['recsysId'] = makeSelectRecommendedRecsysIdForClaimId(claimId)(state) || recsysId; - recsys.entries[claimId]['pageLoadedAt'] = Date.now(); - recsys.entries[claimId]['recClaimIds'] = claimIds; - } - recsys.log('onRecsLoaded', claimId); - }, - - /** - * Creates an Entry with optional parentUuid - * @param: claimId: string - * @param: parentUuid: string (optional) - */ - createRecsysEntry: function (claimId, parentUuid) { - if (window.store && claimId) { - const state = window.store.getState(); - const user = selectUser(state); - const userId = user ? user.id : null; - if (parentUuid) { - // Make a stub entry that will be filled out on page load - recsys.entries[claimId] = { - uuid: Uuidv4(), - parentUuid: parentUuid, - uid: userId || null, // selectUser - claimId: claimId, - recClickedVideoIdx: [], - pageLoadedAt: Date.now(), - events: [], - }; - } else { - recsys.entries[claimId] = { - uuid: Uuidv4(), - uid: userId, // selectUser - claimId: claimId, - pageLoadedAt: Date.now(), - recsysId: null, - recClaimIds: [], - recClickedVideoIdx: [], - events: [], - }; - } - } - recsys.log('createRecsysEntry', claimId); - }, - - /** - * Send event for claimId - * @param claimId - * @param isTentative - */ - sendRecsysEntry: function (claimId, isTentative) { - const shareTelemetry = - IS_WEB || (window && window.store && selectDaemonSettings(window.store.getState()).share_usage_data); - - if (recsys.entries[claimId] && shareTelemetry) { - const data = JSON.stringify(recsys.entries[claimId]); - try { - navigator.sendBeacon(recsysEndpoint, data); - if (!isTentative) { - delete recsys.entries[claimId]; - } - } catch (error) { - console.log('no beacon for you', error); - } - } - recsys.log('sendRecsysEntry', claimId); - }, - - /** - * A player event fired. Get the Entry for the claimId, and add the events - * @param claimId - * @param event - */ - onRecsysPlayerEvent: function (claimId, event, isEmbedded) { - if (!recsys.entries[claimId]) { - recsys.createRecsysEntry(claimId); - // do something to show it's floating or autoplay - } - if (isEmbedded) { - recsys.entries[claimId]['isEmbed'] = true; - } - recsys.entries[claimId].events.push(event); - recsys.log('onRecsysPlayerEvent', claimId); - }, - log: function (callName, claimId) { - if (recsys.debug) { - console.log(`Call: ***${callName}***, ClaimId: ${claimId}, Recsys Entries`, Object.assign({}, recsys.entries)); - } - }, - - /** - * Player closed. Check to see if primaryUri = playingUri - * if so, send the Entry. - */ - onPlayerDispose: function (claimId, isEmbedded) { - if (window.store) { - const state = window.store.getState(); - const playingUri = selectPlayingUri(state); - const primaryUri = selectPrimaryUri(state); - const onFilePage = playingUri === primaryUri; - if (!onFilePage || isEmbedded) { - if (isEmbedded) { - recsys.entries[claimId]['isEmbed'] = true; - } - recsys.sendRecsysEntry(claimId); - } - } - recsys.log('PlayerDispose', claimId); - }, - - // /** - // * File page unmount or change event - // * Check to see if playingUri, floatingEnabled, primaryUri === playingUri - // * If not, send the Entry. - // * If floating enabled, leaving file page will pop out player, leading to - // * more events until player is disposed. Don't send unless floatingPlayer playingUri - // */ - // onLeaveFilePage: function (primaryUri) { - // if (window.store) { - // const state = window.store.getState(); - // const claim = makeSelectClaimForUri(primaryUri)(state); - // const claimId = claim ? claim.claim_id : null; - // const playingUri = selectPlayingUri(state); - // const actualPlayingUri = playingUri && playingUri.uri; - // // const primaryUri = selectPrimaryUri(state); - // const floatingPlayer = makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state); - // // When leaving page, if floating player is enabled, play will continue. - // if (claimId) { - // recsys.entries[claimId]['pageExitedAt'] = Date.now(); - // } - // const shouldSend = - // (claimId && floatingPlayer && actualPlayingUri && actualPlayingUri !== primaryUri) || !floatingPlayer || !actualPlayingUri; - // if (shouldSend) { - // recsys.sendRecsysEntry(claimId); - // } - // recsys.log('LeaveFile', claimId); - // } - // }, - - /** - * Navigate event - * Send all claimIds that aren't currently playing. - */ - onNavigate: function () { - if (window.store) { - const state = window.store.getState(); - const playingUri = selectPlayingUri(state); - const actualPlayingUri = playingUri && playingUri.uri; - const claim = makeSelectClaimForUri(actualPlayingUri)(state); - const playingClaimId = claim ? claim.claim_id : null; - // const primaryUri = selectPrimaryUri(state); - const floatingPlayer = makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state); - // When leaving page, if floating player is enabled, play will continue. - Object.keys(recsys.entries).forEach((claimId) => { - const shouldSkip = recsys.entries[claimId].parentUuid && !recsys.entries[claimId].recClaimIds; - if (!shouldSkip && ((claimId !== playingClaimId && floatingPlayer) || !floatingPlayer)) { - recsys.entries[claimId]['pageExitedAt'] = Date.now(); - recsys.sendRecsysEntry(claimId); - } - recsys.log('OnNavigate', claimId); - }); - } - }, -}; -// @if TARGET='web' -document.addEventListener('visibilitychange', function logData() { - if (document.visibilityState === 'hidden') { - Object.keys(recsys.entries).map((claimId) => recsys.sendRecsysEntry(claimId, true)); - } -}); -// @endif - -history.listen(() => { - recsys.onNavigate(); -}); - -export default recsys; diff --git a/ui/analytics.js b/ui/analytics.js index 132589d64..46db94fa2 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -51,7 +51,6 @@ type Analytics = { ) => Promise, emailProvidedEvent: () => void, emailVerifiedEvent: () => void, - rewardEligibleEvent: () => void, startupEvent: () => void, purchaseEvent: (number) => void, readyEvent: (number) => void, @@ -355,9 +354,6 @@ const analytics: Analytics = { emailVerifiedEvent: () => { sendMatomoEvent('Engagement', 'Email-Verified'); }, - rewardEligibleEvent: () => { - sendMatomoEvent('Engagement', 'Reward-Eligible'); - }, openUrlEvent: (url: string) => { sendMatomoEvent('Engagement', 'Open-Url', url); }, diff --git a/ui/component/app/index.js b/ui/component/app/index.js index 4726fe72c..3a27dc1d4 100644 --- a/ui/component/app/index.js +++ b/ui/component/app/index.js @@ -1,9 +1,6 @@ import { hot } from 'react-hot-loader/root'; import { connect } from 'react-redux'; import { selectGetSyncErrorMessage, selectSyncFatalError } from 'redux/selectors/sync'; -import { doFetchAccessToken, doUserSetReferrer } from 'redux/actions/user'; -import { selectUser, selectAccessToken, selectUserVerifiedEmail } from 'redux/selectors/user'; -import { selectUnclaimedRewards } from 'redux/selectors/rewards'; import { doFetchChannelListMine, doFetchCollectionListMine, doResolveUris } from 'redux/actions/claims'; import { selectMyChannelUrls, selectMyChannelClaimIds } from 'redux/selectors/claims'; import * as SETTINGS from 'constants/settings'; @@ -25,7 +22,7 @@ import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings import { doSyncLoop } from 'redux/actions/sync'; import { doDownloadUpgradeRequested, - doSignIn, + doSignIn, // huh doGetAndPopulatePreferences, doSetActiveChannel, doSetIncognito, @@ -34,8 +31,6 @@ import { doFetchModBlockedList, doFetchCommentModAmIList } from 'redux/actions/c import App from './view'; const select = (state) => ({ - user: selectUser(state), - accessToken: selectAccessToken(state), theme: selectThemePath(state), language: selectLanguage(state), syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state), @@ -43,8 +38,6 @@ const select = (state) => ({ autoUpdateDownloaded: selectAutoUpdateDownloaded(state), isUpgradeAvailable: selectIsUpgradeAvailable(state), syncError: selectGetSyncErrorMessage(state), - rewards: selectUnclaimedRewards(state), - isAuthenticated: selectUserVerifiedEmail(state), currentModal: selectModal(state), syncFatalError: selectSyncFatalError(state), activeChannelClaim: selectActiveChannelClaim(state), @@ -55,7 +48,6 @@ const select = (state) => ({ }); const perform = (dispatch) => ({ - fetchAccessToken: () => dispatch(doFetchAccessToken()), fetchChannelListMine: () => dispatch(doFetchChannelListMine()), fetchCollectionListMine: () => dispatch(doFetchCollectionListMine()), setLanguage: (language) => dispatch(doSetLanguage(language)), @@ -64,7 +56,6 @@ const perform = (dispatch) => ({ updatePreferences: () => dispatch(doGetAndPopulatePreferences()), getWalletSyncPref: () => dispatch(doGetWalletSyncPreference()), syncLoop: (noInterval) => dispatch(doSyncLoop(noInterval)), - setReferrer: (referrer, doClaim) => dispatch(doUserSetReferrer(referrer, doClaim)), setActiveChannelIfNotSet: () => dispatch(doSetActiveChannel()), setIncognito: () => dispatch(doSetIncognito()), fetchModBlockedList: () => dispatch(doFetchModBlockedList()), diff --git a/ui/component/app/view.jsx b/ui/component/app/view.jsx index 4c5f5f849..4a0d7862d 100644 --- a/ui/component/app/view.jsx +++ b/ui/component/app/view.jsx @@ -1,16 +1,12 @@ // @flow -import * as PAGES from 'constants/pages'; import React, { useEffect, useRef, useState, useLayoutEffect } from 'react'; import classnames from 'classnames'; -import analytics from 'analytics'; import Router from 'component/router/index'; import ReactModal from 'react-modal'; import { openContextMenu } from 'util/context-menu'; import useKonamiListener from 'util/enhanced-layout'; import FileRenderFloating from 'component/fileRenderFloating'; import { withRouter } from 'react-router'; -import usePrevious from 'effects/use-previous'; -import REWARDS from 'rewards'; import usePersistedState from 'effects/use-persisted-state'; import LANGUAGES from 'constants/languages'; import useZoom from 'effects/use-zoom'; @@ -46,7 +42,6 @@ type Props = { length: number, push: (string) => void, }, - fetchAccessToken: () => void, fetchChannelListMine: () => void, fetchCollectionListMine: () => void, signIn: () => void, @@ -82,27 +77,18 @@ type Props = { function App(props: Props) { const { theme, - user, - fetchAccessToken, fetchChannelListMine, fetchCollectionListMine, - signIn, autoUpdateDownloaded, isUpgradeAvailable, requestDownloadUpgrade, uploadCount, history, - syncError, language, languages, setLanguage, updatePreferences, getWalletSyncPref, - rewards, - setReferrer, - isAuthenticated, - syncLoop, - currentModal, syncFatalError, myChannelClaimIds, activeChannelId, @@ -117,38 +103,16 @@ function App(props: Props) { const appRef = useRef(); const isEnhancedLayout = useKonamiListener(); - const [hasSignedIn, setHasSignedIn] = useState(false); - const [readyForSync, setReadyForSync] = useState(false); - const [readyForPrefs, setReadyForPrefs] = useState(false); - const hasVerifiedEmail = user && Boolean(user.has_verified_email); - const isRewardApproved = user && user.is_reward_approved; - const previousHasVerifiedEmail = usePrevious(hasVerifiedEmail); - const previousRewardApproved = usePrevious(isRewardApproved); - const { pathname, search } = props.location; const [upgradeNagClosed, setUpgradeNagClosed] = useState(false); const [resolvedSubscriptions, setResolvedSubscriptions] = useState(false); - // const [retryingSync, setRetryingSync] = useState(false); const [langRenderKey, setLangRenderKey] = useState(0); const [sidebarOpen] = usePersistedState('sidebar', true); const showUpgradeButton = (autoUpdateDownloaded || isUpgradeAvailable) && !upgradeNagClosed; - // referral claiming - const referredRewardAvailable = rewards && rewards.some((reward) => reward.reward_type === REWARDS.TYPE_REFEREE); - const urlParams = new URLSearchParams(search); - const rawReferrerParam = urlParams.get('r'); - const sanitizedReferrerParam = rawReferrerParam && rawReferrerParam.replace(':', '#'); - const userId = user && user.id; const useCustomScrollbar = !IS_MAC; const hasMyChannels = myChannelClaimIds && myChannelClaimIds.length > 0; const hasNoChannels = myChannelClaimIds && myChannelClaimIds.length === 0; const shouldMigrateLanguage = LANGUAGE_MIGRATIONS[language]; const hasActiveChannelClaim = activeChannelId !== undefined; - const isPersonalized = hasVerifiedEmail; - - useEffect(() => { - if (userId) { - analytics.setUser(userId); - } - }, [userId]); useEffect(() => { if (!uploadCount) return; @@ -188,23 +152,10 @@ function App(props: Props) { }, []); // Enable ctrl +/- zooming on Desktop. - // @if TARGET='app' useZoom(); - // @endif // Enable 'Alt + Left/Right' for history navigation on Desktop. - // @if TARGET='app' useHistoryNav(history); - // @endif - - useEffect(() => { - if (referredRewardAvailable && sanitizedReferrerParam && isRewardApproved) { - setReferrer(sanitizedReferrerParam, true); - } else if (referredRewardAvailable && sanitizedReferrerParam) { - setReferrer(sanitizedReferrerParam, false); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [sanitizedReferrerParam, isRewardApproved, referredRewardAvailable]); useEffect(() => { const { current: wrapperElement } = appRef; @@ -212,13 +163,9 @@ function App(props: Props) { ReactModal.setAppElement(wrapperElement); } - fetchAccessToken(); - - // @if TARGET='app' fetchChannelListMine(); // This is fetched after a user is signed in on web fetchCollectionListMine(); - // @endif - }, [appRef, fetchAccessToken, fetchChannelListMine, fetchCollectionListMine]); + }, [appRef, fetchChannelListMine, fetchCollectionListMine]); useEffect(() => { // $FlowFixMe @@ -261,71 +208,20 @@ function App(props: Props) { }, [shouldMigrateLanguage, setLanguage]); useEffect(() => { - // Check that previousHasVerifiedEmail was not undefined instead of just not truthy - // This ensures we don't fire the emailVerified event on the initial user fetch - if (previousHasVerifiedEmail === false && hasVerifiedEmail) { - analytics.emailVerifiedEvent(); + if (updatePreferences && getWalletSyncPref) { + getWalletSyncPref().then(() => updatePreferences()); } - }, [previousHasVerifiedEmail, hasVerifiedEmail, signIn]); - - useEffect(() => { - if (previousRewardApproved === false && isRewardApproved) { - analytics.rewardEligibleEvent(); - } - }, [previousRewardApproved, isRewardApproved]); - - useEffect(() => { - if (updatePreferences && getWalletSyncPref && readyForPrefs) { - getWalletSyncPref() - .then(() => updatePreferences()) - .then(() => { - setReadyForSync(true); - }); - } - }, [updatePreferences, getWalletSyncPref, setReadyForSync, readyForPrefs, hasVerifiedEmail]); - - // ready for sync syncs, however after signin when hasVerifiedEmail, that syncs too. - useEffect(() => { - // signInSyncPref is cleared after sharedState loop. - if (readyForSync && hasVerifiedEmail) { - // In case we are syncing. - syncLoop(); - } - }, [readyForSync, hasVerifiedEmail, syncLoop]); - - // We know someone is logging in or not when we get their user object - // We'll use this to determine when it's time to pull preferences - // This will no longer work if desktop users no longer get a user object from lbryinc - useEffect(() => { - if (user) { - setReadyForPrefs(true); - } - }, [user, setReadyForPrefs]); - - useEffect(() => { - if (syncError && isAuthenticated && !pathname.includes(PAGES.AUTH_WALLET_PASSWORD) && !currentModal) { - history.push(`/$/${PAGES.AUTH_WALLET_PASSWORD}?redirect=${pathname}`); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [syncError, pathname, isAuthenticated]); - - // Keep this at the end to ensure initial setup effects are run first - useEffect(() => { - if (!hasSignedIn && hasVerifiedEmail) { - signIn(); - setHasSignedIn(true); - } - }, [hasVerifiedEmail, signIn, hasSignedIn]); + }, [updatePreferences, getWalletSyncPref]); // batch resolve subscriptions to be used by the sideNavigation component. // add it here so that it only resolves the first time, despite route changes. // useLayoutEffect because it has to be executed before the sideNavigation component requests them useLayoutEffect(() => { - if (sidebarOpen && isPersonalized && subscriptions && !resolvedSubscriptions) { + if (sidebarOpen && subscriptions && !resolvedSubscriptions) { setResolvedSubscriptions(true); resolveUris(subscriptions.map((sub) => sub.uri)); } - }, [sidebarOpen, isPersonalized, resolvedSubscriptions, subscriptions, resolveUris, setResolvedSubscriptions]); + }, [sidebarOpen, resolvedSubscriptions, subscriptions, resolveUris, setResolvedSubscriptions]); useEffect(() => { // When language is changed or translations are fetched, we render. diff --git a/ui/component/button/index.js b/ui/component/button/index.js index f50b0e001..9741d8012 100644 --- a/ui/component/button/index.js +++ b/ui/component/button/index.js @@ -1,12 +1,9 @@ import Button from './view'; import React, { forwardRef } from 'react'; import { connect } from 'react-redux'; -import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user'; const mapStateToProps = (state) => ({ pathname: state.router.location.pathname, - emailVerified: selectUserVerifiedEmail(state), - user: selectUser(state), }); const ConnectedButton = connect(mapStateToProps)(Button); diff --git a/ui/component/button/view.jsx b/ui/component/button/view.jsx index e663d9cea..e2e2b30b5 100644 --- a/ui/component/button/view.jsx +++ b/ui/component/button/view.jsx @@ -32,11 +32,9 @@ type Props = { onMouseEnter: ?(any) => any, onMouseLeave: ?(any) => any, pathname: string, - emailVerified: boolean, myref: any, dispatch: any, 'aria-label'?: string, - user: ?User, }; // use forwardRef to allow consumers to pass refs to the button content if they want to @@ -63,11 +61,9 @@ const Button = forwardRef((props: Props, ref: any) => { iconSize, iconColor, activeClass, - emailVerified, myref, dispatch, //