diff --git a/package.json b/package.json index 92cee1d04..d61a8142d 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "imagesloaded": "^4.1.4", "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#9009708fff61b0a7b614597ba990629421711bf4", + "lbry-redux": "lbryio/lbry-redux#1dd2d4cff5b86dc9169d761198b9257227e9c11d", "lbryinc": "lbryio/lbryinc#275f35b31ec614e2b89689f860fe19e645deee68", "lint-staged": "^7.0.2", "localforage": "^1.7.1", diff --git a/static/app-strings.json b/static/app-strings.json index 7b21bec08..66ad86797 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1027,5 +1027,11 @@ "Your video may not be the best format. Use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.": "Your video may not be the best format. Use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.", "Your video has a bitrate over 6 mbps. We suggest transcoding to provide viewers the best experience.": "Your video has a bitrate over 6 mbps. We suggest transcoding to provide viewers the best experience.", "Your video has a bitrate over 5 mbps. We suggest transcoding to provide viewers the best experience.": "Your video has a bitrate over 5 mbps. We suggest transcoding to provide viewers the best experience.", - "Almost there": "Almost there" -} \ No newline at end of file + "Almost there": "Almost there", + "Comment Acknowledgement": "Comment Acknowledgement", + "A few things to know before making your comment:": "A few things to know before making your comment:", + "Commenting is in alpha. During the alpha, all comments are sent to a LBRY, Inc. server, not the LBRY network itself.": "Commenting is in alpha. During the alpha, all comments are sent to a LBRY, Inc. server, not the LBRY network itself.", + "Deleting or editing comments is not currently possible. Please be mindful of this when posting.": "Deleting or editing comments is not currently possible. Please be mindful of this when posting.", + "When the alpha ends, we will attempt to transition comments, but do not promise to do so.": "When the alpha ends, we will attempt to transition comments, but do not promise to do so.", + "More Channels": "More Channels" +} diff --git a/ui/analytics.js b/ui/analytics.js index 01c704e23..a0a333d48 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -34,6 +34,7 @@ type Analytics = { toggleThirdParty: (boolean, ?boolean) => void, apiLogView: (string, string, string, ?number, ?() => void) => Promise, apiLogPublish: (ChannelClaim | StreamClaim) => void, + apiSyncTags: ({}) => void, tagFollowEvent: (string, boolean, string) => void, videoStartEvent: (string, number) => void, videoBufferEvent: (string, number) => void, @@ -165,6 +166,12 @@ const analytics: Analytics = { } }, + apiSyncTags: params => { + if (internalAnalyticsEnabled && isProduction) { + Lbryio.call('content_tags', 'sync', params); + } + }, + apiSearchFeedback: (query, vote) => { if (isProduction) { // We don't need to worry about analytics enabled here because users manually click on the button to provide feedback diff --git a/ui/component/app/index.js b/ui/component/app/index.js index 3863b4c0e..f1c450769 100644 --- a/ui/component/app/index.js +++ b/ui/component/app/index.js @@ -19,6 +19,7 @@ import { doSignIn, doSyncWithPreferences, doGetAndPopulatePreferences, + doAnalyticsTagSync, } from 'redux/actions/app'; import App from './view'; @@ -37,6 +38,7 @@ const select = state => ({ }); const perform = dispatch => ({ + analyticsTagSync: () => dispatch(doAnalyticsTagSync()), fetchTransactions: (page, pageSize) => dispatch(doFetchTransactions(page, pageSize)), fetchAccessToken: () => dispatch(doFetchAccessToken()), fetchChannelListMine: () => dispatch(doFetchChannelListMine()), diff --git a/ui/component/app/view.jsx b/ui/component/app/view.jsx index 1af984c88..d59c4f424 100644 --- a/ui/component/app/view.jsx +++ b/ui/component/app/view.jsx @@ -66,6 +66,7 @@ type Props = { syncError: ?string, rewards: Array, setReferrer: (string, boolean) => void, + analyticsTagSync: () => void, }; function App(props: Props) { @@ -90,6 +91,7 @@ function App(props: Props) { updatePreferences, rewards, setReferrer, + analyticsTagSync, } = props; const appRef = useRef(); @@ -159,6 +161,7 @@ function App(props: Props) { } else if (referredRewardAvailable && sanitizedReferrerParam) { setReferrer(sanitizedReferrerParam, false); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [sanitizedReferrerParam, isRewardApproved, referredRewardAvailable]); useEffect(() => { @@ -182,6 +185,7 @@ function App(props: Props) { if (!languages.includes(language)) { setLanguage(language); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [language, languages]); useEffect(() => { @@ -216,13 +220,14 @@ function App(props: Props) { // @if TARGET='app' useEffect(() => { updatePreferences(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // @endif useEffect(() => { if (hasVerifiedEmail && syncEnabled) { checkSync(); - + analyticsTagSync(); let syncInterval = setInterval(() => { checkSync(); }, SYNC_INTERVAL); @@ -231,12 +236,14 @@ function App(props: Props) { clearInterval(syncInterval); }; } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasVerifiedEmail, syncEnabled, checkSync]); useEffect(() => { if (syncError) { history.push(`/$/${PAGES.AUTH}?redirect=${pathname}`); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [syncError, pathname]); // @if TARGET='web' diff --git a/ui/component/claimListDiscover/index.js b/ui/component/claimListDiscover/index.js index 7814f8e33..123f96b5e 100644 --- a/ui/component/claimListDiscover/index.js +++ b/ui/component/claimListDiscover/index.js @@ -3,10 +3,10 @@ import { doClaimSearch, selectClaimSearchByQuery, selectFetchingClaimSearch, - doToggleTagFollow, selectBlockedChannels, SETTINGS, } from 'lbry-redux'; +import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import ClaimListDiscover from './view'; @@ -20,7 +20,7 @@ const select = state => ({ const perform = { doClaimSearch, - doToggleTagFollow, + doToggleTagFollowDesktop, }; export default connect( diff --git a/ui/component/claimListDiscover/view.jsx b/ui/component/claimListDiscover/view.jsx index 210efa40a..75cdd2607 100644 --- a/ui/component/claimListDiscover/view.jsx +++ b/ui/component/claimListDiscover/view.jsx @@ -20,7 +20,7 @@ type Props = { doClaimSearch: ({}) => void, loading: boolean, personalView: boolean, - doToggleTagFollow: string => void, + doToggleTagFollowDesktop: string => void, meta?: Node, showNsfw: boolean, showReposts: boolean, @@ -101,12 +101,12 @@ function ClaimListDiscover(props: Props) { const durationParam = urlParams.get(CS.DURATION_KEY) || null; const showDuration = !(claimType && claimType === CS.CLAIM_CHANNEL); - const showContentType = !(claimType || streamType); const isFiltered = () => Boolean(urlParams.get(CS.FRESH_KEY) || urlParams.get(CS.CONTENT_KEY) || urlParams.get(CS.DURATION_KEY)); useEffect(() => { if (isFiltered()) setExpanded(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const options: { diff --git a/ui/component/claimTilesDiscover/index.js b/ui/component/claimTilesDiscover/index.js index 7814f8e33..123f96b5e 100644 --- a/ui/component/claimTilesDiscover/index.js +++ b/ui/component/claimTilesDiscover/index.js @@ -3,10 +3,10 @@ import { doClaimSearch, selectClaimSearchByQuery, selectFetchingClaimSearch, - doToggleTagFollow, selectBlockedChannels, SETTINGS, } from 'lbry-redux'; +import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import ClaimListDiscover from './view'; @@ -20,7 +20,7 @@ const select = state => ({ const perform = { doClaimSearch, - doToggleTagFollow, + doToggleTagFollowDesktop, }; export default connect( diff --git a/ui/component/tagsSearch/index.js b/ui/component/tagsSearch/index.js index eb46fc779..a6c71c5bb 100644 --- a/ui/component/tagsSearch/index.js +++ b/ui/component/tagsSearch/index.js @@ -1,12 +1,6 @@ import { connect } from 'react-redux'; -import { - selectUnfollowedTags, - selectFollowedTags, - doReplaceTags, - doToggleTagFollow, - doAddTag, - doDeleteTag, -} from 'lbry-redux'; +import { selectUnfollowedTags, selectFollowedTags, doReplaceTags, doAddTag, doDeleteTag } from 'lbry-redux'; +import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import DiscoveryFirstRun from './view'; const select = (state, props) => ({ @@ -17,7 +11,7 @@ const select = (state, props) => ({ export default connect( select, { - doToggleTagFollow, + doToggleTagFollowDesktop, doAddTag, doDeleteTag, doReplaceTags, diff --git a/ui/component/tagsSearch/view.jsx b/ui/component/tagsSearch/view.jsx index f55a54922..e49a778a0 100644 --- a/ui/component/tagsSearch/view.jsx +++ b/ui/component/tagsSearch/view.jsx @@ -9,7 +9,7 @@ type Props = { tagsPassedIn: Array, unfollowedTags: Array, followedTags: Array, - doToggleTagFollow: string => void, + doToggleTagFollowDesktop: string => void, doAddTag: string => void, onSelect?: Tag => void, suggestMature?: boolean, @@ -33,7 +33,7 @@ export default function TagsSearch(props: Props) { tagsPassedIn = [], unfollowedTags = [], followedTags = [], - doToggleTagFollow, + doToggleTagFollowDesktop, doAddTag, onSelect, onRemove, @@ -99,7 +99,7 @@ export default function TagsSearch(props: Props) { } if (!followedTags.some(({ name }) => name === tag)) { - doToggleTagFollow(tag); + doToggleTagFollowDesktop(tag); } }); } @@ -109,7 +109,7 @@ export default function TagsSearch(props: Props) { if (onSelect) { onSelect([{ name: tag }]); } else { - doToggleTagFollow(tag); + doToggleTagFollowDesktop(tag); } } return ( @@ -174,8 +174,6 @@ export default function TagsSearch(props: Props) { onClick={() => handleTagClick(tag)} /> ))} - - {!suggestedTags.length &&

{__('No matching tags')}

} diff --git a/ui/component/tagsSelect/index.js b/ui/component/tagsSelect/index.js index eb46fc779..a6c71c5bb 100644 --- a/ui/component/tagsSelect/index.js +++ b/ui/component/tagsSelect/index.js @@ -1,12 +1,6 @@ import { connect } from 'react-redux'; -import { - selectUnfollowedTags, - selectFollowedTags, - doReplaceTags, - doToggleTagFollow, - doAddTag, - doDeleteTag, -} from 'lbry-redux'; +import { selectUnfollowedTags, selectFollowedTags, doReplaceTags, doAddTag, doDeleteTag } from 'lbry-redux'; +import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import DiscoveryFirstRun from './view'; const select = (state, props) => ({ @@ -17,7 +11,7 @@ const select = (state, props) => ({ export default connect( select, { - doToggleTagFollow, + doToggleTagFollowDesktop, doAddTag, doDeleteTag, doReplaceTags, diff --git a/ui/component/tagsSelect/view.jsx b/ui/component/tagsSelect/view.jsx index 574a32f2b..507aa0688 100644 --- a/ui/component/tagsSelect/view.jsx +++ b/ui/component/tagsSelect/view.jsx @@ -11,7 +11,7 @@ import Card from 'component/common/card'; type Props = { showClose?: boolean, followedTags: Array, - doToggleTagFollow?: string => void, + doToggleTagFollowDesktop?: string => void, suggestMature: boolean, // Overrides // The default component is for following tags @@ -34,7 +34,7 @@ export default function TagsSelect(props: Props) { const { showClose, followedTags, - doToggleTagFollow = null, + doToggleTagFollowDesktop = null, title, help, tagsChosen, @@ -59,8 +59,8 @@ export default function TagsSelect(props: Props) { function handleTagClick(tag) { if (onRemove) { onRemove(tag); - } else if (doToggleTagFollow) { - doToggleTagFollow(tag.name); + } else if (doToggleTagFollowDesktop) { + doToggleTagFollowDesktop(tag.name); const wasFollowing = followedTags.map(tag => tag.name).includes(tag.name); const nowFollowing = !wasFollowing; diff --git a/ui/page/discover/index.js b/ui/page/discover/index.js index 5bf5a2ec7..38e7c1e0e 100644 --- a/ui/page/discover/index.js +++ b/ui/page/discover/index.js @@ -1,5 +1,6 @@ import { connect } from 'react-redux'; -import { selectFollowedTags, doToggleTagFollow } from 'lbry-redux'; +import { selectFollowedTags } from 'lbry-redux'; +import { doToggleTagFollowDesktop } from 'redux/actions/tags'; import Tags from './view'; const select = state => ({ @@ -9,6 +10,6 @@ const select = state => ({ export default connect( select, { - doToggleTagFollow, + doToggleTagFollowDesktop, } )(Tags); diff --git a/ui/page/discover/view.jsx b/ui/page/discover/view.jsx index 4e2868171..a08ec5004 100644 --- a/ui/page/discover/view.jsx +++ b/ui/page/discover/view.jsx @@ -12,14 +12,14 @@ import Icon from 'component/common/icon'; type Props = { location: { search: string }, followedTags: Array, - doToggleTagFollow: string => void, + doToggleTagFollowDesktop: string => void, }; function TagsPage(props: Props) { const { location: { search }, followedTags, - doToggleTagFollow, + doToggleTagFollowDesktop, } = props; const buttonRef = useRef(); const isHovering = useHover(buttonRef); @@ -39,7 +39,7 @@ function TagsPage(props: Props) { } function handleFollowClick() { - doToggleTagFollow(tag); + doToggleTagFollowDesktop(tag); const nowFollowing = !isFollowing; analytics.tagFollowEvent(tag, nowFollowing, 'tag-page'); diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js index 2f3a34828..b7ec14f5d 100644 --- a/ui/redux/actions/app.js +++ b/ui/redux/actions/app.js @@ -19,6 +19,7 @@ import { doPreferenceGet, doToast, doClearSupport, + selectFollowedTagsList, // SHARED_PREFERENCES, } from 'lbry-redux'; import Native from 'native'; @@ -435,6 +436,15 @@ export function doAnalyticsView(uri, timeToStart) { }; } +export function doAnalyticsTagSync() { + return (dispatch, getState) => { + const state = getState(); + const tags = selectFollowedTagsList(state); + const stringOfTags = tags.join(','); + analytics.apiSyncTags({ content_tags: stringOfTags }); + }; +} + export function doSignIn() { return (dispatch, getState) => { // @if TARGET='web' diff --git a/ui/redux/actions/tags.js b/ui/redux/actions/tags.js new file mode 100644 index 000000000..fa352dd36 --- /dev/null +++ b/ui/redux/actions/tags.js @@ -0,0 +1,13 @@ +// @flow +import { doToggleTagFollow, selectFollowedTagsList } from 'lbry-redux'; + +import analytics from 'analytics'; + +export const doToggleTagFollowDesktop = (name: string) => (dispatch: Dispatch, getState: GetState) => { + dispatch(doToggleTagFollow(name)); + + const state = getState(); + const tags = selectFollowedTagsList(state); + const stringOfTags = tags.join(','); + analytics.apiSyncTags({ content_tags: stringOfTags }); +}; diff --git a/yarn.lock b/yarn.lock index 99ad23060..73dd33164 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7316,9 +7316,9 @@ lazy-val@^1.0.4: yargs "^13.2.2" zstd-codec "^0.1.1" -lbry-redux@lbryio/lbry-redux#9009708fff61b0a7b614597ba990629421711bf4: +lbry-redux@lbryio/lbry-redux#1dd2d4cff5b86dc9169d761198b9257227e9c11d: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/9009708fff61b0a7b614597ba990629421711bf4" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/1dd2d4cff5b86dc9169d761198b9257227e9c11d" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0"