Initial scaffold: Beat Pocket MV3 extension
- manifest.json with MV3 config, host permissions for beat-battle.net - content/detector.ts: route + overlay observer, emits bbp:phase events - content/layout.ts: defensive mobile-first layout reflow - content/chat-drawer.ts: bottom-sheet drawer, dispatches synthetic events through site's own React-managed textarea + button (preserves auth, rate-limit, mute, profanity guards) - content/util/selectors.ts: text- and role-based fallback chain - content/util/ws-proxy.ts: lightweight WebSocket instrumentation, no payload capture - content/inject.css: mobile overrides using site's existing --bb-* vars - background.js: MV3 service worker stub - package.json + tsconfig.json + esbuild.config.mjs: build pipeline - icons/: 16/32/48/128 placeholder PNGs (chili-red disc) - docs/PLAN.md: full V1 architecture, risks, scope - README.md: scope, dev workflow (load unpacked), tech
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* layout.ts — restructure the outer shell on mobile:
|
||||
*
|
||||
* - Mount #bbp-host for our overlay UI (drawer, FAB).
|
||||
* - For home: hide leaderboard sidebars, ensure single-column.
|
||||
* - For in-game: leave the room overlay intact, just plumb our drawer.
|
||||
*
|
||||
* Reads selectors defensively (never breaks if a class is renamed).
|
||||
*/
|
||||
|
||||
import { isHome, isInGame, SITE } from './util/selectors';
|
||||
|
||||
let hostEl: HTMLDivElement | null = null;
|
||||
|
||||
export function ensureHost(): HTMLDivElement {
|
||||
if (hostEl && document.contains(hostEl)) return hostEl;
|
||||
hostEl = document.createElement('div');
|
||||
hostEl.id = 'bbp-host';
|
||||
hostEl.setAttribute('aria-hidden', 'false');
|
||||
// Must be at the END of body so it's above everything else visually,
|
||||
// but pointer-events: none on root so it doesn't block.
|
||||
document.body.appendChild(hostEl);
|
||||
return hostEl;
|
||||
}
|
||||
|
||||
export function applyHomeLayout(): void {
|
||||
if (!isHome()) return;
|
||||
// Hide desktop-only side panels. We rely on the same defensive selectors
|
||||
// we use everywhere; if the site changes layout, we just won't reflow.
|
||||
document.querySelectorAll<HTMLElement>(
|
||||
'.bb-sidebar, [data-bb-sidebar], .bb-leaderboard, [data-bb-leaderboard]',
|
||||
).forEach((el) => (el.style.display = 'none'));
|
||||
|
||||
// Make the main column full-width on mobile
|
||||
const main = document.querySelector<HTMLElement>('main, [role="main"], .bb-main, [data-bb-main]');
|
||||
if (main) {
|
||||
main.style.maxWidth = '100%';
|
||||
main.style.paddingLeft = '8px';
|
||||
main.style.paddingRight = '8px';
|
||||
}
|
||||
}
|
||||
|
||||
export function applyInGameLayout(): void {
|
||||
if (!isInGame()) return;
|
||||
// Don't touch .bb-room-overlay's outer behaviour — it's already mobile-aware.
|
||||
// We just make sure there's room for our FAB at the bottom.
|
||||
const overlay = document.querySelector<HTMLElement>(SITE.overlay);
|
||||
if (overlay) {
|
||||
overlay.style.paddingBottom = 'calc(96px + env(safe-area-inset-bottom))';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user