Skip to content

Commit

Permalink
Reader Onboarding: Implement preview pane and selectable sites (#95445)
Browse files Browse the repository at this point in the history
* Print hello world onclick

* Print site CardData onclick

* Preview is working ish

* Use stream component, compact cards, and hide actions

* Improve responsive CSS

* Select first post for preview by default

* Improve style

* Hide post comments and ellipse

* Add preview title

* Rollback Prettier changes to an otherwise unchanged file

* Remove comment
  • Loading branch information
DustyReagan authored Oct 18, 2024
1 parent 2cd3cf2 commit dcff49b
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 19 deletions.
7 changes: 7 additions & 0 deletions client/blocks/reader-subscription-list-item/connected.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class ConnectedSubscriptionListItem extends Component {
followSource: PropTypes.string,
railcar: PropTypes.object,
disableSuggestedFollows: PropTypes.bool,
onItemClick: PropTypes.func,
isSelected: PropTypes.bool,
};

static defaultProps = {
Expand All @@ -33,6 +35,7 @@ class ConnectedSubscriptionListItem extends Component {
showLastUpdatedDate: true,
showFollowedOnDate: true,
disableSuggestedFollows: false,
onItemClick: () => {},
};

componentDidMount() {
Expand Down Expand Up @@ -65,6 +68,8 @@ class ConnectedSubscriptionListItem extends Component {
followSource,
railcar,
disableSuggestedFollows,
onItemClick,
isSelected,
} = this.props;

return (
Expand All @@ -81,6 +86,8 @@ class ConnectedSubscriptionListItem extends Component {
followSource={ followSource }
railcar={ railcar }
disableSuggestedFollows={ disableSuggestedFollows }
onItemClick={ onItemClick }
isSelected={ isSelected }
/>
);
}
Expand Down
17 changes: 16 additions & 1 deletion client/blocks/reader-subscription-list-item/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ function ReaderSubscriptionListItem( {
isLoggedIn,
registerLastActionRequiresLogin: registerLastActionRequiresLoginProp,
disableSuggestedFollows,
onItemClick,
isSelected,
} ) {
const siteTitle = getSiteName( { feed, site } );
const siteAuthor = site && site.owner;
Expand Down Expand Up @@ -111,8 +113,21 @@ function ReaderSubscriptionListItem( {
}
};

const handleClick = () => {
onItemClick();
};

return (
<div className={ clsx( 'reader-subscription-list-item', className ) }>
<div
className={ clsx( 'reader-subscription-list-item', className, {
'is-selected': isSelected,
} ) }
onClick={ handleClick }
onKeyDown={ ( e ) => e.key === 'Enter' && handleClick( e ) }
role="button"
tabIndex={ 0 }
aria-pressed={ isSelected }
>
<div className="reader-subscription-list-item__avatar">
<ReaderAvatar
siteIcon={ siteIcon }
Expand Down
60 changes: 57 additions & 3 deletions client/reader/onboarding/subscribe-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { LoadingPlaceholder } from '@automattic/components';
import { useQuery } from '@tanstack/react-query';
import { Modal, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import React, { useMemo } from 'react';
import React, { useMemo, useState, ComponentType, useEffect } from 'react';
import { useSelector } from 'react-redux';
import ConnectedReaderSubscriptionListItem from 'calypso/blocks/reader-subscription-list-item/connected';
import wpcom from 'calypso/lib/wp';
import Stream from 'calypso/reader/stream';
import { getReaderFollowedTags } from 'calypso/state/reader/tags/selectors';
import { curatedBlogs } from '../curated-blogs';

Expand All @@ -28,6 +29,15 @@ interface Card {
data: CardData[];
}

interface StreamProps {
streamKey: string;
className?: string;
followSource?: string;
useCompactCards?: boolean;
}

const TypedStream: ComponentType< StreamProps > = Stream as ComponentType< StreamProps >;

const SubscribeModal: React.FC< SubscribeModalProps > = ( { isOpen, onClose } ) => {
const followedTags = useSelector( getReaderFollowedTags ) || [];
const followedTagSlugs = followedTags.map( ( tag ) => tag.slug );
Expand All @@ -53,7 +63,12 @@ const SubscribeModal: React.FC< SubscribeModalProps > = ( { isOpen, onClose } )
( card: Card ) => card.type === 'recommended_blogs'
);

return recommendedBlogsCard ? recommendedBlogsCard.data : [];
return recommendedBlogsCard
? recommendedBlogsCard.data.map( ( site: CardData & { URL?: string } ) => ( {
...site,
site_URL: site.URL || site.site_URL,
} ) )
: [];
},
} );

Expand Down Expand Up @@ -111,6 +126,25 @@ const SubscribeModal: React.FC< SubscribeModalProps > = ( { isOpen, onClose } )
</>
);

const [ selectedSite, setSelectedSite ] = useState< CardData | null >( null );

// Select the first site by default when recommendations are loaded.
useEffect( () => {
if ( combinedRecommendations.length > 0 && ! selectedSite ) {
setSelectedSite( combinedRecommendations[ 0 ] );
}
}, [ combinedRecommendations, selectedSite ] );

const handleItemClick = ( site: CardData ) => {
setSelectedSite( site );
};

const formatUrl = ( url: string ): string => {
return url
.replace( /^(https?:\/\/)?(www\.)?/, '' ) // Remove protocol and www
.replace( /\/$/, '' ); // Remove trailing slash
};

return (
isOpen && (
<Modal
Expand Down Expand Up @@ -146,6 +180,8 @@ const SubscribeModal: React.FC< SubscribeModalProps > = ( { isOpen, onClose } )
showFollowedOnDate={ false }
followSource="reader-onboarding-modal"
disableSuggestedFollows
onItemClick={ () => handleItemClick( site ) }
isSelected={ selectedSite?.feed_ID === site.feed_ID }
/>
) ) }
</div>
Expand All @@ -157,7 +193,25 @@ const SubscribeModal: React.FC< SubscribeModalProps > = ( { isOpen, onClose } )
</div>
<div className="subscribe-modal__preview-column">
<div className="subscribe-modal__preview-placeholder">
{ __( 'Select a blog to preview its posts' ) }
{ selectedSite ? (
<>
<div className="subscribe-modal__preview-stream-header">
<h3>{ formatUrl( selectedSite.site_URL ) }</h3>
</div>
<div className="subscribe-modal__preview-stream-container">
<TypedStream
streamKey={ `feed:${ selectedSite.feed_ID }` }
className="is-site-stream subscribe-modal__preview-stream"
followSource="reader_subscribe_modal"
useCompactCards
/>
</div>
</>
) : (
<div className="subscribe-modal__preview-placeholder-text">
{ __( 'Select a blog to preview its posts' ) }
</div>
) }
</div>
</div>
</div>
Expand Down
70 changes: 55 additions & 15 deletions client/reader/onboarding/subscribe-modal/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@
&__content {
display: flex;
flex-direction: column;
height: 100%;
height: calc( 100vh - 200px );
align-items: center;

@include break-medium {
@media ( min-width: 1200px ) {
flex-direction: row;
overflow: hidden;
align-items: initial;
}
}

&__site-list-column {
flex: 1;
padding: 30px;
padding: 20px 20px 0;
overflow-y: auto;
max-width: 600px;

@include break-medium {
@media ( min-width: 1200px ) {
max-width: 450px;
}

Expand All @@ -37,31 +42,66 @@
p {
text-wrap: balance;
}

.reader-subscription-list-item {
padding: 12px;
border: 1px solid var( --color-neutral-5 );
border-radius: 6px; /* stylelint-disable-line scales/radii */
cursor: pointer;
margin-bottom: 12px;

&.is-selected {
background-color: #e6f3fa;
border: 1px solid #0087be;
border-radius: 6px; /* stylelint-disable-line scales/radii */
}
}
}

&__recommended-sites {
margin-bottom: 24px;
}

&__preview-column {
flex: 1;
padding: 24px;
display: flex;
display: none;
flex-direction: column;
overflow: hidden;

clip-path: inset( 0 0 0 0 );

@include break-medium {
@media ( min-width: 1200px ) {
display: flex;
}
}

&__recommended-sites {
margin-bottom: 24px;
.reader-post-actions,
.comments__comment-list,
.reader-post-options-menu__ellipsis-menu,
.reader-update-notice {
display: none;
}
}

&__preview-placeholder {
display: flex;
align-items: center;
justify-content: center;
flex-grow: 1;
background-color: #e0e0e0;
font-style: italic;
border: 1px solid #ccc;
border: 1px solid #f2f2f2;
border-radius: 6px; /* stylelint-disable-line scales/radii */
background-color: #f2f2f2;
height: calc( 100vh - 224px );
width: calc( 100vw - 620px );
overflow: hidden;
position: fixed;
}

&__preview-stream-header {
background-color: #fff;
text-align: center;
line-height: rem( 36px );
font-size: rem( 14px );
}

&__preview-stream-container {
padding-top: 40px;
}
}

0 comments on commit dcff49b

Please sign in to comment.