improve pulls view mobile layout
603 unmodified linesExpand all6046056066076086086096106116126136146156166176186196206216146156226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986996227007017027037043275 unmodified linesExpand all603 unmodified linesExpand all .untangled-diff-view-commit .untangled-diff-file-header { position: static; }
.untangled-pr-file-tree, .untangled-pr-file-tree { position: static; max-height: none; display: none; }}
@media (min-width: 768px) and (max-width: 1023px) { .untangled-pr-history { position: static; max-height: none; }}
.untangled-pr-file-tree { display: none;@media (max-width: 767px) { .untangled-pr-history { position: fixed; top: auto; bottom: 0; left: 0; right: 0; z-index: 50; width: 100%; max-height: none; overflow: visible; padding: 0; background: transparent; border: none; box-shadow: none; transform: translateY(calc(100% - 3rem)); transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); }
.untangled-pr-history.open { transform: none; }
.untangled-pr-history-body { transform: translateY(4rem); transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); }
.untangled-pr-history.open .untangled-pr-history-body { transform: none; }
.untangled-pr-history details, .untangled-pr-history details summary { border-top-left-radius: 0.625rem !important; border-top-right-radius: 0.625rem !important; }
/* Style the history card skeleton to be a collapsed header at the bottom on mobile */ .untangled-pr-history-card { border: none !important; background: transparent !important; }
.untangled-pr-history-card .untangled-pr-history-submission, .untangled-pr-history-card .px-4, .untangled-pr-history-card .p-4, .untangled-pr-history-card .untangled-pr-history-comment { display: none !important; }
.untangled-pr-history-card > header { background: rgb(229 231 235); height: 3rem; border-top-left-radius: 0.625rem !important; border-top-right-radius: 0.625rem !important; padding: 0 1rem; border: 1px solid rgb(209 213 219); border-bottom: none; }}
@media (max-width: 767px) and (prefers-color-scheme: dark) { .untangled-pr-history-card > header { background: rgb(31 41 55); border-color: rgb(55 65 81); }}
summary::-webkit-details-marker { display: none;}summary { list-style: none;}
@media (max-width: 767px) { .untangled-pr-summary-card { padding: 1rem; padding: 0.75rem; }
.untangled-thread-meta { padding: 0.25rem 0.25rem 0.5rem;3275 unmodified linesExpand all656 unmodified linesExpand all65765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369483 unmodified lines77877978078178278378478578678778878979079179279379479579685 unmodified lines8828838848858558868878888898908918928938948958968978981 unmodified line656 unmodified linesExpand all patch: string; roundLabel: string; storageKey: string; history: JSX.Element; mobileDrawerOpen?: boolean; onMobileDrawerClose?: () => void;}> = (props) => { const files = createMemo(() => parseDiffFiles(props.patch)); const stats = createMemo(() => totalDiffStats(files())); const tree = createMemo(() => diffFileTree(files())); const [expanded, setExpanded] = createSignal(true); const [filesVisible, setFilesVisible] = createSignal(true); const [historyVisible, setHistoryVisible] = createSignal(true);
const [isDesktop, setIsDesktop] = createSignal(window.matchMedia('(min-width: 768px)').matches); onMount(() => { const media = window.matchMedia('(min-width: 768px)'); const listener = (e: MediaQueryListEvent) => setIsDesktop(e.matches); media.addEventListener('change', listener); onCleanup(() => media.removeEventListener('change', listener)); });
createEffect(() => { if (!isDesktop() && props.mobileDrawerOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; } });
onCleanup(() => { document.body.style.overflow = ''; });
const loadReviewed = (): Set<string> => { try { const data = localStorage.getItem(props.storageKey); if (!data) return new Set();83 unmodified lines };
return ( <section class="untangled-pr-diff-breakout"> {/* backdrop overlay - only visible on mobile when open */} <div id="bottomSheetBackdrop" class={clsx( "fixed inset-0 bg-black/50 md:hidden opacity-0 pointer-events-none transition-opacity duration-300 z-40", props.mobileDrawerOpen && "opacity-100 pointer-events-auto" )} onClick={() => props.onMobileDrawerClose?.()} /> <div class={clsx( 'untangled-pr-diff-toolbar', !filesVisible() && 'untangled-pr-diff-toolbar-sidebar-collapsed', !historyVisible() && 'untangled-pr-diff-toolbar-history-collapsed', )}85 unmodified lines </For> </div>
<Show when={historyVisible()}> <aside class="untangled-pr-history">{props.history}</aside> <aside class={clsx( "untangled-pr-history", "fixed bottom-0 left-0 right-0 z-50 w-full md:static md:z-auto md:max-h-screen md:sticky md:top-12 overflow-hidden", props.mobileDrawerOpen && "open" )} > {props.history} </aside> </Show> </div> </section> );1 unmodified line1 unmodified line2345678910111017 unmodified linesExpand all102910301031103210331034103510361037355 unmodified linesExpand all1393139413951396139713981399139513961397140014011402140314041405139914001401140214061407140814091410141114121413141414151416141714181419142014211422140514061407140814091423142414251426142714281429143014311432143314341435143614371411141214131438143914401441144214431444212 unmodified linesExpand all1657165816591660166116621663166416657 unmodified lines1 unmodified lineimport { ArrowLeftRight, CircleChevronUp, CirclePlus, ChevronDown, ChevronUp, Copy, Diff, Eye, FolderCode,1017 unmodified linesExpand all const [composerOpen, setComposerOpen] = createSignal(false); const [workingAction, setWorkingAction] = createSignal<'comment' | 'state' | 'merge' | null>(null); const working = createMemo(() => workingAction() !== null); const [error, setError] = createSignal<string | null>(null); const [mobileDrawerOpen, setMobileDrawerOpen] = createSignal(false);
const pullQuery = createQuery(() => { const repo = repoQuery.data; return {355 unmodified linesExpand all <PullDiffView patch={patchQuery.data!} roundLabel={roundLabel()} storageKey={`reviewed:${repoQuery.data!.owner.handle}/${repoQuery.data!.slug}/pulls/${detail().pull.number || parseAtUri(detail().pull.uri).rkey}/round/${roundIndex()}`} mobileDrawerOpen={mobileDrawerOpen()} onMobileDrawerClose={() => setMobileDrawerOpen(false)} history={ <div class="flex flex-col"> {/* History Header */} <div <details open={true} class="rounded-t shadow-lg md:shadow-none group/panel w-full" > <summary class={clsx( 'flex items-baseline justify-between border border-b-0 rounded-t px-4 py-3 shadow-sm transition-colors duration-200', roundIndex() === 0 ? 'bg-blue-50 dark:bg-blue-950 border-blue-200 dark:border-blue-900' : 'bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700' "h-12 flex gap-4 items-center justify-between", "rounded-t cursor-pointer list-none px-4", "text-white md:text-black md:dark:text-white", detail().pull.state === 'open' ? 'bg-green-600 dark:bg-green-700' : detail().pull.state === 'merged' ? 'bg-purple-600 dark:bg-purple-700' : 'bg-red-600 dark:bg-red-700', "md:bg-white md:dark:bg-gray-800", "shadow-sm border-t md:border-x border-gray-200 dark:border-gray-700", "md:pointer-events-none" )} onClick={(e) => { e.preventDefault(); setMobileDrawerOpen(!mobileDrawerOpen()); }} > <h3 class="text-base font-semibold text-gray-900 dark:text-white">history</h3> <span class="text-sm text-gray-500 dark:text-gray-400"> {detail().pull.value.rounds.length} round{detail().pull.value.rounds.length === 1 ? '' : 's'} <span class="mx-1 select-none">·</span> {detail().comments.length} comment{detail().comments.length === 1 ? '' : 's'} <h3 class="text-base font-semibold text-white md:text-gray-900 md:dark:text-white">history</h3> <span class="pointer-events-auto cursor-text flex items-center gap-2 text-sm text-white md:text-gray-500 md:dark:text-gray-400"> <span> {detail().pull.value.rounds.length} round{detail().pull.value.rounds.length === 1 ? '' : 's'} </span> <span class="select-none before:content-['\00B7']"></span> <span> {detail().comments.length} comment{detail().comments.length === 1 ? '' : 's'} </span> <span class="md:hidden inline ml-2"> <Show when={mobileDrawerOpen()} fallback={<ChevronUp class="size-4" />}> <ChevronDown class="size-4" /> </Show> </span> </span> </div>
<For each={detail().pull.value.rounds}> </summary> <div class="max-h-[85vh] md:max-h-[calc(100vh-3rem-3rem)] w-full flex flex-col gap-4 overflow-y-auto bg-slate-100 dark:bg-gray-900 md:bg-transparent p-0 untangled-pr-history-body"> <For each={detail().pull.value.rounds}> {(round, index) => { const isSelected = () => index() === roundIndex(); const isLatest = () => index() === detail().pull.value.rounds.length - 1; const roundComments = () => commentsByRound()[index()] || [];212 unmodified linesExpand all ); }} </For> </div> </details> } /> </Match> </Switch>7 unmodified lines