Work on header and buttons
Committed dbb048
--- a/canopy/static/screen.css
+++ b/canopy/static/screen.css
margin-bottom: 1em; }
body > header > div:last-child {
text-align: right; }
+body > header > div > div > * {
+ display: inline-block; }
article#content {
grid-column: 2;
margin-bottom: 1em; }
a {
- color: #268bd2; }
+ color: #268bd2;
+ text-decoration: none; }
a:visited {
color: #6c71c4; }
color: #586e75; }
p.p-note {
margin-top: .25em; }
-#search {
- margin: 0 0 .5em 0; }
.breadcrumbs {
font-size: .8em; }
textarea {
padding: .5em; }
button {
- background-color: #93a1a1;
+ background-color: #586e75;
border: .2em outset #586e75;
border-radius: .25em;
color: #002b36;
--- a/canopy/templates/template.html
+++ b/canopy/templates/template.html
content=initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width>
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black-translucent>
-<!--link rel=icon href=/static/photo.png-->
+$if "photo" in owner:
+ <link rel=icon href=/media/$owner["photo"][0]>
$if not tx.request.uri.path:
<link rel=manifest href=/manifest.json>
<link rel=stylesheet href=/chats/mediasoup-demo-app.css>
<header>
<div class=h-card>
-$if "photo" in owner:
- <img class=u-photo src=/media/$owner["photo"][0]>
-<div class=namedesc>
-<a class=p-name href=/><strong>$owner["name"][0]</strong></a><br>
-$if "note" in owner:
- <span class=p-note>$owner["note"][0]</span><br>
-<small class=identifiers>
-$if email := get_first(owner, "email"):
- <a class=u-email
- href=mailto:$owner["email"][0]><code>$owner["email"][0]</code></a> •
-$if onion := get_onion():
- $ _stripped_onion = onion.lstrip("x")
- $ _prefix_length = len(onion) - len(_stripped_onion)
- <a class=u-url rel=me
- href=http://$onion><code>@$_stripped_onion[:12-_prefix_length]</code></a> •
-<code><a class="u-url u-uid" rel=me href=/>@$tx.host.name</code>
-• <a href=/owner/actor><code>@$owner["nickname"][0]@$tx.host.name</code></a>
-$if key := get_key():
- • <a class=p-key href=/owner/keyring><code>$:"–".join(key.split()[:2])</code></a>
-</small>
-</div>
+ $if "photo" in owner:
+ <img class=u-photo src=/media/$owner["photo"][0]>
+ <div class=namedesc>
+ <a class=p-name href=/><strong>$owner["name"][0]</strong></a><br>
+ $if "note" in owner:
+ <span class=p-note>$owner["note"][0]</span><br>
+ <small class=identifiers>
+ $if email := get_first(owner, "email"):
+ <a class=u-email
+ href=mailto:$owner["email"][0]><code>$owner["email"][0]</code></a> •
+ $if onion := get_onion():
+ $ _stripped_onion = onion.lstrip("x")
+ $ _prefix_length = len(onion) - len(_stripped_onion)
+ <a class=u-url rel=me
+ href=http://$onion><code>@$_stripped_onion[:12-_prefix_length]</code></a> •
+ <code><a class="u-url u-uid" rel=me href=/>@$tx.host.name</code>
+ $if nickname := get_first(owner, "nickname"):
+ • <a href=/owner/actor><code>@$nickname@$tx.host.name</code></a>
+ $if key := get_key():
+ • <a class=p-key href=/owner/keyring><code>$:"–".join(key.split()[:2])</code></a>
+ </small>
+ </div>
</div>
<div>
-<form id=search action=/search>
- <input name=q type=text> <button>Search</button>
-</form>
-<div id=assistant>
- <span class=partial></span>
- <button>Activate Assistant</button>
-</div>
+ <form id=search action=/search>
+ <input class=partial name=q type=text> <button>Query</button>
+ </form>
+ <button id=listen>Listen for Queries</button>
</div>
</header>
$continue
<li><a href=/$mount_app.prefix>$mount_name.capitalize()</a></li>
</ul>
-<p class=system><a class=systemtext href=/system
- title=system><span>System</span></a></p>
-</nav>
-
-<aside>
-$:livestream()
-
-<div id=chat>
- <button>Enter Room</button>
- <div id=mediasoup-demo-app-media-query-detector></div>
- <div id=mediasoup-demo-app-container></div>
-</div>
$if tx.user.is_owner:
- <form action=/owner/sign-out method=post>
+ <form id=identity action=/owner/sign-out method=post>
<button>Sign Out</button>
</form>
$elif "session" in tx.user and tx.user.session.get("uid", None):
<p>Signed in as <a
href=$tx.user.session["uid"][0]>$tx.user.session["name"][0]</a>.</p>
- <form action=/guests/sign-out method=post>
+ <form id=identity action=/guests/sign-out method=post>
<button>Sign Out</button>
</form>
$else:
- <form action=/guests/sign-in style="margin:1em 0">
- <input name=me type=text> <button>Sign In</button>
+ <form id=identity action=/guests/sign-in style="margin:1em 0">
+ <!--input name=me type=text--> <button>Sign In</button>
</form>
+<p class=system><a class=systemtext href=/system
+ title=system><span>System</span></a></p>
+</nav>
+
+<aside>
+$:livestream()
+
+<div style=text-align:right><button id=enter>Enter Room</button></div>
+
+<div id=chat>
+ <div id=mediasoup-demo-app-media-query-detector></div>
+ <div id=mediasoup-demo-app-container></div>
+</div>
+
$if "aside" in resource:
$:resource.aside()
</aside>
<script src=https://cdn.jsdelivr.net/npm/vosk-browser@0.0.5/dist/vosk.js></script>
<script>
async function initAssistant() {
- const partialContainer = document.querySelector('#assistant .partial')
+ const partialContainer = document.querySelector('#search .partial')
- partialContainer.textContent = 'Loading...'
+ partialContainer.value = 'Loading...'
const channel = new MessageChannel()
const model = await Vosk.createModel('/static/vosk-model-small-en-us-0.15.tar.gz')
recognizer.setWords(true)
let ownerGivenName = '$owner["name"][0].split()[0]'
- let wakeWord = `$${ownerGivenName.toLowerCase()} assistant`
- let readyWord = `Say "$${ownerGivenName} Assistant help".`
+ let wakeWord = 'query plus'
+ let readyWord = `Say "query plus help".`
let state = 'asleep'
- partialContainer.textContent = readyWord
+ partialContainer.value = readyWord
recognizer.on('result', message => {
let input = message.result.text
if (input.slice(0, wakeWord.length) != wakeWord) {
- partialContainer.textContent = readyWord
+ partialContainer.value = readyWord
return
}
input = input.slice(wakeWord.length + 1)
audio.addEventListener('canplaythrough', () => {
audio.play()
state = 'asleep'
- partialContainer.textContent = readyWord
+ partialContainer.value = readyWord
})
})
- partialContainer.textContent = `$${input}`
+ partialContainer.value = `$${input}`
})
recognizer.on('partialresult', message => {
const input = message.result.partial
if (input.slice(0, wakeWord.length) != wakeWord)
return
state = 'awake'
- partialContainer.textContent = input.slice(wakeWord.length)
+ partialContainer.value = input.slice(wakeWord.length)
})
const mediaStream = await navigator.mediaDevices.getUserMedia({
<script>
window.onload = () => {
- const assistantTrigger = document.querySelector('#assistant button')
- assistantTrigger.onmouseup = () => {
- assistantTrigger.disabled = true
- assistantTrigger.style.display = 'none'
+ const listenTrigger = document.querySelector('button#listen')
+ listenTrigger.onmouseup = () => {
+ listenTrigger.disabled = true
+ listenTrigger.style.display = 'none'
initAssistant()
}
- const chatTrigger = document.querySelector('#chat button')
- chatTrigger.onmouseup = () => {
- chatTrigger.disabled = true
- chatTrigger.style.display = 'none'
+ const enterTrigger = document.querySelector('button#enter')
+ enterTrigger.onmouseup = () => {
+ enterTrigger.disabled = true
+ enterTrigger.style.display = 'none'
initChat()
}
}