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
+38 -44
View File
@@ -1,14 +1,8 @@
import { useCallback, useEffect } from "react";
import {
Alert,
Dimensions,
Pressable,
Text,
View,
} from "react-native";
import type { Human } from "@/api/types";
import { SafeAreaView } from "react-native-safe-area-context";
import { StatusBar } from "expo-status-bar";
import { useCallback, useEffect } from 'react';
import { Alert, Dimensions, Pressable, Text, View } from 'react-native';
import type { Human } from '@/api/types';
import { SafeAreaView } from 'react-native-safe-area-context';
import { StatusBar } from 'expo-status-bar';
import {
AudioSession,
LiveKitRoom,
@@ -17,14 +11,14 @@ import {
useLocalParticipant,
useRoomContext,
useTracks,
} from "@livekit/react-native";
import type { TrackReferenceOrPlaceholder } from "@livekit/components-core";
import { Track } from "livekit-client";
import { Mic, MicOff, PhoneOff, Video, VideoOff } from "lucide-react-native";
import { useNetwork } from "@/hooks/use-networks";
import { resolveHumanDisplay } from "@/lib/humans";
import { cn } from "@/lib/utils";
import type { RootStackScreenProps } from "@/navigation/types";
} from '@livekit/react-native';
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core';
import { Track } from 'livekit-client';
import { Mic, MicOff, PhoneOff, Video, VideoOff } from 'lucide-react-native';
import { useNetwork } from '@/hooks/use-networks';
import { resolveHumanDisplay } from '@/lib/humans';
import { cn } from '@/lib/utils';
import type { RootStackScreenProps } from '@/navigation/types';
/**
* Mobile huddle screen — LiveKit room with a tile grid, basic mic/camera
@@ -35,7 +29,7 @@ import type { RootStackScreenProps } from "@/navigation/types";
export function HuddleScreen({
route,
navigation,
}: RootStackScreenProps<"Huddle">) {
}: RootStackScreenProps<'Huddle'>) {
const { token, serverUrl, streamName, networkId } = route.params;
// iOS in particular requires us to bracket the room session with
@@ -66,10 +60,10 @@ export function HuddleScreen({
connect={true}
audio={true}
video={false}
options={{ adaptiveStream: { pixelDensity: "screen" } }}
options={{ adaptiveStream: { pixelDensity: 'screen' } }}
onDisconnected={leave}
onError={(err) => {
Alert.alert("Huddle error", err.message ?? "Failed to connect.");
Alert.alert('Huddle error', err.message ?? 'Failed to connect.');
leave();
}}
>
@@ -119,15 +113,18 @@ function HuddleRoom({ networkId, streamName, onLeave }: HuddleRoomProps) {
}, [room, onLeave]);
return (
<SafeAreaView className="flex-1" edges={["top", "bottom"]}>
<SafeAreaView className="flex-1" edges={['top', 'bottom']}>
<View className="flex-row items-center justify-between px-4 pt-2 pb-3">
<View className="flex-1">
<Text className="text-white text-base font-semibold" numberOfLines={1}>
<Text
className="text-white text-base font-semibold"
numberOfLines={1}
>
{streamName}
</Text>
<Text className="text-white/60 text-xs mt-0.5">
{tracks.length === 1
? "1 participant"
? '1 participant'
: `${tracks.length} participants`}
</Text>
</View>
@@ -139,7 +136,7 @@ function HuddleRoom({ networkId, streamName, onLeave }: HuddleRoomProps) {
<View className="flex-row items-center justify-center gap-4 px-4 py-4">
<ControlButton
label={isMicrophoneEnabled ? "Mute" : "Unmute"}
label={isMicrophoneEnabled ? 'Mute' : 'Unmute'}
active={isMicrophoneEnabled}
onPress={toggleMic}
icon={
@@ -151,7 +148,7 @@ function HuddleRoom({ networkId, streamName, onLeave }: HuddleRoomProps) {
}
/>
<ControlButton
label={isCameraEnabled ? "Stop video" : "Start video"}
label={isCameraEnabled ? 'Stop video' : 'Start video'}
active={isCameraEnabled}
onPress={toggleCamera}
icon={
@@ -182,7 +179,7 @@ function TileGrid({ tiles, humans }: TileGridProps) {
// Compute a square-ish grid: 1 → 1col, 2 → 1col (stacked), 3-4 → 2col,
// 5+ → 2col with scroll. Keeps each tile big enough on a phone screen.
const columns = tiles.length <= 1 ? 1 : 2;
const { width, height } = Dimensions.get("window");
const { width, height } = Dimensions.get('window');
const rows = Math.max(1, Math.ceil(tiles.length / columns));
const tileWidth = (width - 16) / columns - 8;
// Subtract approx chrome height (header + control bar ≈ 200px). This is a
@@ -229,16 +226,12 @@ function Tile({
return (
<View
className={cn(
"flex-1 overflow-hidden rounded-2xl bg-neutral-900",
isSpeaking && "border-2 border-emerald-400",
'flex-1 overflow-hidden rounded-2xl bg-neutral-900',
isSpeaking && 'border-2 border-emerald-400',
)}
>
{hasVideo ? (
<VideoTrack
trackRef={tile}
style={{ flex: 1 }}
objectFit="cover"
/>
<VideoTrack trackRef={tile} style={{ flex: 1 }} objectFit="cover" />
) : (
<View className="flex-1 items-center justify-center">
<View className="h-16 w-16 items-center justify-center rounded-full bg-neutral-700">
@@ -261,7 +254,9 @@ function Tile({
}
function trackKey(tile: TrackReferenceOrPlaceholder): string {
const sid = isTrackReference(tile) ? tile.publication.trackSid : "placeholder";
const sid = isTrackReference(tile)
? tile.publication.trackSid
: 'placeholder';
return `${tile.participant.identity}:${tile.source}:${sid}`;
}
@@ -270,7 +265,7 @@ interface ControlButtonProps {
label: string;
onPress: () => void;
active?: boolean;
tone?: "default" | "danger";
tone?: 'default' | 'danger';
}
function ControlButton({
@@ -278,7 +273,7 @@ function ControlButton({
label,
onPress,
active = false,
tone = "default",
tone = 'default',
}: ControlButtonProps) {
// Used purely for the visual state — destructive tone always wins so
// "Leave" is unmistakable regardless of toggle state.
@@ -287,16 +282,15 @@ function ControlButton({
onPress={onPress}
accessibilityLabel={label}
className={cn(
"h-14 w-14 items-center justify-center rounded-full",
tone === "danger"
? "bg-red-600 active:bg-red-700"
'h-14 w-14 items-center justify-center rounded-full',
tone === 'danger'
? 'bg-red-600 active:bg-red-700'
: active
? "bg-white/20 active:bg-white/30"
: "bg-white/10 active:bg-white/20",
? 'bg-white/20 active:bg-white/30'
: 'bg-white/10 active:bg-white/20',
)}
>
{icon}
</Pressable>
);
}