mirror of
https://github.com/patarapolw/cjdic2.git
synced 2026-11-09 17:39:35 +00:00
furigana format is now <>{} and add input message for glob
This commit is contained in:
1 parent
b1ef987f9d
commit
96e36e1d4c
3 files changed
+46
-30
No files matched your search
@@ -38,7 +38,7 @@ interface Progress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function LoadingDialog() {
|
function LoadingDialog() {
|
||||||
const [messages, setMessages] = useState<Progress[]>([]);
|
const [messages, set_messages] = useState<Progress[]>([]);
|
||||||
|
|
||||||
const isInit = useRef(false);
|
const isInit = useRef(false);
|
||||||
|
|
||||||
@@ -106,11 +106,11 @@ function LoadingDialog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await invoke("init_yomitan", { dicts, lang });
|
await invoke("init_yomitan", { dicts, lang });
|
||||||
setMessages([]);
|
set_messages([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
listen<LoadYomitanZipDirResult>("load-yomitan-dir", ({ payload }) => {
|
listen<LoadYomitanZipDirResult>("load-yomitan-dir", ({ payload }) => {
|
||||||
setMessages((messages) => {
|
set_messages((messages) => {
|
||||||
if (payload.new_dicts.length > 0) {
|
if (payload.new_dicts.length > 0) {
|
||||||
messages = [
|
messages = [
|
||||||
...messages,
|
...messages,
|
||||||
@@ -149,7 +149,7 @@ function LoadingDialog() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function updateProgress(payload: Progress) {
|
function updateProgress(payload: Progress) {
|
||||||
setMessages((messages) => {
|
set_messages((messages) => {
|
||||||
const prev = messages[messages.length - 1];
|
const prev = messages[messages.length - 1];
|
||||||
if (prev?.message === payload.message) {
|
if (prev?.message === payload.message) {
|
||||||
messages = messages.slice(0, messages.length - 1);
|
messages = messages.slice(0, messages.length - 1);
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { useSearchParams } from "react-router";
|
import { useSearchParams } from "react-router";
|
||||||
import { toKana } from "wanakana";
|
import { toHiragana, toKana } from "wanakana";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Card,
|
Card,
|
||||||
CloseButton,
|
CloseButton,
|
||||||
Group,
|
Field,
|
||||||
Input,
|
Input,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
Stack,
|
Stack,
|
||||||
@@ -116,9 +116,10 @@ function SearchPage() {
|
|||||||
}
|
}
|
||||||
if (!norm_q) return;
|
if (!norm_q) return;
|
||||||
|
|
||||||
const ender = /\p{Z}$/u.test(q) ? "" : "*";
|
const ender =
|
||||||
|
/\p{Z}$/u.test(q) || [..."*?[]"].some((c) => q.includes(c)) ? "" : "*";
|
||||||
|
|
||||||
const re = /\<(.+?)\>\[(.+?)\]/g;
|
const re = /\<(.+?)\>{(.+?)}/g;
|
||||||
|
|
||||||
let qTerm = "";
|
let qTerm = "";
|
||||||
let qReading = "";
|
let qReading = "";
|
||||||
@@ -199,9 +200,7 @@ function SearchPage() {
|
|||||||
q = toKana(q, {
|
q = toKana(q, {
|
||||||
useObsoleteKana: true,
|
useObsoleteKana: true,
|
||||||
IMEMode: true,
|
IMEMode: true,
|
||||||
customKanaMapping: Object.fromEntries(
|
customKanaMapping: Object.fromEntries([..."<>{}"].map((c) => [c, c])),
|
||||||
"<>[]".split("").map((c) => [c, c]),
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,14 +223,14 @@ function SearchPage() {
|
|||||||
target,
|
target,
|
||||||
}) => {
|
}) => {
|
||||||
const cleanedFuri = [...furigana.replace(/n/g, "ん")]
|
const cleanedFuri = [...furigana.replace(/n/g, "ん")]
|
||||||
.map((c) => katakanaToHiragana(c))
|
.map((c) => toHiragana(c, { passRomaji: true }))
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
let parts = compositionData.split(KANJI_REGEX);
|
let parts = compositionData.split(KANJI_REGEX);
|
||||||
if (parts.length === 1) return;
|
if (parts.length === 1) return;
|
||||||
|
|
||||||
const hiraganaParts = parts.map((p) =>
|
const hiraganaParts = parts.map((p) =>
|
||||||
[...p].map((c) => katakanaToHiragana(c)).join(""),
|
[...p].map((c) => toHiragana(c, { passRomaji: true })).join(""),
|
||||||
);
|
);
|
||||||
const regex = new RegExp(
|
const regex = new RegExp(
|
||||||
`^${hiraganaParts.map((p, idx) => `(${idx & 1 ? ".+" : p})`).join("")}$`,
|
`^${hiraganaParts.map((p, idx) => `(${idx & 1 ? ".+" : p})`).join("")}$`,
|
||||||
@@ -244,7 +243,7 @@ function SearchPage() {
|
|||||||
rt.shift();
|
rt.shift();
|
||||||
|
|
||||||
const markup = parts
|
const markup = parts
|
||||||
.map((p, idx) => (idx & 1 ? `<${p}>[${rt[idx]}]` : p))
|
.map((p, idx) => (idx & 1 ? `<${p}>{${rt[idx]}}` : p))
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
set_q((q) => {
|
set_q((q) => {
|
||||||
@@ -262,13 +261,6 @@ function SearchPage() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function katakanaToHiragana(k: string) {
|
|
||||||
let c = k.charCodeAt(0);
|
|
||||||
return c >= 12449 && c <= 12531
|
|
||||||
? String.fromCharCode(k.charCodeAt(0) - 96)
|
|
||||||
: k;
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearButton = q.trim() ? (
|
const clearButton = q.trim() ? (
|
||||||
<CloseButton
|
<CloseButton
|
||||||
size={"xs"}
|
size={"xs"}
|
||||||
@@ -309,7 +301,7 @@ function SearchPage() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Group attached w="full">
|
<Field.Root w="full">
|
||||||
<InputGroup endElement={clearButton}>
|
<InputGroup endElement={clearButton}>
|
||||||
<Input
|
<Input
|
||||||
id="greet-input"
|
id="greet-input"
|
||||||
@@ -324,8 +316,24 @@ function SearchPage() {
|
|||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
{/* <Button type="submit">Search</Button> */}
|
{q.includes(" ") ? (
|
||||||
</Group>
|
<Field.HelperText>
|
||||||
|
Space (" ") to mark word boundary for search
|
||||||
|
</Field.HelperText>
|
||||||
|
) : null}
|
||||||
|
{[..."*?[]"].some((c) => q.includes(c)) ? (
|
||||||
|
<Field.HelperText>
|
||||||
|
<code>{"*?[]"}</code> can be used as
|
||||||
|
<a
|
||||||
|
href="https://en.wikipedia.org/wiki/Glob_(programming)#Syntax"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
glob
|
||||||
|
</a>
|
||||||
|
</Field.HelperText>
|
||||||
|
) : null}
|
||||||
|
</Field.Root>
|
||||||
<div style={{ marginTop: "0.5em", display: "flex", gap: "1em" }}>
|
<div style={{ marginTop: "0.5em", display: "flex", gap: "1em" }}>
|
||||||
<Switch.Root
|
<Switch.Root
|
||||||
checked={isAutoKana}
|
checked={isAutoKana}
|
||||||
@@ -357,18 +365,23 @@ function SearchPage() {
|
|||||||
<li key={i} lang={lang} style={{ marginLeft: "1.5em" }}>
|
<li key={i} lang={lang} style={{ marginLeft: "1.5em" }}>
|
||||||
<div>
|
<div>
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
<Card.Header flexDirection={"row"} gap={0}>
|
<Card.Header display={"block"}>
|
||||||
<a onClick={() => onTermClicked(term + " ")}>{term}</a>
|
<a
|
||||||
|
onClick={() =>
|
||||||
|
onTermClicked(reading ? `<${term}>{${reading}}` : term)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{term}
|
||||||
|
</a>
|
||||||
{reading && reading !== term ? (
|
{reading && reading !== term ? (
|
||||||
<>
|
<>
|
||||||
{"("}
|
{"("}
|
||||||
<a onClick={() => onTermClicked(reading + " ")}>
|
<a onClick={() => onTermClicked(reading)}>{reading}</a>
|
||||||
{reading}
|
|
||||||
</a>
|
|
||||||
{")"}
|
{")"}
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
【{dict_title}】{JSONdumpClean(it)}
|
<span>【{dict_title}】</span>
|
||||||
|
<span>{JSONdumpClean(it)}</span>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Body>
|
<Card.Body>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -29,4 +29,7 @@ export default defineConfig(async () => ({
|
|||||||
ignored: ["**/src-tauri/**"],
|
ignored: ["**/src-tauri/**"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
chunkSizeWarningLimit: 1024, // default = 500 kB
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
Reference in new issue
Block a user