@alfalab/bridge-to-native 0.0.8 → 0.0.9

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.
@@ -12,19 +12,19 @@ export declare class BridgeToNative {
12
12
  readonly environment: Environment;
13
13
  readonly nativeFallbacks: NativeFallbacks;
14
14
  private nextPageId;
15
+ private readonly _blankPagePath;
16
+ private readonly _handleRedirect;
17
+ constructor(handleRedirect: HandleRedirect, blankPagePath: string, nativeParams?: NativeParams);
15
18
  private _nativeNavigationAndTitle;
19
+ get nativeNavigationAndTitle(): NativeNavigationAndTitle;
16
20
  private _originalWebviewParams;
21
+ get originalWebviewParams(): string;
17
22
  private _appVersion;
23
+ get appVersion(): string;
18
24
  private _iosAppId?;
25
+ get iosAppId(): string | undefined;
19
26
  private _theme;
20
- private readonly _blankPagePath;
21
- private readonly _handleRedirect;
22
- constructor(handleRedirect: HandleRedirect, blankPagePath: string, nativeParams?: NativeParams);
23
27
  get theme(): Theme;
24
- get appVersion(): string;
25
- get iosAppId(): string | undefined;
26
- get nativeNavigationAndTitle(): NativeNavigationAndTitle;
27
- get originalWebviewParams(): string;
28
28
  /**
29
29
  * Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
30
30
  *
@@ -43,6 +43,7 @@ export declare class BridgeToNative {
43
43
  * `false` – текущая версия ниже.
44
44
  */
45
45
  isCurrentVersionHigherOrEqual(versionToCompare: string): boolean;
46
+ checkAndroidAllowOpenInNewWebview(): boolean;
46
47
  /**
47
48
  * Сохраняет текущее состояние BridgeToNative в sessionStorage.
48
49
  * Так же сохраняет текущее состояние nativeNavigationAndTitle.
@@ -35,8 +35,11 @@ class BridgeToNative {
35
35
  this.nativeFallbacks = new native_fallbacks_1.NativeFallbacks(this);
36
36
  this._blankPagePath = blankPagePath;
37
37
  }
38
- get theme() {
39
- return this._theme;
38
+ get nativeNavigationAndTitle() {
39
+ return this._nativeNavigationAndTitle;
40
+ }
41
+ get originalWebviewParams() {
42
+ return this._originalWebviewParams;
40
43
  }
41
44
  get appVersion() {
42
45
  return this._appVersion;
@@ -44,11 +47,8 @@ class BridgeToNative {
44
47
  get iosAppId() {
45
48
  return this._iosAppId;
46
49
  }
47
- get nativeNavigationAndTitle() {
48
- return this._nativeNavigationAndTitle;
49
- }
50
- get originalWebviewParams() {
51
- return this._originalWebviewParams;
50
+ get theme() {
51
+ return this._theme;
52
52
  }
53
53
  /**
54
54
  * Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
@@ -89,6 +89,10 @@ class BridgeToNative {
89
89
  }
90
90
  return true;
91
91
  }
92
+ checkAndroidAllowOpenInNewWebview() {
93
+ const comparisonResult = this.isCurrentVersionHigherOrEqual(constants_1.START_VERSION_ANDROID_ALLOW_OPEN_NEW_WEBVIEW);
94
+ return this.environment === 'android' && comparisonResult;
95
+ }
92
96
  /**
93
97
  * Сохраняет текущее состояние BridgeToNative в sessionStorage.
94
98
  * Так же сохраняет текущее состояние nativeNavigationAndTitle.
package/constants.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { NativeFeaturesFromVersion } from './types';
2
+ export declare const START_VERSION_ANDROID_ALLOW_OPEN_NEW_WEBVIEW = "10.35.0";
3
+ export declare const ANDROID_APP_ID = "YWxmYWJhbms=";
2
4
  export declare const CLOSE_WEBVIEW_SEARCH_KEY = "closeWebView";
3
5
  export declare const CLOSE_WEBVIEW_SEARCH_VALUE = "true";
4
6
  export declare const PREVIOUS_B2N_STATE_STORAGE_KEY = "previousBridgeToNativeState";
package/constants.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEEP_LINK_PATTERN = exports.nativeFeaturesFromVersion = exports.versionToIosAppId = exports.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY = exports.PREVIOUS_B2N_STATE_STORAGE_KEY = exports.CLOSE_WEBVIEW_SEARCH_VALUE = exports.CLOSE_WEBVIEW_SEARCH_KEY = void 0;
3
+ exports.DEEP_LINK_PATTERN = exports.nativeFeaturesFromVersion = exports.versionToIosAppId = exports.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY = exports.PREVIOUS_B2N_STATE_STORAGE_KEY = exports.CLOSE_WEBVIEW_SEARCH_VALUE = exports.CLOSE_WEBVIEW_SEARCH_KEY = exports.ANDROID_APP_ID = exports.START_VERSION_ANDROID_ALLOW_OPEN_NEW_WEBVIEW = void 0;
4
+ exports.START_VERSION_ANDROID_ALLOW_OPEN_NEW_WEBVIEW = '10.35.0';
5
+ exports.ANDROID_APP_ID = 'YWxmYWJhbms=';
4
6
  exports.CLOSE_WEBVIEW_SEARCH_KEY = 'closeWebView';
5
7
  exports.CLOSE_WEBVIEW_SEARCH_VALUE = 'true';
6
8
  exports.PREVIOUS_B2N_STATE_STORAGE_KEY = 'previousBridgeToNativeState';
@@ -1,4 +1,4 @@
1
- import { PdfType } from './types';
1
+ import { ExternalNavigationOptions, PdfType } from './types';
2
2
  import type { BridgeToNative } from './bridge-to-native';
3
3
  /**
4
4
  * Класс содержит реализацию обходных путей для веб-фич, которые не работают в нативном-вебвью.
@@ -21,7 +21,7 @@ export declare class NativeFallbacks {
21
21
  * ```
22
22
  * В разных OS и разных версиях приложения, открытие ресурса будет работать по-разному:
23
23
  *
24
- * - Если текущая версия приложения может открыть ссылку в браузере,
24
+ * - Если текущая версия приложения может открыть ссылку в браузере и не задан параметр `forceOpenInWebview`,
25
25
  * обогащаем URL специальным query-параметром (`target=_blank` в приложении не работает).
26
26
  * - Если это iOS, меняем URL на диплинк, который откроет ссылку в новом вебвью, поверх текущего.
27
27
  * К первому-вебвью, пользователь вернётся, когда закроет второе вебвью с внешним ресурсом.
@@ -29,11 +29,14 @@ export declare class NativeFallbacks {
29
29
  * навигации с приложением. Это «фолбэк-сценарий» с плохим UX (сайт полностью выпадает из истории), но другого способа нет.
30
30
  *
31
31
  * @param link Строка - валидный урл.
32
- * @param onClick Дополнительный обработчик на клик, например, для отправки метрики.
32
+ * @param options - опции
33
+ * @param options.forceOpenInWebview Boolean - по умолчанию = false, если передать true,
34
+ * все ссылки будут открываться в рамках webview, иначе открытие по возможности будет происходить в браузере.
35
+ * @param options.onClick Дополнительный обработчик на клик, например, для отправки метрики.
33
36
  * Внимание! Не факт, что в «фолбэк-сценарии» асинхронная операция будет выполнена (метрика отправлена)!
34
37
  * @returns Пропсы для ссылки в вебвью окружении.
35
38
  */
36
- getExternalLinkProps(link: string, onClick?: () => void): {
39
+ getExternalLinkProps(link: string, options?: ExternalNavigationOptions): {
37
40
  href: string;
38
41
  onClick: (() => void) | undefined;
39
42
  };
@@ -54,6 +57,8 @@ export declare class NativeFallbacks {
54
57
  * См. описание в `getExternalLinkProps`, чтобы узнать, как выбирается способ для перехода.
55
58
  *
56
59
  * @param link Строка - валидный урл.
60
+ * @param forceOpenInWebview Boolean - по умолчанию = false, если передать true,
61
+ * все ссылки будут открываться в рамках webview, иначе открытие по возможности будет происходить в браузере.
57
62
  */
58
- visitExternalResource(link: string): void;
63
+ visitExternalResource(link: string, forceOpenInWebview?: boolean): void;
59
64
  }
@@ -24,7 +24,7 @@ class NativeFallbacks {
24
24
  * ```
25
25
  * В разных OS и разных версиях приложения, открытие ресурса будет работать по-разному:
26
26
  *
27
- * - Если текущая версия приложения может открыть ссылку в браузере,
27
+ * - Если текущая версия приложения может открыть ссылку в браузере и не задан параметр `forceOpenInWebview`,
28
28
  * обогащаем URL специальным query-параметром (`target=_blank` в приложении не работает).
29
29
  * - Если это iOS, меняем URL на диплинк, который откроет ссылку в новом вебвью, поверх текущего.
30
30
  * К первому-вебвью, пользователь вернётся, когда закроет второе вебвью с внешним ресурсом.
@@ -32,21 +32,26 @@ class NativeFallbacks {
32
32
  * навигации с приложением. Это «фолбэк-сценарий» с плохим UX (сайт полностью выпадает из истории), но другого способа нет.
33
33
  *
34
34
  * @param link Строка - валидный урл.
35
- * @param onClick Дополнительный обработчик на клик, например, для отправки метрики.
35
+ * @param options - опции
36
+ * @param options.forceOpenInWebview Boolean - по умолчанию = false, если передать true,
37
+ * все ссылки будут открываться в рамках webview, иначе открытие по возможности будет происходить в браузере.
38
+ * @param options.onClick Дополнительный обработчик на клик, например, для отправки метрики.
36
39
  * Внимание! Не факт, что в «фолбэк-сценарии» асинхронная операция будет выполнена (метрика отправлена)!
37
40
  * @returns Пропсы для ссылки в вебвью окружении.
38
41
  */
39
- getExternalLinkProps(link, onClick) {
40
- const { iosAppId } = this.b2n;
42
+ getExternalLinkProps(link, options = {}) {
43
+ const { onClick, forceOpenInWebview } = options;
44
+ const { iosAppId, environment, appVersion, checkAndroidAllowOpenInNewWebview } = this.b2n;
41
45
  const url = (0, utils_1.getUrlInstance)(link);
42
- if (this.b2n.canUseNativeFeature('linksInBrowser')) {
46
+ const appId = (0, utils_1.getAppId)(environment, iosAppId);
47
+ if (!forceOpenInWebview && this.b2n.canUseNativeFeature('linksInBrowser')) {
43
48
  url.searchParams.append('openInBrowser', 'true');
44
49
  return { href: url.href, onClick };
45
50
  }
46
- if (iosAppId) {
51
+ if (iosAppId || checkAndroidAllowOpenInNewWebview()) {
47
52
  return {
48
- href: `${iosAppId}://webFeature?type=recommendation&url=${encodeURIComponent(url.href)}`,
49
- onClick,
53
+ href: `${appId}://webFeature?type=recommendation&url=${encodeURIComponent(url.href)}`,
54
+ onClick: options === null || options === void 0 ? void 0 : options.onClick,
50
55
  };
51
56
  }
52
57
  return {
@@ -95,17 +100,20 @@ class NativeFallbacks {
95
100
  * См. описание в `getExternalLinkProps`, чтобы узнать, как выбирается способ для перехода.
96
101
  *
97
102
  * @param link Строка - валидный урл.
103
+ * @param forceOpenInWebview Boolean - по умолчанию = false, если передать true,
104
+ * все ссылки будут открываться в рамках webview, иначе открытие по возможности будет происходить в браузере.
98
105
  */
99
- visitExternalResource(link) {
106
+ visitExternalResource(link, forceOpenInWebview = false) {
100
107
  var _a;
101
- const { iosAppId } = this.b2n;
108
+ const { iosAppId, appVersion, environment, checkAndroidAllowOpenInNewWebview } = this.b2n;
102
109
  const url = (0, utils_1.getUrlInstance)(link);
103
- if (this.b2n.canUseNativeFeature('linksInBrowser')) {
110
+ const appId = (0, utils_1.getAppId)(environment, iosAppId);
111
+ if (!forceOpenInWebview && this.b2n.canUseNativeFeature('linksInBrowser')) {
104
112
  url.searchParams.append('openInBrowser', 'true');
105
113
  window.location.replace(url.href);
106
114
  }
107
- else if (iosAppId) {
108
- window.location.replace(`${iosAppId}://webFeature?type=recommendation&url=${encodeURIComponent(url.href)}`);
115
+ else if (iosAppId || checkAndroidAllowOpenInNewWebview()) {
116
+ window.location.replace(`${appId}://webFeature?type=recommendation&url=${encodeURIComponent(url.href)}`);
109
117
  }
110
118
  else {
111
119
  (_a = this.b2n.nativeNavigationAndTitle) === null || _a === void 0 ? void 0 : _a.setInitialView('');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "license": "UNLICENSED",
3
3
  "name": "@alfalab/bridge-to-native",
4
- "version": "0.0.8",
4
+ "version": "0.0.9",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/core-ds/bridge-to-native.git"
package/types.d.ts CHANGED
@@ -32,4 +32,8 @@ export declare type PreviousNativeNavigationAndTitleState = {
32
32
  export declare type SyncPurpose = 'initialization' | 'navigation' | 'title-replacing';
33
33
  export declare type HandleRedirect = (appName: string, path?: string, params?: Record<string, string>) => void;
34
34
  export declare type Theme = 'light' | 'dark';
35
+ export declare type ExternalNavigationOptions = {
36
+ onClick?: () => void;
37
+ forceOpenInWebview?: boolean;
38
+ };
35
39
  export {};
package/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Environment } from './types';
1
2
  /**
2
3
  * Разделяет веб ссылку на компоненты
3
4
  * @param route внутренний путь для навигации
@@ -19,3 +20,4 @@ export declare const getUrlInstance: (link: string) => URL;
19
20
  * @returns Правильный формат или нет.
20
21
  */
21
22
  export declare const isValidVersionFormat: (version?: string | undefined) => boolean;
23
+ export declare const getAppId: (environment: Environment, iosAppId?: string | undefined) => string | null;
package/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isValidVersionFormat = exports.getUrlInstance = exports.extractAppNameRouteAndQuery = void 0;
3
+ exports.getAppId = exports.isValidVersionFormat = exports.getUrlInstance = exports.extractAppNameRouteAndQuery = void 0;
4
+ const constants_1 = require("./constants");
4
5
  /**
5
6
  * Разделяет веб ссылку на компоненты
6
7
  * @param route внутренний путь для навигации
@@ -57,3 +58,13 @@ const isValidVersionFormat = (version) => {
57
58
  return versionPattern.test(version);
58
59
  };
59
60
  exports.isValidVersionFormat = isValidVersionFormat;
61
+ const getAppId = (environment, iosAppId) => {
62
+ if (environment === 'android') {
63
+ return atob(constants_1.ANDROID_APP_ID);
64
+ }
65
+ if (environment === 'ios' && iosAppId && typeof iosAppId === 'string') {
66
+ return iosAppId;
67
+ }
68
+ return null;
69
+ };
70
+ exports.getAppId = getAppId;