v3: code quality pass
This commit is contained in:
@@ -26,9 +26,10 @@ import { usePlaylistListSync } from "../hooks/usePlaylistListSync.ts";
|
||||
import { usePositionAwareSync } from "../hooks/usePositionAwareSync.ts";
|
||||
import { useInfiniteScroll } from "../hooks/useInfiniteScroll.ts";
|
||||
import { useFeedCache } from "../hooks/useFeedCache.ts";
|
||||
import { Avatar } from "../components/Avatar.tsx";
|
||||
import { useScrollSave } from "../hooks/useScrollSave.ts";
|
||||
import { PlaylistCard } from "../components/PlaylistCard.tsx";
|
||||
import { NewPlaylistForm } from "../components/NewPlaylistForm.tsx";
|
||||
import { ProfileSubpageHeader } from "../components/ProfileSubpageHeader.tsx";
|
||||
import { ConfirmModal } from "../components/ConfirmModal.tsx";
|
||||
import { PageShell } from "../components/PageShell.tsx";
|
||||
import { PageError } from "../components/PageError.tsx";
|
||||
@@ -283,35 +284,24 @@ export function UserPlaylists() {
|
||||
!state.followed.loadingMore,
|
||||
);
|
||||
|
||||
// Scroll save
|
||||
useEffect(() => {
|
||||
if (state.status !== "loaded") return;
|
||||
let timer: ReturnType<typeof setTimeout>;
|
||||
const onScroll = () => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
if (state.status !== "loaded") return;
|
||||
const y = globalThis.scrollY;
|
||||
saveCreated(
|
||||
state.created.items,
|
||||
state.created.page,
|
||||
state.created.hasMore,
|
||||
y,
|
||||
);
|
||||
saveFollowed(
|
||||
state.followed.items,
|
||||
state.followed.page,
|
||||
state.followed.hasMore,
|
||||
y,
|
||||
);
|
||||
}, 100);
|
||||
};
|
||||
globalThis.addEventListener("scroll", onScroll, { passive: true });
|
||||
return () => {
|
||||
globalThis.removeEventListener("scroll", onScroll);
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [state, saveCreated, saveFollowed]);
|
||||
useScrollSave(
|
||||
state.status === "loaded",
|
||||
useCallback((y) => {
|
||||
if (state.status !== "loaded") return;
|
||||
saveCreated(
|
||||
state.created.items,
|
||||
state.created.page,
|
||||
state.created.hasMore,
|
||||
y,
|
||||
);
|
||||
saveFollowed(
|
||||
state.followed.items,
|
||||
state.followed.page,
|
||||
state.followed.hasMore,
|
||||
y,
|
||||
);
|
||||
}, [state, saveCreated, saveFollowed]),
|
||||
);
|
||||
|
||||
const scrollRestored = useRef(false);
|
||||
useLayoutEffect(() => {
|
||||
@@ -364,34 +354,25 @@ export function UserPlaylists() {
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
<div className="profile-subpage-header">
|
||||
<Link to={`/users/${username}`} className="profile-subpage-back">
|
||||
← {profileUser.username}
|
||||
</Link>
|
||||
<div className="profile-subpage-title-row">
|
||||
<Avatar
|
||||
userId={profileUser.id}
|
||||
username={profileUser.username}
|
||||
hasAvatar={!!profileUser.avatarMime}
|
||||
size={36}
|
||||
<ProfileSubpageHeader
|
||||
username={username!}
|
||||
profileUser={profileUser}
|
||||
title="Playlists"
|
||||
actions={isOwnProfile && (
|
||||
<NewPlaylistForm
|
||||
toggleClassName="btn-primary"
|
||||
onCreated={(p) =>
|
||||
setState((s) => {
|
||||
if (s.status !== "loaded") return s;
|
||||
if (s.created.items.some((pl) => pl.id === p.id)) return s;
|
||||
return {
|
||||
...s,
|
||||
created: { ...s.created, items: [p, ...s.created.items] },
|
||||
};
|
||||
})}
|
||||
/>
|
||||
<h1 className="profile-subpage-title">Playlists</h1>
|
||||
{isOwnProfile && (
|
||||
<NewPlaylistForm
|
||||
toggleClassName="btn-primary"
|
||||
onCreated={(p) =>
|
||||
setState((s) => {
|
||||
if (s.status !== "loaded") return s;
|
||||
if (s.created.items.some((pl) => pl.id === p.id)) return s;
|
||||
return {
|
||||
...s,
|
||||
created: { ...s.created, items: [p, ...s.created.items] },
|
||||
};
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
||||
<section className="profile-section">
|
||||
<div className="profile-section-header">
|
||||
|
||||
Reference in New Issue
Block a user