newOS for Developers
Back to Overview
useRating
hook175 linesHandles the voting/rating mechanism for posts with short taps, long-press progression, error handling, and Watts collection modal.
Source Path
apps/web/hooks/useRating.tsxPackage
@newos/web
Signature
useRating(): {
rateDisabled: boolean; // Is rating currently disabled
progress: number; // Progress bar value (0-100)
err: string | null; // Error message if any
pending: boolean; // Is a rating in progress
shortRating: (id: string) => void; // Handler for quick tap rating
longClick: (id: string) => void; // Handler for long press start
longClickEnd: () => void; // Handler for long press end
longClickProgress: () => void; // Progress tick for long press
modal: React.ReactElement; // Watts collection modal
}Data Flow & API Calls
Reads (Input)
current() — Gets current user to check Watts balanceWrites (Output)
rate({ id, value }) — Submits the rating for a postValue: 1 for short rating, up to 100 for long-press
powerUp() — Triggered via modal when user needs more WattsHooks Used
useDialog() — Manages Watts collection modaluseIsWideScreen() — Responsive behaviorKey Features
Short Rating (Tap)
Call shortRating(id) for a quick +1 Watt vote. Automatically debounced to prevent double-taps.
Long Press Rating
For larger ratings: call longClick(id) on press start,longClickProgress() on interval, longClickEnd() on release.
Progress Bar
During long press, progress increments from 0 to 100. Final value determines the rating amount.
Watts Collection Modal
When user has 0 Watts, shows a modal to collect free Watts. Access via modal return value.
Error Handling
err contains error messages. Check for 401 (unauthorized) to prompt login, or 402 for insufficient Watts.
Usage Example
const {
shortRating,
longClick,
longClickEnd,
longClickProgress,
progress,
pending,
modal
} = useRating();
// Set up interval for long press
const intervalRef = useRef<NodeJS.Timer>();
const handleMouseDown = (postId: string) => {
longClick(postId);
intervalRef.current = setInterval(longClickProgress, 50);
};
const handleMouseUp = () => {
clearInterval(intervalRef.current);
longClickEnd();
};
return (
<>
<button
onClick={() => shortRating(postId)}
onMouseDown={() => handleMouseDown(postId)}
onMouseUp={handleMouseUp}
disabled={pending}
>
<ProgressCircle progress={progress} />
⚡ Vote
</button>
{modal}
</>
);Edge Cases & Gotchas
rateDisabled State — Check
rateDisabled before allowing rating actions. True when pending or user has no Watts.Self-Rating Prevention — Some components check if author === current user before enabling rating. This hook doesn't enforce it.
Modal Rendering — Always render the
modal return value in your component. It's null when not active.Touch Events — For mobile, use
onTouchStart andonTouchEnd in addition to mouse events.Progress Reset — Progress automatically resets to 0 when
longClickEnd() is called.