Tighten up eslint rule to catch unused const {_} = useLingui() (#9122)

* tighten eslint config to catch unused `useLingui`s

* fix now-invalid uses of _

* remove unused function that produces a ton of eslint warnings

* upgrade react compiler plugin
This commit is contained in:
Samuel Newman
2025-10-02 19:59:05 +03:00
committed by GitHub
parent 02b189a40e
commit 77bf49f212
19 changed files with 29 additions and 64 deletions
@@ -24,7 +24,6 @@ import type * as bsky from '#/types/bsky'
export function RecentChats({postUri}: {postUri: string}) {
const control = useDialogContext()
const {_} = useLingui()
const {currentAccount} = useSession()
const {data} = useListConvosQuery({status: 'accepted'})
const convos = data?.pages[0]?.convos?.slice(0, 10)
@@ -47,7 +47,6 @@ export function StarterPackDialog({
targetDid,
enabled,
}: StarterPackDialogProps) {
const {_} = useLingui()
const navigation = useNavigation<NavigationProp>()
const requireEmailVerification = useRequireEmailVerification()
+1 -1
View File
@@ -51,7 +51,7 @@ export function useIntentHandler() {
}
const urlp = new URL(url)
const [_, intent, intentType] = urlp.pathname.split('/')
const [__, intent, intentType] = urlp.pathname.split('/')
// On native, our links look like bluesky://intent/SomeIntent, so we have to check the hostname for the
// intent check. On web, we have to check the first part of the path since we have an actual hostname
+11 -11
View File
@@ -105,7 +105,7 @@ export function parseEmbedPlayerFromUrl(
urlp.hostname === 'm.youtube.com' ||
urlp.hostname === 'music.youtube.com'
) {
const [_, page, shortOrLiveVideoId] = urlp.pathname.split('/')
const [__, page, shortOrLiveVideoId] = urlp.pathname.split('/')
const isShorts = page === 'shorts'
const isLive = page === 'live'
@@ -137,7 +137,7 @@ export function parseEmbedPlayerFromUrl(
window.location.hostname
: 'localhost'
const [_, channelOrVideo, clipOrId, id] = urlp.pathname.split('/')
const [__, channelOrVideo, clipOrId, id] = urlp.pathname.split('/')
if (channelOrVideo === 'videos') {
return {
@@ -162,7 +162,7 @@ export function parseEmbedPlayerFromUrl(
// spotify
if (urlp.hostname === 'open.spotify.com') {
const [_, typeOrLocale, idOrType, id] = urlp.pathname.split('/')
const [__, typeOrLocale, idOrType, id] = urlp.pathname.split('/')
if (idOrType) {
if (typeOrLocale === 'playlist' || idOrType === 'playlist') {
@@ -210,7 +210,7 @@ export function parseEmbedPlayerFromUrl(
urlp.hostname === 'soundcloud.com' ||
urlp.hostname === 'www.soundcloud.com'
) {
const [_, user, trackOrSets, set] = urlp.pathname.split('/')
const [__, user, trackOrSets, set] = urlp.pathname.split('/')
if (user && trackOrSets) {
if (trackOrSets === 'sets' && set) {
@@ -270,7 +270,7 @@ export function parseEmbedPlayerFromUrl(
}
if (urlp.hostname === 'vimeo.com' || urlp.hostname === 'www.vimeo.com') {
const [_, videoId] = urlp.pathname.split('/')
const [__, videoId] = urlp.pathname.split('/')
if (videoId) {
return {
type: 'vimeo_video',
@@ -281,7 +281,7 @@ export function parseEmbedPlayerFromUrl(
}
if (urlp.hostname === 'giphy.com' || urlp.hostname === 'www.giphy.com') {
const [_, gifs, nameAndId] = urlp.pathname.split('/')
const [__, gifs, nameAndId] = urlp.pathname.split('/')
/*
* nameAndId is a string that consists of the name (dash separated) and the id of the gif (the last part of the name)
@@ -309,7 +309,7 @@ export function parseEmbedPlayerFromUrl(
// These can include (presumably) a tracking id in the path name, so we have to check for that as well
if (giphyRegex.test(urlp.hostname)) {
// We can link directly to the gif, if its a proper link
const [_, media, trackingOrId, idOrFilename, filename] =
const [__, media, trackingOrId, idOrFilename, filename] =
urlp.pathname.split('/')
if (media === 'media') {
@@ -338,7 +338,7 @@ export function parseEmbedPlayerFromUrl(
// Finally, we should see if it is a link to i.giphy.com. These links don't necessarily end in .gif but can also
// be .webp
if (urlp.hostname === 'i.giphy.com' || urlp.hostname === 'www.i.giphy.com') {
const [_, mediaOrFilename, filename] = urlp.pathname.split('/')
const [__, mediaOrFilename, filename] = urlp.pathname.split('/')
if (mediaOrFilename === 'media' && filename) {
const gifId = filename.split('.')[0]
@@ -389,7 +389,7 @@ export function parseEmbedPlayerFromUrl(
const path_components = urlp.pathname.slice(1, i + 1).split('/')
if (path_components.length === 4) {
// discard username - it's not relevant
const [photos, _, albums, id] = path_components
const [photos, __, albums, id] = path_components
if (photos === 'photos' && albums === 'albums') {
// this at least has the shape of a valid photo-album URL!
return {
@@ -417,7 +417,7 @@ export function parseEmbedPlayerFromUrl(
// link shortened flickr path
if (urlp.hostname === 'flic.kr') {
const b58alph = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
let [_, type, idBase58Enc] = urlp.pathname.split('/')
let [__, type, idBase58Enc] = urlp.pathname.split('/')
let id = 0n
for (const char of idBase58Enc) {
const nextIdx = b58alph.indexOf(char)
@@ -528,7 +528,7 @@ export function parseTenorGif(urlp: URL):
return {success: false}
}
let [_, id, filename] = urlp.pathname.split('/')
let [__, id, filename] = urlp.pathname.split('/')
if (!id || !filename) {
return {success: false}
-17
View File
@@ -62,23 +62,6 @@ export function useWarnMaxGraphemeCount({
}, [splitter, maxCount, text])
}
// https://stackoverflow.com/a/52171480
export function toHashCode(str: string, seed = 0): number {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i)
h1 = Math.imul(h1 ^ ch, 2654435761)
h2 = Math.imul(h2 ^ ch, 1597334677)
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507)
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909)
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507)
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909)
return 4294967296 * (2097151 & h2) + (h1 >>> 0)
}
export function countLines(str: string | undefined): number {
if (!str) return 0
return str.match(/\n/g)?.length ?? 0
+1 -1
View File
@@ -46,7 +46,7 @@ export function parseStarterPackUri(uri?: string): {
} else {
const url = new URL(uri)
const parts = url.pathname.split('/')
const [_, path, name, rkey] = parts
const [__, path, name, rkey] = parts
if (parts.length !== 4) return null
if (path !== 'starter-pack' && path !== 'start') return null
-2
View File
@@ -69,7 +69,6 @@ import {Text} from '#/components/Typography'
import * as bsky from '#/types/bsky'
export function StepFinished() {
const {_} = useLingui()
const {state, dispatch} = useContext(Context)
const onboardDispatch = useOnboardingDispatch()
const [saving, setSaving] = useState(false)
@@ -495,7 +494,6 @@ function ValueProposition({
function Dot({active}: {active: boolean}) {
const t = useTheme()
const {_} = useLingui()
return (
<View
-1
View File
@@ -428,7 +428,6 @@ let SearchScreenInner = ({
const {hasSession} = useSession()
const {gtTablet} = useBreakpoints()
const [activeTab, setActiveTab] = useState(0)
const {_} = useLingui()
const onPageSelected = useCallback(
(index: number) => {
@@ -31,7 +31,6 @@ const FEED_PARAMS: {
}
export function ExploreTrendingVideos() {
const {_} = useLingui()
const gutters = useGutters([0, 'base'])
const {data, isLoading, error} = usePostFeedQuery(FEED_DESC, FEED_PARAMS)
+5 -5
View File
@@ -492,23 +492,23 @@ function createApi({
}
}
} else if (feedDesc.startsWith('author')) {
const [_, actor, filter] = feedDesc.split('|')
const [__, actor, filter] = feedDesc.split('|')
return new AuthorFeedAPI({agent, feedParams: {actor, filter}})
} else if (feedDesc.startsWith('likes')) {
const [_, actor] = feedDesc.split('|')
const [__, actor] = feedDesc.split('|')
return new LikesFeedAPI({agent, feedParams: {actor}})
} else if (feedDesc.startsWith('feedgen')) {
const [_, feed] = feedDesc.split('|')
const [__, feed] = feedDesc.split('|')
return new CustomFeedAPI({
agent,
feedParams: {feed},
userInterests,
})
} else if (feedDesc.startsWith('list')) {
const [_, list] = feedDesc.split('|')
const [__, list] = feedDesc.split('|')
return new ListFeedAPI({agent, feedParams: {list}})
} else if (feedDesc.startsWith('posts')) {
const [_, uriList] = feedDesc.split('|')
const [__, uriList] = feedDesc.split('|')
return new PostListFeedAPI({agent, feedParams: {uris: uriList.split(',')}})
} else if (feedDesc === 'demo') {
return new DemoFeedAPI({agent})
@@ -69,7 +69,7 @@ export function* findAllProfilesInQueryData(
queryClient.getQueriesData<AppBskyUnspeccedGetSuggestedUsers.OutputSchema>({
queryKey: [getSuggestedUsersQueryKeyRoot],
})
for (const [_, response] of responses) {
for (const [_key, response] of responses) {
if (!response) {
continue
}
@@ -116,7 +116,6 @@ function EditImageInner({
}) {
const t = useTheme()
const [isDragging, setIsDragging] = useState(false)
const {_} = useLingui()
const control = Dialog.useDialogContext()
const source = image.source
@@ -30,7 +30,7 @@ function getDecorations(doc: ProsemirrorNode) {
let match
while ((match = regex.exec(textContent))) {
const [matchedString, _, tag] = match
const [matchedString, __, tag] = match
if (!tag || tag.replace(TRAILING_PUNCTUATION_REGEX, '').length > 64)
continue
+1 -1
View File
@@ -126,7 +126,7 @@ function FeedgenErrorMessage({
})[knownError],
[_l, knownError],
)
const [_, uri] = feedDesc.split('|')
const [__, uri] = feedDesc.split('|')
const [ownerDid] = safeParseFeedgenUri(uri)
const removePromptControl = Prompt.usePromptControl()
const {mutateAsync: removeFeed} = useRemoveFeedMutation()
@@ -2,7 +2,6 @@ import {useCallback, useMemo, useState} from 'react'
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {type AppBskyActorDefs as ActorDefs} from '@atproto/api'
import {Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useFocusEffect} from '@react-navigation/native'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
@@ -27,7 +26,6 @@ type Props = NativeStackScreenProps<
export function ModerationMutedAccounts({}: Props) {
const t = useTheme()
const moderationOpts = useModerationOpts()
const {_} = useLingui()
const setMinimalShellMode = useSetMinimalShellMode()
const [isPTRing, setIsPTRing] = useState(false)
-2
View File
@@ -1,6 +1,5 @@
import {useCallback} from 'react'
import {Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useFocusEffect} from '@react-navigation/native'
import {
@@ -17,7 +16,6 @@ export const ProfileFeedLikedByScreen = ({route}: Props) => {
const setMinimalShellMode = useSetMinimalShellMode()
const {name, rkey} = route.params
const uri = makeRecordUri(name, 'app.bsky.feed.generator', rkey)
const {_} = useLingui()
useFocusEffect(
useCallback(() => {