@terrafirmagreg-team/recipe 1.2.1 → 1.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terrafirmagreg-team/recipe",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "type": "module",
5
5
  "description": "Recipe viewer and calculator",
6
6
  "license": "LGPL-3.0-only",
@@ -20,19 +20,18 @@
20
20
  ],
21
21
  "./types/*": "./src/types/*.ts",
22
22
  "./types": "./src/types/index.ts",
23
- "./styles.css": "./styles.css",
24
- "./locales": "./src/locales.ts"
23
+ "./styles.css": "./styles.css"
25
24
  },
26
25
  "dependencies": {
27
26
  "@terrafirmagreg-team/data": "1.2.1",
28
27
  "@terrafirmagreg-team/dump": "1.2.1",
29
- "@terrafirmagreg-team/game": "1.2.1",
30
- "@terrafirmagreg-team/kit": "1.2.1",
28
+ "@terrafirmagreg-team/game": "1.2.2",
29
+ "@terrafirmagreg-team/kit": "1.2.3",
31
30
  "@terrafirmagreg-team/mdx": "1.2.1",
32
31
  "@terrafirmagreg-team/preview": "1.2.1",
33
32
  "@terrafirmagreg-team/sites": "1.2.1",
34
- "@terrafirmagreg-team/translate": "1.2.1",
35
- "@terrafirmagreg-team/ui": "1.2.1",
33
+ "@terrafirmagreg-team/translate": "1.2.3",
34
+ "@terrafirmagreg-team/ui": "1.2.2",
36
35
  "comlink": "^4.4.2",
37
36
  "fflate": "0.8.3",
38
37
  "fumadocs-core": "16.17.8",
@@ -156,7 +156,7 @@ export function SlotHitbox({
156
156
  dataset={dataset}
157
157
  id={widget.id}
158
158
  name={name}
159
- kind={kind === 'tag' ? 'item' : kind}
159
+ kind={widgetRefKind(widget)}
160
160
  lang={lang}
161
161
  langMap={langMap}
162
162
  level={tooltipLevel}
@@ -177,7 +177,7 @@ export function SlotHitbox({
177
177
  dataset={dataset}
178
178
  id={widget.id}
179
179
  name={name}
180
- kind={kind === 'tag' ? 'item' : kind}
180
+ kind={widgetRefKind(widget)}
181
181
  lang={lang}
182
182
  langMap={langMap}
183
183
  level={tooltipLevel}
@@ -37,6 +37,7 @@ export function RecipeEmbedCard({
37
37
  title={title}
38
38
  src={src}
39
39
  onFail={() => setFailed(true)}
40
+ interactive={false}
40
41
  />
41
42
  </FitBox>
42
43
  </Link>
@@ -4,10 +4,9 @@ import { createElement } from 'react';
4
4
  import type * as PageTree from 'fumadocs-core/page-tree';
5
5
  import { Entry } from '@terrafirmagreg-team/game/components/entry/entry';
6
6
  import { loadMergedLangMap, creativeTabName } from '@terrafirmagreg-team/dump/lib/dump/assets/lang/load';
7
- import { loadClientManifest } from '@terrafirmagreg-team/dump/lib/dump/client/dump';
8
7
  import { DUMP_POINTER_TTL } from '@terrafirmagreg-team/dump/lib/dump/json-reader';
9
8
  import { createAsyncCache } from '@terrafirmagreg-team/data/lib/async-cache';
10
- import { loadDatasetRecipeCategories } from '@terrafirmagreg-team/recipe/lib/data/category/load';
9
+ import { getRecipeSource } from '@terrafirmagreg-team/recipe/lib/source';
11
10
  import { keyTreeNode } from '@terrafirmagreg-team/translate/server';
12
11
  import { loadLocaleRegistry } from '@terrafirmagreg-team/translate/server';
13
12
  import { encodeQueryValue } from '@terrafirmagreg-team/translate/lib/url';
@@ -68,8 +67,9 @@ async function buildRecipeTrees(): Promise<SectionTrees> {
68
67
  for (const lang of languages ?? [defaultLanguage]) {
69
68
  const ref = { id };
70
69
  const map = await loadMergedLangMap(ref, lang);
71
- const categories = await loadDatasetRecipeCategories(ref);
72
- const types = (await loadClientManifest(ref))?.indexes.recipes.types;
70
+ const source = getRecipeSource();
71
+ const categories = await source.categories(ref);
72
+ const types = (await source.manifest(ref))?.indexes.recipes.types;
73
73
  const nonEmpty = types
74
74
  ? new Set(
75
75
  types
@@ -3,6 +3,7 @@
3
3
  import { useEffect, useState, type ReactNode, type RefObject } from 'react';
4
4
  import { useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
5
5
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
6
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
6
7
  import { PagedCard } from '@terrafirmagreg-team/recipe/components/cards/paged-card';
7
8
  import { RecipeDefaultMenuItem } from '@terrafirmagreg-team/recipe/components/cards/default-item';
8
9
  import { CopyIdMenu } from '@terrafirmagreg-team/game/components/entry/copy-id-menu';
@@ -67,6 +68,7 @@ function RecipeGridCard({
67
68
  defaultMaterial?: string;
68
69
  }) {
69
70
  const t = useTranslations();
71
+ const resolved = useResolvedLang();
70
72
  const { dataset, lang, langMap, names, nav, index } = session;
71
73
  const recipe = useAsyncValue(
72
74
  () => loadClientRecipe(dataset, row.id, row.bucket),
@@ -89,17 +91,17 @@ function RecipeGridCard({
89
91
 
90
92
  const focus = () =>
91
93
  pushUrlState(
92
- recipeHref(dataset, lang, { ...nav, id: row.id, solo: undefined }),
94
+ recipeHref(dataset, resolved, { ...nav, id: row.id, solo: undefined }),
93
95
  );
94
96
 
95
97
  const isolate = () =>
96
98
  pushUrlState(
97
- recipeHref(dataset, lang, { ...nav, id: row.id, solo: '1' }),
99
+ recipeHref(dataset, resolved, { ...nav, id: row.id, solo: '1' }),
98
100
  );
99
101
 
100
102
  const openNewTab = () =>
101
103
  window.open(
102
- recipeHref(dataset, lang, { ...nav, id: row.id, solo: '1' }),
104
+ recipeHref(dataset, resolved, { ...nav, id: row.id, solo: '1' }),
103
105
  '_blank',
104
106
  'noopener',
105
107
  );
@@ -3,6 +3,7 @@
3
3
  import Link from 'next/link';
4
4
  import type { ReactNode } from 'react';
5
5
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
6
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
6
7
  import { QueryPager } from '@terrafirmagreg-team/recipe/components/views/browser/query-controls';
7
8
  import { Pager } from '@terrafirmagreg-team/ui/components/blocks/page/pager';
8
9
  import { RecipeToolbar } from '@terrafirmagreg-team/recipe/components/views/browser/toolbar';
@@ -38,6 +39,7 @@ export function RecipeFrame({
38
39
  children: ReactNode;
39
40
  }) {
40
41
  const t = useTranslations();
42
+ const resolved = useResolvedLang();
41
43
  const goPage = (dir: number) => {
42
44
  if (!list || list.pages <= 1) return;
43
45
  const next = (list.page + dir + list.pages) % list.pages;
@@ -46,7 +48,7 @@ export function RecipeFrame({
46
48
  return;
47
49
  }
48
50
  replaceUrlState(
49
- recipeHref(session.dataset, session.lang, {
51
+ recipeHref(session.dataset, resolved, {
50
52
  ...session.nav,
51
53
  id: undefined,
52
54
  rpage: next > 0 ? next + 1 : undefined,
@@ -88,7 +90,6 @@ export function RecipeFrame({
88
90
  ) : (
89
91
  <QueryPager
90
92
  dataset={session.dataset}
91
- lang={session.lang}
92
93
  params={{ ...session.nav, id: undefined }}
93
94
  query={session.query}
94
95
  list={list}
@@ -21,6 +21,27 @@ import { cn } from '@terrafirmagreg-team/ui/lib/utils/cn';
21
21
  import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
22
22
  import type { RecipePageData } from '@terrafirmagreg-team/recipe/types';
23
23
 
24
+ export function RecipeBrowserFallback() {
25
+ return (
26
+ <div className="viewport-shell recipe-viewport not-prose flex w-full flex-col gap-3">
27
+ <div className="flex min-h-0 flex-1 gap-4">
28
+ <main className="flex min-w-0 flex-1 flex-col">
29
+ <Skeleton className="mb-3 h-9 w-full rounded-md" />
30
+ <div className="flex min-h-0 flex-1 flex-col items-center justify-start gap-2 pt-2">
31
+ {Array.from({ length: 6 }, (_, i) => (
32
+ <Skeleton
33
+ key={i}
34
+ className="h-24 rounded-md"
35
+ style={{ width: 240 + (i % 3) * 70 }}
36
+ />
37
+ ))}
38
+ </div>
39
+ </main>
40
+ </div>
41
+ </div>
42
+ );
43
+ }
44
+
24
45
  export function RecipeBrowser({
25
46
  dataset: id,
26
47
  datasetTitle,
@@ -9,6 +9,7 @@ import {
9
9
  useState,
10
10
  } from 'react';
11
11
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
12
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
12
13
  import { useFavorites } from '@terrafirmagreg-team/recipe/hooks/use-favorites';
13
14
  import { useFavoriteHotkey } from '@terrafirmagreg-team/recipe/hooks/use-favorite-hotkey';
14
15
  import { useHideUnused } from '@terrafirmagreg-team/recipe/hooks/use-hide-unused';
@@ -111,12 +112,13 @@ export const ItemPanel = memo(function ItemPanel({
111
112
  });
112
113
  }, []);
113
114
 
114
- const onPress = useItemPress({ dataset, lang, nav, isCalc });
115
+ const resolved = useResolvedLang();
116
+ const onPress = useItemPress({ dataset, nav, isCalc });
115
117
 
116
118
  const setTab = (next: string) => {
117
119
  setPanelPage(0);
118
120
  replaceUrlState(
119
- recipeHref(dataset, lang, {
121
+ recipeHref(dataset, resolved, {
120
122
  ...nav,
121
123
  tab: next || undefined,
122
124
  }),
@@ -212,7 +214,6 @@ export const ItemPanel = memo(function ItemPanel({
212
214
  <RecipeSettings />
213
215
  <QuerySearch
214
216
  dataset={dataset}
215
- lang={lang}
216
217
  params={nav}
217
218
  query={query}
218
219
  onQuery={(next) => {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useMemo, useRef } from 'react';
4
4
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
5
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
5
6
  import { RecipeFrame } from '@terrafirmagreg-team/recipe/components/views/browser/frame';
6
7
  import { ItemViewHeader } from '@terrafirmagreg-team/recipe/components/views/browser/item-view-header';
7
8
  import {
@@ -35,6 +36,7 @@ import type {
35
36
 
36
37
  export function ItemView({ session }: { session: RecipeSession }) {
37
38
  const t = useTranslations();
39
+ const resolved = useResolvedLang();
38
40
  const {
39
41
  dataset,
40
42
  lang,
@@ -63,7 +65,6 @@ export function ItemView({ session }: { session: RecipeSession }) {
63
65
  const tags = useItemTagGroups({ dataset, index, item, kind });
64
66
  const pane = useItemPane({
65
67
  dataset,
66
- lang,
67
68
  nav,
68
69
  relation,
69
70
  recipeId,
@@ -110,13 +111,13 @@ export function ItemView({ session }: { session: RecipeSession }) {
110
111
  const row = typeFilter.rows[focusIndex + dir];
111
112
  if (focusIndex < 0 || !row) return;
112
113
  replaceUrlState(
113
- recipeHref(dataset, lang, { ...nav, id: row.id, rpage: undefined }),
114
+ recipeHref(dataset, resolved, { ...nav, id: row.id, rpage: undefined }),
114
115
  );
115
116
  return;
116
117
  }
117
118
  if (list.pages <= 1) return;
118
119
  replaceUrlState(
119
- recipeHref(dataset, lang, {
120
+ recipeHref(dataset, resolved, {
120
121
  ...nav,
121
122
  rpage: (list.page + dir + list.pages) % list.pages,
122
123
  }),
@@ -2,6 +2,7 @@
2
2
  import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
3
3
 
4
4
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
5
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
5
6
  import { EmptyState } from '@terrafirmagreg-team/ui/components/blocks/page/empty-state';
6
7
  import { LinkPreview } from '@terrafirmagreg-team/ui/components/blocks/link/link-preview';
7
8
  import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
@@ -27,6 +28,7 @@ export function ItemTagGroups({
27
28
  nav: RecipeHrefOpts;
28
29
  }) {
29
30
  const t = useTranslations();
31
+ const resolved = useResolvedLang();
30
32
  if (!groups.length) {
31
33
  return <EmptyState variant="empty">{t('No tags for this item.', { note: 'recipe.empty_tags' })}</EmptyState>;
32
34
  }
@@ -47,7 +49,7 @@ export function ItemTagGroups({
47
49
  return (
48
50
  <LinkPreview
49
51
  key={`${tagKind}:${id}`}
50
- href={recipeHref(dataset, lang, {
52
+ href={recipeHref(dataset, resolved, {
51
53
  type: 'emi:tag',
52
54
  id: tagPseudoId(id, tagKind),
53
55
  search: query || undefined,
@@ -65,7 +67,7 @@ export function ItemTagGroups({
65
67
  ? text || token
66
68
  : `${text} ${token}`;
67
69
  replaceUrlState(
68
- recipeHref(dataset, lang, {
70
+ recipeHref(dataset, resolved, {
69
71
  type: 'emi:tag',
70
72
  search,
71
73
  }),
@@ -10,20 +10,18 @@ import {
10
10
  } from '@terrafirmagreg-team/ui/components/ui/input-group';
11
11
  import { Pager } from '@terrafirmagreg-team/ui/components/blocks/page/pager';
12
12
  import { recipeHref } from '@terrafirmagreg-team/recipe/lib/links';
13
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
13
14
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
14
15
  import { cn } from '@terrafirmagreg-team/ui/lib/utils/cn';
15
- import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
16
16
  import type { RecipeHrefOpts } from '@terrafirmagreg-team/recipe/types';
17
17
 
18
18
  type QueryNav = {
19
19
  dataset: DatasetRef;
20
- lang: Lang;
21
20
  params?: RecipeHrefOpts;
22
21
  };
23
22
 
24
23
  export function QuerySearch({
25
24
  dataset,
26
- lang,
27
25
  params,
28
26
  query,
29
27
  onQuery,
@@ -35,6 +33,7 @@ export function QuerySearch({
35
33
  placeholder?: string;
36
34
  className?: string;
37
35
  }) {
36
+ const resolved = useResolvedLang();
38
37
  return (
39
38
  <InputGroup className={cn('w-full', className)}>
40
39
  <InputGroupAddon>
@@ -48,7 +47,7 @@ export function QuerySearch({
48
47
  const next = event.target.value;
49
48
  onQuery(next);
50
49
  replaceUrlState(
51
- recipeHref(dataset, lang, {
50
+ recipeHref(dataset, resolved, {
52
51
  ...params,
53
52
  search: next || undefined,
54
53
  }),
@@ -61,7 +60,6 @@ export function QuerySearch({
61
60
 
62
61
  export function QueryPager({
63
62
  dataset,
64
- lang,
65
63
  params,
66
64
  query,
67
65
  list,
@@ -81,6 +79,7 @@ export function QueryPager({
81
79
  leading?: ReactNode;
82
80
  className?: string;
83
81
  }) {
82
+ const resolved = useResolvedLang();
84
83
  return (
85
84
  <Pager
86
85
  page={list.page}
@@ -92,7 +91,7 @@ export function QueryPager({
92
91
  className={className}
93
92
  onPage={(next) =>
94
93
  replaceUrlState(
95
- recipeHref(dataset, lang, {
94
+ recipeHref(dataset, resolved, {
96
95
  ...params,
97
96
  search: query || undefined,
98
97
  rpage: next + 1,
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useEffect, useRef } from 'react';
4
4
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
5
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
5
6
  import { useAsyncResult, useAsyncValue } from '@terrafirmagreg-team/ui/hooks/use-async-value';
6
7
  import { RecipeFrame } from '@terrafirmagreg-team/recipe/components/views/browser/frame';
7
8
  import {
@@ -29,9 +30,9 @@ const EMPTY_ROWS: RecipeCompactRow[] = [];
29
30
 
30
31
  export function TypeView({ session }: { session: RecipeSession }) {
31
32
  const t = useTranslations();
33
+ const resolved = useResolvedLang();
32
34
  const {
33
35
  dataset,
34
- lang,
35
36
  index,
36
37
  indexLoading,
37
38
  place,
@@ -82,14 +83,14 @@ export function TypeView({ session }: { session: RecipeSession }) {
82
83
  const row = focusRes.value?.[0];
83
84
  const category = row ? index.types[row.type] : undefined;
84
85
  replaceUrlState(
85
- recipeHref(dataset, lang, {
86
+ recipeHref(dataset, resolved, {
86
87
  ...nav,
87
88
  ...(category && category !== shown ? { type: category } : {}),
88
89
  ...(category ? {} : { id: undefined }),
89
90
  rpage: undefined,
90
91
  }),
91
92
  );
92
- }, [focusIndex, focusRes.pending, focusRes.value, index, nav, dataset, lang, recipeId, rows, shown]);
93
+ }, [focusIndex, focusRes.pending, focusRes.value, index, nav, dataset, resolved, recipeId, rows, shown]);
93
94
  const list = useFitPages(
94
95
  boxRef,
95
96
  feedRows,
@@ -109,13 +110,13 @@ export function TypeView({ session }: { session: RecipeSession }) {
109
110
  const row = allRows[next];
110
111
  if (focusIndex < 0 || !row) return;
111
112
  replaceUrlState(
112
- recipeHref(dataset, lang, { ...nav, id: row.id, rpage: undefined }),
113
+ recipeHref(dataset, resolved, { ...nav, id: row.id, rpage: undefined }),
113
114
  );
114
115
  return;
115
116
  }
116
117
  if (list.pages <= 1) return;
117
118
  replaceUrlState(
118
- recipeHref(dataset, lang, {
119
+ recipeHref(dataset, resolved, {
119
120
  ...nav,
120
121
  rpage: (list.page + dir + list.pages) % list.pages,
121
122
  }),
@@ -154,7 +155,7 @@ export function TypeView({ session }: { session: RecipeSession }) {
154
155
  onChange={(id) => {
155
156
  if (id === shown) return;
156
157
  replaceUrlState(
157
- recipeHref(dataset, lang, {
158
+ recipeHref(dataset, resolved, {
158
159
  ...nav,
159
160
  type: id,
160
161
  id: undefined,
@@ -0,0 +1,32 @@
1
+ import { Suspense } from 'react';
2
+ import { WorkspaceBody } from '@terrafirmagreg-team/ui/components/layouts/workspace';
3
+ import type {
4
+ SectionLandingProps,
5
+ SectionLandingView,
6
+ } from '@terrafirmagreg-team/kit/components/views/routes';
7
+ import type { RecipeSource } from '@terrafirmagreg-team/recipe/lib/source';
8
+ import {
9
+ RecipeBrowser,
10
+ RecipeBrowserFallback,
11
+ } from '@terrafirmagreg-team/recipe/components/views/browser';
12
+
13
+ export function recipeLanding({
14
+ page,
15
+ lang,
16
+ }: SectionLandingProps<RecipeSource>): SectionLandingView {
17
+ return {
18
+ node: (
19
+ <WorkspaceBody className="viewport-body">
20
+ <Suspense fallback={<RecipeBrowserFallback />}>
21
+ <RecipeBrowser
22
+ dataset={page.dataset.id}
23
+ datasetTitle={page.datasetTitle ?? page.dataset.id}
24
+ lang={lang}
25
+ versions={page.versions}
26
+ />
27
+ </Suspense>
28
+ </WorkspaceBody>
29
+ ),
30
+ workspace: { full: true, pagination: false },
31
+ };
32
+ }
@@ -0,0 +1,14 @@
1
+ import { Layout } from '@terrafirmagreg-team/kit/components/layouts/layout';
2
+ import type { SectionLayoutViewProps } from '@terrafirmagreg-team/kit/components/views/routes';
3
+ import { RecipeAxisSwitcher } from '@terrafirmagreg-team/recipe/components/views/browser/axis-switcher';
4
+ import { useRecipeLeftSidebarTree } from '@terrafirmagreg-team/recipe/hooks/use-left-sidebar-tree';
5
+
6
+ export function RecipeLayout(props: SectionLayoutViewProps) {
7
+ return (
8
+ <Layout
9
+ {...props}
10
+ useTree={useRecipeLeftSidebarTree}
11
+ sidebar={{ feature: RecipeAxisSwitcher }}
12
+ />
13
+ );
14
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useEffect, useMemo, useState } from 'react';
4
4
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
5
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
5
6
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
6
7
  import { recipeItemName } from '@terrafirmagreg-team/recipe/lib/client-index';
7
8
  import { useFluidColors } from '@terrafirmagreg-team/recipe/hooks/alloy/use-fluid-colors';
@@ -92,10 +93,11 @@ export function useMixState(recipe: AlloyRecipe, session: RecipeSession) {
92
93
  }
93
94
  }
94
95
 
96
+ const resolved = useResolvedLang();
95
97
  useEffect(() => {
96
98
  const mix = amounts.map((value) => trim(value)).join(';');
97
99
  replaceUrlState(
98
- recipeHref(session.dataset, session.lang, {
100
+ recipeHref(session.dataset, resolved, {
99
101
  tool: 'alloy',
100
102
  id: recipe.recipe.id,
101
103
  tab: session.tab,
@@ -108,7 +110,7 @@ export function useMixState(recipe: AlloyRecipe, session: RecipeSession) {
108
110
  amounts,
109
111
  recipe.recipe.id,
110
112
  session.dataset,
111
- session.lang,
113
+ resolved,
112
114
  session.tab,
113
115
  ]);
114
116
  const mix = useMemo(
@@ -21,13 +21,12 @@ import { useCalcResolver } from './use-resolver';
21
21
  import { useRecipeDefaults } from './use-defaults';
22
22
 
23
23
  export function useCalcData(session: RecipeSession) {
24
- const { dataset, lang } = session;
24
+ const { dataset } = session;
25
25
  const catalog = session.index;
26
26
  const storageKey = calcStorageKey('recipe', dataset);
27
27
  const sharePending = useCalcShare({
28
28
  storageKey,
29
29
  dataset,
30
- lang,
31
30
  incoming: session.tree ?? '',
32
31
  });
33
32
  const {
@@ -8,18 +8,17 @@ import {
8
8
  writeCalcTabs,
9
9
  } from '@terrafirmagreg-team/recipe/lib/calc/storage';
10
10
  import { recipeCalcHref } from '@terrafirmagreg-team/recipe/lib/links';
11
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
11
12
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
12
13
  import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
13
14
 
14
15
  export function useCalcShare({
15
16
  storageKey,
16
17
  dataset,
17
- lang,
18
18
  incoming,
19
19
  }: {
20
20
  storageKey: string;
21
21
  dataset: DatasetRef;
22
- lang: string;
23
22
  incoming: string;
24
23
  }): boolean {
25
24
  const isShareId = incoming.startsWith('s');
@@ -44,6 +43,7 @@ export function useCalcShare({
44
43
  };
45
44
  }, [isShareId, incoming, dataset]);
46
45
  const transport = isShareId ? sharedTree : incoming || null;
46
+ const resolved = useResolvedLang();
47
47
 
48
48
  useEffect(() => {
49
49
  if (transport === null) return;
@@ -56,8 +56,8 @@ export function useCalcShare({
56
56
  entry.id,
57
57
  );
58
58
  }
59
- if (incoming) replaceUrlState(recipeCalcHref(dataset, lang));
60
- }, [transport, storageKey, dataset, lang, incoming]);
59
+ if (incoming) replaceUrlState(recipeCalcHref(dataset, resolved));
60
+ }, [transport, storageKey, dataset, resolved, incoming]);
61
61
 
62
62
  return isShareId && sharedTree === null;
63
63
  }
@@ -6,11 +6,13 @@ import {
6
6
  encodeCalcState,
7
7
  } from '@terrafirmagreg-team/recipe/lib/calc/tree';
8
8
  import { recipeCalcHref } from '@terrafirmagreg-team/recipe/lib/links';
9
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
9
10
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
10
11
  import type { RecipeSession } from '@terrafirmagreg-team/recipe/types';
11
12
 
12
13
  export function useAddToCalc(session: RecipeSession) {
13
- const { dataset, lang, tree } = session;
14
+ const { dataset, tree } = session;
15
+ const resolved = useResolvedLang();
14
16
  return useCallback(
15
17
  (item: string, kind: 'item' | 'fluid') => {
16
18
  const state = decodeCalcState(tree ?? '') ?? {
@@ -40,12 +42,12 @@ export function useAddToCalc(session: RecipeSession) {
40
42
  replaceUrlState(
41
43
  recipeCalcHref(
42
44
  dataset,
43
- lang,
45
+ resolved,
44
46
  encodeCalcState({ ...state, cards }),
45
47
  ),
46
48
  );
47
49
  },
48
- [tree, dataset, lang],
50
+ [tree, dataset, resolved],
49
51
  );
50
52
  }
51
53
 
@@ -4,12 +4,12 @@ import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
4
4
  import { createElement, useMemo } from 'react';
5
5
  import { ArrowDownToLine, ArrowUpFromLine, Tag } from 'lucide-react';
6
6
  import { useTranslations } from '@terrafirmagreg-team/translate/hooks/use-translations';
7
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
7
8
  import { usePaneKeys } from '@terrafirmagreg-team/ui/hooks/use-pane-keys';
8
9
  import { recipeHref } from '@terrafirmagreg-team/recipe/lib/links';
9
10
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
10
11
  import { EMPTY_ROWS } from '@terrafirmagreg-team/recipe/hooks/use-item-feeds';
11
12
  import type { PaneTabOption } from '@terrafirmagreg-team/recipe/components/views/browser/pane-tabs';
12
- import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
13
13
  import type {
14
14
  RecipeCompactRow,
15
15
  RecipeHrefOpts,
@@ -23,7 +23,6 @@ const inFeed = (id: string | undefined, rows: RecipeCompactRow[] | undefined) =>
23
23
 
24
24
  export function useItemPane({
25
25
  dataset,
26
- lang,
27
26
  nav,
28
27
  relation,
29
28
  recipeId,
@@ -33,7 +32,6 @@ export function useItemPane({
33
32
  feedsPending,
34
33
  }: {
35
34
  dataset: DatasetRef;
36
- lang: Lang;
37
35
  nav: RecipeHrefOpts;
38
36
  relation?: RecipeRelation;
39
37
  recipeId?: string;
@@ -43,6 +41,7 @@ export function useItemPane({
43
41
  feedsPending: boolean;
44
42
  }) {
45
43
  const t = useTranslations();
44
+ const resolved = useResolvedLang();
46
45
  const available = {
47
46
  recipes: (recipes ?? EMPTY_ROWS).length > 0,
48
47
  uses: (uses ?? EMPTY_ROWS).length > 0,
@@ -60,7 +59,7 @@ export function useItemPane({
60
59
  relation && (feedsPending || available[relation]) ? relation : fallback;
61
60
  const select = (next: ItemPane) => {
62
61
  replaceUrlState(
63
- recipeHref(dataset, lang, {
62
+ recipeHref(dataset, resolved, {
64
63
  ...nav,
65
64
  relation: next === 'recipes' ? undefined : next,
66
65
  rpage: undefined,
@@ -9,21 +9,20 @@ import {
9
9
  } from '@terrafirmagreg-team/recipe/lib/calc/storage';
10
10
  import { requestCalcFocus } from '@terrafirmagreg-team/recipe/lib/calc/focus';
11
11
  import { recipeHref } from '@terrafirmagreg-team/recipe/lib/links';
12
+ import { useResolvedLang } from '@terrafirmagreg-team/translate/hooks/use-resolved-lang';
12
13
  import { replaceUrlState } from '@terrafirmagreg-team/ui/lib/utils/history';
13
- import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
14
14
  import type { RecipeHrefOpts } from '@terrafirmagreg-team/recipe/types';
15
15
 
16
16
  export function useItemPress({
17
17
  dataset,
18
- lang,
19
18
  nav,
20
19
  isCalc,
21
20
  }: {
22
21
  dataset: DatasetRef;
23
- lang: Lang;
24
22
  nav: RecipeHrefOpts;
25
23
  isCalc: boolean;
26
24
  }) {
25
+ const resolved = useResolvedLang();
27
26
  const pressRef = useRef<(id: string, ref?: 'item' | 'fluid') => void>(
28
27
  () => {},
29
28
  );
@@ -67,7 +66,7 @@ export function useItemPress({
67
66
  return;
68
67
  }
69
68
  replaceUrlState(
70
- recipeHref(dataset, lang, {
69
+ recipeHref(dataset, resolved, {
71
70
  ...nav,
72
71
  type: undefined,
73
72
  tool: undefined,