infra: add linting and formatting for js projects (#230)

* wip

* wip

* wip

* format

* wip(mobile): lint and format

* cleanup

* nits

* nits

* idiomatic react

* nit

* format all root files
This commit was merged in pull request #230.
This commit is contained in:
Arjun Patel
2026-06-02 07:44:24 -07:00
committed by GitHub
parent 2fe562ce2b
commit a8a0b7db1b
258 changed files with 7822 additions and 5195 deletions
@@ -1,12 +1,12 @@
import { useEffect, useRef, type ReactNode } from "react";
import { Platform, ScrollView, Text, View, type ViewStyle } from "react-native";
import { Renderer, useMarkdown, type MarkedStyles } from "react-native-marked";
import type { Particle } from "@/api/types";
import { cn } from "@/lib/utils";
import { RelativeTimestamp } from "@/components/RelativeTimestamp";
import { useStreamSafeArea } from "./stream-safe-area";
import { useEffect, useRef, type ReactNode } from 'react';
import { Platform, ScrollView, Text, View, type ViewStyle } from 'react-native';
import { Renderer, useMarkdown, type MarkedStyles } from 'react-native-marked';
import type { Particle } from '@/api/types';
import { cn } from '@/lib/utils';
import { RelativeTimestamp } from '@/components/RelativeTimestamp';
import { useStreamSafeArea } from './stream-safe-area';
type TextParticle = Extract<Particle, { type: "text" }>;
type TextParticle = Extract<Particle, { type: 'text' }>;
interface TextParticleViewProps {
particle: TextParticle;
@@ -31,11 +31,9 @@ function computeReadDuration(text: string): number {
}
function getImmersiveStyle(length: number) {
if (length < 30)
return { className: "text-5xl font-semibold leading-tight" };
if (length < 70)
return { className: "text-3xl font-semibold leading-snug" };
return { className: "text-2xl font-normal leading-snug" };
if (length < 30) return { className: 'text-5xl font-semibold leading-tight' };
if (length < 70) return { className: 'text-3xl font-semibold leading-snug' };
return { className: 'text-2xl font-normal leading-snug' };
}
// Mirrors desktop's text-particle-view: short plain notes get the immersive
@@ -59,7 +57,7 @@ function withTaskCheckboxes(markdown: string): string {
return markdown.replace(
TASK_ITEM_RE,
(_match, indent: string, mark: string) =>
`${indent}${mark === " " ? "☐" : "☑"} `,
`${indent}${mark === ' ' ? '☐' : '☑'} `,
);
}
@@ -72,11 +70,11 @@ function withTaskCheckboxes(markdown: string): string {
// Known gap vs desktop: fenced code blocks aren't syntax-highlighted (Crepe
// uses CodeMirror; react-native-marked only exposes the language tag). They
// render as plain monospace on the dark surface, which is acceptable for v1.
const TEXT_COLOR = "rgba(255,255,255,0.92)";
const ACCENT = "#60a5fa";
const SURFACE = "rgba(24,24,28,0.96)";
const OUTLINE = "rgba(255,255,255,0.2)";
const MONO = Platform.OS === "ios" ? "Menlo" : "monospace";
const TEXT_COLOR = 'rgba(255,255,255,0.92)';
const ACCENT = '#60a5fa';
const SURFACE = 'rgba(24,24,28,0.96)';
const OUTLINE = 'rgba(255,255,255,0.2)';
const MONO = Platform.OS === 'ios' ? 'Menlo' : 'monospace';
const MARKDOWN_THEME = {
colors: {
@@ -90,26 +88,88 @@ const MARKDOWN_THEME = {
const MARKDOWN_STYLES: MarkedStyles = {
text: { color: TEXT_COLOR, fontSize: 18, lineHeight: 28 },
li: { color: TEXT_COLOR, fontSize: 18, lineHeight: 28 },
strong: { fontWeight: "700" },
em: { fontStyle: "italic" },
strong: { fontWeight: '700' },
em: { fontStyle: 'italic' },
strikethrough: {
textDecorationLine: "line-through",
color: "rgba(255,255,255,0.6)",
textDecorationLine: 'line-through',
color: 'rgba(255,255,255,0.6)',
},
// fontStyle "normal" cancels react-native-marked's italic-by-default for
// links and inline code (desktop renders neither italic).
link: { color: ACCENT, fontStyle: "normal" },
link: { color: ACCENT, fontStyle: 'normal' },
// borderBottomWidth 0 removes the library's default heading underline rule,
// which desktop's headings don't have.
h1: { color: "#ffffff", fontSize: 28, lineHeight: 34, fontWeight: "700", marginTop: 8, marginBottom: 8, borderBottomWidth: 0 },
h2: { color: "#ffffff", fontSize: 24, lineHeight: 30, fontWeight: "700", marginTop: 8, marginBottom: 6, borderBottomWidth: 0 },
h3: { color: "#ffffff", fontSize: 20, lineHeight: 26, fontWeight: "600", marginTop: 6, marginBottom: 4 },
h4: { color: "#ffffff", fontSize: 18, lineHeight: 24, fontWeight: "600", marginTop: 6, marginBottom: 4 },
h5: { color: "#ffffff", fontSize: 16, lineHeight: 22, fontWeight: "600", marginTop: 4, marginBottom: 2 },
h6: { color: "rgba(255,255,255,0.7)", fontSize: 15, lineHeight: 20, fontWeight: "600", marginTop: 4, marginBottom: 2 },
codespan: { color: "#fca5a5", fontFamily: MONO, fontStyle: "normal", backgroundColor: "rgba(255,255,255,0.1)" },
code: { backgroundColor: SURFACE, borderColor: OUTLINE, borderWidth: 1, borderRadius: 8, padding: 12, marginVertical: 6 },
blockquote: { borderLeftWidth: 3, borderLeftColor: OUTLINE, paddingLeft: 12, marginVertical: 6, opacity: 0.85 },
h1: {
color: '#ffffff',
fontSize: 28,
lineHeight: 34,
fontWeight: '700',
marginTop: 8,
marginBottom: 8,
borderBottomWidth: 0,
},
h2: {
color: '#ffffff',
fontSize: 24,
lineHeight: 30,
fontWeight: '700',
marginTop: 8,
marginBottom: 6,
borderBottomWidth: 0,
},
h3: {
color: '#ffffff',
fontSize: 20,
lineHeight: 26,
fontWeight: '600',
marginTop: 6,
marginBottom: 4,
},
h4: {
color: '#ffffff',
fontSize: 18,
lineHeight: 24,
fontWeight: '600',
marginTop: 6,
marginBottom: 4,
},
h5: {
color: '#ffffff',
fontSize: 16,
lineHeight: 22,
fontWeight: '600',
marginTop: 4,
marginBottom: 2,
},
h6: {
color: 'rgba(255,255,255,0.7)',
fontSize: 15,
lineHeight: 20,
fontWeight: '600',
marginTop: 4,
marginBottom: 2,
},
codespan: {
color: '#fca5a5',
fontFamily: MONO,
fontStyle: 'normal',
backgroundColor: 'rgba(255,255,255,0.1)',
},
code: {
backgroundColor: SURFACE,
borderColor: OUTLINE,
borderWidth: 1,
borderRadius: 8,
padding: 12,
marginVertical: 6,
},
blockquote: {
borderLeftWidth: 3,
borderLeftColor: OUTLINE,
paddingLeft: 12,
marginVertical: 6,
opacity: 0.85,
},
// hr is left to the library default, which already draws a 1px rule in the
// themed border color (OUTLINE).
table: { borderWidth: 1, borderColor: OUTLINE, marginVertical: 6 },
@@ -187,7 +247,10 @@ export function TextParticleView({
// Immersive (short, plain): centered, large type — feels like a lock-screen
// note. Short messages that contain markdown fall through to the rendered
// card so formatting isn't shown as raw syntax.
if (content.length < IMMERSIVE_CHAR_LIMIT && !hasMarkdownFormatting(content)) {
if (
content.length < IMMERSIVE_CHAR_LIMIT &&
!hasMarkdownFormatting(content)
) {
const style = getImmersiveStyle(content.length);
return (
<View
@@ -198,7 +261,7 @@ export function TextParticleView({
}}
>
<Text
className={cn("text-white text-center max-w-xl", style.className)}
className={cn('text-white text-center max-w-xl', style.className)}
>
{content}
</Text>