Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions components/DesktopRail.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { usePathname, useRouter } from 'next/navigation';
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { useCourses, useTasks, useUserSettings, reorderCoursesOptimistic } from '@/lib/data-hooks';
Expand Down Expand Up @@ -204,7 +204,8 @@ export default function DesktopRail() {
const [collapsed, setCollapsed] = useRailCollapsed();
const { courses } = useCourses();
const { tasks } = useTasks();
const { active } = useTimerState();
const { active, start: startTimer } = useTimerState();
const router = useRouter();
const { reading, sizeOf } = useUpNext();
const { settings } = useUserSettings();

Expand Down Expand Up @@ -397,8 +398,8 @@ export default function DesktopRail() {
const tint = resolveTint(course.color, course.tint);
const tipText = `${course.code} 路 ${course.name}${count > 0 ? ` 路 ${count} open` : ''}`;
return (
<div key={course.id} className="group/spine relative">
<Link
key={course.id}
href={`/courses/${course.id}`}
aria-current={on ? 'page' : undefined}
className={`${rowBase} scroll-my-7 -ml-[18px] ${on ? 'text-ink' : 'text-ink-soft hover:text-ink'}`}
Expand Down Expand Up @@ -442,12 +443,29 @@ export default function DesktopRail() {
)}
{count > 0 && (
<span
className={`rail-wide shrink-0 font-mono text-[11px] tabular-nums text-muted ${running ? '' : 'ml-auto'}`}
className={`rail-wide shrink-0 font-mono text-[11px] tabular-nums text-muted mouse:group-hover/spine:invisible mouse:group-focus-within/spine:invisible ${running ? '' : 'ml-auto'}`}
>
{count}
</span>
)}
</Link>
{/* One click: an untimed sitting on this course, and the timer opens.
A sibling of the link, not inside it. Hover only; a touch screen has
no hover and keeps the start at the foot. */}
<button
type="button"
onClick={() => {
setTip(null);
startTimer(course.id, null, null);
router.push('/timer');
}}
aria-label={`Start untimed timer for ${course.code}`}
className="rail-wide absolute right-2 top-1/2 hidden h-7 w-7 -translate-y-1/2 place-items-center rounded-full opacity-0 transition-opacity mouse:grid mouse:group-hover/spine:opacity-100 focus-visible:opacity-100 mouse:group-focus-within/spine:opacity-100"
style={{ background: tint, color: course.color }}
>
{PLAY}
</button>
</div>
);
}

Expand Down
4 changes: 3 additions & 1 deletion readmedesign.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ is the whole screen, as it always was.
above it. The one you are on is swiped in its
own tint, as on the Tasks filter. A sitting on the clock puts a 6px dot in
the course colour pulsing on `tick` on its row; the rail never draws a
second clock. A long list fades at whichever end has more behind it and
second clock. Pointing at a spine (a mouse only) swaps its open count for a
small play disc in the course tint: one click starts an untimed sitting on
that course and opens the timer. A long list fades at whichever end has more behind it and
keeps the current course in view. Pointing at the list shows a dashed
"add a course" line after the last one, always there when the term has none.
- **The start** at the foot offers Up next's pick, through the same popover a
Expand Down
Loading