@nakamura-123/pages 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,8 +37,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.isCheckRequired = exports.coinCheckFnc = void 0;
40
- var lib_1 = require("@nakamura-123/lib");
41
40
  var toolkit_1 = require("@reduxjs/toolkit");
41
+ // import { initConnection } from "expo-iap";
42
+ var lib_1 = require("@nakamura-123/lib");
42
43
  var CoinFnc_1 = require("./CoinFnc");
43
44
  var stores_1 = require("@nakamura-123/stores");
44
45
  // 00.メイン関数
@@ -1,7 +1,7 @@
1
1
  import RNIap, { ProductPurchase, Purchase } from "expo-iap";
2
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>;
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) => Promise<ProductPurchase | null>;
5
5
  export declare const restorePurchases: (dispatch: (action: any) => void, isAlert?: boolean) => Promise<Storage.Receipt[] | null>;
6
6
  export declare const updateAllFreeState: (receipt: Storage.Receipt | null) => (dispatch: any, getState: any) => void;
7
- export declare const getAndroidPurchaseState: (purchase: Purchase) => "paid" | "canceled" | "waiting";
7
+ export declare const getAndroidPurchaseState: (purchase: Purchase) => "paid" | "canceled" | "wait";
@@ -52,7 +52,6 @@ var initializeIAP = function (paymentItems, setProducts, setLoading) { return __
52
52
  return [4 /*yield*/, (0, expo_iap_1.initConnection)()];
53
53
  case 1:
54
54
  result = _a.sent();
55
- console.log("IAP Connection Initialized: ", result);
56
55
  itemSkus = paymentItems || [];
57
56
  console.log("Item SKUs: ", itemSkus);
58
57
  if (!(itemSkus.length > 0)) return [3 /*break*/, 3];
@@ -60,7 +59,7 @@ var initializeIAP = function (paymentItems, setProducts, setLoading) { return __
60
59
  case 2:
61
60
  productList = _a.sent();
62
61
  console.log("Product List: ", productList);
63
- setProducts(productList);
62
+ setProducts && setProducts(productList);
64
63
  return [3 /*break*/, 4];
65
64
  case 3:
66
65
  console.warn("No SKUs provided.");
@@ -71,7 +70,7 @@ var initializeIAP = function (paymentItems, setProducts, setLoading) { return __
71
70
  console.warn("IAP Initialization Error: ", err_1);
72
71
  return [3 /*break*/, 7];
73
72
  case 6:
74
- setLoading(false);
73
+ setLoading && setLoading(false);
75
74
  return [7 /*endfinally*/];
76
75
  case 7: return [2 /*return*/];
77
76
  }
@@ -79,7 +78,7 @@ var initializeIAP = function (paymentItems, setProducts, setLoading) { return __
79
78
  }); };
80
79
  exports.initializeIAP = initializeIAP;
81
80
  // 11. 購入処理
82
- var handlePurchase = function (productId, dispatch) { return __awaiter(void 0, void 0, void 0, function () {
81
+ var handlePurchase = function (productId) { return __awaiter(void 0, void 0, void 0, function () {
83
82
  var purchase, receipt, isValid, err_2;
84
83
  return __generator(this, function (_a) {
85
84
  switch (_a.label) {
@@ -95,25 +94,18 @@ var handlePurchase = function (productId, dispatch) { return __awaiter(void 0, v
95
94
  purchase = purchase[0];
96
95
  // 購入データの検証
97
96
  if (!purchase) {
98
- // dispatch(pushCoinWarn({ title: "購入応答がありません", log: purchase }));
99
97
  throw new Error("無効な購入応答");
100
98
  }
101
99
  receipt = purchase.transactionReceipt || purchase.purchaseToken;
102
100
  if (!receipt) {
103
- // dispatch(
104
- // pushCoinWarn({ title: "レシートが取得できません", log: purchase })
105
- // );
106
101
  throw new Error("レシートデータが無効です");
107
102
  }
108
103
  isValid = (0, ReceiptFnc_1.validatePurchaseClientSide)(receipt, react_native_1.Platform.OS);
109
104
  if (!isValid) {
110
- // dispatch(
111
- // pushCoinWarn({ title: "購入検証に失敗しました", log: purchase })
112
- // );
113
105
  throw new Error("購入検証に失敗しました");
114
106
  }
115
107
  if (!(react_native_1.Platform.OS === "android" &&
116
- (0, exports.getAndroidPurchaseState)(purchase) === "waiting")) return [3 /*break*/, 2];
108
+ (0, exports.getAndroidPurchaseState)(purchase) === "wait")) return [3 /*break*/, 2];
117
109
  alert("手続きが完了しました。支払いが完了したら、このページにある「以前購入した方はこちらから復元」をタップしてください。");
118
110
  return [3 /*break*/, 4];
119
111
  case 2: return [4 /*yield*/, (0, expo_iap_1.finishTransaction)({ purchase: purchase, isConsumable: false })];
@@ -142,11 +134,10 @@ var restorePurchases = function (dispatch, isAlert) { return __awaiter(void 0, v
142
134
  switch (_a.label) {
143
135
  case 0:
144
136
  _a.trys.push([0, 8, , 9]);
145
- console.log("restorePurchases");
137
+ console.log("restorePurchases復元中:");
146
138
  return [4 /*yield*/, (0, expo_iap_1.getAvailablePurchases)()];
147
139
  case 1:
148
140
  purchases = _a.sent();
149
- // const purchases: Purchase[] = await getAvailablePurchases();
150
141
  console.log("purchases", purchases);
151
142
  receipts = [];
152
143
  _i = 0, purchases_1 = purchases;
@@ -218,21 +209,19 @@ var getAndroidPurchaseState = function (purchase) {
218
209
  return "paid";
219
210
  }
220
211
  switch (purchase.purchaseStateAndroid) {
221
- case 0:
222
- return "paid";
223
212
  case 1:
224
- return "canceled";
213
+ return "paid";
225
214
  case 2:
226
- return "waiting";
215
+ return "wait";
227
216
  default:
228
- return "paid";
217
+ return "canceled";
229
218
  }
230
219
  };
231
220
  exports.getAndroidPurchaseState = getAndroidPurchaseState;
232
221
  // 94. Androidの後払いアイテムの承認をするか否か
233
222
  var checkIsAcknowledgedAndroid = function (purchase) {
234
223
  if (purchase.platform === "ios")
235
- return true; // iOSでは常に承認済み
224
+ return false; // iOSでは常に未承認(finishは自動で行われる)
236
225
  return ((0, exports.getAndroidPurchaseState)(purchase) === "paid" &&
237
226
  !purchase.isAcknowledgedAndroid);
238
227
  };
@@ -3,14 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validatePurchaseClientSide = exports.unifyReceipt = void 0;
4
4
  // 01. レシートの形式を統一
5
5
  var unifyReceipt = function (receipt) {
6
- var os = receipt.platform === "ios" ? "ios" : "android";
7
6
  if (receipt.platform === "android")
8
7
  return {
9
8
  transactionId: receipt.transactionId || "",
10
9
  productId: receipt.productId,
11
10
  transactionDate: Number(receipt.transactionDate),
12
11
  receipt: receipt.purchaseToken || "",
13
- isPaid: receipt.purchaseStateAndroid === 0,
12
+ isPaid: receipt.purchaseStateAndroid === 1,
14
13
  };
15
14
  else
16
15
  return {
@@ -31,28 +30,34 @@ var validatePurchaseClientSide = function (receipt, platform) {
31
30
  return false;
32
31
  }
33
32
  // 2. プラットフォーム特有のチェック
34
- if (platform === "android") {
35
- // Android特有のチェック(例: レシートがJSON形式でない場合など)
36
- try {
37
- var parsedReceipt = JSON.parse(receipt);
38
- if (!parsedReceipt.purchaseToken ||
39
- typeof parsedReceipt.purchaseToken !== "string") {
40
- console.error("購入データが無効です: purchaseTokenがありません");
41
- return false;
42
- }
43
- }
44
- catch (_a) {
45
- console.error("購入データが無効です: レシートの形式が不正です (JSONである必要があります)");
46
- return false;
47
- }
48
- }
49
- if (platform === "ios") {
50
- // iOS特有のチェック
51
- if (!/^[A-Za-z0-9+/=]+$/.test(receipt)) {
52
- console.error("購入データが無効です: レシートがBase64形式ではありません");
53
- return false;
54
- }
55
- }
33
+ // if (platform === "android") {
34
+ // // Android特有のチェック(例: レシートがJSON形式でない場合など)
35
+ // try {
36
+ // const parsedReceipt = JSON.parse(receipt);
37
+ // if (
38
+ // !parsedReceipt.purchaseToken ||
39
+ // typeof parsedReceipt.purchaseToken !== "string"
40
+ // ) {
41
+ // console.error("購入データが無効です: purchaseTokenがありません");
42
+ // return false;
43
+ // }
44
+ // } catch {
45
+ // console.error(
46
+ // "購入データが無効です: レシートの形式が不正です (JSONである必要があります)"
47
+ // );
48
+ // return false;
49
+ // }
50
+ // }
51
+ // iOSは、もうこの形式ではなくJSON形式なので、これは当てはまらない。
52
+ // if (platform === "ios") {
53
+ // // iOS特有のチェック
54
+ // if (!/^[A-Za-z0-9+/=]+$/.test(receipt)) {
55
+ // console.error(
56
+ // "購入データが無効です: レシートがBase64形式ではありません"
57
+ // );
58
+ // return false;
59
+ // }
60
+ // }
56
61
  console.log("クライアントサイドの簡易検証が成功しました");
57
62
  return true;
58
63
  }
@@ -25,14 +25,11 @@ var useConfirmExit = function (navigation) {
25
25
  showExitConfirmation(function () { return navigation.goBack(); }, onSaveProgress, removeSave);
26
26
  return true; // デフォルトの戻る挙動を無効化
27
27
  };
28
- // ここがポイント:subscription を受け取る
29
- var subscription = react_native_1.BackHandler.addEventListener("hardwareBackPress", onBackPress);
30
- // cleanup で subscription.remove() を呼ぶ
28
+ react_native_1.BackHandler.addEventListener("hardwareBackPress", onBackPress);
31
29
  return function () {
32
- subscription.remove();
30
+ return react_native_1.BackHandler.removeEventListener("hardwareBackPress", onBackPress);
33
31
  };
34
- }, [navigation, onSaveProgress, removeSave]) // 依存を入れて stale 回避
35
- );
32
+ }, []));
36
33
  };
37
34
  exports.useConfirmExit = useConfirmExit;
38
35
  // 確認ダイアログを表示する関数
@@ -98,7 +98,7 @@ var CoinPage = function (_a) {
98
98
  _a.label = 1;
99
99
  case 1:
100
100
  _a.trys.push([1, 6, 7, 8]);
101
- return [4 /*yield*/, (0, CoinFnc_1.handlePurchase)(productId, dispatch)];
101
+ return [4 /*yield*/, (0, CoinFnc_1.handlePurchase)(productId)];
102
102
  case 2:
103
103
  purchase = _a.sent();
104
104
  if (!purchase) {
@@ -3,7 +3,6 @@ import { Home, Nav } from "@nakamura-123/types";
3
3
  interface Prop {
4
4
  menuLists: Home.MenuListItem[];
5
5
  navigation: Nav.NavigationProp<"Home">;
6
- t: (key: string) => string;
7
6
  }
8
7
  declare const HomePage: React.FC<Prop>;
9
8
  export default HomePage;
@@ -67,6 +67,7 @@ var react_native_1 = require("react-native");
67
67
  var realm_1 = __importDefault(require("realm"));
68
68
  var react_redux_1 = require("react-redux");
69
69
  var react_2 = require("@realm/react");
70
+ var react_i18next_1 = require("react-i18next");
70
71
  var i18next_1 = __importDefault(require("i18next"));
71
72
  var common_1 = require("@nakamura-123/common");
72
73
  var stores_1 = require("@nakamura-123/stores");
@@ -87,26 +88,22 @@ var MenuRectangle = function (_a) {
87
88
  };
88
89
  var LOAD_OLD_MSG = " 旧システムのデータ引き継ぎを実施いたします。ふせんデータや模擬試験の成績など、可能な限りデータを移行いたしますが、仕様上一部移行ができない項目があります。あらかじめご了承ください。\n\n なお、引き継ぎをキャンセルされた場合でも、設定ページより再度操作を行うことが可能です。";
89
90
  var HomePage = function (_a) {
90
- var menuLists = _a.menuLists, navigation = _a.navigation, t = _a.t;
91
+ var menuLists = _a.menuLists, navigation = _a.navigation;
91
92
  var dispatch = (0, react_redux_1.useDispatch)();
92
93
  var DailyLogDB = (0, react_2.useQuery)(db_1.DailyLogSchema);
93
94
  // ここは、データの引き継ぎを行うための処理です。
94
95
  var realm = (0, react_2.useRealm)();
95
- // const { t } = useTranslation();
96
+ var t = (0, react_i18next_1.useTranslation)().t;
96
97
  var showLoadOldData = (0, react_redux_1.useSelector)(function (state) { return state.setting.guide.loadOldData; });
97
98
  var settingAsyncLoaded = (0, react_redux_1.useSelector)(function (state) { return state.setting.asyncLoaded; });
98
99
  var oldInfo = (0, react_redux_1.useSelector)(function (state) { return state.app.appSetting.oldInfo; });
99
100
  var isJLPT = (0, react_redux_1.useSelector)(function (state) { return state.app.appSetting.setting.appSystem; }) === "JLPT";
100
- // let language = useSelector((state: RootState) => state.setting.language);
101
- // language = isJLPT ? language : "ja"; // JLPTの時は、jaにする。
101
+ var language = (0, react_redux_1.useSelector)(function (state) { return state.setting.language; });
102
+ language = isJLPT ? language : "ja"; // JLPTの時は、jaにする。
102
103
  (0, react_1.useEffect)(function () {
103
- console.log("18next");
104
- console.log(i18next_1.default);
105
- console.log("t");
106
- console.log(t("home.updateMsg"));
107
104
  if (!settingAsyncLoaded)
108
105
  return;
109
- // i18next.changeLanguage(language); // 言語を切り替える
106
+ i18next_1.default.changeLanguage(language); // 言語を切り替える
110
107
  if (!showLoadOldData)
111
108
  return;
112
109
  dispatch({ type: "setting/guideStateFalse", payload: "loadOldData" });
@@ -22,12 +22,49 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __generator = (this && this.__generator) || function (thisArg, body) {
35
+ 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);
36
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
+ function verb(n) { return function (v) { return step([n, v]); }; }
38
+ function step(op) {
39
+ if (f) throw new TypeError("Generator is already executing.");
40
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
41
+ 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;
42
+ if (y = 0, t) op = [op[0] & 2, t.value];
43
+ switch (op[0]) {
44
+ case 0: case 1: t = op; break;
45
+ case 4: _.label++; return { value: op[1], done: false };
46
+ case 5: _.label++; y = op[1]; op = [0]; continue;
47
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
+ default:
49
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
+ if (t[2]) _.ops.pop();
54
+ _.trys.pop(); continue;
55
+ }
56
+ op = body.call(thisArg, _);
57
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
+ }
60
+ };
25
61
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
62
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
63
  };
28
64
  Object.defineProperty(exports, "__esModule", { value: true });
29
65
  var react_1 = __importStar(require("react"));
30
66
  var react_native_1 = require("react-native");
67
+ var expo_iap_1 = require("expo-iap");
31
68
  var common_1 = require("@nakamura-123/common");
32
69
  var CharaCard_1 = __importDefault(require("../component/Result/CharaCard"));
33
70
  var LessonTitle_1 = __importDefault(require("../component/Result/LessonTitle"));
@@ -39,6 +76,7 @@ var CoinCheck_1 = require("../component/Coin/CoinCheck");
39
76
  var lib_1 = require("@nakamura-123/lib");
40
77
  var react_i18next_1 = require("react-i18next");
41
78
  var AdCard_1 = __importDefault(require("../component/Result/AdCard"));
79
+ var CoinFnc_1 = require("../component/Coin/CoinFnc");
42
80
  var ResultPage = function (_a) {
43
81
  var navigation = _a.navigation;
44
82
  var dispatch = (0, react_redux_1.useDispatch)();
@@ -47,15 +85,60 @@ var ResultPage = function (_a) {
47
85
  var _b = (0, react_redux_1.useSelector)(function (state) { return state.setting.payment; }), allFreeState = _b.allFreeState, lastCheckedDate = _b.lastCheckedDate;
48
86
  var isJLPT = (0, react_redux_1.useSelector)(function (state) { return state.app.appSetting.setting.appSystem; }) === "JLPT";
49
87
  var isCompletelyFree = (0, react_redux_1.useSelector)(function (state) { var _a; return (_a = state.app.appSetting.setting) === null || _a === void 0 ? void 0 : _a.payment.isCompletelyFree; }) || false;
88
+ var items = allFreeId ? [allFreeId] : [];
50
89
  (0, react_1.useEffect)(function () {
51
- var isCheckRequir = (0, CoinCheck_1.isCheckRequired)(allFreeState, lastCheckedDate, isCompletelyFree);
52
- if (isCheckRequir) {
53
- // 最終チェック日を更新・成功しようがしまいが、1日1回以上やらないようにする.
54
- var todayStr = lib_1.timeFnc.getTodayString();
55
- dispatch({ type: "setting/updateLastCheckedDate", payload: todayStr });
56
- // ここで復元処理を行う
57
- dispatch((0, CoinCheck_1.coinCheckFnc)(allFreeId));
58
- }
90
+ var cancelled = false;
91
+ (function () { return __awaiter(void 0, void 0, void 0, function () {
92
+ var need, todayStr, e_1, _a;
93
+ return __generator(this, function (_b) {
94
+ switch (_b.label) {
95
+ case 0:
96
+ need = (0, CoinCheck_1.isCheckRequired)(allFreeState, lastCheckedDate, isCompletelyFree);
97
+ if (!need)
98
+ return [2 /*return*/];
99
+ _b.label = 1;
100
+ case 1:
101
+ _b.trys.push([1, 5, 6, 10]);
102
+ todayStr = lib_1.timeFnc.getTodayString();
103
+ dispatch({ type: "setting/updateLastCheckedDate", payload: todayStr });
104
+ // 3) 接続
105
+ // --- expo-iap ---
106
+ return [4 /*yield*/, (0, CoinFnc_1.initializeIAP)(items)];
107
+ case 2:
108
+ // 3) 接続
109
+ // --- expo-iap ---
110
+ _b.sent();
111
+ return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, 5000); })];
112
+ case 3:
113
+ _b.sent(); // 少し待つ
114
+ // 4) チェック本体(復元や検証)
115
+ return [4 /*yield*/, dispatch((0, CoinCheck_1.coinCheckFnc)(allFreeId))];
116
+ case 4:
117
+ // 4) チェック本体(復元や検証)
118
+ _b.sent();
119
+ return [3 /*break*/, 10];
120
+ case 5:
121
+ e_1 = _b.sent();
122
+ console.warn("IAP check failed:", e_1);
123
+ return [3 /*break*/, 10];
124
+ case 6:
125
+ _b.trys.push([6, 8, , 9]);
126
+ return [4 /*yield*/, (0, expo_iap_1.endConnection)()];
127
+ case 7:
128
+ _b.sent();
129
+ return [3 /*break*/, 9];
130
+ case 8:
131
+ _a = _b.sent();
132
+ return [3 /*break*/, 9];
133
+ case 9: return [7 /*endfinally*/];
134
+ case 10: return [2 /*return*/];
135
+ }
136
+ });
137
+ }); })();
138
+ return function () {
139
+ cancelled = true;
140
+ };
141
+ // 依存は必要最小限。チェック条件が変わった時だけ再評価されるように。
59
142
  }, []);
60
143
  var scoreInfo = (0, quizHook_1.useScoreInfo)();
61
144
  return (<react_native_1.View style={styles.page}>
@@ -68,6 +151,13 @@ var ResultPage = function (_a) {
68
151
  <common_1.MiniIconBtn onPress={function () { return navigation.goBack(); }} icon="arrow-left" title={t("quiz.resultBtn.back")} color="blue" outerStyle={styles.miniBtnOuter}/>
69
152
  </react_native_1.View>
70
153
  <QuizFlatList_1.default navigation={navigation}/>
154
+ {/* <Button
155
+ title={"チェック"}
156
+ onPress={async () => {
157
+ const purchases = await getAvailablePurchases();
158
+ console.log("getAvailablePurchases", purchases);
159
+ }}
160
+ /> */}
71
161
  </react_native_1.View>);
72
162
  };
73
163
  var styles = react_native_1.StyleSheet.create({
@@ -16,6 +16,8 @@ var BlankBtn_1 = __importDefault(require("./BlankBtn"));
16
16
  var InputNav_1 = __importDefault(require("./InputNav"));
17
17
  var MultiGuide_1 = __importDefault(require("./MultiGuide"));
18
18
  var NormalMultiGuide_1 = __importDefault(require("./NormalMultiGuide"));
19
+ var BlangGuide_1 = __importDefault(require("./BlangGuide"));
20
+ var InputGuide_1 = __importDefault(require("./InputGuide"));
19
21
  var isDQInStoreNormal = types_1.qGard.isDQInStoreNormal;
20
22
  var Answer = function (_a) {
21
23
  var question = (0, quizHook_1.useQuestionDataD)();
@@ -36,11 +38,15 @@ var Answer = function (_a) {
36
38
  </>)}
37
39
  {/* 3.穴埋めモード */}
38
40
  {types_1.qGard.isDQInStoreBlank(question) && mode === "quiz" && (<>
41
+ <BlangGuide_1.default />
39
42
  <BlankAnswer_1.default question={question}/>
40
43
  <BlankBtn_1.default />
41
44
  </>)}
42
45
  {/* 4.記述モード */}
43
- {types_1.qGard.isDQInStoreInput(question) && <InputNav_1.default question={question}/>}
46
+ {types_1.qGard.isDQInStoreInput(question) && (<>
47
+ <InputGuide_1.default />
48
+ <InputNav_1.default question={question}/>
49
+ </>)}
44
50
  </react_native_1.View>);
45
51
  };
46
52
  var styles = react_native_1.StyleSheet.create({
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const BlankGuide: React.FC;
3
+ export default BlankGuide;
@@ -0,0 +1,29 @@
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 common_1 = require("@nakamura-123/common");
8
+ var lib_1 = require("@nakamura-123/lib");
9
+ var react_native_1 = require("react-native");
10
+ var quizHook_1 = require("../../hooks/quizHook");
11
+ var BlankGuide = function () {
12
+ var viewHeight = 20;
13
+ var mode = (0, quizHook_1.useGetMode)();
14
+ var shouldShow = mode === "quiz";
15
+ return (<common_1.CollopseView height={viewHeight} visible={shouldShow} style={styles.container}>
16
+ <common_1.MyText fsize="sm" color="red">
17
+ 答えを確認して正解・不正解をタップ
18
+ </common_1.MyText>
19
+ </common_1.CollopseView>);
20
+ };
21
+ var styles = react_native_1.StyleSheet.create({
22
+ container: {
23
+ justifyContent: "center",
24
+ alignItems: "center",
25
+ backgroundColor: lib_1.colors.bkBeige,
26
+ marginBottom: 5,
27
+ },
28
+ });
29
+ exports.default = BlankGuide;
@@ -41,7 +41,9 @@ var CollapseExplane = function (_a) {
41
41
  return (<react_native_1.View style={styles.container}>
42
42
  {/* タップ可能な横長のボタン */}
43
43
  <react_native_1.TouchableOpacity style={styles.button} onPress={toggleExpanded}>
44
- <common_1.MyText fsize="md">{isCollapsed ? "解説を見る ▼" : "閉じる ▲"}</common_1.MyText>
44
+ <common_1.MyText fsize="md" color="white">
45
+ {isCollapsed ? "解説を見る ▼" : "閉じる ▲"}
46
+ </common_1.MyText>
45
47
  </react_native_1.TouchableOpacity>
46
48
 
47
49
  {/* 折りたたみ可能なコンテンツ */}
@@ -57,7 +59,7 @@ var styles = react_native_1.StyleSheet.create({
57
59
  marginTop: 10,
58
60
  },
59
61
  button: {
60
- backgroundColor: lib_1.colors.ltBeige,
62
+ backgroundColor: lib_1.colors.red,
61
63
  paddingVertical: 5,
62
64
  width: "100%",
63
65
  alignItems: "center",
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const InputGuide: React.FC;
3
+ export default InputGuide;
@@ -0,0 +1,29 @@
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 common_1 = require("@nakamura-123/common");
8
+ var lib_1 = require("@nakamura-123/lib");
9
+ var react_native_1 = require("react-native");
10
+ var quizHook_1 = require("../../hooks/quizHook");
11
+ var InputGuide = function () {
12
+ var viewHeight = 20;
13
+ var mode = (0, quizHook_1.useGetMode)();
14
+ var shouldShow = mode === "quiz";
15
+ return (<common_1.CollopseView height={viewHeight} visible={shouldShow} style={styles.container}>
16
+ <common_1.MyText fsize="sm" color="red">
17
+ 「解説を見る▼」を開いて正解・不正解をタップ
18
+ </common_1.MyText>
19
+ </common_1.CollopseView>);
20
+ };
21
+ var styles = react_native_1.StyleSheet.create({
22
+ container: {
23
+ justifyContent: "center",
24
+ alignItems: "center",
25
+ backgroundColor: lib_1.colors.bkBeige,
26
+ marginBottom: 5,
27
+ },
28
+ });
29
+ exports.default = InputGuide;
@@ -22,7 +22,6 @@ var react_redux_2 = require("react-redux");
22
22
  var common_1 = require("@nakamura-123/common");
23
23
  var lib_1 = require("@nakamura-123/lib");
24
24
  var react_native_animatable_1 = require("react-native-animatable");
25
- var react_native_gesture_handler_1 = require("react-native-gesture-handler");
26
25
  var MyTextqqyy = function (_a) {
27
26
  var children = _a.children, style = _a.style, isNotSearch = _a.isNotSearch, fsize = _a.fsize, selectable = _a.selectable;
28
27
  var dispatch = (0, react_redux_2.useDispatch)();
@@ -91,16 +90,16 @@ var renderText = function (item, onSearch, fsize, fWeight, dispatch) {
91
90
  </common_1.MyText>),
92
91
  multiRed: <react_native_animatable_1.View key={item.key} style={styles.redBox}/>,
93
92
  multiBlue: <react_native_animatable_1.View key={item.key} style={styles.grayBox}/>,
94
- blankAns: (<react_native_gesture_handler_1.TouchableOpacity key={item.key} onPress={function () {
93
+ blankAns: (<common_1.PressAnimatedWrap key={item.key} onPress={function () {
95
94
  return dispatch({
96
95
  type: "quiz/setBlankNum",
97
96
  payload: Number(item.content),
98
97
  });
99
- }} style={styles.blankBox}>
98
+ }} style={styles.blankBox} scale={0.6}>
100
99
  <common_1.MyText color="white" fsize="sm">
101
100
  {item.content}
102
101
  </common_1.MyText>
103
- </react_native_gesture_handler_1.TouchableOpacity>),
102
+ </common_1.PressAnimatedWrap>),
104
103
  text: (<common_1.MyText key={item.key} fsize={fsize} weight={fWeight}>
105
104
  {item.content}
106
105
  </common_1.MyText>),
@@ -10,12 +10,20 @@ var MyTextqqyy_1 = __importDefault(require("./MyTextqqyy"));
10
10
  var common_1 = require("@nakamura-123/common");
11
11
  var ZoomableImage_1 = __importDefault(require("./ZoomableImage"));
12
12
  var RubyText_1 = __importDefault(require("./RubyText"));
13
+ var utils_1 = require("@nakamura-123/lib/dist/functions/utils");
13
14
  var RenderImgOrText = function (_a) {
14
15
  var word = _a.word, _b = _a.imgKey, imgKey = _b === void 0 ? null : _b, navigation = _a.navigation, isNotSearch = _a.isNotSearch, selectable = _a.selectable;
15
16
  var qImgs = (0, react_redux_1.useSelector)(function (state) { return state.app.imgs.qImgs; });
17
+ var rImgs = (0, react_redux_1.useSelector)(function (state) { return state.app.imgs.rImgs; });
16
18
  var regex = /\)ff\(/;
17
19
  if (typeof word === "string" && /^\//.test(word)) {
18
- var path = lib_1.utilFnc.getImgPathFromWord(qImgs, imgKey, word);
20
+ var isQuizImg = /^\/q[0-9]/.test(word);
21
+ var path = isQuizImg
22
+ ? lib_1.utilFnc.getImgPathFromWord(qImgs, imgKey, word)
23
+ : (0, utils_1.getrImgPath)(rImgs, word);
24
+ if (!path)
25
+ return <MyTextqqyy_1.default>{word}</MyTextqqyy_1.default>;
26
+ // 画像表示
19
27
  return navigation ? (<ZoomableImage_1.default path={path} navigation={navigation}/>) : (<common_1.MyImage path={path}/>);
20
28
  }
21
29
  else if (regex.test(word))