-
Notifications
You must be signed in to change notification settings - Fork 138
Fix #596: Implement favorite button functionality on podcast details … #633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7eafcc7
92a2e0c
b74455e
a872569
ec21f07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -359,6 +359,7 @@ html[data-theme='light'] { | |||||
| transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | ||||||
| cursor: pointer; | ||||||
| position: relative; | ||||||
| z-index: 1; | ||||||
| overflow: hidden; | ||||||
| animation: fadeInUp 0.6s ease-out both; | ||||||
| } | ||||||
|
|
@@ -404,12 +405,40 @@ html[data-theme='light'] { | |||||
| gap: 8px; | ||||||
| opacity: 0; | ||||||
| transition: opacity 0.3s ease; | ||||||
| position: relative; | ||||||
| z-index: 10; | ||||||
| pointer-events: auto; | ||||||
| } | ||||||
|
|
||||||
| .enhanced-podcast-card:hover .card-actions { | ||||||
| opacity: 1; | ||||||
| } | ||||||
|
|
||||||
| .action-btn.share { | ||||||
| background-color: rgba(123, 124, 128, 0.15); /* same subtle bg as unfavorited */ | ||||||
| border: 1px solid rgba(123, 124, 128, 0.3); /* same border */ | ||||||
| transition: all 0.3s ease; | ||||||
| color: inherit; /* keep the existing icon color */ | ||||||
| border-radius: 8px; | ||||||
| width: 36px; | ||||||
| height: 36px; | ||||||
| cursor: pointer; | ||||||
| font-size: 14px; | ||||||
| position: relative; | ||||||
| z-index: 15; | ||||||
| user-select: none; | ||||||
| } | ||||||
|
|
||||||
| .action-btn.share:hover { | ||||||
| background-color: rgba(123, 124, 128, 0.25); /* slightly darker on hover */ | ||||||
| border-color: rgba(123, 124, 128, 0.5); | ||||||
| transform: scale(1.1); | ||||||
| } | ||||||
|
|
||||||
| .action-btn.share:active { | ||||||
| transform: scale(0.95); | ||||||
| } | ||||||
|
|
||||||
| .action-btn { | ||||||
| width: 36px; | ||||||
| height: 36px; | ||||||
|
|
@@ -419,12 +448,35 @@ html[data-theme='light'] { | |||||
| cursor: pointer; | ||||||
| transition: all 0.3s ease; | ||||||
| font-size: 14px; | ||||||
| position: relative; | ||||||
| z-index: 15; | ||||||
| pointer-events: auto !important; | ||||||
| user-select: none; | ||||||
| } | ||||||
|
|
||||||
| .action-btn:hover { | ||||||
| background: var(--podcast-bg-card-hover); | ||||||
| transform: scale(1.1); | ||||||
| } | ||||||
| /* Enhanced favorite button styling */ | ||||||
| .action-btn.favorite { | ||||||
| transition: all 0.2s ease; | ||||||
| border: 1px solid transparent; | ||||||
| } | ||||||
|
|
||||||
| .action-btn.favorite:active { | ||||||
| transform: scale(0.95); | ||||||
| } | ||||||
|
|
||||||
| .action-btn.favorite.unfavorited { | ||||||
| background-color: rgba(123, 124, 128, 0.15); /* light purple-blue tint */ | ||||||
| color: white; /* keep the heart white */ | ||||||
| border-color: rgba(123, 124, 128, 0.3); | ||||||
| } | ||||||
|
|
||||||
| .action-btn.favorite.unfavorited:hover { | ||||||
| background-color: rgba(123, 124, 128, 0.15); | ||||||
|
||||||
| background-color: rgba(123, 124, 128, 0.15); | |
| background-color: rgba(123, 124, 128, 0.25); /* increased opacity for visible hover effect */ |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -99,8 +99,18 @@ const SpotifyTitle: React.FC<SpotifyTitleProps> = ({ spotifyUrl, type }) => { | |||||||||
| export default function Podcasts(): ReactElement { | ||||||||||
| const history = useHistory(); | ||||||||||
| const [currentPage, setCurrentPage] = useState(1); | ||||||||||
| const [searchTerm, setSearchTerm] = useState(''); | ||||||||||
| const [selectedFilter, setSelectedFilter] = useState<'all' | 'episode' | 'show' | 'playlist'>('all'); | ||||||||||
| const [searchTerm, setSearchTerm] = useState(""); | ||||||||||
| const [selectedFilter, setSelectedFilter] = useState< | ||||||||||
| "all" | "episode" | "show" | "playlist" | ||||||||||
| >("all"); | ||||||||||
|
||||||||||
| >("all"); | |
| >('all'); |
Copilot
AI
Oct 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The className logic is confusing - applying both 'unfavorited' and potentially 'favorited' classes. Consider using conditional logic: className={action-btn favorite ${favorites.includes(podcast.id) ? 'favorited' : 'unfavorited'}}
| className={`action-btn favorite unfavorited ${ | |
| favorites.includes(podcast.id) ? "favorited" : "" | |
| }`} | |
| className={`action-btn favorite ${favorites.includes(podcast.id) ? 'favorited' : 'unfavorited'}`} |
Copilot
AI
Oct 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple event propagation prevention methods are redundant. e.nativeEvent.stopImmediatePropagation() is unnecessary when e.stopPropagation() is already used, and handleFavorite already calls event.stopPropagation(). Consider simplifying to just e.stopPropagation() or move all event handling to the handleFavorite function.
| e.preventDefault(); | |
| e.stopPropagation(); | |
| e.nativeEvent.stopImmediatePropagation(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function parameter
podcastis optional but the function body doesn't handle the undefined case. This will cause runtime errors when accessingpodcast.typeandpodcast.spotifyUrlif no podcast is passed.