mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
name selection
This commit is contained in:
parent
ef3b4ce367
commit
68a43c39de
12 changed files with 392 additions and 81 deletions
|
@ -150,7 +150,7 @@ const BootAnimation = (props: BootAnimationProps) => {
|
|||
|
||||
setBackgroundFloatingTextShown(true);
|
||||
//4200
|
||||
}, 4200);
|
||||
}, 0);
|
||||
}
|
||||
}, [bootBackgroundTextTex, currentBootStatusTextTex.offset, props.visible]);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Suspense, useEffect, useMemo, useRef } from "react";
|
||||
import React, { useEffect, useMemo, useRef } from "react";
|
||||
import authorizeHeaderUnderline from "../../static/sprite/authorize_header_underline.png";
|
||||
import authorizeGlass from "../../static/sprite/authorize_glass.png";
|
||||
import authorizeGlassUnderline from "../../static/sprite/authorize_glass_underline.png";
|
||||
|
@ -11,6 +11,7 @@ import * as THREE from "three";
|
|||
import { OrbitControls } from "@react-three/drei";
|
||||
import { useStore } from "../../store";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
import StaticJpCharacter from "../TextRenderer/StaticJpCharacter";
|
||||
|
||||
type BootAuthorizeUserProps = {
|
||||
visible: boolean;
|
||||
|
@ -94,6 +95,8 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
|
|||
}
|
||||
}, [activeLetterMap.offset, letterIdx, prevData]);
|
||||
|
||||
const playerName = useStore((state) => state.playerName.split(""));
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.visible && (
|
||||
|
@ -146,6 +149,11 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
|
|||
/>
|
||||
</sprite>
|
||||
|
||||
<group position={[playerName.length * -0.25 - 0.2, -0.27, 0]}>
|
||||
{playerName.map((char, idx) => (
|
||||
<StaticJpCharacter char={char} charIdx={idx} key={idx} />
|
||||
))}
|
||||
</group>
|
||||
<sprite
|
||||
scale={[2, 0.01, 0]}
|
||||
position={[-1.06, -0.42, 0]}
|
||||
|
|
|
@ -21,10 +21,8 @@ const PermissionDenied = memo(() => {
|
|||
<group scale={[0.08, 0.7, 0]} position={[-1, 0.19, 0]}>
|
||||
{"Permission denied".split("").map((letter, idx) => (
|
||||
<StaticOrangeLetter
|
||||
color={"orange"}
|
||||
letter={letter}
|
||||
letterIdx={idx}
|
||||
scale={[1.5, 0.25, 0.25]}
|
||||
key={idx}
|
||||
/>
|
||||
))}
|
||||
|
|
53
src/components/TextRenderer/StaticJpCharacter.tsx
Normal file
53
src/components/TextRenderer/StaticJpCharacter.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import orangeFont from "../../static/sprite/orange_jp_font.png";
|
||||
import * as THREE from "three";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import jp_font_json from "../../resources/font_data/jp_font.json";
|
||||
import React, { memo, useMemo } from "react";
|
||||
|
||||
const StaticJpCharacter = memo((props: { char: string; charIdx: number }) => {
|
||||
const colorTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
orangeFont
|
||||
);
|
||||
const charData = useMemo(
|
||||
() => jp_font_json.glyphs[props.char as keyof typeof jp_font_json.glyphs],
|
||||
[props.char]
|
||||
);
|
||||
|
||||
const geom = useMemo(() => {
|
||||
const geometry = new THREE.PlaneBufferGeometry();
|
||||
|
||||
const uvAttribute = geometry.attributes.uv;
|
||||
|
||||
for (let i = 0; i < uvAttribute.count; i++) {
|
||||
let u = uvAttribute.getX(i);
|
||||
let v = uvAttribute.getY(i);
|
||||
|
||||
u = (u * charData[2]) / 240 + charData[0] / 240;
|
||||
|
||||
v = (v * charData[3]) / 96 + (1 - charData[1] / 96 - 16 / 96);
|
||||
|
||||
uvAttribute.setXY(i, u, v);
|
||||
}
|
||||
return geometry;
|
||||
}, [charData]);
|
||||
|
||||
return (
|
||||
<mesh
|
||||
position={[props.charIdx / 4, 0, 0]}
|
||||
scale={[0.25, 0.25, 0]}
|
||||
geometry={geom}
|
||||
renderOrder={205}
|
||||
>
|
||||
<meshBasicMaterial
|
||||
map={colorTexture}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
side={THREE.FrontSide}
|
||||
depthTest={false}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
});
|
||||
|
||||
export default StaticJpCharacter;
|
|
@ -5,12 +5,7 @@ import orange_font_json from "../../resources/font_data/big_font.json";
|
|||
import React, { memo, useMemo } from "react";
|
||||
|
||||
const StaticOrangeLetter = memo(
|
||||
(props: {
|
||||
color: string;
|
||||
letter: string;
|
||||
letterIdx: number;
|
||||
scale: number[];
|
||||
}) => {
|
||||
(props: { letter: string; letterIdx: number }) => {
|
||||
const colorTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
orangeFont
|
||||
|
@ -75,7 +70,7 @@ const StaticOrangeLetter = memo(
|
|||
return (
|
||||
<mesh
|
||||
position={[props.letterIdx * 1.6, -letterData[4] / 50, 0]}
|
||||
scale={props.scale as [number, number, number]}
|
||||
scale={[1.5, 0.25, 0.25]}
|
||||
geometry={geom}
|
||||
renderOrder={205}
|
||||
>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import authorize_user_letters from "../../resources/authorize_user_letters.json";
|
||||
import handleNameSelection from "../../utils/handleNameSelection";
|
||||
|
||||
const handleBootSceneKeyPress = (bootSceneContext: any) => {
|
||||
const {
|
||||
keyPress,
|
||||
|
@ -6,6 +9,7 @@ const handleBootSceneKeyPress = (bootSceneContext: any) => {
|
|||
activePromptComponent,
|
||||
promptVisible,
|
||||
authorizeUserLetterIdx,
|
||||
playerName,
|
||||
} = bootSceneContext;
|
||||
|
||||
if (promptVisible) {
|
||||
|
@ -38,7 +42,14 @@ const handleBootSceneKeyPress = (bootSceneContext: any) => {
|
|||
case "authorize_user":
|
||||
switch (keyPress) {
|
||||
case "X":
|
||||
return { event: "authorize_user_back" };
|
||||
if (playerName.length > 0) {
|
||||
return {
|
||||
event: "update_player_name",
|
||||
playerName: playerName.slice(0, -1),
|
||||
};
|
||||
} else {
|
||||
return { event: "authorize_user_back" };
|
||||
}
|
||||
case "LEFT":
|
||||
// if utmost left, break
|
||||
if ([0, 13, 26, 39, 52].includes(authorizeUserLetterIdx)) break;
|
||||
|
@ -85,7 +96,19 @@ const handleBootSceneKeyPress = (bootSceneContext: any) => {
|
|||
authorizeUserLetterIdx: authorizeUserLetterIdx - 13,
|
||||
};
|
||||
}
|
||||
case "CIRCLE":
|
||||
const chosenCharacter =
|
||||
authorize_user_letters[
|
||||
authorizeUserLetterIdx.toString() as keyof typeof authorize_user_letters
|
||||
];
|
||||
|
||||
const newName = handleNameSelection(playerName, chosenCharacter);
|
||||
|
||||
if (newName !== undefined)
|
||||
return { event: "update_player_name", playerName: newName };
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -7,9 +7,12 @@ const bootManager = (eventState: any) => {
|
|||
const setAuthorizeUserLetterIdx = useStore.getState()
|
||||
.setAuthorizeUserLetterIdx;
|
||||
|
||||
const setPlayerName = useStore.getState().setPlayerName;
|
||||
|
||||
const dispatchAction = (eventState: {
|
||||
event: string;
|
||||
authorizeUserLetterIdx: number;
|
||||
playerName: string;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "main_menu_up":
|
||||
|
@ -30,6 +33,14 @@ const bootManager = (eventState: any) => {
|
|||
action: () =>
|
||||
setAuthorizeUserLetterIdx(eventState.authorizeUserLetterIdx),
|
||||
};
|
||||
case "authorize_user_back":
|
||||
return {
|
||||
action: () => setPlayerName(""),
|
||||
};
|
||||
case "update_player_name":
|
||||
return {
|
||||
action: () => setPlayerName(eventState.playerName),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,69 +1,67 @@
|
|||
{
|
||||
"letters": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
58,
|
||||
59,
|
||||
60,
|
||||
61,
|
||||
62,
|
||||
63,
|
||||
64
|
||||
]
|
||||
"0": "ッ",
|
||||
"1": "ャ",
|
||||
"2": "ァ",
|
||||
"3": "ワ",
|
||||
"4": "ラ",
|
||||
"5": "ヤ",
|
||||
"6": "マ",
|
||||
"7": "ハ",
|
||||
"8": "ナ",
|
||||
"9": "タ",
|
||||
"10": "サ",
|
||||
"11": "カ",
|
||||
"12": "ア",
|
||||
"13": "",
|
||||
"14": "",
|
||||
"15": "ィ",
|
||||
"16": "",
|
||||
"17": "リ",
|
||||
"18": "",
|
||||
"19": "ミ",
|
||||
"20": "ヒ",
|
||||
"21": "ニ",
|
||||
"22": "チ",
|
||||
"23": "シ",
|
||||
"24": "キ",
|
||||
"25": "イ",
|
||||
"26": "゛",
|
||||
"27": "ュ",
|
||||
"28": "ゥ",
|
||||
"29": "",
|
||||
"30": "ル",
|
||||
"31": "ユ",
|
||||
"32": "ム",
|
||||
"33": "フ",
|
||||
"34": "ヌ",
|
||||
"35": "ツ",
|
||||
"36": "ス",
|
||||
"37": "ク",
|
||||
"38": "ウ",
|
||||
"39": "゜",
|
||||
"40": "",
|
||||
"41": "ェ",
|
||||
"42": "",
|
||||
"43": "レ",
|
||||
"44": "",
|
||||
"45": "メ",
|
||||
"46": "ヘ",
|
||||
"47": "ネ",
|
||||
"48": "テ",
|
||||
"49": "セ",
|
||||
"50": "ケ",
|
||||
"51": "エ",
|
||||
"52": "ー",
|
||||
"53": "ョ",
|
||||
"54": "ォ",
|
||||
"55": "ン",
|
||||
"56": "ロ",
|
||||
"57": "ヨ",
|
||||
"58": "モ",
|
||||
"59": "ホ",
|
||||
"60": "ノ",
|
||||
"61": "ト",
|
||||
"62": "ソ",
|
||||
"63": "コ",
|
||||
"64": "オ"
|
||||
}
|
||||
|
|
92
src/resources/font_data/jp_font.json
Normal file
92
src/resources/font_data/jp_font.json
Normal file
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"kerning": 2,
|
||||
"height": 21,
|
||||
"baseline": 4,
|
||||
"glyphs": {
|
||||
"ア": [0, 0, 16, 16, 0],
|
||||
"イ": [16, 0, 16, 16, 0],
|
||||
"ウ": [32, 0, 16, 16, 0],
|
||||
"エ": [48, 0, 16, 16, 0],
|
||||
"オ": [64, 0, 16, 16, 0],
|
||||
"カ": [80, 0, 16, 16, 0],
|
||||
"キ": [96, 0, 16, 16, 0],
|
||||
"ク": [112, 0, 16, 16, 0],
|
||||
"ケ": [128, 0, 16, 16, 0],
|
||||
"コ": [144, 0, 16, 16, 0],
|
||||
"サ": [160, 0, 16, 16, 0],
|
||||
"シ": [176, 0, 16, 16, 0],
|
||||
"ス": [192, 0, 16, 16, 0],
|
||||
"セ": [208, 0, 16, 16, 0],
|
||||
"ソ": [224, 0, 16, 16, 0],
|
||||
|
||||
"タ": [0, 16, 16, 16, 0],
|
||||
"チ": [16, 16, 16, 16, 0],
|
||||
"ツ": [32, 16, 16, 16, 0],
|
||||
"テ": [48, 16, 16, 16, 0],
|
||||
"ト": [64, 16, 16, 16, 0],
|
||||
"ナ": [80, 16, 16, 16, 0],
|
||||
"ニ": [96, 16, 16, 16, 0],
|
||||
"ヌ": [112, 16, 16, 16, 0],
|
||||
"ネ": [128, 16, 16, 16, 0],
|
||||
"ノ": [144, 16, 16, 16, 0],
|
||||
"ハ": [160, 16, 16, 16, 0],
|
||||
"ヒ": [176, 16, 16, 16, 0],
|
||||
"フ": [192, 16, 16, 16, 0],
|
||||
"ヘ": [208, 16, 16, 16, 0],
|
||||
"ホ": [224, 16, 16, 16, 0],
|
||||
|
||||
"マ": [0, 32, 16, 16, 0],
|
||||
"ミ": [16, 32, 16, 16, 0],
|
||||
"ム": [32, 32, 16, 16, 0],
|
||||
"メ": [48, 32, 16, 16, 0],
|
||||
"モ": [64, 32, 16, 16, 0],
|
||||
"ヤ": [80, 32, 16, 16, 0],
|
||||
"ユ": [96, 32, 16, 16, 0],
|
||||
"ヨ": [112, 32, 16, 16, 0],
|
||||
"ラ": [128, 32, 16, 16, 0],
|
||||
"リ": [144, 32, 16, 16, 0],
|
||||
"ル": [160, 32, 16, 16, 0],
|
||||
"レ": [176, 32, 16, 16, 0],
|
||||
"ロ": [192, 32, 16, 16, 0],
|
||||
"ワ": [208, 32, 16, 16, 0],
|
||||
"ン": [224, 32, 16, 16, 0],
|
||||
|
||||
"ッ": [0, 48, 16, 16, 0],
|
||||
"ャ": [16, 48, 16, 16, 0],
|
||||
"ュ": [32, 48, 16, 16, 0],
|
||||
"ョ": [48, 48, 16, 16, 0],
|
||||
"ガ": [64, 48, 16, 16, 0],
|
||||
"ギ": [80, 48, 16, 16, 0],
|
||||
"グ": [96, 48, 16, 16, 0],
|
||||
"ゲ": [112, 48, 16, 16, 0],
|
||||
"ゴ": [128, 48, 16, 16, 0],
|
||||
"ザ": [144, 48, 16, 16, 0],
|
||||
"ジ": [160, 48, 16, 16, 0],
|
||||
"ズ": [176, 48, 16, 16, 0],
|
||||
"ゼ": [192, 48, 16, 16, 0],
|
||||
"ゾ": [208, 48, 16, 16, 0],
|
||||
"ダ": [224, 48, 16, 16, 0],
|
||||
|
||||
"ヂ": [0, 64, 16, 16, 0],
|
||||
"ヅ": [16, 64, 16, 16, 0],
|
||||
"デ": [32, 64, 16, 16, 0],
|
||||
"ド": [48, 64, 16, 16, 0],
|
||||
"バ": [64, 64, 16, 16, 0],
|
||||
"ビ": [80, 64, 16, 16, 0],
|
||||
"ブ": [96, 64, 16, 16, 0],
|
||||
"ベ": [112, 64, 16, 16, 0],
|
||||
"ボ": [128, 64, 16, 16, 0],
|
||||
"パ": [144, 64, 16, 16, 0],
|
||||
"ピ": [160, 64, 16, 16, 0],
|
||||
"プ": [176, 64, 16, 16, 0],
|
||||
"ペ": [192, 64, 16, 16, 0],
|
||||
"ポ": [208, 64, 16, 16, 0],
|
||||
|
||||
"ァ": [0, 80, 16, 16, 0],
|
||||
"ィ": [16, 80, 16, 16, 0],
|
||||
"ゥ": [32, 80, 16, 16, 0],
|
||||
"ェ": [48, 80, 16, 16, 0],
|
||||
"ォ": [64, 80, 16, 16, 0],
|
||||
"ー": [80, 80, 16, 16, 0]
|
||||
}
|
||||
}
|
|
@ -16,11 +16,11 @@ const BootScene = () => {
|
|||
setTimeout(() => {
|
||||
setAccelaVisible(false);
|
||||
// 2000
|
||||
}, 2000);
|
||||
}, 0);
|
||||
setTimeout(() => {
|
||||
setMainMenuVisible(true);
|
||||
//6200
|
||||
}, 6200);
|
||||
}, 0);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
10
src/store.ts
10
src/store.ts
|
@ -82,6 +82,9 @@ type State = {
|
|||
// gate scene
|
||||
gateLvl: number;
|
||||
|
||||
// player name
|
||||
playerName: string;
|
||||
|
||||
// boot scene
|
||||
mainMenuComponentMatrix: ["authorize_user", "load_data"];
|
||||
mainMenuComponentMatrixIdx: 0 | 1;
|
||||
|
@ -235,6 +238,9 @@ export const useStore = create(
|
|||
// gate scene
|
||||
gateLvl: 0,
|
||||
|
||||
// player name
|
||||
playerName: "",
|
||||
|
||||
// boot scene
|
||||
mainMenuComponentMatrix: ["authorize_user", "load_data"],
|
||||
mainMenuComponentMatrixIdx: 0,
|
||||
|
@ -389,6 +395,9 @@ export const useStore = create(
|
|||
// gate scene setters
|
||||
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
|
||||
|
||||
// player name setters
|
||||
setPlayerName: (to: string) => set(() => ({ playerName: to })),
|
||||
|
||||
// boot scene setters
|
||||
setBootSubscene: (to: "load_data" | "authorize_user" | "main_menu") =>
|
||||
set(() => ({ bootSubscene: to })),
|
||||
|
@ -528,6 +537,7 @@ export const getBootSceneContext = () => {
|
|||
|
||||
return {
|
||||
...getPromptContext(),
|
||||
playerName: state.playerName,
|
||||
subscene: state.bootSubscene,
|
||||
activeMainMenuComponent:
|
||||
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
|
||||
|
|
123
src/utils/handleNameSelection.ts
Normal file
123
src/utils/handleNameSelection.ts
Normal file
|
@ -0,0 +1,123 @@
|
|||
// huge thanks to oo for help with this!!
|
||||
|
||||
const handleNameSelection = (currentString: string, newCharacter: string) => {
|
||||
// characters that cannot be the first letter
|
||||
const cantBeFirst = [
|
||||
"ン",
|
||||
"ァ",
|
||||
"ィ",
|
||||
"ゥ",
|
||||
"ェ",
|
||||
"ォ",
|
||||
"ャ",
|
||||
"ュ",
|
||||
"ョ",
|
||||
"ッ",
|
||||
"゛",
|
||||
"゜",
|
||||
"ー",
|
||||
];
|
||||
if (currentString.length === 0 && cantBeFirst.includes(newCharacter)) return;
|
||||
|
||||
const lastChar = currentString.slice(-1);
|
||||
|
||||
//「ー」 cannot be added to 「ッ」 and 「ン」
|
||||
if (newCharacter === "ー") {
|
||||
if (lastChar === "ッ" || lastChar === "ン" || lastChar === "ー") return;
|
||||
else return currentString.concat(newCharacter);
|
||||
}
|
||||
|
||||
// characters that can be followed by the lowercase characters
|
||||
const fstLowerCharSet = ["ャ", "ュ", "ョ"];
|
||||
const fstSetAppendable = [
|
||||
"キ",
|
||||
"シ",
|
||||
"チ",
|
||||
"ニ",
|
||||
"ヒ",
|
||||
"ミ",
|
||||
"リ",
|
||||
|
||||
// dakuten
|
||||
"ギ",
|
||||
"ジ",
|
||||
"ヂ",
|
||||
"ビ",
|
||||
|
||||
//handakuten
|
||||
"ピ",
|
||||
];
|
||||
|
||||
const sndLowerCharSet = ["ァ", "ィ", "ゥ", "ェ", "ォ"];
|
||||
const sndSetAppendable = ["フ"];
|
||||
|
||||
if (fstLowerCharSet.includes(newCharacter)) {
|
||||
if (fstSetAppendable.includes(lastChar))
|
||||
return currentString.concat(newCharacter);
|
||||
else return;
|
||||
} else if (sndLowerCharSet.includes(newCharacter)) {
|
||||
if (sndSetAppendable.includes(lastChar))
|
||||
return currentString.concat(newCharacter);
|
||||
else return;
|
||||
}
|
||||
|
||||
// for 「ッ」, it can added to any character except itself
|
||||
if (newCharacter === "ッ") {
|
||||
if (lastChar !== "ッ") return currentString.concat(newCharacter);
|
||||
else return;
|
||||
}
|
||||
|
||||
// characters that can be modified with dakuten
|
||||
if (newCharacter === "゛") {
|
||||
const modifiableByDakuten = {
|
||||
カ: "ガ",
|
||||
キ: "ギ",
|
||||
ク: "グ",
|
||||
ケ: "ゲ",
|
||||
コ: "ゴ",
|
||||
サ: "ザ",
|
||||
シ: "ジ",
|
||||
ス: "ズ",
|
||||
セ: "ゼ",
|
||||
ソ: "ゾ",
|
||||
タ: "ダ",
|
||||
チ: "ヂ",
|
||||
ツ: "ヅ",
|
||||
テ: "デ",
|
||||
ト: "ド",
|
||||
ハ: "バ",
|
||||
ヒ: "ビ",
|
||||
フ: "ブ",
|
||||
ヘ: "ベ",
|
||||
ホ: "ボ",
|
||||
};
|
||||
const modified =
|
||||
modifiableByDakuten[lastChar as keyof typeof modifiableByDakuten];
|
||||
|
||||
if (modified) return currentString.slice(0, -1) + modified;
|
||||
else return;
|
||||
}
|
||||
// will look into this
|
||||
//*Although 「ヂ、ヅ」 are included in the character table that Ad posted, I couldn't select them.
|
||||
|
||||
// characters that can be modified with handakuten
|
||||
if (newCharacter === "゜") {
|
||||
const modifiableByHandakuten = {
|
||||
ハ: "パ",
|
||||
ヒ: "ピ",
|
||||
フ: "プ",
|
||||
ヘ: "ペ",
|
||||
ホ: "ポ",
|
||||
};
|
||||
|
||||
const modified =
|
||||
modifiableByHandakuten[lastChar as keyof typeof modifiableByHandakuten];
|
||||
|
||||
if (modified) return currentString.slice(0, -1) + modified;
|
||||
else return;
|
||||
}
|
||||
|
||||
return currentString.concat(newCharacter);
|
||||
};
|
||||
|
||||
export default handleNameSelection;
|
Loading…
Reference in a new issue