@norcy/react-native-toolkit 0.1.73 → 0.1.74

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.
@@ -42,16 +42,9 @@ const getAppInsideQueryParams = url => {
42
42
  let GlobalNavigation = null;
43
43
  const AppLink = exports.AppLink = {
44
44
  /* 测试用例:
45
- 1. https://norcy.xyz/iread 安卓打开浏览器官网
46
- 2. https://www.coolapk.com/apk/com.norcy.iread 安卓跳酷安
47
- 3. https://apps.apple.com/app/id1589203887 iOS 跳 AppStore
48
- 4. https://apps.apple.com/app/id1589203887?action=write-review iOS 跳评价
49
- 5. https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com App 内跳转
50
- 6. yiyue://WebPage?url=https%3A%2F%2Fqq.com App 内跳转
51
- 7. WebPage?url=https%3A%2F%2Fqq.com App 内跳转
52
- 9. https://qq.com 跳转浏览器
45
+ 详见 https://docs.qq.com/sheet/DSHpXb29STWpYempK?tab=w20187
53
46
  */
54
- open: url => {
47
+ open: (url, ignoreSelf) => {
55
48
  if (!url) {
56
49
  return;
57
50
  }
@@ -72,6 +65,11 @@ const AppLink = exports.AppLink = {
72
65
  return;
73
66
  }
74
67
 
68
+ // 如果是官网,则不再处理,因为 App 内跳转已经处理了
69
+ if (ignoreSelf && url.startsWith(_Tool.ToolkitConfig.AppWebsite)) {
70
+ return;
71
+ }
72
+
75
73
  // 第三优先级:外部跳转 AppStore、H5 等
76
74
  _reactNative.Linking.canOpenURL(url).then(supported => {
77
75
  if (supported) {
@@ -80,19 +78,21 @@ const AppLink = exports.AppLink = {
80
78
  } else {
81
79
  console.error('无法跳转', url);
82
80
  }
83
- }).catch(() => {
84
- console.error('无法跳转', url);
81
+ }).catch(e => {
82
+ console.error('无法跳转', url, e);
85
83
  });
86
84
  },
87
85
  init: navigation => {
88
86
  GlobalNavigation = navigation;
89
- _reactNative.Linking.getInitialURL().then(url => {
90
- // 此处 url 都是官网开头
91
- AppLink.open(url !== null && url !== void 0 ? url : undefined);
92
- }).catch(err => console.error('获取初始URL时出错:', err));
87
+ setTimeout(() => {
88
+ _reactNative.Linking.getInitialURL().then(url => {
89
+ // 此处 url 都是官网开头
90
+ AppLink.open(url !== null && url !== void 0 ? url : undefined, true);
91
+ }).catch(err => console.error('获取初始URL时出错:', err));
92
+ }, 1500);
93
93
  _reactNative.Linking.addEventListener('url', event => {
94
94
  // 此处 url 都是官网开头
95
- AppLink.open(event.url);
95
+ AppLink.open(event.url, true);
96
96
  });
97
97
  }
98
98
  };
@@ -1 +1 @@
1
- {"version":3,"names":["_queryString","_interopRequireDefault","require","_reactNative","_Tool","obj","__esModule","default","getAppInsideQueryParams","url","ret","page","params","scheme","query","split","queryString","parse","startsWith","ToolkitConfig","AppWebsite","AppScheme","pageName","substring","length","GlobalNavigation","AppLink","exports","open","console","log","AndroidStoreUrl","Tool","goAppStoreReview","_GlobalNavigation","navigate","Linking","canOpenURL","then","supported","openURL","error","catch","init","navigation","getInitialURL","undefined","err","addEventListener","event"],"sources":["AppLink.ts"],"sourcesContent":["import { NavigationProp, ParamListBase } from '@react-navigation/native';\nimport queryString from 'query-string';\nimport { Linking } from 'react-native';\nimport { Tool, ToolkitConfig } from './Tool';\n\nconst getAppInsideQueryParams = (\n url: string\n): { page: string; params?: object } => {\n // 专门处理 App 内跳转\n // 情况 1:https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n // 情况 2:yiyue://WebPage?url=https%3A%2F%2Fqq.com\n // 情况 3:WebPage?url=https%3A%2F%2Fqq.com\n // 全部都转为 {page:Add, params:{value:'你好', mode:0}}\n const ret = { page: '', params: {} };\n\n const [scheme, query] = url.split('?');\n const params = queryString.parse(query) as { [key: string]: string };\n\n if (scheme.startsWith(ToolkitConfig.AppWebsite) && params.page) {\n // https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n ret.page = params.page;\n delete params.page;\n ret.params = params;\n } else if (scheme.startsWith(ToolkitConfig.AppScheme)) {\n // yiyue://WebPage?url=https%3A%2F%2Fqq.com\n const pageName = scheme.substring(ToolkitConfig.AppScheme.length);\n ret.page = pageName;\n ret.params = params;\n } else if (scheme.startsWith('http')) {\n // 除了第一个 if,http 开头的不处理\n } else {\n // WebPage?url=https%3A%2F%2Fqq.com\n ret.page = scheme;\n ret.params = params;\n }\n return ret;\n};\n\nlet GlobalNavigation: NavigationProp<ParamListBase> | null = null;\n\nexport const AppLink = {\n /* 测试用例:\n 1. https://norcy.xyz/iread 安卓打开浏览器官网\n 2. https://www.coolapk.com/apk/com.norcy.iread 安卓跳酷安\n 3. https://apps.apple.com/app/id1589203887 iOS 跳 AppStore\n 4. https://apps.apple.com/app/id1589203887?action=write-review iOS 跳评价\n 5. https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com App 内跳转\n 6. yiyue://WebPage?url=https%3A%2F%2Fqq.com App 内跳转\n 7. WebPage?url=https%3A%2F%2Fqq.com App 内跳转\n 9. https://qq.com 跳转浏览器\n */\n open: (url?: string) => {\n if (!url) {\n return;\n }\n\n console.log('Open URL', url);\n\n // 第一优先级:Android 市场\n if (url.startsWith(ToolkitConfig.AndroidStoreUrl)) {\n Tool.goAppStoreReview();\n return;\n }\n\n // 第二优先级:App 内跳转\n const ret = getAppInsideQueryParams(url);\n if (ret.page) {\n console.log('App 内跳转', ret);\n GlobalNavigation?.navigate(ret.page, ret.params);\n return;\n }\n\n // 第三优先级:外部跳转 AppStore、H5 等\n Linking.canOpenURL(url)\n .then((supported) => {\n if (supported) {\n console.log('外部跳转', url);\n Linking.openURL(url);\n } else {\n console.error('无法跳转', url);\n }\n })\n .catch(() => {\n console.error('无法跳转', url);\n });\n },\n\n init: (navigation: NavigationProp<ParamListBase>) => {\n GlobalNavigation = navigation;\n Linking.getInitialURL()\n .then((url) => {\n // 此处 url 都是官网开头\n AppLink.open(url ?? undefined);\n })\n .catch((err) => console.error('获取初始URL时出错:', err));\n\n Linking.addEventListener('url', (event) => {\n // 此处 url 都是官网开头\n AppLink.open(event.url);\n });\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["_queryString","_interopRequireDefault","require","_reactNative","_Tool","obj","__esModule","default","getAppInsideQueryParams","url","ret","page","params","scheme","query","split","queryString","parse","startsWith","ToolkitConfig","AppWebsite","AppScheme","pageName","substring","length","GlobalNavigation","AppLink","exports","open","ignoreSelf","console","log","AndroidStoreUrl","Tool","goAppStoreReview","_GlobalNavigation","navigate","Linking","canOpenURL","then","supported","openURL","error","catch","e","init","navigation","setTimeout","getInitialURL","undefined","err","addEventListener","event"],"sources":["AppLink.ts"],"sourcesContent":["import { NavigationProp, ParamListBase } from '@react-navigation/native';\nimport queryString from 'query-string';\nimport { Linking } from 'react-native';\nimport { Tool, ToolkitConfig } from './Tool';\n\nconst getAppInsideQueryParams = (\n url: string\n): { page: string; params?: object } => {\n // 专门处理 App 内跳转\n // 情况 1:https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n // 情况 2:yiyue://WebPage?url=https%3A%2F%2Fqq.com\n // 情况 3:WebPage?url=https%3A%2F%2Fqq.com\n // 全部都转为 {page:Add, params:{value:'你好', mode:0}}\n const ret = { page: '', params: {} };\n\n const [scheme, query] = url.split('?');\n const params = queryString.parse(query) as { [key: string]: string };\n\n if (scheme.startsWith(ToolkitConfig.AppWebsite) && params.page) {\n // https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n ret.page = params.page;\n delete params.page;\n ret.params = params;\n } else if (scheme.startsWith(ToolkitConfig.AppScheme)) {\n // yiyue://WebPage?url=https%3A%2F%2Fqq.com\n const pageName = scheme.substring(ToolkitConfig.AppScheme.length);\n ret.page = pageName;\n ret.params = params;\n } else if (scheme.startsWith('http')) {\n // 除了第一个 if,http 开头的不处理\n } else {\n // WebPage?url=https%3A%2F%2Fqq.com\n ret.page = scheme;\n ret.params = params;\n }\n return ret;\n};\n\nlet GlobalNavigation: NavigationProp<ParamListBase> | null = null;\n\nexport const AppLink = {\n /* 测试用例:\n 详见 https://docs.qq.com/sheet/DSHpXb29STWpYempK?tab=w20187\n */\n open: (url?: string, ignoreSelf?: boolean) => {\n if (!url) {\n return;\n }\n\n console.log('Open URL', url);\n\n // 第一优先级:Android 市场\n if (url.startsWith(ToolkitConfig.AndroidStoreUrl)) {\n Tool.goAppStoreReview();\n return;\n }\n\n // 第二优先级:App 内跳转\n const ret = getAppInsideQueryParams(url);\n if (ret.page) {\n console.log('App 内跳转', ret);\n GlobalNavigation?.navigate(ret.page, ret.params);\n return;\n }\n\n // 如果是官网,则不再处理,因为 App 内跳转已经处理了\n if (ignoreSelf && url.startsWith(ToolkitConfig.AppWebsite)) {\n return;\n }\n\n // 第三优先级:外部跳转 AppStore、H5 等\n Linking.canOpenURL(url)\n .then((supported) => {\n if (supported) {\n console.log('外部跳转', url);\n Linking.openURL(url);\n } else {\n console.error('无法跳转', url);\n }\n })\n .catch((e) => {\n console.error('无法跳转', url, e);\n });\n },\n\n init: (navigation: NavigationProp<ParamListBase>) => {\n GlobalNavigation = navigation;\n setTimeout(() => {\n Linking.getInitialURL()\n .then((url) => {\n // 此处 url 都是官网开头\n AppLink.open(url ?? undefined, true);\n })\n .catch((err) => console.error('获取初始URL时出错:', err));\n }, 1500);\n\n Linking.addEventListener('url', (event) => {\n // 此处 url 都是官网开头\n AppLink.open(event.url, true);\n });\n },\n};\n"],"mappings":"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"}
@@ -35,16 +35,9 @@ const getAppInsideQueryParams = url => {
35
35
  let GlobalNavigation = null;
36
36
  export const AppLink = {
37
37
  /* 测试用例:
38
- 1. https://norcy.xyz/iread 安卓打开浏览器官网
39
- 2. https://www.coolapk.com/apk/com.norcy.iread 安卓跳酷安
40
- 3. https://apps.apple.com/app/id1589203887 iOS 跳 AppStore
41
- 4. https://apps.apple.com/app/id1589203887?action=write-review iOS 跳评价
42
- 5. https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com App 内跳转
43
- 6. yiyue://WebPage?url=https%3A%2F%2Fqq.com App 内跳转
44
- 7. WebPage?url=https%3A%2F%2Fqq.com App 内跳转
45
- 9. https://qq.com 跳转浏览器
38
+ 详见 https://docs.qq.com/sheet/DSHpXb29STWpYempK?tab=w20187
46
39
  */
47
- open: url => {
40
+ open: (url, ignoreSelf) => {
48
41
  if (!url) {
49
42
  return;
50
43
  }
@@ -65,6 +58,11 @@ export const AppLink = {
65
58
  return;
66
59
  }
67
60
 
61
+ // 如果是官网,则不再处理,因为 App 内跳转已经处理了
62
+ if (ignoreSelf && url.startsWith(ToolkitConfig.AppWebsite)) {
63
+ return;
64
+ }
65
+
68
66
  // 第三优先级:外部跳转 AppStore、H5 等
69
67
  Linking.canOpenURL(url).then(supported => {
70
68
  if (supported) {
@@ -73,19 +71,21 @@ export const AppLink = {
73
71
  } else {
74
72
  console.error('无法跳转', url);
75
73
  }
76
- }).catch(() => {
77
- console.error('无法跳转', url);
74
+ }).catch(e => {
75
+ console.error('无法跳转', url, e);
78
76
  });
79
77
  },
80
78
  init: navigation => {
81
79
  GlobalNavigation = navigation;
82
- Linking.getInitialURL().then(url => {
83
- // 此处 url 都是官网开头
84
- AppLink.open(url !== null && url !== void 0 ? url : undefined);
85
- }).catch(err => console.error('获取初始URL时出错:', err));
80
+ setTimeout(() => {
81
+ Linking.getInitialURL().then(url => {
82
+ // 此处 url 都是官网开头
83
+ AppLink.open(url !== null && url !== void 0 ? url : undefined, true);
84
+ }).catch(err => console.error('获取初始URL时出错:', err));
85
+ }, 1500);
86
86
  Linking.addEventListener('url', event => {
87
87
  // 此处 url 都是官网开头
88
- AppLink.open(event.url);
88
+ AppLink.open(event.url, true);
89
89
  });
90
90
  }
91
91
  };
@@ -1 +1 @@
1
- {"version":3,"names":["queryString","Linking","Tool","ToolkitConfig","getAppInsideQueryParams","url","ret","page","params","scheme","query","split","parse","startsWith","AppWebsite","AppScheme","pageName","substring","length","GlobalNavigation","AppLink","open","console","log","AndroidStoreUrl","goAppStoreReview","_GlobalNavigation","navigate","canOpenURL","then","supported","openURL","error","catch","init","navigation","getInitialURL","undefined","err","addEventListener","event"],"sources":["AppLink.ts"],"sourcesContent":["import { NavigationProp, ParamListBase } from '@react-navigation/native';\nimport queryString from 'query-string';\nimport { Linking } from 'react-native';\nimport { Tool, ToolkitConfig } from './Tool';\n\nconst getAppInsideQueryParams = (\n url: string\n): { page: string; params?: object } => {\n // 专门处理 App 内跳转\n // 情况 1:https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n // 情况 2:yiyue://WebPage?url=https%3A%2F%2Fqq.com\n // 情况 3:WebPage?url=https%3A%2F%2Fqq.com\n // 全部都转为 {page:Add, params:{value:'你好', mode:0}}\n const ret = { page: '', params: {} };\n\n const [scheme, query] = url.split('?');\n const params = queryString.parse(query) as { [key: string]: string };\n\n if (scheme.startsWith(ToolkitConfig.AppWebsite) && params.page) {\n // https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n ret.page = params.page;\n delete params.page;\n ret.params = params;\n } else if (scheme.startsWith(ToolkitConfig.AppScheme)) {\n // yiyue://WebPage?url=https%3A%2F%2Fqq.com\n const pageName = scheme.substring(ToolkitConfig.AppScheme.length);\n ret.page = pageName;\n ret.params = params;\n } else if (scheme.startsWith('http')) {\n // 除了第一个 if,http 开头的不处理\n } else {\n // WebPage?url=https%3A%2F%2Fqq.com\n ret.page = scheme;\n ret.params = params;\n }\n return ret;\n};\n\nlet GlobalNavigation: NavigationProp<ParamListBase> | null = null;\n\nexport const AppLink = {\n /* 测试用例:\n 1. https://norcy.xyz/iread 安卓打开浏览器官网\n 2. https://www.coolapk.com/apk/com.norcy.iread 安卓跳酷安\n 3. https://apps.apple.com/app/id1589203887 iOS 跳 AppStore\n 4. https://apps.apple.com/app/id1589203887?action=write-review iOS 跳评价\n 5. https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com App 内跳转\n 6. yiyue://WebPage?url=https%3A%2F%2Fqq.com App 内跳转\n 7. WebPage?url=https%3A%2F%2Fqq.com App 内跳转\n 9. https://qq.com 跳转浏览器\n */\n open: (url?: string) => {\n if (!url) {\n return;\n }\n\n console.log('Open URL', url);\n\n // 第一优先级:Android 市场\n if (url.startsWith(ToolkitConfig.AndroidStoreUrl)) {\n Tool.goAppStoreReview();\n return;\n }\n\n // 第二优先级:App 内跳转\n const ret = getAppInsideQueryParams(url);\n if (ret.page) {\n console.log('App 内跳转', ret);\n GlobalNavigation?.navigate(ret.page, ret.params);\n return;\n }\n\n // 第三优先级:外部跳转 AppStore、H5 等\n Linking.canOpenURL(url)\n .then((supported) => {\n if (supported) {\n console.log('外部跳转', url);\n Linking.openURL(url);\n } else {\n console.error('无法跳转', url);\n }\n })\n .catch(() => {\n console.error('无法跳转', url);\n });\n },\n\n init: (navigation: NavigationProp<ParamListBase>) => {\n GlobalNavigation = navigation;\n Linking.getInitialURL()\n .then((url) => {\n // 此处 url 都是官网开头\n AppLink.open(url ?? undefined);\n })\n .catch((err) => console.error('获取初始URL时出错:', err));\n\n Linking.addEventListener('url', (event) => {\n // 此处 url 都是官网开头\n AppLink.open(event.url);\n });\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["queryString","Linking","Tool","ToolkitConfig","getAppInsideQueryParams","url","ret","page","params","scheme","query","split","parse","startsWith","AppWebsite","AppScheme","pageName","substring","length","GlobalNavigation","AppLink","open","ignoreSelf","console","log","AndroidStoreUrl","goAppStoreReview","_GlobalNavigation","navigate","canOpenURL","then","supported","openURL","error","catch","e","init","navigation","setTimeout","getInitialURL","undefined","err","addEventListener","event"],"sources":["AppLink.ts"],"sourcesContent":["import { NavigationProp, ParamListBase } from '@react-navigation/native';\nimport queryString from 'query-string';\nimport { Linking } from 'react-native';\nimport { Tool, ToolkitConfig } from './Tool';\n\nconst getAppInsideQueryParams = (\n url: string\n): { page: string; params?: object } => {\n // 专门处理 App 内跳转\n // 情况 1:https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n // 情况 2:yiyue://WebPage?url=https%3A%2F%2Fqq.com\n // 情况 3:WebPage?url=https%3A%2F%2Fqq.com\n // 全部都转为 {page:Add, params:{value:'你好', mode:0}}\n const ret = { page: '', params: {} };\n\n const [scheme, query] = url.split('?');\n const params = queryString.parse(query) as { [key: string]: string };\n\n if (scheme.startsWith(ToolkitConfig.AppWebsite) && params.page) {\n // https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com\n ret.page = params.page;\n delete params.page;\n ret.params = params;\n } else if (scheme.startsWith(ToolkitConfig.AppScheme)) {\n // yiyue://WebPage?url=https%3A%2F%2Fqq.com\n const pageName = scheme.substring(ToolkitConfig.AppScheme.length);\n ret.page = pageName;\n ret.params = params;\n } else if (scheme.startsWith('http')) {\n // 除了第一个 if,http 开头的不处理\n } else {\n // WebPage?url=https%3A%2F%2Fqq.com\n ret.page = scheme;\n ret.params = params;\n }\n return ret;\n};\n\nlet GlobalNavigation: NavigationProp<ParamListBase> | null = null;\n\nexport const AppLink = {\n /* 测试用例:\n 详见 https://docs.qq.com/sheet/DSHpXb29STWpYempK?tab=w20187\n */\n open: (url?: string, ignoreSelf?: boolean) => {\n if (!url) {\n return;\n }\n\n console.log('Open URL', url);\n\n // 第一优先级:Android 市场\n if (url.startsWith(ToolkitConfig.AndroidStoreUrl)) {\n Tool.goAppStoreReview();\n return;\n }\n\n // 第二优先级:App 内跳转\n const ret = getAppInsideQueryParams(url);\n if (ret.page) {\n console.log('App 内跳转', ret);\n GlobalNavigation?.navigate(ret.page, ret.params);\n return;\n }\n\n // 如果是官网,则不再处理,因为 App 内跳转已经处理了\n if (ignoreSelf && url.startsWith(ToolkitConfig.AppWebsite)) {\n return;\n }\n\n // 第三优先级:外部跳转 AppStore、H5 等\n Linking.canOpenURL(url)\n .then((supported) => {\n if (supported) {\n console.log('外部跳转', url);\n Linking.openURL(url);\n } else {\n console.error('无法跳转', url);\n }\n })\n .catch((e) => {\n console.error('无法跳转', url, e);\n });\n },\n\n init: (navigation: NavigationProp<ParamListBase>) => {\n GlobalNavigation = navigation;\n setTimeout(() => {\n Linking.getInitialURL()\n .then((url) => {\n // 此处 url 都是官网开头\n AppLink.open(url ?? undefined, true);\n })\n .catch((err) => console.error('获取初始URL时出错:', err));\n }, 1500);\n\n Linking.addEventListener('url', (event) => {\n // 此处 url 都是官网开头\n AppLink.open(event.url, true);\n });\n },\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { NavigationProp, ParamListBase } from '@react-navigation/native';
2
2
  export declare const AppLink: {
3
- open: (url?: string) => void;
3
+ open: (url?: string, ignoreSelf?: boolean) => void;
4
4
  init: (navigation: NavigationProp<ParamListBase>) => void;
5
5
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@norcy/react-native-toolkit",
3
- "version": "0.1.73",
3
+ "version": "0.1.74",
4
4
  "description": "My Toolkit",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/AppLink.ts CHANGED
@@ -40,16 +40,9 @@ let GlobalNavigation: NavigationProp<ParamListBase> | null = null;
40
40
 
41
41
  export const AppLink = {
42
42
  /* 测试用例:
43
- 1. https://norcy.xyz/iread 安卓打开浏览器官网
44
- 2. https://www.coolapk.com/apk/com.norcy.iread 安卓跳酷安
45
- 3. https://apps.apple.com/app/id1589203887 iOS 跳 AppStore
46
- 4. https://apps.apple.com/app/id1589203887?action=write-review iOS 跳评价
47
- 5. https://norcy.xyz/iread?page=WebPage&url=https%3A%2F%2Fqq.com App 内跳转
48
- 6. yiyue://WebPage?url=https%3A%2F%2Fqq.com App 内跳转
49
- 7. WebPage?url=https%3A%2F%2Fqq.com App 内跳转
50
- 9. https://qq.com 跳转浏览器
43
+ 详见 https://docs.qq.com/sheet/DSHpXb29STWpYempK?tab=w20187
51
44
  */
52
- open: (url?: string) => {
45
+ open: (url?: string, ignoreSelf?: boolean) => {
53
46
  if (!url) {
54
47
  return;
55
48
  }
@@ -70,6 +63,11 @@ export const AppLink = {
70
63
  return;
71
64
  }
72
65
 
66
+ // 如果是官网,则不再处理,因为 App 内跳转已经处理了
67
+ if (ignoreSelf && url.startsWith(ToolkitConfig.AppWebsite)) {
68
+ return;
69
+ }
70
+
73
71
  // 第三优先级:外部跳转 AppStore、H5 等
74
72
  Linking.canOpenURL(url)
75
73
  .then((supported) => {
@@ -80,23 +78,25 @@ export const AppLink = {
80
78
  console.error('无法跳转', url);
81
79
  }
82
80
  })
83
- .catch(() => {
84
- console.error('无法跳转', url);
81
+ .catch((e) => {
82
+ console.error('无法跳转', url, e);
85
83
  });
86
84
  },
87
85
 
88
86
  init: (navigation: NavigationProp<ParamListBase>) => {
89
87
  GlobalNavigation = navigation;
90
- Linking.getInitialURL()
91
- .then((url) => {
92
- // 此处 url 都是官网开头
93
- AppLink.open(url ?? undefined);
94
- })
95
- .catch((err) => console.error('获取初始URL时出错:', err));
88
+ setTimeout(() => {
89
+ Linking.getInitialURL()
90
+ .then((url) => {
91
+ // 此处 url 都是官网开头
92
+ AppLink.open(url ?? undefined, true);
93
+ })
94
+ .catch((err) => console.error('获取初始URL时出错:', err));
95
+ }, 1500);
96
96
 
97
97
  Linking.addEventListener('url', (event) => {
98
98
  // 此处 url 都是官网开头
99
- AppLink.open(event.url);
99
+ AppLink.open(event.url, true);
100
100
  });
101
101
  },
102
102
  };