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,22 +1,25 @@
import { useEffect, useRef, useState } from "react";
import { Pencil } from "lucide-react";
import type { Particle } from "@/api/types";
import type { ParticlePath } from "@/lib/particle-path";
import { cn } from "@/lib/utils";
import { useAllLinkMetadata, type LinkPreviewEntry } from "@/hooks/use-link-metadata";
import { extractUrls } from "@/lib/link-metadata";
import { useEffect, useRef, useState } from 'react';
import { Pencil } from 'lucide-react';
import type { Particle } from '@/api/types';
import type { ParticlePath } from '@/lib/particle-path';
import { cn } from '@/lib/utils';
import {
useAllLinkMetadata,
type LinkPreviewEntry,
} from '@/hooks/use-link-metadata';
import { extractUrls } from '@/lib/link-metadata';
import {
LinkPreviewCard,
LinkPreviewCardSkeleton,
} from "@/components/link-preview-card";
import { useParticleAttachments } from "@/hooks/use-particle-attachments";
import { ParticleAttachments } from "@/features/particles/particle-attachments";
import { TextEditOverlay } from "@/features/particles/text-edit-overlay";
import { RelativeTimestamp } from "@/components/relative-timestamp";
import { useAuthStore } from "@/stores/auth-store";
import { MarkdownEditor } from "@/features/compose/markdown-editor";
} from '@/components/link-preview-card';
import { useParticleAttachments } from '@/hooks/use-particle-attachments';
import { ParticleAttachments } from '@/features/particles/particle-attachments';
import { TextEditOverlay } from '@/features/particles/text-edit-overlay';
import { RelativeTimestamp } from '@/components/relative-timestamp';
import { useAuthStore } from '@/stores/auth-store';
import { MarkdownEditor } from '@/features/compose/markdown-editor';
type TextParticle = Extract<Particle, { type: "text" }>;
type TextParticle = Extract<Particle, { type: 'text' }>;
interface TextParticleViewProps {
particle: TextParticle;
@@ -43,18 +46,21 @@ function computeReadDuration(
attachmentCount: number,
): number {
const base = (text.length / CHARS_PER_MINUTE) * 60;
const extra = linkCount * EXTRA_S_PER_LINK + attachmentCount * EXTRA_S_PER_ATTACHMENT;
const extra =
linkCount * EXTRA_S_PER_LINK + attachmentCount * EXTRA_S_PER_ATTACHMENT;
return Math.min(Math.max(base + extra, MIN_DURATION_S), MAX_DURATION_S);
}
function getImmersiveTextStyle(length: number) {
if (length < 30) return { size: "text-5xl", weight: "font-semibold" };
if (length < 70) return { size: "text-3xl", weight: "font-semibold" };
return { size: "text-2xl", weight: "font-normal" };
if (length < 30) return { size: 'text-5xl', weight: 'font-semibold' };
if (length < 70) return { size: 'text-3xl', weight: 'font-semibold' };
return { size: 'text-2xl', weight: 'font-normal' };
}
function hasMarkdownFormatting(content: string): boolean {
return /^#{1,6} |^\s*[-*+] |^\s*\d+\. |^```|`[^`]+`|\*\*|__|\*[^*]|_[^_]|^>/m.test(content);
return /^#{1,6} |^\s*[-*+] |^\s*\d+\. |^```|`[^`]+`|\*\*|__|\*[^*]|_[^_]|^>/m.test(
content,
);
}
function LinkPreviews({ entries }: { entries: LinkPreviewEntry[] }) {
@@ -93,7 +99,11 @@ export function TextParticleView({
const hasAttachments = attachments.length > 0;
const hasEnrichments = hasLinks || hasAttachments;
const durationS = computeReadDuration(content, urls.length, attachments.length);
const durationS = computeReadDuration(
content,
urls.length,
attachments.length,
);
const elapsedRef = useRef(0);
// Reset elapsed when particle changes
@@ -120,8 +130,10 @@ export function TextParticleView({
// Content is just bare URLs with no surrounding text
const contentTrimmed = content.trim();
const linksOnly = hasLinks && urls.every((url) => contentTrimmed.includes(url)) &&
contentTrimmed.replace(/https?:\/\/[^\s<>"')\]]+/g, "").trim() === "";
const linksOnly =
hasLinks &&
urls.every((url) => contentTrimmed.includes(url)) &&
contentTrimmed.replace(/https?:\/\/[^\s<>"')\]]+/g, '').trim() === '';
const editButton = isCreator && !isEditing && (
<button
@@ -170,13 +182,17 @@ export function TextParticleView({
}
// Mode 2: short plain text, no enrichments — immersive centered display
if (content.length < IMMERSIVE_CHAR_LIMIT && !hasEnrichments && !hasMarkdownFormatting(content)) {
if (
content.length < IMMERSIVE_CHAR_LIMIT &&
!hasEnrichments &&
!hasMarkdownFormatting(content)
) {
const style = getImmersiveTextStyle(content.length);
return (
<div className="group relative flex h-full w-full flex-col items-center justify-center gap-4 bg-gradient-to-b from-black/40 via-black/20 to-black/40 px-8 pt-[var(--stream-safe-top,2rem)] pb-[var(--stream-safe-bottom,2rem)]">
<p
className={cn(
"max-w-2xl break-words text-center leading-relaxed text-white select-text cursor-text",
'max-w-2xl break-words text-center leading-relaxed text-white select-text cursor-text',
style.size,
style.weight,
)}
@@ -195,16 +211,21 @@ export function TextParticleView({
<div className="group relative flex h-full w-full items-center justify-center bg-gradient-to-b from-black/40 via-black/20 to-black/40 px-8 pt-[var(--stream-safe-top,2rem)] pb-[var(--stream-safe-bottom,2rem)]">
<div
className={cn(
"flex max-h-full w-full max-w-2xl flex-col gap-4 overflow-y-auto overscroll-contain rounded bg-white/10 p-6 backdrop-blur-md",
"[&::-webkit-scrollbar]:w-2",
"[&::-webkit-scrollbar]:p-2",
"[&::-webkit-scrollbar-track]:bg-transparent",
"[&::-webkit-scrollbar-thumb]:rounded-full",
"[&::-webkit-scrollbar-thumb]:bg-white/30",
"[&::-webkit-scrollbar-thumb]:hover:bg-white/50",
'flex max-h-full w-full max-w-2xl flex-col gap-4 overflow-y-auto overscroll-contain rounded bg-white/10 p-6 backdrop-blur-md',
'[&::-webkit-scrollbar]:w-2',
'[&::-webkit-scrollbar]:p-2',
'[&::-webkit-scrollbar-track]:bg-transparent',
'[&::-webkit-scrollbar-thumb]:rounded-full',
'[&::-webkit-scrollbar-thumb]:bg-white/30',
'[&::-webkit-scrollbar-thumb]:hover:bg-white/50',
)}
>
<MarkdownEditor key={content} value={content} readOnly className="select-text pb-3" />
<MarkdownEditor
key={content}
value={content}
readOnly
className="select-text pb-3"
/>
{hasLinks && <LinkPreviews entries={linkPreviews} />}