@ihabdevteam/core 0.110.0 → 0.112.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/CHANGELOG.md +57 -0
- package/dist/components.cjs.js +178 -184
- package/dist/hooks.cjs.js +1 -1
- package/dist/i18n.cjs.js +3 -9
- package/dist/ihabdevteam-core.cjs.js +181 -187
- package/dist/ihabdevteam-core.d.ts +29 -2
- package/dist/packages/core/src/components/Training/TrainingPagePopup.d.ts +12 -0
- package/dist/packages/core/src/components/Training/TrainingPagePopup.js +19 -3
- package/dist/packages/core/src/i18n/locales/en.json +53 -2804
- package/dist/packages/core/src/i18n/locales/ko.json +51 -2801
- package/dist/packages/core/src/utils/noiseSettingsStore.d.ts +14 -0
- package/dist/packages/core/src/utils/noiseSettingsStore.js +13 -0
- package/dist/packages/core/src/utils/wordSuggestionPolicy.d.ts +2 -1
- package/dist/packages/core/src/utils/wordSuggestionPolicy.js +2 -1
- package/dist/packages/core/src/utils.d.ts +1 -1
- package/dist/packages/core/src/utils.js +1 -1
- package/dist/packages/core/src/version.d.ts +1 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/utils.cjs.js +2 -2
- package/package.json +1 -1
|
@@ -1333,7 +1333,7 @@ export declare function copyText(text: string): Promise<boolean>;
|
|
|
1333
1333
|
*
|
|
1334
1334
|
* 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
|
|
1335
1335
|
*/
|
|
1336
|
-
export declare const CORE_VERSION = "0.
|
|
1336
|
+
export declare const CORE_VERSION = "0.112.0";
|
|
1337
1337
|
|
|
1338
1338
|
/** @public */
|
|
1339
1339
|
declare const coreDefault: Record<string, unknown>;
|
|
@@ -2983,6 +2983,15 @@ export declare interface NoiseSettingsStore {
|
|
|
2983
2983
|
load: () => Promise<Partial<CoreNoiseSettings> | null>;
|
|
2984
2984
|
/** 현재 훈련 대상의 소음설정을 저장(fire-and-forget). */
|
|
2985
2985
|
save: (settings: CoreNoiseSettings) => Promise<void> | void;
|
|
2986
|
+
/**
|
|
2987
|
+
* **판에 실제로 걸린 설정**이 정해지거나 바뀔 때마다 부른다 — 저장 병합 직후,
|
|
2988
|
+
* `noiseOverride` 적용 직후, 판 중 변경마다. 선택.
|
|
2989
|
+
*
|
|
2990
|
+
* `save` 와 따로 두는 까닭: `noiseOverride` 가 걸린 판은 저장을 건너뛴다. 앱이 결과마다
|
|
2991
|
+
* 그 판의 소음 조건을 함께 기록한다면 `save` 로는 그 값을 못 받는다 — 저장값으로
|
|
2992
|
+
* 기록해 조건이 틀리게 남는다. 이 콜백은 저장 여부와 무관하게 늘 걸린 값을 준다.
|
|
2993
|
+
*/
|
|
2994
|
+
applied?: (settings: CoreNoiseSettings) => void;
|
|
2986
2995
|
}
|
|
2987
2996
|
|
|
2988
2997
|
/**
|
|
@@ -4455,6 +4464,12 @@ export declare function removeItem<T>(draft: readonly DraftItem<T>[], key: strin
|
|
|
4455
4464
|
/** @public 배열에서 from 위치 요소를 to 위치로 옮긴 새 배열을 반환한다(원본 불변). 드래그 재정렬 등에 사용. */
|
|
4456
4465
|
export declare function reorderArray<T>(arr: readonly T[], from: number, to: number): T[];
|
|
4457
4466
|
|
|
4467
|
+
/**
|
|
4468
|
+
* @public 판에 걸린 소음설정을 앱에 알린다(`NoiseSettingsStore.applied`). 없으면 아무 일도 안 한다.
|
|
4469
|
+
* 알림이 실패해도 훈련은 이어진다 — `saveNoiseSettings` 와 같은 결로 삼킨다.
|
|
4470
|
+
*/
|
|
4471
|
+
export declare function reportAppliedNoiseSettings(settings: CoreNoiseSettings): void;
|
|
4472
|
+
|
|
4458
4473
|
/** @public */
|
|
4459
4474
|
export declare interface ReportBlock {
|
|
4460
4475
|
/** 블록을 가리키는 값. 같은 목록 안에서 겹치지 않아야 한다. */
|
|
@@ -6938,6 +6953,17 @@ export declare type TrainingPagePopupProps = {
|
|
|
6938
6953
|
dailyTotal?: number;
|
|
6939
6954
|
/** 완료 정본의 항목 식별자(item_ref) — 기기 간 완료표시 동기화 */
|
|
6940
6955
|
itemRef?: string;
|
|
6956
|
+
/**
|
|
6957
|
+
* **이 판에만** 거는 소음 설정 — 저장하지 않는다.
|
|
6958
|
+
*
|
|
6959
|
+
* 저장된 설정(`loadNoiseSettings`)을 불러와 병합한 **뒤에** 그 위에 덮는다. 함수로 주면
|
|
6960
|
+
* 병합된 저장값을 받아 계산한다(저장된 `mainVolume` 에 맞춰 소음을 정할 때).
|
|
6961
|
+
* 이 prop 이 있는 판에서는 판 중 툴팁으로 바꾼 것까지 **저장을 건너뛴다** — 고객의
|
|
6962
|
+
* 저장된 설정을 말없이 고치지 않도록. 마운트 때 한 번만 읽는다.
|
|
6963
|
+
*
|
|
6964
|
+
* 판에 실제로 걸린 값은 `NoiseSettingsStore.applied` 로 받는다.
|
|
6965
|
+
*/
|
|
6966
|
+
noiseOverride?: Partial<CoreNoiseSettings> | ((saved: CoreNoiseSettings) => Partial<CoreNoiseSettings>);
|
|
6941
6967
|
/** 훈련 결과 팝업 렌더러 — 없으면 결과 팝업을 표시하지 않음 */
|
|
6942
6968
|
renderResultPopup?: (props: {
|
|
6943
6969
|
score?: number | null;
|
|
@@ -8184,7 +8210,8 @@ export declare const WORD_SUGGESTION_ACCOUNT_LIMIT = 5;
|
|
|
8184
8210
|
* 거절하는데, 화면이 이 표를 갖고 있어야 누르기 전에 같은 문구로 미리 알릴 수 있다
|
|
8185
8211
|
* — 없으면 "누르면 그 제안에 투표됩니다"라고 안내해 놓고 거절 문구를 받게 된다.
|
|
8186
8212
|
*
|
|
8187
|
-
* 값은 wordSuggestion.error.* i18n 키이기도 하다(서버 코드와 문구 키가 같다).
|
|
8213
|
+
* 값은 wordSuggestion.error.* i18n 키이기도 하다(서버 코드와 문구 키가 같다). 그 문구는
|
|
8214
|
+
* 코어 사전이 아니라 **소비자 앱 사전**(말귀 src/i18n)에 있다 — 0.111.0 에서 옮겼다.
|
|
8188
8215
|
*/
|
|
8189
8216
|
export declare const WORD_SUGGESTION_EXISTING_ERROR: {
|
|
8190
8217
|
readonly selected: "ALREADY_SELECTED";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode, type FC, type CSSProperties, type RefObject, type Dispatch, type SetStateAction } from "react";
|
|
2
2
|
import './TrainingPagePopup.css';
|
|
3
|
+
import { type CoreNoiseSettings } from './NoisePlayerContext';
|
|
3
4
|
import { Page, ListenStep, ConfirmStep, ConfirmWithTextStep, OrderListStep, CardStep, CardOrderStep } from './TrainingStepComponents';
|
|
4
5
|
/** @public */
|
|
5
6
|
export type { ScenarioPage, ScenarioStep, FlowState } from './trainingScenario';
|
|
@@ -66,6 +67,17 @@ export type TrainingPagePopupProps = {
|
|
|
66
67
|
dailyTotal?: number;
|
|
67
68
|
/** 완료 정본의 항목 식별자(item_ref) — 기기 간 완료표시 동기화 */
|
|
68
69
|
itemRef?: string;
|
|
70
|
+
/**
|
|
71
|
+
* **이 판에만** 거는 소음 설정 — 저장하지 않는다.
|
|
72
|
+
*
|
|
73
|
+
* 저장된 설정(`loadNoiseSettings`)을 불러와 병합한 **뒤에** 그 위에 덮는다. 함수로 주면
|
|
74
|
+
* 병합된 저장값을 받아 계산한다(저장된 `mainVolume` 에 맞춰 소음을 정할 때).
|
|
75
|
+
* 이 prop 이 있는 판에서는 판 중 툴팁으로 바꾼 것까지 **저장을 건너뛴다** — 고객의
|
|
76
|
+
* 저장된 설정을 말없이 고치지 않도록. 마운트 때 한 번만 읽는다.
|
|
77
|
+
*
|
|
78
|
+
* 판에 실제로 걸린 값은 `NoiseSettingsStore.applied` 로 받는다.
|
|
79
|
+
*/
|
|
80
|
+
noiseOverride?: Partial<CoreNoiseSettings> | ((saved: CoreNoiseSettings) => Partial<CoreNoiseSettings>);
|
|
69
81
|
/** 훈련 결과 팝업 렌더러 — 없으면 결과 팝업을 표시하지 않음 */
|
|
70
82
|
renderResultPopup?: (props: {
|
|
71
83
|
score?: number | null;
|
|
@@ -23,14 +23,14 @@ import TrainingResultPopup from '../Popup/TrainingResultPopup';
|
|
|
23
23
|
import useTrainingSessionLog from '../../hooks/useTrainingSessionLog';
|
|
24
24
|
import { logTrainingCompletion } from '../../utils/trainingLogger';
|
|
25
25
|
import { toItemResults } from '../../utils/trainingItemResults';
|
|
26
|
-
import { loadNoiseSettings, saveNoiseSettings } from '../../utils/noiseSettingsStore';
|
|
26
|
+
import { loadNoiseSettings, saveNoiseSettings, reportAppliedNoiseSettings } from '../../utils/noiseSettingsStore';
|
|
27
27
|
// 문장 4종은 각 PagePopup 래퍼에서 useTrainingSessionLog로 이미 기록 → 베이스에서 중복 방지
|
|
28
28
|
const SENTENCE_TIME_LOGGED_TYPES = new Set(['LISTEN_IN_NOISE', 'SHORT_STORY', 'LONG_STORY', 'ORDERING_SENTENCE']);
|
|
29
29
|
// renderResultPopup 미지정 시 기본 결과 팝업 — 모든 훈련 타입 공통 폴백
|
|
30
30
|
const defaultRenderResult = (p) => _jsx(TrainingResultPopup, { score: p.score, contextsLength: p.contextsLength, results: p.results, onReplay: p.onReplay, onClose: p.onClose });
|
|
31
31
|
import { getScenarioPageId, getScenarioStepKey, createScenarioFlowState, resolveScenarioStepProps, } from './trainingScenario';
|
|
32
32
|
function TrainingPagePopupInner(props) {
|
|
33
|
-
const { scenario, title, subTitle, depth, icon, wrapperStyle, iconTooltip, pageIndex, pageCount, stepIndex, stepCount, onBack, onComplete, onNext, onSettings, useNoiseSetting = true, children, ariaLabel, label, buildResults, onResult: externalOnResultProp, typeKey, entryPoint, dailyTotal, itemRef, renderResultPopup, } = props;
|
|
33
|
+
const { scenario, title, subTitle, depth, icon, wrapperStyle, iconTooltip, pageIndex, pageCount, stepIndex, stepCount, onBack, onComplete, onNext, onSettings, useNoiseSetting = true, children, ariaLabel, label, buildResults, onResult: externalOnResultProp, typeKey, entryPoint, dailyTotal, itemRef, renderResultPopup, noiseOverride, } = props;
|
|
34
34
|
// 시간 기록 — 문장 4종은 각 래퍼(useTrainingSessionLog)에서 기록하므로 제외, 그 외(단어 등) 공통 기록
|
|
35
35
|
useTrainingSessionLog(typeKey && !SENTENCE_TIME_LOGGED_TYPES.has(typeKey) ? typeKey : '');
|
|
36
36
|
// 팝업 진입 시각 — 완료 정본의 소요 시간 계산 (마운트 시 1회만 effect에서 초기화)
|
|
@@ -119,6 +119,9 @@ function TrainingPagePopupInner(props) {
|
|
|
119
119
|
// 최신 설정 미러(setSettings에서 머지·저장 시 참조 — 상태 업데이터 내 부수효과 회피)
|
|
120
120
|
const noiseSettingsRef = useRef(noiseSettings);
|
|
121
121
|
useEffect(() => { noiseSettingsRef.current = noiseSettings; }, [noiseSettings]);
|
|
122
|
+
// 이 판에만 거는 설정 — 마운트 때 한 번 붙잡는다(부모가 매 렌더 새 함수를 넘겨도 다시 걸지 않게).
|
|
123
|
+
// 있으면 이 판은 저장을 건너뛴다(mergeAndSaveSettings 참고).
|
|
124
|
+
const noiseOverrideRef = useRef(noiseOverride);
|
|
122
125
|
// 계정/고객 저장소에서 초기값 로드 (앱이 configureNoiseSettingsStore로 주입)
|
|
123
126
|
useEffect(() => {
|
|
124
127
|
let cancelled = false;
|
|
@@ -129,6 +132,16 @@ function TrainingPagePopupInner(props) {
|
|
|
129
132
|
const merged = saved ? { ...noiseSettingsRef.current, ...saved } : { ...DEFAULT_NOISE_SETTINGS };
|
|
130
133
|
noiseSettingsRef.current = merged;
|
|
131
134
|
setNoisePart(merged);
|
|
135
|
+
reportAppliedNoiseSettings(merged);
|
|
136
|
+
// override 는 병합이 끝난 **뒤에** 덮는다 — 로드가 늦게 와도 override 가 이긴다.
|
|
137
|
+
const override = noiseOverrideRef.current;
|
|
138
|
+
if (override) {
|
|
139
|
+
const patch = typeof override === 'function' ? override(merged) : override;
|
|
140
|
+
const applied = { ...merged, ...patch };
|
|
141
|
+
noiseSettingsRef.current = applied;
|
|
142
|
+
setNoisePart(applied);
|
|
143
|
+
reportAppliedNoiseSettings(applied);
|
|
144
|
+
}
|
|
132
145
|
});
|
|
133
146
|
return () => { cancelled = true; };
|
|
134
147
|
}, []);
|
|
@@ -146,7 +159,10 @@ function TrainingPagePopupInner(props) {
|
|
|
146
159
|
const merged = { ...noiseSettingsRef.current, ...next };
|
|
147
160
|
noiseSettingsRef.current = merged;
|
|
148
161
|
setNoisePart(merged);
|
|
149
|
-
|
|
162
|
+
// noiseOverride 판은 저장하지 않는다 — 판 중에 바꾼 것도 이 판에만.
|
|
163
|
+
if (!noiseOverrideRef.current)
|
|
164
|
+
saveNoiseSettings(merged);
|
|
165
|
+
reportAppliedNoiseSettings(merged);
|
|
150
166
|
}, []);
|
|
151
167
|
// 문장(메인) 재생 컨트롤 — 툴팁(하단 설정)과 오디오 플레이어가 공유. 계정 설정("훈련" 패널)의
|
|
152
168
|
// 기본값과 동일한 noiseSettings(mainVolume/mainSpeed)에 함께 영속화된다.
|