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 {sha256} from 'js-sha256'
import {ScreenEvent, TrackEvent} from './types'
import {logger} from '#/logger'
const segmentClient = createClient({
writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI',
@ -54,9 +55,9 @@ export function init(store: RootStoreModel) {
if (sess.did) {
const did_hashed = sha256(sess.did)
segmentClient.identify(did_hashed, {did_hashed})
store.log.debug('Ping w/hash')
logger.debug('Ping w/hash')
} else {
store.log.debug('Ping w/o hash')
logger.debug('Ping w/o hash')
segmentClient.identify()
}
}
@ -68,19 +69,19 @@ export function init(store: RootStoreModel) {
// -prf
segmentClient.isReady.onChange(() => {
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
}
const context = segmentClient.context.get()
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
}
const oldAppInfo = store.appInfo
const newAppInfo = context.app as AppInfo
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 (store.session.hasSession) {

View File

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

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@ import {RootStoreModel} from '../../state'
import {resetToTab} from '../../Navigation'
import {devicePlatform, isIOS} from 'platform/detection'
import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
const SERVICE_DID = (serviceUrl?: string) =>
serviceUrl?.includes('staging')
@ -29,19 +30,27 @@ export function init(store: RootStoreModel) {
token: token.data,
appId: 'xyz.blueskyweb.app',
})
store.log.debug('Notifications: Sent push token (init)', {
tokenType: token.type,
token: token.data,
})
logger.debug(
'Notifications: Sent push token (init)',
{
tokenType: token.type,
token: token.data,
},
logger.DebugContext.notifications,
)
} 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
// 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}) => {
store.log.debug('Notifications: Push token changed', {t, tokenType: type})
logger.debug(
'Notifications: Push token changed',
{t, tokenType: type},
logger.DebugContext.notifications,
)
if (t) {
try {
await store.agent.api.app.bsky.notification.registerPush({
@ -50,12 +59,16 @@ export function init(store: RootStoreModel) {
token: t,
appId: 'xyz.blueskyweb.app',
})
store.log.debug('Notifications: Sent push token (event)', {
tokenType: type,
token: t,
})
logger.debug(
'Notifications: Sent push token (event)',
{
tokenType: type,
token: t,
},
logger.DebugContext.notifications,
)
} 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
Notifications.addNotificationReceivedListener(event => {
store.log.debug('Notifications: received', {event})
logger.debug(
'Notifications: received',
{event},
logger.DebugContext.notifications,
)
if (event.request.trigger.type === 'push') {
// refresh notifications in the background
store.me.notifications.syncQueue()
@ -75,7 +92,11 @@ export function init(store: RootStoreModel) {
// TODO: handle android payload deeplink
}
if (payload) {
store.log.debug('Notifications: received payload', payload)
logger.debug(
'Notifications: received payload',
payload,
logger.DebugContext.notifications,
)
// TODO: deeplink notif here
}
}
@ -84,14 +105,20 @@ export function init(store: RootStoreModel) {
// handle notifications that are tapped on
const sub = Notifications.addNotificationResponseReceivedListener(
response => {
store.log.debug('Notifications: response received', {
actionIdentifier: response.actionIdentifier,
})
logger.debug(
'Notifications: response received',
{
actionIdentifier: response.actionIdentifier,
},
logger.DebugContext.notifications,
)
if (
response.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER
) {
store.log.debug(
logger.debug(
'User pressed a notification, opening notifications tab',
{},
logger.DebugContext.notifications,
)
track('Notificatons:OpenApp')
store.me.notifications.refresh() // refresh notifications

View File

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

View File

@ -4,6 +4,7 @@ import {BskyAgent} from '@atproto/api'
import {RootStoreModel} from './models/root-store'
import * as apiPolyfill from 'lib/api/api-polyfill'
import * as storage from 'lib/storage'
import {logger} from '#/logger'
export const LOCAL_DEV_SERVICE =
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}))
try {
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)
} 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()

View File

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

View File

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

View File

@ -11,6 +11,7 @@ import * as apilib from 'lib/api/index'
import {cleanError} from 'lib/strings/errors'
import {ThreadViewPreference} from '../ui/preferences'
import {PostThreadItemModel} from './post-thread-item'
import {logger} from '#/logger'
export class PostThreadModel {
// state
@ -163,7 +164,7 @@ export class PostThreadModel {
this.hasLoaded = true
this.error = cleanError(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
}

View File

@ -15,6 +15,7 @@ import {cleanError} from 'lib/strings/errors'
import {FollowState} from '../cache/my-follows'
import {Image as RNImage} from 'react-native-image-crop-picker'
import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export class ProfileViewerModel {
muted?: boolean
@ -235,7 +236,7 @@ export class ProfileModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source'
import {logger} from '#/logger'
const DEFAULT_LIMIT = 50
@ -120,7 +121,7 @@ export class FeedsDiscoveryModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -144,7 +145,7 @@ export class SuggestedActorsModel {
this.hasLoaded = true
this.error = cleanError(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 {PostThreadModel} from '../content/post-thread'
import {cleanError} from 'lib/strings/errors'
import {logger} from '#/logger'
const GROUPABLE_REASONS = ['like', 'repost', 'follow']
const PAGE_SIZE = 30
@ -210,7 +211,7 @@ export class NotificationsFeedItemModel {
if (valid.success) {
return v
} else {
this.rootStore.log.warn('Received an invalid record', {
logger.warn('Received an invalid record', {
record: v,
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',
{record: v},
)
@ -319,7 +320,7 @@ export class NotificationsFeedModel {
* Nuke all data
*/
clear() {
this.rootStore.log.debug('NotificationsModel:clear')
logger.debug('NotificationsModel:clear')
this.isLoading = false
this.isRefreshing = false
this.hasLoaded = false
@ -336,7 +337,7 @@ export class NotificationsFeedModel {
* Load for first render
*/
setup = bundleAsync(async (isRefreshing: boolean = false) => {
this.rootStore.log.debug('NotificationsModel:refresh', {isRefreshing})
logger.debug('NotificationsModel:refresh', {isRefreshing})
await this.lock.acquireAsync()
try {
this._xLoading(isRefreshing)
@ -368,7 +369,7 @@ export class NotificationsFeedModel {
* Sync the next set of notifications to show
*/
syncQueue = bundleAsync(async () => {
this.rootStore.log.debug('NotificationsModel:syncQueue')
logger.debug('NotificationsModel:syncQueue')
if (this.unreadCount >= MAX_VISIBLE_NOTIFS) {
return // no need to check
}
@ -401,7 +402,7 @@ export class NotificationsFeedModel {
this._setQueued(this._filterNotifications(queueModels))
this._countUnread()
} catch (e) {
this.rootStore.log.error('NotificationsModel:syncQueue failed', {
logger.error('NotificationsModel:syncQueue failed', {
error: e,
})
} finally {
@ -463,10 +464,7 @@ export class NotificationsFeedModel {
}
}
await Promise.all(promises).catch(e => {
this.rootStore.log.error(
'Uncaught failure during notifications update()',
e,
)
logger.error('Uncaught failure during notifications update()', e)
})
}
@ -483,7 +481,7 @@ export class NotificationsFeedModel {
this.lastSync ? this.lastSync.toISOString() : undefined,
)
} catch (e: any) {
this.rootStore.log.warn('Failed to update notifications read state', {
logger.warn('Failed to update notifications read state', {
error: e,
})
}
@ -505,10 +503,10 @@ export class NotificationsFeedModel {
this.error = cleanError(error)
this.loadMoreError = cleanError(loadMoreError)
if (error) {
this.rootStore.log.error('Failed to fetch notifications', {error})
logger.error('Failed to fetch notifications', {error})
}
if (loadMoreError) {
this.rootStore.log.error('Failed to load more notifications', {
logger.error('Failed to load more notifications', {
error: loadMoreError,
})
}

View File

@ -10,6 +10,7 @@ import {RootStoreModel} from '../root-store'
import {updateDataOptimistically} from 'lib/async/revertible'
import {track} from 'lib/analytics/analytics'
import {hackAddDeletedEmbed} from 'lib/api/hack-add-deleted-embed'
import {logger} from '#/logger'
type FeedViewPost = AppBskyFeedDefs.FeedViewPost
type ReasonRepost = AppBskyFeedDefs.ReasonRepost
@ -42,14 +43,14 @@ export class PostsFeedItemModel {
} else {
this.postRecord = 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,
})
}
} else {
this.postRecord = undefined
this.richText = undefined
rootStore.log.warn(
logger.warn(
'app.bsky.feed.getTimeline or app.bsky.feed.getAuthorFeed served an unexpected record type',
{record: this.post.record},
)
@ -132,7 +133,7 @@ export class PostsFeedItemModel {
track('Post:Like')
}
} 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')
}
} 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')
}
} 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)
this.rootStore.emitPostDeleted(this.post.uri)
} catch (error) {
this.rootStore.log.error('Failed to delete post', {error})
logger.error('Failed to delete post', {error})
} finally {
track('Post:Delete')
}

View File

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

View File

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

View File

@ -4,6 +4,7 @@ import {RootStoreModel} from '../root-store'
import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -98,7 +99,7 @@ export class ActorFeedsModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -86,7 +87,7 @@ export class BlockedAccountsModel {
this.hasLoaded = true
this.error = cleanError(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 {bundleAsync} from 'lib/async/bundle'
import * as apilib from 'lib/api/index'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -97,7 +98,7 @@ export class LikesModel {
this.hasLoaded = true
this.error = cleanError(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 {bundleAsync} from 'lib/async/bundle'
import {accumulate} from 'lib/async/accumulate'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -204,10 +205,10 @@ export class ListsListModel {
this.error = cleanError(err)
this.loadMoreError = cleanError(loadMoreErr)
if (err) {
this.rootStore.log.error('Failed to fetch user lists', {error: err})
logger.error('Failed to fetch user lists', {error: err})
}
if (loadMoreErr) {
this.rootStore.log.error('Failed to fetch user lists', {
logger.error('Failed to fetch user lists', {
error: loadMoreErr,
})
}

View File

@ -6,6 +6,7 @@ import {
import {RootStoreModel} from '../root-store'
import {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -86,7 +87,7 @@ export class MutedAccountsModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import * as apilib from 'lib/api/index'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -100,7 +101,7 @@ export class RepostedByModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -99,7 +100,7 @@ export class UserFollowersModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {bundleAsync} from 'lib/async/bundle'
import {logger} from '#/logger'
const PAGE_SIZE = 30
@ -99,7 +100,7 @@ export class UserFollowsModel {
this.hasLoaded = true
this.error = cleanError(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 {MyFollowsCache} from './cache/my-follows'
import {isObj, hasProp} from 'lib/type-guards'
import {logger} from '#/logger'
const PROFILE_UPDATE_INTERVAL = 10 * 60 * 1e3 // 10min
const NOTIFS_UPDATE_INTERVAL = 30 * 1e3 // 30sec
@ -104,21 +105,21 @@ export class MeModel {
async load() {
const sess = this.rootStore.session
this.rootStore.log.debug('MeModel:load', {hasSession: sess.hasSession})
logger.debug('MeModel:load', {hasSession: sess.hasSession})
if (sess.hasSession) {
this.did = sess.currentSession?.did || ''
await this.fetchProfile()
this.mainFeed.clear()
/* 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 => {
this.rootStore.log.error('Failed to setup notifications model', {
logger.error('Failed to setup notifications model', {
error: 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,
})
})
@ -134,7 +135,7 @@ export class MeModel {
async updateIfNeeded() {
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()
await this.fetchProfile()
await this.fetchInviteCodes()
@ -188,7 +189,7 @@ export class MeModel {
})
})
} catch (e) {
this.rootStore.log.error('Failed to fetch user invite codes', {
logger.error('Failed to fetch user invite codes', {
error: e,
})
}
@ -205,7 +206,7 @@ export class MeModel {
this.appPasswords = res.data.passwords
})
} catch (e) {
this.rootStore.log.error('Failed to fetch user app passwords', {
logger.error('Failed to fetch user app passwords', {
error: e,
})
}
@ -228,7 +229,7 @@ export class MeModel {
})
return res.data
} 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)
})
} 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 {Dimensions} from 'lib/media/types'
import {isIOS} from 'platform/detection'
import {logger} from '#/logger'
export interface ImageManipulationAttributes {
aspectRatio?: '4:3' | '1:1' | '3:4' | 'None'
@ -188,7 +189,7 @@ export class ImageModel implements Omit<RNImage, 'size'> {
this.cropped = cropped
})
} 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 {
agent: BskyAgent
appInfo?: AppInfo
log = logger
session = new SessionModel(this)
shell = new ShellUiModel(this)
preferences = new PreferencesModel(this)
@ -122,15 +121,15 @@ export class RootStoreModel {
* Called during init to resume any stored session.
*/
async attemptSessionResumption() {
this.log.debug('RootStoreModel:attemptSessionResumption')
logger.debug('RootStoreModel:attemptSessionResumption')
try {
await this.session.attemptSessionResumption()
this.log.debug('Session initialized', {
logger.debug('Session initialized', {
hasSession: this.session.hasSession,
})
this.updateSessionState()
} 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,
{hadSession}: {hadSession: boolean},
) {
this.log.debug('RootStoreModel:handleSessionChange')
logger.debug('RootStoreModel:handleSessionChange')
this.agent = agent
applyDebugHeader(this.agent)
this.me.clear()
@ -157,7 +156,7 @@ export class RootStoreModel {
* Called by the session model. Handles session drops by informing the user.
*/
async handleSessionDrop() {
this.log.debug('RootStoreModel:handleSessionDrop')
logger.debug('RootStoreModel:handleSessionDrop')
resetToTab('HomeTab')
this.me.clear()
this.emitSessionDropped()
@ -167,7 +166,7 @@ export class RootStoreModel {
* Clears all session-oriented state.
*/
clearAllSessionState() {
this.log.debug('RootStoreModel:clearAllSessionState')
logger.debug('RootStoreModel:clearAllSessionState')
this.session.clear()
resetToTab('HomeTab')
this.me.clear()
@ -184,7 +183,7 @@ export class RootStoreModel {
await this.me.updateIfNeeded()
await this.preferences.sync()
} 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 {IS_PROD} from 'lib/constants'
import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export type ServiceDescription = DescribeServer.OutputSchema
@ -56,7 +57,7 @@ export class SessionModel {
),
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 {getAge} from 'lib/strings/time'
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
@ -76,7 +77,7 @@ export class CreateAccountModel {
this.setServiceDescription(desc)
this.setUserDomain(desc.availableUserDomains[0])
} catch (err: any) {
this.rootStore.log.warn(
logger.warn(
`Failed to fetch service description for ${this.serviceUrl}`,
{error: err},
)
@ -127,7 +128,7 @@ export class CreateAccountModel {
errMsg =
'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.setError(cleanError(errMsg))
throw e

View File

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

View File

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

View File

@ -4,6 +4,7 @@ import {bundleAsync} from 'lib/async/bundle'
import {cleanError} from 'lib/strings/errors'
import {FeedSourceModel} from '../content/feed-source'
import {track} from 'lib/analytics/analytics'
import {logger} from '#/logger'
export class SavedFeedsModel {
// state
@ -126,7 +127,7 @@ export class SavedFeedsModel {
this.hasLoaded = true
this.error = cleanError(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 {cleanError} from 'lib/strings/errors'
import {isWeb} from 'platform/detection'
import {logger} from '#/logger'
enum Forms {
Login,
@ -81,10 +82,9 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
if (aborted) {
return
}
store.log.warn(
`Failed to fetch service description for ${serviceUrl}`,
{error: err},
)
logger.warn(`Failed to fetch service description for ${serviceUrl}`, {
error: err,
})
setError(
'Unable to contact your service. Please check your Internet connection.',
)
@ -93,7 +93,7 @@ export const Login = ({onPressBack}: {onPressBack: () => void}) => {
return () => {
aborted = true
}
}, [store.session, store.log, serviceUrl, retryDescribeTrigger])
}, [store.session, serviceUrl, retryDescribeTrigger])
const onPressRetryConnect = () => setRetryDescribeTrigger({})
const onPressForgotPassword = () => {
@ -349,7 +349,7 @@ const LoginForm = ({
})
} catch (e: any) {
const errMsg = e.toString()
store.log.warn('Failed to login', {error: e})
logger.warn('Failed to login', {error: e})
setIsProcessing(false)
if (errMsg.includes('Authentication Required')) {
setError('Invalid username or password')
@ -578,7 +578,7 @@ const ForgotPasswordForm = ({
onEmailSent()
} catch (e: any) {
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)
if (isNetworkError(e)) {
setError(
@ -694,7 +694,6 @@ const ForgotPasswordForm = ({
}
const SetNewPasswordForm = ({
store,
error,
serviceUrl,
setError,
@ -734,7 +733,7 @@ const SetNewPasswordForm = ({
onPasswordSet()
} catch (e: any) {
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)
if (isNetworkError(e)) {
setError(

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ import {pluralize} from 'lib/strings/helpers'
import {AtUri} from '@atproto/api'
import * as Toast from 'view/com/util/Toast'
import {sanitizeHandle} from 'lib/strings/handles'
import {logger} from '#/logger'
export const FeedSourceCard = observer(function FeedSourceCardImpl({
item,
@ -45,7 +46,7 @@ export const FeedSourceCard = observer(function FeedSourceCardImpl({
Toast.show('Removed from my feeds')
} catch (e) {
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')
} catch (e) {
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])

View File

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

View File

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

View File

@ -12,6 +12,7 @@ import {
} from '@fortawesome/react-native-fontawesome'
import Clipboard from '@react-native-clipboard/clipboard'
import * as Toast from '../util/Toast'
import {logger} from '#/logger'
export const snapPoints = ['70%']
@ -95,7 +96,7 @@ export function Component({}: {}) {
}
} catch (e) {
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 {useAnalytics} from 'lib/analytics/analytics'
import {cleanError} from 'lib/strings/errors'
import {logger} from '#/logger'
export const snapPoints = ['100%']
@ -65,7 +66,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
return
}
setProcessing(false)
store.log.warn(
logger.warn(
`Failed to fetch service description for ${String(
store.agent.service,
)}`,
@ -79,7 +80,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
return () => {
aborted = true
}
}, [store.agent.service, store.session, store.log, retryDescribeTrigger])
}, [store.agent.service, store.session, retryDescribeTrigger])
// events
// =
@ -105,7 +106,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
try {
track('EditHandle:SetNewHandle')
const newHandle = isCustom ? handle : createFullHandle(handle, userDomain)
store.log.debug(`Updating handle to ${newHandle}`)
logger.debug(`Updating handle to ${newHandle}`)
await store.agent.updateHandle({
handle: newHandle,
})
@ -113,7 +114,7 @@ export function Component({onChanged}: {onChanged: () => void}) {
onChanged()
} catch (err: any) {
setError(cleanError(err))
store.log.error('Failed to update handle', {handle, error: err})
logger.error('Failed to update handle', {handle, error: err})
} finally {
setProcessing(false)
}
@ -343,7 +344,7 @@ function CustomHandleForm({
}
} catch (err: any) {
setError(cleanError(err))
store.log.error('Failed to verify domain', {handle, error: err})
logger.error('Failed to verify domain', {handle, error: err})
} finally {
setIsVerifying(false)
}
@ -355,7 +356,6 @@ function CustomHandleForm({
setError,
canSave,
onPressSave,
store.log,
store.agent,
])

View File

@ -15,6 +15,7 @@ import {CONFIGURABLE_LABEL_GROUPS} from 'lib/labeling/const'
import {isIOS} from 'platform/detection'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import * as Toast from '../util/Toast'
import {logger} from '#/logger'
export const snapPoints = ['90%']
@ -103,7 +104,7 @@ const AdultContentEnabledPref = observer(
Toast.show(
'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(
'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],

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,6 +10,7 @@ import {usePalette} from 'lib/hooks/usePalette'
import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from 'lib/routes/types'
import {useStores} from 'state/index'
import {logger} from '#/logger'
const MESSAGES = {
[KnownError.Unknown]: '',
@ -73,7 +74,7 @@ function FeedgenErrorMessage({
Toast.show(
'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() {

View File

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

View File

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

View File

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

View File

@ -39,6 +39,7 @@ import {isInvalidHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {Link} from '../util/Link'
import {ProfileHeaderSuggestedFollows} from './ProfileHeaderSuggestedFollows'
import {logger} from '#/logger'
interface Props {
view: ProfileModel
@ -150,9 +151,9 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
: '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(() => {
track('ProfileHeader:EditProfileButtonClicked')
@ -193,10 +194,10 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
await view.muteAccount()
Toast.show('Account muted')
} 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()}`)
}
}, [track, view, store])
}, [track, view])
const onPressUnmuteAccount = React.useCallback(async () => {
track('ProfileHeader:UnmuteAccountButtonClicked')
@ -204,10 +205,10 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
await view.unmuteAccount()
Toast.show('Account unmuted')
} 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()}`)
}
}, [track, view, store])
}, [track, view])
const onPressBlockAccount = React.useCallback(async () => {
track('ProfileHeader:BlockAccountButtonClicked')
@ -222,7 +223,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
onRefreshAll()
Toast.show('Account blocked')
} 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()}`)
}
},
@ -242,7 +243,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoadedImpl({
onRefreshAll()
Toast.show('Account unblocked')
} 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()}`)
}
},

View File

@ -21,6 +21,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views'
import {ProfileCard} from 'view/com/profile/ProfileCard'
import {logger} from '#/logger'
type Props = NativeStackScreenProps<
CommonNavigatorParams,
@ -52,9 +53,9 @@ export const ModerationBlockedAccounts = withAuthRequired(
blockedAccounts
.loadMore()
.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 = ({
item,

View File

@ -21,6 +21,7 @@ import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views'
import {ProfileCard} from 'view/com/profile/ProfileCard'
import {logger} from '#/logger'
type Props = NativeStackScreenProps<
CommonNavigatorParams,
@ -49,9 +50,9 @@ export const ModerationMutedAccounts = withAuthRequired(
mutedAccounts
.loadMore()
.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 = ({
item,

View File

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

View File

@ -14,6 +14,7 @@ import {s} from 'lib/styles'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {clamp} from 'lodash'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {logger} from '#/logger'
const SHELL_FOOTER_HEIGHT = 44
@ -38,7 +39,7 @@ export const PostThreadScreen = withAuthRequired(
InteractionManager.runAfterInteractions(() => {
if (!view.hasLoaded && !view.isLoading) {
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 {useSetTitle} from 'lib/hooks/useSetTitle'
import {combinedDisplayName} from 'lib/strings/display-names'
import {logger} from '#/logger'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
export const ProfileScreen = withAuthRequired(
@ -108,16 +109,16 @@ export const ProfileScreen = withAuthRequired(
uiState
.refresh()
.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(() => {
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,
}),
)
}, [uiState, store])
}, [uiState])
const onPressTryAgain = React.useCallback(() => {
uiState.setup()
}, [uiState])

View File

@ -40,6 +40,7 @@ import {NavigationProp} from 'lib/routes/types'
import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links'
import {ComposeIcon2} from 'lib/icons'
import {logger} from '#/logger'
const SECTION_TITLES = ['Posts', 'About']
@ -165,9 +166,9 @@ export const ProfileFeedScreenInner = observer(
Toast.show(
'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 () => {
Haptics.default()
@ -181,19 +182,19 @@ export const ProfileFeedScreenInner = observer(
Toast.show(
'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 () => {
Haptics.default()
if (feedInfo) {
feedInfo.togglePin().catch(e => {
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 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 {ComposeIcon2} from 'lib/icons'
import {ListItems} from 'view/com/lists/ListItems'
import {logger} from '#/logger'
const SECTION_TITLES_CURATE = ['Posts', 'About']
const SECTION_TITLES_MOD = ['About']
@ -272,9 +273,9 @@ const Header = observer(function HeaderImpl({
Haptics.default()
list.togglePin().catch(e => {
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(() => {
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 {Haptics} from 'lib/haptics'
import {TextLink} from 'view/com/util/Link'
import {logger} from '#/logger'
const HITSLOP_TOP = {
top: 20,
@ -159,31 +160,30 @@ const ListItem = observer(function ListItemImpl({
item: FeedSourceModel
}) {
const pal = usePalette('default')
const store = useStores()
const isPinned = item.isPinned
const onTogglePinned = useCallback(() => {
Haptics.default()
item.togglePin().catch(e => {
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(
() =>
savedFeeds.movePinnedFeed(item, 'up').catch(e => {
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(
() =>
savedFeeds.movePinnedFeed(item, 'down').catch(e => {
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 (

View File

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