@nakamura-123/pages 0.0.1 → 0.1.1

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 (154) hide show
  1. package/dist/component/Basic/BasicContents.d.ts +10 -0
  2. package/dist/component/Basic/BasicContents.js +117 -0
  3. package/dist/component/BasicSetting.js +1 -0
  4. package/dist/component/Coin/CatchCopy.js +1 -1
  5. package/dist/component/Coin/CoinCheck.d.ts +12 -0
  6. package/dist/component/Coin/CoinCheck.js +80 -0
  7. package/dist/component/Coin/CoinFnc.d.ts +6 -0
  8. package/dist/component/Coin/CoinFnc.js +240 -0
  9. package/dist/component/Coin/CoinPageComponent.d.ts +15 -0
  10. package/dist/component/Coin/CoinPageComponent.js +73 -0
  11. package/dist/component/Coin/ReceiptFnc.d.ts +6 -0
  12. package/dist/component/Coin/ReceiptFnc.js +56 -0
  13. package/dist/component/Coin/Recommend.js +1 -1
  14. package/dist/component/Coin/WaitingPayBanner.d.ts +6 -0
  15. package/dist/component/Coin/WaitingPayBanner.js +19 -0
  16. package/dist/component/Coin/WarnBanner.d.ts +3 -0
  17. package/dist/component/Coin/WarnBanner.js +14 -0
  18. package/dist/component/Discription.d.ts +6 -0
  19. package/dist/component/Discription.js +28 -0
  20. package/dist/component/Grade/GradeCard/ChangeWeeklyModal.js +4 -7
  21. package/dist/component/Grade/GradeCard/DatePickerModal.js +10 -1
  22. package/dist/component/Grade/GradeCard/Square3sGrade.js +1 -3
  23. package/dist/component/Grade/GradeCard/StoreReview.d.ts +3 -0
  24. package/dist/component/Grade/GradeCard/StoreReview.js +92 -0
  25. package/dist/component/Grade/GradeCard/TargetDate.js +10 -6
  26. package/dist/component/Grade/GradeCard/WeeklyProgress.js +1 -2
  27. package/dist/component/Grade/QuizCntGraph.js +1 -3
  28. package/dist/component/Grade/StoreReview.d.ts +3 -0
  29. package/dist/component/Grade/StoreReview.js +92 -0
  30. package/dist/component/MiniTestCard.d.ts +1 -0
  31. package/dist/component/MiniTestCard.js +10 -4
  32. package/dist/component/OnlineInput/OnlineInputFnc.d.ts +3 -0
  33. package/dist/component/OnlineInput/OnlineInputFnc.js +34 -0
  34. package/dist/component/OnlineInput/OnlineSaveBtn.d.ts +6 -0
  35. package/dist/component/OnlineInput/OnlineSaveBtn.js +24 -0
  36. package/dist/component/OnlineInput/OnlineSavedList.d.ts +7 -0
  37. package/dist/component/OnlineInput/OnlineSavedList.js +35 -0
  38. package/dist/component/OnlineInput/OnlineSavetList.d.ts +3 -0
  39. package/dist/component/OnlineInput/OnlineSavetList.js +29 -0
  40. package/dist/component/OnlineInput/PasswardModal.d.ts +7 -0
  41. package/dist/component/OnlineInput/PasswardModal.js +155 -0
  42. package/dist/component/OnlineInput/PasswordIdModal.d.ts +9 -0
  43. package/dist/component/OnlineInput/PasswordIdModal.js +148 -0
  44. package/dist/component/OnlineSave/OnlineSavePage.d.ts +3 -0
  45. package/dist/component/OnlineSave/OnlineSavePage.js +26 -0
  46. package/dist/component/QuizSet/QuizOptionDrill.js +1 -1
  47. package/dist/component/SelectRange/SelectYearRange.js +6 -4
  48. package/dist/component/SubCategoryLeft.d.ts +1 -0
  49. package/dist/component/SubCategoryLeft.js +3 -1
  50. package/dist/component/SubCategoryList.d.ts +1 -0
  51. package/dist/component/SubCategoryList.js +40 -8
  52. package/dist/component/TabAnimeView.js +1 -3
  53. package/dist/component/TabContentsWrap-suteru.d.ts +0 -0
  54. package/dist/component/TabContentsWrap-suteru.js +50 -0
  55. package/dist/component/TabContentsWrap.d.ts +0 -7
  56. package/dist/component/TabContentsWrap.js +49 -37
  57. package/dist/component/Tag5s.js +1 -3
  58. package/dist/component/TagBadge5s.d.ts +3 -2
  59. package/dist/component/TagBadge5s.js +2 -3
  60. package/dist/component/TestPage/AverageBar.js +1 -2
  61. package/dist/functions/gradeFnc.d.ts +1 -0
  62. package/dist/functions/gradeFnc.js +84 -1
  63. package/dist/functions/questionFormat.js +1 -1
  64. package/dist/functions/tagFnc.d.ts +1 -0
  65. package/dist/functions/tagFnc.js +15 -7
  66. package/dist/functions/testFnc.js +4 -3
  67. package/dist/hooks/BadgeHook.js +0 -11
  68. package/dist/hooks/basicHook.js +3 -2
  69. package/dist/index.d.ts +3 -1
  70. package/dist/index.js +5 -1
  71. package/dist/page/BasicPage.js +32 -77
  72. package/dist/page/BootPage.js +13 -2
  73. package/dist/page/CoinPage.js +152 -42
  74. package/dist/page/FAQPage.d.ts +3 -0
  75. package/dist/page/FAQPage.js +190 -0
  76. package/dist/page/GetBadgePage.js +0 -1
  77. package/dist/page/GradePage.js +31 -1
  78. package/dist/page/HomePage.js +13 -5
  79. package/dist/page/ImgZoom.js +1 -6
  80. package/dist/page/OnlineInputPage.d.ts +3 -0
  81. package/dist/page/OnlineInputPage.js +75 -0
  82. package/dist/page/OnlineSavePage.d.ts +3 -0
  83. package/dist/page/OnlineSavePage.js +26 -0
  84. package/dist/page/QuizPage 2.d.ts +7 -0
  85. package/dist/page/QuizPage 2.js +105 -0
  86. package/dist/page/QuizPage copy.d.ts +0 -0
  87. package/dist/page/QuizPage copy.js +69 -0
  88. package/dist/page/QuizPage.js +14 -2
  89. package/dist/page/QuizSettingPage.js +13 -1
  90. package/dist/page/QuizSetupPage.js +1 -1
  91. package/dist/page/ReportPage.js +5 -3
  92. package/dist/page/ResultPage.js +35 -2
  93. package/dist/page/SettingPage.js +11 -2
  94. package/dist/page/TestPage.js +13 -3
  95. package/dist/quiz/QuizContests.d.ts +0 -0
  96. package/dist/quiz/QuizContests.js +58 -0
  97. package/dist/quiz/QuizWrap.d.ts +0 -0
  98. package/dist/quiz/QuizWrap.js +99 -0
  99. package/dist/quiz/Title.js +1 -2
  100. package/dist/quiz/answer/Answer.js +3 -0
  101. package/dist/quiz/answer/Input/CollapseExplain.d.ts +8 -0
  102. package/dist/quiz/answer/Input/CollapseExplain.js +70 -0
  103. package/dist/quiz/answer/Input/CollapseExplane.d.ts +8 -0
  104. package/dist/quiz/answer/Input/CollapseExplane.js +70 -0
  105. package/dist/quiz/answer/Input/InputAnswerBtn.d.ts +5 -0
  106. package/dist/quiz/answer/Input/InputAnswerBtn.js +54 -0
  107. package/dist/quiz/answer/Input/InputBox.d.ts +8 -0
  108. package/dist/quiz/answer/Input/InputBox.js +61 -0
  109. package/dist/quiz/answer/Input/InputCorrectBtn.d.ts +9 -0
  110. package/dist/quiz/answer/Input/InputCorrectBtn.js +42 -0
  111. package/dist/quiz/answer/Input/InputCounter.d.ts +7 -0
  112. package/dist/quiz/answer/Input/InputCounter.js +24 -0
  113. package/dist/quiz/answer/Input/InputFnc.d.ts +2 -0
  114. package/dist/quiz/answer/Input/InputFnc.js +28 -0
  115. package/dist/quiz/answer/Input/InputMsg.d.ts +5 -0
  116. package/dist/quiz/answer/Input/InputMsg.js +15 -0
  117. package/dist/quiz/answer/Input/InputNextBtn.d.ts +5 -0
  118. package/dist/quiz/answer/Input/InputNextBtn.js +37 -0
  119. package/dist/quiz/answer/Input/InputSaveSelector.d.ts +7 -0
  120. package/dist/quiz/answer/Input/InputSaveSelector.js +53 -0
  121. package/dist/quiz/answer/Input/InputTab.d.ts +7 -0
  122. package/dist/quiz/answer/Input/InputTab.js +41 -0
  123. package/dist/quiz/answer/Input/InputWarnning.d.ts +8 -0
  124. package/dist/quiz/answer/Input/InputWarnning.js +55 -0
  125. package/dist/quiz/answer/Input/InputWarnningMsg.d.ts +0 -0
  126. package/dist/quiz/answer/Input/InputWarnningMsg.js +1 -0
  127. package/dist/quiz/answer/InputBox.d.ts +7 -0
  128. package/dist/quiz/answer/InputBox.js +33 -0
  129. package/dist/quiz/answer/InputFnc.d.ts +2 -0
  130. package/dist/quiz/answer/InputFnc.js +28 -0
  131. package/dist/quiz/answer/InputNav.d.ts +7 -0
  132. package/dist/quiz/answer/InputNav.js +100 -0
  133. package/dist/quiz/answer/InputTab.d.ts +7 -0
  134. package/dist/quiz/answer/InputTab.js +41 -0
  135. package/dist/quiz/answer/styles/getChoiceStyle.d.ts +1 -1
  136. package/dist/quiz/answer/styles/getChoiceStyle.js +2 -0
  137. package/dist/quiz/check/NextQuizBtn.js +6 -10
  138. package/dist/quiz/common/MyTextqqyy.d.ts +1 -0
  139. package/dist/quiz/common/MyTextqqyy.js +9 -8
  140. package/dist/quiz/common/RenderImgOrText.d.ts +1 -0
  141. package/dist/quiz/common/RenderImgOrText.js +4 -2
  142. package/dist/quiz/explain/CorrectedBar.js +2 -3
  143. package/dist/quiz/explain/Explain.js +9 -0
  144. package/dist/quiz/explain/ExplainLogic.d.ts +1 -1
  145. package/dist/quiz/explain/ExplainLogic.js +2 -0
  146. package/dist/quiz/question/Question.js +2 -0
  147. package/dist/quiz/question/QuestionFormats.js +0 -2
  148. package/dist/quiz/question/QuestionReference.d.ts +3 -0
  149. package/dist/quiz/question/QuestionReference.js +28 -0
  150. package/dist/quiz/save/QuizSaveData.js +2 -2
  151. package/dist/quiz/setting/Bottom3Btn.js +1 -2
  152. package/dist/quiz/setting/ReturnSaveBtn.js +4 -3
  153. package/dist/tsconfig.tsbuildinfo +1 -1
  154. package/package.json +3 -2
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { StackNavigationProp } from "@react-navigation/stack";
3
+ import { Nav, Db } from "@nakamura-123/types";
4
+ interface Prop {
5
+ navigation: StackNavigationProp<Nav.RootStackParamList>;
6
+ subject: Db.SubjectInfo;
7
+ index: number;
8
+ }
9
+ declare const BasicPage: React.FC<Prop>;
10
+ export default BasicPage;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ var react_1 = __importStar(require("react"));
30
+ var react_native_1 = require("react-native");
31
+ var react_native_gesture_handler_1 = require("react-native-gesture-handler");
32
+ var react_redux_1 = require("react-redux");
33
+ var common_1 = require("@nakamura-123/common");
34
+ var stores_1 = require("@nakamura-123/stores");
35
+ var Badge5s_1 = __importDefault(require("../Badge5s"));
36
+ var TagBadge5s_1 = __importDefault(require("../TagBadge5s"));
37
+ var SubCategoryList_1 = __importDefault(require("../SubCategoryList"));
38
+ var MiniTestCard_1 = __importDefault(require("../MiniTestCard"));
39
+ var BasicSetting_1 = __importDefault(require("../BasicSetting"));
40
+ var BasicPage = function (_a) {
41
+ var navigation = _a.navigation, subject = _a.subject, index = _a.index;
42
+ var dispatch = (0, react_redux_1.useDispatch)();
43
+ // // Reduxから必要なデータを一括取得
44
+ var categoryList = (0, react_redux_1.useSelector)(function (state) { return state.app[subject.list]; });
45
+ var activeIndex = (0, react_redux_1.useSelector)(function (state) { return state.setting.viewSet[subject.name].activeIndex; });
46
+ // 選択されたカテゴリー情報を取得
47
+ var selectedList = categoryList[index];
48
+ // カテゴリー名を計算
49
+ var categoryName = "".concat(selectedList.label, " ").concat(selectedList.title).trim();
50
+ var selectKey = selectedList.key;
51
+ var categoryLabel = selectedList.label + selectedList.title;
52
+ var initScrollY = (0, react_redux_1.useSelector)(function (state) { return state.setting.viewSet[subject.name].scrollY; });
53
+ var scrollViewRef = (0, react_1.useRef)(null);
54
+ // 移動を監視
55
+ var _b = (0, react_1.useState)(false), isReady = _b[0], setIsReady = _b[1];
56
+ (0, react_1.useEffect)(function () {
57
+ if (scrollViewRef.current)
58
+ setIsReady(true); // 準備完了
59
+ }, [scrollViewRef.current]); // scrollViewRef.current の変更を監視
60
+ (0, react_1.useEffect)(function () {
61
+ var _a;
62
+ if (isReady)
63
+ (_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({ y: initScrollY, animated: false });
64
+ }, [isReady]);
65
+ var handleEndScroll = function (event) {
66
+ var scrollY = event.nativeEvent.contentOffset.y;
67
+ dispatch({ type: "setting/setScrollY", payload: scrollY });
68
+ };
69
+ // 全問スタートのハンドラー関数
70
+ var isLocked = common_1.commonHook.useIsLocked(subject.type, selectKey);
71
+ var allQuizIcon = isLocked ? "lock" : "pencil-alt";
72
+ var handleAllQuiz = function () {
73
+ if (isLocked) {
74
+ navigation.navigate("Coin");
75
+ return;
76
+ }
77
+ var ALL_NUM = 0;
78
+ dispatch(stores_1.quizAction.setLesson({
79
+ subject: subject.name,
80
+ type: subject.type,
81
+ category: selectKey,
82
+ lesson: {
83
+ title: selectedList.label + selectedList.title,
84
+ key: ALL_NUM,
85
+ },
86
+ }));
87
+ navigation.navigate("QuizSetup");
88
+ };
89
+ if (activeIndex !== index)
90
+ return null;
91
+ return (<react_native_gesture_handler_1.ScrollView style={styles.scrollContainer} contentContainerStyle={styles.container} showsVerticalScrollIndicator={false} ref={scrollViewRef} onMomentumScrollEnd={handleEndScroll}>
92
+ <common_1.RoundRectangle title={categoryName} style={styles.categoryName}/>
93
+ <common_1.HelpMark name="basicList" marginTop={20} top={-23}/>
94
+ <SubCategoryList_1.default navigation={navigation} subject={subject} index={index}/>
95
+
96
+ <MiniTestCard_1.default navigation={navigation} subject={subject} index={index}/>
97
+ <common_1.HelpMark name="badge" marginTop={10} top={-18}/>
98
+ <Badge5s_1.default badgeType="basic" subject={subject.name} category={selectKey}/>
99
+ <TagBadge5s_1.default subject={subject} index={index}/>
100
+ <common_1.HelpMark name="quizOption.allQuiz" top={0}/>
101
+ <common_1.RoundRectangleIcon title={categoryLabel + "全問を復習"} icon={allQuizIcon} onPress={handleAllQuiz}/>
102
+ <BasicSetting_1.default navigation={navigation} subjectType={subject.type}/>
103
+ </react_native_gesture_handler_1.ScrollView>);
104
+ };
105
+ var styles = react_native_1.StyleSheet.create({
106
+ scrollContainer: {
107
+ padding: 20,
108
+ },
109
+ container: {
110
+ paddingBottom: 100,
111
+ },
112
+ categoryName: {
113
+ marginTop: 10,
114
+ marginBottom: 10,
115
+ },
116
+ });
117
+ exports.default = BasicPage;
@@ -25,6 +25,7 @@ var styles = react_native_1.StyleSheet.create({
25
25
  flexDirection: "row",
26
26
  justifyContent: "space-around",
27
27
  alignItems: "center",
28
+ alignSelf: "center",
28
29
  paddingVertical: 16,
29
30
  },
30
31
  });
@@ -22,7 +22,7 @@ var styles = react_native_1.StyleSheet.create({
22
22
  },
23
23
  text: {
24
24
  fontSize: 20,
25
- fontWeight: "bold",
25
+ letterSpacing: 2,
26
26
  },
27
27
  msg: {
28
28
  marginTop: 5,
@@ -0,0 +1,12 @@
1
+ import { Storage } from "@nakamura-123/types";
2
+ export declare const coinCheckFnc: import("@reduxjs/toolkit").AsyncThunk<void, string, {
3
+ state?: unknown;
4
+ dispatch?: import("redux").Dispatch;
5
+ extra?: unknown;
6
+ rejectValue?: unknown;
7
+ serializedErrorType?: unknown;
8
+ pendingMeta?: unknown;
9
+ fulfilledMeta?: unknown;
10
+ rejectedMeta?: unknown;
11
+ }>;
12
+ export declare const isCheckRequired: (allFreeState: Storage.PeymentState, lastCheckedDate: string | null) => boolean;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isCheckRequired = exports.coinCheckFnc = void 0;
40
+ var lib_1 = require("@nakamura-123/lib");
41
+ var toolkit_1 = require("@reduxjs/toolkit");
42
+ var CoinFnc_1 = require("./CoinFnc");
43
+ var stores_1 = require("@nakamura-123/stores");
44
+ // 00.メイン関数
45
+ exports.coinCheckFnc = (0, toolkit_1.createAsyncThunk)("coin/check", function (allFreeId_1, _a) { return __awaiter(void 0, [allFreeId_1, _a], void 0, function (allFreeId, _b) {
46
+ var receipts, isExistedId, todayStr;
47
+ var dispatch = _b.dispatch;
48
+ return __generator(this, function (_c) {
49
+ switch (_c.label) {
50
+ case 0: return [4 /*yield*/, (0, CoinFnc_1.restorePurchases)(dispatch, false)];
51
+ case 1:
52
+ receipts = _c.sent();
53
+ isExistedId = hasPurchasedItems(receipts, allFreeId);
54
+ if (!isExistedId) {
55
+ // 返金などをされていて、flaseの場合、このIDのアイテムを削除し、store更新
56
+ stores_1.coinStorage.removePurchasedItem(allFreeId);
57
+ dispatch({ type: "setting/updateAllFreeState", payload: "none" });
58
+ }
59
+ todayStr = lib_1.timeFnc.getTodayString();
60
+ dispatch({ type: "setting/updateLastCheckedDate", payload: todayStr });
61
+ return [2 /*return*/];
62
+ }
63
+ });
64
+ }); });
65
+ // 91. 復元を行い、チェックが必要か判定
66
+ var isCheckRequired = function (allFreeState, lastCheckedDate) {
67
+ if (allFreeState === "none")
68
+ return false;
69
+ var inThisWeek = lib_1.timeFnc.isWithinWeek(lastCheckedDate);
70
+ if (inThisWeek && allFreeState === "paid")
71
+ return false;
72
+ return true;
73
+ };
74
+ exports.isCheckRequired = isCheckRequired;
75
+ // 92. 課金アイテムが有るかを確認
76
+ var hasPurchasedItems = function (receipts, id) {
77
+ if (!receipts)
78
+ return false;
79
+ return receipts.some(function (receipt) { return receipt.productId === id; });
80
+ };
@@ -0,0 +1,6 @@
1
+ import RNIap, { ProductPurchase } from "react-native-iap";
2
+ import { Storage } from "@nakamura-123/types";
3
+ export declare const initializeIAP: (paymentItems: string[] | undefined, setProducts: (products: RNIap.Product[]) => void, setLoading: (loading: boolean) => void) => Promise<void>;
4
+ export declare const handlePurchase: (productId: string, dispatch: (action: any) => void) => Promise<ProductPurchase | null>;
5
+ export declare const restorePurchases: (dispatch: (action: any) => void, isAlert?: boolean) => Promise<Storage.Receipt[] | null>;
6
+ export declare const updateAllFreeState: (receipt: Storage.Receipt | null) => (dispatch: any, getState: any) => void;
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.updateAllFreeState = exports.restorePurchases = exports.handlePurchase = exports.initializeIAP = void 0;
43
+ var netinfo_1 = __importDefault(require("@react-native-community/netinfo")); // ネットワーク状態確認用ライブラリ
44
+ var react_native_1 = require("react-native");
45
+ var react_native_iap_1 = require("react-native-iap");
46
+ var stores_1 = require("@nakamura-123/stores");
47
+ var ReceiptFnc_1 = require("./ReceiptFnc");
48
+ var pushCoinLog = stores_1.errorAction.pushCoinLog, pushCoinError = stores_1.errorAction.pushCoinError, pushCoinWarn = stores_1.errorAction.pushCoinWarn;
49
+ // 01. IAPの初期化
50
+ var initializeIAP = function (paymentItems, setProducts, setLoading) { return __awaiter(void 0, void 0, void 0, function () {
51
+ var result, itemSkus, productList, err_1;
52
+ return __generator(this, function (_a) {
53
+ switch (_a.label) {
54
+ case 0:
55
+ _a.trys.push([0, 5, 6, 7]);
56
+ return [4 /*yield*/, (0, react_native_iap_1.initConnection)()];
57
+ case 1:
58
+ result = _a.sent();
59
+ console.log("IAP Connection Initialized: ", result);
60
+ itemSkus = paymentItems || [];
61
+ console.log("Item SKUs: ", itemSkus);
62
+ if (!(itemSkus.length > 0)) return [3 /*break*/, 3];
63
+ return [4 /*yield*/, (0, react_native_iap_1.getProducts)({ skus: itemSkus })];
64
+ case 2:
65
+ productList = _a.sent();
66
+ console.log("Product List: ", productList);
67
+ setProducts(productList);
68
+ return [3 /*break*/, 4];
69
+ case 3:
70
+ console.warn("No SKUs provided.");
71
+ _a.label = 4;
72
+ case 4: return [3 /*break*/, 7];
73
+ case 5:
74
+ err_1 = _a.sent();
75
+ console.warn("IAP Initialization Error: ", err_1);
76
+ return [3 /*break*/, 7];
77
+ case 6:
78
+ setLoading(false);
79
+ return [7 /*endfinally*/];
80
+ case 7: return [2 /*return*/];
81
+ }
82
+ });
83
+ }); };
84
+ exports.initializeIAP = initializeIAP;
85
+ // 11. 購入処理
86
+ var handlePurchase = function (productId, dispatch) { return __awaiter(void 0, void 0, void 0, function () {
87
+ var params, purchase, receipt, isValid, err_2;
88
+ return __generator(this, function (_a) {
89
+ switch (_a.label) {
90
+ case 0: return [4 /*yield*/, isNetworkAvailable()];
91
+ case 1:
92
+ if (!(_a.sent())) {
93
+ alert("インターネットに接続されていません。");
94
+ throw new Error("インターネットに接続されていません。");
95
+ }
96
+ params = react_native_1.Platform.OS === "ios" ? { sku: productId } : { skus: [productId] };
97
+ _a.label = 2;
98
+ case 2:
99
+ _a.trys.push([2, 7, , 8]);
100
+ return [4 /*yield*/, (0, react_native_iap_1.requestPurchase)(params)];
101
+ case 3:
102
+ purchase = _a.sent();
103
+ dispatch(pushCoinLog({ title: "Purchase", log: purchase }));
104
+ if (Array.isArray(purchase))
105
+ purchase = purchase[0];
106
+ // 購入データの検証
107
+ if (!purchase) {
108
+ dispatch(pushCoinWarn({ title: "購入応答がありません", log: purchase }));
109
+ throw new Error("無効な購入応答");
110
+ }
111
+ receipt = purchase.transactionReceipt || purchase.purchaseToken;
112
+ if (!receipt) {
113
+ dispatch(pushCoinWarn({ title: "レシートが取得できません", log: purchase }));
114
+ throw new Error("レシートデータが無効です");
115
+ }
116
+ isValid = (0, ReceiptFnc_1.validatePurchaseClientSide)(receipt, react_native_1.Platform.OS);
117
+ if (!isValid) {
118
+ dispatch(pushCoinWarn({ title: "購入検証に失敗しました", log: purchase }));
119
+ throw new Error("購入検証に失敗しました");
120
+ }
121
+ if (!(react_native_1.Platform.OS === "android" && purchase.purchaseStateAndroid === 2)) return [3 /*break*/, 4];
122
+ alert("手続きが完了しました。。支払いが完了したら、このページにある「以前購入した方はこちらから復元」をタップしてください。");
123
+ return [3 /*break*/, 6];
124
+ case 4: return [4 /*yield*/, (0, react_native_iap_1.finishTransaction)({ purchase: purchase, isConsumable: false })];
125
+ case 5:
126
+ _a.sent();
127
+ alert("購入が完了しました!");
128
+ _a.label = 6;
129
+ case 6: return [2 /*return*/, purchase]; // 成功時に購入データを返す
130
+ case 7:
131
+ err_2 = _a.sent();
132
+ // エラー処理を整理
133
+ dispatch(pushCoinError({ title: "購入処理中にエラーが発生しました", log: err_2 }));
134
+ alert("購入に失敗しました。\nしばらく時間を置いた後、もう一度実行してみてください。もしそれでも購入できない場合は「よくある質問」をご確認いただくか、必要に応じて「お問い合わせフォーム」からご連絡ください。");
135
+ return [2 /*return*/, null]; // 失敗時はnullを返す
136
+ case 8: return [2 /*return*/];
137
+ }
138
+ });
139
+ }); };
140
+ exports.handlePurchase = handlePurchase;
141
+ // 21. 購入復元
142
+ var restorePurchases = function (dispatch, isAlert) { return __awaiter(void 0, void 0, void 0, function () {
143
+ var purchases, receipts, _i, purchases_1, purchase, receipt, error_1;
144
+ return __generator(this, function (_a) {
145
+ switch (_a.label) {
146
+ case 0:
147
+ _a.trys.push([0, 9, , 10]);
148
+ return [4 /*yield*/, isNetworkAvailable()];
149
+ case 1:
150
+ if (!(_a.sent())) {
151
+ isAlert && alert("インターネットに接続されていません。");
152
+ throw new Error("インターネットに接続されていません。");
153
+ }
154
+ return [4 /*yield*/, (0, react_native_iap_1.getAvailablePurchases)()];
155
+ case 2:
156
+ purchases = _a.sent();
157
+ dispatch(pushCoinLog({ title: "Purchases", log: purchases }));
158
+ receipts = [];
159
+ _i = 0, purchases_1 = purchases;
160
+ _a.label = 3;
161
+ case 3:
162
+ if (!(_i < purchases_1.length)) return [3 /*break*/, 6];
163
+ purchase = purchases_1[_i];
164
+ receipt = (0, ReceiptFnc_1.unifyReceipt)(purchase);
165
+ if (receipt) {
166
+ dispatch((0, exports.updateAllFreeState)(receipt));
167
+ receipts.push(receipt);
168
+ }
169
+ if (!checkNeedFinish(purchase)) return [3 /*break*/, 5];
170
+ return [4 /*yield*/, (0, react_native_iap_1.finishTransaction)({ purchase: purchase, isConsumable: false })];
171
+ case 4:
172
+ _a.sent();
173
+ _a.label = 5;
174
+ case 5:
175
+ _i++;
176
+ return [3 /*break*/, 3];
177
+ case 6:
178
+ if (receipts.length === 0)
179
+ dispatch((0, exports.updateAllFreeState)(null)); // 購入アイテムがない場合はAllFreeの状態を更新
180
+ dispatch(pushCoinLog({ title: "Receipts", log: receipts }));
181
+ if (!(receipts.length > 0)) return [3 /*break*/, 8];
182
+ return [4 /*yield*/, stores_1.coinStorage.replacePurchasedItems(receipts)];
183
+ case 7:
184
+ _a.sent();
185
+ _a.label = 8;
186
+ case 8:
187
+ isAlert &&
188
+ (receipts.length > 0
189
+ ? alert("購入アイテムを復元しました!")
190
+ : alert("購入済みのアイテムがありませんでした"));
191
+ return [2 /*return*/, receipts]; // 復元アイテムがあればpurchasesを返す
192
+ case 9:
193
+ error_1 = _a.sent();
194
+ dispatch(pushCoinError({ title: "購入復元に失敗しました", log: error_1 }));
195
+ isAlert &&
196
+ alert("購入アイテムの復元に失敗しました。しばらく時間を置いた後、もう一度実行してみてください。もしそれでも購入できない場合は「よくある質問」をご確認いただくか、必要に応じて「お問い合わせフォーム」からご連絡ください。");
197
+ return [2 /*return*/, null]; // エラーが発生した場合もnullを返す
198
+ case 10: return [2 /*return*/];
199
+ }
200
+ });
201
+ }); };
202
+ exports.restorePurchases = restorePurchases;
203
+ // 91. AllFreeの状態確認
204
+ var updateAllFreeState = function (receipt) { return function (dispatch, getState) {
205
+ var _a;
206
+ if (receipt === null) {
207
+ dispatch({ type: "setting/updateAllFreeState", payload: "none" });
208
+ dispatch({ type: "setting/updateLastCheckedDate", payload: null });
209
+ return;
210
+ }
211
+ var app = getState().app;
212
+ var freeId = (_a = app.appSetting.setting) === null || _a === void 0 ? void 0 : _a.payment.items.allFreeId;
213
+ if (!freeId)
214
+ return;
215
+ var isPaid = receipt.isPaid, productId = receipt.productId;
216
+ var paymentState = isPaid ? "paid" : "wait";
217
+ if (productId === freeId) {
218
+ dispatch({ type: "setting/updateAllFreeState", payload: paymentState });
219
+ }
220
+ }; };
221
+ exports.updateAllFreeState = updateAllFreeState;
222
+ // 92. androidの後払いアイテムの承認をするか否か
223
+ var checkNeedFinish = function (purchase) {
224
+ return purchase.purchaseStateAndroid === 1 && !purchase.isAcknowledgedAndroid;
225
+ };
226
+ // 93. ネットワーク状態の確認
227
+ var isNetworkAvailable = function () { return __awaiter(void 0, void 0, void 0, function () {
228
+ var state, isConnected, isInternetReachable;
229
+ var _a, _b;
230
+ return __generator(this, function (_c) {
231
+ switch (_c.label) {
232
+ case 0: return [4 /*yield*/, netinfo_1.default.fetch()];
233
+ case 1:
234
+ state = _c.sent();
235
+ isConnected = (_a = state.isConnected) !== null && _a !== void 0 ? _a : false;
236
+ isInternetReachable = (_b = state.isInternetReachable) !== null && _b !== void 0 ? _b : false;
237
+ return [2 /*return*/, isConnected && isInternetReachable];
238
+ }
239
+ });
240
+ }); };
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import RNIap from "react-native-iap";
3
+ import { Nav } from "@nakamura-123/types";
4
+ import { Comment } from "./AppReviews";
5
+ interface Props {
6
+ navigation: Nav.NavigationProp<"Coin">;
7
+ comments: Comment[];
8
+ products: RNIap.Product[];
9
+ onPurchase: (productId: string) => void;
10
+ onRestore: () => void;
11
+ loading: boolean;
12
+ isAllfreePaid: boolean;
13
+ }
14
+ declare const CoinPage: React.FC<Props>;
15
+ export default CoinPage;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var react_native_1 = require("react-native");
8
+ var lib_1 = require("@nakamura-123/lib");
9
+ var common_1 = require("@nakamura-123/common");
10
+ var CatchCopy_1 = __importDefault(require("./CatchCopy"));
11
+ var Recommend_1 = __importDefault(require("./Recommend"));
12
+ var AppReviews_1 = __importDefault(require("./AppReviews"));
13
+ var WaitingPayBanner_1 = __importDefault(require("./WaitingPayBanner"));
14
+ var waitingMsg = "処理中です。しばらくお待ちください...。\n10秒以上かかることもあります。";
15
+ var CoinPage = function (_a) {
16
+ var navigation = _a.navigation, comments = _a.comments, products = _a.products, onPurchase = _a.onPurchase, onRestore = _a.onRestore, loading = _a.loading, isAllfreePaid = _a.isAllfreePaid;
17
+ var isAndroid = react_native_1.Platform.OS === "android";
18
+ return (<>
19
+ <common_1.Spinner loading={loading}/>
20
+ <react_native_1.ScrollView style={styles.container}>
21
+ <CatchCopy_1.default />
22
+ <Recommend_1.default />
23
+ <common_1.RoundRectangleIcon title="よくある質問はこちら" icon="book" onPress={function () { return navigation.navigate("FAQ"); }}/>
24
+ <WaitingPayBanner_1.default currentPage="coin"/>
25
+
26
+ {products.map(function (product, index) {
27
+ var name = isAndroid ? product.name : product.title;
28
+ var price = product.localizedPrice;
29
+ var title = "".concat(name, " ").concat(price);
30
+ return (<common_1.RectangleCard key={index} title={title} note={product.description} left={<common_1.IconInCircle name="gift"/>} color={isAllfreePaid ? "ltBlack" : "blue"} onPress={function () {
31
+ return isAllfreePaid ? null : onPurchase(product.productId);
32
+ }}/>);
33
+ })}
34
+ <react_native_1.View style={styles.txtContainer}>
35
+ <common_1.MyText fsize="sm" color="gray">
36
+ ※ご購入の前に、必ず各モードの無料部分で使用感をご確認ください。
37
+ </common_1.MyText>
38
+ {react_native_1.Platform.OS === "android" && (<common_1.MyText fsize="sm" color="gray">
39
+ ※スムーズに決済するため、できる限りコンビニ支払い以外の方法を推奨します。
40
+ </common_1.MyText>)}
41
+ </react_native_1.View>
42
+ <common_1.RoundRectangleIcon title="以前購入した方はこちらから復元" icon="coins" onPress={function () { return onRestore(); }}/>
43
+ <react_native_1.View style={styles.serviceBox}>
44
+ <common_1.MyText fsize="md" color="blue" onPress={function () { return react_native_1.Linking.openURL("https://drill-notes.com/kiyaku"); }}>
45
+ ▲サービス利用規約はこちら▲
46
+ </common_1.MyText>
47
+ </react_native_1.View>
48
+
49
+ <AppReviews_1.default comments={comments}/>
50
+ <react_native_1.View style={{ height: 100 }}/>
51
+ </react_native_1.ScrollView>
52
+ </>);
53
+ };
54
+ var styles = react_native_1.StyleSheet.create({
55
+ container: {
56
+ flex: 1,
57
+ backgroundColor: lib_1.colors.beige,
58
+ padding: 20,
59
+ paddingTop: 40,
60
+ },
61
+ txtContainer: {
62
+ marginTop: 10,
63
+ marginHorizontal: 10,
64
+ justifyContent: "center",
65
+ alignItems: "center",
66
+ },
67
+ serviceBox: {
68
+ marginBottom: 20,
69
+ justifyContent: "center",
70
+ alignItems: "center",
71
+ },
72
+ });
73
+ exports.default = CoinPage;
@@ -0,0 +1,6 @@
1
+ import { ProductPurchase } from "react-native-iap";
2
+ import { Storage } from "@nakamura-123/types";
3
+ type Receipt = Storage.Receipt;
4
+ export declare const unifyReceipt: (receipt: ProductPurchase) => Receipt | null;
5
+ export declare const validatePurchaseClientSide: (receipt: string | undefined, platform: "ios" | "android") => boolean;
6
+ export {};
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatePurchaseClientSide = exports.unifyReceipt = void 0;
4
+ var react_native_1 = require("react-native");
5
+ // 01. レシートの形式を統一
6
+ var unifyReceipt = function (receipt) {
7
+ var os = react_native_1.Platform.OS;
8
+ return {
9
+ transactionId: receipt.transactionId || "",
10
+ productId: receipt.productId,
11
+ transactionDate: Number(receipt.transactionDate),
12
+ receipt: os === "ios" ? receipt.transactionReceipt : receipt.purchaseToken,
13
+ isPaid: os === "ios" || receipt.purchaseStateAndroid === 1, // iOSでは即時完了、AndroidはpurchaseStateが1が支払済み、2が未払い
14
+ };
15
+ };
16
+ exports.unifyReceipt = unifyReceipt;
17
+ // 02. レシートの検証
18
+ var validatePurchaseClientSide = function (receipt, platform) {
19
+ try {
20
+ // 1. レシートが存在するか確認
21
+ if (!receipt || receipt.length < 10) {
22
+ console.error("購入データが無効です: レシートが存在しません");
23
+ return false;
24
+ }
25
+ // 2. プラットフォーム特有のチェック
26
+ if (platform === "android") {
27
+ // Android特有のチェック(例: レシートがJSON形式でない場合など)
28
+ try {
29
+ var parsedReceipt = JSON.parse(receipt);
30
+ if (!parsedReceipt.purchaseToken ||
31
+ typeof parsedReceipt.purchaseToken !== "string") {
32
+ console.error("購入データが無効です: purchaseTokenがありません");
33
+ return false;
34
+ }
35
+ }
36
+ catch (_a) {
37
+ console.error("購入データが無効です: レシートの形式が不正です (JSONである必要があります)");
38
+ return false;
39
+ }
40
+ }
41
+ if (platform === "ios") {
42
+ // iOS特有のチェック
43
+ if (!/^[A-Za-z0-9+/=]+$/.test(receipt)) {
44
+ console.error("購入データが無効です: レシートがBase64形式ではありません");
45
+ return false;
46
+ }
47
+ }
48
+ console.log("クライアントサイドの簡易検証が成功しました");
49
+ return true;
50
+ }
51
+ catch (error) {
52
+ console.error("購入検証中にエラーが発生しました: ", error);
53
+ return false;
54
+ }
55
+ };
56
+ exports.validatePurchaseClientSide = validatePurchaseClientSide;
@@ -63,7 +63,7 @@ var styles = react_native_1.StyleSheet.create({
63
63
  },
64
64
  topRound: {
65
65
  position: "absolute",
66
- top: -10,
66
+ top: -15,
67
67
  },
68
68
  contentBox: {
69
69
  flexDirection: "row",