mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-28 07:32:52 +00:00
Every word the landing, the header menus, the phone sheet, the footer,
the help corner and the way in (sign-in, sign-up, the reset, the
invitation, the callback, onboarding, the 404) write goes through
@hanzo/i18n's t(): one sentence is one message, its figures, names and
links arguments; copy written as data is phrase('…') where written and
t(label) where drawn. Plans, the chart, the API states and the lines
lib/kai and lib/enso build for the landing do the same.
Right to left: <html lang dir> is set before the first paint (the
package's bootScript first in the head); a figure, clock, range or
price outside a sentence is isolated; sides are logical gui props, the
layout's [data-join] corners logical, a bar grows from the start;
arrows along the line mirror (Onward for "words ->" links). The repo
dates read in the reader's language.
Gates select by slot, never by an English label (rtl, help). New gate
translated.spec.ts: in Arabic the landing at 1440 and 390, every menu
open, the phone sheet, sign-in, sign-up and the app signed in hold no
authored English, nothing scrolls sideways, every range is isolated;
French the same for English's commonest words. What another package
draws with no words prop is listed by name (@hanzo/ui's Footer label,
@hanzo/build's composer row and suggestions).
@hanzo/i18n 0.5.3 (the catalogs: 1,443 keys, every offered locale
complete), @hanzo/app 0.2.1 (the app's words). The link gate imports
the terms versions from @hanzo/app, the one SDK main now resolves.
33 lines
1.3 KiB
TypeScript
33 lines
1.3 KiB
TypeScript
'use client'
|
|
|
|
import { useMemo } from 'react'
|
|
import { useIamToken } from '@hanzo/iam/react'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
import { speech, type Speech } from '@hanzo/voice'
|
|
import { base } from '@hanzo/app/lib/ai'
|
|
|
|
/**
|
|
* Hanzo's transcriber for whoever is reading: their own metered lane when they are
|
|
* signed in, the visitor's lane when they are not.
|
|
*
|
|
* The visitor's lane (`speech({ public: true })`) is Hanzo's own transcriber with no
|
|
* credential, a minute at a time within a day per visitor. Past the day it refuses,
|
|
* the browser's recogniser takes over and the mic's label says the free day is used.
|
|
* `base()` is the one place the chat client reads its host from, so a local cloud
|
|
* points both.
|
|
*/
|
|
export function useEar(): Speech {
|
|
const { token } = useIamToken()
|
|
return useMemo(() => speech({ ...base(), ...(token ? { token } : { public: true }) }), [token])
|
|
}
|
|
|
|
/**
|
|
* What the microphone says in each state, in the reader's language: @hanzo/voice's
|
|
* `Voice` takes them as `says`, and its own are English. A refusal the platform
|
|
* gives is the package's and is appended as it comes.
|
|
*/
|
|
export function useSays(): { idle: string; listening: string; speaking: string } {
|
|
const { t } = useI18n()
|
|
return { idle: t('Talk to Hanzo'), listening: t('Listening — click to stop'), speaking: t('Speaking — talk to interrupt') }
|
|
}
|