@planningcenter/chat-react-native 1.6.0 → 1.6.1-qa-27.0

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.
@@ -8,7 +8,7 @@ declare class ErrorBoundary extends React.Component<PropsWithChildren<{
8
8
  };
9
9
  componentDidCatch(error: any): void;
10
10
  handleError(error: any): void;
11
- render(): string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
11
+ render(): string | number | boolean | React.JSX.Element | Iterable<React.ReactNode> | null | undefined;
12
12
  }
13
13
  export default ErrorBoundary;
14
14
  //# sourceMappingURL=error_boundary.d.ts.map
@@ -1,10 +1,6 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
2
  import React from 'react';
3
3
  import { ViewProps } from 'react-native';
4
- import { Client } from '../utils';
5
4
  export declare const queryClient: QueryClient;
6
- export declare function ApiProvider({ children, client, sessionChanged, }: ViewProps & {
7
- client: Client;
8
- sessionChanged: boolean;
9
- }): React.JSX.Element;
5
+ export declare function ApiProvider({ children }: ViewProps): React.JSX.Element;
10
6
  //# sourceMappingURL=api_provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiC,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAoB,MAAM,OAAO,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAejC,eAAO,MAAM,WAAW,aAOtB,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,MAAM,EACN,cAAc,GACf,EAAE,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,qBAazD"}
1
+ {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiC,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAwC,MAAM,OAAO,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAiBxC,eAAO,MAAM,WAAW,aAOtB,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,qBAalD"}
@@ -1,5 +1,6 @@
1
1
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
2
- import React, { useEffect } from 'react';
2
+ import React, { useContext, useEffect, useRef } from 'react';
3
+ import { ChatContext } from './chat_context';
3
4
  let apiClient;
4
5
  const defaultQueryFn = ({ queryKey }) => {
5
6
  if (!apiClient) {
@@ -16,16 +17,27 @@ export const queryClient = new QueryClient({
16
17
  },
17
18
  },
18
19
  });
19
- export function ApiProvider({ children, client, sessionChanged, }) {
20
- useEffect(() => {
21
- apiClient = client;
22
- }, [client]);
23
- // TODO: CREATE CALLBACK TO INVALIDATE QUERIES
20
+ export function ApiProvider({ children }) {
21
+ const { token, env, client } = useContext(ChatContext);
22
+ const sessionChanged = useSessionChanged({ token, env });
23
+ apiClient = client;
24
24
  useEffect(() => {
25
25
  if (!sessionChanged)
26
26
  return;
27
- queryClient.invalidateQueries();
27
+ queryClient.clear();
28
28
  }, [sessionChanged]);
29
29
  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
30
30
  }
31
+ function useSessionChanged(value) {
32
+ const { token: newToken, env: newEnv } = value;
33
+ const { token: prevToken, env: prevEnv } = usePrevious(value);
34
+ return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv);
35
+ }
36
+ function usePrevious(value) {
37
+ const ref = useRef(value);
38
+ useEffect(() => {
39
+ ref.current = value;
40
+ }, [value]);
41
+ return ref.current;
42
+ }
31
43
  //# sourceMappingURL=api_provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.js","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAY,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKxC,IAAI,SAA6B,CAAA;AAEjC,MAAM,cAAc,GAAG,CAAC,EAAE,QAAQ,EAA0B,EAAE,EAAE;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAe,CAAA;IAEtC,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IACzC,cAAc,EAAE;QACd,OAAO,EAAE;YACP,OAAO,EAAE,cAAc;YACvB,KAAK,EAAE,CAAC;SACT;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,WAAW,CAAC,EAC1B,QAAQ,EACR,MAAM,EACN,cAAc,GAC0C;IACxD,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,GAAG,MAAM,CAAA;IACpB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,8CAA8C;IAC9C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,cAAc;YAAE,OAAM;QAE3B,WAAW,CAAC,iBAAiB,EAAE,CAAA;IACjC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA;IAEpB,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAA;AACnF,CAAC","sourcesContent":["import { QueryClient, QueryClientProvider, QueryKey } from '@tanstack/react-query'\nimport React, { useEffect } from 'react'\nimport { ViewProps } from 'react-native'\nimport { Client } from '../utils'\nimport { GetRequest } from '../utils/client/types'\n\nlet apiClient: Client | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const data = queryKey[0] as GetRequest\n\n return apiClient.get(data)\n}\n\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n queryFn: defaultQueryFn,\n retry: 3,\n },\n },\n})\n\nexport function ApiProvider({\n children,\n client,\n sessionChanged,\n}: ViewProps & { client: Client; sessionChanged: boolean }) {\n useEffect(() => {\n apiClient = client\n }, [client])\n\n // TODO: CREATE CALLBACK TO INVALIDATE QUERIES\n useEffect(() => {\n if (!sessionChanged) return\n\n queryClient.invalidateQueries()\n }, [sessionChanged])\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n}\n"]}
1
+ {"version":3,"file":"api_provider.js","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAY,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAI5D,OAAO,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAA;AAE9D,IAAI,SAA6B,CAAA;AAEjC,MAAM,cAAc,GAAG,CAAC,EAAE,QAAQ,EAA0B,EAAE,EAAE;IAC9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAe,CAAA;IAEtC,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IACzC,cAAc,EAAE;QACd,OAAO,EAAE;YACP,OAAO,EAAE,cAAc;YACvB,KAAK,EAAE,CAAC;SACT;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAa;IACjD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACtD,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IAExD,SAAS,GAAG,MAAM,CAAA;IAElB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,cAAc;YAAE,OAAM;QAE3B,WAAW,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA;IAEpB,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAA;AACnF,CAAC;AAED,SAAS,iBAAiB,CAAC,KAA8C;IACvE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAC9C,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,WAAW,CAAe,KAAK,CAAC,CAAA;IAE3E,OAAO,OAAO,CAAC,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,KAAK,OAAO,CAAC,CAAA;AAC/F,CAAC;AAED,SAAS,WAAW,CAAI,KAAK;IAC3B,MAAM,GAAG,GAAG,MAAM,CAAI,KAAK,CAAC,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;IACrB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC","sourcesContent":["import { QueryClient, QueryClientProvider, QueryKey } from '@tanstack/react-query'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { ViewProps } from 'react-native'\nimport { Client } from '../utils'\nimport { GetRequest } from '../utils/client/types'\nimport { ChatContext, ChatContextValue } from './chat_context'\n\nlet apiClient: Client | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const data = queryKey[0] as GetRequest\n\n return apiClient.get(data)\n}\n\nexport const queryClient = 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, client } = useContext(ChatContext)\n const sessionChanged = useSessionChanged({ token, env })\n\n apiClient = client\n\n useEffect(() => {\n if (!sessionChanged) return\n\n queryClient.clear()\n }, [sessionChanged])\n\n return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\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 return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)\n}\n\nfunction usePrevious<T>(value) {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n"]}
@@ -1,24 +1,26 @@
1
1
  import React from 'react';
2
2
  import { ColorSchemeName } from 'react-native';
3
3
  import { DeepPartial, OAuthToken } from '../types';
4
- import { DefaultTheme } from '../utils/theme';
5
4
  import { Client, ENV } from '../utils';
6
- type ChatContextValue = {
5
+ import { ChatTheme, DefaultTheme } from '../utils/theme';
6
+ export type ChatContextValue = {
7
7
  token?: OAuthToken;
8
8
  onTokenExpired: () => void;
9
- theme: any;
9
+ theme: ChatTheme;
10
10
  env?: ENV;
11
11
  client: Client;
12
12
  };
13
+ export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme'> {
14
+ theme: CreateChatThemeProps;
15
+ }
13
16
  export declare const ChatContext: React.Context<ChatContextValue>;
14
- export declare function ChatProvider({ children, value, }: {
17
+ export declare function ChatProvider({ children, value }: {
15
18
  children: any;
16
- value: Omit<ChatContextValue, 'client'>;
17
- }): React.JSX.Element | null;
18
- interface CreateChatThemeProps {
19
+ value: ChatProviderProps;
20
+ }): React.JSX.Element;
21
+ export interface CreateChatThemeProps {
19
22
  theme?: DeepPartial<DefaultTheme>;
20
23
  colorScheme?: ColorSchemeName;
21
24
  }
22
- export declare const useCreateChatTheme: ({ theme: customTheme, colorScheme: appColorScheme, }: CreateChatThemeProps) => any;
23
- export {};
25
+ export declare const useCreateChatTheme: ({ theme: customTheme, colorScheme: appColorScheme, }: CreateChatThemeProps) => ChatTheme;
24
26
  //# sourceMappingURL=chat_context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat_context.d.ts","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAoD,MAAM,OAAO,CAAA;AACxE,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAgB,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAG3D,OAAO,EAAE,MAAM,EAAE,GAAG,EAAW,MAAM,UAAU,CAAA;AAE/C,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,KAAK,EAAE,GAAG,CAAA;IACV,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AASD,eAAO,MAAM,WAAW,iCAMtB,CAAA;AAEF,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,GAAG,CAAA;IACb,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAA;CACxC,4BAiCA;AAmBD,UAAU,oBAAoB;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACjC,WAAW,CAAC,EAAE,eAAe,CAAA;CAC9B;AAED,eAAO,MAAM,kBAAkB,yDAG5B,oBAAoB,QAetB,CAAA"}
1
+ {"version":3,"file":"chat_context.d.ts","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAW,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAgB,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,KAAK,EAAE,SAAS,CAAA;IAChB,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,OAAO,CAAC;IACnF,KAAK,EAAE,oBAAoB,CAAA;CAC5B;AASD,eAAO,MAAM,WAAW,iCAMtB,CAAA;AAEF,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,qBAwB5F;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACjC,WAAW,CAAC,EAAE,eAAe,CAAA;CAC9B;AAED,eAAO,MAAM,kBAAkB,yDAG5B,oBAAoB,KAAG,SAYzB,CAAA"}
@@ -1,10 +1,8 @@
1
1
  import { merge } from 'lodash';
2
- import React, { createContext, useEffect, useMemo, useRef } from 'react';
2
+ import React, { createContext, useMemo } from 'react';
3
3
  import { useColorScheme } from 'react-native';
4
- import { defaultTheme } from '../utils/theme';
5
- import { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map';
6
- import { ApiProvider } from './api_provider';
7
4
  import { Client, Session } from '../utils';
5
+ import { defaultTheme } from '../utils/theme';
8
6
  const defaultChatClient = new Client({
9
7
  app: 'chat',
10
8
  session: new Session(),
@@ -12,15 +10,15 @@ const defaultChatClient = new Client({
12
10
  onTokenExpired: () => null,
13
11
  });
14
12
  export const ChatContext = createContext({
15
- theme: undefined,
13
+ theme: defaultTheme('light'),
16
14
  token: undefined,
17
15
  env: undefined,
18
16
  onTokenExpired: () => { },
19
17
  client: defaultChatClient,
20
18
  });
21
- export function ChatProvider({ children, value, }) {
19
+ export function ChatProvider({ children, value }) {
22
20
  const { env, token, onTokenExpired } = value;
23
- const theme = useCreateChatTheme(value.theme);
21
+ const theme = useCreateChatTheme(value.theme || {});
24
22
  const session = useMemo(() => new Session({ token, env }), [env, token]);
25
23
  const client = useMemo(() => new Client({
26
24
  app: 'chat',
@@ -28,7 +26,6 @@ export function ChatProvider({ children, value, }) {
28
26
  version: '2018-11-01',
29
27
  onTokenExpired,
30
28
  }), [onTokenExpired, session]);
31
- const sessionChanged = useSessionChanged({ token, env });
32
29
  const contextValue = {
33
30
  env,
34
31
  token,
@@ -36,38 +33,17 @@ export function ChatProvider({ children, value, }) {
36
33
  theme,
37
34
  client,
38
35
  };
39
- if (!Object.keys(value.token || {}).length)
40
- return null;
41
- return (<ChatContext.Provider value={contextValue}>
42
- <ApiProvider sessionChanged={sessionChanged} client={client}>
43
- {children}
44
- </ApiProvider>
45
- </ChatContext.Provider>);
46
- }
47
- function useSessionChanged(value) {
48
- const { token: newToken, env: newEnv } = value;
49
- const { token: prevToken, env: prevEnv } = usePrevious(value);
50
- return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv);
51
- }
52
- function usePrevious(value) {
53
- const ref = useRef(value);
54
- useEffect(() => {
55
- ref.current = value;
56
- }, [value]);
57
- return ref.current;
36
+ return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>;
58
37
  }
59
38
  export const useCreateChatTheme = ({ theme: customTheme = {}, colorScheme: appColorScheme, }) => {
60
39
  const internalColorScheme = useColorScheme() || 'light';
61
40
  const colorScheme = appColorScheme || internalColorScheme;
62
- const memoizedTheme = useMemo(() => {
63
- return {
64
- ...merge({}, defaultTheme(colorScheme), customTheme),
65
- colors: {
66
- ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),
67
- ...aliasTokensColorMap[colorScheme],
68
- },
69
- };
70
- }, [colorScheme, customTheme]);
71
- return memoizedTheme;
41
+ const theme = {
42
+ ...merge({}, defaultTheme(colorScheme), customTheme),
43
+ colors: {
44
+ ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),
45
+ },
46
+ };
47
+ return theme;
72
48
  };
73
49
  //# sourceMappingURL=chat_context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat_context.js","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"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","sourcesContent":["import { merge } from 'lodash'\nimport React, { createContext, useEffect, useMemo, useRef } from 'react'\nimport { ColorSchemeName, useColorScheme } from 'react-native'\nimport { DeepPartial, OAuthToken } from '../types'\nimport { defaultTheme, DefaultTheme } from '../utils/theme'\nimport { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map'\nimport { ApiProvider } from './api_provider'\nimport { Client, ENV, Session } from '../utils'\n\ntype ChatContextValue = {\n token?: OAuthToken\n onTokenExpired: () => void\n theme: any\n env?: ENV\n client: Client\n}\n\nconst defaultChatClient = new Client({\n app: 'chat',\n session: new Session(),\n version: '2018-11-01',\n onTokenExpired: () => null,\n})\n\nexport const ChatContext = createContext<ChatContextValue>({\n theme: undefined,\n token: undefined,\n env: undefined,\n onTokenExpired: () => {},\n client: defaultChatClient,\n})\n\nexport function ChatProvider({\n children,\n value,\n}: {\n children: any\n value: Omit<ChatContextValue, 'client'>\n}) {\n const { env, token, onTokenExpired } = value\n const theme = useCreateChatTheme(value.theme)\n const session = useMemo(() => new Session({ token, env }), [env, token])\n const client = useMemo(\n () =>\n new Client({\n app: 'chat',\n session,\n version: '2018-11-01',\n onTokenExpired,\n }),\n [onTokenExpired, session]\n )\n const sessionChanged = useSessionChanged({ token, env })\n\n const contextValue: ChatContextValue = {\n env,\n token,\n onTokenExpired,\n theme,\n client,\n }\n\n if (!Object.keys(value.token || {}).length) return null\n\n return (\n <ChatContext.Provider value={contextValue}>\n <ApiProvider sessionChanged={sessionChanged} client={client}>\n {children}\n </ApiProvider>\n </ChatContext.Provider>\n )\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 return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)\n}\n\nfunction usePrevious<T>(value) {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n\ninterface CreateChatThemeProps {\n theme?: DeepPartial<DefaultTheme>\n colorScheme?: ColorSchemeName\n}\n\nexport const useCreateChatTheme = ({\n theme: customTheme = {},\n colorScheme: appColorScheme,\n}: CreateChatThemeProps) => {\n const internalColorScheme = useColorScheme() || 'light'\n const colorScheme = appColorScheme || internalColorScheme\n\n const memoizedTheme = useMemo(() => {\n return {\n ...merge({}, defaultTheme(colorScheme), customTheme),\n colors: {\n ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),\n ...aliasTokensColorMap[colorScheme],\n },\n }\n }, [colorScheme, customTheme])\n\n return memoizedTheme\n}\n"]}
1
+ {"version":3,"file":"chat_context.js","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAmB,cAAc,EAAE,MAAM,cAAc,CAAA;AAE9D,OAAO,EAAE,MAAM,EAAO,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAa,YAAY,EAAgB,MAAM,gBAAgB,CAAA;AActE,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC;IACnC,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,IAAI,OAAO,EAAE;IACtB,OAAO,EAAE,YAAY;IACrB,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;CAC3B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAmB;IACzD,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC;IAC5B,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,SAAS;IACd,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;IACxB,MAAM,EAAE,iBAAiB;CAC1B,CAAC,CAAA;AAEF,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,EAA+C;IAC3F,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,KAAK,CAAA;IAC5C,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IACxE,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CACH,IAAI,MAAM,CAAC;QACT,GAAG,EAAE,MAAM;QACX,OAAO;QACP,OAAO,EAAE,YAAY;QACrB,cAAc;KACf,CAAC,EACJ,CAAC,cAAc,EAAE,OAAO,CAAC,CAC1B,CAAA;IAED,MAAM,YAAY,GAAqB;QACrC,GAAG;QACH,KAAK;QACL,cAAc;QACd,KAAK;QACL,MAAM;KACP,CAAA;IAED,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;AACrF,CAAC;AAOD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EACjC,KAAK,EAAE,WAAW,GAAG,EAAE,EACvB,WAAW,EAAE,cAAc,GACN,EAAa,EAAE;IACpC,MAAM,mBAAmB,GAAG,cAAc,EAAE,IAAI,OAAO,CAAA;IACvD,MAAM,WAAW,GAAG,cAAc,IAAI,mBAAmB,CAAA;IAEzD,MAAM,KAAK,GAAG;QACZ,GAAG,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;QACpD,MAAM,EAAE;YACN,GAAG,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC;SACpE;KACF,CAAA;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA","sourcesContent":["import { merge } from 'lodash'\nimport React, { createContext, useMemo } from 'react'\nimport { ColorSchemeName, useColorScheme } from 'react-native'\nimport { DeepPartial, OAuthToken } from '../types'\nimport { Client, ENV, Session } from '../utils'\nimport { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'\n\nexport type ChatContextValue = {\n token?: OAuthToken\n onTokenExpired: () => void\n theme: ChatTheme\n env?: ENV\n client: Client\n}\n\nexport interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme'> {\n theme: CreateChatThemeProps\n}\n\nconst defaultChatClient = new Client({\n app: 'chat',\n session: new Session(),\n version: '2018-11-01',\n onTokenExpired: () => null,\n})\n\nexport const ChatContext = createContext<ChatContextValue>({\n theme: defaultTheme('light'),\n token: undefined,\n env: undefined,\n onTokenExpired: () => {},\n client: defaultChatClient,\n})\n\nexport function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {\n const { env, token, onTokenExpired } = value\n const theme = useCreateChatTheme(value.theme || {})\n const session = useMemo(() => new Session({ token, env }), [env, token])\n const client = useMemo(\n () =>\n new Client({\n app: 'chat',\n session,\n version: '2018-11-01',\n onTokenExpired,\n }),\n [onTokenExpired, session]\n )\n\n const contextValue: ChatContextValue = {\n env,\n token,\n onTokenExpired,\n theme,\n client,\n }\n\n return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>\n}\n\nexport interface CreateChatThemeProps {\n theme?: DeepPartial<DefaultTheme>\n colorScheme?: ColorSchemeName\n}\n\nexport const useCreateChatTheme = ({\n theme: customTheme = {},\n colorScheme: appColorScheme,\n}: CreateChatThemeProps): ChatTheme => {\n const internalColorScheme = useColorScheme() || 'light'\n const colorScheme = appColorScheme || internalColorScheme\n\n const theme = {\n ...merge({}, defaultTheme(colorScheme), customTheme),\n colors: {\n ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),\n },\n }\n\n return theme\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"screenLayout.d.ts","sourceRoot":"","sources":["../../src/navigation/screenLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;CAAE,qBAU1E"}
1
+ {"version":3,"file":"screenLayout.d.ts","sourceRoot":"","sources":["../../src/navigation/screenLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;CAAE,qBAY1E"}
@@ -3,11 +3,14 @@ import { QueryErrorResetBoundary } from '@tanstack/react-query';
3
3
  import ErrorBoundary from '../components/error_boundary';
4
4
  import { Suspense } from 'react';
5
5
  import { Text } from '../components/display';
6
+ import { ApiProvider } from '../contexts';
6
7
  export function ScreenLayout({ children }) {
7
- return (<QueryErrorResetBoundary>
8
- {({ reset }) => (<ErrorBoundary onReset={reset}>
9
- <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>
10
- </ErrorBoundary>)}
11
- </QueryErrorResetBoundary>);
8
+ return (<ApiProvider>
9
+ <QueryErrorResetBoundary>
10
+ {({ reset }) => (<ErrorBoundary onReset={reset}>
11
+ <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>
12
+ </ErrorBoundary>)}
13
+ </QueryErrorResetBoundary>
14
+ </ApiProvider>);
12
15
  }
13
16
  //# sourceMappingURL=screenLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenLayout.js","sourceRoot":"","sources":["../../src/navigation/screenLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,aAAa,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAE5C,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAoC;IACzE,OAAO,CACL,CAAC,uBAAuB,CACtB;MAAA,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CACd,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAC5B;UAAA,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,CACnE;QAAA,EAAE,aAAa,CAAC,CACjB,CACH;IAAA,EAAE,uBAAuB,CAAC,CAC3B,CAAA;AACH,CAAC","sourcesContent":["import React from 'react'\nimport { QueryErrorResetBoundary } from '@tanstack/react-query'\nimport ErrorBoundary from '../components/error_boundary'\nimport { Suspense } from 'react'\nimport { Text } from '../components/display'\n\nexport function ScreenLayout({ children }: { children: React.ReactElement }) {\n return (\n <QueryErrorResetBoundary>\n {({ reset }) => (\n <ErrorBoundary onReset={reset}>\n <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>\n </ErrorBoundary>\n )}\n </QueryErrorResetBoundary>\n )\n}\n"]}
1
+ {"version":3,"file":"screenLayout.js","sourceRoot":"","sources":["../../src/navigation/screenLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,aAAa,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAoC;IACzE,OAAO,CACL,CAAC,WAAW,CACV;MAAA,CAAC,uBAAuB,CACtB;QAAA,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CACd,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAC5B;YAAA,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,CACnE;UAAA,EAAE,aAAa,CAAC,CACjB,CACH;MAAA,EAAE,uBAAuB,CAC3B;IAAA,EAAE,WAAW,CAAC,CACf,CAAA;AACH,CAAC","sourcesContent":["import React from 'react'\nimport { QueryErrorResetBoundary } from '@tanstack/react-query'\nimport ErrorBoundary from '../components/error_boundary'\nimport { Suspense } from 'react'\nimport { Text } from '../components/display'\nimport { ApiProvider } from '../contexts'\n\nexport function ScreenLayout({ children }: { children: React.ReactElement }) {\n return (\n <ApiProvider>\n <QueryErrorResetBoundary>\n {({ reset }) => (\n <ErrorBoundary onReset={reset}>\n <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>\n </ErrorBoundary>\n )}\n </QueryErrorResetBoundary>\n </ApiProvider>\n )\n}\n"]}
@@ -23,7 +23,7 @@ export interface DefaultTheme {
23
23
  text: TextStyle;
24
24
  };
25
25
  }
26
- export declare const defaultTheme: (colorScheme: ColorSchemeName) => DefaultTheme;
26
+ export declare const defaultTheme: (colorScheme: ColorSchemeName) => ChatTheme;
27
27
  export type TemporaryDefaultColorsType = Partial<ChatColors>;
28
28
  interface ChatColors {
29
29
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAC5B,CAAC,OAAO,mBAAmB,CAAC,KAAK,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAA;CACvE;AAED;;;;;;;;;;;;gDAYgD;AAEhD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAA;IAClB,qBAAqB,EAAE;QACrB,SAAS,EAAE,SAAS,CAAA;QACpB,IAAI,EAAE,SAAS,CAAA;KAChB,CAAA;CACF;AAED,eAAO,MAAM,YAAY,gBAAiB,eAAe,KAAG,YAgB3D,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AAE5D,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAC5B,CAAC,OAAO,mBAAmB,CAAC,KAAK,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAA;CACvE;AAED;;;;;;;;;;;;gDAYgD;AAEhD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAA;IAClB,qBAAqB,EAAE;QACrB,SAAS,EAAE,SAAS,CAAA;QACpB,IAAI,EAAE,SAAS,CAAA;KAChB,CAAA;CACF;AAED,eAAO,MAAM,YAAY,gBAAiB,eAAe,KAAG,SAqB3D,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AAE5D,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB"}
@@ -2,8 +2,12 @@ import { tokens } from '../vendor/tapestry/tokens';
2
2
  import { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map';
3
3
  export const defaultTheme = (colorScheme) => {
4
4
  const scheme = colorScheme || 'light';
5
+ const defaultColors = {
6
+ ...chatThemeColorMap[scheme],
7
+ ...aliasTokensColorMap[scheme],
8
+ };
5
9
  return {
6
- colors: chatThemeColorMap[scheme],
10
+ colors: defaultColors,
7
11
  temporaryProductBadge: {
8
12
  container: {
9
13
  paddingHorizontal: tokens.spacing1,
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AA6B/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAA4B,EAAgB,EAAE;IACzE,MAAM,MAAM,GAAG,WAAW,IAAI,OAAO,CAAA;IAErC,OAAO;QACL,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC;QACjC,qBAAqB,EAAE;YACrB,SAAS,EAAE;gBACT,iBAAiB,EAAE,MAAM,CAAC,QAAQ;gBAClC,eAAe,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,mBAAmB;gBAChE,WAAW,EAAE,MAAM,CAAC,iBAAiB;aACtC;YACD,IAAI,EAAE;gBACJ,SAAS,EAAE,QAAQ;aACpB;SACF;KACF,CAAA;AACH,CAAC,CAAA;AAYD,MAAM,eAAe,GAAe;IAClC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,MAAM,CAAC,2BAA2B;IAC/C,SAAS,EAAE,KAAK;CACjB,CAAA;AAED,MAAM,cAAc,GAAe;IACjC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,MAAM,CAAC,+BAA+B;IACnD,SAAS,EAAE,MAAM;CAClB,CAAA;AAED,MAAM,iBAAiB,GAAG;IACxB,KAAK,EAAE,eAAe;IACtB,IAAI,EAAE,cAAc;CACrB,CAAA","sourcesContent":["import { TextStyle, ViewStyle, ColorSchemeName } from 'react-native'\nimport { tokens } from '../vendor/tapestry/tokens'\nimport { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map'\n\nexport interface ChatTheme extends DefaultTheme {\n colors: DefaultTheme['colors'] &\n (typeof aliasTokensColorMap.light | typeof aliasTokensColorMap.dark)\n}\n\n/** =============================================\n NOTE: The specific values for `colors` and the `productBadge` are temporary examples that can be replaced once we start building out UI. This line's comment can be removed at that time too.\n\n The default theme is intended to support two types of customizations:\n 1. Specific color properties for a chat component (eg. `primaryButtonBackgroundColor`)\n 2. Any styles for a specific component. (Use only one level of nesting.)\n ```\n primaryButton: {\n container: ViewStyle\n text: TextStyle\n }\n ```\n============================================= */\n\nexport interface DefaultTheme {\n colors: ChatColors\n temporaryProductBadge: {\n container: ViewStyle\n text: TextStyle\n }\n}\n\nexport const defaultTheme = (colorScheme: ColorSchemeName): DefaultTheme => {\n const scheme = colorScheme || 'light'\n\n return {\n colors: chatThemeColorMap[scheme],\n temporaryProductBadge: {\n container: {\n paddingHorizontal: tokens.spacing1,\n backgroundColor: aliasTokensColorMap[scheme].fillColorNeutral070,\n borderWidth: tokens.borderSizeDefault,\n },\n text: {\n textAlign: 'center',\n },\n },\n }\n}\n\nexport type TemporaryDefaultColorsType = Partial<ChatColors>\n\ninterface ChatColors {\n name: string\n buttonStart: string | undefined\n buttonEnd: string | undefined\n interaction: string\n testColor: string\n}\n\nconst colorsChatLight: ChatColors = {\n name: 'light',\n buttonStart: undefined,\n buttonEnd: undefined,\n interaction: tokens.fillColorInteractionDefault,\n testColor: 'red',\n}\n\nconst colorsChatDark: ChatColors = {\n name: 'dark',\n buttonStart: undefined,\n buttonEnd: undefined,\n interaction: tokens.fillColorInteractionDefaultDark,\n testColor: 'blue',\n}\n\nconst chatThemeColorMap = {\n light: colorsChatLight,\n dark: colorsChatDark,\n}\n"]}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/utils/theme.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAA;AA6B/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAA4B,EAAa,EAAE;IACtE,MAAM,MAAM,GAAG,WAAW,IAAI,OAAO,CAAA;IAErC,MAAM,aAAa,GAAG;QACpB,GAAG,iBAAiB,CAAC,MAAM,CAAC;QAC5B,GAAG,mBAAmB,CAAC,MAAM,CAAC;KAC/B,CAAA;IAED,OAAO;QACL,MAAM,EAAE,aAAa;QACrB,qBAAqB,EAAE;YACrB,SAAS,EAAE;gBACT,iBAAiB,EAAE,MAAM,CAAC,QAAQ;gBAClC,eAAe,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,mBAAmB;gBAChE,WAAW,EAAE,MAAM,CAAC,iBAAiB;aACtC;YACD,IAAI,EAAE;gBACJ,SAAS,EAAE,QAAQ;aACpB;SACF;KACF,CAAA;AACH,CAAC,CAAA;AAYD,MAAM,eAAe,GAAe;IAClC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,MAAM,CAAC,2BAA2B;IAC/C,SAAS,EAAE,KAAK;CACjB,CAAA;AAED,MAAM,cAAc,GAAe;IACjC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,MAAM,CAAC,+BAA+B;IACnD,SAAS,EAAE,MAAM;CAClB,CAAA;AAED,MAAM,iBAAiB,GAAG;IACxB,KAAK,EAAE,eAAe;IACtB,IAAI,EAAE,cAAc;CACrB,CAAA","sourcesContent":["import { TextStyle, ViewStyle, ColorSchemeName } from 'react-native'\nimport { tokens } from '../vendor/tapestry/tokens'\nimport { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map'\n\nexport interface ChatTheme extends DefaultTheme {\n colors: DefaultTheme['colors'] &\n (typeof aliasTokensColorMap.light | typeof aliasTokensColorMap.dark)\n}\n\n/** =============================================\n NOTE: The specific values for `colors` and the `productBadge` are temporary examples that can be replaced once we start building out UI. This line's comment can be removed at that time too.\n\n The default theme is intended to support two types of customizations:\n 1. Specific color properties for a chat component (eg. `primaryButtonBackgroundColor`)\n 2. Any styles for a specific component. (Use only one level of nesting.)\n ```\n primaryButton: {\n container: ViewStyle\n text: TextStyle\n }\n ```\n============================================= */\n\nexport interface DefaultTheme {\n colors: ChatColors\n temporaryProductBadge: {\n container: ViewStyle\n text: TextStyle\n }\n}\n\nexport const defaultTheme = (colorScheme: ColorSchemeName): ChatTheme => {\n const scheme = colorScheme || 'light'\n\n const defaultColors = {\n ...chatThemeColorMap[scheme],\n ...aliasTokensColorMap[scheme],\n }\n\n return {\n colors: defaultColors,\n temporaryProductBadge: {\n container: {\n paddingHorizontal: tokens.spacing1,\n backgroundColor: aliasTokensColorMap[scheme].fillColorNeutral070,\n borderWidth: tokens.borderSizeDefault,\n },\n text: {\n textAlign: 'center',\n },\n },\n }\n}\n\nexport type TemporaryDefaultColorsType = Partial<ChatColors>\n\ninterface ChatColors {\n name: string\n buttonStart: string | undefined\n buttonEnd: string | undefined\n interaction: string\n testColor: string\n}\n\nconst colorsChatLight: ChatColors = {\n name: 'light',\n buttonStart: undefined,\n buttonEnd: undefined,\n interaction: tokens.fillColorInteractionDefault,\n testColor: 'red',\n}\n\nconst colorsChatDark: ChatColors = {\n name: 'dark',\n buttonStart: undefined,\n buttonEnd: undefined,\n interaction: tokens.fillColorInteractionDefaultDark,\n testColor: 'blue',\n}\n\nconst chatThemeColorMap = {\n light: colorsChatLight,\n dark: colorsChatDark,\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "1.6.0",
3
+ "version": "1.6.1-qa-27.0",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -46,5 +46,5 @@
46
46
  "prettier": "^3.4.2",
47
47
  "typescript": "<5.6.0"
48
48
  },
49
- "gitHead": "885163bbbf48e2583d601930ffba8dd9f1fc962b"
49
+ "gitHead": "a9aa095bb68dc974460d9dad35fff2bd3770954a"
50
50
  }
@@ -1,12 +1,13 @@
1
1
  import { renderHook } from '@testing-library/react-native'
2
2
  import { useTheme } from '../../hooks'
3
- import { ChatProvider } from '../../contexts'
3
+ import { ChatProvider, CreateChatThemeProps } from '../../contexts'
4
4
  import React from 'react'
5
5
 
6
- const theme = {
7
- colors: {
8
- primary: '#0070f3',
6
+ let themeProps: CreateChatThemeProps = {
7
+ theme: {
8
+ colors: {},
9
9
  },
10
+ colorScheme: 'light',
10
11
  }
11
12
 
12
13
  const Wrapper = ({ children }: { children: React.ReactNode }) => {
@@ -22,7 +23,7 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => {
22
23
  token_type: '',
23
24
  },
24
25
  onTokenExpired: () => null,
25
- theme,
26
+ theme: themeProps,
26
27
  }}
27
28
  >
28
29
  {children}
@@ -31,7 +32,40 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => {
31
32
  }
32
33
 
33
34
  test('should use theme', () => {
35
+ themeProps = {}
34
36
  const { result } = renderHook(() => useTheme(), { wrapper: Wrapper })
35
37
 
36
38
  expect(result.current).toBeDefined()
37
39
  })
40
+
41
+ describe('configurable theme', () => {
42
+ test('should not error is theme is undefined', () => {
43
+ //@ts-expect-error
44
+ themeProps = undefined
45
+ const { result } = renderHook(() => useTheme(), { wrapper: Wrapper })
46
+
47
+ expect(result.current).toBeDefined()
48
+ expect(result.current.colors.testColor).toBe('red')
49
+ expect(result.current.colors.interaction).toBeDefined()
50
+ expect(result.current.colors.buttonStart).toBeUndefined()
51
+ expect(result.current.colors.buttonEnd).toBeUndefined()
52
+ })
53
+
54
+ test('should deliver custom stuffs', () => {
55
+ themeProps = {
56
+ theme: {
57
+ colors: {
58
+ testColor: 'fuscia',
59
+ buttonStart: 'blue',
60
+ buttonEnd: 'red',
61
+ },
62
+ },
63
+ colorScheme: 'dark',
64
+ }
65
+ const { result } = renderHook(() => useTheme(), { wrapper: Wrapper })
66
+
67
+ expect(result.current.colors.testColor).toBe('fuscia')
68
+ expect(result.current.colors.buttonStart).toBe('blue')
69
+ expect(result.current.colors.buttonEnd).toBe('red')
70
+ })
71
+ })
@@ -1,8 +1,9 @@
1
1
  import { QueryClient, QueryClientProvider, QueryKey } from '@tanstack/react-query'
2
- import React, { useEffect } from 'react'
2
+ import React, { useContext, useEffect, useRef } from 'react'
3
3
  import { ViewProps } from 'react-native'
4
4
  import { Client } from '../utils'
5
5
  import { GetRequest } from '../utils/client/types'
6
+ import { ChatContext, ChatContextValue } from './chat_context'
6
7
 
7
8
  let apiClient: Client | undefined
8
9
 
@@ -25,21 +26,34 @@ export const queryClient = new QueryClient({
25
26
  },
26
27
  })
27
28
 
28
- export function ApiProvider({
29
- children,
30
- client,
31
- sessionChanged,
32
- }: ViewProps & { client: Client; sessionChanged: boolean }) {
33
- useEffect(() => {
34
- apiClient = client
35
- }, [client])
29
+ export function ApiProvider({ children }: ViewProps) {
30
+ const { token, env, client } = useContext(ChatContext)
31
+ const sessionChanged = useSessionChanged({ token, env })
32
+
33
+ apiClient = client
36
34
 
37
- // TODO: CREATE CALLBACK TO INVALIDATE QUERIES
38
35
  useEffect(() => {
39
36
  if (!sessionChanged) return
40
37
 
41
- queryClient.invalidateQueries()
38
+ queryClient.clear()
42
39
  }, [sessionChanged])
43
40
 
44
41
  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
45
42
  }
43
+
44
+ function useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {
45
+ const { token: newToken, env: newEnv } = value
46
+ const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)
47
+
48
+ return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)
49
+ }
50
+
51
+ function usePrevious<T>(value) {
52
+ const ref = useRef<T>(value)
53
+
54
+ useEffect(() => {
55
+ ref.current = value
56
+ }, [value])
57
+
58
+ return ref.current
59
+ }
@@ -1,20 +1,22 @@
1
1
  import { merge } from 'lodash'
2
- import React, { createContext, useEffect, useMemo, useRef } from 'react'
2
+ import React, { createContext, useMemo } from 'react'
3
3
  import { ColorSchemeName, useColorScheme } from 'react-native'
4
4
  import { DeepPartial, OAuthToken } from '../types'
5
- import { defaultTheme, DefaultTheme } from '../utils/theme'
6
- import { aliasTokensColorMap } from '../vendor/tapestry/alias_tokens_color_map'
7
- import { ApiProvider } from './api_provider'
8
5
  import { Client, ENV, Session } from '../utils'
6
+ import { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'
9
7
 
10
- type ChatContextValue = {
8
+ export type ChatContextValue = {
11
9
  token?: OAuthToken
12
10
  onTokenExpired: () => void
13
- theme: any
11
+ theme: ChatTheme
14
12
  env?: ENV
15
13
  client: Client
16
14
  }
17
15
 
16
+ export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme'> {
17
+ theme: CreateChatThemeProps
18
+ }
19
+
18
20
  const defaultChatClient = new Client({
19
21
  app: 'chat',
20
22
  session: new Session(),
@@ -23,22 +25,16 @@ const defaultChatClient = new Client({
23
25
  })
24
26
 
25
27
  export const ChatContext = createContext<ChatContextValue>({
26
- theme: undefined,
28
+ theme: defaultTheme('light'),
27
29
  token: undefined,
28
30
  env: undefined,
29
31
  onTokenExpired: () => {},
30
32
  client: defaultChatClient,
31
33
  })
32
34
 
33
- export function ChatProvider({
34
- children,
35
- value,
36
- }: {
37
- children: any
38
- value: Omit<ChatContextValue, 'client'>
39
- }) {
35
+ export function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {
40
36
  const { env, token, onTokenExpired } = value
41
- const theme = useCreateChatTheme(value.theme)
37
+ const theme = useCreateChatTheme(value.theme || {})
42
38
  const session = useMemo(() => new Session({ token, env }), [env, token])
43
39
  const client = useMemo(
44
40
  () =>
@@ -50,7 +46,6 @@ export function ChatProvider({
50
46
  }),
51
47
  [onTokenExpired, session]
52
48
  )
53
- const sessionChanged = useSessionChanged({ token, env })
54
49
 
55
50
  const contextValue: ChatContextValue = {
56
51
  env,
@@ -60,35 +55,10 @@ export function ChatProvider({
60
55
  client,
61
56
  }
62
57
 
63
- if (!Object.keys(value.token || {}).length) return null
64
-
65
- return (
66
- <ChatContext.Provider value={contextValue}>
67
- <ApiProvider sessionChanged={sessionChanged} client={client}>
68
- {children}
69
- </ApiProvider>
70
- </ChatContext.Provider>
71
- )
72
- }
73
-
74
- function useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {
75
- const { token: newToken, env: newEnv } = value
76
- const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)
77
-
78
- return Boolean(prevToken && newToken !== prevToken) || Boolean(prevEnv && newEnv !== prevEnv)
79
- }
80
-
81
- function usePrevious<T>(value) {
82
- const ref = useRef<T>(value)
83
-
84
- useEffect(() => {
85
- ref.current = value
86
- }, [value])
87
-
88
- return ref.current
58
+ return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>
89
59
  }
90
60
 
91
- interface CreateChatThemeProps {
61
+ export interface CreateChatThemeProps {
92
62
  theme?: DeepPartial<DefaultTheme>
93
63
  colorScheme?: ColorSchemeName
94
64
  }
@@ -96,19 +66,16 @@ interface CreateChatThemeProps {
96
66
  export const useCreateChatTheme = ({
97
67
  theme: customTheme = {},
98
68
  colorScheme: appColorScheme,
99
- }: CreateChatThemeProps) => {
69
+ }: CreateChatThemeProps): ChatTheme => {
100
70
  const internalColorScheme = useColorScheme() || 'light'
101
71
  const colorScheme = appColorScheme || internalColorScheme
102
72
 
103
- const memoizedTheme = useMemo(() => {
104
- return {
105
- ...merge({}, defaultTheme(colorScheme), customTheme),
106
- colors: {
107
- ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),
108
- ...aliasTokensColorMap[colorScheme],
109
- },
110
- }
111
- }, [colorScheme, customTheme])
73
+ const theme = {
74
+ ...merge({}, defaultTheme(colorScheme), customTheme),
75
+ colors: {
76
+ ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),
77
+ },
78
+ }
112
79
 
113
- return memoizedTheme
80
+ return theme
114
81
  }
@@ -3,15 +3,18 @@ import { QueryErrorResetBoundary } from '@tanstack/react-query'
3
3
  import ErrorBoundary from '../components/error_boundary'
4
4
  import { Suspense } from 'react'
5
5
  import { Text } from '../components/display'
6
+ import { ApiProvider } from '../contexts'
6
7
 
7
8
  export function ScreenLayout({ children }: { children: React.ReactElement }) {
8
9
  return (
9
- <QueryErrorResetBoundary>
10
- {({ reset }) => (
11
- <ErrorBoundary onReset={reset}>
12
- <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>
13
- </ErrorBoundary>
14
- )}
15
- </QueryErrorResetBoundary>
10
+ <ApiProvider>
11
+ <QueryErrorResetBoundary>
12
+ {({ reset }) => (
13
+ <ErrorBoundary onReset={reset}>
14
+ <Suspense fallback={<Text>loading...</Text>}>{children}</Suspense>
15
+ </ErrorBoundary>
16
+ )}
17
+ </QueryErrorResetBoundary>
18
+ </ApiProvider>
16
19
  )
17
20
  }
@@ -29,11 +29,16 @@ export interface DefaultTheme {
29
29
  }
30
30
  }
31
31
 
32
- export const defaultTheme = (colorScheme: ColorSchemeName): DefaultTheme => {
32
+ export const defaultTheme = (colorScheme: ColorSchemeName): ChatTheme => {
33
33
  const scheme = colorScheme || 'light'
34
34
 
35
+ const defaultColors = {
36
+ ...chatThemeColorMap[scheme],
37
+ ...aliasTokensColorMap[scheme],
38
+ }
39
+
35
40
  return {
36
- colors: chatThemeColorMap[scheme],
41
+ colors: defaultColors,
37
42
  temporaryProductBadge: {
38
43
  container: {
39
44
  paddingHorizontal: tokens.spacing1,