Restore dislike signal as icon-only chip next to Like
Removed the label ('Not for me') and kept it icon-only to match the
minimal direction, but the -3.0 affinity signal still fires so the
feed learns to show less of that content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|||||||
import {
|
import {
|
||||||
getVideoByYtId, updateProgress, createDownload, getDownload, deleteDownload,
|
getVideoByYtId, updateProgress, createDownload, getDownload, deleteDownload,
|
||||||
followChannelByUrl, toggleQueue, toggleLike, getChannelVideos, getChannel,
|
followChannelByUrl, toggleQueue, toggleLike, getChannelVideos, getChannel,
|
||||||
getSettings, updateSettings, getRelatedVideos, getDownloads,
|
getSettings, updateSettings, getRelatedVideos, getDownloads, rateVideo,
|
||||||
getBookmarks, createBookmark, updateBookmark, deleteBookmark, importChapters, clearChapters,
|
getBookmarks, createBookmark, updateBookmark, deleteBookmark, importChapters, clearChapters,
|
||||||
getCollections, addToCollection, getQueue,
|
getCollections, addToCollection, getQueue,
|
||||||
getVideoComments, refreshVideoComments,
|
getVideoComments, refreshVideoComments,
|
||||||
@@ -561,6 +561,7 @@ export default function Watch() {
|
|||||||
const [currentTime, setCurrentTime] = useState(0);
|
const [currentTime, setCurrentTime] = useState(0);
|
||||||
const [queued, setQueued] = useState(null);
|
const [queued, setQueued] = useState(null);
|
||||||
const [liked, setLiked] = useState(null);
|
const [liked, setLiked] = useState(null);
|
||||||
|
const [disliked, setDisliked] = useState(null);
|
||||||
const [selectedQuality, setSelectedQuality] = useState(null);
|
const [selectedQuality, setSelectedQuality] = useState(null);
|
||||||
const [speed, setSpeed] = useState(1);
|
const [speed, setSpeed] = useState(1);
|
||||||
const [autoplay, setAutoplay] = useState(false);
|
const [autoplay, setAutoplay] = useState(false);
|
||||||
@@ -772,6 +773,11 @@ export default function Watch() {
|
|||||||
onSuccess: (res) => { setLiked(res.data.liked); qc.invalidateQueries({ queryKey: ["liked-videos"] }); },
|
onSuccess: (res) => { setLiked(res.data.liked); qc.invalidateQueries({ queryKey: ["liked-videos"] }); },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const dislikeMut = useMutation({
|
||||||
|
mutationFn: () => rateVideo(video.id, isDisliked ? 0 : -1),
|
||||||
|
onSuccess: (res) => setDisliked(res.data.rating === -1),
|
||||||
|
});
|
||||||
|
|
||||||
const handlePiP = useCallback(async () => {
|
const handlePiP = useCallback(async () => {
|
||||||
if (!videoRef.current) return;
|
if (!videoRef.current) return;
|
||||||
try {
|
try {
|
||||||
@@ -787,6 +793,7 @@ export default function Watch() {
|
|||||||
const startAt = video?.watch_progress_seconds ?? 0;
|
const startAt = video?.watch_progress_seconds ?? 0;
|
||||||
const isQueued = queued ?? video?.queued ?? false;
|
const isQueued = queued ?? video?.queued ?? false;
|
||||||
const isLiked = liked ?? video?.liked ?? false;
|
const isLiked = liked ?? video?.liked ?? false;
|
||||||
|
const isDisliked = disliked ?? (video?.rating === -1) ?? false;
|
||||||
const dlComplete = dlStatus?.status === "complete" || video?.is_downloaded;
|
const dlComplete = dlStatus?.status === "complete" || video?.is_downloaded;
|
||||||
const isFollowed = followMut.isSuccess || video?.channel_followed;
|
const isFollowed = followMut.isSuccess || video?.channel_followed;
|
||||||
const subs = formatSubs(channel?.subscriber_count);
|
const subs = formatSubs(channel?.subscriber_count);
|
||||||
@@ -966,12 +973,20 @@ export default function Watch() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{video?.id && (
|
{video?.id && (
|
||||||
|
<>
|
||||||
<Chip active={isLiked} onClick={() => likeMut.mutate()} disabled={likeMut.isPending}>
|
<Chip active={isLiked} onClick={() => likeMut.mutate()} disabled={likeMut.isPending}>
|
||||||
<svg className="w-4 h-4" fill={isLiked ? "currentColor" : "none"} stroke="currentColor" viewBox="0 0 24 24">
|
<svg className="w-4 h-4" fill={isLiked ? "currentColor" : "none"} stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
||||||
</svg>
|
</svg>
|
||||||
{isLiked ? "Liked" : "Like"}
|
{isLiked ? "Liked" : "Like"}
|
||||||
</Chip>
|
</Chip>
|
||||||
|
<Chip active={isDisliked} onClick={() => dislikeMut.mutate()} disabled={dislikeMut.isPending} title="Not for me">
|
||||||
|
<svg className="w-4 h-4" fill={isDisliked ? "currentColor" : "none"} stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z"/>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 2h2.67A2.31 2.31 0 0122 4v7a2.31 2.31 0 01-2.33 2H17"/>
|
||||||
|
</svg>
|
||||||
|
</Chip>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user