Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions messages/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,6 @@
"/components/DialectSelector/DialectSelector": {
"legend": "方言"
},
"/components/DialectSelector/useDialects": {
"karahuto": "樺太",
"east_coast": "西海岸",
"otasu": "小田洲",
"ushiro": "鵜城",
"raichishi": "来知志",
"hokkaido": "北海道",
"southwest": "南西",
"northeast": "北東",
"saru": "沙流",
"chitose": "千歳",
"mukawa": "鵡川",
"horobetsu": "幌別",
"abuta": "虻田",
"shiraoi": "白老",
"shizunai": "静内",
"ishikari": "石狩",
"shiranuka": "白糠",
"tokachi": "十勝",
"kushiro": "釧路",
"urakawa": "浦河",
"bihoro": "美幌",
"samani": "様似"
},
"/components/DialectSelector/DialectSelectorCheckbox": {
"count": "<vh>(</vh>{count}<vh>件)</vh>"
},
Expand Down Expand Up @@ -137,5 +113,29 @@
},
"/components/Search/Search": {
"label": "キーワード"
},
"/hooks/useDialectFormatter": {
"karahuto": "樺太",
"east_coast": "西海岸",
"otasu": "小田洲",
"ushiro": "鵜城",
"raichishi": "来知志",
"hokkaido": "北海道",
"southwest": "南西",
"northeast": "北東",
"saru": "沙流",
"chitose": "千歳",
"mukawa": "鵡川",
"horobetsu": "幌別",
"abuta": "虻田",
"shiraoi": "白老",
"shizunai": "静内",
"ishikari": "石狩",
"shiranuka": "白糠",
"tokachi": "十勝",
"kushiro": "釧路",
"urakawa": "浦河",
"bihoro": "美幌",
"samani": "様似"
}
}
1 change: 0 additions & 1 deletion src/app/[locale]/search/Result.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const ResultRoot: FC<ResultRootProps> = (props) => {
document={hit.document}
uri={hit.uri}
author={hit.author}
dialect={hit.dialect}
dialectLv1={hit.dialect_lv1}
dialectLv2={hit.dialect_lv2}
dialectLv3={hit.dialect_lv3}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ import { FC, ReactNode, useMemo } from "react";
import { ChevronRightIcon } from "@radix-ui/react-icons";
import { Flex } from "@radix-ui/themes";

export type HierarchyProps = {
children: string | null;
export type BreadcrumbProps = {
values: ReactNode[];
};

export const Hierarchy: FC<HierarchyProps> = (props) => {
const { children } = props;
export const Breadcrumb: FC<BreadcrumbProps> = (props) => {
const { values } = props;

const nodes = useMemo(() => {
const nodes: ReactNode[] = [];

if (!children) {
if (!values) {
return null;
}

for (const [key, fragment] of Object.entries(children.split("/"))) {
for (const [key, fragment] of Object.entries(values)) {
if (nodes.length !== 0) {
nodes.push(<ChevronRightIcon color="gray" key={key} aria-label="→" />);
}
Expand All @@ -25,7 +25,7 @@ export const Hierarchy: FC<HierarchyProps> = (props) => {
}

return nodes;
}, [children]);
}, [values]);

if (!nodes) {
return null;
Expand Down
1 change: 1 addition & 0 deletions src/components/Breadcrumb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Breadcrumb";
57 changes: 33 additions & 24 deletions src/components/DialectSelector/useDialects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useTranslations } from "next-intl";
import { useDialectFormatter } from "@/hooks/useDialectFormatter";

export type Dialect = {
label: string;
Expand All @@ -7,52 +7,61 @@ export type Dialect = {
};

export const useDialects = (): Dialect[] => {
const t = useTranslations("/components/DialectSelector/useDialects");
const format = useDialectFormatter();

const dialects: Dialect[] = [
{
label: t("karahuto"),
label: format("樺太"),
value: "樺太",
children: [
{
label: t("east_coast"),
label: format("樺太/西海岸"),
value: "樺太/西海岸",
children: [
{ label: t("otasu"), value: "樺太/西海岸/小田洲" },
{ label: t("ushiro"), value: "樺太/西海岸/鵜城" },
{ label: t("raichishi"), value: "樺太/西海岸/来知志" },
{
label: format("樺太/西海岸/小田洲"),
value: "樺太/西海岸/小田洲",
},
{
label: format("樺太/西海岸/鵜城"),
value: "樺太/西海岸/鵜城",
},
{
label: format("樺太/西海岸/来知志"),
value: "樺太/西海岸/来知志",
},
],
},
],
},
{
label: t("hokkaido"),
label: format("北海道"),
value: "北海道",
children: [
{
label: t("southwest"),
label: format("北海道/南西"),
value: "北海道/南西",
children: [
{ label: t("saru"), value: "北海道/南西/沙流" },
{ label: t("chitose"), value: "北海道/南西/千歳" },
{ label: t("mukawa"), value: "北海道/南西/鵡川" },
{ label: t("horobetsu"), value: "北海道/南西/幌別" },
{ label: t("abuta"), value: "北海道/南西/虻田" },
{ label: t("shiraoi"), value: "北海道/南西/白老" },
{ label: format("北海道/南西/沙流"), value: "北海道/南西/沙流" },
{ label: format("北海道/南西/千歳"), value: "北海道/南西/千歳" },
{ label: format("北海道/南西/鵡川"), value: "北海道/南西/鵡川" },
{ label: format("北海道/南西/幌別"), value: "北海道/南西/幌別" },
{ label: format("北海道/南西/虻田"), value: "北海道/南西/虻田" },
{ label: format("北海道/南西/白老"), value: "北海道/南西/白老" },
],
},
{
label: t("northeast"),
label: format("北海道/北東"),
value: "北海道/北東",
children: [
{ label: t("shizunai"), value: "北海道/北東/静内" },
{ label: t("ishikari"), value: "北海道/北東/石狩" },
{ label: t("shiranuka"), value: "北海道/北東/白糠" },
{ label: t("tokachi"), value: "北海道/北東/十勝" },
{ label: t("kushiro"), value: "北海道/北東/釧路" },
{ label: t("urakawa"), value: "北海道/北東/浦河" },
{ label: t("bihoro"), value: "北海道/北東/美幌" },
{ label: t("samani"), value: "北海道/北東/様似" },
{ label: format("北海道/北東/静内"), value: "北海道/北東/静内" },
{ label: format("北海道/北東/石狩"), value: "北海道/北東/石狩" },
{ label: format("北海道/北東/白糠"), value: "北海道/北東/白糠" },
{ label: format("北海道/北東/十勝"), value: "北海道/北東/十勝" },
{ label: format("北海道/北東/釧路"), value: "北海道/北東/釧路" },
{ label: format("北海道/北東/浦河"), value: "北海道/北東/浦河" },
{ label: format("北海道/北東/美幌"), value: "北海道/北東/美幌" },
{ label: format("北海道/北東/様似"), value: "北海道/北東/様似" },
],
},
],
Expand Down
12 changes: 7 additions & 5 deletions src/components/Entry/Entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export type EntryRootProps = {
collectionLv3: string | null;
uri: string | null;
author: string | null;
dialect: string | null;
dialectLv1: string[] | null;
dialectLv2: string[] | null;
dialectLv3: string[] | null;
Expand All @@ -49,7 +48,6 @@ const EntryRoot: React.FC<EntryRootProps> = (props) => {
document,
uri,
author,
dialect,
dialectLv1,
dialectLv2,
dialectLv3,
Expand Down Expand Up @@ -119,9 +117,14 @@ const EntryRoot: React.FC<EntryRootProps> = (props) => {
)}

<Flex gap="1" flexGrow="1" flexShrink="0" justify="end" align="center">
{(author || dialect) && (
{(author || dialectLv1 || dialectLv2 || dialectLv3) && (
<Box flexGrow="1" flexShrink="0" asChild>
<EntryAuthor author={author} dialect={dialect} />
<EntryAuthor
author={author}
dialectLv1={dialectLv1}
dialectLv2={dialectLv2}
dialectLv3={dialectLv3}
/>
</Box>
)}

Expand All @@ -132,7 +135,6 @@ const EntryRoot: React.FC<EntryRootProps> = (props) => {
collectionLv3={collectionLv3}
document={document}
author={author}
dialect={dialect}
dialectLv1={dialectLv1}
dialectLv2={dialectLv2}
dialectLv3={dialectLv3}
Expand Down
27 changes: 21 additions & 6 deletions src/components/Entry/EntryAuthor.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import { useDialectFormatter } from "@/hooks/useDialectFormatter";
import { getMostDetailedDialects } from "@/utils/getMostDetailedDialects";
import { Text, VisuallyHidden } from "@radix-ui/themes";
import { useTranslations } from "next-intl";
import { FC } from "react";

type EntryAuthorProps = {
author: string | null;
dialect: string | null;
dialectLv1: string[] | null;
dialectLv2: string[] | null;
dialectLv3: string[] | null;
};

export const EntryAuthor: FC<EntryAuthorProps> = (props) => {
const { author, dialect } = props;
const { author, dialectLv1, dialectLv2, dialectLv3 } = props;

const t = useTranslations("/components/Entry/EntryAuthor");
const formatDialect = useDialectFormatter();

if (author && dialect) {
const dialects = getMostDetailedDialects(
dialectLv1 ?? [],
dialectLv2 ?? [],
dialectLv3 ?? [],
);
const formattedDialects =
dialects.length > 0
? dialects.map((dialect) => formatDialect(dialect)).join(", ")
: null;

if (author && formattedDialects) {
return (
<Text color="gray" size="2">
{t.rich("author_with_dialect", {
author,
dialect,
dialect: formattedDialects,
vh: (chunks) => <VisuallyHidden>{chunks}</VisuallyHidden>,
})}
</Text>
Expand All @@ -35,11 +50,11 @@ export const EntryAuthor: FC<EntryAuthorProps> = (props) => {
);
}

if (dialect) {
if (formattedDialects) {
return (
<Text color="gray" size="2">
{t.rich("dialect", {
dialect,
dialect: formattedDialects,
vh: (chunks) => <VisuallyHidden>{chunks}</VisuallyHidden>,
})}
</Text>
Expand Down
43 changes: 33 additions & 10 deletions src/components/Entry/EntryDetailsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { CopyIcon, DotsHorizontalIcon } from "@radix-ui/react-icons";
import {
Badge,
Button,
Code,
DataList,
Expand All @@ -12,16 +11,16 @@ import {
Link,
Text,
Tooltip,
VisuallyHidden,
} from "@radix-ui/themes";
import { FC, useCallback } from "react";
import dayjs from "dayjs";
import { useLocale, useTranslations } from "next-intl";

import { formatDateOrRange } from "@/utils/timestamp";
import { toHref } from "@/utils/uri";
import { useLocale, useTranslations } from "next-intl";
import { getMostDetailedDialects } from "@/utils/getMostDetailedDialects";

import { Hierarchy } from "../Hierarchy/Hierarchy";
import { Breadcrumb } from "../Breadcrumb";

const NoData = () => {
const t = useTranslations("/components/Entry/EntryDetailsDialog");
Expand All @@ -35,7 +34,6 @@ export type EntryDetailsDialogProps = {
collectionLv2: string | null;
collectionLv3: string | null;
author: string | null;
dialect: string | null;
dialectLv1: string[] | null;
dialectLv2: string[] | null;
dialectLv3: string[] | null;
Expand All @@ -52,8 +50,10 @@ export const EntryDetailsDialog: FC<EntryDetailsDialogProps> = (props) => {
collectionLv3,
document,
author,
dialect,
uri,
dialectLv1,
dialectLv2,
dialectLv3,
recordedAt,
publishedAt,
} = props;
Expand All @@ -62,6 +62,16 @@ export const EntryDetailsDialog: FC<EntryDetailsDialogProps> = (props) => {
const t = useTranslations("/components/Entry/EntryDetailsDialog");
const href = uri ? toHref(uri) : null;

const hasDialect = !!(dialectLv1 || dialectLv2 || dialectLv3);

const mostDetailedDialects = hasDialect
? getMostDetailedDialects(
dialectLv1 ?? [],
dialectLv2 ?? [],
dialectLv3 ?? [],
)
: null;

dayjs.locale(locale);

const handleCopy = useCallback(() => {
Expand Down Expand Up @@ -107,9 +117,14 @@ export const EntryDetailsDialog: FC<EntryDetailsDialogProps> = (props) => {
<DataList.Label>{t("collection")}</DataList.Label>
<DataList.Value>
{collectionLv3 || collectionLv2 || collectionLv1 ? (
<Hierarchy>
{collectionLv3 ?? collectionLv2 ?? collectionLv1}
</Hierarchy>
<Breadcrumb
values={
collectionLv3?.split("/") ??
collectionLv2?.split("/") ??
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
collectionLv1?.split("/")!
}
/>
) : (
<NoData />
)}
Expand All @@ -129,7 +144,15 @@ export const EntryDetailsDialog: FC<EntryDetailsDialogProps> = (props) => {
<DataList.Item>
<DataList.Label>{t("dialect")}</DataList.Label>
<DataList.Value>
{dialect ? <Badge>{dialect}</Badge> : <NoData />}
<Flex direction="column" gap="1">
{mostDetailedDialects ? (
mostDetailedDialects.map((dialect) => (
<Breadcrumb key={dialect} values={dialect.split("/")} />
))
) : (
<NoData />
)}
</Flex>
</DataList.Value>
</DataList.Item>

Expand Down
Empty file removed src/components/Hierarchy/index.ts
Empty file.
Loading
Loading