Merge pull request #1814 from bluesky-social/eric/replace-logger

Remove old logger
zio/stable
Eric Bailey 2023-11-04 14:00:38 -05:00 committed by GitHub
commit 95b5e642dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 301 additions and 345 deletions

View File

@ -10,6 +10,7 @@ import {RootStoreModel, AppInfo} from 'state/models/root-store'
import {useStores} from 'state/models/root-store' import {useStores} from 'state/models/root-store'
import {sha256} from 'js-sha256' import {sha256} from 'js-sha256'
import {ScreenEvent, TrackEvent} from './types' import {ScreenEvent, TrackEvent} from './types'
import {logger} from '#/logger'
const segmentClient = createClient({ const segmentClient = createClient({
writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI', writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI',
@ -54,9 +55,9 @@ export function init(store: RootStoreModel) {
if (sess.did) { if (sess.did) {
const did_hashed = sha256(sess.did) const did_hashed = sha256(sess.did)
segmentClient.identify(did_hashed, {did_hashed}) segmentClient.identify(did_hashed, {did_hashed})
store.log.debug('Ping w/hash') logger.debug('Ping w/hash')
} else { } else {
store.log.debug('Ping w/o hash') logger.debug('Ping w/o hash')
segmentClient.identify() segmentClient.identify()
} }
} }
@ -68,19 +69,19 @@ export function init(store: RootStoreModel) {
// -prf // -prf
segmentClient.isReady.onChange(() => { segmentClient.isReady.onChange(() => {
if (AppState.currentState !== 'active') { if (AppState.currentState !== 'active') {
store.log.debug('Prevented a metrics ping while the app was backgrounded') logger.debug('Prevented a metrics ping while the app was backgrounded')
return return
} }
const context = segmentClient.context.get() const context = segmentClient.context.get()
if (typeof context?.app === 'undefined') { if (typeof context?.app === 'undefined') {
store.log.debug('Aborted metrics ping due to unavailable context') logger.debug('Aborted metrics ping due to unavailable context')
return return
} }
const oldAppInfo = store.appInfo const oldAppInfo = store.appInfo
const newAppInfo = context.app as AppInfo const newAppInfo = context.app as AppInfo
store.setAppInfo(newAppInfo) store.setAppInfo(newAppInfo)
store.log.debug('Recording app info', {new: newAppInfo, old: oldAppInfo}) logger.debug('Recording app info', {new: newAppInfo, old: oldAppInfo})
if (typeof oldAppInfo === 'undefined') { if (typeof oldAppInfo === 'undefined') {
if (store.session.hasSession) { if (store.session.hasSession) {

View File

@ -7,6 +7,7 @@ import {
import {RootStoreModel} from 'state/models/root-store' import {RootStoreModel} from 'state/models/root-store'
import {useStores} from 'state/models/root-store' import {useStores} from 'state/models/root-store'
import {sha256} from 'js-sha256' import {sha256} from 'js-sha256'
import {logger} from '#/logger'
const segmentClient = createClient( const segmentClient = createClient(
{ {
@ -49,9 +50,9 @@ export function init(store: RootStoreModel) {
if (sess.did) { if (sess.did) {
const did_hashed = sha256(sess.did) const did_hashed = sha256(sess.did)
segmentClient.identify(did_hashed, {did_hashed}) segmentClient.identify(did_hashed, {did_hashed})
store.log.debug('Ping w/hash') logger.debug('Ping w/hash')
} else { } else {
store.log.debug('Ping w/o hash') logger.debug('Ping w/o hash')
segmentClient.identify() segmentClient.identify()
} }
} }

View File

@ -15,6 +15,7 @@ import {LinkMeta} from '../link-meta/link-meta'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {ImageModel} from 'state/models/media/image' import {ImageModel} from 'state/models/media/image'
import {shortenLinks} from 'lib/strings/rich-text-manip' import {shortenLinks} from 'lib/strings/rich-text-manip'
import {logger} from '#/logger'
export interface ExternalEmbedDraft { export interface ExternalEmbedDraft {
uri: string uri: string
@ -178,7 +179,7 @@ export async function post(store: RootStoreModel, opts: PostOpts) {
) { ) {
encoding = 'image/jpeg' encoding = 'image/jpeg'
} else { } else {
store.log.warn('Unexpected image format for thumbnail, skipping', { logger.warn('Unexpected image format for thumbnail, skipping', {
thumbnail: opts.extLink.localThumb.path, thumbnail: opts.extLink.localThumb.path,
}) })
} }

View File

@ -2,6 +2,7 @@ import React from 'react'
import {AppBskyActorDefs} from '@atproto/api' import {AppBskyActorDefs} from '@atproto/api'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {FollowState} from 'state/models/cache/my-follows' import {FollowState} from 'state/models/cache/my-follows'
import {logger} from '#/logger'
export function useFollowProfile(profile: AppBskyActorDefs.ProfileViewBasic) { export function useFollowProfile(profile: AppBskyActorDefs.ProfileViewBasic) {
const store = useStores() const store = useStores()
@ -22,7 +23,7 @@ export function useFollowProfile(profile: AppBskyActorDefs.ProfileViewBasic) {
following: false, following: false,
} }
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to delete follow', {error: e}) logger.error('Failed to delete follow', {error: e})
throw e throw e
} }
} else if (state === FollowState.NotFollowing) { } else if (state === FollowState.NotFollowing) {
@ -40,7 +41,7 @@ export function useFollowProfile(profile: AppBskyActorDefs.ProfileViewBasic) {
following: true, following: true,
} }
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to create follow', {error: e}) logger.error('Failed to create follow', {error: e})
throw e throw e
} }
} }

View File

@ -2,6 +2,7 @@ import * as Updates from 'expo-updates'
import {useCallback, useEffect} from 'react' import {useCallback, useEffect} from 'react'
import {AppState} from 'react-native' import {AppState} from 'react-native'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {logger} from '#/logger'
export function useOTAUpdate() { export function useOTAUpdate() {
const store = useStores() const store = useStores()
@ -21,7 +22,7 @@ export function useOTAUpdate() {
}) })
}, [store.shell]) }, [store.shell])
const checkForUpdate = useCallback(async () => { const checkForUpdate = useCallback(async () => {
store.log.debug('useOTAUpdate: Checking for update...') logger.debug('useOTAUpdate: Checking for update...')
try { try {
// Check if new OTA update is available // Check if new OTA update is available
const update = await Updates.checkForUpdateAsync() const update = await Updates.checkForUpdateAsync()
@ -34,16 +35,16 @@ export function useOTAUpdate() {
// show a popup modal // show a popup modal
showUpdatePopup() showUpdatePopup()
} catch (e) { } catch (e) {
store.log.error('useOTAUpdate: Error while checking for update', { logger.error('useOTAUpdate: Error while checking for update', {
error: e, error: e,
}) })
} }
}, [showUpdatePopup, store.log]) }, [showUpdatePopup])
const updateEventListener = useCallback( const updateEventListener = useCallback(
(event: Updates.UpdateEvent) => { (event: Updates.UpdateEvent) => {
store.log.debug('useOTAUpdate: Listening for update...') logger.debug('useOTAUpdate: Listening for update...')
if (event.type === Updates.UpdateEventType.ERROR) { if (event.type === Updates.UpdateEventType.ERROR) {
store.log.error('useOTAUpdate: Error while listening for update', { logger.error('useOTAUpdate: Error while listening for update', {
message: event.message, message: event.message,
}) })
} else if (event.type === Updates.UpdateEventType.NO_UPDATE_AVAILABLE) { } else if (event.type === Updates.UpdateEventType.NO_UPDATE_AVAILABLE) {
@ -55,7 +56,7 @@ export function useOTAUpdate() {
showUpdatePopup() showUpdatePopup()
} }
}, },
[showUpdatePopup, store.log], [showUpdatePopup],
) )
useEffect(() => { useEffect(() => {

View File

@ -3,6 +3,7 @@ import {RootStoreModel} from '../../state'
import {resetToTab} from '../../Navigation' import {resetToTab} from '../../Navigation'
import {devicePlatform, isIOS} from 'platform/detection' import {devicePlatform, isIOS} from 'platform/detection'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
const SERVICE_DID = (serviceUrl?: string) => const SERVICE_DID = (serviceUrl?: string) =>
serviceUrl?.includes('staging') serviceUrl?.includes('staging')
@ -29,19 +30,27 @@ export function init(store: RootStoreModel) {
token: token.data, token: token.data,
appId: 'xyz.blueskyweb.app', appId: 'xyz.blueskyweb.app',
}) })
store.log.debug('Notifications: Sent push token (init)', { logger.debug(
tokenType: token.type, 'Notifications: Sent push token (init)',
token: token.data, {
}) tokenType: token.type,
token: token.data,
},
logger.DebugContext.notifications,
)
} catch (error) { } catch (error) {
store.log.error('Notifications: Failed to set push token', {error}) logger.error('Notifications: Failed to set push token', {error})
} }
} }
// listens for new changes to the push token // listens for new changes to the push token
// In rare situations, a push token may be changed by the push notification service while the app is running. When a token is rolled, the old one becomes invalid and sending notifications to it will fail. A push token listener will let you handle this situation gracefully by registering the new token with your backend right away. // In rare situations, a push token may be changed by the push notification service while the app is running. When a token is rolled, the old one becomes invalid and sending notifications to it will fail. A push token listener will let you handle this situation gracefully by registering the new token with your backend right away.
Notifications.addPushTokenListener(async ({data: t, type}) => { Notifications.addPushTokenListener(async ({data: t, type}) => {
store.log.debug('Notifications: Push token changed', {t, tokenType: type}) logger.debug(
'Notifications: Push token changed',
{t, tokenType: type},
logger.DebugContext.notifications,
)
if (t) { if (t) {
try { try {
await store.agent.api.app.bsky.notification.registerPush({ await store.agent.api.app.bsky.notification.registerPush({
@ -50,12 +59,16 @@ export function init(store: RootStoreModel) {
token: t, token: t,
appId: 'xyz.blueskyweb.app', appId: 'xyz.blueskyweb.app',
}) })
store.log.debug('Notifications: Sent push token (event)', { logger.debug(
tokenType: type, 'Notifications: Sent push token (event)',
token: t, {
}) tokenType: type,
token: t,
},
logger.DebugContext.notifications,
)
} catch (error) { } catch (error) {
store.log.error('Notifications: Failed to set push token', {error}) logger.error('Notifications: Failed to set push token', {error})
} }
} }
}) })
@ -63,7 +76,11 @@ export function init(store: RootStoreModel) {
// handle notifications that are received, both in the foreground or background // handle notifications that are received, both in the foreground or background
Notifications.addNotificationReceivedListener(event => { Notifications.addNotificationReceivedListener(event => {
store.log.debug('Notifications: received', {event}) logger.debug(
'Notifications: received',
{event},
logger.DebugContext.notifications,
)
if (event.request.trigger.type === 'push') { if (event.request.trigger.type === 'push') {
// refresh notifications in the background // refresh notifications in the background
store.me.notifications.syncQueue() store.me.notifications.syncQueue()
@ -75,7 +92,11 @@ export function init(store: RootStoreModel) {
// TODO: handle android payload deeplink // TODO: handle android payload deeplink
} }
if (payload) { if (payload) {
store.log.debug('Notifications: received payload', payload) logger.debug(
'Notifications: received payload',
payload,
logger.DebugContext.notifications,
)
// TODO: deeplink notif here // TODO: deeplink notif here
} }
} }
@ -84,14 +105,20 @@ export function init(store: RootStoreModel) {
// handle notifications that are tapped on // handle notifications that are tapped on
const sub = Notifications.addNotificationResponseReceivedListener( const sub = Notifications.addNotificationResponseReceivedListener(
response => { response => {
store.log.debug('Notifications: response received', { logger.debug(
actionIdentifier: response.actionIdentifier, 'Notifications: response received',
}) {
actionIdentifier: response.actionIdentifier,
},
logger.DebugContext.notifications,
)
if ( if (
response.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER response.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER
) { ) {
store.log.debug( logger.debug(
'User pressed a notification, opening notifications tab', 'User pressed a notification, opening notifications tab',
{},
logger.DebugContext.notifications,
) )
track('Notificatons:OpenApp') track('Notificatons:OpenApp')
store.me.notifications.refresh() // refresh notifications store.me.notifications.refresh() // refresh notifications

View File

@ -7,4 +7,6 @@
*/ */
export const DebugContext = { export const DebugContext = {
// e.g. composer: 'composer' // e.g. composer: 'composer'
session: 'session',
notifications: 'notifications',
} as const } as const

View File

@ -4,6 +4,7 @@ import {BskyAgent} from '@atproto/api'
import {RootStoreModel} from './models/root-store' import {RootStoreModel} from './models/root-store'
import * as apiPolyfill from 'lib/api/api-polyfill' import * as apiPolyfill from 'lib/api/api-polyfill'
import * as storage from 'lib/storage' import * as storage from 'lib/storage'
import {logger} from '#/logger'
export const LOCAL_DEV_SERVICE = export const LOCAL_DEV_SERVICE =
Platform.OS === 'android' ? 'http://10.0.2.2:2583' : 'http://localhost:2583' Platform.OS === 'android' ? 'http://10.0.2.2:2583' : 'http://localhost:2583'
@ -22,10 +23,10 @@ export async function setupState(serviceUri = DEFAULT_SERVICE) {
rootStore = new RootStoreModel(new BskyAgent({service: serviceUri})) rootStore = new RootStoreModel(new BskyAgent({service: serviceUri}))
try { try {
data = (await storage.load(ROOT_STATE_STORAGE_KEY)) || {} data = (await storage.load(ROOT_STATE_STORAGE_KEY)) || {}
rootStore.log.debug('Initial hydrate', {hasSession: !!data.session}) logger.debug('Initial hydrate', {hasSession: !!data.session})
rootStore.hydrate(data) rootStore.hydrate(data)
} catch (e: any) { } catch (e: any) {
rootStore.log.error('Failed to load state from storage', {error: e}) logger.error('Failed to load state from storage', {error: e})
} }
rootStore.attemptSessionResumption() rootStore.attemptSessionResumption()

View File

@ -6,6 +6,7 @@ import {sanitizeHandle} from 'lib/strings/handles'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export class FeedSourceModel { export class FeedSourceModel {
// state // state
@ -134,7 +135,7 @@ export class FeedSourceModel {
try { try {
await this.rootStore.preferences.addSavedFeed(this.uri) await this.rootStore.preferences.addSavedFeed(this.uri)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to save feed', {error}) logger.error('Failed to save feed', {error})
} finally { } finally {
track('CustomFeed:Save') track('CustomFeed:Save')
} }
@ -147,7 +148,7 @@ export class FeedSourceModel {
try { try {
await this.rootStore.preferences.removeSavedFeed(this.uri) await this.rootStore.preferences.removeSavedFeed(this.uri)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to unsave feed', {error}) logger.error('Failed to unsave feed', {error})
} finally { } finally {
track('CustomFeed:Unsave') track('CustomFeed:Unsave')
} }
@ -157,7 +158,7 @@ export class FeedSourceModel {
try { try {
await this.rootStore.preferences.addPinnedFeed(this.uri) await this.rootStore.preferences.addPinnedFeed(this.uri)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to pin feed', {error}) logger.error('Failed to pin feed', {error})
} finally { } finally {
track('CustomFeed:Pin', { track('CustomFeed:Pin', {
name: this.displayName, name: this.displayName,
@ -194,7 +195,7 @@ export class FeedSourceModel {
} catch (e: any) { } catch (e: any) {
this.likeUri = undefined this.likeUri = undefined
this.likeCount = (this.likeCount || 1) - 1 this.likeCount = (this.likeCount || 1) - 1
this.rootStore.log.error('Failed to like feed', {error: e}) logger.error('Failed to like feed', {error: e})
} finally { } finally {
track('CustomFeed:Like') track('CustomFeed:Like')
} }
@ -215,7 +216,7 @@ export class FeedSourceModel {
} catch (e: any) { } catch (e: any) {
this.likeUri = uri this.likeUri = uri
this.likeCount = (this.likeCount || 0) + 1 this.likeCount = (this.likeCount || 0) + 1
this.rootStore.log.error('Failed to unlike feed', {error: e}) logger.error('Failed to unlike feed', {error: e})
} finally { } finally {
track('CustomFeed:Unlike') track('CustomFeed:Unlike')
} }

View File

@ -16,6 +16,7 @@ import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {until} from 'lib/async/until' import {until} from 'lib/async/until'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -339,7 +340,7 @@ export class ListModel {
try { try {
await this.rootStore.preferences.addPinnedFeed(this.uri) await this.rootStore.preferences.addPinnedFeed(this.uri)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to pin feed', {error}) logger.error('Failed to pin feed', {error})
} finally { } finally {
track('CustomFeed:Pin', { track('CustomFeed:Pin', {
name: this.data?.name || '', name: this.data?.name || '',
@ -455,10 +456,10 @@ export class ListModel {
this.error = cleanError(err) this.error = cleanError(err)
this.loadMoreError = cleanError(loadMoreErr) this.loadMoreError = cleanError(loadMoreErr)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user items', {error: err}) logger.error('Failed to fetch user items', {error: err})
} }
if (loadMoreErr) { if (loadMoreErr) {
this.rootStore.log.error('Failed to fetch user items', { logger.error('Failed to fetch user items', {
error: loadMoreErr, error: loadMoreErr,
}) })
} }

View File

@ -11,6 +11,7 @@ import * as apilib from 'lib/api/index'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {ThreadViewPreference} from '../ui/preferences' import {ThreadViewPreference} from '../ui/preferences'
import {PostThreadItemModel} from './post-thread-item' import {PostThreadItemModel} from './post-thread-item'
import {logger} from '#/logger'
export class PostThreadModel { export class PostThreadModel {
// state // state
@ -163,7 +164,7 @@ export class PostThreadModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch post thread', {error: err}) logger.error('Failed to fetch post thread', {error: err})
} }
this.notFound = err instanceof GetPostThread.NotFoundError this.notFound = err instanceof GetPostThread.NotFoundError
} }

View File

@ -15,6 +15,7 @@ import {cleanError} from 'lib/strings/errors'
import {FollowState} from '../cache/my-follows' import {FollowState} from '../cache/my-follows'
import {Image as RNImage} from 'react-native-image-crop-picker' import {Image as RNImage} from 'react-native-image-crop-picker'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export class ProfileViewerModel { export class ProfileViewerModel {
muted?: boolean muted?: boolean
@ -235,7 +236,7 @@ export class ProfileModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch profile', {error: err}) logger.error('Failed to fetch profile', {error: err})
} }
} }

View File

@ -4,6 +4,7 @@ import {RootStoreModel} from '../root-store'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source' import {FeedSourceModel} from '../content/feed-source'
import {logger} from '#/logger'
const DEFAULT_LIMIT = 50 const DEFAULT_LIMIT = 50
@ -120,7 +121,7 @@ export class FeedsDiscoveryModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch popular feeds', {error: err}) logger.error('Failed to fetch popular feeds', {error: err})
} }
} }

View File

@ -3,6 +3,7 @@ import {AppBskyActorDefs, moderateProfile} from '@atproto/api'
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -144,7 +145,7 @@ export class SuggestedActorsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch suggested actors', {error: err}) logger.error('Failed to fetch suggested actors', {error: err})
} }
} }
} }

View File

@ -17,6 +17,7 @@ import {bundleAsync} from 'lib/async/bundle'
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {PostThreadModel} from '../content/post-thread' import {PostThreadModel} from '../content/post-thread'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {logger} from '#/logger'
const GROUPABLE_REASONS = ['like', 'repost', 'follow'] const GROUPABLE_REASONS = ['like', 'repost', 'follow']
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -210,7 +211,7 @@ export class NotificationsFeedItemModel {
if (valid.success) { if (valid.success) {
return v return v
} else { } else {
this.rootStore.log.warn('Received an invalid record', { logger.warn('Received an invalid record', {
record: v, record: v,
error: valid.error, error: valid.error,
}) })
@ -218,7 +219,7 @@ export class NotificationsFeedItemModel {
} }
} }
} }
this.rootStore.log.warn( logger.warn(
'app.bsky.notifications.list served an unsupported record type', 'app.bsky.notifications.list served an unsupported record type',
{record: v}, {record: v},
) )
@ -319,7 +320,7 @@ export class NotificationsFeedModel {
* Nuke all data * Nuke all data
*/ */
clear() { clear() {
this.rootStore.log.debug('NotificationsModel:clear') logger.debug('NotificationsModel:clear')
this.isLoading = false this.isLoading = false
this.isRefreshing = false this.isRefreshing = false
this.hasLoaded = false this.hasLoaded = false
@ -336,7 +337,7 @@ export class NotificationsFeedModel {
* Load for first render * Load for first render
*/ */
setup = bundleAsync(async (isRefreshing: boolean = false) => { setup = bundleAsync(async (isRefreshing: boolean = false) => {
this.rootStore.log.debug('NotificationsModel:refresh', {isRefreshing}) logger.debug('NotificationsModel:refresh', {isRefreshing})
await this.lock.acquireAsync() await this.lock.acquireAsync()
try { try {
this._xLoading(isRefreshing) this._xLoading(isRefreshing)
@ -368,7 +369,7 @@ export class NotificationsFeedModel {
* Sync the next set of notifications to show * Sync the next set of notifications to show
*/ */
syncQueue = bundleAsync(async () => { syncQueue = bundleAsync(async () => {
this.rootStore.log.debug('NotificationsModel:syncQueue') logger.debug('NotificationsModel:syncQueue')
if (this.unreadCount >= MAX_VISIBLE_NOTIFS) { if (this.unreadCount >= MAX_VISIBLE_NOTIFS) {
return // no need to check return // no need to check
} }
@ -401,7 +402,7 @@ export class NotificationsFeedModel {
this._setQueued(this._filterNotifications(queueModels)) this._setQueued(this._filterNotifications(queueModels))
this._countUnread() this._countUnread()
} catch (e) { } catch (e) {
this.rootStore.log.error('NotificationsModel:syncQueue failed', { logger.error('NotificationsModel:syncQueue failed', {
error: e, error: e,
}) })
} finally { } finally {
@ -463,10 +464,7 @@ export class NotificationsFeedModel {
} }
} }
await Promise.all(promises).catch(e => { await Promise.all(promises).catch(e => {
this.rootStore.log.error( logger.error('Uncaught failure during notifications update()', e)
'Uncaught failure during notifications update()',
e,
)
}) })
} }
@ -483,7 +481,7 @@ export class NotificationsFeedModel {
this.lastSync ? this.lastSync.toISOString() : undefined, this.lastSync ? this.lastSync.toISOString() : undefined,
) )
} catch (e: any) { } catch (e: any) {
this.rootStore.log.warn('Failed to update notifications read state', { logger.warn('Failed to update notifications read state', {
error: e, error: e,
}) })
} }
@ -505,10 +503,10 @@ export class NotificationsFeedModel {
this.error = cleanError(error) this.error = cleanError(error)
this.loadMoreError = cleanError(loadMoreError) this.loadMoreError = cleanError(loadMoreError)
if (error) { if (error) {
this.rootStore.log.error('Failed to fetch notifications', {error}) logger.error('Failed to fetch notifications', {error})
} }
if (loadMoreError) { if (loadMoreError) {
this.rootStore.log.error('Failed to load more notifications', { logger.error('Failed to load more notifications', {
error: loadMoreError, error: loadMoreError,
}) })
} }

View File

@ -10,6 +10,7 @@ import {RootStoreModel} from '../root-store'
import {updateDataOptimistically} from 'lib/async/revertible' import {updateDataOptimistically} from 'lib/async/revertible'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {hackAddDeletedEmbed} from 'lib/api/hack-add-deleted-embed' import {hackAddDeletedEmbed} from 'lib/api/hack-add-deleted-embed'
import {logger} from '#/logger'
type FeedViewPost = AppBskyFeedDefs.FeedViewPost type FeedViewPost = AppBskyFeedDefs.FeedViewPost
type ReasonRepost = AppBskyFeedDefs.ReasonRepost type ReasonRepost = AppBskyFeedDefs.ReasonRepost
@ -42,14 +43,14 @@ export class PostsFeedItemModel {
} else { } else {
this.postRecord = undefined this.postRecord = undefined
this.richText = undefined this.richText = undefined
rootStore.log.warn('Received an invalid app.bsky.feed.post record', { logger.warn('Received an invalid app.bsky.feed.post record', {
error: valid.error, error: valid.error,
}) })
} }
} else { } else {
this.postRecord = undefined this.postRecord = undefined
this.richText = undefined this.richText = undefined
rootStore.log.warn( logger.warn(
'app.bsky.feed.getTimeline or app.bsky.feed.getAuthorFeed served an unexpected record type', 'app.bsky.feed.getTimeline or app.bsky.feed.getAuthorFeed served an unexpected record type',
{record: this.post.record}, {record: this.post.record},
) )
@ -132,7 +133,7 @@ export class PostsFeedItemModel {
track('Post:Like') track('Post:Like')
} }
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to toggle like', {error}) logger.error('Failed to toggle like', {error})
} }
} }
@ -167,7 +168,7 @@ export class PostsFeedItemModel {
track('Post:Repost') track('Post:Repost')
} }
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to toggle repost', {error}) logger.error('Failed to toggle repost', {error})
} }
} }
@ -181,7 +182,7 @@ export class PostsFeedItemModel {
track('Post:ThreadMute') track('Post:ThreadMute')
} }
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to toggle thread mute', {error}) logger.error('Failed to toggle thread mute', {error})
} }
} }
@ -190,7 +191,7 @@ export class PostsFeedItemModel {
await this.rootStore.agent.deletePost(this.post.uri) await this.rootStore.agent.deletePost(this.post.uri)
this.rootStore.emitPostDeleted(this.post.uri) this.rootStore.emitPostDeleted(this.post.uri)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to delete post', {error}) logger.error('Failed to delete post', {error})
} finally { } finally {
track('Post:Delete') track('Post:Delete')
} }

View File

@ -22,6 +22,7 @@ import {LikesFeedAPI} from 'lib/api/feed/likes'
import {CustomFeedAPI} from 'lib/api/feed/custom' import {CustomFeedAPI} from 'lib/api/feed/custom'
import {ListFeedAPI} from 'lib/api/feed/list' import {ListFeedAPI} from 'lib/api/feed/list'
import {MergeFeedAPI} from 'lib/api/feed/merge' import {MergeFeedAPI} from 'lib/api/feed/merge'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -161,7 +162,7 @@ export class PostsFeedModel {
* Nuke all data * Nuke all data
*/ */
clear() { clear() {
this.rootStore.log.debug('FeedModel:clear') logger.debug('FeedModel:clear')
this.isLoading = false this.isLoading = false
this.isRefreshing = false this.isRefreshing = false
this.hasNewLatest = false this.hasNewLatest = false
@ -177,7 +178,7 @@ export class PostsFeedModel {
* Load for first render * Load for first render
*/ */
setup = bundleAsync(async (isRefreshing: boolean = false) => { setup = bundleAsync(async (isRefreshing: boolean = false) => {
this.rootStore.log.debug('FeedModel:setup', {isRefreshing}) logger.debug('FeedModel:setup', {isRefreshing})
if (isRefreshing) { if (isRefreshing) {
this.isRefreshing = true // set optimistically for UI this.isRefreshing = true // set optimistically for UI
} }
@ -324,10 +325,10 @@ export class PostsFeedModel {
this.knownError = detectKnownError(this.feedType, error) this.knownError = detectKnownError(this.feedType, error)
this.loadMoreError = cleanError(loadMoreError) this.loadMoreError = cleanError(loadMoreError)
if (error) { if (error) {
this.rootStore.log.error('Posts feed request failed', {error}) logger.error('Posts feed request failed', {error})
} }
if (loadMoreError) { if (loadMoreError) {
this.rootStore.log.error('Posts feed load-more request failed', { logger.error('Posts feed load-more request failed', {
error: loadMoreError, error: loadMoreError,
}) })
} }

View File

@ -2,6 +2,7 @@ import {makeAutoObservable, runInAction} from 'mobx'
import {ComAtprotoServerDefs, AppBskyActorDefs} from '@atproto/api' import {ComAtprotoServerDefs, AppBskyActorDefs} from '@atproto/api'
import {RootStoreModel} from './root-store' import {RootStoreModel} from './root-store'
import {isObj, hasProp, isStrArray} from 'lib/type-guards' import {isObj, hasProp, isStrArray} from 'lib/type-guards'
import {logger} from '#/logger'
export class InvitedUsers { export class InvitedUsers {
copiedInvites: string[] = [] copiedInvites: string[] = []
@ -63,7 +64,7 @@ export class InvitedUsers {
}) })
this.rootStore.me.follows.hydrateMany(this.profiles) this.rootStore.me.follows.hydrateMany(this.profiles)
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to fetch profiles for invited users', { logger.error('Failed to fetch profiles for invited users', {
error: e, error: e,
}) })
} }

View File

@ -4,6 +4,7 @@ import {RootStoreModel} from '../root-store'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source' import {FeedSourceModel} from '../content/feed-source'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -98,7 +99,7 @@ export class ActorFeedsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user followers', {error: err}) logger.error('Failed to fetch user followers', {error: err})
} }
} }

View File

@ -6,6 +6,7 @@ import {
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -86,7 +87,7 @@ export class BlockedAccountsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user followers', {error: err}) logger.error('Failed to fetch user followers', {error: err})
} }
} }

View File

@ -5,6 +5,7 @@ import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import * as apilib from 'lib/api/index' import * as apilib from 'lib/api/index'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -97,7 +98,7 @@ export class LikesModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch likes', {error: err}) logger.error('Failed to fetch likes', {error: err})
} }
} }

View File

@ -4,6 +4,7 @@ import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {accumulate} from 'lib/async/accumulate' import {accumulate} from 'lib/async/accumulate'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -204,10 +205,10 @@ export class ListsListModel {
this.error = cleanError(err) this.error = cleanError(err)
this.loadMoreError = cleanError(loadMoreErr) this.loadMoreError = cleanError(loadMoreErr)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user lists', {error: err}) logger.error('Failed to fetch user lists', {error: err})
} }
if (loadMoreErr) { if (loadMoreErr) {
this.rootStore.log.error('Failed to fetch user lists', { logger.error('Failed to fetch user lists', {
error: loadMoreErr, error: loadMoreErr,
}) })
} }

View File

@ -6,6 +6,7 @@ import {
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -86,7 +87,7 @@ export class MutedAccountsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user followers', {error: err}) logger.error('Failed to fetch user followers', {error: err})
} }
} }

View File

@ -8,6 +8,7 @@ import {RootStoreModel} from '../root-store'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import * as apilib from 'lib/api/index' import * as apilib from 'lib/api/index'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -100,7 +101,7 @@ export class RepostedByModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch reposted by view', {error: err}) logger.error('Failed to fetch reposted by view', {error: err})
} }
} }

View File

@ -6,6 +6,7 @@ import {
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -99,7 +100,7 @@ export class UserFollowersModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user followers', {error: err}) logger.error('Failed to fetch user followers', {error: err})
} }
} }

View File

@ -6,6 +6,7 @@ import {
import {RootStoreModel} from '../root-store' import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle' import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
@ -99,7 +100,7 @@ export class UserFollowsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user follows', err) logger.error('Failed to fetch user follows', err)
} }
} }

View File

@ -1,115 +0,0 @@
import {makeAutoObservable} from 'mobx'
// import {XRPCError, XRPCInvalidResponseError} from '@atproto/xrpc' TODO
const MAX_ENTRIES = 300
interface LogEntry {
id: string
type?: string
summary?: string
details?: string
ts?: number
}
let _lastTs: string
let _lastId: string
function genId(): string {
let candidate = String(Date.now())
if (_lastTs === candidate) {
const id = _lastId + 'x'
_lastId = id
return id
}
_lastTs = candidate
_lastId = candidate
return candidate
}
export class LogModel {
entries: LogEntry[] = []
timers = new Map<string, number>()
constructor() {
makeAutoObservable(this)
}
add(entry: LogEntry) {
this.entries.push(entry)
while (this.entries.length > MAX_ENTRIES) {
this.entries = this.entries.slice(50)
}
}
debug(summary: string, details?: any) {
details = detailsToStr(details)
console.debug(summary, details || '')
this.add({
id: genId(),
type: 'debug',
summary,
details,
ts: Date.now(),
})
}
warn(summary: string, details?: any) {
details = detailsToStr(details)
console.debug(summary, details || '')
this.add({
id: genId(),
type: 'warn',
summary,
details,
ts: Date.now(),
})
}
error(summary: string, details?: any) {
details = detailsToStr(details)
console.debug(summary, details || '')
this.add({
id: genId(),
type: 'error',
summary,
details,
ts: Date.now(),
})
}
time = (label = 'default') => {
this.timers.set(label, performance.now())
}
timeEnd = (label = 'default', warn = false) => {
const endTime = performance.now()
if (this.timers.has(label)) {
const elapsedTime = endTime - this.timers.get(label)!
console.log(`${label}: ${elapsedTime.toFixed(3)}ms`)
this.timers.delete(label)
} else {
warn && console.warn(`Timer with label '${label}' does not exist.`)
}
}
}
function detailsToStr(details?: any) {
if (details && typeof details !== 'string') {
if (
// details instanceof XRPCInvalidResponseError || TODO
details.constructor.name === 'XRPCInvalidResponseError'
) {
return `The server gave an ill-formatted response.\nMethod: ${
details.lexiconNsid
}.\nError: ${details.validationError.toString()}`
} else if (
// details instanceof XRPCError || TODO
details.constructor.name === 'XRPCError'
) {
return `An XRPC error occurred.\nStatus: ${details.status}\nError: ${details.error}\nMessage: ${details.message}`
} else if (details instanceof Error) {
return details.toString()
}
return JSON.stringify(details, null, 2)
}
return details
}

View File

@ -9,6 +9,7 @@ import {NotificationsFeedModel} from './feeds/notifications'
import {MyFeedsUIModel} from './ui/my-feeds' import {MyFeedsUIModel} from './ui/my-feeds'
import {MyFollowsCache} from './cache/my-follows' import {MyFollowsCache} from './cache/my-follows'
import {isObj, hasProp} from 'lib/type-guards' import {isObj, hasProp} from 'lib/type-guards'
import {logger} from '#/logger'
const PROFILE_UPDATE_INTERVAL = 10 * 60 * 1e3 // 10min const PROFILE_UPDATE_INTERVAL = 10 * 60 * 1e3 // 10min
const NOTIFS_UPDATE_INTERVAL = 30 * 1e3 // 30sec const NOTIFS_UPDATE_INTERVAL = 30 * 1e3 // 30sec
@ -104,21 +105,21 @@ export class MeModel {
async load() { async load() {
const sess = this.rootStore.session const sess = this.rootStore.session
this.rootStore.log.debug('MeModel:load', {hasSession: sess.hasSession}) logger.debug('MeModel:load', {hasSession: sess.hasSession})
if (sess.hasSession) { if (sess.hasSession) {
this.did = sess.currentSession?.did || '' this.did = sess.currentSession?.did || ''
await this.fetchProfile() await this.fetchProfile()
this.mainFeed.clear() this.mainFeed.clear()
/* dont await */ this.mainFeed.setup().catch(e => { /* dont await */ this.mainFeed.setup().catch(e => {
this.rootStore.log.error('Failed to setup main feed model', {error: e}) logger.error('Failed to setup main feed model', {error: e})
}) })
/* dont await */ this.notifications.setup().catch(e => { /* dont await */ this.notifications.setup().catch(e => {
this.rootStore.log.error('Failed to setup notifications model', { logger.error('Failed to setup notifications model', {
error: e, error: e,
}) })
}) })
/* dont await */ this.notifications.setup().catch(e => { /* dont await */ this.notifications.setup().catch(e => {
this.rootStore.log.error('Failed to setup notifications model', { logger.error('Failed to setup notifications model', {
error: e, error: e,
}) })
}) })
@ -134,7 +135,7 @@ export class MeModel {
async updateIfNeeded() { async updateIfNeeded() {
if (Date.now() - this.lastProfileStateUpdate > PROFILE_UPDATE_INTERVAL) { if (Date.now() - this.lastProfileStateUpdate > PROFILE_UPDATE_INTERVAL) {
this.rootStore.log.debug('Updating me profile information') logger.debug('Updating me profile information')
this.lastProfileStateUpdate = Date.now() this.lastProfileStateUpdate = Date.now()
await this.fetchProfile() await this.fetchProfile()
await this.fetchInviteCodes() await this.fetchInviteCodes()
@ -188,7 +189,7 @@ export class MeModel {
}) })
}) })
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to fetch user invite codes', { logger.error('Failed to fetch user invite codes', {
error: e, error: e,
}) })
} }
@ -205,7 +206,7 @@ export class MeModel {
this.appPasswords = res.data.passwords this.appPasswords = res.data.passwords
}) })
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to fetch user app passwords', { logger.error('Failed to fetch user app passwords', {
error: e, error: e,
}) })
} }
@ -228,7 +229,7 @@ export class MeModel {
}) })
return res.data return res.data
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to create app password', {error: e}) logger.error('Failed to create app password', {error: e})
} }
} }
} }
@ -243,7 +244,7 @@ export class MeModel {
this.appPasswords = this.appPasswords.filter(p => p.name !== name) this.appPasswords = this.appPasswords.filter(p => p.name !== name)
}) })
} catch (e) { } catch (e) {
this.rootStore.log.error('Failed to delete app password', {error: e}) logger.error('Failed to delete app password', {error: e})
} }
} }
} }

View File

@ -9,6 +9,7 @@ import {ActionCrop, FlipType, SaveFormat} from 'expo-image-manipulator'
import {Position} from 'react-avatar-editor' import {Position} from 'react-avatar-editor'
import {Dimensions} from 'lib/media/types' import {Dimensions} from 'lib/media/types'
import {isIOS} from 'platform/detection' import {isIOS} from 'platform/detection'
import {logger} from '#/logger'
export interface ImageManipulationAttributes { export interface ImageManipulationAttributes {
aspectRatio?: '4:3' | '1:1' | '3:4' | 'None' aspectRatio?: '4:3' | '1:1' | '3:4' | 'None'
@ -188,7 +189,7 @@ export class ImageModel implements Omit<RNImage, 'size'> {
this.cropped = cropped this.cropped = cropped
}) })
} catch (err) { } catch (err) {
this.rootStore.log.error('Failed to crop photo', {error: err}) logger.error('Failed to crop photo', {error: err})
} }
} }

View File

@ -41,7 +41,6 @@ export type AppInfo = z.infer<typeof appInfo>
export class RootStoreModel { export class RootStoreModel {
agent: BskyAgent agent: BskyAgent
appInfo?: AppInfo appInfo?: AppInfo
log = logger
session = new SessionModel(this) session = new SessionModel(this)
shell = new ShellUiModel(this) shell = new ShellUiModel(this)
preferences = new PreferencesModel(this) preferences = new PreferencesModel(this)
@ -122,15 +121,15 @@ export class RootStoreModel {
* Called during init to resume any stored session. * Called during init to resume any stored session.
*/ */
async attemptSessionResumption() { async attemptSessionResumption() {
this.log.debug('RootStoreModel:attemptSessionResumption') logger.debug('RootStoreModel:attemptSessionResumption')
try { try {
await this.session.attemptSessionResumption() await this.session.attemptSessionResumption()
this.log.debug('Session initialized', { logger.debug('Session initialized', {
hasSession: this.session.hasSession, hasSession: this.session.hasSession,
}) })
this.updateSessionState() this.updateSessionState()
} catch (e: any) { } catch (e: any) {
this.log.warn('Failed to initialize session', {error: e}) logger.warn('Failed to initialize session', {error: e})
} }
} }
@ -141,7 +140,7 @@ export class RootStoreModel {
agent: BskyAgent, agent: BskyAgent,
{hadSession}: {hadSession: boolean}, {hadSession}: {hadSession: boolean},
) { ) {
this.log.debug('RootStoreModel:handleSessionChange') logger.debug('RootStoreModel:handleSessionChange')
this.agent = agent this.agent = agent
applyDebugHeader(this.agent) applyDebugHeader(this.agent)
this.me.clear() this.me.clear()
@ -157,7 +156,7 @@ export class RootStoreModel {
* Called by the session model. Handles session drops by informing the user. * Called by the session model. Handles session drops by informing the user.
*/ */
async handleSessionDrop() { async handleSessionDrop() {
this.log.debug('RootStoreModel:handleSessionDrop') logger.debug('RootStoreModel:handleSessionDrop')
resetToTab('HomeTab') resetToTab('HomeTab')
this.me.clear() this.me.clear()
this.emitSessionDropped() this.emitSessionDropped()
@ -167,7 +166,7 @@ export class RootStoreModel {
* Clears all session-oriented state. * Clears all session-oriented state.
*/ */
clearAllSessionState() { clearAllSessionState() {
this.log.debug('RootStoreModel:clearAllSessionState') logger.debug('RootStoreModel:clearAllSessionState')
this.session.clear() this.session.clear()
resetToTab('HomeTab') resetToTab('HomeTab')
this.me.clear() this.me.clear()
@ -184,7 +183,7 @@ export class RootStoreModel {
await this.me.updateIfNeeded() await this.me.updateIfNeeded()
await this.preferences.sync() await this.preferences.sync()
} catch (e: any) { } catch (e: any) {
this.log.error('Failed to fetch latest state', {error: e}) logger.error('Failed to fetch latest state', {error: e})
} }
} }

View File

@ -12,6 +12,7 @@ import {z} from 'zod'
import {RootStoreModel} from './root-store' import {RootStoreModel} from './root-store'
import {IS_PROD} from 'lib/constants' import {IS_PROD} from 'lib/constants'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export type ServiceDescription = DescribeServer.OutputSchema export type ServiceDescription = DescribeServer.OutputSchema
@ -56,7 +57,7 @@ export class SessionModel {
), ),
isResumingSession: this.isResumingSession, isResumingSession: this.isResumingSession,
} }
this.rootStore.log.debug(message, details) logger.debug(message, details, logger.DebugContext.session)
} }
/** /**

View File

@ -8,6 +8,7 @@ import {createFullHandle} from 'lib/strings/handles'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {getAge} from 'lib/strings/time' import {getAge} from 'lib/strings/time'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
const DEFAULT_DATE = new Date(Date.now() - 60e3 * 60 * 24 * 365 * 20) // default to 20 years ago const DEFAULT_DATE = new Date(Date.now() - 60e3 * 60 * 24 * 365 * 20) // default to 20 years ago
@ -76,7 +77,7 @@ export class CreateAccountModel {
this.setServiceDescription(desc) this.setServiceDescription(desc)
this.setUserDomain(desc.availableUserDomains[0]) this.setUserDomain(desc.availableUserDomains[0])
} catch (err: any) { } catch (err: any) {
this.rootStore.log.warn( logger.warn(
`Failed to fetch service description for ${this.serviceUrl}`, `Failed to fetch service description for ${this.serviceUrl}`,
{error: err}, {error: err},
) )
@ -127,7 +128,7 @@ export class CreateAccountModel {
errMsg = errMsg =
'Invite code not accepted. Check that you input it correctly and try again.' 'Invite code not accepted. Check that you input it correctly and try again.'
} }
this.rootStore.log.error('Failed to create account', {error: e}) logger.error('Failed to create account', {error: e})
this.setIsProcessing(false) this.setIsProcessing(false)
this.setError(cleanError(errMsg)) this.setError(cleanError(errMsg))
throw e throw e

View File

@ -14,6 +14,7 @@ import {deviceLocales} from 'platform/detection'
import {getAge} from 'lib/strings/time' import {getAge} from 'lib/strings/time'
import {FeedTuner} from 'lib/api/feed-manip' import {FeedTuner} from 'lib/api/feed-manip'
import {LANGUAGES} from '../../../locale/languages' import {LANGUAGES} from '../../../locale/languages'
import {logger} from '#/logger'
// TEMP we need to permanently convert 'show' to 'ignore', for now we manually convert -prf // TEMP we need to permanently convert 'show' to 'ignore', for now we manually convert -prf
export type LabelPreference = APILabelPreference | 'show' export type LabelPreference = APILabelPreference | 'show'
@ -246,7 +247,7 @@ export class PreferencesModel {
}) })
await this.rootStore.agent.setSavedFeeds(saved, pinned) await this.rootStore.agent.setSavedFeeds(saved, pinned)
} catch (error) { } catch (error) {
this.rootStore.log.error('Failed to set default feeds', {error}) logger.error('Failed to set default feeds', {error})
} }
} }
} finally { } finally {

View File

@ -4,6 +4,7 @@ import {ProfileModel} from '../content/profile'
import {PostsFeedModel} from '../feeds/posts' import {PostsFeedModel} from '../feeds/posts'
import {ActorFeedsModel} from '../lists/actor-feeds' import {ActorFeedsModel} from '../lists/actor-feeds'
import {ListsListModel} from '../lists/lists-list' import {ListsListModel} from '../lists/lists-list'
import {logger} from '#/logger'
export enum Sections { export enum Sections {
PostsNoReplies = 'Posts', PostsNoReplies = 'Posts',
@ -223,14 +224,10 @@ export class ProfileUiModel {
await Promise.all([ await Promise.all([
this.profile this.profile
.setup() .setup()
.catch(err => .catch(err => logger.error('Failed to fetch profile', {error: err})),
this.rootStore.log.error('Failed to fetch profile', {error: err}),
),
this.feed this.feed
.setup() .setup()
.catch(err => .catch(err => logger.error('Failed to fetch feed', {error: err})),
this.rootStore.log.error('Failed to fetch feed', {error: err}),
),
]) ])
runInAction(() => { runInAction(() => {
this.isAuthenticatedUser = this.isAuthenticatedUser =
@ -241,9 +238,7 @@ export class ProfileUiModel {
this.lists.source = this.profile.did this.lists.source = this.profile.did
this.lists this.lists
.loadMore() .loadMore()
.catch(err => .catch(err => logger.error('Failed to fetch lists', {error: err}))
this.rootStore.log.error('Failed to fetch lists', {error: err}),
)
} }
async refresh() { async refresh() {

View File

@ -4,6 +4,7 @@ import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source' import {FeedSourceModel} from '../content/feed-source'
import {track} from 'lib/analytics/analytics' import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export class SavedFeedsModel { export class SavedFeedsModel {
// state // state
@ -126,7 +127,7 @@ export class SavedFeedsModel {
this.hasLoaded = true this.hasLoaded = true
this.error = cleanError(err) this.error = cleanError(err)
if (err) { if (err) {
this.rootStore.log.error('Failed to fetch user feeds', {err}) logger.error('Failed to fetch user feeds', {err})
} }
} }

View File

@ -30,6 +30,7 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext' import {useTheme} from 'lib/ThemeContext'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {logger} from '#/logger'
enum Forms { enum Forms {
Login, Login,
@ -81,10 +82,9 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
if (aborted) { if (aborted) {
return return
} }
store.log.warn( logger.warn(`Failed to fetch service description for ${serviceUrl}`, {
`Failed to fetch service description for ${serviceUrl}`, error: err,
{error: err}, })
)
setError( setError(
'Unable to contact your service. Please check your Internet connection.', 'Unable to contact your service. Please check your Internet connection.',
) )
@ -93,7 +93,7 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
return () => { return () => {
aborted = true aborted = true
} }
}, [store.session, store.log, serviceUrl, retryDescribeTrigger]) }, [store.session, serviceUrl, retryDescribeTrigger])
const onPressRetryConnect = () => setRetryDescribeTrigger({}) const onPressRetryConnect = () => setRetryDescribeTrigger({})
const onPressForgotPassword = () => { const onPressForgotPassword = () => {
@ -349,7 +349,7 @@ const LoginForm = ({
}) })
} catch (e: any) { } catch (e: any) {
const errMsg = e.toString() const errMsg = e.toString()
store.log.warn('Failed to login', {error: e}) logger.warn('Failed to login', {error: e})
setIsProcessing(false) setIsProcessing(false)
if (errMsg.includes('Authentication Required')) { if (errMsg.includes('Authentication Required')) {
setError('Invalid username or password') setError('Invalid username or password')
@ -578,7 +578,7 @@ const ForgotPasswordForm = ({
onEmailSent() onEmailSent()
} catch (e: any) { } catch (e: any) {
const errMsg = e.toString() const errMsg = e.toString()
store.log.warn('Failed to request password reset', {error: e}) logger.warn('Failed to request password reset', {error: e})
setIsProcessing(false) setIsProcessing(false)
if (isNetworkError(e)) { if (isNetworkError(e)) {
setError( setError(
@ -694,7 +694,6 @@ const ForgotPasswordForm = ({
} }
const SetNewPasswordForm = ({ const SetNewPasswordForm = ({
store,
error, error,
serviceUrl, serviceUrl,
setError, setError,
@ -734,7 +733,7 @@ const SetNewPasswordForm = ({
onPasswordSet() onPasswordSet()
} catch (e: any) { } catch (e: any) {
const errMsg = e.toString() const errMsg = e.toString()
store.log.warn('Failed to set new password', {error: e}) logger.warn('Failed to set new password', {error: e})
setIsProcessing(false) setIsProcessing(false)
if (isNetworkError(e)) { if (isNetworkError(e)) {
setError( setError(

View File

@ -12,6 +12,7 @@ import {useCameraPermission} from 'lib/hooks/usePermissions'
import {HITSLOP_10, POST_IMG_MAX} from 'lib/constants' import {HITSLOP_10, POST_IMG_MAX} from 'lib/constants'
import {GalleryModel} from 'state/models/media/gallery' import {GalleryModel} from 'state/models/media/gallery'
import {isMobileWeb, isNative} from 'platform/detection' import {isMobileWeb, isNative} from 'platform/detection'
import {logger} from '#/logger'
type Props = { type Props = {
gallery: GalleryModel gallery: GalleryModel
@ -39,7 +40,7 @@ export function OpenCameraBtn({gallery}: Props) {
gallery.add(img) gallery.add(img)
} catch (err: any) { } catch (err: any) {
// ignore // ignore
store.log.warn('Error using camera', {error: err}) logger.warn('Error using camera', {error: err})
} }
}, [gallery, track, store, requestCameraAccessIfNeeded]) }, [gallery, track, store, requestCameraAccessIfNeeded])

View File

@ -16,6 +16,7 @@ import {
} from 'lib/strings/url-helpers' } from 'lib/strings/url-helpers'
import {ComposerOpts} from 'state/models/ui/shell' import {ComposerOpts} from 'state/models/ui/shell'
import {POST_IMG_MAX} from 'lib/constants' import {POST_IMG_MAX} from 'lib/constants'
import {logger} from '#/logger'
export function useExternalLinkFetch({ export function useExternalLinkFetch({
setQuote, setQuote,
@ -46,7 +47,7 @@ export function useExternalLinkFetch({
setExtLink(undefined) setExtLink(undefined)
}, },
err => { err => {
store.log.error('Failed to fetch post for quote embedding', { logger.error('Failed to fetch post for quote embedding', {
error: err, error: err,
}) })
setExtLink(undefined) setExtLink(undefined)
@ -66,7 +67,7 @@ export function useExternalLinkFetch({
}) })
}, },
err => { err => {
store.log.error('Failed to fetch feed for embedding', {error: err}) logger.error('Failed to fetch feed for embedding', {error: err})
setExtLink(undefined) setExtLink(undefined)
}, },
) )
@ -84,7 +85,7 @@ export function useExternalLinkFetch({
}) })
}, },
err => { err => {
store.log.error('Failed to fetch list for embedding', {error: err}) logger.error('Failed to fetch list for embedding', {error: err})
setExtLink(undefined) setExtLink(undefined)
}, },
) )

View File

@ -20,6 +20,7 @@ import {TextLink} from '../util/Link'
import {FAB} from '../util/fab/FAB' import {FAB} from '../util/fab/FAB'
import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn' import {LoadLatestBtn} from '../util/load-latest/LoadLatestBtn'
import useAppState from 'react-native-appstate-hook' import useAppState from 'react-native-appstate-hook'
import {logger} from '#/logger'
export const FeedPage = observer(function FeedPageImpl({ export const FeedPage = observer(function FeedPageImpl({
testID, testID,
@ -66,10 +67,10 @@ export const FeedPage = observer(function FeedPageImpl({
if (feed.isLoading) { if (feed.isLoading) {
return return
} }
store.log.debug('HomeScreen: Polling for new posts') logger.debug('HomeScreen: Polling for new posts')
feed.checkForLatest() feed.checkForLatest()
}, },
[appState, isScreenFocused, isPageFocused, store, feed], [appState, isScreenFocused, isPageFocused, feed],
) )
const scrollToTop = React.useCallback(() => { const scrollToTop = React.useCallback(() => {
@ -96,7 +97,7 @@ export const FeedPage = observer(function FeedPageImpl({
const pollInterval = setInterval(doPoll, POLL_FREQ) const pollInterval = setInterval(doPoll, POLL_FREQ)
screen('Feed') screen('Feed')
store.log.debug('HomeScreen: Updating feed') logger.debug('HomeScreen: Updating feed')
feed.checkForLatest() feed.checkForLatest()
return () => { return () => {

View File

@ -15,6 +15,7 @@ import {pluralize} from 'lib/strings/helpers'
import {AtUri} from '@atproto/api' import {AtUri} from '@atproto/api'
import * as Toast from 'view/com/util/Toast' import * as Toast from 'view/com/util/Toast'
import {sanitizeHandle} from 'lib/strings/handles' import {sanitizeHandle} from 'lib/strings/handles'
import {logger} from '#/logger'
export const FeedSourceCard = observer(function FeedSourceCardImpl({ export const FeedSourceCard = observer(function FeedSourceCardImpl({
item, item,
@ -45,7 +46,7 @@ export const FeedSourceCard = observer(function FeedSourceCardImpl({
Toast.show('Removed from my feeds') Toast.show('Removed from my feeds')
} catch (e) { } catch (e) {
Toast.show('There was an issue contacting your server') Toast.show('There was an issue contacting your server')
store.log.error('Failed to unsave feed', {error: e}) logger.error('Failed to unsave feed', {error: e})
} }
}, },
}) })
@ -55,7 +56,7 @@ export const FeedSourceCard = observer(function FeedSourceCardImpl({
Toast.show('Added to my feeds') Toast.show('Added to my feeds')
} catch (e) { } catch (e) {
Toast.show('There was an issue contacting your server') Toast.show('There was an issue contacting your server')
store.log.error('Failed to save feed', {error: e}) logger.error('Failed to save feed', {error: e})
} }
} }
}, [store, item]) }, [store, item])

View File

@ -21,6 +21,7 @@ import {useStores} from 'state/index'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {OnScrollCb} from 'lib/hooks/useOnMainScroll' import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
import {logger} from '#/logger'
const LOADING_ITEM = {_reactKey: '__loading__'} const LOADING_ITEM = {_reactKey: '__loading__'}
const EMPTY_ITEM = {_reactKey: '__empty__'} const EMPTY_ITEM = {_reactKey: '__empty__'}
@ -94,7 +95,7 @@ export const ListItems = observer(function ListItemsImpl({
try { try {
await list.refresh() await list.refresh()
} catch (err) { } catch (err) {
list.rootStore.log.error('Failed to refresh lists', {error: err}) logger.error('Failed to refresh lists', {error: err})
} }
setIsRefreshing(false) setIsRefreshing(false)
}, [list, track, setIsRefreshing]) }, [list, track, setIsRefreshing])
@ -104,7 +105,7 @@ export const ListItems = observer(function ListItemsImpl({
try { try {
await list.loadMore() await list.loadMore()
} catch (err) { } catch (err) {
list.rootStore.log.error('Failed to load more lists', {error: err}) logger.error('Failed to load more lists', {error: err})
} }
}, [list, track]) }, [list, track])

View File

@ -19,6 +19,7 @@ import {useAnalytics} from 'lib/analytics/analytics'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {FlatList} from '../util/Views.web' import {FlatList} from '../util/Views.web'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {logger} from '#/logger'
const LOADING = {_reactKey: '__loading__'} const LOADING = {_reactKey: '__loading__'}
const EMPTY = {_reactKey: '__empty__'} const EMPTY = {_reactKey: '__empty__'}
@ -78,7 +79,7 @@ export const ListsList = observer(function ListsListImpl({
try { try {
await listsList.refresh() await listsList.refresh()
} catch (err) { } catch (err) {
listsList.rootStore.log.error('Failed to refresh lists', {error: err}) logger.error('Failed to refresh lists', {error: err})
} }
setIsRefreshing(false) setIsRefreshing(false)
}, [listsList, track, setIsRefreshing]) }, [listsList, track, setIsRefreshing])
@ -88,7 +89,7 @@ export const ListsList = observer(function ListsListImpl({
try { try {
await listsList.loadMore() await listsList.loadMore()
} catch (err) { } catch (err) {
listsList.rootStore.log.error('Failed to load more lists', {error: err}) logger.error('Failed to load more lists', {error: err})
} }
}, [listsList, track]) }, [listsList, track])

View File

@ -12,6 +12,7 @@ import {
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import Clipboard from '@react-native-clipboard/clipboard' import Clipboard from '@react-native-clipboard/clipboard'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {logger} from '#/logger'
export const snapPoints = ['70%'] export const snapPoints = ['70%']
@ -95,7 +96,7 @@ export function Component({}: {}) {
} }
} catch (e) { } catch (e) {
Toast.show('Failed to create app password.') Toast.show('Failed to create app password.')
store.log.error('Failed to create app password', {error: e}) logger.error('Failed to create app password', {error: e})
} }
} }

View File

@ -21,6 +21,7 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext' import {useTheme} from 'lib/ThemeContext'
import {useAnalytics} from 'lib/analytics/analytics' import {useAnalytics} from 'lib/analytics/analytics'
import {cleanError} from 'lib/strings/errors' import {cleanError} from 'lib/strings/errors'
import {logger} from '#/logger'
export const snapPoints = ['100%'] export const snapPoints = ['100%']
@ -65,7 +66,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
return return
} }
setProcessing(false) setProcessing(false)
store.log.warn( logger.warn(
`Failed to fetch service description for ${String( `Failed to fetch service description for ${String(
store.agent.service, store.agent.service,
)}`, )}`,
@ -79,7 +80,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
return () => { return () => {
aborted = true aborted = true
} }
}, [store.agent.service, store.session, store.log, retryDescribeTrigger]) }, [store.agent.service, store.session, retryDescribeTrigger])
// events // events
// = // =
@ -105,7 +106,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
try { try {
track('EditHandle:SetNewHandle') track('EditHandle:SetNewHandle')
const newHandle = isCustom ? handle : createFullHandle(handle, userDomain) const newHandle = isCustom ? handle : createFullHandle(handle, userDomain)
store.log.debug(`Updating handle to ${newHandle}`) logger.debug(`Updating handle to ${newHandle}`)
await store.agent.updateHandle({ await store.agent.updateHandle({
handle: newHandle, handle: newHandle,
}) })
@ -113,7 +114,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
onChanged() onChanged()
} catch (err: any) { } catch (err: any) {
setError(cleanError(err)) setError(cleanError(err))
store.log.error('Failed to update handle', {handle, error: err}) logger.error('Failed to update handle', {handle, error: err})
} finally { } finally {
setProcessing(false) setProcessing(false)
} }
@ -343,7 +344,7 @@ function CustomHandleForm({
} }
} catch (err: any) { } catch (err: any) {
setError(cleanError(err)) setError(cleanError(err))
store.log.error('Failed to verify domain', {handle, error: err}) logger.error('Failed to verify domain', {handle, error: err})
} finally { } finally {
setIsVerifying(false) setIsVerifying(false)
} }
@ -355,7 +356,6 @@ function CustomHandleForm({
setError, setError,
canSave, canSave,
onPressSave, onPressSave,
store.log,
store.agent, store.agent,
]) ])

View File

@ -15,6 +15,7 @@ import {CONFIGURABLE_LABEL_GROUPS} from 'lib/labeling/const'
import {isIOS} from 'platform/detection' import {isIOS} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {logger} from '#/logger'
export const snapPoints = ['90%'] export const snapPoints = ['90%']
@ -103,7 +104,7 @@ const AdultContentEnabledPref = observer(
Toast.show( Toast.show(
'There was an issue syncing your preferences with the server', 'There was an issue syncing your preferences with the server',
) )
store.log.error('Failed to update preferences with server', {error: e}) logger.error('Failed to update preferences with server', {error: e})
} }
} }
@ -168,7 +169,7 @@ const ContentLabelPref = observer(function ContentLabelPrefImpl({
Toast.show( Toast.show(
'There was an issue syncing your preferences with the server', 'There was an issue syncing your preferences with the server',
) )
store.log.error('Failed to update preferences with server', {error: e}) logger.error('Failed to update preferences with server', {error: e})
} }
}, },
[store, group], [store, group],

View File

@ -20,6 +20,7 @@ import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {isWeb, isAndroid} from 'platform/detection' import {isWeb, isAndroid} from 'platform/detection'
import isEqual from 'lodash.isequal' import isEqual from 'lodash.isequal'
import {logger} from '#/logger'
export const snapPoints = ['fullscreen'] export const snapPoints = ['fullscreen']
@ -62,7 +63,7 @@ export const Component = observer(function UserAddRemoveListsImpl({
setMembershipsLoaded(true) setMembershipsLoaded(true)
}, },
err => { err => {
store.log.error('Failed to fetch memberships', {error: err}) logger.error('Failed to fetch memberships', {error: err})
}, },
) )
}, [memberships, listsList, store, setSelected, setMembershipsLoaded]) }, [memberships, listsList, store, setSelected, setMembershipsLoaded])
@ -76,7 +77,7 @@ export const Component = observer(function UserAddRemoveListsImpl({
try { try {
changes = await memberships.updateTo(selected) changes = await memberships.updateTo(selected)
} catch (err) { } catch (err) {
store.log.error('Failed to update memberships', {error: err}) logger.error('Failed to update memberships', {error: err})
return return
} }
Toast.show('Lists updated') Toast.show('Lists updated')

View File

@ -11,6 +11,7 @@ import {EmptyState} from '../util/EmptyState'
import {OnScrollCb} from 'lib/hooks/useOnMainScroll' import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
import {s} from 'lib/styles' import {s} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'} const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
@ -61,7 +62,7 @@ export const Feed = observer(function Feed({
setIsPTRing(true) setIsPTRing(true)
await view.refresh() await view.refresh()
} catch (err) { } catch (err) {
view.rootStore.log.error('Failed to refresh notifications feed', { logger.error('Failed to refresh notifications feed', {
error: err, error: err,
}) })
} finally { } finally {
@ -73,7 +74,7 @@ export const Feed = observer(function Feed({
try { try {
await view.loadMore() await view.loadMore()
} catch (err) { } catch (err) {
view.rootStore.log.error('Failed to load more notifications', { logger.error('Failed to load more notifications', {
error: err, error: err,
}) })
} }

View File

@ -7,6 +7,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
export const PostLikedBy = observer(function PostLikedByImpl({ export const PostLikedBy = observer(function PostLikedByImpl({
uri, uri,
@ -20,8 +21,8 @@ export const PostLikedBy = observer(function PostLikedByImpl({
useEffect(() => { useEffect(() => {
view view
.loadMore() .loadMore()
.catch(err => store.log.error('Failed to fetch likes', {error: err})) .catch(err => logger.error('Failed to fetch likes', {error: err}))
}, [view, store.log]) }, [view])
const onRefresh = () => { const onRefresh = () => {
view.refresh() view.refresh()
@ -29,9 +30,7 @@ export const PostLikedBy = observer(function PostLikedByImpl({
const onEndReached = () => { const onEndReached = () => {
view view
.loadMore() .loadMore()
.catch(err => .catch(err => logger.error('Failed to load more likes', {error: err}))
view?.rootStore.log.error('Failed to load more likes', {error: err}),
)
} }
if (!view.hasLoaded) { if (!view.hasLoaded) {

View File

@ -7,6 +7,7 @@ import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
import {ErrorMessage} from '../util/error/ErrorMessage' import {ErrorMessage} from '../util/error/ErrorMessage'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
export const PostRepostedBy = observer(function PostRepostedByImpl({ export const PostRepostedBy = observer(function PostRepostedByImpl({
uri, uri,
@ -23,8 +24,8 @@ export const PostRepostedBy = observer(function PostRepostedByImpl({
useEffect(() => { useEffect(() => {
view view
.loadMore() .loadMore()
.catch(err => store.log.error('Failed to fetch reposts', {error: err})) .catch(err => logger.error('Failed to fetch reposts', {error: err}))
}, [view, store.log]) }, [view])
const onRefresh = () => { const onRefresh = () => {
view.refresh() view.refresh()
@ -32,9 +33,7 @@ export const PostRepostedBy = observer(function PostRepostedByImpl({
const onEndReached = () => { const onEndReached = () => {
view view
.loadMore() .loadMore()
.catch(err => .catch(err => logger.error('Failed to load more reposts', {error: err}))
view?.rootStore.log.error('Failed to load more reposts', {error: err}),
)
} }
if (!view.hasLoaded) { if (!view.hasLoaded) {

View File

@ -30,6 +30,7 @@ import {useNavigation} from '@react-navigation/native'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {NavigationProp} from 'lib/routes/types' import {NavigationProp} from 'lib/routes/types'
import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeDisplayName} from 'lib/strings/display-names'
import {logger} from '#/logger'
const MAINTAIN_VISIBLE_CONTENT_POSITION = {minIndexForVisible: 2} const MAINTAIN_VISIBLE_CONTENT_POSITION = {minIndexForVisible: 2}
@ -119,7 +120,7 @@ export const PostThread = observer(function PostThread({
try { try {
view?.refresh() view?.refresh()
} catch (err) { } catch (err) {
view.rootStore.log.error('Failed to refresh posts thread', {error: err}) logger.error('Failed to refresh posts thread', {error: err})
} }
setIsRefreshing(false) setIsRefreshing(false)
}, [view, setIsRefreshing]) }, [view, setIsRefreshing])

View File

@ -36,6 +36,7 @@ import {TimeElapsed} from 'view/com/util/TimeElapsed'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {MAX_POST_LINES} from 'lib/constants' import {MAX_POST_LINES} from 'lib/constants'
import {logger} from '#/logger'
export const PostThreadItem = observer(function PostThreadItem({ export const PostThreadItem = observer(function PostThreadItem({
item, item,
@ -111,14 +112,14 @@ export const PostThreadItem = observer(function PostThreadItem({
const onPressToggleRepost = React.useCallback(() => { const onPressToggleRepost = React.useCallback(() => {
return item return item
.toggleRepost() .toggleRepost()
.catch(e => store.log.error('Failed to toggle repost', {error: e})) .catch(e => logger.error('Failed to toggle repost', {error: e}))
}, [item, store]) }, [item])
const onPressToggleLike = React.useCallback(() => { const onPressToggleLike = React.useCallback(() => {
return item return item
.toggleLike() .toggleLike()
.catch(e => store.log.error('Failed to toggle like', {error: e})) .catch(e => logger.error('Failed to toggle like', {error: e}))
}, [item, store]) }, [item])
const onCopyPostText = React.useCallback(() => { const onCopyPostText = React.useCallback(() => {
Clipboard.setString(record?.text || '') Clipboard.setString(record?.text || '')
@ -138,9 +139,9 @@ export const PostThreadItem = observer(function PostThreadItem({
Toast.show('You will now receive notifications for this thread') Toast.show('You will now receive notifications for this thread')
} }
} catch (e) { } catch (e) {
store.log.error('Failed to toggle thread mute', {error: e}) logger.error('Failed to toggle thread mute', {error: e})
} }
}, [item, store]) }, [item])
const onDeletePost = React.useCallback(() => { const onDeletePost = React.useCallback(() => {
item.delete().then( item.delete().then(
@ -149,11 +150,11 @@ export const PostThreadItem = observer(function PostThreadItem({
Toast.show('Post deleted') Toast.show('Post deleted')
}, },
e => { e => {
store.log.error('Failed to delete post', {error: e}) logger.error('Failed to delete post', {error: e})
Toast.show('Failed to delete post, please try again') Toast.show('Failed to delete post, please try again')
}, },
) )
}, [item, store]) }, [item])
const onPressShowMore = React.useCallback(() => { const onPressShowMore = React.useCallback(() => {
setLimitLines(false) setLimitLines(false)

View File

@ -32,6 +32,7 @@ import {getTranslatorLink} from '../../../locale/helpers'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {MAX_POST_LINES} from 'lib/constants' import {MAX_POST_LINES} from 'lib/constants'
import {countLines} from 'lib/strings/helpers' import {countLines} from 'lib/strings/helpers'
import {logger} from '#/logger'
export const Post = observer(function PostImpl({ export const Post = observer(function PostImpl({
view, view,
@ -142,14 +143,14 @@ const PostLoaded = observer(function PostLoadedImpl({
const onPressToggleRepost = React.useCallback(() => { const onPressToggleRepost = React.useCallback(() => {
return item return item
.toggleRepost() .toggleRepost()
.catch(e => store.log.error('Failed to toggle repost', {error: e})) .catch(e => logger.error('Failed to toggle repost', {error: e}))
}, [item, store]) }, [item])
const onPressToggleLike = React.useCallback(() => { const onPressToggleLike = React.useCallback(() => {
return item return item
.toggleLike() .toggleLike()
.catch(e => store.log.error('Failed to toggle like', {error: e})) .catch(e => logger.error('Failed to toggle like', {error: e}))
}, [item, store]) }, [item])
const onCopyPostText = React.useCallback(() => { const onCopyPostText = React.useCallback(() => {
Clipboard.setString(record.text) Clipboard.setString(record.text)
@ -169,9 +170,9 @@ const PostLoaded = observer(function PostLoadedImpl({
Toast.show('You will now receive notifications for this thread') Toast.show('You will now receive notifications for this thread')
} }
} catch (e) { } catch (e) {
store.log.error('Failed to toggle thread mute', {error: e}) logger.error('Failed to toggle thread mute', {error: e})
} }
}, [item, store]) }, [item])
const onDeletePost = React.useCallback(() => { const onDeletePost = React.useCallback(() => {
item.delete().then( item.delete().then(
@ -180,11 +181,11 @@ const PostLoaded = observer(function PostLoadedImpl({
Toast.show('Post deleted') Toast.show('Post deleted')
}, },
e => { e => {
store.log.error('Failed to delete post', {error: e}) logger.error('Failed to delete post', {error: e})
Toast.show('Failed to delete post, please try again') Toast.show('Failed to delete post, please try again')
}, },
) )
}, [item, setDeleted, store]) }, [item, setDeleted])
const onPressShowMore = React.useCallback(() => { const onPressShowMore = React.useCallback(() => {
setLimitLines(false) setLimitLines(false)

View File

@ -19,6 +19,7 @@ import {s} from 'lib/styles'
import {useAnalytics} from 'lib/analytics/analytics' import {useAnalytics} from 'lib/analytics/analytics'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useTheme} from 'lib/ThemeContext' import {useTheme} from 'lib/ThemeContext'
import {logger} from '#/logger'
const LOADING_ITEM = {_reactKey: '__loading__'} const LOADING_ITEM = {_reactKey: '__loading__'}
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@ -92,7 +93,7 @@ export const Feed = observer(function Feed({
try { try {
await feed.refresh() await feed.refresh()
} catch (err) { } catch (err) {
feed.rootStore.log.error('Failed to refresh posts feed', {error: err}) logger.error('Failed to refresh posts feed', {error: err})
} }
setIsRefreshing(false) setIsRefreshing(false)
}, [feed, track, setIsRefreshing]) }, [feed, track, setIsRefreshing])
@ -104,7 +105,7 @@ export const Feed = observer(function Feed({
try { try {
await feed.loadMore() await feed.loadMore()
} catch (err) { } catch (err) {
feed.rootStore.log.error('Failed to load more posts', {error: err}) logger.error('Failed to load more posts', {error: err})
} }
}, [feed, track]) }, [feed, track])

View File

@ -10,6 +10,7 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useNavigation} from '@react-navigation/native' import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from 'lib/routes/types' import {NavigationProp} from 'lib/routes/types'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {logger} from '#/logger'
const MESSAGES = { const MESSAGES = {
[KnownError.Unknown]: '', [KnownError.Unknown]: '',
@ -73,7 +74,7 @@ function FeedgenErrorMessage({
Toast.show( Toast.show(
'There was an an issue removing this feed. Please check your internet connection and try again.', 'There was an an issue removing this feed. Please check your internet connection and try again.',
) )
store.log.error('Failed to remove feed', {error: err}) logger.error('Failed to remove feed', {error: err})
} }
}, },
onPressCancel() { onPressCancel() {

View File

@ -32,6 +32,7 @@ import {makeProfileLink} from 'lib/routes/links'
import {isEmbedByEmbedder} from 'lib/embeds' import {isEmbedByEmbedder} from 'lib/embeds'
import {MAX_POST_LINES} from 'lib/constants' import {MAX_POST_LINES} from 'lib/constants'
import {countLines} from 'lib/strings/helpers' import {countLines} from 'lib/strings/helpers'
import {logger} from '#/logger'
export const FeedItem = observer(function FeedItemImpl({ export const FeedItem = observer(function FeedItemImpl({
item, item,
@ -94,15 +95,15 @@ export const FeedItem = observer(function FeedItemImpl({
track('FeedItem:PostRepost') track('FeedItem:PostRepost')
return item return item
.toggleRepost() .toggleRepost()
.catch(e => store.log.error('Failed to toggle repost', {error: e})) .catch(e => logger.error('Failed to toggle repost', {error: e}))
}, [track, item, store]) }, [track, item])
const onPressToggleLike = React.useCallback(() => { const onPressToggleLike = React.useCallback(() => {
track('FeedItem:PostLike') track('FeedItem:PostLike')
return item return item
.toggleLike() .toggleLike()
.catch(e => store.log.error('Failed to toggle like', {error: e})) .catch(e => logger.error('Failed to toggle like', {error: e}))
}, [track, item, store]) }, [track, item])
const onCopyPostText = React.useCallback(() => { const onCopyPostText = React.useCallback(() => {
Clipboard.setString(record?.text || '') Clipboard.setString(record?.text || '')
@ -123,9 +124,9 @@ export const FeedItem = observer(function FeedItemImpl({
Toast.show('You will now receive notifications for this thread') Toast.show('You will now receive notifications for this thread')
} }
} catch (e) { } catch (e) {
store.log.error('Failed to toggle thread mute', {error: e}) logger.error('Failed to toggle thread mute', {error: e})
} }
}, [track, item, store]) }, [track, item])
const onDeletePost = React.useCallback(() => { const onDeletePost = React.useCallback(() => {
track('FeedItem:PostDelete') track('FeedItem:PostDelete')
@ -135,11 +136,11 @@ export const FeedItem = observer(function FeedItemImpl({
Toast.show('Post deleted') Toast.show('Post deleted')
}, },
e => { e => {
store.log.error('Failed to delete post', {error: e}) logger.error('Failed to delete post', {error: e})
Toast.show('Failed to delete post, please try again') Toast.show('Failed to delete post, please try again')
}, },
) )
}, [track, item, setDeleted, store]) }, [track, item, setDeleted])
const onPressShowMore = React.useCallback(() => { const onPressShowMore = React.useCallback(() => {
setLimitLines(false) setLimitLines(false)

View File

@ -10,6 +10,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
import {ProfileCardWithFollowBtn} from './ProfileCard' import {ProfileCardWithFollowBtn} from './ProfileCard'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
export const ProfileFollowers = observer(function ProfileFollowers({ export const ProfileFollowers = observer(function ProfileFollowers({
name, name,
@ -27,16 +28,16 @@ export const ProfileFollowers = observer(function ProfileFollowers({
view view
.loadMore() .loadMore()
.catch(err => .catch(err =>
store.log.error('Failed to fetch user followers', {error: err}), logger.error('Failed to fetch user followers', {error: err}),
) )
}, [view, store.log]) }, [view])
const onRefresh = () => { const onRefresh = () => {
view.refresh() view.refresh()
} }
const onEndReached = () => { const onEndReached = () => {
view.loadMore().catch(err => view.loadMore().catch(err =>
view?.rootStore.log.error('Failed to load more followers', { logger.error('Failed to load more followers', {
error: err, error: err,
}), }),
) )

View File

@ -7,6 +7,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
import {ProfileCardWithFollowBtn} from './ProfileCard' import {ProfileCardWithFollowBtn} from './ProfileCard'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {logger} from '#/logger'
export const ProfileFollows = observer(function ProfileFollows({ export const ProfileFollows = observer(function ProfileFollows({
name, name,
@ -23,8 +24,8 @@ export const ProfileFollows = observer(function ProfileFollows({
useEffect(() => { useEffect(() => {
view view
.loadMore() .loadMore()
.catch(err => store.log.error('Failed to fetch user follows', err)) .catch(err => logger.error('Failed to fetch user follows', err))
}, [view, store.log]) }, [view])
const onRefresh = () => { const onRefresh = () => {
view.refresh() view.refresh()
@ -32,9 +33,7 @@ export const ProfileFollows = observer(function ProfileFollows({
const onEndReached = () => { const onEndReached = () => {
view view
.loadMore() .loadMore()
.catch(err => .catch(err => logger.error('Failed to load more follows', err))
view?.rootStore.log.error('Failed to load more follows', err),
)
} }
if (!view.hasLoaded) { if (!view.hasLoaded) {

View File

@ -39,6 +39,7 @@ import {isInvalidHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {Link} from '../util/Link' import {Link} from '../util/Link'
import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows' import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows'
import {logger} from '#/logger'
interface Props { interface Props {
view: ProfileModel view: ProfileModel
@ -150,9 +151,9 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
: 'ProfileHeader:UnfollowButtonClicked', : 'ProfileHeader:UnfollowButtonClicked',
) )
}, },
err => store.log.error('Failed to toggle follow', {error: err}), err => logger.error('Failed to toggle follow', {error: err}),
) )
}, [track, view, store.log, setShowSuggestedFollows]) }, [track, view, setShowSuggestedFollows])
const onPressEditProfile = React.useCallback(() => { const onPressEditProfile = React.useCallback(() => {
track('ProfileHeader:EditProfileButtonClicked') track('ProfileHeader:EditProfileButtonClicked')
@ -193,10 +194,10 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
await view.muteAccount() await view.muteAccount()
Toast.show('Account muted') Toast.show('Account muted')
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to mute account', {error: e}) logger.error('Failed to mute account', {error: e})
Toast.show(`There was an issue! ${e.toString()}`) Toast.show(`There was an issue! ${e.toString()}`)
} }
}, [track, view, store]) }, [track, view])
const onPressUnmuteAccount = React.useCallback(async () => { const onPressUnmuteAccount = React.useCallback(async () => {
track('ProfileHeader:UnmuteAccountButtonClicked') track('ProfileHeader:UnmuteAccountButtonClicked')
@ -204,10 +205,10 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
await view.unmuteAccount() await view.unmuteAccount()
Toast.show('Account unmuted') Toast.show('Account unmuted')
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to unmute account', {error: e}) logger.error('Failed to unmute account', {error: e})
Toast.show(`There was an issue! ${e.toString()}`) Toast.show(`There was an issue! ${e.toString()}`)
} }
}, [track, view, store]) }, [track, view])
const onPressBlockAccount = React.useCallback(async () => { const onPressBlockAccount = React.useCallback(async () => {
track('ProfileHeader:BlockAccountButtonClicked') track('ProfileHeader:BlockAccountButtonClicked')
@ -222,7 +223,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
onRefreshAll() onRefreshAll()
Toast.show('Account blocked') Toast.show('Account blocked')
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to block account', {error: e}) logger.error('Failed to block account', {error: e})
Toast.show(`There was an issue! ${e.toString()}`) Toast.show(`There was an issue! ${e.toString()}`)
} }
}, },
@ -242,7 +243,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
onRefreshAll() onRefreshAll()
Toast.show('Account unblocked') Toast.show('Account unblocked')
} catch (e: any) { } catch (e: any) {
store.log.error('Failed to unblock account', {error: e}) logger.error('Failed to unblock account', {error: e})
Toast.show(`There was an issue! ${e.toString()}`) Toast.show(`There was an issue! ${e.toString()}`)
} }
}, },

View File

@ -21,6 +21,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader' import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views' import {CenteredView} from 'view/com/util/Views'
import {ProfileCard} from 'view/com/profile/ProfileCard' import {ProfileCard} from 'view/com/profile/ProfileCard'
import {logger} from '#/logger'
type Props = NativeStackScreenProps< type Props = NativeStackScreenProps<
CommonNavigatorParams, CommonNavigatorParams,
@ -52,9 +53,9 @@ export const ModerationBlockedAccounts = withAuthRequired(
blockedAccounts blockedAccounts
.loadMore() .loadMore()
.catch(err => .catch(err =>
store.log.error('Failed to load more blocked accounts', {error: err}), logger.error('Failed to load more blocked accounts', {error: err}),
) )
}, [blockedAccounts, store]) }, [blockedAccounts])
const renderItem = ({ const renderItem = ({
item, item,

View File

@ -21,6 +21,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader' import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views' import {CenteredView} from 'view/com/util/Views'
import {ProfileCard} from 'view/com/profile/ProfileCard' import {ProfileCard} from 'view/com/profile/ProfileCard'
import {logger} from '#/logger'
type Props = NativeStackScreenProps< type Props = NativeStackScreenProps<
CommonNavigatorParams, CommonNavigatorParams,
@ -49,9 +50,9 @@ export const ModerationMutedAccounts = withAuthRequired(
mutedAccounts mutedAccounts
.loadMore() .loadMore()
.catch(err => .catch(err =>
store.log.error('Failed to load more muted accounts', {error: err}), logger.error('Failed to load more muted accounts', {error: err}),
) )
}, [mutedAccounts, store]) }, [mutedAccounts])
const renderItem = ({ const renderItem = ({
item, item,

View File

@ -20,6 +20,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {s, colors} from 'lib/styles' import {s, colors} from 'lib/styles'
import {useAnalytics} from 'lib/analytics/analytics' import {useAnalytics} from 'lib/analytics/analytics'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {logger} from '#/logger'
type Props = NativeStackScreenProps< type Props = NativeStackScreenProps<
NotificationsTabNavigatorParams, NotificationsTabNavigatorParams,
@ -60,7 +61,7 @@ export const NotificationsScreen = withAuthRequired(
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
store.shell.setMinimalShellMode(false) store.shell.setMinimalShellMode(false)
store.log.debug('NotificationsScreen: Updating feed') logger.debug('NotificationsScreen: Updating feed')
const softResetSub = store.onScreenSoftReset(onPressLoadLatest) const softResetSub = store.onScreenSoftReset(onPressLoadLatest)
store.me.notifications.update() store.me.notifications.update()
screen('Notifications') screen('Notifications')

View File

@ -14,6 +14,7 @@ import {s} from 'lib/styles'
import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {clamp} from 'lodash' import {clamp} from 'lodash'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {logger} from '#/logger'
const SHELL_FOOTER_HEIGHT = 44 const SHELL_FOOTER_HEIGHT = 44
@ -38,7 +39,7 @@ export const PostThreadScreen = withAuthRequired(
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {
if (!view.hasLoaded && !view.isLoading) { if (!view.hasLoaded && !view.isLoading) {
view.setup().catch(err => { view.setup().catch(err => {
store.log.error('Failed to fetch thread', {error: err}) logger.error('Failed to fetch thread', {error: err})
}) })
} }
}) })

View File

@ -29,6 +29,7 @@ import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
import {FeedSourceModel} from 'state/models/content/feed-source' import {FeedSourceModel} from 'state/models/content/feed-source'
import {useSetTitle} from 'lib/hooks/useSetTitle' import {useSetTitle} from 'lib/hooks/useSetTitle'
import {combinedDisplayName} from 'lib/strings/display-names' import {combinedDisplayName} from 'lib/strings/display-names'
import {logger} from '#/logger'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
export const ProfileScreen = withAuthRequired( export const ProfileScreen = withAuthRequired(
@ -108,16 +109,16 @@ export const ProfileScreen = withAuthRequired(
uiState uiState
.refresh() .refresh()
.catch((err: any) => .catch((err: any) =>
store.log.error('Failed to refresh user profile', {error: err}), logger.error('Failed to refresh user profile', {error: err}),
) )
}, [uiState, store]) }, [uiState])
const onEndReached = React.useCallback(() => { const onEndReached = React.useCallback(() => {
uiState.loadMore().catch((err: any) => uiState.loadMore().catch((err: any) =>
store.log.error('Failed to load more entries in user profile', { logger.error('Failed to load more entries in user profile', {
error: err, error: err,
}), }),
) )
}, [uiState, store]) }, [uiState])
const onPressTryAgain = React.useCallback(() => { const onPressTryAgain = React.useCallback(() => {
uiState.setup() uiState.setup()
}, [uiState]) }, [uiState])

View File

@ -40,6 +40,7 @@ import {NavigationProp} from 'lib/routes/types'
import {sanitizeHandle} from 'lib/strings/handles' import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {ComposeIcon2} from 'lib/icons' import {ComposeIcon2} from 'lib/icons'
import {logger} from '#/logger'
const SECTION_TITLES = ['Posts', 'About'] const SECTION_TITLES = ['Posts', 'About']
@ -165,9 +166,9 @@ export const ProfileFeedScreenInner = observer(
Toast.show( Toast.show(
'There was an an issue updating your feeds, please check your internet connection and try again.', 'There was an an issue updating your feeds, please check your internet connection and try again.',
) )
store.log.error('Failed up update feeds', {error: err}) logger.error('Failed up update feeds', {error: err})
} }
}, [store, feedInfo]) }, [feedInfo])
const onToggleLiked = React.useCallback(async () => { const onToggleLiked = React.useCallback(async () => {
Haptics.default() Haptics.default()
@ -181,19 +182,19 @@ export const ProfileFeedScreenInner = observer(
Toast.show( Toast.show(
'There was an an issue contacting the server, please check your internet connection and try again.', 'There was an an issue contacting the server, please check your internet connection and try again.',
) )
store.log.error('Failed up toggle like', {error: err}) logger.error('Failed up toggle like', {error: err})
} }
}, [store, feedInfo]) }, [feedInfo])
const onTogglePinned = React.useCallback(async () => { const onTogglePinned = React.useCallback(async () => {
Haptics.default() Haptics.default()
if (feedInfo) { if (feedInfo) {
feedInfo.togglePin().catch(e => { feedInfo.togglePin().catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to toggle pinned feed', {error: e}) logger.error('Failed to toggle pinned feed', {error: e})
}) })
} }
}, [store, feedInfo]) }, [feedInfo])
const onPressShare = React.useCallback(() => { const onPressShare = React.useCallback(() => {
const url = toShareUrl(`/profile/${handleOrDid}/feed/${rkey}`) const url = toShareUrl(`/profile/${handleOrDid}/feed/${rkey}`)

View File

@ -43,6 +43,7 @@ import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink, makeListLink} from 'lib/routes/links' import {makeProfileLink, makeListLink} from 'lib/routes/links'
import {ComposeIcon2} from 'lib/icons' import {ComposeIcon2} from 'lib/icons'
import {ListItems} from 'view/com/lists/ListItems' import {ListItems} from 'view/com/lists/ListItems'
import {logger} from '#/logger'
const SECTION_TITLES_CURATE = ['Posts', 'About'] const SECTION_TITLES_CURATE = ['Posts', 'About']
const SECTION_TITLES_MOD = ['About'] const SECTION_TITLES_MOD = ['About']
@ -272,9 +273,9 @@ const Header = observer(function HeaderImpl({
Haptics.default() Haptics.default()
list.togglePin().catch(e => { list.togglePin().catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to toggle pinned list', {error: e}) logger.error('Failed to toggle pinned list', {error: e})
}) })
}, [store, list]) }, [list])
const onSubscribeMute = useCallback(() => { const onSubscribeMute = useCallback(() => {
store.shell.openModal({ store.shell.openModal({

View File

@ -26,6 +26,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import * as Toast from 'view/com/util/Toast' import * as Toast from 'view/com/util/Toast'
import {Haptics} from 'lib/haptics' import {Haptics} from 'lib/haptics'
import {TextLink} from 'view/com/util/Link' import {TextLink} from 'view/com/util/Link'
import {logger} from '#/logger'
const HITSLOP_TOP = { const HITSLOP_TOP = {
top: 20, top: 20,
@ -159,31 +160,30 @@ const ListItem = observer(function ListItemImpl({
item: FeedSourceModel item: FeedSourceModel
}) { }) {
const pal = usePalette('default') const pal = usePalette('default')
const store = useStores()
const isPinned = item.isPinned const isPinned = item.isPinned
const onTogglePinned = useCallback(() => { const onTogglePinned = useCallback(() => {
Haptics.default() Haptics.default()
item.togglePin().catch(e => { item.togglePin().catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to toggle pinned feed', {error: e}) logger.error('Failed to toggle pinned feed', {error: e})
}) })
}, [item, store]) }, [item])
const onPressUp = useCallback( const onPressUp = useCallback(
() => () =>
savedFeeds.movePinnedFeed(item, 'up').catch(e => { savedFeeds.movePinnedFeed(item, 'up').catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to set pinned feed order', {error: e}) logger.error('Failed to set pinned feed order', {error: e})
}), }),
[store, savedFeeds, item], [savedFeeds, item],
) )
const onPressDown = useCallback( const onPressDown = useCallback(
() => () =>
savedFeeds.movePinnedFeed(item, 'down').catch(e => { savedFeeds.movePinnedFeed(item, 'down').catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to set pinned feed order', {error: e}) logger.error('Failed to set pinned feed order', {error: e})
}), }),
[store, savedFeeds, item], [savedFeeds, item],
) )
return ( return (

View File

@ -45,6 +45,7 @@ import {formatCount} from 'view/com/util/numeric/format'
import Clipboard from '@react-native-clipboard/clipboard' import Clipboard from '@react-native-clipboard/clipboard'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn' import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn'
import {logger} from '#/logger'
// TEMPORARY (APP-700) // TEMPORARY (APP-700)
// remove after backend testing finishes // remove after backend testing finishes
@ -110,10 +111,9 @@ export const SettingsScreen = withAuthRequired(
Toast.show('Your handle has been updated') Toast.show('Your handle has been updated')
}, },
err => { err => {
store.log.error( logger.error('Failed to reload from server after handle update', {
'Failed to reload from server after handle update', error: err,
{error: err}, })
)
setIsSwitching(false) setIsSwitching(false)
}, },
) )