popup: teach how to use (gestures + live-mode voice command) in text and narration
Browse files- frontend/app.js +11 -5
- frontend/index.html +2 -1
- frontend/style.css +1 -0
frontend/app.js
CHANGED
|
@@ -4,8 +4,9 @@ const cam = $("cam"), canvas = $("canvas"), statusEl = $("status"),
|
|
| 4 |
player = $("player"), stage = $("stage"),
|
| 5 |
btnAsk = $("btn-ask"), btnDescribe = $("btn-describe"),
|
| 6 |
btnLive = $("btn-live"), a11yBtn = $("a11y");
|
| 7 |
-
const intro = $("intro"), introBodyEl = $("intro-body"),
|
| 8 |
-
|
|
|
|
| 9 |
introReplay = $("intro-replay"), introHintEl = $("intro-hint");
|
| 10 |
|
| 11 |
function vibrate(ms) { try { navigator.vibrate && navigator.vibrate(ms); } catch (e) {} }
|
|
@@ -20,7 +21,9 @@ const T = {
|
|
| 20 |
langListen: "Listening… say your language",
|
| 21 |
welcome: "Welcome to Iris. Tap the screen to describe what is in front of you. Hold to ask a question. Double-tap to turn live mode on or off, which announces new things around you.",
|
| 22 |
liveOn: "Live mode on.", liveOff: "Live mode off.", confLang: "English selected.",
|
| 23 |
-
introBody: "This is Iris, your eyes by voice.
|
|
|
|
|
|
|
| 24 |
introClose: "Close", introVideo: "Watch the demo", introHint: "Say \"close\" or tap the button",
|
| 25 |
bAsk: "Ask", bDescribe: "Describe", bLive: "Live" },
|
| 26 |
pt: { idle: "Iris", listening: "Ouvindo…", thinking: "Pensando…",
|
|
@@ -29,7 +32,9 @@ const T = {
|
|
| 29 |
langListen: "Ouvindo… diga seu idioma",
|
| 30 |
welcome: "Bem-vindo ao Iris. Toque na tela para descrever o que está à sua frente. Segure para fazer uma pergunta. Toque duas vezes para ligar ou desligar o modo ao vivo, que avisa o que aparece de novo à sua volta.",
|
| 31 |
liveOn: "Modo ao vivo ligado.", liveOff: "Modo ao vivo desligado.", confLang: "Português selecionado.",
|
| 32 |
-
introBody: "Este é o Iris, os seus olhos por voz.
|
|
|
|
|
|
|
| 33 |
introClose: "Fechar", introVideo: "Ver o vídeo", introHint: "Diga \"fechar\" ou toque no botão",
|
| 34 |
bAsk: "Perguntar", bDescribe: "Descrever", bLive: "Ao vivo" },
|
| 35 |
};
|
|
@@ -170,6 +175,7 @@ const CLOSE_WORDS = /\b(close|fechar|ok|okay|start|begin|continue|continuar|come
|
|
| 170 |
|
| 171 |
function renderIntro() {
|
| 172 |
introBodyEl.textContent = t("introBody");
|
|
|
|
| 173 |
introCloseBtn.textContent = t("introClose");
|
| 174 |
introVideo.textContent = t("introVideo");
|
| 175 |
introVideo.href = DEMO_VIDEO_URL;
|
|
@@ -212,7 +218,7 @@ function speakIntro(force) {
|
|
| 212 |
unlockAudio();
|
| 213 |
try {
|
| 214 |
speechSynthesis.cancel();
|
| 215 |
-
const u = new SpeechSynthesisUtterance(t("
|
| 216 |
u.lang = lang === "pt" ? "pt-BR" : "en-US";
|
| 217 |
u.onstart = () => {
|
| 218 |
introSpokenSession = true;
|
|
|
|
| 4 |
player = $("player"), stage = $("stage"),
|
| 5 |
btnAsk = $("btn-ask"), btnDescribe = $("btn-describe"),
|
| 6 |
btnLive = $("btn-live"), a11yBtn = $("a11y");
|
| 7 |
+
const intro = $("intro"), introBodyEl = $("intro-body"), introHowEl = $("intro-how"),
|
| 8 |
+
introCloseBtn = $("intro-close"), introVideo = $("intro-video"),
|
| 9 |
+
introEn = $("intro-en"), introPt = $("intro-pt"),
|
| 10 |
introReplay = $("intro-replay"), introHintEl = $("intro-hint");
|
| 11 |
|
| 12 |
function vibrate(ms) { try { navigator.vibrate && navigator.vibrate(ms); } catch (e) {} }
|
|
|
|
| 21 |
langListen: "Listening… say your language",
|
| 22 |
welcome: "Welcome to Iris. Tap the screen to describe what is in front of you. Hold to ask a question. Double-tap to turn live mode on or off, which announces new things around you.",
|
| 23 |
liveOn: "Live mode on.", liveOff: "Live mode off.", confLang: "English selected.",
|
| 24 |
+
introBody: "This is Iris, your eyes by voice. It reads your money, your bills, and your medicine, out loud.",
|
| 25 |
+
introHow: "Tap to describe · Hold to ask · Double-tap (or say \"live mode\") for live mode",
|
| 26 |
+
introSpeak: "This is Iris, your eyes by voice. It reads your money, bills, and medicine out loud. To use it: tap the screen to describe what is in front of you, hold and speak to ask a question, and double-tap, or say live mode, to turn live mode on or off. To close this, say close, or tap the big button.",
|
| 27 |
introClose: "Close", introVideo: "Watch the demo", introHint: "Say \"close\" or tap the button",
|
| 28 |
bAsk: "Ask", bDescribe: "Describe", bLive: "Live" },
|
| 29 |
pt: { idle: "Iris", listening: "Ouvindo…", thinking: "Pensando…",
|
|
|
|
| 32 |
langListen: "Ouvindo… diga seu idioma",
|
| 33 |
welcome: "Bem-vindo ao Iris. Toque na tela para descrever o que está à sua frente. Segure para fazer uma pergunta. Toque duas vezes para ligar ou desligar o modo ao vivo, que avisa o que aparece de novo à sua volta.",
|
| 34 |
liveOn: "Modo ao vivo ligado.", liveOff: "Modo ao vivo desligado.", confLang: "Português selecionado.",
|
| 35 |
+
introBody: "Este é o Iris, os seus olhos por voz. Ele lê o seu dinheiro, suas contas e seus remédios, em voz alta.",
|
| 36 |
+
introHow: "Toque para descrever · Segure para perguntar · Toque duplo (ou diga \"modo ao vivo\") para o modo ao vivo",
|
| 37 |
+
introSpeak: "Este é o Iris, os seus olhos por voz. Ele lê o seu dinheiro, suas contas e seus remédios em voz alta. Para usar: toque na tela para descrever o que está à sua frente, segure e fale para fazer uma pergunta, e toque duas vezes, ou diga modo ao vivo, para ligar ou desligar o modo ao vivo. Para fechar, diga fechar, ou toque no botão grande.",
|
| 38 |
introClose: "Fechar", introVideo: "Ver o vídeo", introHint: "Diga \"fechar\" ou toque no botão",
|
| 39 |
bAsk: "Perguntar", bDescribe: "Descrever", bLive: "Ao vivo" },
|
| 40 |
};
|
|
|
|
| 175 |
|
| 176 |
function renderIntro() {
|
| 177 |
introBodyEl.textContent = t("introBody");
|
| 178 |
+
introHowEl.textContent = t("introHow");
|
| 179 |
introCloseBtn.textContent = t("introClose");
|
| 180 |
introVideo.textContent = t("introVideo");
|
| 181 |
introVideo.href = DEMO_VIDEO_URL;
|
|
|
|
| 218 |
unlockAudio();
|
| 219 |
try {
|
| 220 |
speechSynthesis.cancel();
|
| 221 |
+
const u = new SpeechSynthesisUtterance(t("introSpeak"));
|
| 222 |
u.lang = lang === "pt" ? "pt-BR" : "en-US";
|
| 223 |
u.onstart = () => {
|
| 224 |
introSpokenSession = true;
|
frontend/index.html
CHANGED
|
@@ -71,7 +71,8 @@
|
|
| 71 |
</svg>
|
| 72 |
</button>
|
| 73 |
<h2 id="intro-title">Iris</h2>
|
| 74 |
-
<p id="intro-body">This is Iris, your eyes by voice.
|
|
|
|
| 75 |
<div class="intro-langs" role="group" aria-label="Language">
|
| 76 |
<button id="intro-en" class="intro-lang">EN</button>
|
| 77 |
<button id="intro-pt" class="intro-lang">PT</button>
|
|
|
|
| 71 |
</svg>
|
| 72 |
</button>
|
| 73 |
<h2 id="intro-title">Iris</h2>
|
| 74 |
+
<p id="intro-body">This is Iris, your eyes by voice. It reads your money, your bills, and your medicine, out loud.</p>
|
| 75 |
+
<p id="intro-how" class="intro-how">Tap to describe · Hold to ask · Double-tap (or say "live mode") for live mode</p>
|
| 76 |
<div class="intro-langs" role="group" aria-label="Language">
|
| 77 |
<button id="intro-en" class="intro-lang">EN</button>
|
| 78 |
<button id="intro-pt" class="intro-lang">PT</button>
|
frontend/style.css
CHANGED
|
@@ -200,6 +200,7 @@ body[data-state=""] #status, body:not([data-state]) #status { letter-spacing: .0
|
|
| 200 |
|
| 201 |
#intro-title { font-family: var(--font-display); font-weight: 700; font-size: clamp(28px, 7vmin, 40px); letter-spacing: .04em; }
|
| 202 |
#intro-body { font-family: var(--font-body); font-size: clamp(16px, 4vmin, 19px); line-height: 1.5; color: var(--fg); max-width: 34ch; }
|
|
|
|
| 203 |
|
| 204 |
.intro-langs { display: flex; gap: 10px; }
|
| 205 |
.intro-lang {
|
|
|
|
| 200 |
|
| 201 |
#intro-title { font-family: var(--font-display); font-weight: 700; font-size: clamp(28px, 7vmin, 40px); letter-spacing: .04em; }
|
| 202 |
#intro-body { font-family: var(--font-body); font-size: clamp(16px, 4vmin, 19px); line-height: 1.5; color: var(--fg); max-width: 34ch; }
|
| 203 |
+
.intro-how { font-family: var(--font-body); font-size: 14px; line-height: 1.6; color: var(--muted); max-width: 32ch; }
|
| 204 |
|
| 205 |
.intro-langs { display: flex; gap: 10px; }
|
| 206 |
.intro-lang {
|