···1import assert from 'assert'
2import {
3 Kysely,
4- KyselyPlugin,
5 Migrator,
6- PluginTransformQueryArgs,
7- PluginTransformResultArgs,
8 PostgresDialect,
9- QueryResult,
10- RootOperationNode,
11- UnknownRow,
12} from 'kysely'
13import {default as Pg} from 'pg'
1415import {dbLogger as log} from '../logger.js'
16import {default as migrations} from './migrations/index.js'
17import {DbMigrationProvider} from './migrations/provider.js'
18-import {DbSchema} from './schema.js'
1920export class Database {
21 migrator: Migrator
22 destroyed = false
2324- constructor(public db: Kysely<DbSchema>, public cfg: PgConfig) {
00025 this.migrator = new Migrator({
26 db,
27 migrationTableSchema: cfg.schema,
···1import assert from 'assert'
2import {
3 Kysely,
4+ type KyselyPlugin,
5 Migrator,
6+ type PluginTransformQueryArgs,
7+ type PluginTransformResultArgs,
8 PostgresDialect,
9+ type QueryResult,
10+ type RootOperationNode,
11+ type UnknownRow,
12} from 'kysely'
13import {default as Pg} from 'pg'
1415import {dbLogger as log} from '../logger.js'
16import {default as migrations} from './migrations/index.js'
17import {DbMigrationProvider} from './migrations/provider.js'
18+import {type DbSchema} from './schema.js'
1920export class Database {
21 migrator: Migrator
22 destroyed = false
2324+ constructor(
25+ public db: Kysely<DbSchema>,
26+ public cfg: PgConfig,
27+ ) {
28 this.migrator = new Migrator({
29 db,
30 migrationTableSchema: cfg.schema,
+7-4
bskylink/src/index.ts
···1import events from 'node:events'
2-import http from 'node:http'
34import cors from 'cors'
5import express from 'express'
6-import {createHttpTerminator, HttpTerminator} from 'http-terminator'
78-import {Config} from './config.js'
9import {AppContext} from './context.js'
10import {default as routes, errorHandler} from './routes/index.js'
11···17 public server?: http.Server
18 private terminator?: HttpTerminator
1920- constructor(public app: express.Application, public ctx: AppContext) {}
0002122 static async create(cfg: Config): Promise<LinkService> {
23 let app = express()
···1import events from 'node:events'
2+import type http from 'node:http'
34import cors from 'cors'
5import express from 'express'
6+import {createHttpTerminator, type HttpTerminator} from 'http-terminator'
78+import {type Config} from './config.js'
9import {AppContext} from './context.js'
10import {default as routes, errorHandler} from './routes/index.js'
11···17 public server?: http.Server
18 private terminator?: HttpTerminator
1920+ constructor(
21+ public app: express.Application,
22+ public ctx: AppContext,
23+ ) {}
2425 static async create(cfg: Config): Promise<LinkService> {
26 let app = express()
+7-4
bskyogcard/src/index.ts
···1import events from 'node:events'
2-import http from 'node:http'
34import express from 'express'
5-import {createHttpTerminator, HttpTerminator} from 'http-terminator'
67-import {Config} from './config.js'
8import {AppContext} from './context.js'
9import {default as routes, errorHandler} from './routes/index.js'
10···15 public server?: http.Server
16 private terminator?: HttpTerminator
1718- constructor(public app: express.Application, public ctx: AppContext) {}
0001920 static async create(cfg: Config): Promise<CardService> {
21 let app = express()
···1import events from 'node:events'
2+import type http from 'node:http'
34import express from 'express'
5+import {createHttpTerminator, type HttpTerminator} from 'http-terminator'
67+import {type Config} from './config.js'
8import {AppContext} from './context.js'
9import {default as routes, errorHandler} from './routes/index.js'
10···15 public server?: http.Server
16 private terminator?: HttpTerminator
1718+ constructor(
19+ public app: express.Application,
20+ public ctx: AppContext,
21+ ) {}
2223 static async create(cfg: Config): Promise<CardService> {
24 let app = express()
···1import React from 'react'
2-import {StyleProp, View, ViewStyle} from 'react-native'
3-import {ModerationUI} from '@atproto/api'
4import {msg, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6···148 modui.noOverride
149 ? _(msg`Learn more about the moderation applied to this content`)
150 : override
151- ? _(msg`Hides the content`)
152- : _(msg`Shows the content`)
153 }>
154 {state => (
155 <View
···1import React from 'react'
2+import {type StyleProp, View, type ViewStyle} from 'react-native'
3+import {type ModerationUI} from '@atproto/api'
4import {msg, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6···148 modui.noOverride
149 ? _(msg`Learn more about the moderation applied to this content`)
150 : override
151+ ? _(msg`Hides the content`)
152+ : _(msg`Shows the content`)
153 }>
154 {state => (
155 <View
···1import React from 'react'
2import {
3 BSKY_LABELER_DID,
4- ModerationCause,
5- ModerationCauseSource,
6} from '@atproto/api'
7import {msg} from '@lingui/macro'
8import {useLingui} from '@lingui/react'
···12import {useSession} from '#/state/session'
13import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
14import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
15-import {Props as SVGIconProps} from '#/components/icons/common'
16import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
17import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
18-import {AppModerationCause} from '#/components/Pills'
19import {useGlobalLabelStrings} from './useGlobalLabelStrings'
20import {getDefinition, getLabelStrings} from './useLabelInfo'
21···153 def.identifier === '!no-unauthenticated'
154 ? EyeSlash
155 : def.severity === 'alert'
156- ? Warning
157- : CircleInfo,
158 name: strings.name,
159 description: strings.description,
160 source,
···1import React from 'react'
2import {
3 BSKY_LABELER_DID,
4+ type ModerationCause,
5+ type ModerationCauseSource,
6} from '@atproto/api'
7import {msg} from '@lingui/macro'
8import {useLingui} from '@lingui/react'
···12import {useSession} from '#/state/session'
13import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
14import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
15+import {type Props as SVGIconProps} from '#/components/icons/common'
16import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
17import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning'
18+import {type AppModerationCause} from '#/components/Pills'
19import {useGlobalLabelStrings} from './useGlobalLabelStrings'
20import {getDefinition, getLabelStrings} from './useLabelInfo'
21···153 def.identifier === '!no-unauthenticated'
154 ? EyeSlash
155 : def.severity === 'alert'
156+ ? Warning
157+ : CircleInfo,
158 name: strings.name,
159 description: strings.description,
160 source,
+5-5
src/lib/statsig/statsig.tsx
···1import React from 'react'
2import {Platform} from 'react-native'
3-import {AppState, AppStateStatus} from 'react-native'
4import {Statsig, StatsigProvider} from 'statsig-react-native-expo'
56import {BUNDLE_DATE, BUNDLE_IDENTIFIER, IS_TESTFLIGHT} from '#/lib/app-info'
7import {logger} from '#/logger'
8-import {MetricEvents} from '#/logger/metrics'
9import {isWeb} from '#/platform/detection'
10import * as persisted from '#/state/persisted'
11import {useSession} from '../../state/session'
12import {timeout} from '../async/timeout'
13import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
14-import {Gate} from './gates'
1516const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'
17···51 process.env.NODE_ENV === 'development'
52 ? 'development'
53 : IS_TESTFLIGHT
54- ? 'staging'
55- : 'production',
56 },
57 // Don't block on waiting for network. The fetched config will kick in on next load.
58 // This ensures the UI is always consistent and doesn't update mid-session.
···1import React from 'react'
2import {Platform} from 'react-native'
3+import {AppState, type AppStateStatus} from 'react-native'
4import {Statsig, StatsigProvider} from 'statsig-react-native-expo'
56import {BUNDLE_DATE, BUNDLE_IDENTIFIER, IS_TESTFLIGHT} from '#/lib/app-info'
7import {logger} from '#/logger'
8+import {type MetricEvents} from '#/logger/metrics'
9import {isWeb} from '#/platform/detection'
10import * as persisted from '#/state/persisted'
11import {useSession} from '../../state/session'
12import {timeout} from '../async/timeout'
13import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
14+import {type Gate} from './gates'
1516const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'
17···51 process.env.NODE_ENV === 'development'
52 ? 'development'
53 : IS_TESTFLIGHT
54+ ? 'staging'
55+ : 'production',
56 },
57 // Don't block on waiting for network. The fetched config will kick in on next load.
58 // This ensures the UI is always consistent and doesn't update mid-session.
···1import {useCallback, useEffect, useState} from 'react'
2import {MMKV} from 'react-native-mmkv'
34-import {Account, Device} from '#/storage/schema'
56export * from '#/storage/schema'
7···83 }
84}
8586-type StorageSchema<T extends Storage<any, any>> = T extends Storage<
87- any,
88- infer U
89->
90- ? U
91- : never
92-type StorageScopes<T extends Storage<any, any>> = T extends Storage<
93- infer S,
94- any
95->
96- ? S
97- : never
9899/**
100 * Hook to use a storage instance. Acts like a useState hook, but persists the
···1import {useCallback, useEffect, useState} from 'react'
2import {MMKV} from 'react-native-mmkv'
34+import {type Account, type Device} from '#/storage/schema'
56export * from '#/storage/schema'
7···83 }
84}
8586+type StorageSchema<T extends Storage<any, any>> =
87+ T extends Storage<any, infer U> ? U : never
88+type StorageScopes<T extends Storage<any, any>> =
89+ T extends Storage<infer S, any> ? S : never
000000009091/**
92 * Hook to use a storage instance. Acts like a useState hook, but persists the
···1import React, {useCallback, useEffect, useState} from 'react'
2import {
3 Image,
4- ImageStyle,
5 Pressable,
6 StyleSheet,
7 TouchableOpacity,
8 TouchableWithoutFeedback,
9 View,
10- ViewStyle,
11} from 'react-native'
12import {
13 FontAwesomeIcon,
14- FontAwesomeIconStyle,
15} from '@fortawesome/react-native-fontawesome'
16import {msg} from '@lingui/macro'
17import {useLingui} from '@lingui/react'
···21import {colors, s} from '#/lib/styles'
22import {useLightbox, useLightboxControls} from '#/state/lightbox'
23import {Text} from '../util/text/Text'
24-import {ImageSource} from './ImageViewing/@types'
25import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
2627export function Lightbox() {
···121 img.type === 'circle-avi'
122 ? '50%'
123 : img.type === 'rect-avi'
124- ? '10%'
125- : 0,
126 } as ImageStyle
127 }
128 alt={img.alt}
···1import React, {useCallback, useEffect, useState} from 'react'
2import {
3 Image,
4+ type ImageStyle,
5 Pressable,
6 StyleSheet,
7 TouchableOpacity,
8 TouchableWithoutFeedback,
9 View,
10+ type ViewStyle,
11} from 'react-native'
12import {
13 FontAwesomeIcon,
14+ type FontAwesomeIconStyle,
15} from '@fortawesome/react-native-fontawesome'
16import {msg} from '@lingui/macro'
17import {useLingui} from '@lingui/react'
···21import {colors, s} from '#/lib/styles'
22import {useLightbox, useLightboxControls} from '#/state/lightbox'
23import {Text} from '../util/text/Text'
24+import {type ImageSource} from './ImageViewing/@types'
25import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
2627export function Lightbox() {
···121 img.type === 'circle-avi'
122 ? '50%'
123 : img.type === 'rect-avi'
124+ ? '10%'
125+ : 0,
126 } as ImageStyle
127 }
128 alt={img.alt}
+2-2
src/view/com/post-thread/PostThreadItem.tsx
···630 showChildReplyLine && !isThreadedChild
631 ? 0
632 : isThreadedChildAdjacentBot
633- ? 4
634- : 8,
635 },
636 ]}>
637 {/* If we are in threaded mode, the avatar is rendered in PostMeta */}
···630 showChildReplyLine && !isThreadedChild
631 ? 0
632 : isThreadedChildAdjacentBot
633+ ? 4
634+ : 8,
635 },
636 ]}>
637 {/* If we are in threaded mode, the avatar is rendered in PostMeta */}
···1import React from 'react'
2import {View} from 'react-native'
3-import {AppBskyActorDefs, AppBskyFeedGetAuthorFeed, AtUri} from '@atproto/api'
00004import {msg as msgLingui, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6import {useNavigation} from '@react-navigation/native'
78import {usePalette} from '#/lib/hooks/usePalette'
9-import {NavigationProp} from '#/lib/routes/types'
10import {cleanError} from '#/lib/strings/errors'
11import {logger} from '#/logger'
12-import {FeedDescriptor} from '#/state/queries/post-feed'
13import {useRemoveFeedMutation} from '#/state/queries/preferences'
14import * as Prompt from '#/components/Prompt'
15import {EmptyState} from '../util/EmptyState'
···119 [KnownError.FeedTooManyRequests]: _l(
120 msgLingui`This feed is currently receiving high traffic and is temporarily unavailable. Please try again later.`,
121 ),
122- }[knownError]),
123 [_l, knownError],
124 )
125 const [_, uri] = feedDesc.split('|')
···1import React from 'react'
2import {View} from 'react-native'
3+import {
4+ type AppBskyActorDefs,
5+ AppBskyFeedGetAuthorFeed,
6+ AtUri,
7+} from '@atproto/api'
8import {msg as msgLingui, Trans} from '@lingui/macro'
9import {useLingui} from '@lingui/react'
10import {useNavigation} from '@react-navigation/native'
1112import {usePalette} from '#/lib/hooks/usePalette'
13+import {type NavigationProp} from '#/lib/routes/types'
14import {cleanError} from '#/lib/strings/errors'
15import {logger} from '#/logger'
16+import {type FeedDescriptor} from '#/state/queries/post-feed'
17import {useRemoveFeedMutation} from '#/state/queries/preferences'
18import * as Prompt from '#/components/Prompt'
19import {EmptyState} from '../util/EmptyState'
···123 [KnownError.FeedTooManyRequests]: _l(
124 msgLingui`This feed is currently receiving high traffic and is temporarily unavailable. Please try again later.`,
125 ),
126+ })[knownError],
127 [_l, knownError],
128 )
129 const [_, uri] = feedDesc.split('|')
+6-6
src/view/com/profile/ProfileMenu.tsx
···461 msg`The account will be able to interact with you after unblocking.`,
462 )
463 : profile.associated?.labeler
464- ? _(
465- msg`Blocking will not prevent labels from being applied on your account, but it will stop this account from replying in your threads or interacting with you.`,
466- )
467- : _(
468- msg`Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
469- )
470 }
471 onConfirm={blockAccount}
472 confirmButtonCta={
···461 msg`The account will be able to interact with you after unblocking.`,
462 )
463 : profile.associated?.labeler
464+ ? _(
465+ msg`Blocking will not prevent labels from being applied on your account, but it will stop this account from replying in your threads or interacting with you.`,
466+ )
467+ : _(
468+ msg`Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you.`,
469+ )
470 }
471 onConfirm={blockAccount}
472 confirmButtonCta={
+8-3
src/view/com/util/List.web.tsx
···1import React, {isValidElement, memo, startTransition, useRef} from 'react'
2-import {FlatListProps, StyleSheet, View, ViewProps} from 'react-native'
3-import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes'
0000045import {batchedUpdates} from '#/lib/batchedUpdates'
6import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
···205 behavior: animated ? 'smooth' : 'instant',
206 })
207 },
208- } as any), // TODO: Better types.
209 [getScrollableNode],
210 )
211
···1import React, {isValidElement, memo, startTransition, useRef} from 'react'
2+import {
3+ type FlatListProps,
4+ StyleSheet,
5+ View,
6+ type ViewProps,
7+} from 'react-native'
8+import {type ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes'
910import {batchedUpdates} from '#/lib/batchedUpdates'
11import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
···210 behavior: animated ? 'smooth' : 'instant',
211 })
212 },
213+ }) as any, // TODO: Better types.
214 [getScrollableNode],
215 )
216