@planningcenter/chat-react-native 3.32.0 → 3.32.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"error_boundary.d.ts","sourceRoot":"","sources":["../../../src/components/page/error_boundary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAAsB,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,CAAA;IAC/C,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAAA;AAED,cAAM,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAAC;IACtF,KAAK,EAAE,kBAAkB,CAGxB;IAED,iBAAiB,CAAC,KAAK,EAAE,GAAG;IAI5B,WAAW,CAAC,KAAK,EAAE,GAAG;IAItB,WAAW,aAGV;IAED,MAAM;CAOP;AA4FD,eAAe,aAAa,CAAA"}
1
+ {"version":3,"file":"error_boundary.d.ts","sourceRoot":"","sources":["../../../src/components/page/error_boundary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAAmC,MAAM,OAAO,CAAA;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,CAAA;IAC/C,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAAA;AAED,cAAM,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAAC;IACtF,KAAK,EAAE,kBAAkB,CAGxB;IAED,iBAAiB,CAAC,KAAK,EAAE,GAAG;IAI5B,WAAW,CAAC,KAAK,EAAE,GAAG;IAItB,WAAW,aAGV;IAED,MAAM;CAOP;AAkGD,eAAe,aAAa,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { useNavigation } from '@react-navigation/native';
2
2
  import { useQueryErrorResetBoundary } from '@tanstack/react-query';
3
- import React, { useEffect, useMemo } from 'react';
3
+ import React, { useCallback, useEffect, useMemo } from 'react';
4
+ import { onAuthRefresh } from '../../utils/auth_events';
4
5
  import { ResponseError } from '../../utils/response_error';
5
6
  import BlankState from '../primitive/blank_state_primitive';
6
7
  class ErrorBoundary extends React.Component {
@@ -29,16 +30,13 @@ class ErrorBoundary extends React.Component {
29
30
  }
30
31
  function ErrorView({ error, onReset }) {
31
32
  const { reset } = useQueryErrorResetBoundary();
32
- useEffect(() => {
33
- if (!reset)
34
- return;
35
- return () => {
36
- onReset();
37
- reset();
38
- };
33
+ const handleReset = useCallback(() => {
34
+ reset();
35
+ onReset();
39
36
  }, [reset, onReset]);
37
+ useEffect(() => handleReset, [handleReset]);
40
38
  if (error instanceof ResponseError) {
41
- return <ResponseErrorView response={error.response} onReset={onReset}/>;
39
+ return <ResponseErrorView response={error.response} onReset={handleReset}/>;
42
40
  }
43
41
  if (isNetworkError(error)) {
44
42
  return (<ErrorContent heading={'Problem connecting!'} body={'Check your internet connection and try again.'}/>);
@@ -56,7 +54,7 @@ function isNetworkError(error) {
56
54
  return false;
57
55
  return new RegExp(networkFailedMessages.join('|'), 'i').test(error.message);
58
56
  }
59
- function ResponseErrorView({ response }) {
57
+ function ResponseErrorView({ response, onReset }) {
60
58
  const { status } = response;
61
59
  const heading = useMemo(() => {
62
60
  switch (status) {
@@ -78,6 +76,11 @@ function ResponseErrorView({ response }) {
78
76
  return 'Something unexpected happened.';
79
77
  }
80
78
  }, [status]);
79
+ useEffect(() => {
80
+ if (status !== 401)
81
+ return;
82
+ return onAuthRefresh(onReset);
83
+ }, [status, onReset]);
81
84
  return <ErrorContent heading={heading} body={body}/>;
82
85
  }
83
86
  function ErrorContent({ heading, body }) {
@@ -1 +1 @@
1
- {"version":3,"file":"error_boundary.js","sourceRoot":"","sources":["../../../src/components/page/error_boundary.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { useQueryErrorResetBoundary } from '@tanstack/react-query'\nimport React, { PropsWithChildren, useEffect, useMemo } from 'react'\nimport { ResponseError } from '../../utils/response_error'\nimport BlankState from '../primitive/blank_state_primitive'\n\ntype ErrorBoundaryState = {\n error: ResponseError | Error | TypeError | null\n unsubscriber: () => void\n}\n\nclass ErrorBoundary extends React.Component<PropsWithChildren<{ onReset?: () => void }>> {\n state: ErrorBoundaryState = {\n error: null,\n unsubscriber: () => {},\n }\n\n componentDidCatch(error: any) {\n this.handleError(error)\n }\n\n handleError(error: any) {\n this.setState({ error })\n }\n\n handleReset = () => {\n this.props.onReset?.()\n this.setState({ error: null })\n }\n\n render() {\n if (this.state.error) {\n return <ErrorView error={this.state.error} onReset={this.handleReset} />\n } else {\n return this.props.children\n }\n }\n}\n\nfunction ErrorView({ error, onReset }: { error: Error | ResponseError; onReset: () => void }) {\n const { reset } = useQueryErrorResetBoundary()\n useEffect(() => {\n if (!reset) return\n\n return () => {\n onReset()\n reset()\n }\n }, [reset, onReset])\n\n if (error instanceof ResponseError) {\n return <ResponseErrorView response={error.response} onReset={onReset} />\n }\n\n if (isNetworkError(error)) {\n return (\n <ErrorContent\n heading={'Problem connecting!'}\n body={'Check your internet connection and try again.'}\n />\n )\n }\n\n return <ErrorContent heading={'Oops!'} body={'Something unexpected happened.'} />\n}\n\nfunction isNetworkError(error: ResponseError | Error | TypeError | null) {\n const isError = error instanceof Error\n const networkFailedMessages = [\n 'Network request failed',\n 'Network request timed out',\n 'Failed to fetch',\n ]\n\n if (!isError) return false\n\n return new RegExp(networkFailedMessages.join('|'), 'i').test(error.message)\n}\n\nfunction ResponseErrorView({ response }: { response: Response; onReset: () => void }) {\n const { status } = response\n const heading = useMemo(() => {\n switch (status) {\n case 403:\n return 'Permission required'\n case 404:\n return 'Content not found'\n default:\n return 'Oops!'\n }\n }, [status])\n\n const body = useMemo(() => {\n switch (status) {\n case 403:\n return 'Contact your administrator for access.'\n case 404:\n return 'If you believe something should be here, please reach out to your administrator.'\n default:\n return 'Something unexpected happened.'\n }\n }, [status])\n\n return <ErrorContent heading={heading} body={body} />\n}\n\nfunction ErrorContent({ heading, body }: { heading: string; body: string }) {\n const navigation = useNavigation()\n\n return (\n <BlankState.Root>\n <BlankState.Imagery name=\"people.noTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>{heading}</BlankState.Heading>\n <BlankState.Text>{body}</BlankState.Text>\n </BlankState.Content>\n <BlankState.Button\n title=\"Go back\"\n onPress={navigation.goBack}\n size=\"md\"\n accessibilityRole=\"link\"\n />\n <BlankState.TextButton onPress={() => navigation.navigate('BugReport')}>\n Report a bug\n </BlankState.TextButton>\n </BlankState.Root>\n )\n}\n\nexport default ErrorBoundary\n"]}
1
+ {"version":3,"file":"error_boundary.js","sourceRoot":"","sources":["../../../src/components/page/error_boundary.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { useQueryErrorResetBoundary } from '@tanstack/react-query'\nimport React, { PropsWithChildren, useCallback, useEffect, useMemo } from 'react'\nimport { onAuthRefresh } from '../../utils/auth_events'\nimport { ResponseError } from '../../utils/response_error'\nimport BlankState from '../primitive/blank_state_primitive'\n\ntype ErrorBoundaryState = {\n error: ResponseError | Error | TypeError | null\n unsubscriber: () => void\n}\n\nclass ErrorBoundary extends React.Component<PropsWithChildren<{ onReset?: () => void }>> {\n state: ErrorBoundaryState = {\n error: null,\n unsubscriber: () => {},\n }\n\n componentDidCatch(error: any) {\n this.handleError(error)\n }\n\n handleError(error: any) {\n this.setState({ error })\n }\n\n handleReset = () => {\n this.props.onReset?.()\n this.setState({ error: null })\n }\n\n render() {\n if (this.state.error) {\n return <ErrorView error={this.state.error} onReset={this.handleReset} />\n } else {\n return this.props.children\n }\n }\n}\n\nfunction ErrorView({ error, onReset }: { error: Error | ResponseError; onReset: () => void }) {\n const { reset } = useQueryErrorResetBoundary()\n\n const handleReset = useCallback(() => {\n reset()\n onReset()\n }, [reset, onReset])\n\n useEffect(() => handleReset, [handleReset])\n\n if (error instanceof ResponseError) {\n return <ResponseErrorView response={error.response} onReset={handleReset} />\n }\n\n if (isNetworkError(error)) {\n return (\n <ErrorContent\n heading={'Problem connecting!'}\n body={'Check your internet connection and try again.'}\n />\n )\n }\n\n return <ErrorContent heading={'Oops!'} body={'Something unexpected happened.'} />\n}\n\nfunction isNetworkError(error: ResponseError | Error | TypeError | null) {\n const isError = error instanceof Error\n const networkFailedMessages = [\n 'Network request failed',\n 'Network request timed out',\n 'Failed to fetch',\n ]\n\n if (!isError) return false\n\n return new RegExp(networkFailedMessages.join('|'), 'i').test(error.message)\n}\n\nfunction ResponseErrorView({ response, onReset }: { response: Response; onReset: () => void }) {\n const { status } = response\n\n const heading = useMemo(() => {\n switch (status) {\n case 403:\n return 'Permission required'\n case 404:\n return 'Content not found'\n default:\n return 'Oops!'\n }\n }, [status])\n\n const body = useMemo(() => {\n switch (status) {\n case 403:\n return 'Contact your administrator for access.'\n case 404:\n return 'If you believe something should be here, please reach out to your administrator.'\n default:\n return 'Something unexpected happened.'\n }\n }, [status])\n\n useEffect(() => {\n if (status !== 401) return\n\n return onAuthRefresh(onReset)\n }, [status, onReset])\n\n return <ErrorContent heading={heading} body={body} />\n}\n\nfunction ErrorContent({ heading, body }: { heading: string; body: string }) {\n const navigation = useNavigation()\n\n return (\n <BlankState.Root>\n <BlankState.Imagery name=\"people.noTextMessage\" />\n <BlankState.Content>\n <BlankState.Heading>{heading}</BlankState.Heading>\n <BlankState.Text>{body}</BlankState.Text>\n </BlankState.Content>\n <BlankState.Button\n title=\"Go back\"\n onPress={navigation.goBack}\n size=\"md\"\n accessibilityRole=\"link\"\n />\n <BlankState.TextButton onPress={() => navigation.navigate('BugReport')}>\n Report a bug\n </BlankState.TextButton>\n </BlankState.Root>\n )\n}\n\nexport default ErrorBoundary\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAwC,MAAM,OAAO,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAmBxC,eAAO,MAAM,eAAe,aAO1B,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,qBA2BlD;AAcD,wBAAgB,eAAe,WAQ9B"}
1
+ {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAwC,MAAM,OAAO,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAoBxC,eAAO,MAAM,eAAe,aAO1B,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,qBA6BlD;AAcD,wBAAgB,eAAe,WAQ9B"}
@@ -4,6 +4,7 @@ import { useApiClient } from '../hooks/use_api_client';
4
4
  import { useAppState } from '../hooks/use_app_state';
5
5
  import { appGrantsRequestArgs } from '../hooks/use_chat_permissions';
6
6
  import { getRequestQueryKey } from '../hooks/use_suspense_api';
7
+ import { emitAuthRefresh } from '../utils/auth_events';
7
8
  import { ChatContext } from './chat_context';
8
9
  let apiClient;
9
10
  const defaultQueryFn = ({ queryKey }) => {
@@ -28,6 +29,7 @@ export function ApiProvider({ children }) {
28
29
  useEffect(() => {
29
30
  if (!sessionChanged)
30
31
  return;
32
+ emitAuthRefresh();
31
33
  if (chatQueryClient.isFetching()) {
32
34
  chatQueryClient.invalidateQueries();
33
35
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.js","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n focusManager,\n QueryClient,\n QueryClientProvider,\n QueryKey,\n usePrefetchQuery,\n} from '@tanstack/react-query'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { ViewProps } from 'react-native'\nimport { ApiClient, useApiClient } from '../hooks/use_api_client'\nimport { useAppState } from '../hooks/use_app_state'\nimport { appGrantsRequestArgs } from '../hooks/use_chat_permissions'\nimport { getRequestQueryKey, RequestQueryKey } from '../hooks/use_suspense_api'\nimport { ChatContext, ChatContextValue } from './chat_context'\n\nlet apiClient: ApiClient | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const [url, data, headers, app = 'chat'] = queryKey as RequestQueryKey\n\n return apiClient[app].get({ url, data, headers })\n}\n\nexport const chatQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n queryFn: defaultQueryFn,\n retry: 3,\n },\n },\n})\n\nexport function ApiProvider({ children }: ViewProps) {\n const { token, env } = useContext(ChatContext)\n const sessionChanged = useSessionChanged({ token, env })\n\n const client = useApiClient()\n\n useEffect(() => {\n if (!sessionChanged) return\n\n if (chatQueryClient.isFetching()) {\n chatQueryClient.invalidateQueries()\n return\n }\n\n chatQueryClient.clear()\n }, [sessionChanged])\n\n useEffect(() => {\n apiClient = client\n }, [client])\n\n return (\n <QueryClientProvider client={chatQueryClient}>\n <PrefetchQueries />\n {children}\n </QueryClientProvider>\n )\n}\n\n// Component to prefetch queries when the app is focused\n// This needs to live in the provider so that it can access the api client\n// and the chat query client\nconst PrefetchQueries = () => {\n usePrefetchQuery({\n queryKey: getRequestQueryKey(appGrantsRequestArgs),\n queryFn: defaultQueryFn,\n })\n\n return null\n}\n\nexport function useFocusManager() {\n const appState = useAppState()\n\n useEffect(() => {\n focusManager.setFocused(appState === 'active')\n }, [appState])\n\n return appState\n}\n\nfunction useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {\n const { token: newToken, env: newEnv } = value\n const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)\n\n const isInitialLogin = !prevToken && !!newToken\n if (isInitialLogin) return false\n\n return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)\n}\n\nfunction usePrevious<T>(value: T): T {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n"]}
1
+ {"version":3,"file":"api_provider.js","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n focusManager,\n QueryClient,\n QueryClientProvider,\n QueryKey,\n usePrefetchQuery,\n} from '@tanstack/react-query'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { ViewProps } from 'react-native'\nimport { ApiClient, useApiClient } from '../hooks/use_api_client'\nimport { useAppState } from '../hooks/use_app_state'\nimport { appGrantsRequestArgs } from '../hooks/use_chat_permissions'\nimport { getRequestQueryKey, RequestQueryKey } from '../hooks/use_suspense_api'\nimport { emitAuthRefresh } from '../utils/auth_events'\nimport { ChatContext, ChatContextValue } from './chat_context'\n\nlet apiClient: ApiClient | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const [url, data, headers, app = 'chat'] = queryKey as RequestQueryKey\n\n return apiClient[app].get({ url, data, headers })\n}\n\nexport const chatQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n queryFn: defaultQueryFn,\n retry: 3,\n },\n },\n})\n\nexport function ApiProvider({ children }: ViewProps) {\n const { token, env } = useContext(ChatContext)\n const sessionChanged = useSessionChanged({ token, env })\n\n const client = useApiClient()\n\n useEffect(() => {\n if (!sessionChanged) return\n\n emitAuthRefresh()\n\n if (chatQueryClient.isFetching()) {\n chatQueryClient.invalidateQueries()\n return\n }\n\n chatQueryClient.clear()\n }, [sessionChanged])\n\n useEffect(() => {\n apiClient = client\n }, [client])\n\n return (\n <QueryClientProvider client={chatQueryClient}>\n <PrefetchQueries />\n {children}\n </QueryClientProvider>\n )\n}\n\n// Component to prefetch queries when the app is focused\n// This needs to live in the provider so that it can access the api client\n// and the chat query client\nconst PrefetchQueries = () => {\n usePrefetchQuery({\n queryKey: getRequestQueryKey(appGrantsRequestArgs),\n queryFn: defaultQueryFn,\n })\n\n return null\n}\n\nexport function useFocusManager() {\n const appState = useAppState()\n\n useEffect(() => {\n focusManager.setFocused(appState === 'active')\n }, [appState])\n\n return appState\n}\n\nfunction useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {\n const { token: newToken, env: newEnv } = value\n const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)\n\n const isInitialLogin = !prevToken && !!newToken\n if (isInitialLogin) return false\n\n return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)\n}\n\nfunction usePrevious<T>(value: T): T {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n"]}
@@ -0,0 +1,7 @@
1
+ type Listener = () => void;
2
+ export declare function onAuthRefresh(listener: Listener): () => void;
3
+ export declare function emitAuthRefresh(): void;
4
+ export declare function __resetAuthRefreshListenersForTests(): void;
5
+ export declare function __getAuthRefreshListenerCountForTests(): number;
6
+ export {};
7
+ //# sourceMappingURL=auth_events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth_events.d.ts","sourceRoot":"","sources":["../../src/utils/auth_events.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAA;AAG1B,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,cAK/C;AAED,wBAAgB,eAAe,SAE9B;AAED,wBAAgB,mCAAmC,SAElD;AAED,wBAAgB,qCAAqC,WAEpD"}
@@ -0,0 +1,17 @@
1
+ const listeners = new Set();
2
+ export function onAuthRefresh(listener) {
3
+ listeners.add(listener);
4
+ return () => {
5
+ listeners.delete(listener);
6
+ };
7
+ }
8
+ export function emitAuthRefresh() {
9
+ listeners.forEach(fn => fn());
10
+ }
11
+ export function __resetAuthRefreshListenersForTests() {
12
+ listeners.clear();
13
+ }
14
+ export function __getAuthRefreshListenerCountForTests() {
15
+ return listeners.size;
16
+ }
17
+ //# sourceMappingURL=auth_events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth_events.js","sourceRoot":"","sources":["../../src/utils/auth_events.ts"],"names":[],"mappings":"AACA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAA;AAErC,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,mCAAmC;IACjD,SAAS,CAAC,KAAK,EAAE,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,qCAAqC;IACnD,OAAO,SAAS,CAAC,IAAI,CAAA;AACvB,CAAC","sourcesContent":["type Listener = () => void\nconst listeners = new Set<Listener>()\n\nexport function onAuthRefresh(listener: Listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n}\n\nexport function emitAuthRefresh() {\n listeners.forEach(fn => fn())\n}\n\nexport function __resetAuthRefreshListenersForTests() {\n listeners.clear()\n}\n\nexport function __getAuthRefreshListenerCountForTests() {\n return listeners.size\n}\n"]}
@@ -8,7 +8,7 @@ export declare class UploadUri {
8
8
  constructor({ session }: {
9
9
  session: Session;
10
10
  });
11
- get schema(): "http" | "https";
11
+ get schema(): string;
12
12
  get host(): string;
13
13
  get subdomain(): "upload" | "upload-staging";
14
14
  get domain(): 'pco' | 'planningcenteronline';
@@ -1 +1 @@
1
- {"version":3,"file":"upload_uri.d.ts","sourceRoot":"","sources":["../../src/utils/upload_uri.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;gBAEA,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE;IAI7C,IAAI,MAAM,qBAMT;IAED,IAAI,IAAI,WAEP;IAED,IAAI,SAAS,gCAOZ;IAED,IAAI,MAAM,IAAI,KAAK,GAAG,sBAAsB,CAE3C;IAED,IAAI,GAAG,mBAON;IAED,IAAI,GAAG,4BAEN;IAED,IAAI,OAAO,WAEV;IAED,IAAI,OAAO;;;;MAMV;CACF"}
1
+ {"version":3,"file":"upload_uri.d.ts","sourceRoot":"","sources":["../../src/utils/upload_uri.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;gBAEA,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE;IAI7C,IAAI,MAAM,WAET;IAED,IAAI,IAAI,WAEP;IAED,IAAI,SAAS,gCAOZ;IAED,IAAI,MAAM,IAAI,KAAK,GAAG,sBAAsB,CAE3C;IAED,IAAI,GAAG,mBAON;IAED,IAAI,GAAG,4BAEN;IAED,IAAI,OAAO,WAEV;IAED,IAAI,OAAO;;;;MAMV;CACF"}
@@ -15,12 +15,7 @@ export class UploadUri {
15
15
  this.session = session;
16
16
  }
17
17
  get schema() {
18
- if (this.env === 'development') {
19
- return 'http';
20
- }
21
- else {
22
- return 'https';
23
- }
18
+ return 'https';
24
19
  }
25
20
  get host() {
26
21
  return `${this.subdomain}.${this.domain}.${this.tld}`;
@@ -1 +1 @@
1
- {"version":3,"file":"upload_uri.js","sourceRoot":"","sources":["../../src/utils/upload_uri.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,0BAA0B,CAAA;AAEjD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAA;AACnC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAA;AACnC,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,EAAE,CAAA;AAC7C,MAAM,aAAa,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAA;AACnD,MAAM,eAAe,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAA;AACvD,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAA;AAE/C;;GAEG;AACH,MAAM,OAAO,SAAS;IACpB,OAAO,CAAS;IAChB,GAAG,CAAS;IAEZ,YAAY,EAAE,OAAO,EAAwB;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,IAAI,MAAM;QACR,IAAI,IAAI,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAA;QACf,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAA;QAChB,CAAC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACvD,CAAC;IAED,IAAI,SAAS;QACX,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,gBAAgB,CAAA;YACzB;gBACE,OAAO,QAAQ,CAAA;QACnB,CAAC;IACH,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAA;IACpE,CAAC;IAED,IAAI,GAAG;QACL,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,KAAK,aAAa;gBAChB,OAAO,MAAM,CAAA;YACf;gBACE,OAAO,KAAK,CAAA;QAChB,CAAC;IACH,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,YAAY,CAAA;IAC1C,CAAC;IAED,IAAI,OAAO;QACT,OAAO,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;IACxC,CAAC;IAED,IAAI,OAAO;QACT,OAAO;YACL,YAAY,EAAE,GAAG,OAAO,IAAI,eAAe,KAAK,KAAK,KAAK,KAAK,KAAK,UAAU,KAAK,aAAa,GAAG;YACnG,aAAa,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE;YAC3D,sBAAsB,EAAE,MAAM;SAC/B,CAAA;IACH,CAAC;CACF","sourcesContent":["import DeviceInfo from 'react-native-device-info'\nimport { Session } from './session'\nconst brand = DeviceInfo.getBrand()\nconst model = DeviceInfo.getModel()\nconst systemName = DeviceInfo.getSystemName()\nconst systemVersion = DeviceInfo.getSystemVersion()\nconst readableVersion = DeviceInfo.getReadableVersion()\nconst appName = DeviceInfo.getApplicationName()\n\n/**\n * This is for accessing https://github.com/planningcenter/upload\n */\nexport class UploadUri {\n session: Session\n app?: string\n\n constructor({ session }: { session: Session }) {\n this.session = session\n }\n\n get schema() {\n if (this.env === 'development') {\n return 'http'\n } else {\n return 'https'\n }\n }\n\n get host() {\n return `${this.subdomain}.${this.domain}.${this.tld}`\n }\n\n get subdomain() {\n switch (this.env) {\n case 'staging':\n return 'upload-staging'\n default:\n return 'upload'\n }\n }\n\n get domain(): 'pco' | 'planningcenteronline' {\n return this.env === 'development' ? 'pco' : 'planningcenteronline'\n }\n\n get tld() {\n switch (this.env) {\n case 'development':\n return 'test'\n default:\n return 'com'\n }\n }\n\n get env() {\n return this.session?.env || 'production'\n }\n\n get baseUrl() {\n return `${this.schema}://${this.host}`\n }\n\n get headers() {\n return {\n 'User-Agent': `${appName}/${readableVersion} (${brand}, ${model}, ${systemName}, ${systemVersion})`,\n Authorization: `Bearer ${this.session.token?.access_token}`,\n 'X-PCO-Moderate-Image': 'true',\n }\n }\n}\n"]}
1
+ {"version":3,"file":"upload_uri.js","sourceRoot":"","sources":["../../src/utils/upload_uri.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,0BAA0B,CAAA;AAEjD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAA;AACnC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAA;AACnC,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,EAAE,CAAA;AAC7C,MAAM,aAAa,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAA;AACnD,MAAM,eAAe,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAA;AACvD,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAA;AAE/C;;GAEG;AACH,MAAM,OAAO,SAAS;IACpB,OAAO,CAAS;IAChB,GAAG,CAAS;IAEZ,YAAY,EAAE,OAAO,EAAwB;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACvD,CAAC;IAED,IAAI,SAAS;QACX,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,gBAAgB,CAAA;YACzB;gBACE,OAAO,QAAQ,CAAA;QACnB,CAAC;IACH,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAA;IACpE,CAAC;IAED,IAAI,GAAG;QACL,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,KAAK,aAAa;gBAChB,OAAO,MAAM,CAAA;YACf;gBACE,OAAO,KAAK,CAAA;QAChB,CAAC;IACH,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,YAAY,CAAA;IAC1C,CAAC;IAED,IAAI,OAAO;QACT,OAAO,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;IACxC,CAAC;IAED,IAAI,OAAO;QACT,OAAO;YACL,YAAY,EAAE,GAAG,OAAO,IAAI,eAAe,KAAK,KAAK,KAAK,KAAK,KAAK,UAAU,KAAK,aAAa,GAAG;YACnG,aAAa,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE;YAC3D,sBAAsB,EAAE,MAAM;SAC/B,CAAA;IACH,CAAC;CACF","sourcesContent":["import DeviceInfo from 'react-native-device-info'\nimport { Session } from './session'\nconst brand = DeviceInfo.getBrand()\nconst model = DeviceInfo.getModel()\nconst systemName = DeviceInfo.getSystemName()\nconst systemVersion = DeviceInfo.getSystemVersion()\nconst readableVersion = DeviceInfo.getReadableVersion()\nconst appName = DeviceInfo.getApplicationName()\n\n/**\n * This is for accessing https://github.com/planningcenter/upload\n */\nexport class UploadUri {\n session: Session\n app?: string\n\n constructor({ session }: { session: Session }) {\n this.session = session\n }\n\n get schema() {\n return 'https'\n }\n\n get host() {\n return `${this.subdomain}.${this.domain}.${this.tld}`\n }\n\n get subdomain() {\n switch (this.env) {\n case 'staging':\n return 'upload-staging'\n default:\n return 'upload'\n }\n }\n\n get domain(): 'pco' | 'planningcenteronline' {\n return this.env === 'development' ? 'pco' : 'planningcenteronline'\n }\n\n get tld() {\n switch (this.env) {\n case 'development':\n return 'test'\n default:\n return 'com'\n }\n }\n\n get env() {\n return this.session?.env || 'production'\n }\n\n get baseUrl() {\n return `${this.schema}://${this.host}`\n }\n\n get headers() {\n return {\n 'User-Agent': `${appName}/${readableVersion} (${brand}, ${model}, ${systemName}, ${systemVersion})`,\n Authorization: `Bearer ${this.session.token?.access_token}`,\n 'X-PCO-Moderate-Image': 'true',\n }\n }\n}\n"]}
@@ -9,7 +9,7 @@ export declare class Uri {
9
9
  app?: string;
10
10
  graph?: Graph;
11
11
  });
12
- get schema(): "http" | "https";
12
+ get schema(): string;
13
13
  get host(): string;
14
14
  get subdomain(): "api.staging" | "api-staging" | "api";
15
15
  get domain(): 'pco' | 'planningcenteronline' | 'churchcenter';
@@ -1 +1 @@
1
- {"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,KAAK,KAAK,GAAG,cAAc,GAAG,gBAAgB,CAAA;AAC9C,qBAAa,GAAG;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,CAAmB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;gBAEA,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAMtF,IAAI,MAAM,qBAMT;IAED,IAAI,IAAI,WAEP;IAED,IAAI,SAAS,0CAOZ;IAED,IAAI,MAAM,IAAI,KAAK,GAAG,sBAAsB,GAAG,cAAc,CAM5D;IAED,IAAI,GAAG,mBAON;IAED,IAAI,cAAc,YAEjB;IAED,IAAI,GAAG,4BAEN;IAED,IAAI,OAAO,WAEV;IAED,IAAI,SAAS,WAEZ;IAED,IAAI,OAAO;;;MAKV;IAED,MAAM,SAAU,MAAM,YAIrB;IAED,GAAG,SAAU,MAAM,YAIlB;CACF"}
1
+ {"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,KAAK,KAAK,GAAG,cAAc,GAAG,gBAAgB,CAAA;AAC9C,qBAAa,GAAG;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,CAAmB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;gBAEA,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;IAMtF,IAAI,MAAM,WAET;IAED,IAAI,IAAI,WAEP;IAED,IAAI,SAAS,0CAOZ;IAED,IAAI,MAAM,IAAI,KAAK,GAAG,sBAAsB,GAAG,cAAc,CAM5D;IAED,IAAI,GAAG,mBAON;IAED,IAAI,cAAc,YAEjB;IAED,IAAI,GAAG,4BAEN;IAED,IAAI,OAAO,WAEV;IAED,IAAI,SAAS,WAEZ;IAED,IAAI,OAAO;;;MAKV;IAED,MAAM,SAAU,MAAM,YAIrB;IAED,GAAG,SAAU,MAAM,YAIlB;CACF"}
@@ -15,12 +15,7 @@ export class Uri {
15
15
  this.graph = graph || 'planningcenter';
16
16
  }
17
17
  get schema() {
18
- if (this.env === 'development') {
19
- return 'http';
20
- }
21
- else {
22
- return 'https';
23
- }
18
+ return 'https';
24
19
  }
25
20
  get host() {
26
21
  return `${this.subdomain}.${this.domain}.${this.tld}`;
@@ -1 +1 @@
1
- {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"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","sourcesContent":["import DeviceInfo from 'react-native-device-info'\nimport { Session } from './session'\nconst brand = DeviceInfo.getBrand()\nconst model = DeviceInfo.getModel()\nconst systemName = DeviceInfo.getSystemName()\nconst systemVersion = DeviceInfo.getSystemVersion()\nconst readableVersion = DeviceInfo.getReadableVersion()\nconst appName = DeviceInfo.getApplicationName()\n\ntype Graph = 'churchcenter' | 'planningcenter'\nexport class Uri {\n session: Session\n graph: Graph = 'planningcenter'\n app?: string\n\n constructor({ session, app, graph }: { session: Session; app?: string; graph?: Graph }) {\n this.session = session\n this.app = app\n this.graph = graph || 'planningcenter'\n }\n\n get schema() {\n if (this.env === 'development') {\n return 'http'\n } else {\n return 'https'\n }\n }\n\n get host() {\n return `${this.subdomain}.${this.domain}.${this.tld}`\n }\n\n get subdomain() {\n switch (this.env) {\n case 'staging':\n return this.isChurchCenter ? 'api.staging' : 'api-staging'\n default:\n return 'api'\n }\n }\n\n get domain(): 'pco' | 'planningcenteronline' | 'churchcenter' {\n if (this.isChurchCenter) {\n return 'churchcenter'\n }\n\n return this.env === 'development' ? 'pco' : 'planningcenteronline'\n }\n\n get tld() {\n switch (this.env) {\n case 'development':\n return 'test'\n default:\n return 'com'\n }\n }\n\n get isChurchCenter() {\n return this.session.isChurchCenterToken\n }\n\n get env() {\n return this.session?.env || 'production'\n }\n\n get baseUrl() {\n return `${this.schema}://${this.host}`\n }\n\n get directory() {\n return this.app ? `/${this.app}/v2` : ''\n }\n\n get headers() {\n return {\n 'User-Agent': `${appName}/${readableVersion} (${brand}, ${model}, ${systemName}, ${systemVersion})`,\n Authorization: `Bearer ${this.session.token?.access_token}`,\n }\n }\n\n appUrl = (path: string) => {\n if (path.startsWith(`${this.schema}://`)) return path\n\n return `${this.baseUrl}${this.directory}${path || '/'}`\n }\n\n api = (path: string) => {\n if (path.startsWith(`${this.schema}://`)) return path\n\n return `${this.baseUrl}${path || '/'}`\n }\n}\n"]}
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../src/utils/uri.ts"],"names":[],"mappings":"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","sourcesContent":["import DeviceInfo from 'react-native-device-info'\nimport { Session } from './session'\nconst brand = DeviceInfo.getBrand()\nconst model = DeviceInfo.getModel()\nconst systemName = DeviceInfo.getSystemName()\nconst systemVersion = DeviceInfo.getSystemVersion()\nconst readableVersion = DeviceInfo.getReadableVersion()\nconst appName = DeviceInfo.getApplicationName()\n\ntype Graph = 'churchcenter' | 'planningcenter'\nexport class Uri {\n session: Session\n graph: Graph = 'planningcenter'\n app?: string\n\n constructor({ session, app, graph }: { session: Session; app?: string; graph?: Graph }) {\n this.session = session\n this.app = app\n this.graph = graph || 'planningcenter'\n }\n\n get schema() {\n return 'https'\n }\n\n get host() {\n return `${this.subdomain}.${this.domain}.${this.tld}`\n }\n\n get subdomain() {\n switch (this.env) {\n case 'staging':\n return this.isChurchCenter ? 'api.staging' : 'api-staging'\n default:\n return 'api'\n }\n }\n\n get domain(): 'pco' | 'planningcenteronline' | 'churchcenter' {\n if (this.isChurchCenter) {\n return 'churchcenter'\n }\n\n return this.env === 'development' ? 'pco' : 'planningcenteronline'\n }\n\n get tld() {\n switch (this.env) {\n case 'development':\n return 'test'\n default:\n return 'com'\n }\n }\n\n get isChurchCenter() {\n return this.session.isChurchCenterToken\n }\n\n get env() {\n return this.session?.env || 'production'\n }\n\n get baseUrl() {\n return `${this.schema}://${this.host}`\n }\n\n get directory() {\n return this.app ? `/${this.app}/v2` : ''\n }\n\n get headers() {\n return {\n 'User-Agent': `${appName}/${readableVersion} (${brand}, ${model}, ${systemName}, ${systemVersion})`,\n Authorization: `Bearer ${this.session.token?.access_token}`,\n }\n }\n\n appUrl = (path: string) => {\n if (path.startsWith(`${this.schema}://`)) return path\n\n return `${this.baseUrl}${this.directory}${path || '/'}`\n }\n\n api = (path: string) => {\n if (path.startsWith(`${this.schema}://`)) return path\n\n return `${this.baseUrl}${path || '/'}`\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.32.0",
3
+ "version": "3.32.1-rc.1",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -64,5 +64,5 @@
64
64
  "react-native-url-polyfill": "^2.0.0",
65
65
  "typescript": "<5.6.0"
66
66
  },
67
- "gitHead": "c992227ce27ae8682032b472514005f029f26ee6"
67
+ "gitHead": "b56ae60405cfd6240e9645fed4fdecb245570a21"
68
68
  }
@@ -56,7 +56,7 @@ describe('URI', () => {
56
56
  isChurchCenterToken: false,
57
57
  },
58
58
  })
59
- expect(uri.baseUrl).toBe('http://api.pco.test')
59
+ expect(uri.baseUrl).toBe('https://api.pco.test')
60
60
  })
61
61
  })
62
62
 
@@ -100,7 +100,7 @@ describe('URI', () => {
100
100
  },
101
101
  graph: 'churchcenter',
102
102
  })
103
- expect(uri.baseUrl).toBe('http://api.churchcenter.test')
103
+ expect(uri.baseUrl).toBe('https://api.churchcenter.test')
104
104
  })
105
105
  })
106
106
  })
@@ -2,7 +2,7 @@ import { http, HttpResponse } from 'msw'
2
2
  import { JSONAPIResponse } from '../types'
3
3
  import DefaultFixtures from './fixtures/defaults'
4
4
 
5
- export const BASE_URL = 'http://api.pco.test/chat/v2'
5
+ export const BASE_URL = 'https://api.pco.test/chat/v2'
6
6
 
7
7
  export const handlers = [
8
8
  // Session fixtures
@@ -1,6 +1,7 @@
1
1
  import { useNavigation } from '@react-navigation/native'
2
2
  import { useQueryErrorResetBoundary } from '@tanstack/react-query'
3
- import React, { PropsWithChildren, useEffect, useMemo } from 'react'
3
+ import React, { PropsWithChildren, useCallback, useEffect, useMemo } from 'react'
4
+ import { onAuthRefresh } from '../../utils/auth_events'
4
5
  import { ResponseError } from '../../utils/response_error'
5
6
  import BlankState from '../primitive/blank_state_primitive'
6
7
 
@@ -39,17 +40,16 @@ class ErrorBoundary extends React.Component<PropsWithChildren<{ onReset?: () =>
39
40
 
40
41
  function ErrorView({ error, onReset }: { error: Error | ResponseError; onReset: () => void }) {
41
42
  const { reset } = useQueryErrorResetBoundary()
42
- useEffect(() => {
43
- if (!reset) return
44
43
 
45
- return () => {
46
- onReset()
47
- reset()
48
- }
44
+ const handleReset = useCallback(() => {
45
+ reset()
46
+ onReset()
49
47
  }, [reset, onReset])
50
48
 
49
+ useEffect(() => handleReset, [handleReset])
50
+
51
51
  if (error instanceof ResponseError) {
52
- return <ResponseErrorView response={error.response} onReset={onReset} />
52
+ return <ResponseErrorView response={error.response} onReset={handleReset} />
53
53
  }
54
54
 
55
55
  if (isNetworkError(error)) {
@@ -77,8 +77,9 @@ function isNetworkError(error: ResponseError | Error | TypeError | null) {
77
77
  return new RegExp(networkFailedMessages.join('|'), 'i').test(error.message)
78
78
  }
79
79
 
80
- function ResponseErrorView({ response }: { response: Response; onReset: () => void }) {
80
+ function ResponseErrorView({ response, onReset }: { response: Response; onReset: () => void }) {
81
81
  const { status } = response
82
+
82
83
  const heading = useMemo(() => {
83
84
  switch (status) {
84
85
  case 403:
@@ -101,6 +102,12 @@ function ResponseErrorView({ response }: { response: Response; onReset: () => vo
101
102
  }
102
103
  }, [status])
103
104
 
105
+ useEffect(() => {
106
+ if (status !== 401) return
107
+
108
+ return onAuthRefresh(onReset)
109
+ }, [status, onReset])
110
+
104
111
  return <ErrorContent heading={heading} body={body} />
105
112
  }
106
113
 
@@ -11,6 +11,7 @@ import { ApiClient, useApiClient } from '../hooks/use_api_client'
11
11
  import { useAppState } from '../hooks/use_app_state'
12
12
  import { appGrantsRequestArgs } from '../hooks/use_chat_permissions'
13
13
  import { getRequestQueryKey, RequestQueryKey } from '../hooks/use_suspense_api'
14
+ import { emitAuthRefresh } from '../utils/auth_events'
14
15
  import { ChatContext, ChatContextValue } from './chat_context'
15
16
 
16
17
  let apiClient: ApiClient | undefined
@@ -43,6 +44,8 @@ export function ApiProvider({ children }: ViewProps) {
43
44
  useEffect(() => {
44
45
  if (!sessionChanged) return
45
46
 
47
+ emitAuthRefresh()
48
+
46
49
  if (chatQueryClient.isFetching()) {
47
50
  chatQueryClient.invalidateQueries()
48
51
  return
@@ -0,0 +1,21 @@
1
+ type Listener = () => void
2
+ const listeners = new Set<Listener>()
3
+
4
+ export function onAuthRefresh(listener: Listener) {
5
+ listeners.add(listener)
6
+ return () => {
7
+ listeners.delete(listener)
8
+ }
9
+ }
10
+
11
+ export function emitAuthRefresh() {
12
+ listeners.forEach(fn => fn())
13
+ }
14
+
15
+ export function __resetAuthRefreshListenersForTests() {
16
+ listeners.clear()
17
+ }
18
+
19
+ export function __getAuthRefreshListenerCountForTests() {
20
+ return listeners.size
21
+ }
@@ -19,11 +19,7 @@ export class UploadUri {
19
19
  }
20
20
 
21
21
  get schema() {
22
- if (this.env === 'development') {
23
- return 'http'
24
- } else {
25
- return 'https'
26
- }
22
+ return 'https'
27
23
  }
28
24
 
29
25
  get host() {
package/src/utils/uri.ts CHANGED
@@ -20,11 +20,7 @@ export class Uri {
20
20
  }
21
21
 
22
22
  get schema() {
23
- if (this.env === 'development') {
24
- return 'http'
25
- } else {
26
- return 'https'
27
- }
23
+ return 'https'
28
24
  }
29
25
 
30
26
  get host() {