Better empty state for the following tabs

This commit is contained in:
Jackson Harper 2024-01-02 16:18:01 +08:00
parent b81d2a33b6
commit c6517ebb8e
23 changed files with 354 additions and 142 deletions

View file

@ -0,0 +1,70 @@
// swiftlint:disable line_length
import Foundation
import Models
import Services
import SwiftUI
import Views
public struct FollowingViewModal: View {
@Environment(\.dismiss) private var dismiss
let message: String = """
We've created a new place for all your newsletters and feeds called Following. You can control the destination of
new items by changing the destination for your subscriptions in the Subscriptions view of your settings. By default
your existing newsletters will go into your library and your existing feeds will go into Following.
From the library you can swipe items left to right to move them into your library. In the reader view you can tap the
bookmark icon on the toolbar to move items into your library.
If you don't need the following tab you can disable it from the filters view in your settings.
- [Learn more about the following](https://docs.omnivore.app/using/following.html)
- [Tell your friends about Omnivore](https://omnivore.app/about)
"""
var closeButton: some View {
Button(action: {
dismiss()
}, label: {
ZStack {
Circle()
.foregroundColor(Color.circleButtonBackground)
.frame(width: 30, height: 30)
Image(systemName: "xmark")
.resizable(resizingMode: Image.ResizingMode.stretch)
.foregroundColor(Color.circleButtonForeground)
.aspectRatio(contentMode: .fit)
.font(Font.title.weight(.bold))
.frame(width: 12, height: 12)
}
})
}
public var body: some View {
HStack {
Text("Your new Following tab")
.font(Font.system(size: 20, weight: .bold))
Spacer()
closeButton
}
.padding(.top, 16)
.padding(.horizontal, 16)
List {
Section {
let parsedMessage = try? AttributedString(markdown: message,
options: .init(interpretedSyntax: .inlineOnly))
Text(parsedMessage ?? "")
.multilineTextAlignment(.leading)
.foregroundColor(Color.appGrayTextContrast)
.accentColor(.blue)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 16)
}
}
}
}

View file

@ -79,30 +79,73 @@ struct FiltersHeader: View {
struct EmptyState: View {
@ObservedObject var viewModel: HomeFeedViewModel
@EnvironmentObject var dataService: DataService
@State var showSendNewslettersAlert = false
var followingEmptyState: some View {
VStack(alignment: .center, spacing: 20) {
if viewModel.stopUsingFollowingPrimer {
VStack(spacing: 10) {
Image.relaxedSlothLight
Text("You are all caught up.").foregroundColor(Color.extensionTextSubtle)
Button(action: {
Task {
await viewModel.loadItems(dataService: dataService, isRefresh: true)
}
}, label: { Text("Refresh").bold() })
.foregroundColor(Color.blue)
}
} else {
Text("You don't have any Feed items.")
.font(Font.system(size: 18, weight: .bold))
Text("Add an RSS/Atom feed")
.foregroundColor(Color.blue)
.onTapGesture {
viewModel.showAddFeedView = true
}
Text("Send your newsletters to following")
.foregroundColor(Color.blue)
.onTapGesture {
showSendNewslettersAlert = true
}
Text("Hide the Following tab")
.foregroundColor(Color.blue)
.onTapGesture {
viewModel.showHideFollowingAlert = true
}
}
}
.frame(minHeight: 400)
.frame(maxWidth: .infinity)
.padding()
.alert("Update newsletter destination", isPresented: $showSendNewslettersAlert, actions: {
Button(action: {
Task {
await viewModel.modifyingNewsletterDestinationToFollowing(dataService: dataService)
}
}, label: { Text("OK") })
Button(LocalText.cancelGeneric, role: .cancel) { showSendNewslettersAlert = false }
}, message: {
// swiftlint:disable:next line_length
Text("Your email address destination folders will be modified to send to this tab.\n\nAll new newsletters will appear here. You can modify the destination for each individual email address and subscription in your settings.")
})
}
var body: some View {
if viewModel.currentFolder == "following" {
if viewModel.isModifyingNewsletterDestination {
return AnyView(
VStack(alignment: .center, spacing: 20) {
Text("You don't have any Feed items.")
.font(Font.system(size: 18, weight: .bold))
Text("Add an RSS/Atom feed")
.foregroundColor(Color.blue)
.onTapGesture {
viewModel.showAddFeedView = true
}
Text("Hide the Following tab")
.foregroundColor(Color.blue)
.onTapGesture {
viewModel.showHideFollowingAlert = true
}
}
.frame(minHeight: 400)
.frame(maxWidth: .infinity)
.padding()
VStack {
Text("Modifying newsletter destinations...")
ProgressView()
}.frame(maxWidth: .infinity, maxHeight: .infinity)
)
} else if viewModel.currentFolder == "following" {
return AnyView(followingEmptyState)
} else {
return AnyView(Group {
Spacer()
@ -293,6 +336,11 @@ struct AnimatingCellHeight: AnimatableModifier {
if viewModel.appliedFilter == nil {
viewModel.setDefaultFilter()
}
// Once the user has seen at least one following item we stop displaying the
// initial help view
if viewModel.currentFolder == "following", viewModel.fetcher.items.count > 0 {
viewModel.stopUsingFollowingPrimer = true
}
}
.environment(\.editMode, self.$isEditMode)
.navigationBarTitleDisplayMode(.inline)

View file

@ -37,7 +37,10 @@ import Views
@State var lastMoreFetched: Date?
@State var lastFiltersFetched: Date?
@State var isModifyingNewsletterDestination = false
@AppStorage(UserDefaultKey.hideFeatureSection.rawValue) var hideFeatureSection = false
@AppStorage(UserDefaultKey.stopUsingFollowingPrimer.rawValue) var stopUsingFollowingPrimer = false
@AppStorage("LibraryTabView::hideFollowingTab") var hideFollowingTab = false
@Published var appliedFilter: InternalFilter? {
@ -325,4 +328,34 @@ import Views
func findFilter(_: DataService, named: String) -> InternalFilter? {
filters.first(where: { $0.name == named })
}
func modifyingNewsletterDestinationToFollowing(dataService: DataService) async {
isModifyingNewsletterDestination = true
do {
var errorCount = 0
let objectIDs = try await dataService.newsletterEmails()
let newsletters = await dataService.viewContext.perform {
let newsletters = objectIDs.compactMap { dataService.viewContext.object(with: $0) as? NewsletterEmail }
return newsletters
}
for newsletter in newsletters {
if let emailId = newsletter.emailId, newsletter.folder != "following" {
do {
try await dataService.updateNewsletterEmail(emailID: emailId, folder: "following")
} catch {
print("error updating newsletter: ", error)
errorCount += 1
}
}
}
if errorCount > 0 {
snackbar("There was an error modifying \(errorCount) of your emails")
} else {
snackbar("Email destination modified")
}
} catch {
snackbar("Error modifying emails")
}
}
}

View file

@ -21,9 +21,6 @@ struct LibraryTabView: View {
@AppStorage("LibraryTabView::hideFollowingTab") var hideFollowingTab = false
@AppStorage(UserDefaultKey.lastSelectedTabItem.rawValue) var selectedTab = "inbox"
@AppStorage(UserDefaultKey.followingPrimerDisplayed.rawValue) var followingPrimerDisplayed = false
@State var showFollowingPrimer = false
@State var showExpandedAudioPlayer = false
private let syncManager = LibrarySyncManager()
@ -74,14 +71,6 @@ struct LibraryTabView: View {
var body: some View {
VStack(spacing: 0) {
if showFollowingPrimer {
PresentationLink(transition: UIDevice.isIPad ? .popover : .sheet(detents: [.medium]), isPresented: $showFollowingPrimer) {
FollowingViewModal()
} label: {
EmptyView()
}
}
TabView(selection: $selectedTab) {
if !hideFollowingTab {
NavigationView {

View file

@ -28,7 +28,7 @@ public enum UserDefaultKey: String {
case recentSearchTerms
case audioPlayerExpanded
case themeName
case followingPrimerDisplayed
case stopUsingFollowingPrimer
case notificationsEnabled
case deviceTokenID
case userWordsPerMinute

View file

@ -30,6 +30,10 @@ public extension Image {
static var readerSettings: Image { Image("reader-settings", bundle: .module) }
static var utilityMenu: Image { Image("utility-menu", bundle: .module) }
static var relaxedSlothLight: Image {
Color.isDarkMode ? Image("relaxed-sloth-dark", bundle: .module) : Image("relaxed-sloth-light", bundle: .module)
}
static var addLink: Image { Image("add-link", bundle: .module) }
static var selectMultiple: Image { Image("select-multiple", bundle: .module) }
static var magnifyingGlass: Image { Image("magnifying-glass", bundle: .module) }

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "relaxed-sloth-dark.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "sloth 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "sloth 2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "sloth 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "sloth 2.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "sloth 3.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -39,8 +39,8 @@
"@opentelemetry/tracing": "^0.24.0",
"@sendgrid/mail": "^7.6.0",
"@sentry/integrations": "^7.10.0",
"@sentry/node": "^5.26.0",
"@sentry/tracing": "^7.9.0",
"@sentry/node": "^6.10.0",
"@sentry/tracing": "^7.10.0",
"addressparser": "^1.0.1",
"analytics-node": "^6.0.0",
"apollo-datasource": "^3.3.1",
@ -151,4 +151,4 @@
"volta": {
"extends": "../../package.json"
}
}
}

View file

@ -102,7 +102,7 @@ export function makeApolloServer(): ApolloServer {
context: contextFunc,
formatError: (err) => {
logger.info('server error', err)
Sentry.captureException(err)
// Sentry.captureException(err)
// hide error messages from frontend on prod
return new Error('Unexpected server error')
},

View file

@ -2,18 +2,18 @@ import { env } from './env'
import * as Sentry from '@sentry/node'
import { CaptureConsole } from '@sentry/integrations'
export const sentryConfig = {
dsn: env.sentry.dsn,
environment: env.server.apiEnv,
// Don't bother collecting and sending events locally (reduces overhead).
enabled: !env.dev.isLocal,
serverName: process.env.GAE_INSTANCE || '',
integrations: [
new Sentry.Integrations.OnUncaughtException(),
new CaptureConsole({ levels: ['error'] }),
],
debug: (env.dev.isLocal && process.env.DEBUG === 'true') || false,
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 0,
}
// export const sentryConfig = {
// dsn: env.sentry.dsn,
// environment: env.server.apiEnv,
// // Don't bother collecting and sending events locally (reduces overhead).
// enabled: !env.dev.isLocal,
// serverName: process.env.GAE_INSTANCE || '',
// integrations: [
// new Sentry.Integrations.OnUncaughtException(),
// new CaptureConsole({ levels: ['error'] }),
// ],
// debug: (env.dev.isLocal && process.env.DEBUG === 'true') || false,
// // We recommend adjusting this value in production, or using tracesSampler
// // for finer control
// tracesSampleRate: 0,
// }

View file

@ -36,7 +36,7 @@ import { userServiceRouter } from './routers/svc/user'
import { webhooksServiceRouter } from './routers/svc/webhooks'
import { textToSpeechRouter } from './routers/text_to_speech'
import { userRouter } from './routers/user_router'
import { sentryConfig } from './sentry'
// import { sentryConfig } from './sentry'
import {
getClaimsByToken,
getTokenByRequest,
@ -56,9 +56,9 @@ export const createApp = (): {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Sentry.init(sentryConfig)
app.use(Sentry.Handlers.requestHandler())
app.use(Sentry.Handlers.tracingHandler())
// Sentry.init(sentryConfig)
// app.use(Sentry.Handlers.requestHandler())
// app.use(Sentry.Handlers.tracingHandler())
app.use(cookieParser())
app.use(json({ limit: '100mb' }))

View file

@ -14,6 +14,7 @@ export type SuggestionAction = {
type SuggestionBoxProps = {
helpMessage: string
suggestions: SuggestionAction[]
isError: boolean
size?: 'large' | 'small'
background?: string
@ -25,6 +26,7 @@ type SuggestionBoxProps = {
type InternalOrExternalLinkProps = {
link: string
children: ReactNode
showArrow: boolean
}
const InternalOrExternalLink = (props: InternalOrExternalLinkProps) => {
@ -40,14 +42,16 @@ const InternalOrExternalLink = (props: InternalOrExternalLinkProps) => {
}}
>
{!isExternal ? (
<Link href={props.link} legacyBehavior>{props.children}</Link>
<Link href={props.link} legacyBehavior>
{props.children}
</Link>
) : (
<a href={props.link} target="_blank" rel="noreferrer">
{props.children}
</a>
)}
</SpanBox>
);
)
}
export const SuggestionBox = (props: SuggestionBoxProps) => {
@ -59,14 +63,13 @@ export const SuggestionBox = (props: SuggestionBoxProps) => {
flexDirection: props.size == 'large' ? 'column' : 'row',
width: 'fit-content',
borderRadius: '5px',
background: props.background ?? '$thBackground3',
fontSize: '15px',
fontSize: '18px',
fontFamily: '$inter',
fontWeight: '500',
color: '$thTextContrast',
color: '$grayText',
px: '15px',
py: props.size == 'large' ? '15px' : '10px',
justifyContent: 'flex-start',
alignItems: 'center',
justifyContent: 'center',
'@smDown': {
flexDirection: 'column',
alignItems: 'center',
@ -74,7 +77,7 @@ export const SuggestionBox = (props: SuggestionBoxProps) => {
},
}}
>
<VStack>
<VStack css={{ alignItems: 'center' }}>
{props.dismissible && (
<SpanBox
css={{
@ -99,12 +102,13 @@ export const SuggestionBox = (props: SuggestionBoxProps) => {
<InternalOrExternalLink
key={`suggestions-${idx}`}
link={suggestion.url}
showArrow={!props.isError}
>
<SpanBox
css={{
display: 'flex',
alignItems: 'center',
color: '$omnivoreCtaYellow',
// color: '$omnivoreCtaYellow',
pt: '15px',
gap: '2px',
'&:hover': {
@ -113,10 +117,12 @@ export const SuggestionBox = (props: SuggestionBoxProps) => {
}}
>
<>{suggestion.text}</>
<ArrowRightIcon
size={25}
color={theme.colors.omnivoreCtaYellow.toString()}
/>
{props.showArrow && (
<ArrowRightIcon
size={25}
color={theme.colors.omnivoreCtaYellow.toString()}
/>
)}
</SpanBox>
</InternalOrExternalLink>
)

View file

@ -3,8 +3,10 @@ import { useMemo } from 'react'
import { LIBRARY_LEFT_MENU_WIDTH } from './LibraryFilterMenu'
import { LayoutType } from './HomeFeedContainer'
import { SuggestionBox, SuggestionAction } from '../../elements/SuggestionBox'
import { ErrorSlothIcon } from '../../elements/icons/ErrorSlothIcon'
type EmptyLibraryProps = {
isError: boolean
searchTerm: string | undefined
onAddLinkClicked: () => void
@ -26,10 +28,14 @@ type MessageType =
type HelpMessageProps = {
type: MessageType
isError: boolean
}
export const ErrorBox = (props: HelpMessageProps) => {
const errorTitle = useMemo(() => {
if (props.isError) {
return 'An error occurred'
}
switch (props.type) {
case 'inbox':
return 'Your inbox is empty. The inbox will contain all your non-archived saved items.'
@ -60,12 +66,10 @@ export const ErrorBox = (props: HelpMessageProps) => {
css={{
width: 'fit-content',
borderRadius: '5px',
background: 'rgba(255, 59, 48, 0.3)',
fontSize: '15px',
fontSize: '25px',
fontFamily: '$inter',
fontWeight: '500',
fontWeight: '700',
color: '$thTextContrast',
py: '10px',
px: '15px',
'@smDown': {
width: '100%',
@ -73,6 +77,7 @@ export const ErrorBox = (props: HelpMessageProps) => {
'@xlgDown': {
justifyContent: 'flex-start',
},
alignItems: 'center',
}}
>
{errorTitle}
@ -87,6 +92,17 @@ type SuggestionMessage = {
export const Suggestion = (props: HelpMessageProps) => {
const helpMessage = useMemo<SuggestionMessage>(() => {
if (props.isError) {
return {
message: 'Something went wrong searching your library',
actions: [
{
text: 'Join our Discord to get help',
url: 'https://discord.gg/h2z5rppzz9',
},
],
}
}
switch (props.type) {
case 'feed':
return {
@ -151,6 +167,7 @@ export const Suggestion = (props: HelpMessageProps) => {
<>
{helpMessage ? (
<SuggestionBox
isError={props.isError}
helpMessage={helpMessage.message}
suggestions={helpMessage.actions}
/>
@ -194,13 +211,16 @@ export const EmptyLibrary = (props: EmptyLibraryProps) => {
<Box
css={{
display: 'inline-flex',
color: '$grayTextContrast',
color: '$thTextSubtle2',
gap: '10px',
pl: '0px',
pt: '30px',
width: '100%',
flexDirection: 'column',
alignItems: 'center',
'@media (max-width: 768px)': {
p: '15px',
},
@ -223,8 +243,9 @@ export const EmptyLibrary = (props: EmptyLibraryProps) => {
},
}}
>
<ErrorBox type={type} />
<Suggestion type={type} />
{props.isError && <ErrorSlothIcon />}
<ErrorBox type={type} isError={props.isError} />
<Suggestion type={type} isError={props.isError} />
</Box>
)
}

View file

@ -111,6 +111,7 @@ export function HomeFeedContainer(): JSX.Element {
size,
setSize,
isValidating,
itemsDataError,
performActionOnItem,
mutate,
} = useGetLibraryItemsQuery(queryInputs)
@ -128,6 +129,12 @@ export function HomeFeedContainer(): JSX.Element {
}
}, [mutate])
useMemo(() => {
if (itemsDataError) {
console.log('search error: ', itemsDataError)
}
}, [itemsDataError])
useEffect(() => {
if (queryValue.startsWith('#')) {
debouncedFetchSearchResults(
@ -854,6 +861,7 @@ export function HomeFeedContainer(): JSX.Element {
hasMore={hasMore}
hasData={!!itemsPages}
totalItems={itemsPages?.[0].search.pageInfo.totalCount || 0}
isError={!!itemsDataError}
isValidating={isValidating}
labelsTarget={labelsTarget}
setLabelsTarget={setLabelsTarget}
@ -888,6 +896,7 @@ type HomeFeedContentProps = {
hasMore: boolean
hasData: boolean
totalItems: number
isError: boolean
isValidating: boolean
loadMore: () => void
labelsTarget: LibraryItem | undefined
@ -1064,6 +1073,7 @@ function LibraryItemsLayout(props: LibraryItemsLayoutProps): JSX.Element {
>
{!props.isValidating && props.items.length == 0 ? (
<EmptyLibrary
isError={props.isError}
layoutType={props.layout}
searchTerm={props.searchTerm}
onAddLinkClicked={() => {

View file

@ -246,6 +246,16 @@ export function useGetLibraryItemsQuery({
},
{ revalidateFirstPage: false }
)
console.log(
'data: ',
data,
'size',
size,
'isValidating',
isValidating,
'error',
error
)
let responseError = error
let responsePages = data as LibraryItemsData[] | undefined

106
yarn.lock
View file

@ -5858,6 +5858,15 @@
"@sentry/types" "7.77.0"
"@sentry/utils" "7.77.0"
"@sentry-internal/tracing@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.91.0.tgz#fbb6e1e3383e1eeee08633384e004da73ac1c37d"
integrity sha512-JH5y6gs6BS0its7WF2DhySu7nkhPDfZcdpAXldxzIlJpqFkuwQKLU5nkYJpiIyZz1NHYYtW5aum2bV2oCOdDRA==
dependencies:
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/browser@7.50.0":
version "7.50.0"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.50.0.tgz#16c995c336322c8aec65570f90f50288678004ec"
@ -5882,17 +5891,6 @@
proxy-from-env "^1.1.0"
which "^2.0.2"
"@sentry/core@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3"
integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==
dependencies:
"@sentry/hub" "5.30.0"
"@sentry/minimal" "5.30.0"
"@sentry/types" "5.30.0"
"@sentry/utils" "5.30.0"
tslib "^1.9.3"
"@sentry/core@7.50.0":
version "7.50.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.50.0.tgz#88bc9cbfc0cb429a28489ece6f0be7a7006436c4"
@ -5910,14 +5908,13 @@
"@sentry/types" "7.77.0"
"@sentry/utils" "7.77.0"
"@sentry/hub@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100"
integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==
"@sentry/core@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.91.0.tgz#229334d7f03dd5d90a17495e61ce4215ab730b2a"
integrity sha512-tu+gYq4JrTdrR+YSh5IVHF0fJi/Pi9y0HZ5H9HnYy+UMcXIotxf6hIEaC6ZKGeLWkGXffz2gKpQLe/g6vy/lPA==
dependencies:
"@sentry/types" "5.30.0"
"@sentry/utils" "5.30.0"
tslib "^1.9.3"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
"@sentry/integrations@7.50.0":
version "7.50.0"
@ -5939,15 +5936,6 @@
"@sentry/utils" "7.77.0"
localforage "^1.8.1"
"@sentry/minimal@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b"
integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==
dependencies:
"@sentry/hub" "5.30.0"
"@sentry/types" "5.30.0"
tslib "^1.9.3"
"@sentry/nextjs@^7.42.0":
version "7.50.0"
resolved "https://registry.yarnpkg.com/@sentry/nextjs/-/nextjs-7.50.0.tgz#b9e7727c8f974644bb84a01f40a0adedb44ec416"
@ -5991,20 +5979,16 @@
"@sentry/utils" "7.77.0"
https-proxy-agent "^5.0.0"
"@sentry/node@^5.26.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48"
integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==
"@sentry/node@^7.10.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.91.0.tgz#26bf13c3daf988f9725afd1a3cc38ba2ff90d62a"
integrity sha512-hTIfSQxD7L+AKIqyjoq8CWBRkEQrrMZmA3GSZgPI5JFWBHgO0HBo5TH/8TU81oEJh6kqqHAl2ObMhmcnaFqlzg==
dependencies:
"@sentry/core" "5.30.0"
"@sentry/hub" "5.30.0"
"@sentry/tracing" "5.30.0"
"@sentry/types" "5.30.0"
"@sentry/utils" "5.30.0"
cookie "^0.4.1"
"@sentry-internal/tracing" "7.91.0"
"@sentry/core" "7.91.0"
"@sentry/types" "7.91.0"
"@sentry/utils" "7.91.0"
https-proxy-agent "^5.0.0"
lru_map "^0.3.3"
tslib "^1.9.3"
"@sentry/react@7.50.0":
version "7.50.0"
@ -6038,28 +6022,12 @@
"@types/aws-lambda" "^8.10.62"
"@types/express" "^4.17.14"
"@sentry/tracing@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f"
integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==
"@sentry/tracing@^7.10.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.91.0.tgz#2019542a9ed991c04a1f5e685a245b0fb8d69be1"
integrity sha512-IlSAMvqfCL/2TwwN4Tmk6bGMgilGruv5oIJ1GMenVZk53bHwjpjzMbd0ms8+S5zJwAgTQXoCbRhaFFrNmptteQ==
dependencies:
"@sentry/hub" "5.30.0"
"@sentry/minimal" "5.30.0"
"@sentry/types" "5.30.0"
"@sentry/utils" "5.30.0"
tslib "^1.9.3"
"@sentry/tracing@^7.9.0":
version "7.77.0"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.77.0.tgz#39d7c30834f503fe9eb20ce1c8c8bd28f7d7c9ce"
integrity sha512-zr6eSCW3NJ124uj4Fy/6hh77cziy43dpYE1WpgvO/yhl1+kdrY2XVJ0bXGqwHU0KBm/eSgHD7yecUxmZUXiabA==
dependencies:
"@sentry-internal/tracing" "7.77.0"
"@sentry/types@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402"
integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==
"@sentry-internal/tracing" "7.91.0"
"@sentry/types@7.50.0":
version "7.50.0"
@ -6071,13 +6039,10 @@
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144"
integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA==
"@sentry/utils@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980"
integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==
dependencies:
"@sentry/types" "5.30.0"
tslib "^1.9.3"
"@sentry/types@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.91.0.tgz#5b68954e08986fecb0d4bef168df58eef62c32c7"
integrity sha512-bcQnb7J3P3equbCUc+sPuHog2Y47yGD2sCkzmnZBjvBT0Z1B4f36fI/5WjyZhTjLSiOdg3F2otwvikbMjmBDew==
"@sentry/utils@7.50.0":
version "7.50.0"
@ -6094,6 +6059,13 @@
dependencies:
"@sentry/types" "7.77.0"
"@sentry/utils@7.91.0":
version "7.91.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.91.0.tgz#3b1a94c053c885877908cd3e1365e3d23e21a73f"
integrity sha512-fvxjrEbk6T6Otu++Ax9ntlQ0sGRiwSC179w68aC3u26Wr30FAIRKqHTCCdc2jyWk7Gd9uWRT/cq+g8NG/8BfSg==
dependencies:
"@sentry/types" "7.91.0"
"@sentry/webpack-plugin@1.20.0":
version "1.20.0"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.20.0.tgz#e7add76122708fb6b4ee7951294b521019720e58"