@neko-os/rc-subscription 0.1.0 → 0.3.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.
- package/README.md +32 -0
- package/dist/config.js +7 -1
- package/dist/containers/SubscriptionHandler.js +52 -2
- package/dist/containers/SubscriptionRequiredCTA.js +3 -2
- package/dist/containers/paywall/Paywall.js +32 -5
- package/dist/index.js +1 -1
- package/dist/locales/cs.js +2 -0
- package/dist/locales/da.js +2 -0
- package/dist/locales/de.js +2 -0
- package/dist/locales/el.js +2 -0
- package/dist/locales/en.js +2 -0
- package/dist/locales/es.js +2 -0
- package/dist/locales/fi.js +2 -0
- package/dist/locales/fr.js +2 -0
- package/dist/locales/hi.js +2 -0
- package/dist/locales/hu.js +2 -0
- package/dist/locales/id.js +2 -0
- package/dist/locales/it.js +2 -0
- package/dist/locales/ja.js +2 -0
- package/dist/locales/ko.js +2 -0
- package/dist/locales/nl.js +2 -0
- package/dist/locales/no.js +2 -0
- package/dist/locales/pl.js +2 -0
- package/dist/locales/pt.js +2 -0
- package/dist/locales/ro.js +2 -0
- package/dist/locales/ru.js +2 -0
- package/dist/locales/sv.js +2 -0
- package/dist/locales/th.js +2 -0
- package/dist/locales/tr.js +2 -0
- package/dist/locales/uk.js +2 -0
- package/dist/locales/vi.js +2 -0
- package/dist/locales/zh.js +2 -0
- package/package.json +1 -1
- package/src/config.js +6 -0
- package/src/containers/SubscriptionHandler.js +52 -2
- package/src/containers/SubscriptionRequiredCTA.js +3 -2
- package/src/containers/paywall/Paywall.js +28 -1
- package/src/index.js +1 -1
- package/src/locales/cs.js +2 -0
- package/src/locales/da.js +2 -0
- package/src/locales/de.js +2 -0
- package/src/locales/el.js +2 -0
- package/src/locales/en.js +2 -0
- package/src/locales/es.js +2 -0
- package/src/locales/fi.js +2 -0
- package/src/locales/fr.js +2 -0
- package/src/locales/hi.js +2 -0
- package/src/locales/hu.js +2 -0
- package/src/locales/id.js +2 -0
- package/src/locales/it.js +2 -0
- package/src/locales/ja.js +2 -0
- package/src/locales/ko.js +2 -0
- package/src/locales/nl.js +2 -0
- package/src/locales/no.js +2 -0
- package/src/locales/pl.js +2 -0
- package/src/locales/pt.js +2 -0
- package/src/locales/ro.js +2 -0
- package/src/locales/ru.js +2 -0
- package/src/locales/sv.js +2 -0
- package/src/locales/th.js +2 -0
- package/src/locales/tr.js +2 -0
- package/src/locales/uk.js +2 -0
- package/src/locales/vi.js +2 -0
- package/src/locales/zh.js +2 -0
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ import { ActiveSubscriptionView } from 'neko-rc-subscription'
|
|
|
84
84
|
|--------|-------------|
|
|
85
85
|
| `useSubscription()` | Full subscription context: `{ isSubscribed, isLoading, customerInfo, offerings, paywallConfig, refresh }` |
|
|
86
86
|
| `useIsSubscribed()` | Shorthand boolean — `true` when active entitlement exists. |
|
|
87
|
+
| `useSubscribedAction(fn?)` | Returns an action wrapper that runs `fn` when subscribed, otherwise opens the paywall. See [Gating an action](#gating-an-action). |
|
|
87
88
|
|
|
88
89
|
### Functions
|
|
89
90
|
|
|
@@ -123,6 +124,37 @@ import { ActiveSubscriptionView } from 'neko-rc-subscription'
|
|
|
123
124
|
| `size` | `string` | `'xs'` | Button size. |
|
|
124
125
|
| `buttonProps` | `object` | — | Extra props forwarded to the unlock Button. |
|
|
125
126
|
|
|
127
|
+
## Gating an action
|
|
128
|
+
|
|
129
|
+
`useSubscribedAction` wraps any callback so it only fires for subscribed users — otherwise the paywall opens (navigates to `subscription/active`). Use it for one-off actions that don't warrant a full gate component (`SubscriptionRequired` / `SubscriptionRequiredCTA`).
|
|
130
|
+
|
|
131
|
+
Two equivalent call styles:
|
|
132
|
+
|
|
133
|
+
```jsx
|
|
134
|
+
import { useSubscribedAction } from 'neko-rc-subscription'
|
|
135
|
+
|
|
136
|
+
// Bind the fn up front
|
|
137
|
+
function ExportButton() {
|
|
138
|
+
const exportData = useSubscribedAction(() => doExport())
|
|
139
|
+
return <Button label="Export" onPress={exportData} />
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Bind nothing — pass the fn at call time (handy when the callback varies)
|
|
143
|
+
function Row({ item }) {
|
|
144
|
+
const run = useSubscribedAction()
|
|
145
|
+
return <Button label="Pin" onPress={() => run(() => pin(item))} />
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
While subscription state is still loading (`isLoading`), the action is a no-op — it neither runs the fn nor opens the paywall, so an already-subscribed user is never bounced to the paywall during init.
|
|
150
|
+
|
|
151
|
+
Arguments are forwarded to the wrapped fn, and its return value is passed through (or `undefined` when the paywall is shown instead):
|
|
152
|
+
|
|
153
|
+
```jsx
|
|
154
|
+
const save = useSubscribedAction(saveReport)
|
|
155
|
+
save(reportId) // -> saveReport(reportId) when subscribed
|
|
156
|
+
```
|
|
157
|
+
|
|
126
158
|
## Package Support
|
|
127
159
|
|
|
128
160
|
The paywall auto-renders available packages from the current RevenueCat offering. Supported package types:
|
package/dist/config.js
CHANGED
|
@@ -2,4 +2,10 @@ import { Platform } from "react-native-web";
|
|
|
2
2
|
|
|
3
3
|
export var RC_API_KEY =
|
|
4
4
|
Platform.OS === 'ios' ? process.env.EXPO_PUBLIC_RC_API_KEY_IOS : process.env.EXPO_PUBLIC_RC_API_KEY_ANDROID;
|
|
5
|
-
export var RC_ENTITLEMENT_ID = process.env.EXPO_PUBLIC_RC_ENTITLEMENT_ID || 'premium';
|
|
5
|
+
export var RC_ENTITLEMENT_ID = process.env.EXPO_PUBLIC_RC_ENTITLEMENT_ID || 'premium';
|
|
6
|
+
export var PRIVACY_POLICY_URL = process.env.EXPO_PUBLIC_PRIVACY_POLICY_URL;
|
|
7
|
+
export var TERMS_OF_USE_URL = process.env.EXPO_PUBLIC_TERMS_OF_USE_URL;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export var SUBSCRIPTION_ROUTE = 'subscription/active';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-rc-subscription/src/containers/SubscriptionHandler.js";function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function
|
|
1
|
+
var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-rc-subscription/src/containers/SubscriptionHandler.js";function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}function _toConsumableArray(r) {return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();}function _nonIterableSpread() {throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _iterableToArray(r) {if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);}function _arrayWithoutHoles(r) {if (Array.isArray(r)) return _arrayLikeToArray(r);}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function asyncGeneratorStep(n, t, e, r, o, a, c) {try {var i = n[a](c),u = i.value;} catch (n) {return void e(n);}i.done ? t(u) : Promise.resolve(u).then(r, o);}function _asyncToGenerator(n) {return function () {var t = this,e = arguments;return new Promise(function (r, o) {var a = n.apply(t, e);function _next(n) {asyncGeneratorStep(a, r, o, _next, _throw, "next", n);}function _throw(n) {asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);}_next(void 0);});};}import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
|
2
2
|
import Purchases from 'react-native-purchases';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
3
4
|
|
|
4
|
-
import { RC_API_KEY, RC_ENTITLEMENT_ID } from "../config";import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
import { RC_API_KEY, RC_ENTITLEMENT_ID, SUBSCRIPTION_ROUTE } from "../config";import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
6
|
|
|
6
7
|
var SubscriptionContext = createContext({
|
|
7
8
|
isSubscribed: false,
|
|
@@ -20,6 +21,55 @@ export function useIsSubscribed() {
|
|
|
20
21
|
return useContext(SubscriptionContext).isSubscribed;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
export function useSubscribedAction(boundFn) {
|
|
40
|
+
var _useSubscription = useSubscription(),isSubscribed = _useSubscription.isSubscribed,isLoading = _useSubscription.isLoading;
|
|
41
|
+
var _useNavigation = useNavigation(),navigate = _useNavigation.navigate;
|
|
42
|
+
|
|
43
|
+
return useCallback(
|
|
44
|
+
function () {for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}
|
|
45
|
+
var fn = boundFn || args[0];
|
|
46
|
+
var fnArgs = boundFn ? args : args.slice(1);
|
|
47
|
+
|
|
48
|
+
if (typeof fn !== 'function') {
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
console.warn(
|
|
51
|
+
'[neko-rc-subscription] useSubscribedAction: no function to run — ' +
|
|
52
|
+
'pass it to the hook `useSubscribedAction(fn)` or to the action `action(fn)`.'
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if (isLoading) return undefined;
|
|
61
|
+
|
|
62
|
+
if (!isSubscribed) {
|
|
63
|
+
navigate(SUBSCRIPTION_ROUTE);
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return fn.apply(void 0, _toConsumableArray(fnArgs));
|
|
68
|
+
},
|
|
69
|
+
[isSubscribed, isLoading, navigate, boundFn]
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
23
73
|
export default function SubscriptionHandler(_ref) {var children = _ref.children,paywallConfig = _ref.paywallConfig;
|
|
24
74
|
var _useState = useState(false),_useState2 = _slicedToArray(_useState, 2),isSubscribed = _useState2[0],setIsSubscribed = _useState2[1];
|
|
25
75
|
var _useState3 = useState(true),_useState4 = _slicedToArray(_useState3, 2),isLoading = _useState4[0],setIsLoading = _useState4[1];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-rc-subscription/src/containers/SubscriptionRequiredCTA.js";var _excluded = ["children", "disabled", "hideButton", "size", "buttonProps"];function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import { BlurView, Button, View, useTranslation } from '@neko-os/ui';
|
|
2
2
|
import { useNavigation } from '@react-navigation/native';
|
|
3
3
|
|
|
4
|
+
import { SUBSCRIPTION_ROUTE } from "../config";
|
|
4
5
|
import { useIsSubscribed } from "./SubscriptionHandler";import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
6
|
|
|
6
7
|
export default function SubscriptionRequiredCTA(_ref)
|
|
@@ -20,7 +21,7 @@ export default function SubscriptionRequiredCTA(_ref)
|
|
|
20
21
|
return (
|
|
21
22
|
_jsxs(View, Object.assign({ relative: true, hiddenOverflow: true }, props, { children: [
|
|
22
23
|
children,
|
|
23
|
-
_jsx(BlurView, { absoluteFill: true, center: true, zIndex: 10, intensity: 18, onPress: function onPress() {return navigate(
|
|
24
|
+
_jsx(BlurView, { absoluteFill: true, center: true, zIndex: 10, intensity: 18, onPress: function onPress() {return navigate(SUBSCRIPTION_ROUTE);}, children:
|
|
24
25
|
!hideButton &&
|
|
25
26
|
_jsx(Button, Object.assign({
|
|
26
27
|
label: t('cta.unlock'),
|
|
@@ -28,7 +29,7 @@ export default function SubscriptionRequiredCTA(_ref)
|
|
|
28
29
|
yellow: true,
|
|
29
30
|
size: size || 'xs' },
|
|
30
31
|
buttonProps, {
|
|
31
|
-
onPress: function onPress() {return navigate(
|
|
32
|
+
onPress: function onPress() {return navigate(SUBSCRIPTION_ROUTE);} })
|
|
32
33
|
) }
|
|
33
34
|
|
|
34
35
|
)] })
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-rc-subscription/src/containers/paywall/Paywall.js";function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}import {
|
|
2
2
|
AnimatedTopBar,
|
|
3
3
|
BlurView,
|
|
4
|
+
Link,
|
|
4
5
|
ReanimatedScrollHandler,
|
|
5
6
|
ScrollView,
|
|
7
|
+
Text,
|
|
6
8
|
View,
|
|
7
9
|
useReanimatedScroll,
|
|
8
10
|
useTranslation } from
|
|
9
11
|
'@neko-os/ui';
|
|
10
|
-
import { Platform } from "react-native-web";
|
|
12
|
+
import { Linking, Platform } from "react-native-web";
|
|
11
13
|
import { useState } from 'react';
|
|
12
14
|
import Animated from 'react-native-reanimated';
|
|
13
15
|
|
|
16
|
+
import { PRIVACY_POLICY_URL, TERMS_OF_USE_URL } from "../../config";
|
|
17
|
+
|
|
14
18
|
import { useSubscription } from "../SubscriptionHandler";
|
|
15
19
|
import PaywallFeatures from "./PaywallFeatures";
|
|
16
20
|
import PaywallFooter from "./PaywallFooter";
|
|
@@ -38,7 +42,28 @@ function getTrialDays(pkg) {var _pkg$product, _intro$periodUnit;
|
|
|
38
42
|
return units;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
function
|
|
45
|
+
function PaywallLegalLinks(_ref) {var t = _ref.t;
|
|
46
|
+
if (!PRIVACY_POLICY_URL && !TERMS_OF_USE_URL) return null;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
_jsxs(View, { row: true, center: true, gap: "xs", paddingV: "md", children: [
|
|
50
|
+
PRIVACY_POLICY_URL &&
|
|
51
|
+
_jsx(Link, { onPress: function onPress() {return Linking.openURL(PRIVACY_POLICY_URL);}, children:
|
|
52
|
+
_jsx(Text, { xs: true, text3: true, underline: true, children: t('paywall.privacyPolicy') }) }
|
|
53
|
+
),
|
|
54
|
+
|
|
55
|
+
PRIVACY_POLICY_URL && TERMS_OF_USE_URL && _jsx(Text, { xs: true, text4: true, children: "\xB7" }),
|
|
56
|
+
TERMS_OF_USE_URL &&
|
|
57
|
+
_jsx(Link, { onPress: function onPress() {return Linking.openURL(TERMS_OF_USE_URL);}, children:
|
|
58
|
+
_jsx(Text, { xs: true, text3: true, underline: true, children: t('paywall.termsOfUse') }) }
|
|
59
|
+
)] }
|
|
60
|
+
|
|
61
|
+
));
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function PaywallScrollContent(_ref2)
|
|
66
|
+
|
|
42
67
|
|
|
43
68
|
|
|
44
69
|
|
|
@@ -49,7 +74,7 @@ function PaywallScrollContent(_ref)
|
|
|
49
74
|
|
|
50
75
|
|
|
51
76
|
|
|
52
|
-
{var _this = this;var image =
|
|
77
|
+
{var _this = this;var image = _ref2.image,title = _ref2.title,subtitle = _ref2.subtitle,features = _ref2.features,packages = _ref2.packages,selectedPkg = _ref2.selectedPkg,onSelect = _ref2.onSelect,monthlyPrice = _ref2.monthlyPrice,showReturnIcon = _ref2.showReturnIcon,modal = _ref2.modal,t = _ref2.t;
|
|
53
78
|
var _useReanimatedScroll = useReanimatedScroll(),scrollHandler = _useReanimatedScroll.scrollHandler;
|
|
54
79
|
|
|
55
80
|
return (
|
|
@@ -68,12 +93,13 @@ function PaywallScrollContent(_ref)
|
|
|
68
93
|
));}
|
|
69
94
|
) }
|
|
70
95
|
),
|
|
96
|
+
_jsx(PaywallLegalLinks, { t: t }),
|
|
71
97
|
_jsx(View, { height: 200 })] }
|
|
72
98
|
));
|
|
73
99
|
|
|
74
100
|
}
|
|
75
101
|
|
|
76
|
-
export default function Paywall(
|
|
102
|
+
export default function Paywall(_ref3) {var _packages$find, _packages$find$produc;var modal = _ref3.modal,showReturn = _ref3.showReturn,footerPaddingB = _ref3.footerPaddingB;
|
|
77
103
|
var _useTranslation = useTranslation('subscription'),t = _useTranslation.t;
|
|
78
104
|
var _useSubscription = useSubscription(),offerings = _useSubscription.offerings,paywallConfig = _useSubscription.paywallConfig;
|
|
79
105
|
var _usePaywallActions = usePaywallActions(),handlePurchase = _usePaywallActions.handlePurchase,handleRestore = _usePaywallActions.handleRestore,loading = _usePaywallActions.loading;
|
|
@@ -114,7 +140,8 @@ export default function Paywall(_ref2) {var _packages$find, _packages$find$produ
|
|
|
114
140
|
onSelect: setSelectedPkg,
|
|
115
141
|
monthlyPrice: monthlyPrice,
|
|
116
142
|
showReturnIcon: showReturnIcon,
|
|
117
|
-
modal: modal
|
|
143
|
+
modal: modal,
|
|
144
|
+
t: t }
|
|
118
145
|
)] }
|
|
119
146
|
),
|
|
120
147
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { registerSubscriptionLocales } from "./locales/index";
|
|
2
|
-
export { default as SubscriptionHandler, useIsSubscribed, useSubscription } from "./containers/SubscriptionHandler";
|
|
2
|
+
export { default as SubscriptionHandler, useIsSubscribed, useSubscribedAction, useSubscription } from "./containers/SubscriptionHandler";
|
|
3
3
|
export { default as SubscriptionRequired } from "./containers/SubscriptionRequired";
|
|
4
4
|
export { default as SubscriptionRequiredCTA } from "./containers/SubscriptionRequiredCTA";
|
|
5
5
|
export { default as Paywall } from "./containers/paywall/Paywall";
|
package/dist/locales/cs.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionCS = {
|
|
|
8
8
|
cta: 'Pokracovat',
|
|
9
9
|
ctaTrial: 'Zahajit zkusebni obdobi',
|
|
10
10
|
restore: 'Obnovit nakupy',
|
|
11
|
+
privacyPolicy: 'Zásady ochrany osobních údajů',
|
|
12
|
+
termsOfUse: 'Podmínky použití',
|
|
11
13
|
monthly: 'Mesicne',
|
|
12
14
|
yearly: 'Rocne',
|
|
13
15
|
lifetime: 'Dozivotne',
|
package/dist/locales/da.js
CHANGED
package/dist/locales/de.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionDE = {
|
|
|
8
8
|
cta: 'Weiter',
|
|
9
9
|
ctaTrial: 'Kostenlos testen',
|
|
10
10
|
restore: 'Kaeufe wiederherstellen',
|
|
11
|
+
privacyPolicy: 'Datenschutzerklärung',
|
|
12
|
+
termsOfUse: 'Nutzungsbedingungen',
|
|
11
13
|
monthly: 'Monatlich',
|
|
12
14
|
yearly: 'Jaehrlich',
|
|
13
15
|
lifetime: 'Lebenslang',
|
package/dist/locales/el.js
CHANGED
package/dist/locales/en.js
CHANGED
package/dist/locales/es.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionES = {
|
|
|
8
8
|
cta: 'Continuar',
|
|
9
9
|
ctaTrial: 'Iniciar prueba gratuita',
|
|
10
10
|
restore: 'Restaurar compras',
|
|
11
|
+
privacyPolicy: 'Política de Privacidad',
|
|
12
|
+
termsOfUse: 'Términos de Uso',
|
|
11
13
|
monthly: 'Mensual',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'De por vida',
|
package/dist/locales/fi.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionFI = {
|
|
|
8
8
|
cta: 'Jatka',
|
|
9
9
|
ctaTrial: 'Aloita ilmainen kokeilu',
|
|
10
10
|
restore: 'Palauta ostokset',
|
|
11
|
+
privacyPolicy: 'Tietosuojakäytäntö',
|
|
12
|
+
termsOfUse: 'Käyttöehdot',
|
|
11
13
|
monthly: 'Kuukausittain',
|
|
12
14
|
yearly: 'Vuosittain',
|
|
13
15
|
lifetime: 'Elinaika',
|
package/dist/locales/fr.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionFR = {
|
|
|
8
8
|
cta: 'Continuer',
|
|
9
9
|
ctaTrial: 'Demarrer l\'essai gratuit',
|
|
10
10
|
restore: 'Restaurer les achats',
|
|
11
|
+
privacyPolicy: 'Politique de Confidentialité',
|
|
12
|
+
termsOfUse: "Conditions d'Utilisation",
|
|
11
13
|
monthly: 'Mensuel',
|
|
12
14
|
yearly: 'Annuel',
|
|
13
15
|
lifetime: 'A vie',
|
package/dist/locales/hi.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionHI = {
|
|
|
8
8
|
cta: 'Jaree rakhen',
|
|
9
9
|
ctaTrial: 'Nishulk pareekshan shuru karen',
|
|
10
10
|
restore: 'Khareedaaree punastaapeet karen',
|
|
11
|
+
privacyPolicy: 'गोपनीयता नीति',
|
|
12
|
+
termsOfUse: 'उपयोग की शर्तें',
|
|
11
13
|
monthly: 'Maaseek',
|
|
12
14
|
yearly: 'Vaarshik',
|
|
13
15
|
lifetime: 'Aajeevon',
|
package/dist/locales/hu.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionHU = {
|
|
|
8
8
|
cta: 'Folytatas',
|
|
9
9
|
ctaTrial: 'Ingyenes proba inditasa',
|
|
10
10
|
restore: 'Vasarlasok visszaallitasa',
|
|
11
|
+
privacyPolicy: 'Adatvédelmi irányelvek',
|
|
12
|
+
termsOfUse: 'Felhasználási feltételek',
|
|
11
13
|
monthly: 'Havi',
|
|
12
14
|
yearly: 'Eves',
|
|
13
15
|
lifetime: 'Elettartam',
|
package/dist/locales/id.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionID = {
|
|
|
8
8
|
cta: 'Lanjutkan',
|
|
9
9
|
ctaTrial: 'Mulai uji coba gratis',
|
|
10
10
|
restore: 'Pulihkan pembelian',
|
|
11
|
+
privacyPolicy: 'Kebijakan Privasi',
|
|
12
|
+
termsOfUse: 'Ketentuan Penggunaan',
|
|
11
13
|
monthly: 'Bulanan',
|
|
12
14
|
yearly: 'Tahunan',
|
|
13
15
|
lifetime: 'Seumur hidup',
|
package/dist/locales/it.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionIT = {
|
|
|
8
8
|
cta: 'Continua',
|
|
9
9
|
ctaTrial: 'Inizia la prova gratuita',
|
|
10
10
|
restore: 'Ripristina acquisti',
|
|
11
|
+
privacyPolicy: 'Informativa sulla Privacy',
|
|
12
|
+
termsOfUse: 'Termini di Utilizzo',
|
|
11
13
|
monthly: 'Mensile',
|
|
12
14
|
yearly: 'Annuale',
|
|
13
15
|
lifetime: 'A vita',
|
package/dist/locales/ja.js
CHANGED
package/dist/locales/ko.js
CHANGED
package/dist/locales/nl.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionNL = {
|
|
|
8
8
|
cta: 'Doorgaan',
|
|
9
9
|
ctaTrial: 'Start gratis proefperiode',
|
|
10
10
|
restore: 'Aankopen herstellen',
|
|
11
|
+
privacyPolicy: 'Privacybeleid',
|
|
12
|
+
termsOfUse: 'Gebruiksvoorwaarden',
|
|
11
13
|
monthly: 'Maandelijks',
|
|
12
14
|
yearly: 'Jaarlijks',
|
|
13
15
|
lifetime: 'Levenslang',
|
package/dist/locales/no.js
CHANGED
package/dist/locales/pl.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionPL = {
|
|
|
8
8
|
cta: 'Kontynuuj',
|
|
9
9
|
ctaTrial: 'Rozpocznij bezpłatny okres próbny',
|
|
10
10
|
restore: 'Przywróć zakupy',
|
|
11
|
+
privacyPolicy: 'Polityka Prywatności',
|
|
12
|
+
termsOfUse: 'Warunki Użytkowania',
|
|
11
13
|
monthly: 'Miesięcznie',
|
|
12
14
|
yearly: 'Rocznie',
|
|
13
15
|
lifetime: 'Dożywotnio',
|
package/dist/locales/pt.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionPT = {
|
|
|
8
8
|
cta: 'Continuar',
|
|
9
9
|
ctaTrial: 'Iniciar teste gratuito',
|
|
10
10
|
restore: 'Restaurar compras',
|
|
11
|
+
privacyPolicy: 'Política de Privacidade',
|
|
12
|
+
termsOfUse: 'Termos de Uso',
|
|
11
13
|
monthly: 'Mensal',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'Vitalício',
|
package/dist/locales/ro.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionRO = {
|
|
|
8
8
|
cta: 'Continuă',
|
|
9
9
|
ctaTrial: 'Începe perioada de probă gratuită',
|
|
10
10
|
restore: 'Restaurează achizițiile',
|
|
11
|
+
privacyPolicy: 'Politica de Confidențialitate',
|
|
12
|
+
termsOfUse: 'Termeni de Utilizare',
|
|
11
13
|
monthly: 'Lunar',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'Pe viață',
|
package/dist/locales/ru.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionRU = {
|
|
|
8
8
|
cta: 'Продолжить',
|
|
9
9
|
ctaTrial: 'Начать бесплатный пробный период',
|
|
10
10
|
restore: 'Восстановить покупки',
|
|
11
|
+
privacyPolicy: 'Политика конфиденциальности',
|
|
12
|
+
termsOfUse: 'Условия использования',
|
|
11
13
|
monthly: 'Ежемесячно',
|
|
12
14
|
yearly: 'Ежегодно',
|
|
13
15
|
lifetime: 'Навсегда',
|
package/dist/locales/sv.js
CHANGED
package/dist/locales/th.js
CHANGED
package/dist/locales/tr.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionTR = {
|
|
|
8
8
|
cta: 'Devam et',
|
|
9
9
|
ctaTrial: 'Ücretsiz denemeyi başlat',
|
|
10
10
|
restore: 'Satın alımları geri yükle',
|
|
11
|
+
privacyPolicy: 'Gizlilik Politikası',
|
|
12
|
+
termsOfUse: 'Kullanım Koşulları',
|
|
11
13
|
monthly: 'Aylık',
|
|
12
14
|
yearly: 'Yıllık',
|
|
13
15
|
lifetime: 'Ömür boyu',
|
package/dist/locales/uk.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionUK = {
|
|
|
8
8
|
cta: 'Продовжити',
|
|
9
9
|
ctaTrial: 'Почати безкоштовний пробний період',
|
|
10
10
|
restore: 'Відновити покупки',
|
|
11
|
+
privacyPolicy: 'Політика конфіденційності',
|
|
12
|
+
termsOfUse: 'Умови використання',
|
|
11
13
|
monthly: 'Щомісячно',
|
|
12
14
|
yearly: 'Щорічно',
|
|
13
15
|
lifetime: 'Назавжди',
|
package/dist/locales/vi.js
CHANGED
|
@@ -8,6 +8,8 @@ export var subscriptionVI = {
|
|
|
8
8
|
cta: 'Tiếp tục',
|
|
9
9
|
ctaTrial: 'Bắt đầu dùng thử miễn phí',
|
|
10
10
|
restore: 'Khôi phục giao dịch',
|
|
11
|
+
privacyPolicy: 'Chính sách Bảo mật',
|
|
12
|
+
termsOfUse: 'Điều khoản Sử dụng',
|
|
11
13
|
monthly: 'Hàng tháng',
|
|
12
14
|
yearly: 'Hàng năm',
|
|
13
15
|
lifetime: 'Trọn đời',
|
package/dist/locales/zh.js
CHANGED
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -3,3 +3,9 @@ import { Platform } from 'react-native'
|
|
|
3
3
|
export const RC_API_KEY =
|
|
4
4
|
Platform.OS === 'ios' ? process.env.EXPO_PUBLIC_RC_API_KEY_IOS : process.env.EXPO_PUBLIC_RC_API_KEY_ANDROID
|
|
5
5
|
export const RC_ENTITLEMENT_ID = process.env.EXPO_PUBLIC_RC_ENTITLEMENT_ID || 'premium'
|
|
6
|
+
export const PRIVACY_POLICY_URL = process.env.EXPO_PUBLIC_PRIVACY_POLICY_URL
|
|
7
|
+
export const TERMS_OF_USE_URL = process.env.EXPO_PUBLIC_TERMS_OF_USE_URL
|
|
8
|
+
|
|
9
|
+
// Route that renders ActiveSubscriptionView, which shows the Paywall when the
|
|
10
|
+
// user is not subscribed. Used to imperatively open the paywall.
|
|
11
|
+
export const SUBSCRIPTION_ROUTE = 'subscription/active'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import React, { createContext, useContext, useEffect, useState } from 'react'
|
|
1
|
+
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
|
2
2
|
import Purchases from 'react-native-purchases'
|
|
3
|
+
import { useNavigation } from '@react-navigation/native'
|
|
3
4
|
|
|
4
|
-
import { RC_API_KEY, RC_ENTITLEMENT_ID } from '../config'
|
|
5
|
+
import { RC_API_KEY, RC_ENTITLEMENT_ID, SUBSCRIPTION_ROUTE } from '../config'
|
|
5
6
|
|
|
6
7
|
const SubscriptionContext = createContext({
|
|
7
8
|
isSubscribed: false,
|
|
@@ -20,6 +21,55 @@ export function useIsSubscribed() {
|
|
|
20
21
|
return useContext(SubscriptionContext).isSubscribed
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Returns an action wrapper that only runs when the user is subscribed,
|
|
26
|
+
* otherwise opens the paywall (navigates to `subscription/active`).
|
|
27
|
+
*
|
|
28
|
+
* Two equivalent call styles:
|
|
29
|
+
*
|
|
30
|
+
* const action = useSubscribedAction(fn) // bind the fn up front
|
|
31
|
+
* action(...args) // -> fn(...args) if subscribed
|
|
32
|
+
*
|
|
33
|
+
* const action = useSubscribedAction() // bind nothing
|
|
34
|
+
* action(fn, ...args) // -> fn(...args) if subscribed
|
|
35
|
+
*
|
|
36
|
+
* Returns the result of `fn` when subscribed, or `undefined` when the paywall
|
|
37
|
+
* is shown instead.
|
|
38
|
+
*/
|
|
39
|
+
export function useSubscribedAction(boundFn) {
|
|
40
|
+
const { isSubscribed, isLoading } = useSubscription()
|
|
41
|
+
const { navigate } = useNavigation()
|
|
42
|
+
|
|
43
|
+
return useCallback(
|
|
44
|
+
(...args) => {
|
|
45
|
+
const fn = boundFn || args[0]
|
|
46
|
+
const fnArgs = boundFn ? args : args.slice(1)
|
|
47
|
+
|
|
48
|
+
if (typeof fn !== 'function') {
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
console.warn(
|
|
51
|
+
'[neko-rc-subscription] useSubscribedAction: no function to run — ' +
|
|
52
|
+
'pass it to the hook `useSubscribedAction(fn)` or to the action `action(fn)`.',
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
return undefined
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Subscription state not resolved yet: no-op rather than wrongly bouncing
|
|
59
|
+
// an already-subscribed user to the paywall.
|
|
60
|
+
if (isLoading) return undefined
|
|
61
|
+
|
|
62
|
+
if (!isSubscribed) {
|
|
63
|
+
navigate(SUBSCRIPTION_ROUTE)
|
|
64
|
+
return undefined
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return fn(...fnArgs)
|
|
68
|
+
},
|
|
69
|
+
[isSubscribed, isLoading, navigate, boundFn],
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
23
73
|
export default function SubscriptionHandler({ children, paywallConfig }) {
|
|
24
74
|
const [isSubscribed, setIsSubscribed] = useState(false)
|
|
25
75
|
const [isLoading, setIsLoading] = useState(true)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BlurView, Button, View, useTranslation } from '@neko-os/ui'
|
|
2
2
|
import { useNavigation } from '@react-navigation/native'
|
|
3
3
|
|
|
4
|
+
import { SUBSCRIPTION_ROUTE } from '../config'
|
|
4
5
|
import { useIsSubscribed } from './SubscriptionHandler'
|
|
5
6
|
|
|
6
7
|
export default function SubscriptionRequiredCTA({
|
|
@@ -20,7 +21,7 @@ export default function SubscriptionRequiredCTA({
|
|
|
20
21
|
return (
|
|
21
22
|
<View relative hiddenOverflow {...props}>
|
|
22
23
|
{children}
|
|
23
|
-
<BlurView absoluteFill center zIndex={10} intensity={18} onPress={() => navigate(
|
|
24
|
+
<BlurView absoluteFill center zIndex={10} intensity={18} onPress={() => navigate(SUBSCRIPTION_ROUTE)}>
|
|
24
25
|
{!hideButton && (
|
|
25
26
|
<Button
|
|
26
27
|
label={t('cta.unlock')}
|
|
@@ -28,7 +29,7 @@ export default function SubscriptionRequiredCTA({
|
|
|
28
29
|
yellow
|
|
29
30
|
size={size || 'xs'}
|
|
30
31
|
{...buttonProps}
|
|
31
|
-
onPress={() => navigate(
|
|
32
|
+
onPress={() => navigate(SUBSCRIPTION_ROUTE)}
|
|
32
33
|
/>
|
|
33
34
|
)}
|
|
34
35
|
</BlurView>
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnimatedTopBar,
|
|
3
3
|
BlurView,
|
|
4
|
+
Link,
|
|
4
5
|
ReanimatedScrollHandler,
|
|
5
6
|
ScrollView,
|
|
7
|
+
Text,
|
|
6
8
|
View,
|
|
7
9
|
useReanimatedScroll,
|
|
8
10
|
useTranslation,
|
|
9
11
|
} from '@neko-os/ui'
|
|
10
|
-
import { Platform } from 'react-native'
|
|
12
|
+
import { Linking, Platform } from 'react-native'
|
|
11
13
|
import { useState } from 'react'
|
|
12
14
|
import Animated from 'react-native-reanimated'
|
|
13
15
|
|
|
16
|
+
import { PRIVACY_POLICY_URL, TERMS_OF_USE_URL } from '../../config'
|
|
17
|
+
|
|
14
18
|
import { useSubscription } from '../SubscriptionHandler'
|
|
15
19
|
import PaywallFeatures from './PaywallFeatures'
|
|
16
20
|
import PaywallFooter from './PaywallFooter'
|
|
@@ -38,6 +42,26 @@ function getTrialDays(pkg) {
|
|
|
38
42
|
return units
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
function PaywallLegalLinks({ t }) {
|
|
46
|
+
if (!PRIVACY_POLICY_URL && !TERMS_OF_USE_URL) return null
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<View row center gap="xs" paddingV="md">
|
|
50
|
+
{PRIVACY_POLICY_URL && (
|
|
51
|
+
<Link onPress={() => Linking.openURL(PRIVACY_POLICY_URL)}>
|
|
52
|
+
<Text xs text3 underline>{t('paywall.privacyPolicy')}</Text>
|
|
53
|
+
</Link>
|
|
54
|
+
)}
|
|
55
|
+
{PRIVACY_POLICY_URL && TERMS_OF_USE_URL && <Text xs text4>·</Text>}
|
|
56
|
+
{TERMS_OF_USE_URL && (
|
|
57
|
+
<Link onPress={() => Linking.openURL(TERMS_OF_USE_URL)}>
|
|
58
|
+
<Text xs text3 underline>{t('paywall.termsOfUse')}</Text>
|
|
59
|
+
</Link>
|
|
60
|
+
)}
|
|
61
|
+
</View>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
41
65
|
function PaywallScrollContent({
|
|
42
66
|
image,
|
|
43
67
|
title,
|
|
@@ -49,6 +73,7 @@ function PaywallScrollContent({
|
|
|
49
73
|
monthlyPrice,
|
|
50
74
|
showReturnIcon,
|
|
51
75
|
modal,
|
|
76
|
+
t,
|
|
52
77
|
}) {
|
|
53
78
|
const { scrollHandler } = useReanimatedScroll()
|
|
54
79
|
|
|
@@ -68,6 +93,7 @@ function PaywallScrollContent({
|
|
|
68
93
|
/>
|
|
69
94
|
))}
|
|
70
95
|
</View>
|
|
96
|
+
<PaywallLegalLinks t={t} />
|
|
71
97
|
<View height={200} />
|
|
72
98
|
</AnimatedScrollView>
|
|
73
99
|
)
|
|
@@ -115,6 +141,7 @@ export default function Paywall({ modal, showReturn, footerPaddingB }) {
|
|
|
115
141
|
monthlyPrice={monthlyPrice}
|
|
116
142
|
showReturnIcon={showReturnIcon}
|
|
117
143
|
modal={modal}
|
|
144
|
+
t={t}
|
|
118
145
|
/>
|
|
119
146
|
</ReanimatedScrollHandler>
|
|
120
147
|
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { registerSubscriptionLocales } from './locales/index'
|
|
2
|
-
export { default as SubscriptionHandler, useIsSubscribed, useSubscription } from './containers/SubscriptionHandler'
|
|
2
|
+
export { default as SubscriptionHandler, useIsSubscribed, useSubscribedAction, useSubscription } from './containers/SubscriptionHandler'
|
|
3
3
|
export { default as SubscriptionRequired } from './containers/SubscriptionRequired'
|
|
4
4
|
export { default as SubscriptionRequiredCTA } from './containers/SubscriptionRequiredCTA'
|
|
5
5
|
export { default as Paywall } from './containers/paywall/Paywall'
|
package/src/locales/cs.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionCS = {
|
|
|
8
8
|
cta: 'Pokracovat',
|
|
9
9
|
ctaTrial: 'Zahajit zkusebni obdobi',
|
|
10
10
|
restore: 'Obnovit nakupy',
|
|
11
|
+
privacyPolicy: 'Zásady ochrany osobních údajů',
|
|
12
|
+
termsOfUse: 'Podmínky použití',
|
|
11
13
|
monthly: 'Mesicne',
|
|
12
14
|
yearly: 'Rocne',
|
|
13
15
|
lifetime: 'Dozivotne',
|
package/src/locales/da.js
CHANGED
package/src/locales/de.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionDE = {
|
|
|
8
8
|
cta: 'Weiter',
|
|
9
9
|
ctaTrial: 'Kostenlos testen',
|
|
10
10
|
restore: 'Kaeufe wiederherstellen',
|
|
11
|
+
privacyPolicy: 'Datenschutzerklärung',
|
|
12
|
+
termsOfUse: 'Nutzungsbedingungen',
|
|
11
13
|
monthly: 'Monatlich',
|
|
12
14
|
yearly: 'Jaehrlich',
|
|
13
15
|
lifetime: 'Lebenslang',
|
package/src/locales/el.js
CHANGED
package/src/locales/en.js
CHANGED
package/src/locales/es.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionES = {
|
|
|
8
8
|
cta: 'Continuar',
|
|
9
9
|
ctaTrial: 'Iniciar prueba gratuita',
|
|
10
10
|
restore: 'Restaurar compras',
|
|
11
|
+
privacyPolicy: 'Política de Privacidad',
|
|
12
|
+
termsOfUse: 'Términos de Uso',
|
|
11
13
|
monthly: 'Mensual',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'De por vida',
|
package/src/locales/fi.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionFI = {
|
|
|
8
8
|
cta: 'Jatka',
|
|
9
9
|
ctaTrial: 'Aloita ilmainen kokeilu',
|
|
10
10
|
restore: 'Palauta ostokset',
|
|
11
|
+
privacyPolicy: 'Tietosuojakäytäntö',
|
|
12
|
+
termsOfUse: 'Käyttöehdot',
|
|
11
13
|
monthly: 'Kuukausittain',
|
|
12
14
|
yearly: 'Vuosittain',
|
|
13
15
|
lifetime: 'Elinaika',
|
package/src/locales/fr.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionFR = {
|
|
|
8
8
|
cta: 'Continuer',
|
|
9
9
|
ctaTrial: 'Demarrer l\'essai gratuit',
|
|
10
10
|
restore: 'Restaurer les achats',
|
|
11
|
+
privacyPolicy: 'Politique de Confidentialité',
|
|
12
|
+
termsOfUse: "Conditions d'Utilisation",
|
|
11
13
|
monthly: 'Mensuel',
|
|
12
14
|
yearly: 'Annuel',
|
|
13
15
|
lifetime: 'A vie',
|
package/src/locales/hi.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionHI = {
|
|
|
8
8
|
cta: 'Jaree rakhen',
|
|
9
9
|
ctaTrial: 'Nishulk pareekshan shuru karen',
|
|
10
10
|
restore: 'Khareedaaree punastaapeet karen',
|
|
11
|
+
privacyPolicy: 'गोपनीयता नीति',
|
|
12
|
+
termsOfUse: 'उपयोग की शर्तें',
|
|
11
13
|
monthly: 'Maaseek',
|
|
12
14
|
yearly: 'Vaarshik',
|
|
13
15
|
lifetime: 'Aajeevon',
|
package/src/locales/hu.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionHU = {
|
|
|
8
8
|
cta: 'Folytatas',
|
|
9
9
|
ctaTrial: 'Ingyenes proba inditasa',
|
|
10
10
|
restore: 'Vasarlasok visszaallitasa',
|
|
11
|
+
privacyPolicy: 'Adatvédelmi irányelvek',
|
|
12
|
+
termsOfUse: 'Felhasználási feltételek',
|
|
11
13
|
monthly: 'Havi',
|
|
12
14
|
yearly: 'Eves',
|
|
13
15
|
lifetime: 'Elettartam',
|
package/src/locales/id.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionID = {
|
|
|
8
8
|
cta: 'Lanjutkan',
|
|
9
9
|
ctaTrial: 'Mulai uji coba gratis',
|
|
10
10
|
restore: 'Pulihkan pembelian',
|
|
11
|
+
privacyPolicy: 'Kebijakan Privasi',
|
|
12
|
+
termsOfUse: 'Ketentuan Penggunaan',
|
|
11
13
|
monthly: 'Bulanan',
|
|
12
14
|
yearly: 'Tahunan',
|
|
13
15
|
lifetime: 'Seumur hidup',
|
package/src/locales/it.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionIT = {
|
|
|
8
8
|
cta: 'Continua',
|
|
9
9
|
ctaTrial: 'Inizia la prova gratuita',
|
|
10
10
|
restore: 'Ripristina acquisti',
|
|
11
|
+
privacyPolicy: 'Informativa sulla Privacy',
|
|
12
|
+
termsOfUse: 'Termini di Utilizzo',
|
|
11
13
|
monthly: 'Mensile',
|
|
12
14
|
yearly: 'Annuale',
|
|
13
15
|
lifetime: 'A vita',
|
package/src/locales/ja.js
CHANGED
package/src/locales/ko.js
CHANGED
package/src/locales/nl.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionNL = {
|
|
|
8
8
|
cta: 'Doorgaan',
|
|
9
9
|
ctaTrial: 'Start gratis proefperiode',
|
|
10
10
|
restore: 'Aankopen herstellen',
|
|
11
|
+
privacyPolicy: 'Privacybeleid',
|
|
12
|
+
termsOfUse: 'Gebruiksvoorwaarden',
|
|
11
13
|
monthly: 'Maandelijks',
|
|
12
14
|
yearly: 'Jaarlijks',
|
|
13
15
|
lifetime: 'Levenslang',
|
package/src/locales/no.js
CHANGED
package/src/locales/pl.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionPL = {
|
|
|
8
8
|
cta: 'Kontynuuj',
|
|
9
9
|
ctaTrial: 'Rozpocznij bezpłatny okres próbny',
|
|
10
10
|
restore: 'Przywróć zakupy',
|
|
11
|
+
privacyPolicy: 'Polityka Prywatności',
|
|
12
|
+
termsOfUse: 'Warunki Użytkowania',
|
|
11
13
|
monthly: 'Miesięcznie',
|
|
12
14
|
yearly: 'Rocznie',
|
|
13
15
|
lifetime: 'Dożywotnio',
|
package/src/locales/pt.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionPT = {
|
|
|
8
8
|
cta: 'Continuar',
|
|
9
9
|
ctaTrial: 'Iniciar teste gratuito',
|
|
10
10
|
restore: 'Restaurar compras',
|
|
11
|
+
privacyPolicy: 'Política de Privacidade',
|
|
12
|
+
termsOfUse: 'Termos de Uso',
|
|
11
13
|
monthly: 'Mensal',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'Vitalício',
|
package/src/locales/ro.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionRO = {
|
|
|
8
8
|
cta: 'Continuă',
|
|
9
9
|
ctaTrial: 'Începe perioada de probă gratuită',
|
|
10
10
|
restore: 'Restaurează achizițiile',
|
|
11
|
+
privacyPolicy: 'Politica de Confidențialitate',
|
|
12
|
+
termsOfUse: 'Termeni de Utilizare',
|
|
11
13
|
monthly: 'Lunar',
|
|
12
14
|
yearly: 'Anual',
|
|
13
15
|
lifetime: 'Pe viață',
|
package/src/locales/ru.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionRU = {
|
|
|
8
8
|
cta: 'Продолжить',
|
|
9
9
|
ctaTrial: 'Начать бесплатный пробный период',
|
|
10
10
|
restore: 'Восстановить покупки',
|
|
11
|
+
privacyPolicy: 'Политика конфиденциальности',
|
|
12
|
+
termsOfUse: 'Условия использования',
|
|
11
13
|
monthly: 'Ежемесячно',
|
|
12
14
|
yearly: 'Ежегодно',
|
|
13
15
|
lifetime: 'Навсегда',
|
package/src/locales/sv.js
CHANGED
package/src/locales/th.js
CHANGED
package/src/locales/tr.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionTR = {
|
|
|
8
8
|
cta: 'Devam et',
|
|
9
9
|
ctaTrial: 'Ücretsiz denemeyi başlat',
|
|
10
10
|
restore: 'Satın alımları geri yükle',
|
|
11
|
+
privacyPolicy: 'Gizlilik Politikası',
|
|
12
|
+
termsOfUse: 'Kullanım Koşulları',
|
|
11
13
|
monthly: 'Aylık',
|
|
12
14
|
yearly: 'Yıllık',
|
|
13
15
|
lifetime: 'Ömür boyu',
|
package/src/locales/uk.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionUK = {
|
|
|
8
8
|
cta: 'Продовжити',
|
|
9
9
|
ctaTrial: 'Почати безкоштовний пробний період',
|
|
10
10
|
restore: 'Відновити покупки',
|
|
11
|
+
privacyPolicy: 'Політика конфіденційності',
|
|
12
|
+
termsOfUse: 'Умови використання',
|
|
11
13
|
monthly: 'Щомісячно',
|
|
12
14
|
yearly: 'Щорічно',
|
|
13
15
|
lifetime: 'Назавжди',
|
package/src/locales/vi.js
CHANGED
|
@@ -8,6 +8,8 @@ export const subscriptionVI = {
|
|
|
8
8
|
cta: 'Tiếp tục',
|
|
9
9
|
ctaTrial: 'Bắt đầu dùng thử miễn phí',
|
|
10
10
|
restore: 'Khôi phục giao dịch',
|
|
11
|
+
privacyPolicy: 'Chính sách Bảo mật',
|
|
12
|
+
termsOfUse: 'Điều khoản Sử dụng',
|
|
11
13
|
monthly: 'Hàng tháng',
|
|
12
14
|
yearly: 'Hàng năm',
|
|
13
15
|
lifetime: 'Trọn đời',
|