mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
Split useTranslation into state + actions via useBetween singleton
Same pattern as the wired-tools split: 600-line useTranslation backs 6 consumers with a wide state + action surface. Split along the read/write seam: - useTranslationStore (internal, was the inner useTranslationState) — the previous singleton body, untouched except for the rename and a doc-comment. - useTranslationState (public, read-only) — useBetween filter exposing settings, the supported-languages list, the loading/loaded flags, the detected-language tags, lastError, and the pure getLanguageName helper. - useTranslationActions (public, imperative) — same singleton filter exposing updateSettings, ensureSupportedLanguagesLoaded, the four translate/queue helpers. Also re-exposes 'settings' because most call sites need 'if(settings.enabled)' before dispatching. - useTranslation (deprecated shim) — composes the singleton via useBetween, preserving the historical full-shape return. applyTextTranslationLocale stays exported from the same module path so LoginView's import keeps working. Updates docs/ARCHITECTURE.md proposal #4 section to list the three new splits (chat-input + wired-tools + translation) alongside the previous five.
This commit is contained in:
@@ -387,6 +387,24 @@ The current branch (**`feat/react19-modernization`**, PR #2) has applied:
|
|||||||
bridges + 1 derive effect) + `useFriendRequestActions` (thin
|
bridges + 1 derive effect) + `useFriendRequestActions` (thin
|
||||||
adapter on the friends store) + shim. Exports `ActiveFriendRequest`
|
adapter on the friends store) + shim. Exports `ActiveFriendRequest`
|
||||||
type.
|
type.
|
||||||
|
- **chat input**: `useChatInputState` (5 state slices + 3 event
|
||||||
|
listeners + 3 lifecycle effects: flood countdown, idle auto-clear,
|
||||||
|
typing-indicator sync) + `useChatInputActions` (`sendChat` with
|
||||||
|
the full slash-command repertoire and the outgoing-translation
|
||||||
|
pipeline) + shim. Single consumer (`ChatInputView`) keeps the
|
||||||
|
original tuple.
|
||||||
|
- **wired tools**: `useWiredToolsStore` (internal singleton — state,
|
||||||
|
listeners, effects, 13 actions in one closure) + `useWiredToolsState`
|
||||||
|
/ `useWiredToolsActions` (read-only and imperative `useBetween`
|
||||||
|
filters over the same singleton) + `useWiredTools` shim. Used by
|
||||||
|
~20 consumers; the singleton sharing keeps a single source of
|
||||||
|
truth while letting consumers import only the slice they touch.
|
||||||
|
- **translation**: `useTranslationStore` (internal singleton) +
|
||||||
|
`useTranslationState` / `useTranslationActions` (filtered
|
||||||
|
`useBetween` views) + `useTranslation` shim. Same pattern as
|
||||||
|
Wired tools — six consumers split across read-only views
|
||||||
|
(settings panel, bootstrap) and dispatch sites (messenger, chat
|
||||||
|
input).
|
||||||
- **Zustand** (proposal #5) — **enabled**. `zustand` installed; factory at
|
- **Zustand** (proposal #5) — **enabled**. `zustand` installed; factory at
|
||||||
`src/state/createNitroStore.ts`. First adoption: the `let isCreatingRoom`
|
`src/state/createNitroStore.ts`. First adoption: the `let isCreatingRoom`
|
||||||
/ `createRoomTimeout` module-level pair in `NavigatorRoomCreatorView`
|
/ `createRoomTimeout` module-level pair in `NavigatorRoomCreatorView`
|
||||||
|
|||||||
@@ -228,7 +228,17 @@ const resolveSupportedLanguage = (value: string, languages: ITranslationLanguage
|
|||||||
return languages[0].code;
|
return languages[0].code;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useTranslationState = () =>
|
/**
|
||||||
|
* Internal singleton state + actions hook. Public consumers should
|
||||||
|
* call useTranslationState (read-only) or useTranslationActions
|
||||||
|
* (imperative) instead. useTranslation is the deprecated shim that
|
||||||
|
* composes both.
|
||||||
|
*
|
||||||
|
* Wrapped in useBetween at each public-hook layer so every consumer
|
||||||
|
* in the tree sees the same instance (preserves the previous
|
||||||
|
* useBetween(useTranslationState) behavior).
|
||||||
|
*/
|
||||||
|
const useTranslationStore = () =>
|
||||||
{
|
{
|
||||||
const defaultTargetLanguage = getBrowserLanguageCode();
|
const defaultTargetLanguage = getBrowserLanguageCode();
|
||||||
const [ settings, setSettings ] = useLocalStorage<ITranslationSettings>(LocalStorageKeys.CHAT_TRANSLATION_SETTINGS, {
|
const [ settings, setSettings ] = useLocalStorage<ITranslationSettings>(LocalStorageKeys.CHAT_TRANSLATION_SETTINGS, {
|
||||||
@@ -597,4 +607,79 @@ const useTranslationState = () =>
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useTranslation = () => useBetween(useTranslationState);
|
/**
|
||||||
|
* Read-only slice of the translation store: persisted settings, the
|
||||||
|
* supported languages list, the loading/loaded flags, the last
|
||||||
|
* incoming/outgoing detected language tags, and the last error message
|
||||||
|
* surfaced to the UI.
|
||||||
|
*
|
||||||
|
* Components that only render translation state subscribe here.
|
||||||
|
*/
|
||||||
|
export const useTranslationState = () =>
|
||||||
|
{
|
||||||
|
const {
|
||||||
|
settings,
|
||||||
|
supportedLanguages,
|
||||||
|
availableTextLocales,
|
||||||
|
languagesLoading,
|
||||||
|
languagesLoaded,
|
||||||
|
localizationTextsLoading,
|
||||||
|
lastIncomingLanguage,
|
||||||
|
lastOutgoingLanguage,
|
||||||
|
lastError,
|
||||||
|
getLanguageName
|
||||||
|
} = useBetween(useTranslationStore);
|
||||||
|
|
||||||
|
return {
|
||||||
|
settings,
|
||||||
|
supportedLanguages,
|
||||||
|
availableTextLocales,
|
||||||
|
languagesLoading,
|
||||||
|
languagesLoaded,
|
||||||
|
localizationTextsLoading,
|
||||||
|
lastIncomingLanguage,
|
||||||
|
lastOutgoingLanguage,
|
||||||
|
lastError,
|
||||||
|
getLanguageName
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imperative slice of the translation store: settings mutation,
|
||||||
|
* supported-languages refresh, the translate* helpers, and the
|
||||||
|
* outgoing-queue write/read pair. Stays separate so components that
|
||||||
|
* only invoke actions (e.g. ChatInputActions) don't pull the full
|
||||||
|
* state shape.
|
||||||
|
*/
|
||||||
|
export const useTranslationActions = () =>
|
||||||
|
{
|
||||||
|
const {
|
||||||
|
settings,
|
||||||
|
updateSettings,
|
||||||
|
ensureSupportedLanguagesLoaded,
|
||||||
|
translateIncoming,
|
||||||
|
translateOutgoing,
|
||||||
|
enqueueOutgoingTranslation,
|
||||||
|
consumeOutgoingTranslation
|
||||||
|
} = useBetween(useTranslationStore);
|
||||||
|
|
||||||
|
return {
|
||||||
|
// settings is exposed here too because most action call sites
|
||||||
|
// need `if(settings.enabled)` checks before dispatching.
|
||||||
|
settings,
|
||||||
|
updateSettings,
|
||||||
|
ensureSupportedLanguagesLoaded,
|
||||||
|
translateIncoming,
|
||||||
|
translateOutgoing,
|
||||||
|
enqueueOutgoingTranslation,
|
||||||
|
consumeOutgoingTranslation
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Prefer `useTranslationState` (read-only) and
|
||||||
|
* `useTranslationActions` (imperative) directly. This shim composes
|
||||||
|
* both into the historical `useTranslation()` shape so the six
|
||||||
|
* existing consumers keep working unchanged.
|
||||||
|
*/
|
||||||
|
export const useTranslation = () => useBetween(useTranslationStore);
|
||||||
|
|||||||
Reference in New Issue
Block a user