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
3 changes: 2 additions & 1 deletion KNOWLEDGE_BASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,12 @@ Press **?** to open the shortcut reference. Navigation shortcuts work outside te
| `Enter` | Open the focused commit. |
| `y` | Copy the focused commit's link. |
| `r` / `q` / `o` | Reply, quote, or show/hide replies. |
| `s` | Star or unstar the focused commit. |
| `c` | Write a commit. |
| `⌘/Ctrl+K` or `/` | Search developers and commits. |
| `⌘/Ctrl+Enter` | Submit from the composer. |
| `⌘/Ctrl+Shift+P` | Toggle composer preview. |
| `g` then `l` / `e` / `p` / `s` | Go to your log / Trending / profile / settings. |
| `g` then `l` / `e` / `p` / `s` / `n` / `m` / `*` | Go to your log / Trending / profile / settings / Notifications / Remotes / Starred. `g m` works only while Remotes is on. |

Source: [shortcut reference](resources/js/components/keyboard-shortcuts-dialog.tsx).

Expand Down
2 changes: 2 additions & 0 deletions resources/js/components/commit-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ export function CommitCard({
<div className="flex flex-wrap items-center gap-0.5">
<CommitStarButton
commit={commit}
keyShortcut="s"
className="px-2 py-0.5"
/>
<CommitPastelButton
Expand All @@ -546,6 +547,7 @@ export function CommitCard({
<>
<CommitStarButton
commit={commit}
keyShortcut="s"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
className="px-2 py-0.5"
/>
<CommitPastelButton
Expand Down
8 changes: 7 additions & 1 deletion resources/js/components/commit-star-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ function starLabel(starred: boolean, count: number): string {

export function CommitStarButton({
commit,
keyShortcut,
className,
}: {
commit: Commit;
keyShortcut?: string;
className?: string;
}) {
const { auth } = usePage().props;
Expand Down Expand Up @@ -156,13 +158,17 @@ export function CommitStarButton({
};

return (
<ActionTooltip label={starred ? 'Unstar' : 'Star'}>
<ActionTooltip
label={starred ? 'Unstar' : 'Star'}
shortcut={keyShortcut}
>
<button
ref={setElement}
aria-disabled={request.processing}
type="button"
onClick={toggle}
aria-pressed={starred}
aria-keyshortcuts={keyShortcut}
aria-label={starLabel(starred, count)}
className={cn(
'group/star inline-flex items-center gap-1 rounded-md px-1.5 py-1 font-mono text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-foreground',
Expand Down
1 change: 1 addition & 0 deletions resources/js/components/commit-thread.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
} from '@/lib/commit';
import { commitStateKey } from '@/lib/commit-state';
import { hasModKey } from '@/lib/keyboard';
import { exactCountTitle, formatCount, formatExactCount } from '@/lib/numbers';

Check warning on line 88 in resources/js/components/commit-thread.tsx

View workflow job for this annotation

GitHub Actions / lint

eslint(no-unused-vars)

resources/js/components/commit-thread.tsx:88:40: Identifier 'formatExactCount' is imported but never used.
import {
characterCount,
cn,
Expand Down Expand Up @@ -309,7 +309,7 @@
if (initial !== previousInitial) {
setPreviousInitial(initial);
if (initial !== undefined && (replies?.length ?? 0) <= repliesPerPage) {
++replyRequest.current;

Check warning on line 312 in resources/js/components/commit-thread.tsx

View workflow job for this annotation

GitHub Actions / lint

react(refs)

resources/js/components/commit-thread.tsx:312:27: Cannot access refs during render

Check warning on line 312 in resources/js/components/commit-thread.tsx

View workflow job for this annotation

GitHub Actions / lint

react(refs)

resources/js/components/commit-thread.tsx:312:15: Cannot access refs during render
setIsLoading(false);
setThread((current) => ({
...current,
Expand Down Expand Up @@ -395,7 +395,7 @@

let isCurrent = true;
const request = ++replyRequest.current;
setIsLoading(true);

Check warning on line 398 in resources/js/components/commit-thread.tsx

View workflow job for this annotation

GitHub Actions / lint

react(set-state-in-effect)

resources/js/components/commit-thread.tsx:398:9: Calling setState synchronously within an effect can trigger cascading renders

fetchRepliesUntil(
{ id: commitId },
Expand Down Expand Up @@ -1311,6 +1311,7 @@
<>
<CommitStarButton
commit={reply}
keyShortcut="s"
className="px-2 py-0.5"
/>
<CommitPastelButton
Expand Down
10 changes: 8 additions & 2 deletions resources/js/components/keyboard-shortcuts-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import { useKeyLabels } from '@/lib/keyboard';

type Shortcut = { keys: string[]; label: string };

const shortcuts = (keys: KeyLabels): Shortcut[] => [
const shortcuts = (keys: KeyLabels, hasRemotes: boolean): Shortcut[] => [
{ keys: ['j'], label: 'Next commit' },
{ keys: ['k'], label: 'Previous commit' },
{ keys: ['y'], label: 'Copy link to the focused commit' },
{ keys: ['↵'], label: 'Open the focused commit' },
{ keys: ['r'], label: 'Reply to commit' },
{ keys: ['q'], label: 'Quote commit' },
{ keys: ['s'], label: 'Star or unstar commit' },
{ keys: ['o'], label: 'Show or hide replies' },
{ keys: ['c'], label: 'Write a commit' },
{ keys: [keys.mod, 'K'], label: 'Search developers and commits' },
Expand All @@ -26,6 +27,9 @@ const shortcuts = (keys: KeyLabels): Shortcut[] => [
{ keys: ['g', 'e'], label: 'Go to trending' },
{ keys: ['g', 'p'], label: 'Go to your profile' },
{ keys: ['g', 's'], label: 'Go to settings' },
{ keys: ['g', 'n'], label: 'Go to notifications' },
...(hasRemotes ? [{ keys: ['g', 'm'], label: 'Go to remotes' }] : []),
{ keys: ['g', '*'], label: 'Go to starred' },
{ keys: ['?'], label: 'Show this list' },
];

Expand Down Expand Up @@ -63,10 +67,12 @@ export function KeyboardShortcutsDialog({
open,
onOpenChange,
canModerate,
hasRemotes,
}: {
open: boolean;
onOpenChange: (open: boolean) => void;
canModerate: boolean;
hasRemotes: boolean;
}) {
const keys = useKeyLabels();

Expand All @@ -78,7 +84,7 @@ export function KeyboardShortcutsDialog({
They work anywhere except while you're typing.
</DialogDescription>

<ShortcutList shortcuts={shortcuts(keys)} />
<ShortcutList shortcuts={shortcuts(keys, hasRemotes)} />

{canModerate && (
<section aria-labelledby="moderation-shortcuts">
Expand Down
24 changes: 21 additions & 3 deletions resources/js/hooks/use-keyboard-shortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { router } from '@inertiajs/react';
import { useEffect } from 'react';
import ConversationController from '@/actions/App/Http/Controllers/ConversationController';
import LogController from '@/actions/App/Http/Controllers/LogController';
import NotificationController from '@/actions/App/Http/Controllers/NotificationController';
import StarredCommitController from '@/actions/App/Http/Controllers/StarredCommitController';
import { signIn } from '@/lib/auth';
import { hasModKey } from '@/lib/keyboard';
import { show } from '@/routes/user';
Expand Down Expand Up @@ -43,11 +46,13 @@ export function focusCommit(commit: HTMLElement): void {
}

/**
* Focus inside a reply acts on that reply, not on the commit card around it.
*
* A deleted commit's actions are inert, which stops pointers and focus but not a scripted click.
*/
function focusedCommitAction(key: string): HTMLButtonElement | null {
const action = document.activeElement
?.closest('[data-commit]')
?.closest('[data-reply], [data-commit]')
?.querySelector<HTMLButtonElement>(
`button[aria-keyshortcuts="${CSS.escape(key)}"]`,
);
Expand Down Expand Up @@ -77,6 +82,7 @@ function openFocusedCommit(): boolean {
export function useKeyboardShortcuts(
user: User | null,
log: Log | null,
hasRemotes: boolean,
onShowHelp: () => void,
onSearch: () => void,
onCompose: () => void,
Expand All @@ -87,12 +93,24 @@ export function useKeyboardShortcuts(

const goTo: Record<string, () => void> =
user === null || log === null
? { l: signIn, e: signIn, p: signIn, s: signIn }
? {
l: signIn,
e: signIn,
p: signIn,
s: signIn,
n: signIn,
'*': signIn,
}
: {
l: () => router.visit(LogController.show(log)),
e: () => router.visit(LogController.show('trending')),
p: () => router.visit(show(user)),
s: () => router.visit(edit()),
n: () => router.visit(NotificationController.index()),
'*': () => router.visit(StarredCommitController.index()),
...(hasRemotes && {
m: () => router.visit(ConversationController.index()),
}),
};

const onKeyDown = (event: KeyboardEvent) => {
Expand Down Expand Up @@ -171,5 +189,5 @@ export function useKeyboardShortcuts(
window.removeEventListener('keydown', onKeyDown);
clearTimeout(goToTimeout);
};
}, [user, log, onShowHelp, onSearch, onCompose]);
}, [user, log, hasRemotes, onShowHelp, onSearch, onCompose]);
}
2 changes: 2 additions & 0 deletions resources/js/layouts/app-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default function AppLayout({ children }: AppLayoutProps) {
useKeyboardShortcuts(
auth.user,
auth.log,
auth.remotes !== null,
showShortcuts,
openSearch,
compose,
Expand Down Expand Up @@ -185,6 +186,7 @@ export default function AppLayout({ children }: AppLayoutProps) {
open={isShowingShortcuts}
onOpenChange={setIsShowingShortcuts}
canModerate={auth.isAdmin}
hasRemotes={auth.remotes !== null}
/>

{isGuest && <LocalSignInDialog />}
Expand Down
1 change: 1 addition & 0 deletions resources/js/pages/onboarding/show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ export default function Show({
open={isShowingShortcuts}
onOpenChange={setIsShowingShortcuts}
canModerate={auth.isAdmin}
hasRemotes={auth.remotes !== null}
/>
</>
);
Expand Down
Loading