|
|
class SpeakBravePlayer extends HTMLElement { |
|
|
connectedCallback() { |
|
|
this.attachShadow({ mode: 'open' |
|
|
|
|
|
this.shadowRoot.getElementById('analyzeBtn').addEventListener('click', async () => { |
|
|
const audioBlob = await getRecordingBlob(); |
|
|
const videoBlob = await getVideoBlob(); |
|
|
|
|
|
const analysis = await analyzeEmotion(audioBlob, videoBlob); |
|
|
if (analysis) { |
|
|
this.shadowRoot.getElementById('analysis').updateAnalysis(analysis); |
|
|
} |
|
|
}); |
|
|
} |
|
|
); |
|
|
this.shadowRoot.innerHTML = ` |
|
|
<style> |
|
|
:host { |
|
|
display: block; |
|
|
margin: 2rem 0; |
|
|
} |
|
|
.container { |
|
|
background: rgba(15, 23, 42, 0.7); |
|
|
backdrop-filter: blur(10px); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
border-radius: 1rem; |
|
|
padding: 2rem; |
|
|
} |
|
|
.header { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
margin-bottom: 1.5rem; |
|
|
} |
|
|
.icon { |
|
|
width: 3rem; |
|
|
height: 3rem; |
|
|
background: rgba(124, 58, 237, 0.2); |
|
|
border-radius: 50%; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin-right: 1rem; |
|
|
} |
|
|
h2 { |
|
|
font-size: 1.5rem; |
|
|
font-weight: 600; |
|
|
margin: 0; |
|
|
background: linear-gradient(90deg, #7c3aed 0%, #2563eb 100%); |
|
|
-webkit-background-clip: text; |
|
|
background-clip: text; |
|
|
color: transparent; |
|
|
} |
|
|
.video-container { |
|
|
margin-bottom: 2rem; |
|
|
border-radius: 0.5rem; |
|
|
overflow: hidden; |
|
|
} |
|
|
.task-card, .reflection-card { |
|
|
background: rgba(30, 41, 59, 0.5); |
|
|
border-radius: 0.5rem; |
|
|
padding: 1.5rem; |
|
|
margin-bottom: 1.5rem; |
|
|
} |
|
|
h3 { |
|
|
font-size: 1.25rem; |
|
|
font-weight: 500; |
|
|
margin-top: 0; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
.task-instructions { |
|
|
margin-bottom: 1.5rem; |
|
|
line-height: 1.6; |
|
|
} |
|
|
.timer { |
|
|
font-size: 1.5rem; |
|
|
font-weight: 600; |
|
|
color: #7c3aed; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
.record-btn { |
|
|
background: #7c3aed; |
|
|
color: white; |
|
|
border: none; |
|
|
padding: 0.75rem 1.5rem; |
|
|
border-radius: 0.5rem; |
|
|
font-weight: 500; |
|
|
cursor: pointer; |
|
|
transition: background 0.2s; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
} |
|
|
.record-btn:hover { |
|
|
background: #6d28d9; |
|
|
} |
|
|
.record-btn i { |
|
|
margin-right: 0.5rem; |
|
|
} |
|
|
.reflection-textarea { |
|
|
width: 100%; |
|
|
min-height: 120px; |
|
|
background: rgba(15, 23, 42, 0.5); |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
border-radius: 0.5rem; |
|
|
padding: 1rem; |
|
|
color: white; |
|
|
font-family: inherit; |
|
|
margin-bottom: 1rem; |
|
|
} |
|
|
.submit-btn { |
|
|
background: #2563eb; |
|
|
color: white; |
|
|
border: none; |
|
|
padding: 0.75rem 1.5rem; |
|
|
border-radius: 0.5rem; |
|
|
font-weight: 500; |
|
|
cursor: pointer; |
|
|
transition: background 0.2s; |
|
|
} |
|
|
.submit-btn:hover { |
|
|
background: #1d4ed8; |
|
|
} |
|
|
</style> |
|
|
<div class="container"> |
|
|
<div class="header"> |
|
|
<div class="icon"> |
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
|
|
<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path> |
|
|
</svg> |
|
|
</div> |
|
|
<h2>Speak Brave Challenge</h2> |
|
|
</div> |
|
|
|
|
|
<div class="video-container"> |
|
|
<iframe width="100%" height="400" src="https://www.youtube.com/embed/example" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
|
|
</div> |
|
|
|
|
|
<div class="task-card"> |
|
|
<h3>Voice Challenge</h3> |
|
|
<div class="task-instructions"> |
|
|
<p>Speak your truth boldly for 1 minute. Express yourself freely without hesitation or self-censorship.</p> |
|
|
<p>Focus on: Confidence, Clarity, and Courage</p> |
|
|
</div> |
|
|
<div class="timer">01:00</div> |
|
|
<button class="record-btn"> |
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
|
|
<circle cx="12" cy="12" r="10"></circle> |
|
|
<circle cx="12" cy="12" r="3"></circle> |
|
|
</svg> |
|
|
Start Recording |
|
|
</button> |
|
|
<button id="analyzeBtn" class="record-btn" style="margin-top: 1rem; background: #2563eb;"> |
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
|
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path> |
|
|
</svg> |
|
|
Analyze Emotion |
|
|
</button> |
|
|
</div> |
|
|
<div class="reflection-card"> |
|
|
<h3>Reflection</h3> |
|
|
<p>How did this challenge make you feel? What did you learn about yourself?</p> |
|
|
<textarea class="reflection-textarea" placeholder="Write your reflection here..."></textarea> |
|
|
<button class="submit-btn">Submit Reflection</button> |
|
|
</div> |
|
|
|
|
|
<emotion-analysis id="analysis"></emotion-analysis> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
} |
|
|
|
|
|
customElements.define('speak-brave-player', SpeakBravePlayer); |