commit
95b5e642dc
|
@ -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) {
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
|
@ -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(
|
||||||
|
'Notifications: Sent push token (init)',
|
||||||
|
{
|
||||||
tokenType: token.type,
|
tokenType: token.type,
|
||||||
token: token.data,
|
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(
|
||||||
|
'Notifications: Sent push token (event)',
|
||||||
|
{
|
||||||
tokenType: type,
|
tokenType: type,
|
||||||
token: t,
|
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(
|
||||||
|
'Notifications: response received',
|
||||||
|
{
|
||||||
actionIdentifier: response.actionIdentifier,
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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()}`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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}`)
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue