feat(spotify): basic controls + oauth state validation#1
Open
DanielMouraoti wants to merge 2 commits intomainfrom
Open
feat(spotify): basic controls + oauth state validation#1DanielMouraoti wants to merge 2 commits intomainfrom
DanielMouraoti wants to merge 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands the Chrome extension with Spotify integration (OAuth + basic playback controls), a new “stats” visualization in the popup, and a Manifest V3 offscreen-based audio system.
Changes:
- Add Spotify OAuth flow (PKCE) in the service worker plus popup controls (connect/play/pause/next/prev) and status handling.
- Introduce a new “productivity” stats rendering in the popup (CSS-based stacked bars + legend) and broaden i18n support.
- Add MV3 offscreen document audio synthesis (Web Audio API) and update manifests/permissions/locales/assets accordingly.
Reviewed changes
Copilot reviewed 25 out of 28 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
popup.js |
Popup UI logic: i18n, stats rendering, timer polling, Spotify controls/status. |
popup.html |
Popup UI markup and styling updates; adds Spotify config UI and stats container. |
background.js |
Timer persistence + Spotify OAuth (PKCE/state validation) + playback API handlers. |
offscreen.js |
Offscreen document to synthesize timer sounds with Web Audio API. |
offscreen.html |
Offscreen document container page. |
manifest.json |
MV3 permissions/host permissions/CSP updates; Spotify oauth2 config. |
chart.js |
Bundled chart library artifact (currently appears unused by the new stats UI). |
_locales/pt_BR/messages.json |
Adds i18n strings (days of week + category labels). |
_locales/en/messages.json |
Adds i18n strings (days of week + category labels). |
assets/README.md |
Documents audio assets and fallback behavior. |
assets/sparkle.mp3 |
Added audio asset placeholder. |
assets/piano.mp3 |
Added audio asset placeholder. |
assets/chime.mp3 |
Added audio asset placeholder. |
assets/bell.mp3 |
Added audio asset placeholder. |
.gitignore |
Adds broad documentation ignore rules and other ignore patterns. |
README.md |
Project documentation updates including Spotify quick start links. |
LICENSE |
Adds MIT license text. |
study-ai-v1.0.0-stable/popup.js |
“Stable” copy of popup logic (same feature set). |
study-ai-v1.0.0-stable/popup.html |
“Stable” popup markup/styles. |
study-ai-v1.0.0-stable/background.js |
“Stable” service worker logic. |
study-ai-v1.0.0-stable/offscreen.js |
“Stable” offscreen audio synthesis. |
study-ai-v1.0.0-stable/offscreen.html |
“Stable” offscreen container page. |
study-ai-v1.0.0-stable/manifest.json |
“Stable” manifest changes. |
study-ai-v1.0.0-stable/chart.js |
“Stable” chart library artifact. |
study-ai-v1.0.0-stable/_locales/pt_BR/messages.json |
“Stable” locale strings. |
study-ai-v1.0.0-stable/_locales/en/messages.json |
“Stable” locale strings. |
study-ai-v1.0.0-stable/assets/README.md |
“Stable” assets documentation. |
study-ai-v1.0.0-stable/assets/sparkle.mp3 |
“Stable” audio asset placeholder. |
study-ai-v1.0.0-stable/assets/piano.mp3 |
“Stable” audio asset placeholder. |
study-ai-v1.0.0-stable/assets/chime.mp3 |
“Stable” audio asset placeholder. |
study-ai-v1.0.0-stable/assets/bell.mp3 |
“Stable” audio asset placeholder. |
study-ai-v1.0.0-stable/.gitignore |
“Stable” ignore rules. |
study-ai-v1.0.0-stable/README.md |
“Stable” README. |
study-ai-v1.0.0-stable/LICENSE |
“Stable” license. |
Comments suppressed due to low confidence (1)
study-ai-v1.0.0-stable/assets/sparkle.mp3:2
- Este arquivo
*.mp3parece ser apenas um placeholder de texto (ID3) e não um MP3 válido. Se a extensão pretende distribuir sons reais, os arquivos precisam ser binários válidos (ou removidos do repo e gerados/baixados via build). Como está, pode confundir e quebrar qualquer tentativa futura de playback por arquivo.
ID3
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| await fullSync(); | ||
|
|
||
| // PRIORIDADE 2: Iniciar polling do Timer (mantém sincronizado) | ||
| setInterval(pollTimer, 200); |
Comment on lines
+21
to
+25
| "https://api.spotify.com/*", | ||
| "https://actions.google.com/*" | ||
| ], | ||
| "web_accessible_resources": [ | ||
| { |
Comment on lines
+22
to
+23
| "https://accounts.spotify.com/*", | ||
| "https://actions.google.com/*" |
Comment on lines
+65
to
69
| - [docs/SPOTIFY_INTEGRATION.md](docs/SPOTIFY_INTEGRATION.md) | ||
| - [docs/MESSAGE_CONTRACT.md](docs/MESSAGE_CONTRACT.md) | ||
|
|
||
| --- | ||
|
|
| *.md | ||
| !README.md | ||
| !LICENSE.md | ||
| !.github/**/*.md |
Comment on lines
+258
to
+259
| const isEnglish = State.language === 'en'; | ||
| const labels = isEnglish |
Comment on lines
+1462
to
+1483
| // Language select | ||
| if ($('languageSelect')) { | ||
| $('languageSelect').addEventListener('change', async (e) => { | ||
| const newLang = e.target.value; | ||
| State.language = newLang; | ||
| await chrome.storage.local.set({ language: State.language }); | ||
|
|
||
| // Atualizar título imediatamente se estiver na aba Stats | ||
| const titleEl = document.getElementById('productivity-title'); | ||
| if (titleEl) { | ||
| const isEnglish = newLang === 'en'; | ||
| titleEl.innerText = isEnglish ? '📊 Productivity' : '📊 Produtividade'; | ||
| } | ||
|
|
||
| // Re-renderizar gráfico se estiver na aba Stats | ||
| if (State.activeTab === 'stats') { | ||
| await new Promise(r => setTimeout(r, 50)); | ||
| renderStudyMetrics(); | ||
| } | ||
| }); | ||
| } | ||
|
|
Comment on lines
+50
to
+60
| // Calcular duração exata (do modo do timer) | ||
| const duration = MODES[timerState.mode] || MODES.focus; | ||
|
|
||
| // Registrar sessão com detalhes completos | ||
| const session = { | ||
| timestamp: now.toISOString(), | ||
| duration: MODES[timerState.mode] || MODES.focus, | ||
| date: now.toLocaleDateString('pt-BR'), | ||
| time: now.toLocaleTimeString('pt-BR'), | ||
| duration: duration, // em segundos | ||
| mode: timerState.mode, | ||
| category: currentCategory | ||
| }); | ||
| category: currentCategory, |
Comment on lines
+24
to
+32
| "web_accessible_resources": [ | ||
| { | ||
| "resources": [ | ||
| "offscreen.html", | ||
| "assets/*" | ||
| ], | ||
| "matches": ["<all_urls>"] | ||
| } | ||
| ], |
Comment on lines
+632
to
638
| const state = randomString(16); | ||
| const codeVerifier = randomString(64); | ||
| const codeChallenge = await sha256Base64Url(codeVerifier); | ||
|
|
||
| const url = new URL(redirectUrl); | ||
| const token = url.hash.match(/access_token=([^&]+)/)?.[1]; | ||
| const expiresIn = url.hash.match(/expires_in=([^&]+)/)?.[1]; | ||
| spotifyRuntimeState.authState = { value: state, createdAt: Date.now() }; | ||
| spotifyRuntimeState.codeVerifier = codeVerifier; | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.