File size: 4,891 Bytes
f0d8b62
84d1bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df2081a
84d1bc5
 
 
 
 
 
 
 
 
 
 
 
8c64fe1
84d1bc5
 
 
8c64fe1
 
 
 
84d1bc5
8c64fe1
 
84d1bc5
df2081a
 
 
 
 
 
 
 
 
84d1bc5
 
 
8c64fe1
 
 
 
 
 
 
 
 
 
 
 
 
84d1bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c64fe1
 
 
 
 
 
84d1bc5
 
 
 
 
 
 
 
 
 
 
 
 
 
17167cf
84d1bc5
f0d8b62
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
  <meta name="theme-color" content="#f4efe6" />
  <meta name="description" content="Paste text and listen. Speech is generated on your device." />
  <title>Phonon Reader</title>
  <link rel="manifest" href="./manifest.webmanifest" />
  <link rel="icon" type="image/png" href="./icons/icon-192.png" />
  <link rel="apple-touch-icon" href="./icons/icon-192.png" />
  <link rel="stylesheet" href="./src/style.css" />
  <script type="importmap">{ "imports": { "phonon-tts": "./vendor/phonon-tts/index.js" } }</script>
</head>
<body>
  <header class="top">
    <h1>Reader</h1>
    <div class="top-actions">
      <span id="net" class="pill" aria-live="polite"></span>
      <button id="btn-edit" class="ghost hidden" type="button">Edit</button>
      <button id="btn-settings" class="ghost" type="button" aria-label="Settings">Settings</button>
    </div>
  </header>

  <div id="model-bar" class="model-bar">
    <div class="model-text" id="model-text">Loading speech model…</div>
    <div class="progress"><div id="model-progress"></div></div>
  </div>

  <main>
    <section id="view-edit">
      <input id="title" class="title-input" type="text" placeholder="Title (optional, used for the file name)" autocomplete="off" />
      <textarea id="input" spellcheck="false"
        placeholder="Paste an article or any text here. Pasting from a web page keeps the paragraphs and drops menus and scripts."></textarea>
      <p id="share-note" class="note hidden"></p>
      <div class="edit-tools">
        <button id="btn-paste" class="ghost small" type="button">Paste</button>
        <button id="btn-clear" class="ghost small" type="button">Clear</button>
      </div>
      <div class="edit-actions">
        <button id="btn-listen" class="ghost" type="button">Listen now</button>
        <button id="btn-convert-start" class="primary" type="button">Convert to audio</button>
      </div>
      <div id="ready" class="ready">
        <div class="ready-title" id="ready-title">Checking what's saved on this device…</div>
        <ul class="ready-list">
          <li id="r-app">App</li>
          <li id="r-model">Speech model</li>
          <li id="r-voice">Voice</li>
        </ul>
        <p class="note" id="ready-note">Speech is generated on this device. Your text is never uploaded.</p>
      </div>
    </section>

    <section id="view-read" class="hidden">
      <div id="export" class="export">
        <div class="export-head">
          <strong id="ex-title"></strong>
          <span id="ex-meta" class="ex-meta"></span>
        </div>
        <div id="ex-bar" class="progress big hidden"><div id="ex-progress"></div></div>
        <div class="export-actions">
          <button id="btn-convert" class="primary" type="button">Convert to audio file</button>
          <button id="btn-share" class="primary hidden" type="button">Share…</button>
          <button id="btn-download" class="ghost hidden" type="button">Download</button>
        </div>
        <p id="ex-note" class="note"></p>
      </div>
      <article id="reader" class="reader"></article>
    </section>
  </main>

  <footer id="player" class="player hidden">
    <div class="status" id="status"></div>
    <div class="controls">
      <button id="btn-prev" class="round" type="button" aria-label="Previous sentence">⏮</button>
      <button id="btn-play" class="round big" type="button" aria-label="Play">▶</button>
      <button id="btn-next" class="round" type="button" aria-label="Next sentence">⏭</button>
    </div>
  </footer>

  <dialog id="settings">
    <form method="dialog" class="settings">
      <h2>Settings</h2>
      <label>Voice
        <select id="voice"><option value="">Default</option></select>
      </label>
      <label>Speed <span id="rate-label">1.0×</span>
        <input id="rate" type="range" min="0.7" max="2" step="0.1" value="1" />
      </label>
      <label>File format
        <select id="format">
          <option value="mp3">MP3 (small, plays everywhere)</option>
          <option value="wav">WAV (lossless, ~6× larger)</option>
        </select>
      </label>
      <label>Engine
        <select id="device">
          <option value="cpu">CPU (recommended on phones)</option>
          <option value="auto">GPU if available</option>
        </select>
      </label>
      <p id="engine-info" class="note"></p>
      <button id="btn-clear-cache" type="button" class="ghost danger">Delete downloaded model</button>
      <div class="dialog-actions"><button class="primary" value="close">Done</button></div>
    </form>
  </dialog>

  <audio id="audio" preload="auto"></audio>
  <script type="module" src="./src/main.js"></script>
  <script type="module" src="./src/update.js"></script>
</body>
</html>