Add video card insert feature + MkDocs video hydration + fixes
- New video card block for GrapesJS landing pages, email templates, MkDocs export, and documentation editor Insert dropdown - Shared HTML generators in admin/src/utils/videoCardHtml.ts - MkDocs video-player.js hydrates .video-card-block elements: thumbnail fix via MEDIA_API_URL, click-to-play inline, Gallery link - Media API CORS: auto-add MkDocs + docs subdomain origins - env_config_hook.py: smart Docker hostname detection, ADMIN_PORT resolution, pass env vars to MkDocs container - Gallery URL uses /gallery?expanded=ID format - VideoPickerModal: fix double /api prefix and Docker hostname thumbs - Seed: default-video-card PageBlock - Remove V1 legacy code (influence/, map/) Bunker Admin
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -18,22 +18,36 @@ def on_config(config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
Hook that runs when MkDocs loads the configuration.
|
||||
Injects environment variables as extra JavaScript.
|
||||
"""
|
||||
import re
|
||||
|
||||
# Read environment variables (with fallbacks)
|
||||
media_api_url = os.environ.get('MEDIA_API_PUBLIC_URL', 'http://localhost:4100')
|
||||
public_url = os.environ.get('ADMIN_URL', 'http://localhost:3000')
|
||||
|
||||
# For production, check for public-facing URLs
|
||||
# Fallback to subdomain-based URLs if available
|
||||
media_api_port = os.environ.get('MEDIA_API_PORT', '4100')
|
||||
admin_port = os.environ.get('ADMIN_PORT', '3000')
|
||||
admin_url = os.environ.get('ADMIN_URL', '')
|
||||
base_domain = os.environ.get('BASE_DOMAIN', '')
|
||||
|
||||
if base_domain and not base_domain.startswith('http'):
|
||||
base_domain = f'https://{base_domain}'
|
||||
|
||||
# Use base_domain to construct URLs if env vars not explicitly set
|
||||
if media_api_url == 'http://localhost:4100' and base_domain:
|
||||
media_api_url = base_domain.replace('cmlite.org', 'media.cmlite.org')
|
||||
# Helper: detect Docker container hostnames (not browser-accessible)
|
||||
def is_docker_hostname(url: str) -> bool:
|
||||
"""Check if URL uses a Docker container hostname instead of localhost/domain."""
|
||||
host = re.sub(r'^https?://', '', url).split(':')[0].split('/')[0]
|
||||
# Docker hostnames typically contain hyphens and no dots (not localhost, not a domain)
|
||||
return host != 'localhost' and '.' not in host
|
||||
|
||||
if public_url == 'http://localhost:3000' and base_domain:
|
||||
public_url = base_domain.replace('cmlite.org', 'app.cmlite.org')
|
||||
# Resolve media API URL — must be browser-accessible (not Docker hostname)
|
||||
if is_docker_hostname(media_api_url):
|
||||
media_api_url = f'http://localhost:{media_api_port}'
|
||||
|
||||
# Resolve public URL (admin app)
|
||||
if admin_url and not is_docker_hostname(admin_url) and 'localhost' not in admin_url:
|
||||
# Production domain — use as-is
|
||||
public_url = admin_url
|
||||
else:
|
||||
# Dev: use ADMIN_PORT (most reliable source of truth)
|
||||
public_url = f'http://localhost:{admin_port}'
|
||||
|
||||
# Create inline JavaScript with config
|
||||
config_script = f"""
|
||||
@@ -61,18 +75,25 @@ def on_config(config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# Note: We'll need to create a file for this
|
||||
env_config_path = 'assets/js/env-config.js'
|
||||
|
||||
# Write the generated config to a file
|
||||
# Write the generated config to a file (only if content changed to avoid
|
||||
# triggering MkDocs file watcher rebuild loop in serve mode)
|
||||
import pathlib
|
||||
docs_dir = pathlib.Path(config['docs_dir'])
|
||||
env_config_file = docs_dir / env_config_path
|
||||
env_config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(env_config_file, 'w') as f:
|
||||
f.write(config_script)
|
||||
existing_content = ''
|
||||
if env_config_file.exists():
|
||||
existing_content = env_config_file.read_text()
|
||||
|
||||
logger.info(f"✓ Generated video config: {env_config_file}")
|
||||
logger.info(f" MEDIA_API_URL: {media_api_url}")
|
||||
logger.info(f" PUBLIC_URL: {public_url}")
|
||||
if existing_content != config_script:
|
||||
with open(env_config_file, 'w') as f:
|
||||
f.write(config_script)
|
||||
logger.info(f"✓ Generated video config: {env_config_file}")
|
||||
logger.info(f" MEDIA_API_URL: {media_api_url}")
|
||||
logger.info(f" PUBLIC_URL: {public_url}")
|
||||
else:
|
||||
logger.info(f"✓ Video config unchanged, skipping write")
|
||||
|
||||
# Insert at the beginning of extra_javascript list
|
||||
if env_config_path not in config['extra_javascript']:
|
||||
|
||||
@@ -99,7 +99,7 @@ def generate_repo_data(repo_config: Dict[str, Any], output_dir: Path) -> None:
|
||||
if repo_config.get('github'):
|
||||
api_url = f"https://api.github.com/repos/{repo}"
|
||||
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||
github_token = "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" # Replace with your GitHub token
|
||||
github_token = os.getenv('GITHUB_TOKEN', '')
|
||||
if github_token:
|
||||
headers['Authorization'] = f'token {github_token}'
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user