From 0dbaec423c36cb972bcedd02c2809d2f1641946d Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:06:55 +0500
Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=94=A8=20REFACTOR:=20refactors=20reco?=
=?UTF-8?q?mmended=20sites=20store=20to=20TS?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../reader/following/{main.jsx => main.tsx} | 12 +--
.../{index.jsx => index.tsx} | 40 +++++++-
.../wpcom/read/recommendations/sites/index.js | 44 ---------
.../wpcom/read/recommendations/sites/index.ts | 92 +++++++++++++++++++
.../state/reader/recommended-sites/actions.ts | 62 +++++++++++--
.../state/reader/recommended-sites/reducer.ts | 4 +-
...-reader-recommended-sites-paging-offset.js | 9 --
...-reader-recommended-sites-paging-offset.ts | 9 ++
.../selectors/get-reader-recommended-sites.js | 9 --
.../selectors/get-reader-recommended-sites.ts | 9 ++
.../selectors/{index.js => index.ts} | 0
.../state/reader/recommended-sites/types.ts | 7 --
12 files changed, 208 insertions(+), 89 deletions(-)
rename client/reader/following/{main.jsx => main.tsx} (87%)
rename client/reader/stream/reader-popular-sites-sidebar/{index.jsx => index.tsx} (59%)
delete mode 100644 client/state/data-layer/wpcom/read/recommendations/sites/index.js
create mode 100644 client/state/data-layer/wpcom/read/recommendations/sites/index.ts
delete mode 100644 client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.js
create mode 100644 client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.ts
delete mode 100644 client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.js
create mode 100644 client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.ts
rename client/state/reader/recommended-sites/selectors/{index.js => index.ts} (100%)
delete mode 100644 client/state/reader/recommended-sites/types.ts
diff --git a/client/reader/following/main.jsx b/client/reader/following/main.tsx
similarity index 87%
rename from client/reader/following/main.jsx
rename to client/reader/following/main.tsx
index 24173d06752f7..c92217100b428 100644
--- a/client/reader/following/main.jsx
+++ b/client/reader/following/main.tsx
@@ -7,7 +7,7 @@ import NavigationHeader from 'calypso/components/navigation-header';
import withDimensions from 'calypso/lib/with-dimensions';
import ReaderOnboarding from 'calypso/reader/onboarding';
import SuggestionProvider from 'calypso/reader/search-stream/suggestion-provider';
-import Stream, { WIDE_DISPLAY_CUTOFF } from 'calypso/reader/stream';
+import ReaderStream, { WIDE_DISPLAY_CUTOFF } from 'calypso/reader/stream';
import ReaderListFollowedSites from 'calypso/reader/stream/reader-list-followed-sites';
import Recent from '../recent';
import { useFollowingView } from './view-preference';
@@ -15,18 +15,16 @@ import ViewToggle from './view-toggle';
import './style.scss';
function FollowingStream( { ...props } ) {
- const { currentView, setView } = useFollowingView();
+ const { currentView } = useFollowingView();
- const viewToggle = config.isEnabled( 'reader/recent-feed-overhaul' ) ? (
-
- ) : null;
+ const viewToggle = config.isEnabled( 'reader/recent-feed-overhaul' ) ? : null;
return (
<>
{ currentView === 'recent' && config.isEnabled( 'reader/recent-feed-overhaul' ) ? (
) : (
- }
@@ -42,7 +40,7 @@ function FollowingStream( { ...props } ) {
{ viewToggle }
-
+
) }
>
diff --git a/client/reader/stream/reader-popular-sites-sidebar/index.jsx b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
similarity index 59%
rename from client/reader/stream/reader-popular-sites-sidebar/index.jsx
rename to client/reader/stream/reader-popular-sites-sidebar/index.tsx
index 1e2e9c8c585b7..2338d345b507b 100644
--- a/client/reader/stream/reader-popular-sites-sidebar/index.jsx
+++ b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
@@ -1,15 +1,46 @@
import ConnectedReaderSubscriptionListItem from 'calypso/blocks/reader-subscription-list-item/connected';
import '../style.scss';
-function unescape( str ) {
+interface PopularSitesSidebarProps {
+ followSource: string;
+ items: PopularSiteItemProp[];
+}
+
+/**
+ * Represents a popular site item which is passed as a prop to the ReaderPopularSitesSidebar component.
+ */
+interface PopularSiteItemProp {
+ blogId: number;
+ feed_ID: number;
+ feed_URL: string;
+ site_name: string;
+ site_description: string;
+ site_icon: string;
+ url: string;
+}
+
+/**
+ * Represents a popular site which is displayed in the ReaderPopularSitesSidebar component.
+ */
+interface ReaderPopularSite {
+ blog_ID: number;
+ description: string;
+ feed_ID: number;
+ name: string;
+ site_icon: string;
+ URL: string;
+}
+
+function unescape( str: string ): string {
return str.replace( /(\d+);/g, ( match, entity ) => String.fromCharCode( entity ) );
}
// create function to transform item into a site object
-const getSiteFromItem = ( item ) => {
+const getSiteFromItem = ( item: PopularSiteItemProp ): ReaderPopularSite | null => {
if ( item.site_name === undefined || item.site_description === undefined ) {
return null;
}
+
return {
feed_ID: item.feed_ID,
blog_ID: item.blogId,
@@ -17,12 +48,11 @@ const getSiteFromItem = ( item ) => {
name: unescape( item?.site_name ),
site_icon: item.site_icon ?? null,
description: unescape( item?.site_description ),
- last_updated: 0,
- unseen_count: 0,
};
};
-const ReaderPopularSitesSidebar = ( { items, followSource } ) => {
+const ReaderPopularSitesSidebar = ( props: PopularSitesSidebarProps ) => {
+ const { followSource, items } = props;
const sites = items
.map( ( item ) => getSiteFromItem( item ) )
.filter( ( site ) => site !== null );
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/index.js b/client/state/data-layer/wpcom/read/recommendations/sites/index.js
deleted file mode 100644
index 9f81f5b184968..0000000000000
--- a/client/state/data-layer/wpcom/read/recommendations/sites/index.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import { decodeEntities } from 'calypso/lib/formatting';
-import { registerHandlers } from 'calypso/state/data-layer/handler-registry';
-import { http } from 'calypso/state/data-layer/wpcom-http/actions';
-import { dispatchRequest } from 'calypso/state/data-layer/wpcom-http/utils';
-import { READER_RECOMMENDED_SITES_REQUEST } from 'calypso/state/reader/action-types';
-import { receiveRecommendedSites } from 'calypso/state/reader/recommended-sites/actions';
-
-const noop = () => {};
-
-export const requestRecommendedSites = ( action ) => {
- const { seed = 1, number = 10, offset = 0 } = action.payload;
- return http( {
- method: 'GET',
- path: '/read/recommendations/sites',
- query: { number, offset, seed, posts_per_site: 0 },
- apiVersion: '1.2',
- onSuccess: action,
- onFailure: action,
- } );
-};
-
-export const fromApi = ( { algorithm, sites } ) =>
- sites.map( ( site ) => ( {
- feedId: site.feed_id,
- blogId: site.blog_id,
- title: decodeEntities( site.blog_title ),
- url: site.blog_url ?? site.URL,
- railcar: site.railcar,
- algorithm,
- } ) );
-
-export const addRecommendedSites = ( { payload: { seed, offset } }, sites ) =>
- receiveRecommendedSites( { sites, seed, offset } );
-
-registerHandlers( 'state/data-layer/wpcom/read/recommendations/sites/index.js', {
- [ READER_RECOMMENDED_SITES_REQUEST ]: [
- dispatchRequest( {
- fetch: requestRecommendedSites,
- onSuccess: addRecommendedSites,
- onError: noop,
- fromApi,
- } ),
- ],
-} );
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
new file mode 100644
index 0000000000000..c750f08de881a
--- /dev/null
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
@@ -0,0 +1,92 @@
+import { Action } from 'redux';
+import { Railcar } from 'calypso/data/marketplace/types';
+import { decodeEntities } from 'calypso/lib/formatting';
+import { registerHandlers } from 'calypso/state/data-layer/handler-registry';
+import { http } from 'calypso/state/data-layer/wpcom-http/actions';
+import { dispatchRequest } from 'calypso/state/data-layer/wpcom-http/utils';
+import { READER_RECOMMENDED_SITES_REQUEST } from 'calypso/state/reader/action-types';
+import {
+ receiveRecommendedSites,
+ RecommendedSitesRequestAction,
+} from 'calypso/state/reader/recommended-sites/actions';
+
+const noop = () => {};
+
+export const requestRecommendedSites = ( action: RecommendedSitesRequestAction ): Action => {
+ const { seed = 1, number = 10, offset = 0 } = action.payload;
+
+ return http( {
+ method: 'GET',
+ path: '/read/recommendations/sites',
+ query: { number, offset, seed, posts_per_site: 0 },
+ apiVersion: '1.2',
+ onSuccess: action,
+ onFailure: action,
+ } );
+};
+
+interface RecommendedSitesBody {
+ algorithm: string;
+ sites: RecommendedSiteResponse[];
+ meta: {
+ next_page: string;
+ };
+}
+
+interface RecommendedSiteResponse {
+ blog_id: number;
+ blog_title?: string;
+ blog_url?: string;
+ description: string;
+ feed_id: number;
+ feed_url: string;
+ icon: {
+ ico: string;
+ img: string;
+ media_id: string;
+ };
+ ID: number;
+ name: string;
+ railcar: Railcar;
+ URL: string;
+}
+
+export interface RecommendedSite {
+ algorithm: string;
+ blogId: number;
+ feedId: number;
+ railcar: Railcar;
+ title: string;
+ url: string;
+}
+
+const mapResponseToRecommendedSites = ( {
+ algorithm,
+ sites,
+}: RecommendedSitesBody ): RecommendedSite[] =>
+ sites.map(
+ ( site: RecommendedSiteResponse ): RecommendedSite => ( {
+ algorithm,
+ blogId: site.blog_id,
+ feedId: site.feed_id,
+ railcar: site.railcar,
+ title: decodeEntities( site.blog_title ?? '' ),
+ url: site.blog_url ?? site.URL,
+ } )
+ );
+
+export const addRecommendedSites = (
+ { payload: { seed, offset } }: RecommendedSitesRequestAction,
+ sites: RecommendedSite[]
+) => receiveRecommendedSites( { sites, seed, offset } );
+
+registerHandlers( 'state/data-layer/wpcom/read/recommendations/sites/index.js', {
+ [ READER_RECOMMENDED_SITES_REQUEST ]: [
+ dispatchRequest( {
+ fetch: requestRecommendedSites,
+ onSuccess: addRecommendedSites,
+ onError: noop,
+ fromApi: mapResponseToRecommendedSites,
+ } ),
+ ],
+} );
diff --git a/client/state/reader/recommended-sites/actions.ts b/client/state/reader/recommended-sites/actions.ts
index 316ce3ae9e6ab..734fad2d5b776 100644
--- a/client/state/reader/recommended-sites/actions.ts
+++ b/client/state/reader/recommended-sites/actions.ts
@@ -4,15 +4,43 @@ import {
READER_RECOMMENDED_SITES_RECEIVE,
READER_RECOMMENDED_SITE_FOLLOWED,
} from 'calypso/state/reader/action-types';
-import 'calypso/state/data-layer/wpcom/read/recommendations/sites';
+import type { RecommendedSite } from 'calypso/state/data-layer/wpcom/read/recommendations/sites';
import 'calypso/state/reader/init';
-import { RecommendedSite } from './types';
+import 'calypso/state/data-layer/wpcom/read/recommendations/sites';
+
+export interface RecommendedSitesRequestAction {
+ type: 'READER_RECOMMENDED_SITES_REQUEST';
+ payload: RecommendedSitesRequestPayload;
+}
+
+interface RecommendedSitesRequestPayload {
+ offset: number;
+ number: number;
+ seed: number;
+}
-export const requestRecommendedSites = ( { offset = 0, number = 4, seed = 0 } ) => ( {
+export const requestRecommendedSites = ( {
+ offset = 0,
+ number = 4,
+ seed = 0,
+}: {
+ offset?: number;
+ number?: number;
+ seed?: number;
+} ): RecommendedSitesRequestAction => ( {
type: READER_RECOMMENDED_SITES_REQUEST,
payload: { offset, number, seed },
} );
+export interface RecommendedSitesReceiveAction {
+ type: 'READER_RECOMMENDED_SITES_RECEIVE';
+ payload: {
+ offset?: number;
+ sites: RecommendedSite[];
+ };
+ seed: number;
+}
+
export const receiveRecommendedSites = ( {
seed,
sites,
@@ -21,25 +49,47 @@ export const receiveRecommendedSites = ( {
seed: number;
sites: RecommendedSite[];
offset?: number;
-} ) => ( {
+} ): RecommendedSitesReceiveAction => ( {
type: READER_RECOMMENDED_SITES_RECEIVE,
payload: { sites, offset },
seed,
} );
+export interface RecommendedSiteDismissedAction {
+ type: 'READER_RECOMMENDED_SITE_DISMISSED';
+ payload: {
+ siteId: number;
+ };
+ seed: number;
+}
+
export const dismissedRecommendedSite = ( {
siteId,
seed,
}: {
siteId: number;
seed: number;
-} ) => ( {
+} ): RecommendedSiteDismissedAction => ( {
type: READER_RECOMMENDED_SITE_DISMISSED,
payload: { siteId },
seed,
} );
-export const followedRecommendedSite = ( { siteId, seed }: { siteId: number; seed: number } ) => ( {
+export interface RecommendedSiteFollowedAction {
+ type: 'READER_RECOMMENDED_SITE_FOLLOWED';
+ payload: {
+ siteId: number;
+ };
+ seed: number;
+}
+
+export const followedRecommendedSite = ( {
+ siteId,
+ seed,
+}: {
+ siteId: number;
+ seed: number;
+} ): RecommendedSiteFollowedAction => ( {
type: READER_RECOMMENDED_SITE_FOLLOWED,
payload: { siteId },
seed,
diff --git a/client/state/reader/recommended-sites/reducer.ts b/client/state/reader/recommended-sites/reducer.ts
index 73da8d3eca562..80e9ff8105503 100644
--- a/client/state/reader/recommended-sites/reducer.ts
+++ b/client/state/reader/recommended-sites/reducer.ts
@@ -1,4 +1,5 @@
import { uniqueBy } from '@automattic/js-utils';
+import { RecommendedSite } from 'calypso/state/data-layer/wpcom/read/recommendations/sites';
import {
READER_RECOMMENDED_SITE_DISMISSED,
READER_RECOMMENDED_SITE_FOLLOWED,
@@ -10,7 +11,6 @@ import {
followedRecommendedSite,
receiveRecommendedSites,
} from './actions';
-import { RecommendedSite } from './types';
/**
* Tracks mappings between randomization seeds and site recs.
@@ -47,7 +47,7 @@ export const pagingOffset = keyedReducer< number >( 'seed', ( state = 0, action
switch ( action.type ) {
case READER_RECOMMENDED_SITES_RECEIVE:
return Math.max(
- ( action as ReturnType< typeof receiveRecommendedSites > ).payload.offset,
+ ( action as ReturnType< typeof receiveRecommendedSites > ).payload.offset ?? 0,
state
);
}
diff --git a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.js b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.js
deleted file mode 100644
index be7c1967772e6..0000000000000
--- a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import 'calypso/state/reader/init';
-
-/**
- * Returns the recommended sites paging offset
- * @param {number} seed the elasticsearch seed for which to grab recs
- * @returns {number} the paging offset
- */
-
-export default ( state, seed ) => state.reader.recommendedSites.pagingOffset[ seed ];
diff --git a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.ts b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.ts
new file mode 100644
index 0000000000000..f6465f1535326
--- /dev/null
+++ b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites-paging-offset.ts
@@ -0,0 +1,9 @@
+import 'calypso/state/reader/init';
+import { AppState } from 'calypso/types';
+
+/**
+ * Returns the recommended sites paging offset
+ */
+export default ( state: AppState, seed: number ) => {
+ return state.reader.recommendedSites.pagingOffset[ seed ];
+};
diff --git a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.js b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.js
deleted file mode 100644
index cc7be652148a0..0000000000000
--- a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import 'calypso/state/reader/init';
-
-/**
- * Returns the recommended sites for a given seed.
- * @param {number} seed the elasticsearch seed for which to grab recs
- * @returns {Array} array of recommended sites for a given seed
- */
-
-export default ( state, seed ) => state.reader.recommendedSites.items[ seed ];
diff --git a/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.ts b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.ts
new file mode 100644
index 0000000000000..683ba0953c2b7
--- /dev/null
+++ b/client/state/reader/recommended-sites/selectors/get-reader-recommended-sites.ts
@@ -0,0 +1,9 @@
+import 'calypso/state/reader/init';
+import { AppState } from 'calypso/types';
+
+/**
+ * Returns the recommended sites for a given seed.
+ */
+export default < T >( state: AppState, seed: number ): T[] => {
+ return state.reader.recommendedSites.items[ seed ];
+};
diff --git a/client/state/reader/recommended-sites/selectors/index.js b/client/state/reader/recommended-sites/selectors/index.ts
similarity index 100%
rename from client/state/reader/recommended-sites/selectors/index.js
rename to client/state/reader/recommended-sites/selectors/index.ts
diff --git a/client/state/reader/recommended-sites/types.ts b/client/state/reader/recommended-sites/types.ts
deleted file mode 100644
index 53fd0c00c9da2..0000000000000
--- a/client/state/reader/recommended-sites/types.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Railcar } from 'calypso/data/marketplace/types';
-
-export type RecommendedSite = {
- feedId: number;
- blogId: number;
- railcar?: Railcar;
-};
From 8299392fd1d3c52105f77d288a2230bd153f6b08 Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:10:24 +0500
Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=91=8C=20IMPROVE:=20dispatch=20typing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/reader/recommended-sites/recommended-sites.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/client/reader/recommended-sites/recommended-sites.tsx b/client/reader/recommended-sites/recommended-sites.tsx
index d8875f4d685d1..e92e51901508b 100644
--- a/client/reader/recommended-sites/recommended-sites.tsx
+++ b/client/reader/recommended-sites/recommended-sites.tsx
@@ -5,8 +5,12 @@ import { __experimentalHStack as HStack } from '@wordpress/components';
import { useTranslate } from 'i18n-calypso';
import React, { useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
+import { Dispatch } from 'redux';
import { isCurrentUserEmailVerified } from 'calypso/state/current-user/selectors';
-import { requestRecommendedSites } from 'calypso/state/reader/recommended-sites/actions';
+import {
+ RecommendedSitesRequestAction,
+ requestRecommendedSites,
+} from 'calypso/state/reader/recommended-sites/actions';
import {
getReaderRecommendedSites,
getReaderRecommendedSitesPagingOffset,
@@ -54,7 +58,7 @@ const RecommendedSitesPlaceholder = ( { count }: { count: number } ) => {
const RecommendedSites = () => {
const translate = useTranslate();
- const dispatch = useDispatch();
+ const dispatch = useDispatch< Dispatch< RecommendedSitesRequestAction > >();
const isEmailVerified = useSelector( isCurrentUserEmailVerified );
const amountOfPlaceHolders = useBreakpoint( '<1040px' ) ? 1 : 2;
From 49729eabf1341819273f40b72ba7b64e425061e0 Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:33:49 +0500
Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20recommended=20sites?=
=?UTF-8?q?=20tests?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../wpcom/read/recommendations/sites/index.ts | 4 +-
.../sites/test/{index.js => index.ts} | 60 +++++++++++++++----
2 files changed, 52 insertions(+), 12 deletions(-)
rename client/state/data-layer/wpcom/read/recommendations/sites/test/{index.js => index.ts} (58%)
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
index c750f08de881a..6d895400c882d 100644
--- a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
@@ -25,7 +25,7 @@ export const requestRecommendedSites = ( action: RecommendedSitesRequestAction )
} );
};
-interface RecommendedSitesBody {
+export interface RecommendedSitesBody {
algorithm: string;
sites: RecommendedSiteResponse[];
meta: {
@@ -60,7 +60,7 @@ export interface RecommendedSite {
url: string;
}
-const mapResponseToRecommendedSites = ( {
+export const mapResponseToRecommendedSites = ( {
algorithm,
sites,
}: RecommendedSitesBody ): RecommendedSite[] =>
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/test/index.js b/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
similarity index 58%
rename from client/state/data-layer/wpcom/read/recommendations/sites/test/index.js
rename to client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
index 16f861cf1a36f..f944f94a628f7 100644
--- a/client/state/data-layer/wpcom/read/recommendations/sites/test/index.js
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
@@ -3,35 +3,74 @@ import {
requestRecommendedSites as requestRecommendedSitesAction,
receiveRecommendedSites,
} from 'calypso/state/reader/recommended-sites/actions';
-import { requestRecommendedSites, addRecommendedSites, fromApi } from '../';
+import {
+ requestRecommendedSites,
+ addRecommendedSites,
+ mapResponseToRecommendedSites,
+ RecommendedSitesBody,
+ RecommendedSite,
+} from '../index';
const algorithm = 'chicken-recs/es1';
const seed = 42;
-const response = {
+const response: RecommendedSitesBody = {
algorithm,
sites: [
{
blog_id: 19096129,
- feed_id: 185124,
blog_title: 'Bente Haarstad Photography&',
blog_url: 'http://bentehaarstad.wordpress.com',
+ description: 'Description 1',
+ feed_id: 185124,
+ feed_url: 'http://bentehaarstad.wordpress.com/feed/',
+ icon: {
+ ico: 'http://bentehaarstad.wordpress.com/favicon.ico',
+ img: 'http://bentehaarstad.wordpress.com/favicon.ico',
+ media_id: '12345',
+ },
+ ID: 12345,
+ name: 'Bente Haarstad Photography&',
railcar: {},
+ URL: 'http://bentehaarstad.wordpress.com',
},
{
blog_id: 38492359,
- feed_id: 42081376,
blog_title: 'The Renegade Press',
blog_url: 'http://chrisnicholaswrites.wordpress.com',
+ description: 'Description 2',
+ feed_id: 42081376,
+ feed_url: 'http://chrisnicholaswrites.wordpress.com/feed/',
+ icon: {
+ ico: 'http://chrisnicholaswrites.wordpress.com/favicon.ico',
+ img: 'http://chrisnicholaswrites.wordpress.com/favicon.ico',
+ media_id: '12345',
+ },
+ ID: 12345,
+ name: 'The Renegade Press',
railcar: {},
+ URL: 'http://chrisnicholaswrites.wordpress.com',
},
{
blog_id: 30436600,
- feed_id: 1098976,
blog_title: 'Make Something Mondays!',
blog_url: 'http://makesomethingmondays.wordpress.com',
+ description: 'Description 3',
+ feed_id: 1098976,
+ feed_url: 'http://makesomethingmondays.wordpress.com/feed/',
+ icon: {
+ ico: 'http://makesomethingmondays.wordpress.com/favicon.ico',
+ img: 'http://makesomethingmondays.wordpress.com/favicon.ico',
+ media_id: '12345',
+ },
+ ID: 12345,
+ name: 'Make Something Mondays!',
railcar: {},
+ URL: 'http://makesomethingmondays.wordpress.com',
},
],
+ meta: {
+ next_page: 'next_page',
+ },
};
describe( 'recommended sites', () => {
@@ -55,10 +94,11 @@ describe( 'recommended sites', () => {
describe( '#receiveRecommendedSites', () => {
test( 'should dispatch action with sites if successful', () => {
const action = requestRecommendedSitesAction( { seed } );
- const result = addRecommendedSites( action, response );
+ const recommendedSites = mapResponseToRecommendedSites( response );
+ const result = addRecommendedSites( action, recommendedSites );
expect( result ).toEqual(
receiveRecommendedSites( {
- sites: response,
+ sites: recommendedSites,
seed,
offset: 0,
} )
@@ -66,9 +106,9 @@ describe( 'recommended sites', () => {
} );
} );
- describe( '#fromApi', () => {
+ describe( '#mapResponseToRecommendedSites', () => {
test( 'should extract only what we care about from the api response. and decode entities', () => {
- const expected = [
+ const expected: RecommendedSite[] = [
{
algorithm,
railcar: {},
@@ -95,7 +135,7 @@ describe( 'recommended sites', () => {
},
];
- expect( fromApi( response ) ).toEqual( expected );
+ expect( mapResponseToRecommendedSites( response ) ).toEqual( expected );
} );
} );
} );
From 63aca72313879f8bd40c8cb289b0761a8b54fa71 Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:52:22 +0500
Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20types?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/reader/stream/reader-popular-sites-sidebar/index.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/reader/stream/reader-popular-sites-sidebar/index.tsx b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
index 2338d345b507b..0bce5fc902d43 100644
--- a/client/reader/stream/reader-popular-sites-sidebar/index.tsx
+++ b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
@@ -54,8 +54,8 @@ const getSiteFromItem = ( item: PopularSiteItemProp ): ReaderPopularSite | null
const ReaderPopularSitesSidebar = ( props: PopularSitesSidebarProps ) => {
const { followSource, items } = props;
const sites = items
- .map( ( item ) => getSiteFromItem( item ) )
- .filter( ( site ) => site !== null );
+ .map( ( item ): ReaderPopularSite | null => getSiteFromItem( item ) )
+ .filter( ( site ): site is ReaderPopularSite => site !== null );
const popularSitesLinks = sites.map( ( site ) => (
Date: Mon, 2 Dec 2024 13:20:29 +0500
Subject: [PATCH 5/9] ADD: title prop in ReaderPopularSitesSidebar component
---
client/reader/discover/discover-stream.js | 24 ++++++++-----------
.../reader-popular-sites-sidebar/index.tsx | 22 +++++++++++------
2 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/client/reader/discover/discover-stream.js b/client/reader/discover/discover-stream.js
index aadc40c33cf45..6e4ee9a8ce670 100644
--- a/client/reader/discover/discover-stream.js
+++ b/client/reader/discover/discover-stream.js
@@ -100,25 +100,21 @@ const DiscoverStream = ( props ) => {
const streamSidebar = () => {
if ( selectedTab === FIRST_POSTS_TAB && recommendedSites?.length ) {
return (
- <>
- { translate( 'New sites' ) }
-
- >
+
);
}
if ( ( isDefaultTab || selectedTab === 'latest' ) && recommendedSites?.length ) {
return (
- <>
- { translate( 'Popular sites' ) }
-
- >
+
);
} else if ( ! ( isDefaultTab || selectedTab === 'latest' ) ) {
return ;
diff --git a/client/reader/stream/reader-popular-sites-sidebar/index.tsx b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
index 0bce5fc902d43..a9ea25b1c82d7 100644
--- a/client/reader/stream/reader-popular-sites-sidebar/index.tsx
+++ b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
@@ -4,6 +4,7 @@ import '../style.scss';
interface PopularSitesSidebarProps {
followSource: string;
items: PopularSiteItemProp[];
+ title?: string;
}
/**
@@ -35,8 +36,10 @@ function unescape( str: string ): string {
return str.replace( /(\d+);/g, ( match, entity ) => String.fromCharCode( entity ) );
}
-// create function to transform item into a site object
-const getSiteFromItem = ( item: PopularSiteItemProp ): ReaderPopularSite | null => {
+/**
+ * Converts a popular site item, provided as a prop, into a popular site object for display in the ReaderPopularSitesSidebar component.
+ */
+const getPopularSiteFromItem = ( item: PopularSiteItemProp ): ReaderPopularSite | null => {
if ( item.site_name === undefined || item.site_description === undefined ) {
return null;
}
@@ -52,12 +55,12 @@ const getSiteFromItem = ( item: PopularSiteItemProp ): ReaderPopularSite | null
};
const ReaderPopularSitesSidebar = ( props: PopularSitesSidebarProps ) => {
- const { followSource, items } = props;
- const sites = items
- .map( ( item ): ReaderPopularSite | null => getSiteFromItem( item ) )
+ const { followSource, items, title } = props;
+ const sites: ReaderPopularSite[] = items
+ .map( ( item ): ReaderPopularSite | null => getPopularSiteFromItem( item ) )
.filter( ( site ): site is ReaderPopularSite => site !== null );
- const popularSitesLinks = sites.map( ( site ) => (
+ const popularSitesLinks: JSX.Element[] = sites.map( ( site ) => (
{
return null;
}
- return { popularSitesLinks }
;
+ return (
+ <>
+ { title ? { title }
: null }
+ { popularSitesLinks }
+ >
+ );
};
export default ReaderPopularSitesSidebar;
From adf443e81afa8e42a77aa1a2f29836d7bc2e724d Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 13:21:01 +0500
Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=92=AB=20UPDATE:=20replace=20subscrip?=
=?UTF-8?q?tions=20available=20on=20recent=20sidebar=20with=20popular=20si?=
=?UTF-8?q?tes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../{follow-sources.jsx => follow-sources.ts} | 1 +
client/reader/following/main.tsx | 55 +++++-
.../reader-list-followed-sites/index.jsx | 157 ------------------
.../wpcom/read/recommendations/sites/index.ts | 10 +-
4 files changed, 61 insertions(+), 162 deletions(-)
rename client/reader/{follow-sources.jsx => follow-sources.ts} (83%)
delete mode 100644 client/reader/stream/reader-list-followed-sites/index.jsx
diff --git a/client/reader/follow-sources.jsx b/client/reader/follow-sources.ts
similarity index 83%
rename from client/reader/follow-sources.jsx
rename to client/reader/follow-sources.ts
index be50b21df6b54..28556d1c5e1a1 100644
--- a/client/reader/follow-sources.jsx
+++ b/client/reader/follow-sources.ts
@@ -3,5 +3,6 @@ export const IN_STREAM_RECOMMENDATION = 'in-stream-recommendation';
export const SEARCH_RESULTS_SITES = 'search-results-sites';
export const READER_POST_OPTIONS_MENU = 'reader-post-options-menu';
export const READER_SUGGESTED_FOLLOWS_DIALOG = 'reader-suggested-follows-dialog';
+export const READER_RECENT_SIDEBAR_POPULAR_SITES = 'reader-recent-sidebar-popular-sites';
export const READER_SEARCH_POPULAR_SITES = 'reader-search-popular-sites';
export const READER_DISCOVER_POPULAR_SITES = 'reader-discover-popular-sites';
diff --git a/client/reader/following/main.tsx b/client/reader/following/main.tsx
index c92217100b428..9e5fdc3b22ceb 100644
--- a/client/reader/following/main.tsx
+++ b/client/reader/following/main.tsx
@@ -1,6 +1,9 @@
import config from '@automattic/calypso-config';
import clsx from 'clsx';
import { translate } from 'i18n-calypso';
+import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { Dispatch } from 'redux';
import AsyncLoad from 'calypso/components/async-load';
import BloganuaryHeader from 'calypso/components/bloganuary-header';
import NavigationHeader from 'calypso/components/navigation-header';
@@ -8,15 +11,23 @@ import withDimensions from 'calypso/lib/with-dimensions';
import ReaderOnboarding from 'calypso/reader/onboarding';
import SuggestionProvider from 'calypso/reader/search-stream/suggestion-provider';
import ReaderStream, { WIDE_DISPLAY_CUTOFF } from 'calypso/reader/stream';
-import ReaderListFollowedSites from 'calypso/reader/stream/reader-list-followed-sites';
+import { RecommendedSite } from 'calypso/state/data-layer/wpcom/read/recommendations/sites';
+import {
+ RecommendedSitesRequestAction,
+ requestRecommendedSites,
+} from 'calypso/state/reader/recommended-sites/actions';
+import { getReaderRecommendedSites } from 'calypso/state/reader/recommended-sites/selectors';
+import { READER_RECENT_SIDEBAR_POPULAR_SITES } from '../follow-sources';
import Recent from '../recent';
+import ReaderPopularSitesSidebar from '../stream/reader-popular-sites-sidebar';
import { useFollowingView } from './view-preference';
import ViewToggle from './view-toggle';
import './style.scss';
+export const RECOMMENDED_SITES_SEED = Math.floor( Math.random() * 10001 );
+
function FollowingStream( { ...props } ) {
const { currentView } = useFollowingView();
-
const viewToggle = config.isEnabled( 'reader/recent-feed-overhaul' ) ? : null;
return (
@@ -27,7 +38,7 @@ function FollowingStream( { ...props } ) {
}
+ streamSidebar={ () => }
>
>();
+ const recommendedSites = useSelector( ( state ) => {
+ return getReaderRecommendedSites< RecommendedSite >( state, RECOMMENDED_SITES_SEED ) || [];
+ } );
+
+ useEffect( () => {
+ // Avoid fetching recommended sites if they are already present in the store.
+ if ( recommendedSites.length > 0 ) {
+ return;
+ }
+
+ dispatch( requestRecommendedSites( { seed: RECOMMENDED_SITES_SEED, number: 10 } ) );
+ }, [ dispatch, recommendedSites ] );
+
+ if ( recommendedSites.length === 0 ) {
+ return null;
+ }
+
+ return (
+ {
+ return {
+ blogId: s.blogId,
+ feed_ID: s.feedId,
+ feed_URL: s.feed_url,
+ site_name: s.title,
+ site_description: s.description,
+ site_icon: s.icon,
+ url: s.url,
+ };
+ } ) }
+ title={ translate( 'Popular sites' ) }
+ />
+ );
+}
+
export default SuggestionProvider( withDimensions( FollowingStream ) );
diff --git a/client/reader/stream/reader-list-followed-sites/index.jsx b/client/reader/stream/reader-list-followed-sites/index.jsx
deleted file mode 100644
index c8c3955e9d8ac..0000000000000
--- a/client/reader/stream/reader-list-followed-sites/index.jsx
+++ /dev/null
@@ -1,157 +0,0 @@
-import { Button } from '@automattic/components';
-import { isMobile } from '@automattic/viewport';
-import { localize } from 'i18n-calypso';
-import { map } from 'lodash';
-import PropTypes from 'prop-types';
-import { Component } from 'react';
-import { connect } from 'react-redux';
-import SearchCard from 'calypso/components/search-card';
-import UrlSearch from 'calypso/lib/url-search';
-import { filterFollowsByIsFollowed, filterFollowsByQuery } from 'calypso/reader/follow-helpers';
-import { isEligibleForUnseen } from 'calypso/reader/get-helpers';
-import { hasReaderFollowOrganization } from 'calypso/state/reader/follows/selectors';
-import getReaderFollowedSites from 'calypso/state/reader/follows/selectors/get-reader-followed-sites';
-import isFeedWPForTeams from 'calypso/state/selectors/is-feed-wpforteams';
-import isSiteWPForTeams from 'calypso/state/selectors/is-site-wpforteams';
-import ReaderListFollowingItem from './item';
-import '../style.scss';
-
-export class ReaderListFollowedSites extends Component {
- constructor( props ) {
- super( props );
- this.state = {
- sitePage: 1,
- query: '',
- };
- }
-
- static defaultProps = {
- sitesPerPage: 25,
- };
-
- static propTypes = {
- path: PropTypes.string.isRequired,
- sites: PropTypes.array,
- doSearch: PropTypes.func.isRequired,
- isWPForTeamsItem: PropTypes.bool,
- hasOrganization: PropTypes.bool,
- sitesPerPage: PropTypes.number,
- };
-
- isUnseen = () => {
- const { isWPForTeamsItem, hasOrganization } = this.props;
- return isEligibleForUnseen( { isWPForTeamsItem, hasOrganization } );
- };
-
- loadMoreSites = () => {
- const { sitePage } = this.state;
- const { sites, sitesPerPage } = this.props;
-
- //If we've reached the end of the set of sites, all sites have loaded
- if ( sitesPerPage * sitePage >= sites.length ) {
- return;
- }
-
- this.setState( {
- sitePage: this.state.sitePage + 1,
- } );
- };
-
- renderSites = ( follows ) => {
- const { path } = this.props;
- return map(
- follows,
- ( follow ) =>
- follow && (
-
- )
- );
- };
-
- searchEvent = ( query ) => {
- this.setState( {
- query: query,
- } );
- this.props.doSearch( query );
- };
-
- render() {
- const { sites, sitesPerPage, translate } = this.props;
- const { sitePage, query } = this.state;
- const searchThreshold = 15;
- let filteredFollows = filterFollowsByQuery( query, sites );
- filteredFollows = filterFollowsByIsFollowed( filteredFollows );
- const allSitesLoaded = sitesPerPage * sitePage >= filteredFollows.length;
- const sitesToShow = filteredFollows.slice( 0, sitesPerPage * sitePage );
-
- if ( ! sitesToShow ) {
- return null;
- }
-
- return (
- <>
- { ! isMobile() ? (
-
- ) : null }
- { sites.length >= searchThreshold && (
-
- ) }
-
- { isMobile() ? (
-
- ) : null }
-
-
- { this.renderSites( sitesToShow ) }
- { ! allSitesLoaded && (
- -
-
-
- ) }
-
- >
- );
- }
-}
-
-export default connect( ( state, ownProps ) => {
- return {
- isWPForTeamsItem:
- isSiteWPForTeams( state, ownProps.site && ownProps.site.ID ) ||
- isFeedWPForTeams( state, ownProps.feed && ownProps.feed.feed_ID ),
- hasOrganization: hasReaderFollowOrganization(
- state,
- ownProps.feed && ownProps.feed.feed_ID,
- ownProps.site && ownProps.site.ID
- ),
- sites: getReaderFollowedSites( state ),
- };
-} )( localize( UrlSearch( ReaderListFollowedSites ) ) );
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
index 6d895400c882d..0b89bfbc7e60a 100644
--- a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
@@ -54,13 +54,16 @@ interface RecommendedSiteResponse {
export interface RecommendedSite {
algorithm: string;
blogId: number;
+ description: string;
feedId: number;
+ feed_url: string;
+ icon: string;
railcar: Railcar;
title: string;
url: string;
}
-export const mapResponseToRecommendedSites = ( {
+const mapResponseToRecommendedSites = ( {
algorithm,
sites,
}: RecommendedSitesBody ): RecommendedSite[] =>
@@ -68,9 +71,12 @@ export const mapResponseToRecommendedSites = ( {
( site: RecommendedSiteResponse ): RecommendedSite => ( {
algorithm,
blogId: site.blog_id,
+ description: site.description,
feedId: site.feed_id,
+ feed_url: site.feed_url,
+ icon: site.icon?.img,
railcar: site.railcar,
- title: decodeEntities( site.blog_title ?? '' ),
+ title: decodeEntities( site.blog_title ?? site.name ),
url: site.blog_url ?? site.URL,
} )
);
From 72e12efc48c9e3549fe079da76078cbc1d4e1443 Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Mon, 2 Dec 2024 13:48:46 +0500
Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20tests?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/reader/following/main.tsx | 2 +-
.../wpcom/read/recommendations/sites/index.ts | 6 +++---
.../read/recommendations/sites/test/index.ts | 15 ++++++++++++---
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/client/reader/following/main.tsx b/client/reader/following/main.tsx
index 9e5fdc3b22ceb..e1defc81c90ad 100644
--- a/client/reader/following/main.tsx
+++ b/client/reader/following/main.tsx
@@ -84,7 +84,7 @@ function ReaderStreamSidebar(): JSX.Element | null {
return {
blogId: s.blogId,
feed_ID: s.feedId,
- feed_URL: s.feed_url,
+ feed_URL: s.feedUrl,
site_name: s.title,
site_description: s.description,
site_icon: s.icon,
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
index 0b89bfbc7e60a..e095dab632431 100644
--- a/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/index.ts
@@ -56,14 +56,14 @@ export interface RecommendedSite {
blogId: number;
description: string;
feedId: number;
- feed_url: string;
+ feedUrl: string;
icon: string;
railcar: Railcar;
title: string;
url: string;
}
-const mapResponseToRecommendedSites = ( {
+export const mapResponseToRecommendedSites = ( {
algorithm,
sites,
}: RecommendedSitesBody ): RecommendedSite[] =>
@@ -73,7 +73,7 @@ const mapResponseToRecommendedSites = ( {
blogId: site.blog_id,
description: site.description,
feedId: site.feed_id,
- feed_url: site.feed_url,
+ feedUrl: site.feed_url,
icon: site.icon?.img,
railcar: site.railcar,
title: decodeEntities( site.blog_title ?? site.name ),
diff --git a/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts b/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
index f944f94a628f7..3ef88b297090c 100644
--- a/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
+++ b/client/state/data-layer/wpcom/read/recommendations/sites/test/index.ts
@@ -111,25 +111,34 @@ describe( 'recommended sites', () => {
const expected: RecommendedSite[] = [
{
algorithm,
- railcar: {},
blogId: 19096129,
+ description: 'Description 1',
feedId: 185124,
+ feedUrl: 'http://bentehaarstad.wordpress.com/feed/',
+ icon: 'http://bentehaarstad.wordpress.com/favicon.ico',
+ railcar: {},
title: 'Bente Haarstad Photography&',
url: 'http://bentehaarstad.wordpress.com',
},
{
algorithm,
- railcar: {},
blogId: 38492359,
+ description: 'Description 2',
feedId: 42081376,
+ feedUrl: 'http://chrisnicholaswrites.wordpress.com/feed/',
+ icon: 'http://chrisnicholaswrites.wordpress.com/favicon.ico',
+ railcar: {},
title: 'The Renegade Press',
url: 'http://chrisnicholaswrites.wordpress.com',
},
{
algorithm,
- railcar: {},
blogId: 30436600,
+ description: 'Description 3',
feedId: 1098976,
+ feedUrl: 'http://makesomethingmondays.wordpress.com/feed/',
+ icon: 'http://makesomethingmondays.wordpress.com/favicon.ico',
+ railcar: {},
title: 'Make Something Mondays!',
url: 'http://makesomethingmondays.wordpress.com',
},
From 9397732504547821793dd3646525025de00b0386 Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Tue, 3 Dec 2024 19:58:46 +0500
Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=91=8C=20IMPROVE:=20psimplify=20title?=
=?UTF-8?q?=20implementation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/reader/stream/reader-popular-sites-sidebar/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/reader/stream/reader-popular-sites-sidebar/index.tsx b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
index a9ea25b1c82d7..e5e622eb5aadd 100644
--- a/client/reader/stream/reader-popular-sites-sidebar/index.tsx
+++ b/client/reader/stream/reader-popular-sites-sidebar/index.tsx
@@ -80,7 +80,7 @@ const ReaderPopularSitesSidebar = ( props: PopularSitesSidebarProps ) => {
return (
<>
- { title ? { title }
: null }
+ { title && { title }
}
{ popularSitesLinks }
>
);
From ea5e8921436e53785af102b824b1b566285fbf3d Mon Sep 17 00:00:00 2001
From: Mehmood Ahmad <31419912+mehmoodak@users.noreply.github.com>
Date: Tue, 3 Dec 2024 20:04:08 +0500
Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=94=A8=20REFACTOR:=20move=20ReaderStr?=
=?UTF-8?q?eamSidebar=20component=20to=20a=20separate=20file?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/reader/following/main.tsx | 52 +-----------------
.../following/reader-stream-sidebar.tsx | 54 +++++++++++++++++++
2 files changed, 55 insertions(+), 51 deletions(-)
create mode 100644 client/reader/following/reader-stream-sidebar.tsx
diff --git a/client/reader/following/main.tsx b/client/reader/following/main.tsx
index e1defc81c90ad..579e9f0132acd 100644
--- a/client/reader/following/main.tsx
+++ b/client/reader/following/main.tsx
@@ -1,9 +1,6 @@
import config from '@automattic/calypso-config';
import clsx from 'clsx';
import { translate } from 'i18n-calypso';
-import { useEffect } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { Dispatch } from 'redux';
import AsyncLoad from 'calypso/components/async-load';
import BloganuaryHeader from 'calypso/components/bloganuary-header';
import NavigationHeader from 'calypso/components/navigation-header';
@@ -11,21 +8,12 @@ import withDimensions from 'calypso/lib/with-dimensions';
import ReaderOnboarding from 'calypso/reader/onboarding';
import SuggestionProvider from 'calypso/reader/search-stream/suggestion-provider';
import ReaderStream, { WIDE_DISPLAY_CUTOFF } from 'calypso/reader/stream';
-import { RecommendedSite } from 'calypso/state/data-layer/wpcom/read/recommendations/sites';
-import {
- RecommendedSitesRequestAction,
- requestRecommendedSites,
-} from 'calypso/state/reader/recommended-sites/actions';
-import { getReaderRecommendedSites } from 'calypso/state/reader/recommended-sites/selectors';
-import { READER_RECENT_SIDEBAR_POPULAR_SITES } from '../follow-sources';
import Recent from '../recent';
-import ReaderPopularSitesSidebar from '../stream/reader-popular-sites-sidebar';
+import ReaderStreamSidebar from './reader-stream-sidebar';
import { useFollowingView } from './view-preference';
import ViewToggle from './view-toggle';
import './style.scss';
-export const RECOMMENDED_SITES_SEED = Math.floor( Math.random() * 10001 );
-
function FollowingStream( { ...props } ) {
const { currentView } = useFollowingView();
const viewToggle = config.isEnabled( 'reader/recent-feed-overhaul' ) ? : null;
@@ -58,42 +46,4 @@ function FollowingStream( { ...props } ) {
);
}
-function ReaderStreamSidebar(): JSX.Element | null {
- const dispatch = useDispatch< Dispatch< RecommendedSitesRequestAction > >();
- const recommendedSites = useSelector( ( state ) => {
- return getReaderRecommendedSites< RecommendedSite >( state, RECOMMENDED_SITES_SEED ) || [];
- } );
-
- useEffect( () => {
- // Avoid fetching recommended sites if they are already present in the store.
- if ( recommendedSites.length > 0 ) {
- return;
- }
-
- dispatch( requestRecommendedSites( { seed: RECOMMENDED_SITES_SEED, number: 10 } ) );
- }, [ dispatch, recommendedSites ] );
-
- if ( recommendedSites.length === 0 ) {
- return null;
- }
-
- return (
- {
- return {
- blogId: s.blogId,
- feed_ID: s.feedId,
- feed_URL: s.feedUrl,
- site_name: s.title,
- site_description: s.description,
- site_icon: s.icon,
- url: s.url,
- };
- } ) }
- title={ translate( 'Popular sites' ) }
- />
- );
-}
-
export default SuggestionProvider( withDimensions( FollowingStream ) );
diff --git a/client/reader/following/reader-stream-sidebar.tsx b/client/reader/following/reader-stream-sidebar.tsx
new file mode 100644
index 0000000000000..5d9f150140721
--- /dev/null
+++ b/client/reader/following/reader-stream-sidebar.tsx
@@ -0,0 +1,54 @@
+import { translate } from 'i18n-calypso';
+import { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { Dispatch } from 'redux';
+import { RecommendedSite } from 'calypso/state/data-layer/wpcom/read/recommendations/sites';
+import {
+ RecommendedSitesRequestAction,
+ requestRecommendedSites,
+} from 'calypso/state/reader/recommended-sites/actions';
+import { getReaderRecommendedSites } from 'calypso/state/reader/recommended-sites/selectors';
+import { READER_RECENT_SIDEBAR_POPULAR_SITES } from '../follow-sources';
+import ReaderPopularSitesSidebar from '../stream/reader-popular-sites-sidebar';
+
+export const RECOMMENDED_SITES_SEED = Math.floor( Math.random() * 10001 );
+
+function ReaderStreamSidebar(): JSX.Element | null {
+ const dispatch = useDispatch< Dispatch< RecommendedSitesRequestAction > >();
+ const recommendedSites = useSelector( ( state ) => {
+ return getReaderRecommendedSites< RecommendedSite >( state, RECOMMENDED_SITES_SEED ) || [];
+ } );
+
+ useEffect( () => {
+ // Avoid fetching recommended sites if they are already present in the store.
+ if ( recommendedSites.length > 0 ) {
+ return;
+ }
+
+ dispatch( requestRecommendedSites( { seed: RECOMMENDED_SITES_SEED, number: 10 } ) );
+ }, [ dispatch, recommendedSites ] );
+
+ if ( recommendedSites.length === 0 ) {
+ return null;
+ }
+
+ return (
+ {
+ return {
+ blogId: s.blogId,
+ feed_ID: s.feedId,
+ feed_URL: s.feedUrl,
+ site_name: s.title,
+ site_description: s.description,
+ site_icon: s.icon,
+ url: s.url,
+ };
+ } ) }
+ title={ translate( 'Popular sites' ) }
+ />
+ );
+}
+
+export default ReaderStreamSidebar;