react-native-seel-widget 0.1.0 → 0.1.3

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.
Files changed (68) hide show
  1. package/package.json +44 -7
  2. package/src/assets/images/accredited.png +0 -0
  3. package/src/assets/images/background_image.jpg +0 -0
  4. package/src/assets/images/button_close.png +0 -0
  5. package/src/assets/images/button_close_background.png +0 -0
  6. package/src/assets/images/checkbox_normal.png +0 -0
  7. package/src/assets/images/checkbox_selected.png +0 -0
  8. package/src/assets/images/close_white.png +0 -0
  9. package/src/assets/images/ic_launcher.png +0 -0
  10. package/src/assets/images/icon_arrow_left.png +0 -0
  11. package/src/assets/images/icon_bg_select.png +0 -0
  12. package/src/assets/images/icon_check_selected_black.png +0 -0
  13. package/src/assets/images/icon_select.png +0 -0
  14. package/src/assets/images/info_black.png +0 -0
  15. package/src/assets/images/seel_icon.png +0 -0
  16. package/src/assets/images/seel_logo.png +0 -0
  17. package/src/assets/images/seel_word.png +0 -0
  18. package/src/assets/images/tick_small_minor.png +0 -0
  19. package/src/constants/key_value.ts +48 -0
  20. package/src/constants/network_request_statue_enum.ts +13 -0
  21. package/src/core/SeelWidgetSDK.ts +103 -0
  22. package/src/dto/EventsRequest.ts +71 -0
  23. package/src/dto/EventsResponse.ts +13 -0
  24. package/src/dto/IEvents.ts +51 -0
  25. package/src/dto/IQuotes.ts +36 -0
  26. package/src/dto/IQuotesRequest.ts +220 -0
  27. package/src/dto/IQuotesResponse.ts +111 -0
  28. package/src/network/request.ts +214 -0
  29. package/src/ui/coverage-info-footer.tsx +186 -0
  30. package/src/ui/gradient-animation-text.tsx +185 -0
  31. package/src/ui/gradient-animation-view.tsx +150 -0
  32. package/src/ui/index.ts +4 -0
  33. package/src/ui/seel-wfp-info-view.tsx +351 -0
  34. package/src/ui/seel-wfp-title-view.tsx +388 -0
  35. package/src/ui/seel-wfp-widget.tsx +270 -0
  36. package/src/utils/format_util.ts +117 -0
  37. package/src/utils/http_util.ts +30 -0
  38. package/src/utils/storage_util.ts +42 -0
  39. package/src/utils/uuid.ts +18 -0
  40. package/.editorconfig +0 -15
  41. package/.gitattributes +0 -3
  42. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -67
  43. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  44. package/.github/actions/setup/action.yml +0 -36
  45. package/.github/workflows/ci.yml +0 -72
  46. package/.nvmrc +0 -1
  47. package/.watchmanconfig +0 -1
  48. package/.yarn/releases/yarn-4.11.0.cjs +0 -942
  49. package/.yarnrc.yml +0 -4
  50. package/CODE_OF_CONDUCT.md +0 -133
  51. package/CONTRIBUTING.md +0 -134
  52. package/babel.config.js +0 -12
  53. package/eslint.config.mjs +0 -29
  54. package/example/app.json +0 -31
  55. package/example/assets/adaptive-icon.png +0 -0
  56. package/example/assets/favicon.png +0 -0
  57. package/example/assets/icon.png +0 -0
  58. package/example/assets/splash-icon.png +0 -0
  59. package/example/babel.config.js +0 -16
  60. package/example/index.js +0 -8
  61. package/example/metro.config.js +0 -20
  62. package/example/package.json +0 -25
  63. package/example/src/App.tsx +0 -20
  64. package/example/tsconfig.json +0 -6
  65. package/lefthook.yml +0 -16
  66. package/src/__tests__/index.test.tsx +0 -1
  67. package/tsconfig.build.json +0 -4
  68. package/tsconfig.json +0 -30
@@ -0,0 +1,117 @@
1
+ export const moneyFormat = (money: any, currency: string, options: any) => {
2
+ try {
3
+ // 解构options参数,提供默认值
4
+ const { showCurrency = true, locale = '', fallbackValue = '-' } = options;
5
+ // 如果没传 currency 或者传空串,就认为不需要做货币格式化
6
+ const propsCurrency = currency || '';
7
+ let targetMoney = money;
8
+ // 如果money是null, undefined或空字符串,或者不是数字或者字符串,直接返回 fallbackValue
9
+ if (
10
+ targetMoney === null ||
11
+ targetMoney === undefined ||
12
+ targetMoney === ''
13
+ ) {
14
+ return fallbackValue;
15
+ }
16
+ // 完善判断非数字情况
17
+ if (typeof money === 'string') {
18
+ targetMoney = Number(money); // 或者可以使用 parseFloat(money)
19
+ }
20
+ // 如果转换后的值不是有效的数字,返回 fallbackValue
21
+ if (Number.isNaN(targetMoney)) return fallbackValue;
22
+ // 如果没有传入currency,把原数据返回,如果不是数字则显示 fallbackValue
23
+ if (!propsCurrency) return targetMoney;
24
+ // 检查 Intl.NumberFormat 是否支持
25
+ if (
26
+ typeof Intl === 'undefined' ||
27
+ typeof Intl.NumberFormat === 'undefined'
28
+ ) {
29
+ // 降级处理:简单格式化
30
+ if (showCurrency) {
31
+ return `${targetMoney} ${propsCurrency}`;
32
+ }
33
+ return `${targetMoney}`;
34
+ }
35
+ // 币种locale 映射
36
+ const currencyLocaleMap: any = {
37
+ USD: 'en-US',
38
+ CAD: 'en-CA',
39
+ AUD: 'en-AU',
40
+ EUR: 'de-DE',
41
+ GBP: 'en-GB',
42
+ NZD: 'en-NZ',
43
+ HKD: 'zh-HK',
44
+ SGD: 'zh-SG',
45
+ DKK: 'da-DK',
46
+ };
47
+ const usedLocale =
48
+ locale ||
49
+ (propsCurrency.toUpperCase() in currencyLocaleMap
50
+ ? currencyLocaleMap[propsCurrency.toUpperCase()]
51
+ : '') ||
52
+ 'en-US';
53
+ const numberFormat = new Intl.NumberFormat(usedLocale, {
54
+ style: 'currency',
55
+ currency: propsCurrency,
56
+ minimumFractionDigits: 2,
57
+ maximumFractionDigits: 2,
58
+ });
59
+ // 检查 formatToParts 是否支持
60
+ if (typeof numberFormat.formatToParts !== 'function') {
61
+ // 降级处理:使用 format 方法
62
+ const formatted = numberFormat.format(targetMoney || 0);
63
+ if (showCurrency) {
64
+ return `${formatted} ${propsCurrency}`;
65
+ }
66
+ return formatted;
67
+ }
68
+ // 获取货币格式化后的各个部分,包括货币符号
69
+ const parts = numberFormat.formatToParts(targetMoney || 0);
70
+ // 兼容性处理:避免使用可选链操作符
71
+ const currencyPart = parts.find((part) => part.type === 'currency');
72
+ const currencySymbol = currencyPart ? currencyPart.value : '';
73
+ // 特殊处理 HKD 货币,使用 $ 符号而不是 HK$
74
+ if (propsCurrency.toUpperCase() === 'HKD') {
75
+ const formattedNumber = numberFormat
76
+ .format(targetMoney || 0)
77
+ .replace(currencySymbol, '$')
78
+ .trim();
79
+ if (showCurrency) {
80
+ return `${formattedNumber} ${propsCurrency}`;
81
+ }
82
+ return formattedNumber;
83
+ }
84
+ // 判断货币符号是否与 currency 一致
85
+ if (currencySymbol === propsCurrency) {
86
+ if (showCurrency) {
87
+ return `${targetMoney} ${propsCurrency}`; // 如果符号一致且需要显示货币符号,返回 money + currency
88
+ }
89
+ return `${targetMoney}`; // 如果符号一致但不需要显示货币符号,返回只有 money
90
+ }
91
+ if (showCurrency) {
92
+ return `${numberFormat.format(targetMoney || 0)} ${propsCurrency}`;
93
+ }
94
+ return `${numberFormat.format(targetMoney || 0)}`;
95
+ } catch (error) {
96
+ console.warn('moneyFormat error:', error);
97
+ // 降级处理:返回简单的格式化结果
98
+ const propsCurrency = currency || '';
99
+ const { showCurrency = true, fallbackValue = '-' } = options;
100
+ const targetMoney = money;
101
+ if (
102
+ targetMoney === null ||
103
+ targetMoney === undefined ||
104
+ targetMoney === ''
105
+ ) {
106
+ return fallbackValue;
107
+ }
108
+ const num =
109
+ typeof targetMoney === 'string' ? Number(targetMoney) : targetMoney;
110
+ if (Number.isNaN(num)) return fallbackValue;
111
+ if (!propsCurrency) return num;
112
+ if (showCurrency) {
113
+ return `${num} ${propsCurrency}`;
114
+ }
115
+ return `${num}`;
116
+ }
117
+ };
@@ -0,0 +1,30 @@
1
+ import { SeelWidgetSDK } from '../core/SeelWidgetSDK';
2
+ import type { IEvents } from '../dto/IEvents';
3
+ import type { IQuotesRequest } from '../dto/IQuotesRequest';
4
+ import type IQuotesResponse from '../dto/IQuotesResponse';
5
+ import { post } from '../network/request';
6
+
7
+ export enum NetworkErrorEnum {
8
+ InvalidURL,
9
+ NoData,
10
+ DecodingError,
11
+ NetworkError,
12
+ ServerError,
13
+ /**
14
+ * Configuration error
15
+ */
16
+ ConfigError,
17
+ Unknown,
18
+ }
19
+
20
+ const defaultBaseURL: string = SeelWidgetSDK.shared.baseURL;
21
+
22
+ export const createQuote = (body: IQuotesRequest) => {
23
+ const url = defaultBaseURL + '/v1/ecommerce/quotes';
24
+ return post<IQuotesResponse>(url, JSON.stringify(body), {});
25
+ };
26
+
27
+ export const createEvent = (body: IEvents) => {
28
+ const url = defaultBaseURL + '/v1/ecommerce/events';
29
+ return post<IQuotesResponse>(url, JSON.stringify(body), {});
30
+ };
@@ -0,0 +1,42 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+
3
+ const StorageValue = {
4
+ True: '1',
5
+ False: '0',
6
+ } as const;
7
+
8
+ export const AsyncStorageKey = {
9
+ OptedIn: 'SeelWFPWidget.OptedIn',
10
+ };
11
+
12
+ function logSetError(key: string, error: unknown) {
13
+ console.error('Failed to set [', key, '] error:', error);
14
+ }
15
+
16
+ function logGetError(key: string, error: unknown) {
17
+ console.error('Failed to get [', key, '] error:', error);
18
+ }
19
+
20
+ export const writeOptedIn = async (value: boolean): Promise<void> => {
21
+ const key = AsyncStorageKey.OptedIn;
22
+ try {
23
+ await AsyncStorage.setItem(
24
+ key,
25
+ value ? StorageValue.True : StorageValue.False
26
+ );
27
+ } catch (error) {
28
+ logSetError(key, error);
29
+ throw error;
30
+ }
31
+ };
32
+
33
+ export const readOptedIn = async (): Promise<boolean> => {
34
+ const key = AsyncStorageKey.OptedIn;
35
+ try {
36
+ const value = await AsyncStorage.getItem(key);
37
+ return value !== null && value !== '' && value !== StorageValue.False;
38
+ } catch (error) {
39
+ logGetError(key, error);
40
+ return false;
41
+ }
42
+ };
@@ -0,0 +1,18 @@
1
+ /* eslint-disable no-bitwise */
2
+ /**
3
+ * Generate a random UUID (v4)
4
+ * @returns A UUID string in the format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
5
+ */
6
+ export function randomUUID(): string {
7
+ // Use crypto.randomUUID if available (browser/Node.js 19+)
8
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
9
+ return crypto.randomUUID();
10
+ }
11
+
12
+ // Fallback implementation for React Native
13
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
14
+ const r = (Math.random() * 16) | 0;
15
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
16
+ return v.toString(16);
17
+ });
18
+ }
package/.editorconfig DELETED
@@ -1,15 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
- [*]
8
-
9
- indent_style = space
10
- indent_size = 2
11
-
12
- end_of_line = lf
13
- charset = utf-8
14
- trim_trailing_whitespace = true
15
- insert_final_newline = true
package/.gitattributes DELETED
@@ -1,3 +0,0 @@
1
- *.pbxproj -text
2
- # specific for windows script files
3
- *.bat text eol=crlf
@@ -1,67 +0,0 @@
1
- name: 🐛 Bug report
2
- description: Report a reproducible bug or regression in this library.
3
- labels: [bug]
4
- body:
5
- - type: markdown
6
- attributes:
7
- value: |
8
- # Bug report
9
-
10
- 👋 Hi!
11
-
12
- **Please fill the following carefully before opening a new issue ❗**
13
- *(Your issue may be closed if it doesn't provide the required pieces of information)*
14
- - type: checkboxes
15
- attributes:
16
- label: Before submitting a new issue
17
- description: Please perform simple checks first.
18
- options:
19
- - label: I tested using the latest version of the library, as the bug might be already fixed.
20
- required: true
21
- - label: I tested using a [supported version](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md) of react native.
22
- required: true
23
- - label: I checked for possible duplicate issues, with possible answers.
24
- required: true
25
- - type: textarea
26
- id: summary
27
- attributes:
28
- label: Bug summary
29
- description: |
30
- Provide a clear and concise description of what the bug is.
31
- If needed, you can also provide other samples: error messages / stack traces, screenshots, gifs, etc.
32
- validations:
33
- required: true
34
- - type: input
35
- id: library-version
36
- attributes:
37
- label: Library version
38
- description: What version of the library are you using?
39
- placeholder: "x.x.x"
40
- validations:
41
- required: true
42
- - type: textarea
43
- id: react-native-info
44
- attributes:
45
- label: Environment info
46
- description: Run `react-native info` in your terminal and paste the results here.
47
- render: shell
48
- validations:
49
- required: true
50
- - type: textarea
51
- id: steps-to-reproduce
52
- attributes:
53
- label: Steps to reproduce
54
- description: |
55
- You must provide a clear list of steps and code to reproduce the problem.
56
- value: |
57
- 1. …
58
- 2. …
59
- validations:
60
- required: true
61
- - type: input
62
- id: reproducible-example
63
- attributes:
64
- label: Reproducible example repository
65
- description: Please provide a link to a repository on GitHub with a reproducible example.
66
- validations:
67
- required: true
@@ -1,8 +0,0 @@
1
- blank_issues_enabled: false
2
- contact_links:
3
- - name: Feature Request 💡
4
- url: https://github.com/seelinc/react-native-seel-widget/discussions/new?category=ideas
5
- about: If you have a feature request, please create a new discussion on GitHub.
6
- - name: Discussions on GitHub 💬
7
- url: https://github.com/seelinc/react-native-seel-widget/discussions
8
- about: If this library works as promised but you need help, please ask questions there.
@@ -1,36 +0,0 @@
1
- name: Setup
2
- description: Setup Node.js and install dependencies
3
-
4
- runs:
5
- using: composite
6
- steps:
7
- - name: Setup Node.js
8
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
9
- with:
10
- node-version-file: .nvmrc
11
-
12
- - name: Restore dependencies
13
- id: yarn-cache
14
- uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
15
- with:
16
- path: |
17
- **/node_modules
18
- .yarn/install-state.gz
19
- key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }}
20
- restore-keys: |
21
- ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
22
- ${{ runner.os }}-yarn-
23
-
24
- - name: Install dependencies
25
- if: steps.yarn-cache.outputs.cache-hit != 'true'
26
- run: yarn install --immutable
27
- shell: bash
28
-
29
- - name: Cache dependencies
30
- if: steps.yarn-cache.outputs.cache-hit != 'true'
31
- uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
32
- with:
33
- path: |
34
- **/node_modules
35
- .yarn/install-state.gz
36
- key: ${{ steps.yarn-cache.outputs.cache-primary-key }}
@@ -1,72 +0,0 @@
1
- name: CI
2
- on:
3
- push:
4
- branches:
5
- - main
6
- pull_request:
7
- branches:
8
- - main
9
- merge_group:
10
- types:
11
- - checks_requested
12
-
13
- concurrency:
14
- group: ${{ github.workflow }}-${{ github.ref }}
15
- cancel-in-progress: true
16
-
17
- jobs:
18
- lint:
19
- runs-on: ubuntu-latest
20
-
21
- steps:
22
- - name: Checkout
23
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
24
-
25
- - name: Setup
26
- uses: ./.github/actions/setup
27
-
28
- - name: Lint files
29
- run: yarn lint
30
-
31
- - name: Typecheck files
32
- run: yarn typecheck
33
-
34
- test:
35
- runs-on: ubuntu-latest
36
-
37
- steps:
38
- - name: Checkout
39
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
40
-
41
- - name: Setup
42
- uses: ./.github/actions/setup
43
-
44
- - name: Run unit tests
45
- run: yarn test --maxWorkers=2 --coverage
46
-
47
- build-library:
48
- runs-on: ubuntu-latest
49
-
50
- steps:
51
- - name: Checkout
52
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
53
-
54
- - name: Setup
55
- uses: ./.github/actions/setup
56
-
57
- - name: Build package
58
- run: yarn prepare
59
-
60
- build-web:
61
- runs-on: ubuntu-latest
62
-
63
- steps:
64
- - name: Checkout
65
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
66
-
67
- - name: Setup
68
- uses: ./.github/actions/setup
69
-
70
- - name: Build example for Web
71
- run: |
72
- yarn example expo export --platform web
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- v22.20.0
package/.watchmanconfig DELETED
@@ -1 +0,0 @@
1
- {}