diff --git a/.AI-SAFEGUARDS.md b/.AI-SAFEGUARDS.md deleted file mode 100644 index f7289d84a..000000000 --- a/.AI-SAFEGUARDS.md +++ /dev/null @@ -1,56 +0,0 @@ -# AI Safeguards Configuration - -## Protected Branches - -These branches CANNOT be modified by AI: - -- docs-v2 (source of truth) -- main - -## Allowed Branches for AI - -- docs-v2-dev (development branch for hourly commits) -- fix-\* (feature branches) -- safepoint/\* (checkpoint branches) - -## Forbidden Commands for AI - -❌ NEVER execute: - -- git reset --hard -- git restore . -- git clean -fd -- git push --force -- git rebase -i (interactive rebase) -- git tag --force -- Any mass git operations without human approval - -## Large Change Protocol (>10 files) - -1. AI must show file list and get approval -2. Human creates .ai-commit-verified file -3. Only then can AI proceed with commit -4. File is deleted after commit - -## Audit Trail - -All AI git operations logged to: .ai-operations.log - -## Emergency Rollback - -If AI makes dangerous changes: - -```bash -git reflog -git reset --hard -``` - -## Human Commit Override - -If AI blocks legitimate commits, use: - -```bash -git commit --no-verify -``` - -Updated: 2026-01-06 after safeguard implementation diff --git a/.augment-guidelines b/.augment-guidelines new file mode 100644 index 000000000..a7129af7a --- /dev/null +++ b/.augment-guidelines @@ -0,0 +1,17 @@ +# Standard Operating Procedure for Scripts + + + +## 1. Safety & Verification Workflow + +- Before applying changes to existing files, you MUST: + 1. Create a "checkpoint" backup using the internal checkpoint tool. + 2. Create a new git branch named `agent/[feature-name]`. + 3. Verify the script's logic by applying it to a temporary copy of the target + file first. + 4. Only after verification and user approval, apply the changes to the project + files in the new branch. diff --git a/.augment/rules/git-safety.md b/.augment/rules/git-safety.md new file mode 100644 index 000000000..3e5ce50a6 --- /dev/null +++ b/.augment/rules/git-safety.md @@ -0,0 +1,5 @@ +# GIT WRITE PROTOCOL +- **ENFORCEMENT:** You MUST verify the existence of local Git hooks in `.git/hooks/` before initiating any write command (commit, push, rebase). +- **FORBIDDEN:** You are STRICTLY FORBIDDEN from using `--no-verify` or `-n`. +- **BEHAVIOR:** When a write command is initiated, you MUST announce: "Initiating [action]. Please approve the safety checkpoint in your terminal." +- **RECOVERY:** If a command fails, suggest restoring from the latest `checkpoint/` branch. diff --git a/.github/AGENTS.md b/.github/AGENTS.md new file mode 100644 index 000000000..d9d49698c --- /dev/null +++ b/.github/AGENTS.md @@ -0,0 +1,39 @@ +# 🤖 PROJECT AGENT RULES & SAFETY PROTOCOLS + +## 🛠️ CRITICAL BOUNDARIES (READ FIRST) + +- **ALWAYS** check for the existence of local Git hooks in `.git/hooks/` before + initiating a write command. +- **NEVER** use `--no-verify` or `-n` flags to bypass safety checks. These are + hard project constraints. +- **NEVER** perform a `git reset --hard` or `git push --force` without an + explicit, multi-turn plan confirmed by the user. +- **NEVER** perform a `git reset --hard` or `git push --force` without a saved + branch to revert to in case of failure. + +## 📦 GIT WORKFLOW & CHECKPOINTS + +This project enforces a "Human-in-the-Loop" (HitL) verification for all +destructive or history-altering actions. + +- **Automatic Checkpoints:** Every `commit`, `push`, and `rebase` triggers a + safety hook that creates a branch named `checkpoint/YYYY-MM-DD_HHMMSS`. +- **Pre-Write Announcement:** Before executing a write command, you MUST state: + _"I am initiating [COMMAND]. A safety checkpoint will be created. Please + switch to your terminal to type 'yes' when prompted."_ +- **Recovery:** If a command fails, the latest pre-failure state is stored in + the most recent `checkpoint/` branch. + +## 🧪 VALIDATION COMMANDS + +Before asking for a commit, you should ideally run these to ensure code quality: + +```bash +# Verify build +mint dev +``` + +# Run local test suite + +Make a test for mintlify in the v2/tests file. DO NOT EVER run a script without +testing it on a local branch first. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7ab9f32f7..569056b53 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -13,7 +13,7 @@ containerized with Docker. - Use `.tsx` for new components; `.jsx` is legacy but supported. - **Automations & Scripts:** - All dynamic, AI, and data-fetching logic in `automations/` and `ai-tools/`. - - Scripts for API doc generation and external data in `v2/scripts/` (see + - Scripts for API doc generation and external data in `snippets/scripts/` (see generate-api-docs.sh, fetch-openapi-specs.sh). - **API Reference:** - OpenAPI spec in `openapi.yaml` (AI API: see ai/worker/api/openapi.yaml). Use @@ -32,10 +32,10 @@ containerized with Docker. `docker buildx build --platform linux/amd64 --load -t livepeer/docs .` - Makefile: `make all` - **API Docs Generation:** - - Use `v2/scripts/generate-api-docs.sh` to convert OpenAPI specs to MDX/API - docs and navigation JSON. Example: + - Use `snippets/scripts/generate-api-docs.sh` to convert OpenAPI specs to + MDX/API docs and navigation JSON. Example: ```bash - ./v2/scripts/generate-api-docs.sh ai/worker/api/openapi.yaml v2/pages/04_gateways/guides-references/api-reference/AI-API "AI API" + ./snippets/scripts/generate-api-docs.sh ai/worker/api/openapi.yaml v2/pages/04_gateways/guides-references/api-reference/AI-API "AI API" ``` - Output: MDX files + navigation snippet for `docs.json`. - **External Data Fetching:** @@ -72,8 +72,8 @@ containerized with Docker. - **OpenAPI:** API docs generated from `openapi.yaml` (see also `ai/worker/api/openapi.yaml`). - **Docker:** Containerized builds for CI/CD and local dev. -- **Automations:** Scripts in `v2/scripts/` automate API doc generation and - external data sync. +- **Automations:** Scripts in `snippets/scripts/` automate API doc generation + and external data sync. ## Key Files & Directories @@ -83,7 +83,7 @@ containerized with Docker. - `openapi.yaml`, `ai/worker/api/openapi.yaml` — API reference - `Dockerfile`, `Makefile` — Build/deploy - `README.md`, `README_V2.md` — Developer notes, protocol/architecture -- `v2/scripts/` — Automation scripts (API docs, data fetching) +- `snippets/scripts/` — Automation scripts (API docs, data fetching) --- diff --git a/.github/workflows/update-livepeer-release.yml b/.github/workflows/update-livepeer-release.yml new file mode 100644 index 000000000..e1858c316 --- /dev/null +++ b/.github/workflows/update-livepeer-release.yml @@ -0,0 +1,60 @@ +name: Update Livepeer Release Version + +on: + schedule: + # Run every 30 minutes + - cron: "*/30 * * * *" + workflow_dispatch: + +jobs: + check-and-update: + runs-on: ubuntu-latest + + steps: + - name: Checkout docs repository + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get latest go-livepeer release + id: get_release + run: | + LATEST_RELEASE=$(curl -s https://api.github.com/repos/livepeer/go-livepeer/releases/latest | jq -r .tag_name) + echo "release=${LATEST_RELEASE}" >> $GITHUB_OUTPUT + echo "Latest release: ${LATEST_RELEASE}" + + - name: Read current version from globals.mdx + id: current_version + run: | + CURRENT=$(grep -oP 'latestVersion\s*=\s*["'"'"']?\K[^"'"'"']+' snippets/automationData/globals/globals.mdx || echo "") + echo "current=${CURRENT}" >> $GITHUB_OUTPUT + echo "Current version: ${CURRENT}" + + - name: Update globals.mdx if needed + if: + steps.get_release.outputs.release != + steps.current_version.outputs.current + run: | + # Create backup + cp snippets/automationData/globals/globals.mdx snippets/automationData/globals/globals.mdx.bak + + # Update the latestVersion value + sed -i "s/latestVersion[[:space:]]*=[[:space:]]*[\"'][^\"']*[\"']/latestVersion = \"${{ steps.get_release.outputs.release }}\"/" snippets/automationData/globals/globals.mdx + + # Update the latestVersionUrl value + sed -i "s|latestVersionUrl[[:space:]]*=[[:space:]]*[\"'][^\"']*[\"']|latestVersionUrl = \"https://github.com/livepeer/go-livepeer/releases/download/${{ steps.get_release.outputs.release }}\"|" snippets/automationData/globals/globals.mdx + + # Verify the changes + echo "Updated content:" + grep "latestVersion" snippets/automationData/globals/globals.mdx + + - name: Commit and push if changed + if: + steps.get_release.outputs.release != + steps.current_version.outputs.current + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add snippets/automationData/globals/globals.mdx + git commit -m "chore: update latest release to ${{ steps.get_release.outputs.release }}" + git push diff --git a/.verify-large-change.sh b/.verify-large-change.sh deleted file mode 100644 index 389295f64..000000000 --- a/.verify-large-change.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# AI Large Change Verification Script -# Used when AI needs to commit more than 10 files - -BRANCH=$(git rev-parse --abbrev-ref HEAD) -FILES_COUNT=$(git diff --cached --name-only | wc -l) -TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') - -echo "" -echo "════════════════════════════════════════════════════════════" -echo "⚠️ LARGE CHANGE VERIFICATION REQUIRED" -echo "════════════════════════════════════════════════════════════" -echo "" -echo "Branch: $BRANCH" -echo "Files to be modified: $FILES_COUNT" -echo "Timestamp: $TIMESTAMP" -echo "" -echo "Files list:" -git diff --cached --name-only | sort -echo "" -echo "════════════════════════════════════════════════════════════" -echo "" -echo "HUMAN ACTION REQUIRED:" -echo "" -echo "1. Review the files above carefully" -echo "2. If safe, create verification file:" -echo " touch .ai-commit-verified" -echo "3. AI will then proceed with commit" -echo "" -echo "════════════════════════════════════════════════════════════" -echo "" diff --git a/AI-ACCOUNTABILITY-CHECKLIST.md b/AI-ACCOUNTABILITY-CHECKLIST.md deleted file mode 100644 index 25f8f70ab..000000000 --- a/AI-ACCOUNTABILITY-CHECKLIST.md +++ /dev/null @@ -1,82 +0,0 @@ -# AI Assistant Accountability Checklist - -Use this for EVERY interaction with ANY AI on this repo. - -## Before Session Starts - -- [ ] AI acknowledges UNIVERSAL-AI-PROTOCOL.md -- [ ] AI states current branch -- [ ] AI lists protected branches (docs-v2, main) -- [ ] AI confirms it has read/write restrictions - -## Before EVERY Git Operation - -- [ ] AI shows PREFLIGHT CHECK (branch, files, operation, approval needed) -- [ ] You review the preflight -- [ ] You explicitly approve or reject -- [ ] AI executes ONLY after approval - -## During Large Changes (> 10 files) - -- [ ] AI lists EXACT files being changed -- [ ] AI explains WHY each file changes -- [ ] You review file list -- [ ] You create `.ai-commit-verified` file -- [ ] AI commits with verification token in message - -## After Each Commit - -- [ ] Verify commit message has: [file count] | [what] | [why] | [approved by] -- [ ] Check `.ai-operations.log` for entry -- [ ] Spot-check git log for timestamp accuracy -- [ ] Review file changes: `git show HEAD` - -## If Something Breaks - -- [ ] Stop work immediately -- [ ] Document what broke -- [ ] Use ROLLBACK-GUIDE.md to revert -- [ ] Don't let AI try to "fix" without rollback first -- [ ] Post-mortem: update UNIVERSAL-AI-PROTOCOL.md - -## Monthly Review - -- [ ] Audit `.ai-operations.log` for patterns -- [ ] Check if any rules were bent -- [ ] Review `git log docs-v2-dev` for auto-commits -- [ ] Test rollback procedures (make sure they still work) -- [ ] Update this checklist based on lessons learned - -## Red Flags (Stop Work Immediately) - -- [ ] AI tries to use `git reset --hard` -- [ ] AI commits to `docs-v2` or `main` -- [ ] AI doesn't show preflight checklist -- [ ] AI modifies 50+ files without asking -- [ ] AI touches `.prettierrc` or `docs.json` -- [ ] AI makes changes to v1/ directory -- [ ] Commit message missing approval token -- [ ] Pre-commit hook does NOT block an AI commit attempt - -## Recovery Commands (Memorize These) - -```bash -# See recent commits -git log --oneline -10 docs-v2-dev - -# Revert last commit (safe, creates new commit) -git revert HEAD - -# View what's in last commit -git show HEAD - -# Unstage last commit (keep files) -git reset --soft HEAD~1 - -# Check audit trail -cat .ai-operations.log | tail -20 -``` - ---- - -**This checklist is your insurance policy against AI fucking up your docs.** diff --git a/AI_GUIDELINES.md b/AI_GUIDELINES.md new file mode 100644 index 000000000..1e495944c --- /dev/null +++ b/AI_GUIDELINES.md @@ -0,0 +1,42 @@ +# 🛡️ AI SAFETY PROTOCOL: GIT WRITE OPERATIONS + +## 1. MANDATORY SAFETY HOOKS + +This repository uses custom Git hooks for "Human-in-the-Loop" (HitL) +verification. + +- **ENFORCEMENT:** You SHALL NOT attempt to bypass hooks. +- **FORBIDDEN:** The use of `--no-verify`, `-n`, or any environment variable + designed to skip Git hook execution is STRICTLY PROHIBITED. +- **BEHAVIOR:** When you initiate a `commit`, `push`, or `rebase`, the hook will + pause and wait for manual input in the user's terminal. You MUST wait for the + user to confirm. + +## 2. AUTOMATED CHECKPOINTING + +Every write command triggers an automatic checkpoint branch. + +- **FORMAT:** `checkpoint/YYYY-MM-DD_HHMMSS` +- **ACTION:** Before running a write command, you MUST state: _"I am initiating + [COMMAND]. A safety checkpoint will be created. Please approve the prompt in + your terminal."_ + +## 3. CATASTROPHIC FAILURE RECOVERY + +In the event of a destructive operation (e.g., accidental file deletion, +corrupted rebase, or broken merge): + +- **DO NOT** attempt to "fix" the state with further complex Git commands. +- **PROCEDURE:** + 1. Identify the latest `checkpoint/` branch using + `git branch --list 'checkpoint/*'`. + 2. Suggest a `git reset --hard` to that specific checkpoint branch to restore + the repository to its pre-failure state. + 3. Notify the user immediately of the failure and the recovery path. + +## 4. SCOPE LIMITATIONS + +- **READS:** You have full permission for `git status`, `git diff`, and + `git log`. +- **WRITES:** Every `commit`, `push`, and `rebase` is a high-stakes action. + Treat them as irreversible without human oversight. diff --git a/README_V2.md b/README_V2.md index 6fddd5d8c..82b06b409 100644 --- a/README_V2.md +++ b/README_V2.md @@ -61,6 +61,33 @@ Developer Gateways +## Components Organisation Options + +**Atomic Design (Brad Frost)** atoms/ → Smallest units (Button, Icon, Input) +molecules/ → Combinations of atoms (SearchBar = Input + Button) organisms/ → +Complex sections (Header, Footer, Card) templates/ → Page layouts pages/ → +Specific instances + +**2. By Function/Purpose** + +primitives/ → Base UI (Button, Text, Box) forms/ → Inputs, Select, Checkbox, +Validation layout/ → Grid, Stack, Container, Spacer navigation/ → Tabs, +Breadcrumb, Menu, Sidebar feedback/ → Alert, Toast, Modal, Spinner data-display/ +→ Table, List, Card, Badge media/ → Image, Video, Avatar, Icon + +**3. By Complexity/Abstraction** base/ → Unstyled primitives core/ → Styled +basics with no logic composite/ → Composed from multiple core smart/ → Stateful, +connected to data + +**4. Shadcn/Radix Style** (flat + registry) ui/ button.jsx card.jsx dialog.jsx +... + +**5. Domain-First** (feature folders) components/ auth/ → LoginForm, SignupForm +dashboard/ → Charts, Stats checkout/ → Cart, Payment shared/ → Reusable across +domains + +====== + #### Direct Usage & Platform Integration | Category | Reason | Business Explanation | @@ -147,7 +174,8 @@ count, specific issue details **EXAMPLE** I'm fetching the latest release of livepeer dynamically in some places eg. -gateways/linux-install. with the `LatestRelease` component. +gateways/linux-install. with a github action `latestVersion` and +`latestVersionUrl` are saved in `/snippets/automationData/globals/globals.mdx`. ### !!! Caveats: @@ -801,3 +829,440 @@ Wiki pages you might want to explore: Wiki pages you might want to explore: - [Architecture (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#1.1) + +Yes, it's possible to test on testnets, and there are orchestrators running on +them. The Livepeer codebase explicitly supports testnet deployments with +dedicated network configurations. + +## Quick Answer + +- **Testnets are supported**: Livepeer supports `arbitrum-one-goerli` and other + testnets +- **Orchestrators exist**: The code assumes orchestrators are available on + testnets +- **Deprecated testnets**: Rinkeby and arbitrum-one-rinkeby are deprecated but + still functional + +--- + +## Testnet Support in Codebase + +### Network Configurations + +The starter code includes specific configurations for testnets [1](#50-0) : + +```go +configOptions := map[string]*NetworkConfig{ + "rinkeby": { + ethController: "0x9a9827455911a858E55f07911904fACC0D66027E", + redeemGas: redeemGasL1, + }, + "arbitrum-one-rinkeby": { + ethController: "0x9ceC649179e2C7Ab91688271bcD09fb707b3E574", + redeemGas: redeemGasL2, + }, + // ... other networks +} +``` + +### Test Scripts + +The test suite includes testnet-specific tests [2](#50-1) : + +```bash +# Run Rinkeby tests +if [ -z ${RINKEBY_ETH_URL+x} ]; then + echo "RINKEBY_ETH_URL is not set - skipping Rinkeby tests" +else + run_lp -gateway -network rinkeby $ETH_ARGS + [ -d "$DEFAULT_DATADIR"/rinkeby ] + kill $pid +fi +``` + +### Development Configurations + +VS Code launch configurations show testnet setups [3](#50-2) : + +```go +if *cfg.Network == "rinkeby" || *cfg.Network == "arbitrum-one-rinkeby" { + glog.Warning("The Rinkeby/ArbRinkeby networks are deprecated in favor of the Goerli/ArbGoerli networks which will be launched in January 2023.") +} +``` + +## Testing on Testnets + +### Configuration + +Use the testnet configuration: + +```yaml +command: + "-gateway -network arbitrum-one-goerli -ethUrl=https://goerli.arbitrum.io/rpc + -ethUrl=https://eth-goerli.g.alchemy.com/v2/YOUR_API_KEY" +``` + +### Finding Orchestrators + +Testnets have fewer orchestrators than mainnet, but they exist: + +1. Check the Livepeer explorer for testnet orchestrators +2. Use the CLI to discover available orchestrators: + ```bash + curl http://localhost:5935/getOrchestrators + ``` + +### Benefits of Testnet Testing + +- No real ETH costs (use testnet faucets) +- Safe environment for experimentation +- Test new features before mainnet deployment + +## Notes + +- Testnet orchestrators are run by community members and the Livepeer team +- Some testnets may have limited capacity compared to mainnet +- Always check the network status before deploying to testnet +- The codebase is designed to work identically across testnet and mainnet, just + with different network parameters + +## On-Chain Gateway Orchestrator Discovery and Connection + +This codemap traces how on-chain Livepeer gateways discover and connect to +orchestrators. The system supports both direct orchestrator specification via +-orchAddr flag [1b] and automatic blockchain-based discovery when no addresses +are provided [1d]. The discovery process queries the BondingManager smart +contract to get all registered orchestrators [2c-2e], with different validation +rules for different node types - transcoders require explicit orchestrator +addresses [3a] while gateways can operate with or without them [3b]. + +### 1. Orchestrator Discovery Initialization + +How a gateway sets up orchestrator discovery when starting in on-chain mode + +### 1a. Discovery Setup Start (`starter.go:1576`) + +Entry point for configuring orchestrator discovery + +```text +// Set up orchestrator discovery +``` + +### 1b. Direct Orchestrator Pool (`starter.go:1584`) + +Uses specific orchestrator addresses when provided + +```text +if len(orchURLs) > 0 { + n.OrchestratorPool = discovery.NewOrchestratorPool(bcast, orchURLs, common.Score_Trusted, orchBlacklist, *cfg.DiscoveryTimeout) +``` + +### 1c. On-Chain DB Cache (`starter.go:1591`) + +Creates blockchain-based orchestrator cache for on-chain mode + +```text +if *cfg.Network != "offchain" { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist, *cfg.DiscoveryTimeout) +``` + +### 1d. Auto-Discovery Fallback (`starter.go:1600`) + +Uses blockchain discovery when no specific orchestrators provided + +```text +if *cfg.OrchWebhookURL == "" && len(orchURLs) == 0 { + n.OrchestratorPool = dbOrchPoolCache +``` + +### 2. Blockchain Orchestrator Pool Query + +How the gateway discovers orchestrators from smart contracts when no addresses +are specified + +### 2a. HTTP Discovery Handler (`handlers.go:1077`) + +Gateway endpoint for discovering available orchestrators + +```text +func registeredOrchestratorsHandler(client eth.LivepeerEthClient, db *common.DB) http.Handler { +``` + +### 2b. Query Transcoder Pool (`handlers.go:1079`) + +Calls Ethereum client to get registered orchestrators + +```text +orchestrators, err := client.TranscoderPool() +``` + +### 2c. Ethereum Client Implementation (`client.go:980`) + +Retrieves all transcoders from the bonding manager contract + +```text +func (c *client) TranscoderPool() ([]*lpTypes.Transcoder, error) { +``` + +### 2d. Get First Orchestrator (`client.go:983`) + +Smart contract call to get first registered orchestrator + +```text +tAddr, err := c.GetFirstTranscoderInPool() +``` + +### 2e. Iterate Through Pool (`client.go:996`) + +Loops through all registered orchestrators + +```text +tAddr, err = c.GetNextTranscoderInPool(tAddr) +``` + +### 3. Error Handling and Validation + +How the gateway validates orchestrator configuration and handles missing +connections + +### 3a. Transcoder Validation (`starter.go:1827`) + +Transcoders and AI workers require orchestrator addresses + +```text +if n.NodeType == core.TranscoderNode || n.NodeType == core.AIWorkerNode { + if len(orchURLs) <= 0 { + glog.Exit("Missing -orchAddr") +``` + +### 3b. Gateway Pool Validation (`starter.go:1605`) + +Gateways can run without orchestrators but won't transcode + +```text +if n.OrchestratorPool == nil { + // Not a fatal error; may continue operating in segment-only mode + glog.Error("No orchestrator specified; transcoding will not happen") +``` + +### 3c. Flag Definition (`flags.go:23`) + +Command line flag for specifying orchestrator addresses + +```text +cfg.OrchAddr = fs.String("orchAddr", *cfg.OrchAddr, "Comma-separated list of orchestrators to connect to") +``` + +# BYOC (Bring Your Own Container) Summary + +BYOC is Livepeer's Generic Processing Pipeline that allows you to run custom +Docker containers for media processing on the Livepeer network while integrating +with Livepeer's infrastructure for job distribution and payments. [1](#53-0) + +## Key Points + +- **BYOC is NOT just any Docker container** - it must implement Livepeer's + processing API +- **Runs on Orchestrators with AI Workers** - containers execute on orchestrator + nodes, not directly on-chain +- **Gateway routes jobs** - gateways accept requests and forward to + orchestrators with BYOC capabilities +- **Payment model** - uses 1 ticket per second of compute (updated in v0.8.7) + [2](#53-1) + +## Architecture + +```mermaid +graph LR + Gateway[BYOC Gateway] --> Orchestrator[BYOC Orchestrator] + Orchestrator --> Container[Custom Container] + + Gateway -.->|/process/request| Orchestrator + Orchestrator -.->|Register Capability| Container +``` + +The system consists of: + +- **BYOCGatewayServer** - Handles job submission from clients [3](#53-2) +- **BYOCOrchestratorServer** - Manages job processing and capability + registration [4](#53-3) + +## Requirements + +1. **Orchestrator with AI Worker** - Needed to run containers +2. **Custom Container** - Must implement Livepeer's API +3. **Off-chain or On-chain** - Works in both modes +4. **Payment Setup** - Tickets for compute time + +## Notes + +- BYOC was introduced as the "Generic Processing Pipeline" in v0.8.5 +- Containers are managed similarly to AI worker containers +- Your container must expose the required HTTP endpoints for job processing + +Wiki pages you might want to explore: + +- [Architecture (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#1.1) +- [AI Workers (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#2.6) + +Wiki pages you might want to explore: + +- [Overview (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#1) +- [AI Workers (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#2.6) + +# On-Chain Gateway Setup + +For an on-chain dual gateway, you don't need to manually connect to +orchestrators - the system discovers them automatically from the blockchain. + +## Quick Answer + +**No special setup needed** - just run the gateway with on-chain flags. The +gateway will: + +- Automatically discover all public orchestrators from the protocol +- Filter by capabilities (video transcoding, AI models) +- Select the best ones based on price and performance + +--- + +## How On-Chain Discovery Works + +### Automatic Orchestrator Discovery + +When you start an on-chain gateway (`-network arbitrum-one-mainnet`), it +automatically creates a `DBOrchestratorPoolCache` that polls the blockchain for +registered orchestrators [1](#55-0) : + +```go +if *cfg.Network != "offchain" { + dbOrchPoolCache, err := discovery.NewDBOrchestratorPoolCache(ctx, n, timeWatcher, orchBlacklist, *cfg.DiscoveryTimeout) + if err != nil { + exit("Could not create orchestrator pool with DB cache: %v", err) + } + + // Use DB cache as orchestrator pool if no specific orchestrators provided + if *cfg.OrchWebhookURL == "" && len(orchURLs) == 0 { + n.OrchestratorPool = dbOrchPoolCache + } +} +``` + +### What Gets Discovered + +The discovery system fetches: + +- **All registered orchestrators** from the BondingManager contract +- **Their capabilities** (video transcoding profiles, AI models) +- **Pricing information** for each capability +- **Performance metrics** and capacity + +### Capability Matching + +When processing requests, the gateway: + +1. Queries discovered orchestrators for required capabilities [2](#55-1) +2. Filters by price limits (`-maxPricePerUnit` for video, + `-maxPricePerCapability` for AI) +3. Selects based on performance and availability + +## Recommended On-Chain Settings + +### Minimal Required Flags + +```yaml +command: + "-gateway -network arbitrum-one-mainnet -ethUrl=https://arb1.arbitrum.io/rpc + -aiServiceRegistry # Required for AI capabilities" +``` + +### Recommended Additions + +```yaml +command: + "-gateway -network arbitrum-one-mainnet -ethUrl=https://arb1.arbitrum.io/rpc + -aiServiceRegistry -maxPricePerUnit=1000000000 # Video price limit + -maxPricePerCapability=/path/to/ai-pricing.json # AI price limits + -monitor=true # Enable metrics" +``` + +## No Manual Orchestrator List Needed + +Unlike off-chain mode where you specify `-orchAddr`, on-chain gateways: + +- **Discover all public orchestrators** automatically +- **Update the list periodically** (every 25 minutes) +- **Handle failures** by trying alternative orchestrators + +You can verify discovery worked: + +```bash +curl http://localhost:5935/getOrchestrators +``` + +This will show all discovered orchestrators with their capabilities and pricing. + +## Notes + +- On-chain discovery requires ETH in your gateway account for transactions + [3](#55-2) +- The gateway will show "No orchestrator specified; transcoding will not happen" + if discovery fails [4](#55-3) +- Test on testnet first to avoid gas costs while verifying setup [5](#55-4) + +Wiki pages you might want to explore: + +- [Discovery and Selection (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#3.5) +- [Architecture (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#1.1) + +Wiki pages you might want to explore: + +- [Discovery and Selection (livepeer/go-livepeer)](/wiki/livepeer/go-livepeer#3.5) + +# LINUX BUILD FROM SOURCE (ELITEPROXY INFO) + +Building from source locally (on linux), usually looks like this: + +The purpose of this step is to ensure ffmpeg is built in a specific location and +does not conflict with any existing installed ffmpeg. Livepeer uses a special +ffmpeg build. + +``` +export ROOT=$HOME/buildoutput +export LD_LIBRARY_PATH=$ROOT/compiled/lib/ export +PKG_CONFIG_PATH=$ROOT/compiled/lib/pkgconfig +export PATH=$ROOT/compiled/bin/:$PATH + +./install_ffmpeg.sh $ROOT +``` + +If you wanted to build a go-livepeer docker image, you can do so from the root +of the repository using this go-livepeer from source. See +[eliteproxy_launch.json](./snippets/assets/domain/04_GATEWAYS/code_examples/eliteproxy_launch.json) +for an example VS Code launch configuration used to build and debug go-livepeer +from source. The launch config shows the same paths being used to ensure +libraries are loaded using Livepeer's ffmpeg + +### ffmpeg issues + +Forgetting to set those paths before building ffmpeg. Also needed when compiling +or debugging go-livepeer. Yes, sometimes a dev will be accidentally getting +libraries from ffmpeg installed globally or somewhat worse - you never had +ffmpeg, ran install_ffmpeg.sh then that ends up as your system ffmpeg with no +clear way to uninstall lol at least in that case, usually go-livepeer works, but +good luck with other ffmpeg builds I almost think "building from source" +deserves a mention inside of +https://github.com/livepeer/go-livepeer/blob/master/CONTRIBUTING.md if not +linked there already + +System packages I had to install to compile go-livepeer + +``` +sudo apt-get update && sudo apt-get -y install build-essential pkg-config autoconf git curl wget +sudo apt-get -y install protobuf-compiler-grpc golang-goprotobuf-dev +sudo apt-get -y install clang clang-tools +``` + +Y diff --git a/ROLLBACK-GUIDE.md b/ROLLBACK-GUIDE.md deleted file mode 100644 index 30eadb4f0..000000000 --- a/ROLLBACK-GUIDE.md +++ /dev/null @@ -1,94 +0,0 @@ -# Emergency Rollback Guide - -## Quick Rollback (Last 5 minutes) - -```bash -# See recent commits -git log --oneline -10 docs-v2-dev - -# Safe rollback - creates new commit that undoes changes -git revert - -# OR - go back to previous state without changing history -git reset --soft HEAD~1 -# Then inspect and recommit if needed -``` - -## View All Changes Since Date - -```bash -# Since last hour -git log --oneline --since="1 hour ago" docs-v2-dev - -# Since specific time -git log --oneline --since="2026-01-06 20:00:00" docs-v2-dev -``` - -## See What Changed in Last Commit - -```bash -git show HEAD -``` - -## Rollback to Specific Commit - -```bash -# List all commits -git reflog - -# Safe method: Create new commit that undoes changes -git revert - -# Restore specific file to previous version -git restore --source= - -# Go back one commit (keeps history) -git reset --soft HEAD~1 - -# NEVER use: git reset --hard (destroys history) -``` - -## If You Need to Undo Last Auto-Commit - -```bash -# See what's in the last commit -git show HEAD - -# Create a new commit that reverts it -git revert HEAD - -# OR - unstage it and inspect -git reset --soft HEAD~1 -git diff --cached -``` - -## See Diff Between Commits - -```bash -# What changed in last auto-commit -git diff HEAD~1 HEAD - -# What changed in a specific commit -git diff ~1 -``` - -## Automatic Checkpoints - -Every 5 minutes a new commit is created on docs-v2-dev with timestamp. Each -commit is a full snapshot you can revert to instantly. - -### View Commit Timeline - -```bash -git log --oneline --graph docs-v2-dev | head -20 -``` - -### Tag Safe Points (Optional) - -```bash -# Save a checkpoint -git tag checkpoint-before-gateway-work - -# Later, go back to it -git reset --hard checkpoint-before-gateway-work -``` diff --git a/UNIVERSAL-AI-PROTOCOL.md b/UNIVERSAL-AI-PROTOCOL.md deleted file mode 100644 index f720ff6a2..000000000 --- a/UNIVERSAL-AI-PROTOCOL.md +++ /dev/null @@ -1,202 +0,0 @@ -# Universal AI Operations Protocol - -## For ANY AI Assistant Working on This Repository - -**Last Updated:** 2026-01-06 -**Created After:** Catastrophic AI failure destroying 12+ files and 318+ files -through formatting disaster - ---- - -## CRITICAL RULES FOR ALL AI ASSISTANTS - -### Rule 1: PROTECTED BRANCHES - UNTOUCHABLE - -``` -docs-v2 = SOURCE OF TRUTH -main = PRODUCTION - -NO AI ASSISTANT IS ALLOWED TO: -- Commit to these branches -- Push to these branches -- Merge into these branches -- Delete these branches -``` - -### Rule 2: PRE-FLIGHT CHECKLIST (EVERY OPERATION) - -Before ANY git command, the AI MUST show you: - -``` -[PREFLIGHT CHECK] -Operating on branch: ________ -Files affected: ________ -Operation: ________ -Expected outcome: ________ - -Proceed? (yes/no) -``` - -**If you don't see this, STOP and ask the AI to show it.** - -### Rule 3: FORBIDDEN COMMANDS (ABSOLUTE) - -``` -❌ NEVER ALLOWED: -- git reset --hard -- git restore . -- git clean -fd -- git push --force -- git rebase -i -- git tag --force -- Mass operations > 50 files without approval -``` - -### Rule 4: LARGE CHANGE PROTOCOL (> 10 files) - -``` -1. AI lists EXACT files being modified -2. AI shows file count and brief explanation -3. Human reviews and approves EXPLICITLY -4. Human creates approval token if needed -5. AI proceeds ONLY after approval -``` - -### Rule 5: COMMIT MESSAGE REQUIREMENTS - -Every commit must include: - -``` -[File count] | [What changed] | [Why changed] | [Approved by: USERNAME] - -Example: -[9 files added] | Restore gateway quickstart files | Fix missing imports from stash | Approved by: alisonhaire -``` - -### Rule 6: FORBIDDEN FILE PATTERNS - -``` -❌ AI must NOT touch without explicit approval: -- .prettierrc, .prettierignore -- docs.json, docs_v2.json -- package.json -- v2/ structure changes -- v1/ any changes (legacy) -- ./git/* (git config) -- Migration of files between v1 and v2 -``` - -### Rule 7: DANGEROUS OPERATION ALERTS - -AI MUST WARN before: - -- Restoring files from commits > 24 hours old -- Deleting ANY file -- Renaming directories -- Changing file structure -- Mass reformatting operations - -### Rule 8: AUDIT TRAIL REQUIREMENT - -Every operation logs to: `.ai-operations.log` - -``` -[TIMESTAMP] BRANCH=docs-v2-dev | FILES=9 | OP=restore | APPROVAL=yes | COMMIT=abc123 -``` - -### Rule 9: CHECKPOINT SYSTEM - -- Auto-commits every 5 minutes on `docs-v2-dev` -- Each commit is tagged with timestamp -- Rollback available to ANY point in last 24 hours -- Tags: `state-before-OPERATION` and `state-after-OPERATION` - -### Rule 10: DRY-RUN FOR COMPLEX OPS - -Before any operation affecting > 5 files: - -``` -1. AI shows DRY-RUN (what WOULD happen) -2. Human reviews -3. Human approves -4. AI executes REAL operation -5. AI shows ACTUAL result -``` - ---- - -## EMERGENCY PROCEDURES - -### If AI Breaks Something - -```bash -# 1. Get the commit hash -git log --oneline docs-v2-dev | head -1 - -# 2. See what broke -git show HEAD - -# 3. Revert it (creates new commit undoing changes) -git revert HEAD - -# 4. Or unstage and inspect -git reset --soft HEAD~1 -``` - -### If AI Touches Protected Branch - -```bash -# Check what happened -git log docs-v2 --oneline -5 - -# Force restore from remote -git fetch origin -git reset --soft origin/docs-v2 -``` - -### If AI Tries Forbidden Command - -The pre-commit hook will block it automatically. - ---- - -## HUMAN RESPONSIBILITY CHECKLIST - -Before each AI session with YOUR docs: - -- [ ] Review protected branches list -- [ ] Know your current branch -- [ ] Have rollback commands ready (see ROLLBACK-GUIDE.md) -- [ ] Verify AI shows preflight checklist EVERY TIME -- [ ] Never let AI skip approval for > 10 file changes -- [ ] Check audit log (.ai-operations.log) regularly - ---- - -## FOR INSTRUCTING ANY NEW AI - -Include this in your prompt to any AI: - -``` -"You are working on a repository with STRICT AI safety protocols. -You MUST: -1. Never commit to docs-v2 or main -2. Show preflight checklist before every operation -3. Get explicit approval for any change > 10 files -4. Never use: git reset --hard, git restore ., git clean -fd -5. Log all operations to .ai-operations.log -6. Work only on docs-v2-dev branch for commits -7. Reference UNIVERSAL-AI-PROTOCOL.md for complete rules" -``` - ---- - -## VERSION CONTROL FOR THIS PROTOCOL - -- Created: 2026-01-06 after catastrophic AI failure -- Enforced by: `.git/hooks/pre-commit` (technical enforcement) -- Audited by: `.ai-operations.log` (human review) -- Rollback by: `ROLLBACK-GUIDE.md` (recovery procedures) - -**This protocol is NOT optional. It is the safety layer that prevents -irreversible damage.** diff --git a/docs.json b/docs.json index 1d7770423..8886cd62f 100644 --- a/docs.json +++ b/docs.json @@ -6,9 +6,9 @@ "timestamp": true }, "colors": { - "primary": "#18794E", + "primary": "#3CB540", "light": "#2b9a66", - "dark": "#18794E" + "dark": "#3CB540" }, "favicon": "/favicon.png", "navigation": { @@ -20,32 +20,6 @@ { "language": "en", "tabs": [ - { - "tab": "Internal Hub", - "hidden": true, - "icon": "info-circle", - "anchors": [ - { - "anchor": "Internal Hub", - "icon": "info-circle", - "groups": [ - { - "group": "Internal Hub", - "pages": [ - "v2/pages/09_internal/internal-overview", - "v2/pages/09_internal/docs-status", - "v2/pages/09_internal/strategic-alignment", - "v2/pages/09_internal/docs-philosophy", - "v2/pages/09_internal/definitions", - "v2/pages/09_internal/personas", - "v2/pages/09_internal/ecosystem", - "v2/pages/09_internal/references" - ] - } - ] - } - ] - }, { "tab": "Home", "icon": "house-heart", @@ -58,65 +32,64 @@ "group": "Home", "icon": "house-heart", "pages": [ - "v2/pages/00_home/Landing", - "v2/pages/00_home/home/livepeer-tl-dr", - "v2/pages/00_home/home/trending-at-livepeer" + "v2/pages/00_home/mission-control", + "v2/pages/00_home/home/primer", + "v2/pages/00_home/home/trending-topics" ] }, { - "group": "Livepeer Showcase", - "icon": "clapperboard-play", + "group": "Livepeer", + "icon": "/snippets/assets/logos/Livepeer-Logo-Symbol-Light.svg", "pages": [ - "v2/pages/00_home/project-showcase/projects-built-on-livepeer", - "v2/pages/00_home/project-showcase/livepeer-applications", - "v2/pages/00_home/project-showcase/industry-verticals" + "v2/pages/00_home/introduction/livepeer-story", + "v2/pages/00_home/introduction/livepeer-vision", + "v2/pages/00_home/introduction/livepeer-future", + "v2/pages/00_home/introduction/livepeer-ecosystem" ] }, { - "group": "Get Started", - "icon": "arrow-right-to-bracket", + "group": "Showcase", + "icon": "clapperboard-play", "pages": [ - "v2/pages/00_home/get-started/use-livepeer", - "v2/pages/00_home/get-started/stream-video-quickstart", - "v2/pages/00_home/get-started/livepeer-ai-quickstart", - "v2/pages/00_home/get-started/build-on-livepeer" + "v2/pages/00_home/project-showcase/projects-built-on-livepeer", + "v2/pages/00_home/project-showcase/livepeer-applications", + "v2/pages/00_home/project-showcase/industry-verticals" ] } ] }, { - "anchor": "Reference HUB", - "icon": "books", - "pages": ["v2/pages/07_resources/redirect"] + "anchor": "Get Started!", + "icon": "play", + "pages": ["v2/pages/03_developers/"] }, { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] + "anchor": "Resource HUB", + "icon": "books", + "pages": ["v2/pages/07_resources/redirect"] }, { "anchor": " ", - "icon": "-", - "href": " " + "icon": "horizontal-rule", + "pages": [" "] } ] }, { "tab": "About", - "icon": "graduation-cap", + "icon": "camera-movie", "anchors": [ { "anchor": "About Livepeer", - "icon": "graduation-cap", + "icon": "play", "groups": [ { "group": "About Livepeer", "icon": "graduation-cap", "pages": [ - "v2/pages/01_about/about-livepeer/livepeer-overview", - "v2/pages/01_about/about-livepeer/why-livepeer", - "v2/pages/01_about/about-livepeer/livepeer-evolution", - "v2/pages/01_about/about-livepeer/livepeer-ecosystem" + "v2/pages/01_about/about-portal", + "v2/pages/01_about/core-concepts/livepeer-core-concepts", + "v2/pages/01_about/core-concepts/livepeer-glossary" ] }, { @@ -125,102 +98,95 @@ "pages": [ "v2/pages/01_about/livepeer-protocol/protocol-overview", "v2/pages/01_about/livepeer-protocol/livepeer-whitepaper", - "v2/pages/01_about/livepeer-protocol/technical-overview" + "v2/pages/01_about/livepeer-protocol/technical-overview", + "v2/pages/01_about/livepeer-protocol/protocol-mechanisms" ] }, { "group": "Livepeer Network", "icon": "circle-nodes", "pages": [ + "v2/pages/01_about/livepeer-network/network-overview", "v2/pages/01_about/livepeer-network/actor-overview", - "v2/pages/01_about/livepeer-network/livepeer-token-economics", - "v2/pages/01_about/livepeer-network/livepeer-governance" + "v2/pages/01_about/livepeer-network/governance-model", + "v2/pages/01_about/livepeer-network/token", + "v2/pages/01_about/livepeer-network/treasury" ] } ] }, { - "anchor": "Reference HUB", + "anchor": "Resource HUB", "icon": "books", "pages": ["v2/pages/07_resources/redirect"] }, - { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] - }, { "anchor": " ", - "icon": "-", - "href": " " + "icon": "horizontal-rule", + "pages": [" "] } ] }, { - "tab": "Community", - "icon": "people-group", + "tab": "Products", + "icon": "film-canister", "anchors": [ { - "anchor": "Community", - "icon": "people-group", + "anchor": "Products", + "icon": "display-code", "groups": [ { - "group": "Livepeer Community", - "icon": "people-group", + "group": "Use Livepeer", + "icon": "play", "pages": [ - "v2/pages/02_community/community-home", - "v2/pages/02_community/livepeer-community/livepeer-Latest-Topics", - "v2/pages/02_community/livepeer-community/community-guidelines" + "v2/pages/010_products/products-portal", + "v2/pages/010_products/products/builder-hub" ] }, { - "group": "Livepeer Connect", - "icon": "hashtag", + "group": "Daydream", + "icon": "video-camera", "pages": [ - "v2/pages/02_community/livepeer-connect/news-and-socials", - "v2/pages/02_community/livepeer-connect/events-and-community-streams", - "v2/pages/02_community/livepeer-connect/forums-and-discussions" + "v2/pages/010_products/products/daydream/daydream" ] }, { - "group": "Livepeer Contribute", - "icon": "door-open", + "group": "Livepeer Studio", + "icon": "user-robot", "pages": [ - "v2/pages/02_community/livepeer-contribute/contribute", - "v2/pages/02_community/livepeer-contribute/opportunities", - "v2/pages/02_community/livepeer-contribute/build-livepeer" + "v2/pages/010_products/products/livepeer-studio/livepeer-studio" ] }, { - "group": "[MOVE HERE] Help Center", - "icon": "comments-question-check", - "hidden": true, + "group": "Stream.place", + "icon": "video-camera", "pages": [ - "v2/pages/02_community/livepeer-community/trending-test" + "v2/pages/010_products/products/streamplace/streamplace", + "v2/pages/010_products/products/streamplace/streamplace-guide", + "v2/pages/010_products/products/streamplace/streamplace-architecture", + "v2/pages/010_products/products/streamplace/streamplace-integration", + "v2/pages/010_products/products/streamplace/streamplace-provenance", + "v2/pages/010_products/products/streamplace/streamplace-funding" ] }, { - "group": "[TO DELETE] Tests", + "group": "All Ecosystem Products", + "icon": "video-camera", "pages": [ - "v2/pages/02_community/livepeer-community/trending-test" + "v2/pages/010_products/products/all-ecosystem/ecosystem-products" ] } ] }, { - "anchor": "Reference HUB", + "anchor": "Resource HUB", "icon": "books", "pages": ["v2/pages/07_resources/redirect"] }, - { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] - }, { "anchor": " ", - "icon": "-", - "href": " " + "icon": "horizontal-rule", + "pages": [" "] } ] }, @@ -236,81 +202,45 @@ "group": "Building on Livepeer", "icon": "code", "pages": [ - "v2/pages/03_developers/developer-home", - "v2/pages/03_developers/building-on-livepeer/developer-guide" - ] - }, - { - "group": "Quickstart", - "icon": "fast-forward", - "pages": [ - { - "group": "Real-time Video", - "pages": [ - "v2/pages/03_developers/building-on-livepeer/quick-starts/livepeer-ai", - "v2/pages/03_developers/livepeer-real-time-video/video-streaming-on-livepeer/README.mdx" - ] - }, - { - "group": "AI Pipelines", - "pages": [ - "v2/pages/03_developers/building-on-livepeer/quick-starts/video-streaming", - "v2/pages/03_developers/building-on-livepeer/quick-starts/livepeer-ai" - ] - } - ] - }, - { - "group": "Developer Platforms", - "icon": "gear-code", - "pages": [ - "v2/pages/03_developers/developer-platforms/builder-hub", - { - "group": "Daydream", - "pages": [ - "v2/pages/03_developers/developer-platforms/daydream/daydream" - ] - }, - { - "group": "Livepeer Studio", - "pages": [ - "v2/pages/03_developers/developer-platforms/livepeer-studio/livepeer-studio" - ] - }, - { - "group": "Frameworks", - "pages": [ - "v2/pages/03_developers/developer-platforms/frameworks/frameworks" - ] - }, - { - "group": "Streamplace", - "pages": [ - "v2/pages/03_developers/developer-platforms/streamplace/streamplace" - ] - }, + "v2/pages/03_developers/developer-portal", + "v2/pages/03_developers/building-on-livepeer/developer-guide", { - "group": "All Ecosystem Products", + "group": "Quickstart", + "icon": "fast-forward", + "expanded": true, "pages": [ - "v2/pages/03_developers/developer-platforms/all-ecosystem/ecosystem-products/ecosystem-products" + { + "group": "Real-time Video", + "pages": [ + "v2/pages/03_developers/building-on-livepeer/quick-starts/livepeer-ai", + "v2/pages/03_developers/livepeer-real-time-video/video-streaming-on-livepeer/README.mdx" + ] + }, + { + "group": "AI Pipelines", + "pages": [ + "v2/pages/03_developers/building-on-livepeer/quick-starts/video-streaming", + "v2/pages/03_developers/building-on-livepeer/quick-starts/livepeer-ai" + ] + } ] } ] }, { - "group": "Developer Tools", - "icon": "tools", + "group": "AI Pipelines", + "icon": "user-robot", "pages": [ - "v2/pages/03_developers/developer-tools/tooling-hub", - "v2/pages/03_developers/developer-tools/livepeer-explorer", - "v2/pages/03_developers/developer-tools/livepeer-cloud", - "v2/pages/03_developers/developer-tools/dashboards" + "v2/pages/03_developers/ai-inference-on-livepeer/ai-pipelines/overview", + "v2/pages/03_developers/ai-inference-on-livepeer/ai-pipelines/byoc", + "v2/pages/03_developers/ai-inference-on-livepeer/ai-pipelines/comfystream" ] }, { "group": "Guides & Tutorials", "icon": "laptop-file", "pages": [ + "v2/pages/03_developers/building-on-livepeer/developer-guide", "v2/pages/03_developers/guides-and-resources/developer-guides", "v2/pages/03_developers/guides-and-resources/resources", "v2/pages/03_developers/guides-and-resources/developer-help", @@ -324,6 +254,27 @@ "v2/pages/03_developers/builder-opportunities/dev-programs", "v2/pages/03_developers/builder-opportunities/livepeer-rfps" ] + } + ] + }, + { + "anchor": "Resource HUB", + "icon": "books", + "pages": ["v2/pages/07_resources/redirect"] + }, + { + "anchor": " ", + "icon": "horizontal-rule", + "pages": [ + { + "group": "Developer Tools", + "icon": "tools", + "pages": [ + "v2/pages/03_developers/developer-tools/tooling-hub", + "v2/pages/03_developers/developer-tools/livepeer-explorer", + "v2/pages/03_developers/developer-tools/livepeer-cloud", + "v2/pages/03_developers/developer-tools/dashboards" + ] }, { "group": "Technical References", @@ -350,21 +301,6 @@ ] } ] - }, - { - "anchor": "Reference HUB", - "icon": "books", - "pages": ["v2/pages/07_resources/redirect"] - }, - { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] - }, - { - "anchor": " ", - "icon": "-", - "href": " " } ] }, @@ -380,7 +316,7 @@ "group": "About Gateways", "icon": "graduation-cap", "pages": [ - "v2/pages/04_gateways/gateways-home", + "v2/pages/04_gateways/gateways-portal", { "group": "Gateway Knowledge Hub", "expanded": true, @@ -393,6 +329,14 @@ } ] }, + { + "group": "Quickstart", + "icon": "/snippets/assets/logos/Livepeer-Logo-Symbol-Light.svg", + "pages": [ + "v2/pages/04_gateways/run-a-gateway/quickstart-a-gateway", + "v2/pages/04_gateways/run-a-gateway/get-AI-to-setup-the-gateway" + ] + }, { "group": "Gateway Services & Providers", "icon": "wand-magic-sparkles", @@ -564,22 +508,9 @@ ] }, { - "anchor": "Quickstart", - "icon": "fast-forward", - "pages": [ - "v2/pages/04_gateways/run-a-gateway/quickstart-a-gateway", - "v2/pages/04_gateways/run-a-gateway/get-AI-to-setup-the-gateway" - ] - }, - { - "anchor": "Quick Links", - "icon": "person-to-portal", - "pages": ["v2/pages/04_gateways/references/"] - }, - { - "anchor": "Resources", + "anchor": "Resource HUB", "icon": "books", - "pages": ["v2/pages/04_gateways/references/"] + "pages": ["v2/pages/07_resources/redirect"] }, { "anchor": " ", @@ -600,7 +531,7 @@ "group": "About Orchestrators (GPU Nodes)", "icon": "graduation-cap", "pages": [ - "v2/pages/05_orchestrators/orchestrators-home", + "v2/pages/05_orchestrators/orchestrators-portal", "v2/pages/05_orchestrators/about-orchestrators/overview", { "group": "Orchestrator Functions", @@ -647,24 +578,19 @@ ] }, { - "anchor": "Reference HUB", + "anchor": "Resource HUB", "icon": "books", "pages": ["v2/pages/07_resources/redirect"] }, - { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] - }, { "anchor": " ", - "icon": "-", - "href": " " + "icon": "horizontal-rule", + "pages": [" "] } ] }, { - "tab": "Delegators & LPT", + "tab": "LP Token", "icon": "hand-holding-dollar", "anchors": [ { @@ -675,7 +601,7 @@ "group": "About LPT", "icon": "graduation-cap", "pages": [ - "v2/pages/06_delegators/token-home", + "v2/pages/06_delegators/token-portal", "v2/pages/06_delegators/about-lpt-livepeer-token/overview", "v2/pages/06_delegators/about-lpt-livepeer-token/why-have-a-token", "v2/pages/06_delegators/about-lpt-livepeer-token/livepeer-token-economics", @@ -703,7 +629,7 @@ }, { "group": "Livepeer Treasury", - "pages": [] + "pages": [" "] }, { "group": "Guides & Resources", @@ -716,24 +642,82 @@ ] }, { - "anchor": "Reference HUB", + "anchor": "Resource HUB", "icon": "books", "pages": ["v2/pages/07_resources/redirect"] }, { - "anchor": "Help Center", - "icon": "comments-question-check", - "pages": ["v2/pages/08_help/redirect"] + "anchor": " ", + "icon": "horizontal-rule", + "pages": [" "] + } + ] + }, + { + "tab": "Community", + "icon": "people-group", + "anchors": [ + { + "anchor": "Community", + "icon": "people-group", + "groups": [ + { + "group": "Livepeer Community", + "icon": "people-group", + "pages": [ + "v2/pages/02_community/community-portal", + "v2/pages/02_community/livepeer-community/livepeer-Latest-Topics", + "v2/pages/02_community/livepeer-community/community-guidelines" + ] + }, + { + "group": "Livepeer Connect", + "icon": "hashtag", + "pages": [ + "v2/pages/02_community/livepeer-connect/news-and-socials", + "v2/pages/02_community/livepeer-connect/events-and-community-streams", + "v2/pages/02_community/livepeer-connect/forums-and-discussions" + ] + }, + { + "group": "Livepeer Contribute", + "icon": "door-open", + "pages": [ + "v2/pages/02_community/livepeer-contribute/contribute", + "v2/pages/02_community/livepeer-contribute/opportunities", + "v2/pages/02_community/livepeer-contribute/build-livepeer" + ] + }, + { + "group": "[MOVE HERE] Help Center", + "icon": "comments-question-check", + "hidden": true, + "pages": [ + "v2/pages/02_community/livepeer-community/trending-test" + ] + }, + { + "group": "[TO DELETE] Tests", + "pages": [ + "v2/pages/02_community/livepeer-community/trending-test" + ] + } + ] + }, + { + "anchor": "Resource HUB", + "icon": "books", + "pages": ["v2/pages/07_resources/redirect"] }, { "anchor": " ", - "icon": "-", - "href": " " + "icon": "horizontal-rule", + "pages": [" "] } ] }, { - "tab": "Reference HUB", + "tab": "Resource HUB", "hidden": false, "icon": "books", "anchors": [ @@ -744,7 +728,7 @@ { "group": "Home", "icon": "house", - "pages": ["v2/pages/07_resources/resources_hub"] + "pages": ["v2/pages/07_resources/resources-portal"] }, { "group": "Documentation Guide", @@ -808,7 +792,7 @@ "pages": [ { "group": "Protocol References", - "pages": [] + "pages": [" "] } ] }, @@ -829,7 +813,7 @@ }, { "anchor": " ", - "icon": "-", + "icon": "horizontal-rule", "href": " " } ] @@ -849,24 +833,24 @@ }, { "group": "Delegating LPT", - "pages": [] + "pages": [" "] }, { "group": "Livepeer Governance", - "pages": [] + "pages": [" "] }, { "group": "Livepeer Treasury", - "pages": [] + "pages": [" "] }, { "group": "Token Resources", - "pages": [] + "pages": [" "] } ] }, { - "anchor": "Reference HUB", + "anchor": "Resource HUB", "icon": "books", "pages": ["v2/pages/07_resources/redirect"] }, @@ -876,6 +860,32 @@ "href": " " } ] + }, + { + "tab": "Internal Hub", + "hidden": true, + "icon": "info-circle", + "anchors": [ + { + "anchor": "Internal Hub", + "icon": "info-circle", + "groups": [ + { + "group": "Internal Hub", + "pages": [ + "v2/pages/09_internal/internal-overview", + "v2/pages/09_internal/docs-status", + "v2/pages/09_internal/strategic-alignment", + "v2/pages/09_internal/docs-philosophy", + "v2/pages/09_internal/definitions", + "v2/pages/09_internal/personas", + "v2/pages/09_internal/ecosystem", + "v2/pages/09_internal/references" + ] + } + ] + } + ] } ] } @@ -3007,7 +3017,7 @@ "redirects": [ { "source": "/v2/pages/07_resources/redirect", - "destination": "/v2/pages/07_resources/resources_hub" + "destination": "/v2/pages/07_resources/resources-portal" }, { "source": "/v2/pages/08_help/redirect", diff --git a/scripts/download-linkedin-video.sh b/scripts/download-linkedin-video.sh new file mode 100644 index 000000000..f9ff250b0 --- /dev/null +++ b/scripts/download-linkedin-video.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Download LinkedIn video using yt-dlp +# Usage: ./scripts/download-linkedin-video.sh + +LINKEDIN_URL="https://www.linkedin.com/feed/update/urn:li:ugcPost:7387171661868933120" +OUTPUT_DIR="snippets/assets/media/videos" +OUTPUT_FILE="livepeer-founders-post.mp4" + +# Create output directory if it doesn't exist +mkdir -p "$OUTPUT_DIR" + +# Check if yt-dlp is installed +if ! command -v yt-dlp &> /dev/null; then + echo "yt-dlp is not installed. Installing via brew..." + brew install yt-dlp +fi + +# Download the video +echo "Downloading LinkedIn video..." +yt-dlp "$LINKEDIN_URL" -o "$OUTPUT_DIR/$OUTPUT_FILE" + +if [ $? -eq 0 ]; then + echo "✅ Video downloaded successfully to: $OUTPUT_DIR/$OUTPUT_FILE" +else + echo "❌ Failed to download video. Try one of these alternatives:" + echo "1. Use https://www.linkedin-video-downloader.com/" + echo "2. Use browser DevTools Network tab" + echo "3. Use a browser extension like Video DownloadHelper" +fi + diff --git a/scripts/download-linkedin-with-cookies.sh b/scripts/download-linkedin-with-cookies.sh new file mode 100644 index 000000000..85cf7ced5 --- /dev/null +++ b/scripts/download-linkedin-with-cookies.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Download LinkedIn video using yt-dlp with browser cookies +# This uses your logged-in session to download the video + +LINKEDIN_URL="https://www.linkedin.com/posts/livepeer_livepeer-mission-to-represent-open-video-activity-7287171661868933120-Uo-7" +OUTPUT_DIR="snippets/assets/media/videos" +OUTPUT_FILE="livepeer-founders-post.mp4" + +# Create output directory if it doesn't exist +mkdir -p "$OUTPUT_DIR" + +echo "Downloading LinkedIn video using browser cookies..." +echo "This will use your logged-in LinkedIn session from Chrome/Firefox/Safari" +echo "" + +# Try with different browsers (yt-dlp will auto-detect) +yt-dlp \ + --cookies-from-browser chrome \ + "$LINKEDIN_URL" \ + -o "$OUTPUT_DIR/$OUTPUT_FILE" \ + --no-warnings + +if [ $? -ne 0 ]; then + echo "" + echo "Chrome cookies failed. Trying Firefox..." + yt-dlp \ + --cookies-from-browser firefox \ + "$LINKEDIN_URL" \ + -o "$OUTPUT_DIR/$OUTPUT_FILE" \ + --no-warnings +fi + +if [ $? -ne 0 ]; then + echo "" + echo "Firefox cookies failed. Trying Safari..." + yt-dlp \ + --cookies-from-browser safari \ + "$LINKEDIN_URL" \ + -o "$OUTPUT_DIR/$OUTPUT_FILE" \ + --no-warnings +fi + +if [ $? -eq 0 ]; then + echo "" + echo "✅ Video downloaded successfully to: $OUTPUT_DIR/$OUTPUT_FILE" +else + echo "" + echo "❌ All methods failed. Please try manual download:" + echo "1. Screen record the video (Cmd+Shift+5 on Mac)" + echo "2. Use a browser extension like Video DownloadHelper" + echo "3. Use an online downloader (may not work for private posts)" +fi + diff --git a/snippets/README.md b/snippets/README.md new file mode 100644 index 000000000..dbddf93e2 --- /dev/null +++ b/snippets/README.md @@ -0,0 +1,6 @@ +See the +[Livepeer Snippets Wiki](https://livepeer-docs-git-docs-v2-livepeer.vercel.app/snippets/wiki/index) +for more information on the snippets folder, its organisation & structure, data, +pages & Livepeer components library within. + +See folders for readme's on specific content. diff --git a/snippets/apiSpecs/README.md b/snippets/apiSpecs/README.md deleted file mode 100644 index 5ead7ff5a..000000000 --- a/snippets/apiSpecs/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# ELI5: Generate API Docs in Mintlify - -Follow these super simple steps to turn an OpenAPI spec (YAML/JSON) into -Mintlify docs. - -## 1) Install Mintlify (first time only) - -```bash -npm i -g mintlify -``` - -## 2) Pick your OpenAPI spec and output folder - -- Spec file: for example `ai/worker/api/openapi.yaml` -- Output folder: where the generated MDX pages go, e.g. - `v2/pages/04_gateways/guides-references/api-reference/CLI-HTTP` -- Title: a friendly name shown in nav, e.g. `"CLI HTTP"` - -## 3) Run the generator script - -From the repo root: - -```bash -./v2/scripts/generate-api-docs.sh ai/worker/api/openapi.yaml v2/pages/04_gateways/guides-references/api-reference/CLI-HTTP "CLI HTTP" -``` - -Examples: - -```bash -# AI API example -./v2/scripts/generate-api-docs.sh ai/worker/api/openapi.yaml v2/pages/04_gateways/guides-references/api-reference/AI-API "AI API" - -# CLI HTTP example -./v2/scripts/generate-api-docs.sh ai/worker/api/openapi.yaml v2/pages/04_gateways/guides-references/api-reference/CLI-HTTP "CLI HTTP" -``` - -## 4) What gets created - -- MDX pages inside your chosen output folder -- A navigation snippet for `docs.json` (list of page paths as strings) - -## 5) Add the pages to `docs.json` - -Open [docs.json](docs.json) and include the generated pages under the right -group. Important: each item inside `pages` must be a string path. - -Example: - -```json -{ - "group": "CLI HTTP API", - "pages": [ - "v2/pages/04_gateways/guides-references/api-reference/CLI-HTTP/overview", - "v2/pages/04_gateways/guides-references/api-reference/CLI-HTTP/reference" - ] -} -``` - -## 6) Preview locally - -```bash -mint dev -``` - -Open the local preview and click into the new group to see the generated API -docs. - -## 7) Troubleshooting (ELI5) - -- Error: "Incorrect type. Expected string": make sure every entry in `pages` is - a string path (no objects). -- Pages not showing: double-check the output folder path matches what you put in - `docs.json`. -- Need to regenerate: rerun the script after updating your OpenAPI spec. - -## 8) Optional: Build via Docker or Makefile - -```bash -# Docker build (amd64) -docker buildx build --platform linux/amd64 --load -t livepeer/docs . - -# Makefile build -make all -``` diff --git a/snippets/assets/README.mdx b/snippets/assets/README.mdx new file mode 100644 index 000000000..80ca3fef6 --- /dev/null +++ b/snippets/assets/README.mdx @@ -0,0 +1,31 @@ +Assets Folder Structure: + +These assets are organised **By Type** and **By Domain** + +**By Type:** General-purpose assets used across the site (logos, icons, images, videos, data). + +**By Domain:** Page-specific assets organised by documentation section. + +```bash +assets/ +├── logos/ # Brand logos and symbols +│ ├── Livepeer-Logo-Symbol.svg +│ ├── Livepeer-Logo-Symbol-Light.svg +│ └── Livepeer-Logo-Symbol-Theme.svg # Auto-switches dark/light mode colour +├── media/ # General media assets +│ ├── icons/ # Reusable custom icons +│ ├── images/ # Reusable images +│ └── videos/ # Reusable videos +└── domain/ # Domain-specific assets by section + ├── SHARED/ # Assets shared across sections + ├── SITE/ # Site-wide assets (favicon, etc.) + ├── 00_HOME/ + ├── 01_ABOUT/ + ├── 02_COMMUNITY/ + ├── 03_DEVELOPERS/ + ├── 04_GATEWAYS/ + ├── 05_ORCHESTRATORS/ + ├── 06_TOKEN/ + ├── 07_REFERENCES/ + └── 08_OTHER/ +``` diff --git a/v2/assets/technical/Architecture_go-livepeer_DeepWiki.htm b/snippets/assets/data/Architecture_go-livepeer_DeepWiki.htm similarity index 100% rename from v2/assets/technical/Architecture_go-livepeer_DeepWiki.htm rename to snippets/assets/data/Architecture_go-livepeer_DeepWiki.htm diff --git a/v2/assets/technical/DeepWiki_TA-Flows.htm b/snippets/assets/data/DeepWiki_TA-Flows.htm similarity index 100% rename from v2/assets/technical/DeepWiki_TA-Flows.htm rename to snippets/assets/data/DeepWiki_TA-Flows.htm diff --git a/v2/assets/technical/protocol-overview.html b/snippets/assets/data/protocol-overview.html similarity index 100% rename from v2/assets/technical/protocol-overview.html rename to snippets/assets/data/protocol-overview.html diff --git a/v2/assets/about/Building the Decentralized Generative AI Tech Stack.png b/snippets/assets/domain/00_HOME/Building the Decentralized Generative AI Tech Stack.png similarity index 100% rename from v2/assets/about/Building the Decentralized Generative AI Tech Stack.png rename to snippets/assets/domain/00_HOME/Building the Decentralized Generative AI Tech Stack.png diff --git a/v2/assets/about/Eric Shreck Gif.gif b/snippets/assets/domain/00_HOME/Eric Shreck Gif.gif similarity index 100% rename from v2/assets/about/Eric Shreck Gif.gif rename to snippets/assets/domain/00_HOME/Eric Shreck Gif.gif diff --git a/v2/assets/hero/hero_about.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_about.png similarity index 100% rename from v2/assets/hero/hero_about.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_about.png diff --git a/snippets/assets/domain/00_HOME/Hero_Images/hero_ai_run.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_ai_run.png new file mode 100644 index 000000000..4d0f7e112 Binary files /dev/null and b/snippets/assets/domain/00_HOME/Hero_Images/hero_ai_run.png differ diff --git a/v2/assets/hero/hero_community.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_community.png similarity index 100% rename from v2/assets/hero/hero_community.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_community.png diff --git a/v2/assets/hero/hero_delegators.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_delegators.png similarity index 100% rename from v2/assets/hero/hero_delegators.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_delegators.png diff --git a/v2/assets/hero/hero_developer.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_developer.png similarity index 100% rename from v2/assets/hero/hero_developer.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_developer.png diff --git a/v2/assets/hero/hero_developer1.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_developer1.png similarity index 100% rename from v2/assets/hero/hero_developer1.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_developer1.png diff --git a/v2/assets/hero/hero_developer_logo.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_developer_logo.png similarity index 100% rename from v2/assets/hero/hero_developer_logo.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_developer_logo.png diff --git a/v2/assets/hero/hero_gateways.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_gateways.png similarity index 100% rename from v2/assets/hero/hero_gateways.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_gateways.png diff --git a/v2/assets/hero/hero_gpu.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_gpu.png similarity index 100% rename from v2/assets/hero/hero_gpu.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_gpu.png diff --git a/v2/assets/hero/hero_help.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_help.png similarity index 100% rename from v2/assets/hero/hero_help.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_help.png diff --git a/v2/assets/hero/hero_logo_developer.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_logo_developer.png similarity index 100% rename from v2/assets/hero/hero_logo_developer.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_logo_developer.png diff --git a/v2/assets/hero/hero_logo_developer_sml.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_logo_developer_sml.png similarity index 100% rename from v2/assets/hero/hero_logo_developer_sml.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_logo_developer_sml.png diff --git a/v2/assets/hero/hero_logo_new.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_logo_new.png similarity index 100% rename from v2/assets/hero/hero_logo_new.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_logo_new.png diff --git a/v2/assets/hero/hero_opportunity.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_opportunity.png similarity index 100% rename from v2/assets/hero/hero_opportunity.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_opportunity.png diff --git a/v2/assets/hero/hero_partner.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_partner.png similarity index 100% rename from v2/assets/hero/hero_partner.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_partner.png diff --git a/v2/assets/hero/hero_reference.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_reference.png similarity index 100% rename from v2/assets/hero/hero_reference.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_reference.png diff --git a/v2/assets/home/Hero_Images/hero_research.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_research.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_research.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_research.png diff --git a/v2/assets/hero/hero_researchers.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_researchers.png similarity index 100% rename from v2/assets/hero/hero_researchers.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_researchers.png diff --git a/v2/assets/hero/hero_showcase.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_showcase.png similarity index 100% rename from v2/assets/hero/hero_showcase.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_showcase.png diff --git a/snippets/assets/domain/00_HOME/Hero_Images/hero_video_stream.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_video_stream.png new file mode 100644 index 000000000..80794db64 Binary files /dev/null and b/snippets/assets/domain/00_HOME/Hero_Images/hero_video_stream.png differ diff --git a/v2/assets/hero/hero_word_NEW.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_word_NEW.png similarity index 100% rename from v2/assets/hero/hero_word_NEW.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_word_NEW.png diff --git a/v2/assets/hero/hero_word_developer.png b/snippets/assets/domain/00_HOME/Hero_Images/hero_word_developer.png similarity index 100% rename from v2/assets/hero/hero_word_developer.png rename to snippets/assets/domain/00_HOME/Hero_Images/hero_word_developer.png diff --git "a/v2/assets/about/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" "b/snippets/assets/domain/00_HOME/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" similarity index 100% rename from "v2/assets/about/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" rename to "snippets/assets/domain/00_HOME/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" diff --git a/v2/assets/home/Livepeer-Logo-Full-Dark.svg b/snippets/assets/domain/00_HOME/Livepeer-Logo-Full-Dark.svg similarity index 100% rename from v2/assets/home/Livepeer-Logo-Full-Dark.svg rename to snippets/assets/domain/00_HOME/Livepeer-Logo-Full-Dark.svg diff --git a/v2/assets/home/Livepeer-Logo-Full-Light.svg b/snippets/assets/domain/00_HOME/Livepeer-Logo-Full-Light.svg similarity index 100% rename from v2/assets/home/Livepeer-Logo-Full-Light.svg rename to snippets/assets/domain/00_HOME/Livepeer-Logo-Full-Light.svg diff --git a/v2/assets/about/image.png b/snippets/assets/domain/00_HOME/evolution.png similarity index 100% rename from v2/assets/about/image.png rename to snippets/assets/domain/00_HOME/evolution.png diff --git a/v2/assets/home/livepeer logo.png b/snippets/assets/domain/00_HOME/livepeer logo.png similarity index 100% rename from v2/assets/home/livepeer logo.png rename to snippets/assets/domain/00_HOME/livepeer logo.png diff --git a/v2/assets/home/livepeer_evolution_slide.png b/snippets/assets/domain/00_HOME/livepeer_evolution_slide.png similarity index 100% rename from v2/assets/home/livepeer_evolution_slide.png rename to snippets/assets/domain/00_HOME/livepeer_evolution_slide.png diff --git a/v2/assets/home/whitepaper_diagram.png b/snippets/assets/domain/00_HOME/whitepaper_diagram.png similarity index 100% rename from v2/assets/home/whitepaper_diagram.png rename to snippets/assets/domain/00_HOME/whitepaper_diagram.png diff --git a/v2/assets/community/Building the Decentralized Generative AI Tech Stack.png b/snippets/assets/domain/01_ABOUT/Building the Decentralized Generative AI Tech Stack.png similarity index 100% rename from v2/assets/community/Building the Decentralized Generative AI Tech Stack.png rename to snippets/assets/domain/01_ABOUT/Building the Decentralized Generative AI Tech Stack.png diff --git a/v2/assets/community/Eric Shreck Gif.gif b/snippets/assets/domain/01_ABOUT/Eric Shreck Gif.gif similarity index 100% rename from v2/assets/community/Eric Shreck Gif.gif rename to snippets/assets/domain/01_ABOUT/Eric Shreck Gif.gif diff --git "a/v2/assets/community/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" "b/snippets/assets/domain/01_ABOUT/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" similarity index 100% rename from "v2/assets/community/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" rename to "snippets/assets/domain/01_ABOUT/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" diff --git a/v2/assets/about/api-reference.jpg b/snippets/assets/domain/01_ABOUT/api-reference.jpg similarity index 100% rename from v2/assets/about/api-reference.jpg rename to snippets/assets/domain/01_ABOUT/api-reference.jpg diff --git a/v2/assets/about/hosted.jpg b/snippets/assets/domain/01_ABOUT/hosted.jpg similarity index 100% rename from v2/assets/about/hosted.jpg rename to snippets/assets/domain/01_ABOUT/hosted.jpg diff --git a/v2/assets/about/image (1).png b/snippets/assets/domain/01_ABOUT/image (1).png similarity index 100% rename from v2/assets/about/image (1).png rename to snippets/assets/domain/01_ABOUT/image (1).png diff --git a/v2/assets/about/no-code.jpg b/snippets/assets/domain/01_ABOUT/no-code.jpg similarity index 100% rename from v2/assets/about/no-code.jpg rename to snippets/assets/domain/01_ABOUT/no-code.jpg diff --git a/v2/assets/developers/Building the Decentralized Generative AI Tech Stack.png b/snippets/assets/domain/02_COMMUNITY/Building the Decentralized Generative AI Tech Stack.png similarity index 100% rename from v2/assets/developers/Building the Decentralized Generative AI Tech Stack.png rename to snippets/assets/domain/02_COMMUNITY/Building the Decentralized Generative AI Tech Stack.png diff --git a/v2/assets/developers/Eric Shreck Gif.gif b/snippets/assets/domain/02_COMMUNITY/Eric Shreck Gif.gif similarity index 100% rename from v2/assets/developers/Eric Shreck Gif.gif rename to snippets/assets/domain/02_COMMUNITY/Eric Shreck Gif.gif diff --git a/v2/assets/community/Hero_90_Youtube.png b/snippets/assets/domain/02_COMMUNITY/Hero_90_Youtube.png similarity index 100% rename from v2/assets/community/Hero_90_Youtube.png rename to snippets/assets/domain/02_COMMUNITY/Hero_90_Youtube.png diff --git a/v2/assets/community/Hero_Blogging.png b/snippets/assets/domain/02_COMMUNITY/Hero_Blogging.png similarity index 100% rename from v2/assets/community/Hero_Blogging.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Blogging.png diff --git a/v2/assets/community/Hero_Calendar.png b/snippets/assets/domain/02_COMMUNITY/Hero_Calendar.png similarity index 100% rename from v2/assets/community/Hero_Calendar.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Calendar.png diff --git a/v2/assets/community/Hero_Discord (1).png b/snippets/assets/domain/02_COMMUNITY/Hero_Discord (1).png similarity index 100% rename from v2/assets/community/Hero_Discord (1).png rename to snippets/assets/domain/02_COMMUNITY/Hero_Discord (1).png diff --git a/v2/assets/community/Hero_Discord.png b/snippets/assets/domain/02_COMMUNITY/Hero_Discord.png similarity index 100% rename from v2/assets/community/Hero_Discord.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Discord.png diff --git a/v2/assets/community/Hero_Events.png b/snippets/assets/domain/02_COMMUNITY/Hero_Events.png similarity index 100% rename from v2/assets/community/Hero_Events.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Events.png diff --git a/v2/assets/community/Hero_Follow (1).png b/snippets/assets/domain/02_COMMUNITY/Hero_Follow (1).png similarity index 100% rename from v2/assets/community/Hero_Follow (1).png rename to snippets/assets/domain/02_COMMUNITY/Hero_Follow (1).png diff --git a/v2/assets/community/Hero_Follow.png b/snippets/assets/domain/02_COMMUNITY/Hero_Follow.png similarity index 100% rename from v2/assets/community/Hero_Follow.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Follow.png diff --git a/v2/assets/community/Hero_Forum.png b/snippets/assets/domain/02_COMMUNITY/Hero_Forum.png similarity index 100% rename from v2/assets/community/Hero_Forum.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Forum.png diff --git a/v2/assets/community/Hero_Github.png b/snippets/assets/domain/02_COMMUNITY/Hero_Github.png similarity index 100% rename from v2/assets/community/Hero_Github.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Github.png diff --git a/v2/assets/community/Hero_LinkedIn (1).png b/snippets/assets/domain/02_COMMUNITY/Hero_LinkedIn (1).png similarity index 100% rename from v2/assets/community/Hero_LinkedIn (1).png rename to snippets/assets/domain/02_COMMUNITY/Hero_LinkedIn (1).png diff --git a/v2/assets/community/Hero_LinkedIn.png b/snippets/assets/domain/02_COMMUNITY/Hero_LinkedIn.png similarity index 100% rename from v2/assets/community/Hero_LinkedIn.png rename to snippets/assets/domain/02_COMMUNITY/Hero_LinkedIn.png diff --git a/v2/assets/community/Hero_Medium.png b/snippets/assets/domain/02_COMMUNITY/Hero_Medium.png similarity index 100% rename from v2/assets/community/Hero_Medium.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Medium.png diff --git a/v2/assets/community/Hero_Meeting.png b/snippets/assets/domain/02_COMMUNITY/Hero_Meeting.png similarity index 100% rename from v2/assets/community/Hero_Meeting.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Meeting.png diff --git a/v2/assets/community/Hero_Newsletter.png b/snippets/assets/domain/02_COMMUNITY/Hero_Newsletter.png similarity index 100% rename from v2/assets/community/Hero_Newsletter.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Newsletter.png diff --git a/v2/assets/community/Hero_Reddit.png b/snippets/assets/domain/02_COMMUNITY/Hero_Reddit.png similarity index 100% rename from v2/assets/community/Hero_Reddit.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Reddit.png diff --git a/v2/assets/community/Hero_Telegram.png b/snippets/assets/domain/02_COMMUNITY/Hero_Telegram.png similarity index 100% rename from v2/assets/community/Hero_Telegram.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Telegram.png diff --git a/v2/assets/community/Hero_Telegran.png b/snippets/assets/domain/02_COMMUNITY/Hero_Telegran.png similarity index 100% rename from v2/assets/community/Hero_Telegran.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Telegran.png diff --git a/v2/assets/community/Hero_X (1).png b/snippets/assets/domain/02_COMMUNITY/Hero_X (1).png similarity index 100% rename from v2/assets/community/Hero_X (1).png rename to snippets/assets/domain/02_COMMUNITY/Hero_X (1).png diff --git a/v2/assets/community/Hero_X.png b/snippets/assets/domain/02_COMMUNITY/Hero_X.png similarity index 100% rename from v2/assets/community/Hero_X.png rename to snippets/assets/domain/02_COMMUNITY/Hero_X.png diff --git a/v2/assets/community/Hero_Yotube.png b/snippets/assets/domain/02_COMMUNITY/Hero_Yotube.png similarity index 100% rename from v2/assets/community/Hero_Yotube.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Yotube.png diff --git a/v2/assets/community/Hero_Youtube (1).png b/snippets/assets/domain/02_COMMUNITY/Hero_Youtube (1).png similarity index 100% rename from v2/assets/community/Hero_Youtube (1).png rename to snippets/assets/domain/02_COMMUNITY/Hero_Youtube (1).png diff --git a/v2/assets/community/Hero_Youtube.png b/snippets/assets/domain/02_COMMUNITY/Hero_Youtube.png similarity index 100% rename from v2/assets/community/Hero_Youtube.png rename to snippets/assets/domain/02_COMMUNITY/Hero_Youtube.png diff --git "a/v2/assets/developers/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" "b/snippets/assets/domain/02_COMMUNITY/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" similarity index 100% rename from "v2/assets/developers/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" rename to "snippets/assets/domain/02_COMMUNITY/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" diff --git a/v2/assets/community/api-reference.jpg b/snippets/assets/domain/02_COMMUNITY/api-reference.jpg similarity index 100% rename from v2/assets/community/api-reference.jpg rename to snippets/assets/domain/02_COMMUNITY/api-reference.jpg diff --git a/v2/assets/community/hosted.jpg b/snippets/assets/domain/02_COMMUNITY/hosted.jpg similarity index 100% rename from v2/assets/community/hosted.jpg rename to snippets/assets/domain/02_COMMUNITY/hosted.jpg diff --git a/v2/assets/community/image (1).png b/snippets/assets/domain/02_COMMUNITY/image (1).png similarity index 100% rename from v2/assets/community/image (1).png rename to snippets/assets/domain/02_COMMUNITY/image (1).png diff --git a/v2/assets/community/image.png b/snippets/assets/domain/02_COMMUNITY/image.png similarity index 100% rename from v2/assets/community/image.png rename to snippets/assets/domain/02_COMMUNITY/image.png diff --git a/v2/assets/community/no-code.jpg b/snippets/assets/domain/02_COMMUNITY/no-code.jpg similarity index 100% rename from v2/assets/community/no-code.jpg rename to snippets/assets/domain/02_COMMUNITY/no-code.jpg diff --git a/v2/assets/home/Building the Decentralized Generative AI Tech Stack.png b/snippets/assets/domain/03_DEVELOPERS/Building the Decentralized Generative AI Tech Stack.png similarity index 100% rename from v2/assets/home/Building the Decentralized Generative AI Tech Stack.png rename to snippets/assets/domain/03_DEVELOPERS/Building the Decentralized Generative AI Tech Stack.png diff --git a/v2/assets/home/Eric Shreck Gif.gif b/snippets/assets/domain/03_DEVELOPERS/Eric Shreck Gif.gif similarity index 100% rename from v2/assets/home/Eric Shreck Gif.gif rename to snippets/assets/domain/03_DEVELOPERS/Eric Shreck Gif.gif diff --git "a/v2/assets/home/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" "b/snippets/assets/domain/03_DEVELOPERS/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" similarity index 100% rename from "v2/assets/home/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" rename to "snippets/assets/domain/03_DEVELOPERS/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" diff --git a/v2/assets/developers/api-reference.jpg b/snippets/assets/domain/03_DEVELOPERS/api-reference.jpg similarity index 100% rename from v2/assets/developers/api-reference.jpg rename to snippets/assets/domain/03_DEVELOPERS/api-reference.jpg diff --git a/v2/assets/developers/comfystream.png b/snippets/assets/domain/03_DEVELOPERS/comfystream.png similarity index 100% rename from v2/assets/developers/comfystream.png rename to snippets/assets/domain/03_DEVELOPERS/comfystream.png diff --git a/v2/assets/developers/hosted.jpg b/snippets/assets/domain/03_DEVELOPERS/hosted.jpg similarity index 100% rename from v2/assets/developers/hosted.jpg rename to snippets/assets/domain/03_DEVELOPERS/hosted.jpg diff --git a/v2/assets/developers/image (1).png b/snippets/assets/domain/03_DEVELOPERS/image (1).png similarity index 100% rename from v2/assets/developers/image (1).png rename to snippets/assets/domain/03_DEVELOPERS/image (1).png diff --git a/v2/assets/developers/image.png b/snippets/assets/domain/03_DEVELOPERS/image.png similarity index 100% rename from v2/assets/developers/image.png rename to snippets/assets/domain/03_DEVELOPERS/image.png diff --git a/v2/assets/developers/no-code.jpg b/snippets/assets/domain/03_DEVELOPERS/no-code.jpg similarity index 100% rename from v2/assets/developers/no-code.jpg rename to snippets/assets/domain/03_DEVELOPERS/no-code.jpg diff --git a/snippets/assets/domain/04_GATEWAYS/code_examples/eliteproxy_launch.example..json b/snippets/assets/domain/04_GATEWAYS/code_examples/eliteproxy_launch.example..json new file mode 100644 index 000000000..54a4fd3d8 --- /dev/null +++ b/snippets/assets/domain/04_GATEWAYS/code_examples/eliteproxy_launch.example..json @@ -0,0 +1,146 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Onchain Gateway", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/livepeer", + "buildFlags": "-tags=mainnet,experimental", + "env": { + "GO111MODULE": "on", + "CGO_ENABLED": "1", + "CC": "", + "CGO_LDFLAGS": "-L/usr/local/cuda/lib64 -L${env:HOME}/buildoutput/compiled/lib -Wl,--copy-dt-needed-entries", + "PATH": "${PATH}:/usr/local/cuda/bin:${env:PATH}", + "PKG_CONFIG_PATH": "${env:HOME}/buildoutput/compiled/lib/pkgconfig", + "LD_LIBRARY_PATH": "${env:HOME}/buildoutput/compiled/lib", + "LIVE_AI_ALLOW_CORS": "1", + "LIVE_AI_WHIP_ADDR": "127.0.0.1:8081", + "LIVE_AI_GATHER_TIMEOUT": "5", + "LIVE_AI_MIN_SEG_DUR": "1s", + "LIVE_AI_NAT_IP": "127.0.0.1", + "LIVE_AI_PLAYBACK_HOST": "rtmp://127.0.0.1:1935/", + "LIVE_AI_WHEP_URL": "http://127.0.0.1:8890/" + }, + "args": [ + "-network", + "arbitrum-one-mainnet", + "-gateway", + "-dataDir", + "${env:HOME}/.lpData-gateway", + "-gatewayHost", + "127.0.0.1:8081", + "-rtmpAddr", + "0.0.0.0:1936", + "-httpAddr", + "127.0.0.1:8081", + "-httpIngest", + "-nvidia", + "0", + "-ethAcctAddr", + "0x0074780FefF1FD0277FAD6ccdb5a29908df6051F", + "-ethPassword", + "${env:HOME}/.lpData-gateway/ethpasstestnet2", + "-orchAddr", + "https://127.0.0.1:8933", + "-ignoreMaxPriceIfNeeded=true", + "-maxPricePerUnit", + "900", + "-maxTotalEV", + "100000000000000", + "-monitor", + "-v", + "5", + "-cliAddr", + "0.0.0.0:7935", + "-ethUrl", + "http://nyc-router.eliteencoder.net:3517" + ] + }, + { + "name": "Local Orchestrator (AI env)", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/livepeer", + "buildFlags": "-tags=mainnet,experimental -buildvcs=false", + "env": { + "GO111MODULE": "on", + "CGO_ENABLED": "1", + "CC": "", + "CGO_LDFLAGS": "-L/usr/local/cuda/lib64 -L${env:HOME}/buildoutput/compiled/lib -Wl,--copy-dt-needed-entries", + "PATH": "${PATH}:/usr/local/cuda/bin:${env:PATH}", + "PKG_CONFIG_PATH": "${env:HOME}/buildoutput/compiled/lib/pkgconfig", + "LD_LIBRARY_PATH": "${env:HOME}/buildoutput/compiled/lib", + "GOTOOLCHAIN": "auto" + }, + "args": [ + "-orchestrator", + "-transcoder", + "-nvidia", + "0", + "-network", + "arbitrum-one-mainnet", + "-dataDir", + "${env:HOME}/.lpData-orch", + "-ethOrchAddr", + "0x104a7CA059A35Fd4dEF5Ecb16600B2CaA1Fe1361", + "-ethPassword", + "${env:HOME}/.lpData-orch/ethpasstestnet2", + "-orchSecret", + "orch-secret", + "-pricePerUnit", + "20", + "-pixelsPerUnit", + "1", + "-monitor", + "-metricsPerStream", + "-serviceAddr", + "127.0.0.1:8933", + "-cliAddr", + "0.0.0.0:7934", + "-ethUrl", + "http://arb.eliteencoder.net:3517", + "-pricePerBroadcaster", + "${env:HOME}/.lpData-orch/broadcasterpricing", + "-v", + "5" + ] + }, + { + "name": "Launch livepeer_cli", + "type": "go", + "request": "launch", + "mode": "auto", + "console": "integratedTerminal", + "program": "${workspaceFolder}/cmd/livepeer_cli", + "buildFlags": "-tags=mainnet,experimental", + "env": { + "GO111MODULE": "on", + "CGO_ENABLED": "1", + "CC": "", + "CGO_LDFLAGS": "-L/usr/local/cuda/lib64 -L${env:HOME}/buildoutput/compiled/lib -Wl,--copy-dt-needed-entries", + "PATH": "${PATH}:/usr/local/cuda/bin:${env:PATH}", + "PKG_CONFIG_PATH": "${env:HOME}/buildoutput/compiled/lib/pkgconfig", + "LD_LIBRARY_PATH": "${env:HOME}/buildoutput/compiled/lib", + "GOTOOLCHAIN": "auto" + }, + "args": [ + "-http", + "7935", + ], + }, + ], + "compounds": [ + { + "name": "Onchain Gateway + Local Orchestrator", + "stopAll": true, + "configurations": [ + "Onchain Gateway", + "Local Orchestrator (AI env)" + ] + } + ] +} diff --git a/v2/assets/gateways/test-video.mp4 b/snippets/assets/domain/04_GATEWAYS/test-video.mp4 similarity index 100% rename from v2/assets/gateways/test-video.mp4 rename to snippets/assets/domain/04_GATEWAYS/test-video.mp4 diff --git a/v2/assets/gateways/view-dropdown.png b/snippets/assets/domain/04_GATEWAYS/view-dropdown.png similarity index 100% rename from v2/assets/gateways/view-dropdown.png rename to snippets/assets/domain/04_GATEWAYS/view-dropdown.png diff --git a/v2/assets/orchestrators/Building the Decentralized Generative AI Tech Stack.png b/snippets/assets/domain/05_ORCHESTRATORS/Building the Decentralized Generative AI Tech Stack.png similarity index 100% rename from v2/assets/orchestrators/Building the Decentralized Generative AI Tech Stack.png rename to snippets/assets/domain/05_ORCHESTRATORS/Building the Decentralized Generative AI Tech Stack.png diff --git a/v2/assets/orchestrators/Eric Shreck Gif.gif b/snippets/assets/domain/05_ORCHESTRATORS/Eric Shreck Gif.gif similarity index 100% rename from v2/assets/orchestrators/Eric Shreck Gif.gif rename to snippets/assets/domain/05_ORCHESTRATORS/Eric Shreck Gif.gif diff --git "a/v2/assets/orchestrators/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" "b/snippets/assets/domain/05_ORCHESTRATORS/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" similarity index 100% rename from "v2/assets/orchestrators/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" rename to "snippets/assets/domain/05_ORCHESTRATORS/Introducing Livepeer Cascade - A Vision For Livepeer\342\200\231s Future in the Age of Real-Time AI Video.png" diff --git a/v2/assets/orchestrators/api-reference.jpg b/snippets/assets/domain/05_ORCHESTRATORS/api-reference.jpg similarity index 100% rename from v2/assets/orchestrators/api-reference.jpg rename to snippets/assets/domain/05_ORCHESTRATORS/api-reference.jpg diff --git a/v2/assets/orchestrators/hosted.jpg b/snippets/assets/domain/05_ORCHESTRATORS/hosted.jpg similarity index 100% rename from v2/assets/orchestrators/hosted.jpg rename to snippets/assets/domain/05_ORCHESTRATORS/hosted.jpg diff --git a/v2/assets/orchestrators/image (1).png b/snippets/assets/domain/05_ORCHESTRATORS/image (1).png similarity index 100% rename from v2/assets/orchestrators/image (1).png rename to snippets/assets/domain/05_ORCHESTRATORS/image (1).png diff --git a/v2/assets/orchestrators/image.png b/snippets/assets/domain/05_ORCHESTRATORS/image.png similarity index 100% rename from v2/assets/orchestrators/image.png rename to snippets/assets/domain/05_ORCHESTRATORS/image.png diff --git a/v2/assets/orchestrators/no-code.jpg b/snippets/assets/domain/05_ORCHESTRATORS/no-code.jpg similarity index 100% rename from v2/assets/orchestrators/no-code.jpg rename to snippets/assets/domain/05_ORCHESTRATORS/no-code.jpg diff --git a/snippets/assets/domain/SHARED/LivepeerDocsHero.svg b/snippets/assets/domain/SHARED/LivepeerDocsHero.svg new file mode 100644 index 000000000..a556f903a --- /dev/null +++ b/snippets/assets/domain/SHARED/LivepeerDocsHero.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v2/assets/logo/dark.svg b/snippets/assets/domain/SHARED/LivepeerDocsLogo.svg similarity index 100% rename from v2/assets/logo/dark.svg rename to snippets/assets/domain/SHARED/LivepeerDocsLogo.svg diff --git a/v2/assets/site/logos/Livepeer-Logo-Full-Dark.svg b/snippets/assets/logos/Livepeer-Logo-Full-Dark.svg similarity index 100% rename from v2/assets/site/logos/Livepeer-Logo-Full-Dark.svg rename to snippets/assets/logos/Livepeer-Logo-Full-Dark.svg diff --git a/v2/assets/site/logos/Livepeer-Logo-Full-Light.svg b/snippets/assets/logos/Livepeer-Logo-Full-Light.svg similarity index 100% rename from v2/assets/site/logos/Livepeer-Logo-Full-Light.svg rename to snippets/assets/logos/Livepeer-Logo-Full-Light.svg diff --git a/snippets/assets/logos/Livepeer-Logo-Full-Theme.svg b/snippets/assets/logos/Livepeer-Logo-Full-Theme.svg new file mode 100644 index 000000000..f9ff72e28 --- /dev/null +++ b/snippets/assets/logos/Livepeer-Logo-Full-Theme.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/v2/assets/site/logos/Livepeer-Logo-Symbol-Dark.svg b/snippets/assets/logos/Livepeer-Logo-Symbol-Dark.svg similarity index 100% rename from v2/assets/site/logos/Livepeer-Logo-Symbol-Dark.svg rename to snippets/assets/logos/Livepeer-Logo-Symbol-Dark.svg diff --git a/snippets/assets/logos/Livepeer-Logo-Symbol-Green-Theme.svg b/snippets/assets/logos/Livepeer-Logo-Symbol-Green-Theme.svg new file mode 100644 index 000000000..8e9bbabaf --- /dev/null +++ b/snippets/assets/logos/Livepeer-Logo-Symbol-Green-Theme.svg @@ -0,0 +1,10 @@ + + + + + diff --git a/v2/assets/site/logos/Livepeer-Logo-Symbol-Light.svg b/snippets/assets/logos/Livepeer-Logo-Symbol-Green.svg similarity index 91% rename from v2/assets/site/logos/Livepeer-Logo-Symbol-Light.svg rename to snippets/assets/logos/Livepeer-Logo-Symbol-Green.svg index 3ea275c47..b9a914dd6 100644 --- a/v2/assets/site/logos/Livepeer-Logo-Symbol-Light.svg +++ b/snippets/assets/logos/Livepeer-Logo-Symbol-Green.svg @@ -1,3 +1,4 @@ - + + diff --git a/snippets/assets/Livepeer-Logo-Symbol-Light.svg b/snippets/assets/logos/Livepeer-Logo-Symbol-Light.svg similarity index 100% rename from snippets/assets/Livepeer-Logo-Symbol-Light.svg rename to snippets/assets/logos/Livepeer-Logo-Symbol-Light.svg diff --git a/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg b/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg new file mode 100644 index 000000000..010dbf29e --- /dev/null +++ b/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg @@ -0,0 +1,10 @@ + + + + + diff --git a/snippets/assets/logos/Livepeer-Logo-Symbol.svg b/snippets/assets/logos/Livepeer-Logo-Symbol.svg new file mode 100644 index 000000000..476e8b544 --- /dev/null +++ b/snippets/assets/logos/Livepeer-Logo-Symbol.svg @@ -0,0 +1,3 @@ + + + diff --git a/snippets/assets/logos/dark.svg b/snippets/assets/logos/dark.svg new file mode 100644 index 000000000..245d63baf --- /dev/null +++ b/snippets/assets/logos/dark.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/v2/assets/logo/light.svg b/snippets/assets/logos/light.svg similarity index 100% rename from v2/assets/logo/light.svg rename to snippets/assets/logos/light.svg diff --git a/v2/assets/products/daydream-logo-dark.svg b/snippets/assets/logos/products/daydream-logo-dark.svg similarity index 100% rename from v2/assets/products/daydream-logo-dark.svg rename to snippets/assets/logos/products/daydream-logo-dark.svg diff --git a/v2/assets/products/livepeer-studio-logo.svg b/snippets/assets/logos/products/livepeer-studio-logo.svg similarity index 100% rename from v2/assets/products/livepeer-studio-logo.svg rename to snippets/assets/logos/products/livepeer-studio-logo.svg diff --git a/v2/assets/products/streamplace-cube.png b/snippets/assets/logos/products/streamplace-cube.png similarity index 100% rename from v2/assets/products/streamplace-cube.png rename to snippets/assets/logos/products/streamplace-cube.png diff --git a/v2/assets/products/streamplace-logo.svg b/snippets/assets/logos/products/streamplace-logo.svg similarity index 100% rename from v2/assets/products/streamplace-logo.svg rename to snippets/assets/logos/products/streamplace-logo.svg diff --git a/v2/assets/hero/Hero_Livepeer_Full.png b/snippets/assets/media/heros/Hero_Livepeer_Full.png similarity index 100% rename from v2/assets/hero/Hero_Livepeer_Full.png rename to snippets/assets/media/heros/Hero_Livepeer_Full.png diff --git a/v2/assets/hero/Hero_Livepeer_Full_sml.png b/snippets/assets/media/heros/Hero_Livepeer_Full_sml.png similarity index 100% rename from v2/assets/hero/Hero_Livepeer_Full_sml.png rename to snippets/assets/media/heros/Hero_Livepeer_Full_sml.png diff --git a/v2/assets/home/Hero_Images/hero_about.png b/snippets/assets/media/heros/hero_about.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_about.png rename to snippets/assets/media/heros/hero_about.png diff --git a/v2/assets/home/Hero_Images/hero_community.png b/snippets/assets/media/heros/hero_community.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_community.png rename to snippets/assets/media/heros/hero_community.png diff --git a/v2/assets/home/Hero_Images/hero_delegators.png b/snippets/assets/media/heros/hero_delegators.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_delegators.png rename to snippets/assets/media/heros/hero_delegators.png diff --git a/v2/assets/home/Hero_Images/hero_developer.png b/snippets/assets/media/heros/hero_developer.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_developer.png rename to snippets/assets/media/heros/hero_developer.png diff --git a/v2/assets/home/Hero_Images/hero_developer1.png b/snippets/assets/media/heros/hero_developer1.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_developer1.png rename to snippets/assets/media/heros/hero_developer1.png diff --git a/v2/assets/home/Hero_Images/hero_developer_logo.png b/snippets/assets/media/heros/hero_developer_logo.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_developer_logo.png rename to snippets/assets/media/heros/hero_developer_logo.png diff --git a/v2/assets/home/Hero_Images/hero_gateways.png b/snippets/assets/media/heros/hero_gateways.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_gateways.png rename to snippets/assets/media/heros/hero_gateways.png diff --git a/v2/assets/home/Hero_Images/hero_gpu.png b/snippets/assets/media/heros/hero_gpu.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_gpu.png rename to snippets/assets/media/heros/hero_gpu.png diff --git a/v2/assets/home/Hero_Images/hero_help.png b/snippets/assets/media/heros/hero_help.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_help.png rename to snippets/assets/media/heros/hero_help.png diff --git a/v2/assets/home/Hero_Images/hero_logo_developer.png b/snippets/assets/media/heros/hero_logo_developer.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_logo_developer.png rename to snippets/assets/media/heros/hero_logo_developer.png diff --git a/v2/assets/home/Hero_Images/hero_logo_developer_sml.png b/snippets/assets/media/heros/hero_logo_developer_sml.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_logo_developer_sml.png rename to snippets/assets/media/heros/hero_logo_developer_sml.png diff --git a/v2/assets/home/Hero_Images/hero_logo_new.png b/snippets/assets/media/heros/hero_logo_new.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_logo_new.png rename to snippets/assets/media/heros/hero_logo_new.png diff --git a/v2/assets/home/Hero_Images/hero_opportunity.png b/snippets/assets/media/heros/hero_opportunity.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_opportunity.png rename to snippets/assets/media/heros/hero_opportunity.png diff --git a/v2/assets/home/Hero_Images/hero_partner.png b/snippets/assets/media/heros/hero_partner.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_partner.png rename to snippets/assets/media/heros/hero_partner.png diff --git a/v2/assets/home/Hero_Images/hero_reference.png b/snippets/assets/media/heros/hero_reference.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_reference.png rename to snippets/assets/media/heros/hero_reference.png diff --git a/v2/assets/home/Hero_Images/hero_researchers.png b/snippets/assets/media/heros/hero_researchers.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_researchers.png rename to snippets/assets/media/heros/hero_researchers.png diff --git a/v2/assets/home/Hero_Images/hero_showcase.png b/snippets/assets/media/heros/hero_showcase.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_showcase.png rename to snippets/assets/media/heros/hero_showcase.png diff --git a/v2/assets/home/Hero_Images/hero_word_NEW.png b/snippets/assets/media/heros/hero_word_NEW.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_word_NEW.png rename to snippets/assets/media/heros/hero_word_NEW.png diff --git a/v2/assets/home/Hero_Images/hero_word_developer.png b/snippets/assets/media/heros/hero_word_developer.png similarity index 100% rename from v2/assets/home/Hero_Images/hero_word_developer.png rename to snippets/assets/media/heros/hero_word_developer.png diff --git a/snippets/assets/media/icons/home-house.gif b/snippets/assets/media/icons/home-house.gif new file mode 100644 index 000000000..adf6aa1cc Binary files /dev/null and b/snippets/assets/media/icons/home-house.gif differ diff --git a/snippets/assets/media/icons/smart-house.gif b/snippets/assets/media/icons/smart-house.gif new file mode 100644 index 000000000..d1c889356 Binary files /dev/null and b/snippets/assets/media/icons/smart-house.gif differ diff --git a/snippets/assets/media/images/DelegatorImg.avif b/snippets/assets/media/images/DelegatorImg.avif new file mode 100644 index 000000000..a4bcdaf02 Binary files /dev/null and b/snippets/assets/media/images/DelegatorImg.avif differ diff --git a/snippets/assets/media/images/GPU callout.png b/snippets/assets/media/images/GPU callout.png new file mode 100644 index 000000000..9ba5c9e91 Binary files /dev/null and b/snippets/assets/media/images/GPU callout.png differ diff --git a/snippets/assets/media/images/GPUImg.webp b/snippets/assets/media/images/GPUImg.webp new file mode 100644 index 000000000..2642e80c9 Binary files /dev/null and b/snippets/assets/media/images/GPUImg.webp differ diff --git a/snippets/assets/media/images/Livepeer Stats.png b/snippets/assets/media/images/Livepeer Stats.png new file mode 100644 index 000000000..36c1501bc Binary files /dev/null and b/snippets/assets/media/images/Livepeer Stats.png differ diff --git a/snippets/assets/media/videos/Embody.mp4 b/snippets/assets/media/videos/Embody.mp4 new file mode 100644 index 000000000..c8d3c79b5 Binary files /dev/null and b/snippets/assets/media/videos/Embody.mp4 differ diff --git a/snippets/assets/media/videos/HeroBackground.mp4 b/snippets/assets/media/videos/HeroBackground.mp4 new file mode 100644 index 000000000..d06bd45ab Binary files /dev/null and b/snippets/assets/media/videos/HeroBackground.mp4 differ diff --git a/snippets/assets/media/videos/LivepeerStudio.mp4 b/snippets/assets/media/videos/LivepeerStudio.mp4 new file mode 100644 index 000000000..f20a6f5b3 Binary files /dev/null and b/snippets/assets/media/videos/LivepeerStudio.mp4 differ diff --git a/snippets/assets/media/videos/daydream.mp4 b/snippets/assets/media/videos/daydream.mp4 new file mode 100644 index 000000000..e32667939 Binary files /dev/null and b/snippets/assets/media/videos/daydream.mp4 differ diff --git a/snippets/assets/media/videos/frameworks.mp4 b/snippets/assets/media/videos/frameworks.mp4 new file mode 100644 index 000000000..4a6cd6915 Binary files /dev/null and b/snippets/assets/media/videos/frameworks.mp4 differ diff --git a/snippets/assets/media/videos/livepeer-founders-post.mp4 b/snippets/assets/media/videos/livepeer-founders-post.mp4 new file mode 100644 index 000000000..bd1b535ce Binary files /dev/null and b/snippets/assets/media/videos/livepeer-founders-post.mp4 differ diff --git a/snippets/assets/media/videos/streamplace.mp4 b/snippets/assets/media/videos/streamplace.mp4 new file mode 100644 index 000000000..c8d3c79b5 Binary files /dev/null and b/snippets/assets/media/videos/streamplace.mp4 differ diff --git a/v2/assets/site/favicon/apple-touch-icon.png b/snippets/assets/site/favicon/apple-touch-icon.png similarity index 100% rename from v2/assets/site/favicon/apple-touch-icon.png rename to snippets/assets/site/favicon/apple-touch-icon.png diff --git a/v2/assets/site/favicon/favicon-96x96.png b/snippets/assets/site/favicon/favicon-96x96.png similarity index 100% rename from v2/assets/site/favicon/favicon-96x96.png rename to snippets/assets/site/favicon/favicon-96x96.png diff --git a/v2/assets/site/favicon/favicon.ico b/snippets/assets/site/favicon/favicon.ico similarity index 100% rename from v2/assets/site/favicon/favicon.ico rename to snippets/assets/site/favicon/favicon.ico diff --git a/v2/assets/site/favicon/favicon.svg b/snippets/assets/site/favicon/favicon.svg similarity index 100% rename from v2/assets/site/favicon/favicon.svg rename to snippets/assets/site/favicon/favicon.svg diff --git a/v2/assets/site/favicon/site.webmanifest b/snippets/assets/site/favicon/site.webmanifest similarity index 100% rename from v2/assets/site/favicon/site.webmanifest rename to snippets/assets/site/favicon/site.webmanifest diff --git a/v2/assets/site/favicon/web-app-manifest-192x192.png b/snippets/assets/site/favicon/web-app-manifest-192x192.png similarity index 100% rename from v2/assets/site/favicon/web-app-manifest-192x192.png rename to snippets/assets/site/favicon/web-app-manifest-192x192.png diff --git a/v2/assets/site/favicon/web-app-manifest-512x512.png b/snippets/assets/site/favicon/web-app-manifest-512x512.png similarity index 100% rename from v2/assets/site/favicon/web-app-manifest-512x512.png rename to snippets/assets/site/favicon/web-app-manifest-512x512.png diff --git a/v2/assets/site/images/404-desolate.jpeg b/snippets/assets/site/images/404-desolate.jpeg similarity index 100% rename from v2/assets/site/images/404-desolate.jpeg rename to snippets/assets/site/images/404-desolate.jpeg diff --git a/v2/assets/site/images/layered-image.webp b/snippets/assets/site/images/layered-image.webp similarity index 100% rename from v2/assets/site/images/layered-image.webp rename to snippets/assets/site/images/layered-image.webp diff --git a/snippets/assets/site/united-kingdom-flag-icon.svg b/snippets/assets/site/united-kingdom-flag-icon.svg new file mode 100644 index 000000000..75b969ded --- /dev/null +++ b/snippets/assets/site/united-kingdom-flag-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/snippets/automationData/README.mdx b/snippets/automationData/README.mdx new file mode 100644 index 000000000..7d8867dbd --- /dev/null +++ b/snippets/automationData/README.mdx @@ -0,0 +1,44 @@ +# Automations + +This folder contains all automations or desired automations in the Livepeer docs. Status will say [Live] if it is live, [WIP] if it is in progress, and [Future] if it is a future automation. + +The following automations are available: + +### Trending & Data Fetching + +- Fetch recent YouTube Videos & Display +- Fetch recent Forum Posts & Display +- Fetch recent Discord Announcements & Display +- Fetch recent Blog Posts & Display +- Fetch RFPs & Display + ~Maybe~ +- Fetch recent Twitter Tweets & Display +- Fetch recent GitHub Issues & Display +- Fetch recent GitHub Pull Requests & Display + +### HUBs & Contact + +- Ecosystem Projects HUB +- Resources HUB +- Partner HUB +- Sales/Data Center Contact Form (?) -> should direct to appropriate email +- + +### Changelog + +- Automated Changelog from Github Releases + +### AI Functions + +- Transcribe a Youtube Video for download +- Translate pages into other languages +- Create a hero image +- Check All Documentation Links (periodically) +- Create a video? + +### AI Optimisations + +- RAG (?) -> enable access to github repo's & external docs for better assistant capabilities +- MCP () + +--- diff --git a/snippets/automationData/globals/README.md b/snippets/automationData/globals/README.mdx similarity index 90% rename from snippets/automationData/globals/README.md rename to snippets/automationData/globals/README.mdx index d4d5f2e67..78ea95bd5 100644 --- a/snippets/automationData/globals/README.md +++ b/snippets/automationData/globals/README.mdx @@ -8,7 +8,7 @@ This is the recommended approach for your setup. It: - Polls the go-livepeer releases API every 30 minutes - Uses Redis to track the last known version (prevents duplicate updates) -- Only updates the `LatestRelease` value without touching anything else +- Only updates the `LatestVersion` value without touching anything else - Commits directly to the docs-v2 branch ## 2. **GitHub Action** (update-livepeer-release.yml) RECOMMENDED @@ -40,11 +40,15 @@ All files include the setup guide with detailed instructions for each approach. ### 2. Code for yml -on: schedule: # Run every 30 minutes - cron: '_/30 _ \* \* \*' -workflow_dispatch: - -jobs: check-and-update: runs-on: ubuntu-latest +```yaml +on: + schedule: # Run every 30 minutes + - cron: "*/30 * * * *" + workflow_dispatch: +jobs: + check-and-update: + runs-on: ubuntu-latest steps: - name: Checkout docs repository uses: actions/checkout@v3 @@ -62,7 +66,7 @@ jobs: check-and-update: runs-on: ubuntu-latest - name: Read current version from globals.jsx id: current_version run: | - CURRENT=$(grep -oP 'LatestRelease:\s*["'\'']?\K[^"'\'']+' snippets/automationData/globals/globals.jsx || echo "") + CURRENT=$(grep -oP 'LatestRelease:\s*["'\''\"]?\K[^"'\'']+' snippets/automationData/globals/globals.jsx || echo "") echo "current=${CURRENT}" >> $GITHUB_OUTPUT echo "Current version: ${CURRENT}" @@ -87,3 +91,4 @@ jobs: check-and-update: runs-on: ubuntu-latest git add snippets/automationData/globals/globals.jsx git commit -m "chore: update latest release to ${{ steps.get_release.outputs.release }}" git push origin docs-v2 +``` diff --git a/snippets/automationData/globals/globals.jsx b/snippets/automationData/globals/globals.jsx index 1a218b714..8440ae0f2 100644 --- a/snippets/automationData/globals/globals.jsx +++ b/snippets/automationData/globals/globals.jsx @@ -1 +1,3 @@ -export const LatestRelease = "v0.8.8"; +export const latestVersion = "v0.7.7"; +export const latestVersionUrl = + "https://github.com/livepeer/go-livepeer/releases/download/v0.7.7"; diff --git a/snippets/automationData/globals/globals.mdx b/snippets/automationData/globals/globals.mdx new file mode 100644 index 000000000..d80520fc2 --- /dev/null +++ b/snippets/automationData/globals/globals.mdx @@ -0,0 +1,2 @@ +export const latestVersion = "v0.7.7"; +export const latestVersionUrl = "https://github.com/livepeer/go-livepeer/releases/download/v0.7.7"; diff --git a/snippets/components/README.md b/snippets/components/README.md new file mode 100644 index 000000000..cbbd54217 --- /dev/null +++ b/snippets/components/README.md @@ -0,0 +1,88 @@ +# Components Library + +These components are organised **By Function/Purpose**. + +Additionally some items are organised by **Domain** where domain-specific +components are extracted to their own folder (e.g., callouts, code strings used +on multiple pages). + +## Folder Structure + +``` +components/ +├── primitives/ # Basic UI elements +├── layout/ # Custom layouts for multiple items +├── display/ # Display elements for media or embeds +├── content/ # Content & Data Display Groups +├── integrations/ # External service integrations +└── domain/ # Domain-specific components +``` + +--- + +## Component Reference + +### primitives/ + +| File | Exports | Description | +| ------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `buttons.jsx` | `BasicBtn`, `DownloadButton` | Button components | +| `divider.jsx` | `CustomDivider` | Divider/separator | +| `icons.jsx` | `LivepeerSVG`, `LivepeerIconOld`, `LivepeerIconFlipped`, `LivepeerIcon` | Livepeer brand icons | +| `links.jsx` | `CustomCallout`, `BlinkingIcon`, `BlinkingTerminal`, `DoubleIconLink`, `GotoLink`, `GotoCard`, `TipWithArrow` | Link and navigation components | + +### layout/ + +| File | Exports | Description | +| --------------- | ----------------------------------------------------------------------------------- | ----------------------- | +| `cards.jsx` | `PostCard`, `CardColumnsPostLayout`, `BlogCard`, `CardBlogDataLayout` | Card layouts | +| `lists.jsx` | `BasicList`, `IconList`, `StepList`, `StepLinkList`, `UpdateList`, `UpdateLinkList` | List layouts | +| `ListSteps.jsx` | `ListSteps` | Step list component | +| `steps.jsx` | `StyledSteps`, `StyledStep` | Styled step components | +| `table.jsx` | `DynamicTable` | Dynamic table component | + +### display/ + +| File | Exports | Description | +| ---------------------- | --------------------------------------------------- | --------------------------- | +| `embed.jsx` | `MarkdownEmbed`, `EmbedMarkdown` | Markdown embed components | +| `image.jsx` | `Image`, `LinkImage` | Image display components | +| `video.jsx` | `YouTubeVideo`, `YouTubeVideoDownload`, `CardVideo` | Video embed components | +| `zoomable-diagram.jsx` | `ScrollableDiagram` | Zoomable/scrollable diagram | + +### content/ + +| File | Exports | Description | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `code.jsx` | `CustomCodeBlock`, `CodeComponent`, `ComplexCodeBlock`, `CodeSection` | Code display components | +| `external-content.jsx` | `ExternalContent` | External content loader | +| `release.jsx` | `LatestVersion` | Version display component | +| `responseField.jsx` | `ValueResponseField`, `CustomResponseField`, `ResponseFieldExpandable`, `ResponseFieldAccordion`, `ResponseFieldGroup` | API response field components | + +### integrations/ + +| File | Exports | Description | +| --------------- | -------------------- | ------------------------------- | +| `coingecko.jsx` | `CoinGeckoExchanges` | CoinGecko exchange data display | + +### domain/04_GATEWAYS/ + +| File | Exports | Description | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `callouts.jsx` | `GatewayOffChainWarning`, `GatewayOnChainWarning`, `GatewayOnChainTTestnetNote`, `OrchAddrNote`, `TestVideoDownload`, `FfmpegWarning` | Gateway-specific callouts | +| `quickstartTabs.jsx` | `QuickStartTabs`, `QuickStartSteps` | Gateway quickstart UI | + +--- + +## Usage + +Import components in MDX files using absolute paths from `/snippets/`: + +```jsx +import { YouTubeVideo } from "/snippets/components/display/video.jsx"; +import { GotoCard, GotoLink } from "/snippets/components/primitives/links.jsx"; +import { CustomCodeBlock } from "/snippets/components/content/code.jsx"; +``` + +**Note:** Mintlify provides `React`, `Frame`, `Card`, `Icon`, and other +primitives globally - do not import them. diff --git a/snippets/components/Report.md b/snippets/components/Report.md new file mode 100644 index 000000000..53f417232 --- /dev/null +++ b/snippets/components/Report.md @@ -0,0 +1,267 @@ +You're absolutely right. Let me revert all changes and do a proper comprehensive +review. + +✅ All changes reverted. Now let me do a comprehensive count and review: + +Now let me count the exported components in each file: + +Now let me check for components that use `export` but aren't at the start of the +line: + +Let me search for all component definitions in these files: + +Perfect! Now let me analyze each file for hardcoded colors and determine what +SHOULD and SHOULD NOT be dynamic: + +Now let me create a comprehensive report. Let me check what colors are actually +theme colors vs decorative: + +Now I need to check what the full ThemeData object contains. Let me look at the +current state: + +I see the ThemeData is very limited. Let me create a comprehensive analysis +report: + +--- + +## 📊 COMPREHENSIVE COMPONENT AUDIT REPORT + +### Total Files: 24 JSX files + +### Total Components: 56 named components + +--- + +## 📁 FILE-BY-FILE COMPONENT COUNT + +### **Content Components** (4 files, 6 components) + +1. **code.jsx** - 4 components + - `CustomCodeBlock`, `CodeComponent`, `ComplexCodeBlock`, `CodeSection` +2. **external-content.jsx** - 1 component + - `ExternalContent` +3. **release.jsx** - 1 component + - `LatestVersion` +4. **responseField.jsx** - 0 exported components + +### **Display Components** (5 files, 17 components) + +5. **embed.jsx** - 2 components + - `MarkdownEmbed`, `EmbedMarkdown` +6. **frameMode.jsx** - 9 components + - `PageHeader`, `H1`, `H2`, `H3`, `H4`, `H5`, `H6`, `P`, `Divider` +7. **image.jsx** - 2 components + - `Image`, `LinkImage` +8. **video.jsx** - 3 components + - `YouTubeVideo`, `YouTubeVideoDownload`, `CardVideo` +9. **zoomable-diagram.jsx** - 1 component + - `ScrollableDiagram` + +### **Domain Components** (4 files, 14 components) + +10. **domain/04_GATEWAYS/callouts.jsx** - 6 components + - `GatewayOffChainWarning`, `GatewayOnChainWarning`, + `GatewayOnChainTTestnetNote`, `OrchAddrNote`, `TestVideoDownload`, + `FfmpegWarning` +11. **domain/04_GATEWAYS/quickstartTabs.jsx** - 2 components + - `QuickStartTabs`, `QuickStartSteps` +12. **domain/SHARED/HeroGif.jsx** - 1 component + - `Starfield` +13. **domain/SHARED/Portals.jsx** - 8 components + - `HeroSectionContainer`, `HeroImageBackgroundComponent`, + `HeroContentContainer`, `PortalContentContainer`, `PortalHeroContent`, + `LogoHeroContainer`, `RefCardContainer`, `HeroOverviewContent` +14. **domain/SHARED/previewCallouts.jsx** - 3 components + - `ComingSoonCallout`, `PreviewCallout`, `ReviewCallout` + +### **Integration Components** (1 file, 1 component) + +15. **integrations/coingecko.jsx** - 1 component + - `CoinGeckoExchanges` + +### **Layout Components** (5 files, 14 components) + +16. **layout/ListSteps.jsx** - 1 component + - `ListSteps` +17. **layout/cards.jsx** - 4 components + - `PostCard`, `CardColumnsPostLayout`, `BlogCard`, `CardBlogDataLayout` +18. **layout/lists.jsx** - 6 components + - `BasicList`, `IconList`, `StepList`, `StepLinkList`, `UpdateList`, + `UpdateLinkList` +19. **layout/steps.jsx** - 2 components + - `StyledSteps`, `StyledStep` +20. **layout/table.jsx** - 1 component + - `DynamicTable` + +### **Primitive Components** (4 files, 14 components) + +21. **primitives/buttons.jsx** - 2 components + - `BasicBtn`, `DownloadButton` +22. **primitives/divider.jsx** - 1 component + - `CustomDivider` +23. **primitives/icons.jsx** - 4 components + - `LivepeerSVG`, `LivepeerIconOld`, `LivepeerIconFlipped`, `LivepeerIcon` +24. **primitives/links.jsx** - 7 components + - `CustomCallout`, `BlinkingIcon`, `BlinkingTerminal`, `DoubleIconLink`, + `GotoLink`, `GotoCard`, `TipWithArrow` + +--- + +## 🎨 COLOR ANALYSIS + +### **Colors That SHOULD BE DYNAMIC** (Theme-dependent) + +These use Livepeer brand green `#2d9a67`, `#3CB540`, `#18794e` or neutral grays +that should adapt to theme: + +1. **external-content.jsx** + - ✅ Border: `#2d9a67` → Should use theme accent + - ✅ Background: `#0d0d0d` → Should use theme card background + - ✅ Link color: `#2d9a67` → Should use theme accent + +2. **zoomable-diagram.jsx** + - ✅ Border: `#333` → Should use theme border + - ✅ Background: `#0d0d0d` → Should use theme card background + - ✅ Button background: `#2d9a67` → Should use theme accent + - ✅ Text: `#fff`, `#666`, `#888` → Should use theme text colors + +3. **table.jsx** + - ⚠️ **SPECIAL CASE**: Header background `#2d9a67` with text `#fff` + - **DO NOT make text dynamic** - white text on green background is + intentional + - Only the border colors should be dynamic: `#2d9a67` → theme accent, + `#333` → theme border + +4. **code.jsx** + - ✅ Note text: `#9ca3af` → Should use theme muted text + +5. **divider.jsx** + - ✅ Divider color: `#e5e7eb` → Should use theme border + +6. **links.jsx** + - ✅ Default color parameter: `#2d9a67` → Should use theme accent (but allow + override) + - ✅ Hardcoded icon: `#2d9a67` → Should use theme accent + +7. **callouts.jsx** (04_GATEWAYS) + - ✅ Icon color: `#2d9a67` → Should use theme accent + +8. **coingecko.jsx** + - ⚠️ **SPECIAL CASE**: Header background `#2d9a67` with text `#fff` + - **DO NOT make text dynamic** - white text on green background is + intentional + - Border colors: `#2d9a67` → theme accent, `#333` → theme border + - Link color: `#2d9a67` → theme accent + - ❌ **Trust score colors MUST STAY FIXED**: `#fbbf24` (yellow), `#22c55e` + (green), `#ef4444` (red) - these are semantic + +9. **steps.jsx** + - ✅ Icon color: `#18794e` → Should use theme accent (darker variant) + - ✅ Title color: `#2b9a66` → Should use theme accent + - ✅ Line color: `#2b9a66` → Should use theme accent + +### **Colors That SHOULD NOT BE DYNAMIC** (Semantic/Decorative) + +1. **previewCallouts.jsx** + - ❌ `#368add` (blue) - Semantic color for "Coming Soon" + - ❌ `#b636dd` (purple) - Semantic color for "Preview/Review" + - **Reason**: These are intentionally different colors to distinguish callout + types + +2. **responseField.jsx** + - ❌ `#3b82f6` (blue) - Syntax highlighting color + - **Reason**: Code syntax highlighting should remain consistent + +3. **coingecko.jsx** - Trust scores + - ❌ `#fbbf24` (yellow), `#22c55e` (green), `#ef4444` (red) + - **Reason**: Semantic colors representing trust levels (universal meaning) + +4. **HeroGif.jsx** - Starfield + - ❌ `#3CB540`, `#2b9a66`, `#18794E`, `#6BBF59` + - **Reason**: Decorative animation with specific brand color palette + +5. **frameMode.jsx** + - ❌ Default icon colors in examples/docs + - ✅ BUT fallback `#fff` in var() should use theme + - **Reason**: Icon colors are user-customizable parameters + +6. **icons.jsx** + - ❌ SVG fill `#fff` in LivepeerSVG + - ✅ BUT CSS variable fallbacks should use theme + - **Reason**: SVG internal colors are structural + +--- + +## 🔧 COMPONENTS NEEDING UPDATES + +### **HIGH PRIORITY** - Must Update (7 files) + +1. **external-content.jsx** ✅ + - Update border, background, link colors to use ThemeData + +2. **zoomable-diagram.jsx** ✅ + - Update all colors to use ThemeData + +3. **table.jsx** ⚠️ + - Update border colors ONLY + - **KEEP** white text on green header + +4. **code.jsx** ✅ + - Update muted text colors + +5. **divider.jsx** ✅ + - Update divider color + +6. **links.jsx** ✅ + - Update default color parameters to use ThemeData + +7. **coingecko.jsx** ⚠️ + - Update border and link colors + - **KEEP** white text on green header + - **KEEP** trust score colors fixed + +### **MEDIUM PRIORITY** - Should Update (2 files) + +8. **callouts.jsx** (04_GATEWAYS) ✅ + - Update icon color + +9. **steps.jsx** ✅ + - Update default color parameters + +### **LOW PRIORITY / NO CHANGE** (3 files) + +10. **previewCallouts.jsx** ❌ NO CHANGE +11. **responseField.jsx** ❌ NO CHANGE +12. **HeroGif.jsx** ❌ NO CHANGE + +--- + +## ⚠️ CRITICAL NOTES + +### **ThemeData Limitations** + +Current ThemeData only has: + +- `accent`, `heroText`, `text` + +**MISSING** theme properties needed: + +- `background` +- `cardBackground` +- `border` +- `mutedText` + +**ACTION REQUIRED**: Expand ThemeData before making component updates! + +### **Table/Header Rule** + +When background is a **fixed brand color** (green), text should be **fixed +contrasting color** (white). Only borders should be dynamic. + +--- + +**RECOMMENDATION**: + +1. First expand `ThemeData` with missing properties +2. Then update only the 9 files marked for update +3. Leave semantic/decorative colors unchanged diff --git a/snippets/components/code.jsx b/snippets/components/code.jsx deleted file mode 100644 index 8ad370851..000000000 --- a/snippets/components/code.jsx +++ /dev/null @@ -1,78 +0,0 @@ -export const CustomCodeBlock = ({ - filename, - icon, - language, - highlight, - codeString = "", - placeholderValue = "", - wrap = true, - lines = true, - preNote = "", - postNote = "", -}) => { - // Return null if no codeString is provided - if (!codeString || codeString.trim() === "") { - return null; - } - - const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue); - return ( - <> - {preNote && ( -
- {preNote} -
- )} - - {renderedCode} - - {postNote && ( -
- {postNote} -
- )} - - ); -}; - -/** - * CodeComponent - Simple code display with {PLACEHOLDER} replacement - * - * Props: - * - codeString: string with {PLACEHOLDER} to replace - * - placeholderValue: string value to insert in place of {PLACEHOLDER} - */ -export const CodeComponent = ({ - filename = "", - icon = "terminal", - language = "", - highlight = "", - expandable = false, - wrap = true, - lines = true, - codeString = "", - placeholderValue = "", -}) => { - const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue); - return ( - - {renderedCode} - - ); -}; diff --git a/snippets/components/coingecko.jsx b/snippets/components/coingecko.jsx deleted file mode 100644 index d5aa3732f..000000000 --- a/snippets/components/coingecko.jsx +++ /dev/null @@ -1,251 +0,0 @@ -import { useState, useEffect } from "react"; - -/** - * CoinGeckoExchanges - Dynamically fetches and displays exchanges that support a coin from CoinGecko - * - * Props: - * - coinId: The CoinGecko coin ID (e.g., "arbitrum", "ethereum", "bitcoin") - */ -export const CoinGeckoExchanges = ({ coinId = "arbitrum" }) => { - const [exchanges, setExchanges] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [sortBy, setSortBy] = useState(null); // null (default order), "name", or "type" - const [sortOrder, setSortOrder] = useState("asc"); // "asc" or "desc" - - useEffect(() => { - const fetchExchanges = async () => { - try { - // Fetch first page of tickers from CoinGecko API - const response = await fetch( - `https://api.coingecko.com/api/v3/coins/${coinId}/tickers?depth=true` - ); - - if (response.ok) { - const data = await response.json(); - - // Extract unique exchanges from tickers, preserving API order - const exchangeMap = new Map(); - - data.tickers?.forEach((ticker) => { - if (ticker.market?.name && ticker.trade_url) { - // Only add if not already in map (preserves first occurrence) - if (!exchangeMap.has(ticker.market.name)) { - exchangeMap.set(ticker.market.name, { - name: ticker.market.name, - url: ticker.trade_url, - trustScore: ticker.trust_score || "N/A", - tradingPair: - ticker.base && ticker.target - ? `${ticker.base}/${ticker.target}` - : "N/A", - type: - ticker.market.identifier?.includes("uniswap") || - ticker.market.identifier?.includes("sushiswap") || - ticker.market.identifier?.includes("pancakeswap") || - ticker.market.name?.toLowerCase().includes("swap") || - ticker.market.name?.toLowerCase().includes("dex") - ? "DEX" - : "CEX", - }); - } - } - }); - - // Convert to array, preserving the order from the API - const exchangeList = Array.from(exchangeMap.values()); - - setExchanges(exchangeList); - } else { - throw new Error("Failed to fetch exchange data"); - } - } catch (err) { - setError("Failed to load exchange data"); - console.error("CoinGeckoExchanges error:", err); - } finally { - setLoading(false); - } - }; - - fetchExchanges(); - }, [coinId]); - - if (loading) { - return
Loading exchanges...
; - } - - if (error) { - return
Error: {error}
; - } - - if (exchanges.length === 0) { - return
No exchanges found for this coin.
; - } - - // Sort exchanges based on current sort settings - const sortedExchanges = sortBy - ? [...exchanges].sort((a, b) => { - let comparison = 0; - - if (sortBy === "type") { - comparison = a.type.localeCompare(b.type); - } else if (sortBy === "name") { - comparison = a.name.localeCompare(b.name); - } - - return sortOrder === "asc" ? comparison : -comparison; - }) - : exchanges; // If no sort selected, use original API order - - const handleSort = (column) => { - if (sortBy === column) { - // Toggle sort order if clicking the same column - setSortOrder(sortOrder === "asc" ? "desc" : "asc"); - } else { - // Set new column and default to ascending - setSortBy(column); - setSortOrder("asc"); - } - }; - - // Convert trust score to color - const getTrustScoreColor = (trustScore) => { - if (trustScore === "N/A" || trustScore === "yellow") return "#fbbf24"; // yellow - if (trustScore === "green") return "#22c55e"; // green - if (trustScore === "red") return "#ef4444"; // red - return "#fbbf24"; // default yellow - }; - - return ( -
- - - - - - - - - - - - {sortedExchanges.map((exchange, index) => ( - - - - - - - - ))} - -
handleSort("name")} - title="Click to sort by name" - > - Exchange {sortBy === "name" && (sortOrder === "asc" ? "↑" : "↓")} - handleSort("type")} - title="Click to sort by type" - > - Type {sortBy === "type" && (sortOrder === "asc" ? "↑" : "↓")} - - Pair - - Trust - - Link -
- {exchange.name} - - - {exchange.type} - - - {exchange.tradingPair} - - - - - Trade → - -
-
- ); -}; diff --git a/snippets/components/content/code.jsx b/snippets/components/content/code.jsx new file mode 100644 index 000000000..ce99dd146 --- /dev/null +++ b/snippets/components/content/code.jsx @@ -0,0 +1,284 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * CustomCodeBlock - Advanced code block with placeholder replacement and optional output + * + * @description + * Displays a code block with support for placeholder replacement, pre/post notes, + * and expandable expected output section. + * + * @param {string} filename - Name of the file to display in the code block header + * @param {string} icon - Icon to display in the code block header + * @param {string} language - Programming language for syntax highlighting + * @param {string} highlight - Line numbers or ranges to highlight (e.g., "1-3,5") + * @param {string} [codeString=""] - The code content to display + * @param {string} [placeholderValue=""] - Value to replace {PLACEHOLDER} with in the code + * @param {boolean} [wrap=true] - Whether to wrap long lines + * @param {boolean} [lines=true] - Whether to show line numbers + * @param {string} [preNote=""] - Note to display before the code block + * @param {string} [postNote=""] - Note to display after the code block + * @param {Object} [output=""] - Optional output configuration object + * @param {string} [output.codeString] - Output code content + * @param {string} [output.filename] - Output filename + * @param {string} [output.icon] - Output icon + * @param {string} [output.language] - Output language + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const CustomCodeBlock = ({ + filename, + icon, + language, + highlight, + codeString = "", + placeholderValue = "", + wrap = true, + lines = true, + preNote = "", + postNote = "", + output = "", +}) => { + // Return null if no codeString is provided + if (!codeString || codeString.trim() === "") { + return null; + } + + const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue); + // const CalloutComponent = callout?.type ? callout.type : Note; + + return ( + <> + + {preNote && ( +
+ {preNote} +
+ )} + + {renderedCode} + + {postNote && ( +
+ {postNote} +
+ )} + {output?.codeString && ( + <> + + Expected Output + + } + > + + {output.codeString} + + +
+ + )} + + ); +}; + +/** + * CodeComponent - Simple code display with {PLACEHOLDER} replacement + * + * Props: + * - codeString: string with {PLACEHOLDER} to replace + * - placeholderValue: string value to insert in place of {PLACEHOLDER} + */ +export const CodeComponent = ({ + filename = "", + icon = "terminal", + language = "", + highlight = "", + expandable = false, + wrap = true, + lines = true, + codeString = "", + placeholderValue = "", +}) => { + const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue); + return ( + + {renderedCode} + + ); +}; + +/** + * ComplexCodeBlock - Code block with placeholder replacement and pre/post notes + * + * @description + * Similar to CustomCodeBlock but without the output section. + * Supports placeholder replacement and optional notes before/after the code. + * + * @param {string} filename - Name of the file to display + * @param {string} icon - Icon for the code block header + * @param {string} language - Programming language for syntax highlighting + * @param {string} highlight - Line numbers to highlight + * @param {string} [codeString=""] - The code content + * @param {string} [placeholderValue=""] - Value to replace {PLACEHOLDER} with + * @param {boolean} [wrap=true] - Whether to wrap long lines + * @param {boolean} [lines=true] - Whether to show line numbers + * @param {React.ReactNode} [preNote=null] - Note to display before the code + * @param {React.ReactNode} [postNote=null] - Note to display after the code + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const ComplexCodeBlock = ({ + filename, + icon, + language, + highlight, + codeString = "", + placeholderValue = "", + wrap = true, + lines = true, + preNote = null, + postNote = null, +}) => { + // Return null if no codeString is provided + if (!codeString || codeString.trim() === "") { + return null; + } + + const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue); + + return ( + <> + + {preNote && ( +
+ {preNote} +
+ )} + + {renderedCode} + + {postNote && ( +
+ {postNote} +
+ )} + + ); +}; + +/** + * CodeSection - Wrapper component for ComplexCodeBlock + * + * @description + * Convenience wrapper that accepts a fields object and spreads it to ComplexCodeBlock. + * Useful for passing configuration objects. + * + * @param {Object} [fields={}] - Object containing all ComplexCodeBlock props + * + * @example + * const codeConfig = { + * filename: "app.js", + * language: "javascript", + * codeString: "console.log('Hello');" + * }; + * + * + * @author Livepeer Documentation Team + */ +export const CodeSection = ({ fields = {} }) => { + return ; +}; + +// export const CodeSection = ({ fields = {} }) => { +// return ; +// }; diff --git a/snippets/components/content/examples/code-examples.mdx b/snippets/components/content/examples/code-examples.mdx new file mode 100644 index 000000000..7baaa2365 --- /dev/null +++ b/snippets/components/content/examples/code-examples.mdx @@ -0,0 +1,187 @@ +--- +title: "Code Components Examples" +description: "Examples of using code-related components from code.jsx" +--- + +import { CustomCodeBlock, CodeComponent, ComplexCodeBlock, CodeSection } from "/snippets/components/content/code.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## CustomCodeBlock + +### Basic Usage + + + +### With Placeholder Replacement + + + +### With Pre and Post Notes + + + +### With Expected Output + + + +## CodeComponent + +### Simple Code Display + + + +### With Placeholder + + + +### With Line Numbers Disabled + + + +## ComplexCodeBlock + +### With Pre Note + + + +### With Post Note + + + +### With Both Notes and Highlighting + + + +## CodeSection + +### Using CodeSection Wrapper + + + +### CodeSection with All Options + + + diff --git a/snippets/components/content/examples/external-content-examples.mdx b/snippets/components/content/examples/external-content-examples.mdx new file mode 100644 index 000000000..fbffbb271 --- /dev/null +++ b/snippets/components/content/examples/external-content-examples.mdx @@ -0,0 +1,154 @@ +--- +title: "ExternalContent Component Examples" +description: "Examples of using the ExternalContent component" +--- + +import { ExternalContent } from "/snippets/components/content/external-content.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## Basic Usage + + +
+

Awesome Livepeer Resources

+

A curated list of awesome Livepeer resources, libraries, tools and more.

+
    +
  • Documentation
  • +
  • Tutorials
  • +
  • Community Projects
  • +
+
+
+ +## Custom Max Height + + +
+

Go Livepeer

+

Official Livepeer node implementation in Go.

+

This content area is limited to 300px height and will scroll if content exceeds that.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+

Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+

Ut enim ad minim veniam, quis nostrud exercitation ullamco.

+
+
+ +## Custom Icon + + +
+

Livepeer Documentation

+

Official documentation repository with a custom book icon.

+
+
+ +## With Markdown Content + + +
+

Livepeer Protocol

+ +

Overview

+

The Livepeer protocol is a decentralized video streaming network protocol.

+ +

Features

+
    +
  • Decentralized: No single point of failure
  • +
  • Scalable: Grows with demand
  • +
  • Cost-effective: Lower costs than traditional solutions
  • +
+ +

Getting Started

+

To get started with the Livepeer protocol:

+
    +
  1. Clone the repository
  2. +
  3. Install dependencies
  4. +
  5. Run the setup script
  6. +
+ +

Code Example

+
npm install @livepeer/sdk
+
+
+ +## Multiple External Content Blocks + + +
+

Livepeer.js

+

JavaScript SDK for Livepeer

+
+
+ + +
+

Livepeer Studio

+

Video infrastructure for developers

+
+
+ +## With Complex Nested Content + + +
+

Community Resources

+ +
+

Join the Livepeer community and contribute to the future of decentralized video!

+
+ +

Ways to Contribute

+ + + + + + + + + + + + + + + + + + + + + +
TypeDescription
CodeSubmit pull requests
DocumentationImprove docs
CommunityHelp others
+
+
+ diff --git a/snippets/components/content/examples/release-examples.mdx b/snippets/components/content/examples/release-examples.mdx new file mode 100644 index 000000000..ee7aade3e --- /dev/null +++ b/snippets/components/content/examples/release-examples.mdx @@ -0,0 +1,93 @@ +--- +title: "LatestVersion Component Examples" +description: "Examples of using the LatestVersion component" +--- + +import { LatestVersion } from "/snippets/components/content/release.jsx"; + +## Basic Usage + +The current version is: + +## In a Sentence + +Download the latest release from GitHub. + +## In a Code Block + +```bash +# Install version +wget https://github.com/livepeer/go-livepeer/releases/download/v0.7.10/livepeer-linux-amd64.tar.gz +``` + +## In a Table + +| Component | Version | +|-----------|---------| +| go-livepeer | | +| livepeer.js | | +| studio | | + +## Multiple Versions + +- **Stable Release:** +- **Beta Release:** +- **Alpha Release:** + +## In a Note + + + The latest stable version is . + Please update your installation if you're running an older version. + + +## In a Warning + + + Version has known security issues. + Please upgrade to immediately. + + +## In a Card + + + Version is now available with bug fixes and performance improvements. + + +## With Download Instructions + + + + The latest version is + + + Download the release for your platform + + + Follow the installation instructions + + + +## In an Accordion + + + Current stable version: + + This version includes: + - Bug fixes + - Performance improvements + - New features + + +## Inline with Text Formatting + +The **latest version** is , which was released with *significant improvements*. + +## In a List + +### Recent Releases + +1. - Current stable +2. - Previous stable +3. - Legacy support + diff --git a/snippets/components/content/examples/responseField-examples.mdx b/snippets/components/content/examples/responseField-examples.mdx new file mode 100644 index 000000000..20efa8406 --- /dev/null +++ b/snippets/components/content/examples/responseField-examples.mdx @@ -0,0 +1,228 @@ +--- +title: "ResponseField Components Examples" +description: "Examples of using ResponseField wrapper components" +--- + +import { + ValueResponseField, + CustomResponseField, + ResponseFieldExpandable, + ResponseFieldAccordion +} from "/snippets/components/content/responseField.jsx"; + +## CustomResponseField + +### Basic Usage + + + Unique identifier for the resource + + + + Display name of the resource + + +### With Default Value + + + Current status of the resource + + +### Required Field + + + API key for authentication (required) + + +## ValueResponseField + +### Basic Value Field + + + +### Multiple Value Fields + + + + + +## ResponseFieldExpandable + +### Basic Expandable Group + + + {[ + { + name: "name", + type: "string", + description: "Stream name", + post: ["My Live Stream"] + }, + { + name: "profiles", + type: "array", + description: "Transcoding profiles", + post: ["[720p, 480p, 360p]"] + }, + { + name: "record", + type: "boolean", + description: "Enable recording", + post: ["true"] + } + ]} + + +### Nested Configuration + + + {[ + { + name: "multistream", + type: "object", + description: "Multistream configuration" + }, + { + name: "multistream.targets", + type: "array", + description: "List of multistream targets" + }, + { + name: "webhooks", + type: "object", + description: "Webhook configuration" + }, + { + name: "webhooks.url", + type: "string", + description: "Webhook endpoint URL", + post: ["https://example.com/webhook"] + } + ]} + + +## ResponseFieldAccordion + +### Basic Accordion + + + {[ + { + name: "id", + type: "string", + description: "Unique asset identifier", + post: ["asset_abc123"] + }, + { + name: "status", + type: "string", + description: "Processing status", + post: ["ready"] + }, + { + name: "createdAt", + type: "timestamp", + description: "Creation timestamp", + post: ["1640000000000"] + } + ]} + + +### Multiple Accordions + + + {[ + { + name: "name", + type: "string", + description: "Asset name", + required: true + }, + { + name: "url", + type: "string", + description: "Source video URL", + required: true + } + ]} + + + + {[ + { + name: "playbackId", + type: "string", + description: "Playback identifier", + post: ["play_abc123"] + }, + { + name: "downloadUrl", + type: "string", + description: "Download URL", + post: ["https://livepeer.studio/download/abc123"] + } + ]} + + +## Combined Example + +### Complete API Documentation + + + POST /api/v1/stream + + + + {[ + { + name: "name", + type: "string", + description: "Stream name", + required: true + }, + { + name: "profiles", + type: "array", + description: "Transcoding profiles (optional)" + } + ]} + + + + {[ + { + name: "id", + type: "string", + description: "Stream ID", + post: ["stream_abc123"] + }, + { + name: "streamKey", + type: "string", + description: "RTMP stream key", + post: ["abc123-xyz789"] + }, + { + name: "playbackUrl", + type: "string", + description: "HLS playback URL", + post: ["https://livepeer.studio/hls/abc123/index.m3u8"] + } + ]} + + diff --git a/snippets/components/content/external-content.jsx b/snippets/components/content/external-content.jsx new file mode 100644 index 000000000..adc2f7ac6 --- /dev/null +++ b/snippets/components/content/external-content.jsx @@ -0,0 +1,87 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * ExternalContent - A reusable component for displaying external GitHub content + * Usage: + * import { ExternalContent } from '/snippets/components/content/external-content.jsx' + * import MyContent from '/snippets/external/my-content.mdx' + * + * + * + */ + +export const ExternalContent = ({ + repoName, + githubUrl, + maxHeight = "1000px", + icon = "github", + children, +}) => { + return ( + <> + +
+
+ + + {repoName} + + + View on GitHub + +
+
+ {children} +
+
+ + ); +}; diff --git a/snippets/components/content/release.jsx b/snippets/components/content/release.jsx new file mode 100644 index 000000000..bb93f4bf2 --- /dev/null +++ b/snippets/components/content/release.jsx @@ -0,0 +1,7 @@ +/** + * LatestVersion - Wrapper for github action which fetches most recent release version of go-livepeer + */ + +export const LatestVersion = ({ version }) => { + return <>{version}; +}; diff --git a/snippets/components/responseField.jsx b/snippets/components/content/responseField.jsx similarity index 100% rename from snippets/components/responseField.jsx rename to snippets/components/content/responseField.jsx diff --git a/snippets/components/custom-view-dropdown.jsx b/snippets/components/custom-view-dropdown.jsx deleted file mode 100644 index c87a71204..000000000 --- a/snippets/components/custom-view-dropdown.jsx +++ /dev/null @@ -1,211 +0,0 @@ -"use client"; -import React, { useState } from "react"; - -export const CustomViewDropdown = ({ views, position = "inline" }) => { - const [selectedView, setSelectedView] = useState(0); - const [isOpen, setIsOpen] = useState(false); - - if (!views || views.length === 0) { - return null; - } - - return ( - <> - {/* Custom Dropdown - Position controlled by 'position' prop */} -
- - - {/* Dropdown Menu */} - {isOpen && ( - <> -
setIsOpen(false)} - /> -
- {views.map((view, index) => ( - - ))} -
- - )} -
- - {/* Content Display */} -
{views[selectedView]?.content}
- - - - ); -}; diff --git a/snippets/components/display/embed.jsx b/snippets/components/display/embed.jsx new file mode 100644 index 000000000..0133b2182 --- /dev/null +++ b/snippets/components/display/embed.jsx @@ -0,0 +1,50 @@ +/** + * MarkdownEmbed - Fetches and renders markdown content from a URL + * + * @description + * Dynamically fetches markdown content from a remote URL and renders it. + * Uses React hooks to manage the fetch lifecycle. + * + * @param {string} url - URL of the markdown file to fetch and display + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const MarkdownEmbed = ({ url }) => { + const [content, setContent] = useState(""); + + useEffect(() => { + fetch(url) + .then((res) => res.text()) + .then(setContent); + }, [url]); + + return {content}; +}; + +/** + * EmbedMarkdown - Alias for MarkdownEmbed + * + * @description + * Alternative name for MarkdownEmbed component. Fetches and renders markdown from a URL. + * + * @param {string} url - URL of the markdown file to fetch and display + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const EmbedMarkdown = ({ url }) => { + const [content, setContent] = useState(""); + + useEffect(() => { + fetch(url) + .then((res) => res.text()) + .then(setContent); + }, [url]); + + return {content}; +}; diff --git a/snippets/components/display/examples/embed-examples.mdx b/snippets/components/display/examples/embed-examples.mdx new file mode 100644 index 000000000..3a3c140a5 --- /dev/null +++ b/snippets/components/display/examples/embed-examples.mdx @@ -0,0 +1,114 @@ +--- +title: "Markdown Embed Components Examples" +description: "Examples of using MarkdownEmbed and EmbedMarkdown components" +--- + +import { MarkdownEmbed, EmbedMarkdown } from "/snippets/components/display/embed.jsx"; + +## MarkdownEmbed + +### Basic Usage + +Embed external markdown content from a URL: + + + +### Embedding Documentation + + + +### Embedding Release Notes + + + +## EmbedMarkdown + +### Basic Usage (Alias) + +`EmbedMarkdown` is an alias for `MarkdownEmbed` and works identically: + + + +### Embedding Contributing Guidelines + + + +## Use Cases + +### 1. Embedding External Documentation + +Keep your docs in sync with external repositories: + + + + + +### 2. Displaying Changelogs + +Show the latest changes from your repository: + + + + + +### 3. Embedding Code of Conduct + + + +### 4. Embedding API Documentation + + + + + + + + + + +## Notes + + + **Important:** The embedded content is fetched client-side when the page loads. + Make sure the URL is publicly accessible and returns raw markdown content. + + + + **CORS Warning:** Some URLs may be blocked by CORS policies. + Use raw GitHub URLs (raw.githubusercontent.com) for best results. + + +## Best Practices + +1. **Use Raw URLs:** Always use raw content URLs (e.g., from GitHub's raw.githubusercontent.com) +2. **Check Accessibility:** Ensure the URL is publicly accessible +3. **Consider Caching:** The content is fetched on each page load +4. **Fallback Content:** Consider providing fallback content if the fetch fails + +## Example with Multiple Embeds + + +
+

README

+ +
+
+

Contributing

+ +
+
+ +## Advanced Usage + +### With Custom Styling + +
+ +
+ +### In a Frame + + + + + diff --git a/snippets/components/display/examples/image-examples.mdx b/snippets/components/display/examples/image-examples.mdx new file mode 100644 index 000000000..e92612c9f --- /dev/null +++ b/snippets/components/display/examples/image-examples.mdx @@ -0,0 +1,221 @@ +--- +title: "Image Components Examples" +description: "Examples of using Image and LinkImage components" +--- + +import { Image, LinkImage } from "/snippets/components/display/image.jsx"; + +## Image Component + +### Basic Usage + +Livepeer Logo + +### With Caption + +Livepeer Architecture + +### With Hint + +Dashboard Screenshot + +### With Caption and Hint + +Video Processing Workflow + +### Custom Icon + +API Flow Diagram + +### Fixed Width (Not Full Width) + +Small Icon + +## LinkImage Component + +### Basic Linked Image + + + +### With Caption and Link + + + +### With Hint and Link + + + +### External Link with Icon + + + +## Use Cases + +### 1. Documentation Screenshots + +Dashboard Overview + +### 2. Architecture Diagrams + +Network Topology + +### 3. Tutorial Images with Links + + + +### 4. Comparison Images + + + Before Optimization + After Optimization + + +### 5. Gallery of Linked Images + + + + + + + +## Advanced Examples + +### Image in a Card + + + Detailed Architecture + + +### Image in an Accordion + + + Complex System Diagram + + +### Image in Steps + + + + Create Stream Interface + + + Configuration Screen + + + Active Stream + + + +## GIF Support + +Animated Demo + diff --git a/snippets/components/display/examples/video-examples.mdx b/snippets/components/display/examples/video-examples.mdx new file mode 100644 index 000000000..a56adb99b --- /dev/null +++ b/snippets/components/display/examples/video-examples.mdx @@ -0,0 +1,216 @@ +--- +title: "Video Components Examples" +description: "Examples of using YouTubeVideo and CardVideo components" +--- + +import { YouTubeVideo, CardVideo } from "/snippets/components/display/video.jsx"; + +## YouTubeVideo Component + +### Basic Usage + + + +### With Caption + + + +### With Hint + + + +### With Caption and Hint + + + +## CardVideo Component + +### Basic Card Video + + + +### Multiple Card Videos + + + + + + +## Use Cases + +### 1. Tutorial Series + + + + + + + + + + + + + +### 2. Video in Steps + + + + + + + Now that you've watched the intro, let's start coding! + + + + + + +### 3. Video Gallery + + + + + + + + + + +### 4. Video in Accordion + + + + + +### 5. Video with Context + + +

Before watching this video, make sure you have:

+
    +
  • Created a Livepeer Studio account
  • +
  • Generated an API key
  • +
  • Set up your development environment
  • +
+ + + + + The code from this video is available in our GitHub repository. + +
+ +## Advanced Examples + +### Video Playlist + + +

Module 1: Fundamentals

+ + +

Module 2: Implementation

+ + +

Module 3: Advanced Topics

+ +
+ +### Comparison Videos + + +
+

Before Optimization

+ +
+
+

After Optimization

+ +
+
+ diff --git a/snippets/components/display/examples/zoomable-diagram-examples.mdx b/snippets/components/display/examples/zoomable-diagram-examples.mdx new file mode 100644 index 000000000..2a0ffc2d6 --- /dev/null +++ b/snippets/components/display/examples/zoomable-diagram-examples.mdx @@ -0,0 +1,261 @@ +--- +title: "ScrollableDiagram Component Examples" +description: "Examples of using the ScrollableDiagram component for interactive diagrams" +--- + +import { ScrollableDiagram } from "/snippets/components/display/zoomable-diagram.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## Basic Usage + + +
+
{`
+    ┌─────────────┐
+    │   Client    │
+    └──────┬──────┘
+           │
+           ▼
+    ┌─────────────┐
+    │   Gateway   │
+    └──────┬──────┘
+           │
+           ▼
+    ┌─────────────┐
+    │   Server    │
+    └─────────────┘
+    `}
+
+
+ +## Custom Max Height + + +
+
{`
+    Layer 1: Application
+    ├── Web Interface
+    ├── API Gateway
+    └── Authentication
+    
+    Layer 2: Business Logic
+    ├── Stream Processing
+    ├── Transcoding Engine
+    └── Storage Manager
+    
+    Layer 3: Data Layer
+    ├── Database
+    ├── Cache
+    └── Object Storage
+    
+    Layer 4: Infrastructure
+    ├── Load Balancer
+    ├── CDN
+    └── Monitoring
+    `}
+
+
+ +## Wide Diagram + + +
+
{`
+    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
+    │  Client  │───▶│  CDN     │───▶│ Gateway  │───▶│ Transcode│───▶│ Storage  │
+    └──────────┘    └──────────┘    └──────────┘    └──────────┘    └──────────┘
+         │               │                │               │               │
+         │               │                │               │               │
+         ▼               ▼                ▼               ▼               ▼
+    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
+    │Analytics │    │  Cache   │    │   Auth   │    │  Queue   │    │ Database │
+    └──────────┘    └──────────┘    └──────────┘    └──────────┘    └──────────┘
+    `}
+
+
+ +## With Mermaid Diagram + + +
+
{`
+    graph LR
+        A[Video Upload] --> B[Validation]
+        B --> C[Queue]
+        C --> D[Transcoding]
+        D --> E[Quality Check]
+        E --> F{Pass?}
+        F -->|Yes| G[Storage]
+        F -->|No| D
+        G --> H[CDN Distribution]
+        H --> I[Playback]
+    `}
+
+
+ +## Complex System Diagram + + +
+
{`
+    ╔════════════════════════════════════════════════════════════════════╗
+    ║                        LIVEPEER ECOSYSTEM                          ║
+    ╚════════════════════════════════════════════════════════════════════╝
+    
+    ┌─────────────────────────────────────────────────────────────────┐
+    │                         CLIENT LAYER                            │
+    ├─────────────────────────────────────────────────────────────────┤
+    │  Web App  │  Mobile App  │  Desktop App  │  Third-party Apps   │
+    └────┬──────┴──────┬───────┴───────┬───────┴──────────┬───────────┘
+         │             │               │                  │
+         └─────────────┴───────────────┴──────────────────┘
+                              │
+                              ▼
+    ┌─────────────────────────────────────────────────────────────────┐
+    │                         API GATEWAY                             │
+    ├─────────────────────────────────────────────────────────────────┤
+    │  Authentication  │  Rate Limiting  │  Request Routing           │
+    └────┬─────────────┴─────────┬───────┴────────────────────────────┘
+         │                       │
+         ▼                       ▼
+    ┌─────────────┐      ┌─────────────────┐
+    │   Stream    │      │     Asset       │
+    │   Service   │      │    Service      │
+    └──────┬──────┘      └────────┬────────┘
+           │                      │
+           └──────────┬───────────┘
+                      ▼
+    ┌─────────────────────────────────────────────────────────────────┐
+    │                    TRANSCODING LAYER                            │
+    ├─────────────────────────────────────────────────────────────────┤
+    │  Orchestrator  │  Transcoder Nodes  │  Quality Verification    │
+    └────────────────┴────────────────────┴──────────────────────────┘
+                              │
+                              ▼
+    ┌─────────────────────────────────────────────────────────────────┐
+    │                      STORAGE LAYER                              │
+    ├─────────────────────────────────────────────────────────────────┤
+    │  Object Storage  │  Database  │  Cache  │  CDN                  │
+    └─────────────────────────────────────────────────────────────────┘
+    `}
+
+
+ +## Use Cases + +### 1. API Flow Diagram + + +
+
{`
+    1. Client Request
+       │
+       ▼
+    2. API Gateway
+       ├─ Validate API Key
+       ├─ Check Rate Limit
+       └─ Route Request
+       │
+       ▼
+    3. Service Layer
+       ├─ Process Request
+       ├─ Business Logic
+       └─ Data Validation
+       │
+       ▼
+    4. Data Layer
+       ├─ Query Database
+       ├─ Update Cache
+       └─ Store Results
+       │
+       ▼
+    5. Response
+       └─ Return to Client
+    `}
+
+
+ +### 2. Network Topology + + +
+
{`
+                    ┌─────────────┐
+                    │  Broadcaster│
+                    └──────┬──────┘
+                           │
+            ┌──────────────┼──────────────┐
+            │              │              │
+            ▼              ▼              ▼
+    ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
+    │Orchestrator 1│ │Orchestrator 2│ │Orchestrator 3│
+    └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
+           │                │                │
+    ┌──────┴────┐    ┌──────┴────┐    ┌──────┴────┐
+    │           │    │           │    │           │
+    ▼           ▼    ▼           ▼    ▼           ▼
+┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
+│Trans 1 │ │Trans 2 │ │Trans 3 │ │Trans 4 │ │Trans 5 │
+└────────┘ └────────┘ └────────┘ └────────┘ └────────┘
+    `}
+
+
+ +### 3. Data Flow + + +
+
{`
+    Input Video ──▶ Validation ──▶ Segmentation ──▶ Transcoding ──▶ Output
+         │              │              │               │              │
+         │              │              │               │              │
+         ▼              ▼              ▼               ▼              ▼
+    Format Check   Size Check    HLS Segments    Multiple         Storage
+    Codec Check    Duration      DASH Segments   Renditions       CDN Push
+    Resolution     Metadata      Thumbnails      720p, 480p       Playback URLs
+    `}
+
+
+ +## Advanced Examples + +### With HTML Content + + +
+
+
+ Frontend Layer +

React Components, State Management, API Calls

+
+
+
+ API Layer +

REST API, GraphQL, WebSocket

+
+
+
+ Backend Layer +

Business Logic, Authentication, Processing

+
+
+
+
+ diff --git a/snippets/components/display/frameMode.jsx b/snippets/components/display/frameMode.jsx new file mode 100644 index 000000000..ba78ed0aa --- /dev/null +++ b/snippets/components/display/frameMode.jsx @@ -0,0 +1,648 @@ +/** + * Frame Mode Headers - Custom heading components for Mintlify frame mode + * + * @description + * These components provide styled headings (H1-H6) that work properly in Mintlify's + * frame mode where default markdown headings may not render correctly. + * + * All components support optional icons at the beginning of the heading. + * Icons use theme-aware colors that adapt to light/dark mode. + * + * @requires ThemeData must be imported in the MDX file where these components are used: + * import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + * + * @note Icon is a Mintlify global component - no import needed + * + * @author Alison Haire + */ + +/** + * H1 - Custom H1 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG (e.g., "rocket", "/snippets/assets/logos/icon.svg") + * @param {number} iconSize - Size of the icon (default: 32) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.75rem") + * + * @example + *

Simple Heading

+ *

Heading with Icon

+ *

Centered with Theme Icon

+ */ + +const PageHeader = ({ + title, + subtitle, + description, + children, + titleColor, + subtitleColor, + descriptionColor, +}) => { + return ( +
+

+ {title} +

+ {subtitle && ( +

+ {subtitle} +

+ )} + {description && ( +
+ {description} +
+ )} + + {children} +
+ +
+
+ ); +}; + +// import { Starfield as HeroStarfield } from "/snippets/components/domain/SHARED/HeroGif.jsx"; +// const PageHeader2 = ({ +// title, +// subtitle, +// description, +// children, +// titleColor, +// subtitleColor, +// descriptionColor, +// }) => { +// return ( +//
+// {/* Background */} +// + +// {/* Content */} +//
+//

+// {title} +//

+ +// {subtitle && ( +//

+// {subtitle} +//

+// )} + +// {description && ( +//
+// {description} +//
+// )} + +// {children} + +//
+// +//
+//
+//
+// ); +// }; + +const H1 = ({ + children, + icon, + iconSize = 32, + iconColor, + align = "left", + gap = "0.75rem", +}) => { + // Use theme-aware color if not specified + const defaultIconColor = iconColor || "var(--h1-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + }; + + const headingStyle = { + margin: "2rem 0 1rem 0", + fontSize: "2.5rem", + fontWeight: "bold", + lineHeight: "1.2", + color: "var(--page-header-title-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +

{children}

+
+ + ); +}; + +/** + * H2 - Custom H2 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 28) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.75rem") + */ +const H2 = ({ + children, + icon, + iconSize = 28, + iconColor, + align = "left", + gap = "0.75rem", +}) => { + const defaultIconColor = iconColor || "var(--h2-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + marginBottom: "1rem", + }; + + const headingStyle = { + margin: 0, + fontSize: "1.875rem", + fontWeight: "bold", + color: "var(--h2-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +

{children}

+
+ + ); +}; + +/** + * H3 - Custom H3 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 24) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.5rem") + */ +const H3 = ({ + children, + icon, + iconSize = 24, + iconColor, + align = "left", + gap = "0.5rem", +}) => { + const defaultIconColor = iconColor || "var(--h3-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + marginBottom: "0.75rem", + }; + + const headingStyle = { + margin: 0, + fontSize: "1.5rem", + fontWeight: "bold", + color: "var(--h3-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +

{children}

+
+ + ); +}; + +/** + * H4 - Custom H4 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 20) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.5rem") + */ +const H4 = ({ + children, + icon, + iconSize = 20, + iconColor, + align = "left", + gap = "0.5rem", +}) => { + const defaultIconColor = iconColor || "var(--h4-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + marginBottom: "0.75rem", + }; + + const headingStyle = { + margin: 0, + fontSize: "1.25rem", + fontWeight: "bold", + color: "var(--h4-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +

{children}

+
+ + ); +}; + +/** + * H5 - Custom H5 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 18) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.5rem") + */ +const H5 = ({ + children, + icon, + iconSize = 18, + iconColor, + align = "left", + gap = "0.5rem", +}) => { + const defaultIconColor = iconColor || "var(--h5-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + marginBottom: "0.5rem", + }; + + const headingStyle = { + margin: 0, + fontSize: "1.125rem", + fontWeight: "bold", + color: "var(--h5-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +
{children}
+
+ + ); +}; + +/** + * H6 - Custom H6 heading component for frame mode + * + * @param {string} children - The heading text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 16) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.5rem") + */ +const H6 = ({ + children, + icon, + iconSize = 16, + iconColor, + align = "left", + gap = "0.5rem", +}) => { + const defaultIconColor = iconColor || "var(--h6-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + marginBottom: "0.5rem", + }; + + const headingStyle = { + margin: 0, + fontSize: "1rem", + fontWeight: "bold", + color: "var(--h6-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +
{children}
+
+ + ); +}; + +/** + * P - Custom paragraph component for frame mode + * + * @param {string} children - The paragraph text + * @param {string} icon - Optional icon name or path to theme-aware SVG + * @param {number} iconSize - Size of the icon (default: 16) + * @param {string} iconColor - Color of the icon (default: theme-aware accent color) + * @param {string} align - Text alignment: "left", "center", "right" (default: "left") + * @param {string} gap - Gap between icon and text (default: "0.5rem") + * + * @example + *

Simple paragraph

+ *

Paragraph with icon

+ *

Centered with theme icon

+ */ +const P = ({ + children, + icon, + iconSize = 16, + iconColor, + align = "left", + gap = "0.5rem", +}) => { + const defaultIconColor = iconColor || "var(--p-icon-color)"; + + const containerStyle = { + display: icon ? "flex" : "block", + alignItems: "center", + gap: icon ? gap : 0, + justifyContent: + align === "center" + ? "center" + : align === "right" + ? "flex-end" + : "flex-start", + textAlign: align, + }; + + const paragraphStyle = { + margin: 0, + color: "var(--p-text-color)", + opacity: 1, + }; + + return ( + <> + +
+ {icon && } +

{children}

+
+ + ); +}; + +/** + * Divider - Horizontal divider line for frame mode + * + * @description + * Renders a horizontal rule (---) with proper styling for frame mode. + * Uses theme-aware border color that adapts to light and dark themes. + * + * @param {string} color - Custom color for the divider (optional, defaults to theme border color) + * @param {string} margin - Vertical margin (default: "1.5rem 0") + * @param {string} opacity - Opacity of the divider (default: 0.2) + * + * @example + * + * + */ +const Divider = ({ color, margin = "1.5rem 0", opacity = 0.2 }) => { + return ( + <> + +
+ + ); +}; + +export { PageHeader, H1, H2, H3, H4, H5, H6, P, Divider }; diff --git a/snippets/components/display/image.jsx b/snippets/components/display/image.jsx new file mode 100644 index 000000000..04094d68a --- /dev/null +++ b/snippets/components/display/image.jsx @@ -0,0 +1,78 @@ +/** + * Image - Image component with Frame wrapper + * + * @description + * Displays an image within a Frame component with optional caption and hint. + * Supports full-width or auto-width display. + * + * @param {string} src - Image source URL + * @param {string} alt - Alt text for accessibility + * @param {string} [caption] - Optional caption to display below the image + * @param {string} [icon] - Icon name (currently unused in implementation) + * @param {string} [hint] - Optional hint text + * @param {boolean} [fullwidth=true] - Whether to display image at full width + * + * @example + * System Diagram + * + * @author Livepeer Documentation Team + */ +export const Image = ({ src, alt, caption, icon, hint, fullwidth = true }) => { + icon = icon ? icon : "arrow-turn-down-right"; + return ( + + {alt} + + ); +}; + +/** + * LinkImage - Clickable image that opens in a new tab + * + * @description + * Displays an image within a Frame component that links to a URL. + * Opens the link in a new tab when clicked. + * + * @param {string} src - Image source URL + * @param {string} alt - Alt text for accessibility + * @param {string} [caption] - Optional caption to display below the image + * @param {string} [icon] - Icon name (currently unused in implementation) + * @param {string} [hint] - Optional hint text + * @param {string} href - URL to navigate to when image is clicked + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const LinkImage = ({ src, alt, caption, icon, hint, href }) => { + icon = icon ? icon : "arrow-turn-down-right"; + return ( + + + {alt} + + + ); +}; + +// +// Livepeer Community GIF +// diff --git a/snippets/components/display/quote.jsx b/snippets/components/display/quote.jsx new file mode 100644 index 000000000..928cf3d9b --- /dev/null +++ b/snippets/components/display/quote.jsx @@ -0,0 +1,14 @@ +export const Quote = ({ children }) => { + const quoteStyle = { + fontSize: "1rem", + textAlign: "center", + opacity: 1, + fontStyle: "italic", + color: "var(--accent)", + border: "1px solid var(--border)", + borderRadius: "8px", + padding: "1rem", + margin: "1rem 0", + }; + return
{children}
; +}; diff --git a/snippets/components/display/video.jsx b/snippets/components/display/video.jsx new file mode 100644 index 000000000..127ea6f47 --- /dev/null +++ b/snippets/components/display/video.jsx @@ -0,0 +1,261 @@ +/** + * YouTubeVideo - Embeds a YouTube video with optional caption and hint + * + * @description + * Displays a YouTube video in a responsive iframe within a Frame component. + * Supports optional hint text and caption with microphone icon. + * + * @param {string} embedUrl - YouTube embed URL (e.g., "https://www.youtube.com/embed/VIDEO_ID") + * @param {string} [title=""] - Video title for accessibility + * @param {string} [hint=""] - Optional hint text to display + * @param {string} [caption] - Optional caption text to display below the video + * + * @example + * + * + * @todo Deconstruct to change icon props. Only render icon if passed in. + * @author Livepeer Documentation Team + */ +export const YouTubeVideo = ({ embedUrl, title = "", hint = "", caption }) => { + return ( + + + {caption} + + ), + } + : {})} + > + + + + + {title} + + + + ); +}; + +// Notes: Fetch video information for youtube videos + +// Yes, **GitHub Actions is viable**. The workflow would: + +// 1. **Trigger on commit/PR** to your code repo +// 2. **Run your script** to fetch YouTube metadata (title, description) +// 3. **Update MDX files** with the fetched data +// 4. **Commit changes** back to the repo (or create a new commit) +// 5. **Mintlify auto-builds** from the updated repo + +// The key is that GitHub Actions can modify files and commit them before Mintlify's build process starts. You'd typically have the action commit directly to the branch or create a new commit that triggers Mintlify's deployment. + +// **Example flow:** +// - Push code → GitHub Action runs → Script fetches YouTube data → Updates MDX → Commits changes → Mintlify detects new commit → Builds docs + +// This is similar to how the [agent automation workflow](https://mintlify.com/docs/guides/automate-agent) works with GitHub Actions. diff --git a/snippets/components/display/zoomable-diagram.jsx b/snippets/components/display/zoomable-diagram.jsx new file mode 100644 index 000000000..f2a98d4fd --- /dev/null +++ b/snippets/components/display/zoomable-diagram.jsx @@ -0,0 +1,150 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * ScrollableDiagram - Interactive diagram viewer with zoom and pan controls + * + * @description + * Displays diagrams or large content with zoom controls (25%-200%) and scrollable pan. + * Includes zoom in/out buttons, reset button, and displays current zoom level. + * + * @param {React.ReactNode} children - Diagram or content to display + * @param {string} [title=""] - Optional title to display above the diagram + * @param {string} [maxHeight="500px"] - Maximum height of the scrollable container + * @param {string} [minWidth="100%"] - Minimum width of the content area + * + * @example + * + * Architecture + * + * + * @author Livepeer Documentation Team + */ +export const ScrollableDiagram = ({ + children, + title = "", + maxHeight = "500px", + minWidth = "100%", +}) => { + const [zoom, setZoom] = useState(100); + + const zoomIn = () => setZoom((z) => Math.min(z + 5, 200)); + const zoomOut = () => setZoom((z) => Math.max(z - 5, 25)); + const resetZoom = () => setZoom(100); + + const containerStyle = { + overflow: "auto", + maxHeight: maxHeight, + border: "1px solid var(--diagram-border)", + borderRadius: "8px", + padding: "1rem", + background: "var(--diagram-bg)", + cursor: "grab", + position: "relative", + }; + + const buttonStyle = { + background: "var(--diagram-button-bg)", + color: "var(--diagram-button-text)", + border: "none", + borderRadius: "4px", + padding: "4px 10px", + cursor: "pointer", + fontSize: "0.75rem", + fontWeight: "600", + }; + + return ( + <> + +
+ {title && ( +

+ {title} +

+ )} +
+
+ {children} +
+
+
+ + Scroll to pan + + + + {zoom}% + + + +
+
+ + ); +}; diff --git a/snippets/components/divider.jsx b/snippets/components/divider.jsx deleted file mode 100644 index f99cbe8ac..000000000 --- a/snippets/components/divider.jsx +++ /dev/null @@ -1,79 +0,0 @@ -const LivepeerIcon = ({ ...props }) => { - return ( - - ); -}; - -const LivepeerIconFlipped = ({ ...props }) => { - return ( - - - - ); -}; - -export const CustomDivider = ({ color, middleText }) => { - const dividerColor = "#e5e7eb"; - - return ( -
- - - -
- {middleText && ( - <> - - - {middleText} - - - - )} -
- - - - - -
- ); -}; diff --git a/snippets/components/domain/04_GATEWAYS/callouts.jsx b/snippets/components/domain/04_GATEWAYS/callouts.jsx new file mode 100644 index 000000000..aaf4d777c --- /dev/null +++ b/snippets/components/domain/04_GATEWAYS/callouts.jsx @@ -0,0 +1,207 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * GatewayOffChainWarning - Warning callout for off-chain Gateway setup + * + * @description + * Displays a warning message informing users they need to run their own Orchestrator + * node to test an off-chain (local) Gateway. Includes links to relevant guides. + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const GatewayOffChainWarning = () => { + return ( + + + You will need to{" "} + + run your own Orchestrator node + {" "} + to test an off-chain (local) Gateway: + +
    +
  • + See{" "} + {" "} + to test a local Gateway without a GPU. +
  • +
  • + See{" "} + {" "} + to setup and run an Orchestrator. +
  • +
+
+ ); +}; + +/** + * GatewayOnChainWarning - Warning callout for on-chain Gateway setup + * + * @description + * Displays a warning message about funding requirements for running an on-chain Gateway. + * Includes a link to the funding guide. + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const GatewayOnChainWarning = () => { + return ( + <> + + + + You will need to{" "} + + fund an Ethereum wallet + {" "} + account on Arbitrum One to run an on-chain Gateway. +

See{" "} + + {" "} + Fund Your Gateway{" "} + +
+
+ + ); +}; + +/** + * GatewayOnChainTTestnetNote - Note about Arbitrum Testnet limitations + * + * @description + * Informs users about the current limitations of using Arbitrum Testnet for Gateways. + * Includes links to community discussions. + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const GatewayOnChainTTestnetNote = () => { + return ( + + While Livepeer contracts are deployed to the Arbitrum Testnet, there is + currently no freely available Orchestrator services on this chain. +
+ + If you would like to use the Aribtum Testnet for your Gateway, you will + need to run your own Orchestrator node. + +
+ There are conversations underway to enable this in the future. Follow & + contribute to the discussion on: + + {" "} + Discord + + + {" "} + Forum + +
+ ); +}; + +/** + * OrchAddrNote - Note about replacing orchestrator address placeholder + * + * @description + * Displays a note reminding users to replace the orchestrator IP:PORT placeholder + * with their actual orchestrator address. + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const OrchAddrNote = () => { + return ( + + Replace {""} with + your locally running orchestrator address
+
+ ); +}; + +/** + * TestVideoDownload - Note about test video file requirement + * + * @description + * Displays a note informing users they need a test video file. + * Accepts children for additional instructions. + * + * @param {React.ReactNode} children - Additional content or instructions + * + * @example + * + * Download a sample video from here + * + * + * @author Livepeer Documentation Team + */ +const TestVideoDownload = ({ children }) => { + return ( + +
+ You need a video file called test-video.mp4 on your + machine!{" "} +
+ {children} +
+ ); +}; + +/** + * FfmpegWarning - Critical warning about FFmpeg installation + * + * @description + * Displays a danger alert warning users not to install FFmpeg with sudo. + * Explains that Livepeer uses a custom FFmpeg build. + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const FfmpegWarning = () => { + return ( + +
+ IMPORTANT! Do not install with sudo!
+ Livepeer uses a custom build of FFmpeg that must be + installed in a specific location. +
+
+ ); +}; + +export { + GatewayOffChainWarning, + GatewayOnChainWarning, + GatewayOnChainTTestnetNote, + OrchAddrNote, + TestVideoDownload, + FfmpegWarning, +}; diff --git a/snippets/components/domain/04_GATEWAYS/quickstartTabs.jsx b/snippets/components/domain/04_GATEWAYS/quickstartTabs.jsx new file mode 100644 index 000000000..7d60f47bf --- /dev/null +++ b/snippets/components/domain/04_GATEWAYS/quickstartTabs.jsx @@ -0,0 +1,123 @@ +/** + * Gateway Quickstart Components + * + * @description + * Components for displaying Gateway setup instructions with tabs for off-chain and on-chain options. + * + * @note Data must be imported in the page where these components are used. + * Example imports: + * import { + * dockerOffChainQuickstart, + * dockerOnChainQuickstart, + * linuxOffChainQuickstart, + * linuxOnChainQuickstart, + * windowsOffChainQuickstart, + * windowsOnChainQuickstart, + * } from "/snippets/data/gateways.jsx"; + * + * @author Livepeer Documentation Team + */ + +import { + GatewayOffChainWarning, + GatewayOnChainWarning, +} from "/snippets/components/domain/04_GATEWAYS/callouts.jsx"; + +/** + * QuickStartTabs - Tabbed interface for Gateway quickstart guides + * + * @description + * Displays two tabs: one for off-chain Gateway setup and one for on-chain Gateway setup. + * Each tab includes the appropriate warning callout followed by setup steps. + * + * @param {React.ReactNode} offchainSteps - Content for the off-chain Gateway tab + * @param {React.ReactNode} onchainSteps - Content for the on-chain Gateway tab + * + * @example + * } + * onchainSteps={} + * /> + * + * @author Livepeer Documentation Team + */ +export const QuickStartTabs = ({ offchainSteps, onchainSteps }) => { + return ( + + + + {offchainSteps} + + + + {onchainSteps} + + + ); +}; + +/** + * QuickStartSteps - Standardized steps for Gateway setup + * + * @description + * Displays a consistent 5-step process for Gateway setup: Install, Configure, Run, Connect, Test. + * Accepts a data source object with content for each step. + * + * @note This component inherits imports from the page it's called in, but will not use + * imports from this file (Mintlify limitation). + * + * @param {Object} dataSource - Object containing step content + * @param {React.ReactNode} dataSource.installStep - Content for installation step + * @param {React.ReactNode} dataSource.configureStep - Content for configuration step + * @param {React.ReactNode} dataSource.runStep - Content for running the Gateway + * @param {React.ReactNode} dataSource.connectStep - Content for connecting to the Gateway + * @param {React.ReactNode} dataSource.testStep - Content for testing the Gateway + * + * @example + * const quickstartData = { + * installStep:

Install instructions...

, + * configureStep:

Configuration steps...

, + * runStep:

How to run...

, + * connectStep:

Connection details...

, + * testStep:

Testing procedures...

+ * }; + * + * + * @author Livepeer Documentation Team + */ +export const QuickStartSteps = ({ dataSource }) => { + // console.log("dataSource", dataSource); + // console.log("dockerOffChainQuickstart", dockerOffChainQuickstart); + const { installStep, configureStep, runStep, connectStep, testStep } = + dataSource; + // console.log("steps obj", installStep); + return ( + + {installStep} + {configureStep} + {runStep} + {connectStep} + {testStep} + + ); +}; + +/* + export const QuickstartSteps = ( + installStep, + configureStep, + runStep, + connectStep, + testStep + ) => { + return ( + + {installStep} + {configureStep} + {runStep} + {connectStep} + {testStep} + + ); + }; +*/ diff --git a/snippets/components/domain/SHARED/HeroGif.jsx b/snippets/components/domain/SHARED/HeroGif.jsx new file mode 100644 index 000000000..0116117ca --- /dev/null +++ b/snippets/components/domain/SHARED/HeroGif.jsx @@ -0,0 +1,279 @@ +// SVG needs fixing... +// export const Starfield1 = () => { +// const canvasRef = useRef(null); + +// // === LIVEPEER LOGO SVG (INLINE) === +// const LIVEPEER_SVG = ` +// +// +// +// `; + +// const COLORS = ["#3CB540", "#2b9a66", "#18794E", "#6BBF59"]; + +// const SIZE_BUCKETS = [ +// { scale: 0.25, weight: 0.65 }, +// { scale: 0.45, weight: 0.2 }, +// { scale: 0.8, weight: 0.1 }, +// { scale: 1.2, weight: 0.04 }, +// { scale: 1.6, weight: 0.01 }, +// ]; + +// const pickScale = () => { +// const r = Math.random(); +// let acc = 0; +// for (const b of SIZE_BUCKETS) { +// acc += b.weight; +// if (r <= acc) return b.scale; +// } +// return 0.25; +// }; + +// const makeLogoImage = (color) => { +// const svg = LIVEPEER_SVG.replace("COLOR_REPLACE", color); +// const img = new Image(); +// img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg); +// return img; +// }; + +// useEffect(() => { +// const canvas = canvasRef.current; +// if (!canvas) return; + +// const ctx = canvas.getContext("2d"); +// let rafId; +// let stars = []; + +// const logoImages = COLORS.map(makeLogoImage); + +// const resize = () => { +// const dpr = window.devicePixelRatio || 1; +// const rect = canvas.getBoundingClientRect(); + +// canvas.width = rect.width * dpr; +// canvas.height = rect.height * dpr; +// ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + +// const count = Math.floor((rect.width * rect.height) / 16000); + +// stars = Array.from({ length: count }).map(() => ({ +// x: Math.random() * rect.width, +// y: Math.random() * rect.height, +// scale: pickScale(), +// base: Math.random() * 0.45 + 0.25, +// speed: Math.random() * 0.015 + 0.003, +// phase: Math.random() * Math.PI * 2, +// img: logoImages[Math.floor(Math.random() * logoImages.length)], +// })); +// }; + +// const draw = () => { +// ctx.clearRect(0, 0, canvas.width, canvas.height); + +// for (const s of stars) { +// s.phase += s.speed; +// s.rotation += s.rotSpeed; + +// const alpha = s.base + Math.sin(s.phase) * 0.25; +// const size = 10 * s.scale; + +// ctx.globalAlpha = Math.max(0, Math.min(1, alpha)); + +// const tinted = makeTinted(s.color); + +// ctx.save(); +// ctx.translate(s.x, s.y); +// ctx.rotate(s.rotation); +// ctx.drawImage(tinted, -size / 2, -size / 2, size, size); +// ctx.restore(); +// } + +// rafId = requestAnimationFrame(draw); +// }; + +// resize(); +// draw(); +// window.addEventListener("resize", resize); + +// return () => { +// cancelAnimationFrame(rafId); +// window.removeEventListener("resize", resize); +// }; +// }, []); + +// return ( +// +// ); +// }; + +export const Starfield = ({ density = 1.1 }) => { + const canvasRef = useRef(null); + + // Detect theme mode + const isDarkMode = () => { + if (typeof window === "undefined") return false; + return ( + document.documentElement.classList.contains("dark") || + window.matchMedia("(prefers-color-scheme: dark)").matches + ); + }; + + // Theme-aware color palettes - leaning toward primary green for each mode + const COLORS_LIGHT = [ + "#5DD662", // Brighter primary green (more weight) + "#5DD662", // Brighter primary green (duplicate for higher probability) + "#7FE584", // Very bright green + "#A0F0A5", // Lightest bright accent + ]; + + const COLORS_DARK = [ + "#2b9a66", // Primary dark green (more weight) + "#2b9a66", // Primary dark green (duplicate for higher probability) + "#18794E", // Darker shade + "#3CB540", // Light green accent + ]; + + const SIZE_BUCKETS = [ + { scale: 0.3, weight: 0.65 }, + { scale: 0.5, weight: 0.2 }, + { scale: 0.9, weight: 0.1 }, + { scale: 1.3, weight: 0.04 }, + { scale: 1.8, weight: 0.01 }, + ]; + + const pickScale = () => { + const r = Math.random(); + let acc = 0; + for (const b of SIZE_BUCKETS) { + acc += b.weight; + if (r <= acc) return b.scale; + } + return 0.25; + }; + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; + const ctx = canvas.getContext("2d"); + + let rafId; + let stars = []; + let tintedCache = new Map(); // key: color -> tinted ImageBitmap|canvas + + // Select color palette based on theme + const COLORS = isDarkMode() ? COLORS_DARK : COLORS_LIGHT; + + // IMPORTANT: try no leading slash first in Mintlify + const logo = new Image(); + logo.src = "/snippets/assets/logos/Livepeer-Logo-Symbol-Light.svg"; + + const makeTinted = (color) => { + if (tintedCache.has(color)) return tintedCache.get(color); + + const off = document.createElement("canvas"); + const octx = off.getContext("2d"); + + const base = 32; // base logo render size in px (scaled per star) + off.width = base; + off.height = base; + + // draw the white SVG + octx.clearRect(0, 0, base, base); + octx.drawImage(logo, 0, 0, base, base); + + // tint it: keep alpha/shape from SVG, fill with color + octx.globalCompositeOperation = "source-in"; + octx.fillStyle = color; + octx.fillRect(0, 0, base, base); + octx.globalCompositeOperation = "source-over"; + + tintedCache.set(color, off); + return off; + }; + + const resize = () => { + const dpr = window.devicePixelRatio || 1; + const rect = canvas.getBoundingClientRect(); + canvas.width = rect.width * dpr; + canvas.height = rect.height * dpr; + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + + const count = Math.floor(((rect.width * rect.height) / 16000) * density); + stars = Array.from({ length: count }).map(() => { + const color = COLORS[Math.floor(Math.random() * COLORS.length)]; + return { + x: Math.random() * rect.width, + y: Math.random() * rect.height, + scale: pickScale(), + base: Math.random() * 0.45 + 0.25, + speed: Math.random() * 0.015 + 0.003, + phase: Math.random() * Math.PI * 2, + color, + rotation: Math.random() * Math.PI * 2, // fixed random angle + rotSpeed: Math.random() * 0.002 - 0.001, // very subtle drift + }; + }); + }; + + const draw = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + for (const s of stars) { + s.phase += s.speed; + s.rotation += s.rotSpeed; + + const alpha = s.base + Math.sin(s.phase) * 0.25; + const size = 10 * s.scale; + + ctx.globalAlpha = Math.max(0, Math.min(1, alpha)); + + const tinted = makeTinted(s.color); + + ctx.save(); + ctx.translate(s.x, s.y); + ctx.rotate(s.rotation); + ctx.drawImage(tinted, -size / 2, -size / 2, size, size); + ctx.restore(); + } + + rafId = requestAnimationFrame(draw); + }; + + logo.onload = () => { + resize(); + draw(); + window.addEventListener("resize", resize); + }; + + return () => { + cancelAnimationFrame(rafId); + window.removeEventListener("resize", resize); + }; + }, []); + + return ( + + ); +}; diff --git a/snippets/components/domain/SHARED/Portals.jsx b/snippets/components/domain/SHARED/Portals.jsx new file mode 100644 index 000000000..9020483c8 --- /dev/null +++ b/snippets/components/domain/SHARED/Portals.jsx @@ -0,0 +1,447 @@ +/* + * Portal Components + * + * @description + * These Components are used on the Portal pages. + * Portal pages use mode: frame which is not correctly supported by Mintlify + * They do this to remove the frontmatter metadata from the page in order to customise the layout. + * mode: frame also strips all styling except for Mintlify components. + * Use display/frameMode.jsx components for headings in frame mode pages. + * + * @imports: REQUIRED - These components require imports on the MDX page to function. + * + * MUST import ThemeData in the MDX file: + * import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + * + * PortalHeroContent uses CustomDivider which needs to be imported on the MDX page: + * import { CustomDivider } from "/snippets/components/primitives/divider.jsx"; + * + * If not imported, components will not render correctly. + * + * @author Alison Haire + */ + +/* + * Background Image Container + * + * @description + * A container component for adding a background image to a portal page hero section. + * It uses className="frame-mode-hero-full" to fill the full width of the page. + * The image sits behind the hero header. + * + * @param {React.ReactNode} children: + * Should be: + * + * + * + * + * @author Alison Haire + */ +const HeroSectionContainer = ({ children, minHeight = "fit-content" }) => { + return ( +
+ {children} + {/* */} + {/* */} +
+ ); +}; + +/* + * Hero Image Background Component + * + * @description + * A container component for the background of a portal page hero section. + * The background sits behind the hero header. + * The background is fixed and will not scroll with the page. + * Currently a gif is generated looking like a starfield using HeroGif.jsx + * This component should sit in a className="frame-mode-hero-full" element. + * + * @param {React.ReactNode} children: + * The background image component. Defaults to + * is created in components/domain/SHARED/HeroGif.jsx + * + * @author Alison Haire + */ +const HeroImageBackgroundComponent = ({ children }) => { + return ( +
+ {children} + {/* */} +
+ ); +}; + +/* + * Hero Container + * + * @description + * A container component for the hero content of a portal page. + * Uses className="frame-mode-container" for centering and margins. + * The content is centered & has margins and gap set. + * + * @param {React.ReactNode} children: + * The content of the hero section. + * Should be: + * + * + * + * @author Alison Haire + */ +const HeroContentContainer = ({ children }) => { + return ( +
+
{children}
+
+ ); +}; + +//unused +const HeroOverviewContent = ({ children }) => { + return ( +
+ {children} +
+ +
+
+ ); +}; + +/* + * Portal Content Container + * + * @description + * A container component for the portal page content. + * Provides margins and centering for the page content. + * + * @param {React.ReactNode} children: + * The content of the page. + * + * @author Alison Haire + */ +const PortalContentContainer = ({ children }) => { + return ( +
+
+ {children} +
+
+ ); +}; + +/* + * Portal Hero Content Component + * + * @description + * A custom header component for portal pages that supports theming and optional + * subheadings/descriptions. + * Wraps the content in a z-index container to sit on top of the + * background image by default - can be toggled off with zIndex=false + * + * @param {string} title: The title of the hero section. + * @param {string} subtitle: The subtitle of the hero section. + * @param {string} description: The description of the hero section. + * @param {React.ReactNode} children: Any additional content to include in the hero section. + * @param {string} titleColor: The color of the title text. + * @param {string} subtitleColor: The color of the subtitle text. + * @param {string} descriptionColor: The color of the description text. + * + * @author Alison Haire + */ +const PortalHeroContent = ({ + zIndex = true, //Not working currently + title = "Portal Page", + subtitle = "Build - Explore - Create", + subtitleIcon = "/snippets/assets/logos/Livepeer-Logo-Symbol-Green-Theme.svg", + description, + refCardLink, + overview, + divider = true, + callout=null, + titleColor, + subtitleColor, + children, +}) => { + return ( + // zIndex && +
+
+

+ {title} +

+ {subtitle && ( + // wrapper for icons +
+ {subtitleIcon && ( + + + + )} +

+ {subtitle} {/* flipped icon */} + {subtitleIcon && ( + + + + )} +

+
+ )} + {description && ( +
+ {description} +
+ )} + {refCardLink && ( +
+ {refCardLink} +
+ )} + +
+ {callout && callout} + {divider ? : null } + {/* */} +
+ {overview && ( +
+ {overview} +
+ )} +
+ {children ? <>{children} : } +
+
+ {/* zIndex && */} +
+ ); +}; + +const PortalCardsHeader = ({ children, title }) => { + return ( +
+

+ {title} +

+ +
+ + Choose Your Mission: + + {children} +
+
+ ); +}; + +const PortalSectionHeader = ({ children, title, icon }) => { + return ( +
+

+ {title} +

+ {children} +
+ ); +}; + +/* + * Logo Hero Container Component + * + * @description + * A component for displaying a logo in the hero section of a portal page. + * Has: + * - A wrapper container for centering & constraining the image size + * - A Centered Image with objectFit: "contain" to resize the logo. + * + * @param {string} src: The source of the logo image. Defaults to theme mode aware Livepeer Logo in "/snippets/assets/logos/Livepeer-Logo-Full-Theme.svg" + * @param {string} alt: The alt text for the logo image. Defaults to "Livepeer Logo" + * @param {string} height: The height of the logo image. Defaults to "100px". + * @param {string} width: The width of the logo image. Defaults to "100%". + * @param {string} margin: The margin around the logo image. Defaults to "2rem auto". + * @param {string} imgHeight: The height of the logo image. Defaults to "100%". + * @param {string} imgWidth: The width of the logo image. Defaults to "auto". + * @param {string} objectFit: The object-fit property of the logo image. Defaults to "contain". + * + * @author Alison Haire + */ +const LogoHeroContainer = ({ + src = "/snippets/assets/logos/Livepeer-Logo-Full-Theme.svg", + alt = "Livepeer Logo", + width = "100%", + margin = "1rem auto 0 auto", + imgHeight = "20px", + imgWidth = "auto", + objectFit = "contain", + children, +}) => { + return ( +
+
+ {alt} + {children && +
+ {children} +
+ } +
+
+ ); +}; + +const RefCardContainer = ({ children }) => { + return ( +
+ {children} +
+ ); +}; + +export { + HeroImageBackgroundComponent, + HeroContentContainer, + PortalContentContainer, + PortalHeroContent, + LogoHeroContainer, + HeroOverviewContent, + HeroSectionContainer, + PortalCardsHeader, + PortalSectionHeader +}; diff --git a/snippets/components/domain/SHARED/previewCallouts.jsx b/snippets/components/domain/SHARED/previewCallouts.jsx new file mode 100644 index 000000000..bd10f445f --- /dev/null +++ b/snippets/components/domain/SHARED/previewCallouts.jsx @@ -0,0 +1,147 @@ +// Callouts while still under construction + +const ComingSoonCallout = ({ type = "page" }) => { + const rowStyle = { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + gap: "1rem", + }; + const colStyle = { + display: "flex", + flexDirection: "column", + gap: "0.5rem", + fontSize: "1.0rem", + flex: 1, + alignItems: "center", + }; + const linkStyle = { + color: "var(--hero-text) !important", + display: "inline-flex", + alignItems: "center", + gap: "4px", + paddingTop: "0.2rem", + }; + const titleStyle = { + fontSize: "1.2rem", + fontWeight: "bold", + fontStyle: "italic", + color: "#ef1a73", + }; + + return ( + +
+
+ +
+
+ + {type === "page" + ? "This page is still cooking... Expect big things soon!" + : "This Tab Group is still cooking... Expect big things soon!"} + +
+ + Check the{" "} + + github issues + + {" "} + for ways to contribute!{" "} + + + Or provide your feedback in this{" "} + + + quick form + + + +
+
+ +
+
+
+ ); +}; + +const PreviewCallout = () => { + const rowStyle = { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + gap: "1rem", + }; + const colStyle = { + display: "flex", + flexDirection: "column", + alignItems: "center", + gap: "0.5rem", + fontSize: "1.0rem", + flex: 1, + }; + const linkStyle = { + color: "var(--hero-text) !important", + display: "inline-flex", + alignItems: "center", + gap: "4px", + paddingTop: "0.2rem", + }; + const titleStyle = { + fontSize: "1.2rem", + fontWeight: "bold", + fontStyle: "italic", + color: "#b636dd", + }; + return ( + +
+
+ +
+
+ + Page is under construction.
+
+
+ + Check the{" "} + + github issues + + {" "} + for ways to contribute!{" "} + + + Or provide your feedback in this{" "} + + + quick form + + + +
+
+ +
+
+
+ ); +}; + +const ReviewCallout = () => { + return ( + +
+ Technical Review Needed!
+ Get in touch if you can help +
+
+ ); +}; + +export { ComingSoonCallout, PreviewCallout, ReviewCallout }; diff --git a/snippets/components/embed.jsx b/snippets/components/embed.jsx deleted file mode 100644 index 228c49ce3..000000000 --- a/snippets/components/embed.jsx +++ /dev/null @@ -1,23 +0,0 @@ -export const MarkdownEmbed = ({ url }) => { - const [content, setContent] = useState(""); - - useEffect(() => { - fetch(url) - .then((res) => res.text()) - .then(setContent); - }, [url]); - - return {content}; -}; - -export const EmbedMarkdown = ({ url }) => { - const [content, setContent] = useState(""); - - useEffect(() => { - fetch(url) - .then((res) => res.text()) - .then(setContent); - }, [url]); - - return {content}; -}; diff --git a/snippets/components/embed.mdx b/snippets/components/embed.mdx deleted file mode 100644 index d6b6eb76b..000000000 --- a/snippets/components/embed.mdx +++ /dev/null @@ -1,53 +0,0 @@ -export const ExternalEmbed = ({ - children, - repoName, - repoUrl, - maxHeight = "1000px", -}) => ( -
-
- - - {repoName} - - - View on GitHub - -
-
- {children} -
-
-); diff --git a/snippets/components/external-content.jsx b/snippets/components/external-content.jsx deleted file mode 100644 index e0f3cadfc..000000000 --- a/snippets/components/external-content.jsx +++ /dev/null @@ -1,69 +0,0 @@ -/** - * ExternalContent - A reusable component for displaying external GitHub content - * Usage: - * import { ExternalContent } from '/snippets/components/external-content.jsx' - * import MyContent from '/snippets/external/my-content.mdx' - * - * - * - */ - -export const ExternalContent = ({ - repoName, - githubUrl, - maxHeight = "1000px", - icon = "github", - children, -}) => { - return ( -
-
- - - {repoName} - - - View on GitHub - -
-
- {children} -
-
- ); -}; diff --git a/snippets/components/gateways/callouts.jsx b/snippets/components/gateways/callouts.jsx deleted file mode 100644 index 7447cf8de..000000000 --- a/snippets/components/gateways/callouts.jsx +++ /dev/null @@ -1,105 +0,0 @@ -const GatewayOffChainWarning = () => { - return ( - - - You will need to{" "} - - run your own Orchestrator node - {" "} - to test an off-chain Gateway: - -
    -
  • - See{" "} - {" "} - to test a local Gateway without a GPU. -
  • -
  • - See{" "} - {" "} - to setup and run an Orchestrator. -
  • -
-
- ); -}; - -const GatewayOnChainWarning = () => { - return ( - - - You will need to{" "} - - fund an Ethereum wallet - {" "} - account on Arbitrum One to run an on-chain Gateway. -

See{" "} - - Fund Your Gateway{" "} - -
-
- ); -}; - -const GatewayOnChainTTestnetNote = () => { - return ( - - While Livepeer contracts are deployed to the Arbitrum Testnet, there is - currently no freely available Orchestrator services on this chain. -
- - If you would like to use the Aribtum Testnet for your Gateway, you will - need to run your own Orchestrator node. - -
- There are conversations underway to enable this in the future. Follow & - contribute to the discussion on: - - {" "} - Discord - - - {" "} - Forum - -
- ); -}; - -const OrchAddrNote = () => { - return ( - - Replace {""} with - your locally running orchestrator address
-
- ); -}; - -const TestVideoDownload = ({ children }) => { - return ( - -
- You need a video file called test-video.mp4 on your - machine!{" "} -
- {children} -
- ); -}; - -export { - GatewayOffChainWarning, - GatewayOnChainWarning, - GatewayOnChainTTestnetNote, - OrchAddrNote, - TestVideoDownload, -}; diff --git a/snippets/components/gateways/quickstartTabs.jsx b/snippets/components/gateways/quickstartTabs.jsx deleted file mode 100644 index a5e75af3c..000000000 --- a/snippets/components/gateways/quickstartTabs.jsx +++ /dev/null @@ -1,64 +0,0 @@ -// THIS MUST BE IMPORTED IN THE PAGE YOU USE IT IN -// ALT: THE DATA MUST BE IN THE SAME PAGE. -// import { -// dockerOffChainQuickstart, -// dockerOnChainQuickstart, -// linuxOffChainQuickstart, -// linuxOnChainQuickstart, -// windowsOffChainQuickstart, -// windowsOnChainQuickstart, -// } from "/snippets/data/gateways.jsx"; - -export const QuickStartTabs = ({ offchainSteps, onchainSteps }) => { - return ( - - - - {offchainSteps} - - - - {onchainSteps} - - - ); -}; - -// THIS INHERITS IMPORTS FROM THE PAGE ITS CALLED IN. -// BUT WILL NOT USE IMPORTS FROM THIS PAGE (WTF MINTLIFY) -export const QuickStartSteps = ({ dataSource }) => { - // console.log("dataSource", dataSource); - // console.log("dockerOffChainQuickstart", dockerOffChainQuickstart); - const { installStep, configureStep, runStep, connectStep, testStep } = - dataSource; - // console.log("steps obj", installStep); - return ( - - {installStep} - {configureStep} - {runStep} - {connectStep} - {testStep} - - ); -}; - -/* - export const QuickstartSteps = ( - installStep, - configureStep, - runStep, - connectStep, - testStep - ) => { - return ( - - {installStep} - {configureStep} - {runStep} - {connectStep} - {testStep} - - ); - }; -*/ diff --git a/snippets/components/icons.jsx b/snippets/components/icons.jsx deleted file mode 100644 index 3d0b97fc5..000000000 --- a/snippets/components/icons.jsx +++ /dev/null @@ -1,32 +0,0 @@ -export const LivepeerSVG = ({ size = 24, ...props }) => { - return ( - - - - ); -}; - -export const LivepeerIcon = ({ ...props }) => { - return ( - - ); -}; - -export const LivepeerIconFlipped = ({ ...props }) => { - return ( - - - - ); -}; diff --git a/snippets/components/image.jsx b/snippets/components/image.jsx deleted file mode 100644 index ef7e5689f..000000000 --- a/snippets/components/image.jsx +++ /dev/null @@ -1,30 +0,0 @@ -export const Image = ({ src, alt, caption, icon, hint, fullwidth = true }) => { - icon = icon ? icon : "arrow-turn-down-right"; - return ( - - {alt} - - ); -}; - -export const LinkImage = ({ src, alt, caption, icon, hint, href }) => { - icon = icon ? icon : "arrow-turn-down-right"; - return ( - - - {alt} - - - ); -}; - -// -// Livepeer Community GIF -// diff --git a/snippets/components/image.tsx b/snippets/components/image.tsx deleted file mode 100644 index a593e98c6..000000000 --- a/snippets/components/image.tsx +++ /dev/null @@ -1,31 +0,0 @@ -export type imageProps = Record; -export const Image = ({ src, alt, caption, icon, hint, fullwidth = true }) => { - icon = icon ? icon : "arrow-turn-down-right"; - return ( - - {alt} - - ); -}; - -export const LinkImage = ({ src, alt, caption, icon, hint, href }) => { - icon = icon ? icon : "arrow-turn-down-right"; - return ( - - - {alt} - - - ); -}; - -// -// Livepeer Community GIF -// diff --git a/snippets/components/index.jsx b/snippets/components/index.jsx deleted file mode 100644 index 61024a713..000000000 --- a/snippets/components/index.jsx +++ /dev/null @@ -1,4 +0,0 @@ -export { - GatewayOffChainWarning, - GatewayOnChainWarning, -} from "./gateways/warnings.jsx"; diff --git a/snippets/components/integrations/coingecko.jsx b/snippets/components/integrations/coingecko.jsx new file mode 100644 index 000000000..c25b98d73 --- /dev/null +++ b/snippets/components/integrations/coingecko.jsx @@ -0,0 +1,286 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * CoinGeckoExchanges - Dynamically fetches and displays exchanges that support a coin from CoinGecko + * + * Props: + * - coinId: The CoinGecko coin ID (e.g., "arbitrum", "ethereum", "bitcoin") + */ +export const CoinGeckoExchanges = ({ coinId = "arbitrum" }) => { + const [exchanges, setExchanges] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [sortBy, setSortBy] = useState(null); // null (default order), "name", or "type" + const [sortOrder, setSortOrder] = useState("asc"); // "asc" or "desc" + + useEffect(() => { + const fetchExchanges = async () => { + try { + // Fetch first page of tickers from CoinGecko API + const response = await fetch( + `https://api.coingecko.com/api/v3/coins/${coinId}/tickers?depth=true`, + ); + + if (response.ok) { + const data = await response.json(); + + // Extract unique exchanges from tickers, preserving API order + const exchangeMap = new Map(); + + data.tickers?.forEach((ticker) => { + if (ticker.market?.name && ticker.trade_url) { + // Only add if not already in map (preserves first occurrence) + if (!exchangeMap.has(ticker.market.name)) { + exchangeMap.set(ticker.market.name, { + name: ticker.market.name, + url: ticker.trade_url, + trustScore: ticker.trust_score || "N/A", + tradingPair: + ticker.base && ticker.target + ? `${ticker.base}/${ticker.target}` + : "N/A", + type: + ticker.market.identifier?.includes("uniswap") || + ticker.market.identifier?.includes("sushiswap") || + ticker.market.identifier?.includes("pancakeswap") || + ticker.market.name?.toLowerCase().includes("swap") || + ticker.market.name?.toLowerCase().includes("dex") + ? "DEX" + : "CEX", + }); + } + } + }); + + // Convert to array, preserving the order from the API + const exchangeList = Array.from(exchangeMap.values()); + + setExchanges(exchangeList); + } else { + throw new Error("Failed to fetch exchange data"); + } + } catch (err) { + setError("Failed to load exchange data"); + console.error("CoinGeckoExchanges error:", err); + } finally { + setLoading(false); + } + }; + + fetchExchanges(); + }, [coinId]); + + if (loading) { + return
Loading exchanges...
; + } + + if (error) { + return
Error: {error}
; + } + + if (exchanges.length === 0) { + return
No exchanges found for this coin.
; + } + + // Sort exchanges based on current sort settings + const sortedExchanges = sortBy + ? [...exchanges].sort((a, b) => { + let comparison = 0; + + if (sortBy === "type") { + comparison = a.type.localeCompare(b.type); + } else if (sortBy === "name") { + comparison = a.name.localeCompare(b.name); + } + + return sortOrder === "asc" ? comparison : -comparison; + }) + : exchanges; // If no sort selected, use original API order + + const handleSort = (column) => { + if (sortBy === column) { + // Toggle sort order if clicking the same column + setSortOrder(sortOrder === "asc" ? "desc" : "asc"); + } else { + // Set new column and default to ascending + setSortBy(column); + setSortOrder("asc"); + } + }; + + // Convert trust score to color + const getTrustScoreColor = (trustScore) => { + if (trustScore === "N/A" || trustScore === "yellow") return "#fbbf24"; // yellow + if (trustScore === "green") return "#22c55e"; // green + if (trustScore === "red") return "#ef4444"; // red + return "#fbbf24"; // default yellow + }; + + return ( + <> + +
+ + + + + + + + + + + + {sortedExchanges.map((exchange, index) => ( + + + + + + + + ))} + +
handleSort("name")} + title="Click to sort by name" + > + Exchange{" "} + {sortBy === "name" && (sortOrder === "asc" ? "↑" : "↓")} + handleSort("type")} + title="Click to sort by type" + > + Type {sortBy === "type" && (sortOrder === "asc" ? "↑" : "↓")} + + Pair + + Trust + + Link +
+ {exchange.name} + + + {exchange.type} + + + {exchange.tradingPair} + + + + + Trade → + +
+
+ + ); +}; diff --git a/snippets/components/layout/ListSteps.jsx b/snippets/components/layout/ListSteps.jsx new file mode 100644 index 000000000..ff824122a --- /dev/null +++ b/snippets/components/layout/ListSteps.jsx @@ -0,0 +1,33 @@ +/** + * ListSteps - Renders a list of items as Steps components + * + * @description + * This component takes an array of step items and renders them using the Steps/Step components. + * Each item in the array is rendered as a Step with its own title, icon, and content. + * + * @param {Array} listItems - Array of objects with Step props and children + * @param {string} listItems[].title - The title of the step + * @param {string} [listItems[].icon] - Optional icon for the step + * @param {React.ReactNode} listItems[].children - Content to display in the step + * @param {Object} stepsConfig - Configuration object with Steps component props + * + * @example + * const items = [ + * { title: "First Step", icon: "check", children:

Step content

}, + * { title: "Second Step", icon: "arrow-right", children:

More content

} + * ]; + * + * + * @author Livepeer Documentation Team + */ +export const ListSteps = (listItems, stepsConfig) => { + return ( + + {listItems.map(({ title, icon, children, ...props }, idx) => ( + + {children} + + ))} + + ); +}; diff --git a/snippets/components/layout/README.md b/snippets/components/layout/README.md new file mode 100644 index 000000000..232853869 --- /dev/null +++ b/snippets/components/layout/README.md @@ -0,0 +1,10 @@ +Layout components are used to structure the UI. They are not interactive and +should not contain any business logic. They are also the second most reusable +components after primitives. + +Index of Layout Components + +- Container +- Grid +- Stack +- Spacer diff --git a/snippets/api-base-urls-table.mdx b/snippets/components/layout/api-base-urls-table.mdx similarity index 90% rename from snippets/api-base-urls-table.mdx rename to snippets/components/layout/api-base-urls-table.mdx index ad68492e3..e58b72731 100644 --- a/snippets/api-base-urls-table.mdx +++ b/snippets/components/layout/api-base-urls-table.mdx @@ -1,5 +1,6 @@ -{/_ API Base URLs Table Snippet Usage: Include this in API landing pages for -styled base URL tables Pass props: urls (array of {name, url} objects) _/} +{/* API Base URLs Table Snippet + Usage: Include this in API landing pages for styled base URL tables + Pass props: urls (array of {name, url} objects) */} export const ApiBaseUrlsTable = ({ urls }) => (
diff --git a/snippets/components/cards.jsx b/snippets/components/layout/cards.jsx similarity index 60% rename from snippets/components/cards.jsx rename to snippets/components/layout/cards.jsx index d77f9acd3..05429f7a6 100644 --- a/snippets/components/cards.jsx +++ b/snippets/components/layout/cards.jsx @@ -1,5 +1,33 @@ -// card layouts - +/** + * PostCard - A card component for displaying forum posts or articles + * + * @description + * Displays a post with title, content, author, date, and optional metadata. + * Includes automatic scroll detection and hints for long content. + * + * @param {string} title - The title of the post + * @param {string} content - HTML content to display (rendered with dangerouslySetInnerHTML) + * @param {string} href - Link URL for the card + * @param {string} [author="Unknown"] - Author name + * @param {string} [datePosted=null] - Date the post was published + * @param {number} [replyCount=null] - Number of replies (currently unused) + * @param {string} [icon="book-open"] - Icon to display on the card + * @param {string} [authorIcon="user-pen"] - Icon for the author section + * @param {string} [dateIcon="calendar"] - Icon for the date section + * @param {string} [cta="Read More"] - Call-to-action button text + * @param {string} [img=null] - Optional image URL for the card + * + * @example + * + * + * @author Livepeer Documentation Team + */ export const PostCard = ({ title, content, @@ -105,6 +133,25 @@ export const PostCard = ({ ); }; +/** + * CardColumnsPostLayout - Layout component for displaying multiple PostCards in columns + * + * @description + * Renders an array of post items in a multi-column layout using the Columns component. + * Each item is rendered as a PostCard. + * + * @param {number} [cols=2] - Number of columns to display + * @param {Array} [items=[]] - Array of PostCard props objects + * + * @example + * const posts = [ + * { title: "Post 1", content: "...", href: "/post-1" }, + * { title: "Post 2", content: "...", href: "/post-2" } + * ]; + * + * + * @author Livepeer Documentation Team + */ export const CardColumnsPostLayout = ({ cols = 2, items = [] }) => { console.log("items", items); return ( @@ -116,6 +163,37 @@ export const CardColumnsPostLayout = ({ cols = 2, items = [] }) => { ); }; +/** + * BlogCard - A card component specifically designed for blog posts + * + * @description + * Similar to PostCard but optimized for blog content with reading time and excerpt support. + * Includes automatic scroll detection for long content. + * + * @param {string} title - The title of the blog post + * @param {string} content - HTML content to display + * @param {string} href - Link URL for the blog post + * @param {string} [author="Livepeer Team"] - Author name + * @param {string} [datePosted=null] - Publication date + * @param {string} [excerpt=null] - Short excerpt (use if linking to external blog) + * @param {number} [readingTime=null] - Estimated reading time in minutes + * @param {string} [icon="book-open"] - Icon for the card + * @param {string} [authorIcon="user-pen"] - Icon for author section (currently commented out) + * @param {string} [dateIcon="calendar"] - Icon for date section + * @param {string} [cta="Read More"] - Call-to-action button text + * @param {string} [img=null] - Optional image URL + * + * @example + * + * + * @author Livepeer Documentation Team + */ export const BlogCard = ({ title, content, @@ -222,6 +300,23 @@ export const BlogCard = ({ ); }; +/** + * CardBlogDataLayout - Layout component for displaying multiple BlogCards + * + * @description + * Renders an array of blog items as BlogCard components in a vertical layout. + * + * @param {Array} [items=[]] - Array of BlogCard props objects + * + * @example + * const blogPosts = [ + * { title: "Blog 1", content: "...", href: "/blog/post-1", readingTime: 5 }, + * { title: "Blog 2", content: "...", href: "/blog/post-2", readingTime: 3 } + * ]; + * + * + * @author Livepeer Documentation Team + */ export const CardBlogDataLayout = ({ items = [] }) => { console.log("items", items); return ( diff --git a/snippets/components/README-custom-view.md b/snippets/components/layout/examples/README-custom-view.md similarity index 100% rename from snippets/components/README-custom-view.md rename to snippets/components/layout/examples/README-custom-view.md diff --git a/snippets/components/layout/examples/cards-examples.mdx b/snippets/components/layout/examples/cards-examples.mdx new file mode 100644 index 000000000..822b24ad3 --- /dev/null +++ b/snippets/components/layout/examples/cards-examples.mdx @@ -0,0 +1,228 @@ +--- +title: "Card Components Examples" +description: "Examples of using PostCard, BlogCard, and card layout components" +--- + +import { PostCard, CardColumnsPostLayout, BlogCard, CardBlogDataLayout } from "/snippets/components/layout/cards.jsx"; + +## PostCard Component + +### Basic Usage + + + +### With Custom Icons + + + +### With Long Content (Scrollable) + + + +### With Custom CTA + + + +### With Image + + + +## CardColumnsPostLayout + +### Two Column Layout + +Start your journey with Livepeer basics.

", + href: "/intro", + author: "Alice Johnson", + datePosted: "2024-01-10" + }, + { + title: "Advanced Features", + content: "

Explore advanced Livepeer capabilities.

", + href: "/advanced", + author: "Bob Williams", + datePosted: "2024-01-12" + } + ]} +/> + +### Three Column Layout + +Get up and running in 5 minutes.

", + href: "/quickstart", + author: "Dev Team", + datePosted: "2024-01-05", + icon: "rocket" + }, + { + title: "Best Practices", + content: "

Learn industry best practices.

", + href: "/best-practices", + author: "Expert Team", + datePosted: "2024-01-08", + icon: "star" + }, + { + title: "Troubleshooting", + content: "

Common issues and solutions.

", + href: "/troubleshooting", + author: "Support Team", + datePosted: "2024-01-11", + icon: "wrench" + } + ]} +/> + +## BlogCard Component + +### Basic Blog Card + + + +### With Author and Reading Time + + + +### With Custom Image + + + +### Long Form Blog Post + + + +## CardBlogDataLayout + +### Blog Post List + +A beginner's guide to using Livepeer Studio for video streaming.

", + href: "https://livepeer.org/blog/studio-guide", + datePosted: "January 10, 2024", + readingTime: 7 + }, + { + title: "Optimizing Video Quality", + content: "

Tips and tricks for achieving the best video quality with Livepeer.

", + href: "https://livepeer.org/blog/video-quality", + datePosted: "January 12, 2024", + readingTime: 10 + }, + { + title: "Livepeer API Deep Dive", + content: "

Comprehensive exploration of the Livepeer API and its capabilities.

", + href: "https://livepeer.org/blog/api-deep-dive", + datePosted: "January 14, 2024", + readingTime: 20, + icon: "code" + } + ]} +/> + +## Mixed Examples + +### Forum Posts in Columns + +I'm trying to stream to multiple platforms simultaneously. What's the best approach?

Looking for guidance on configuration and best practices.

", + href: "/forum/multistreaming-question", + author: "StreamerPro", + datePosted: "2 hours ago", + icon: "question-circle" + }, + { + title: "Solved: Transcoding performance issues", + content: "

After optimizing my transcoding profiles, I saw a 40% improvement in performance!

Here's what worked for me...

", + href: "/forum/transcoding-solved", + author: "DevExpert", + datePosted: "5 hours ago", + icon: "check-circle", + cta: "View Solution" + } + ]} +/> + diff --git a/snippets/components/layout/examples/lists-examples.mdx b/snippets/components/layout/examples/lists-examples.mdx new file mode 100644 index 000000000..bcf07a460 --- /dev/null +++ b/snippets/components/layout/examples/lists-examples.mdx @@ -0,0 +1,326 @@ +--- +title: "List Components Examples" +description: "Examples of using StepList, StepLinkList, and UpdateLinkList components" +--- + +import { StepList, StepLinkList, UpdateLinkList } from "/snippets/components/layout/lists.jsx"; + +## StepList Component + +### Basic Usage + + + +### Installation Steps + + + +### Troubleshooting Steps + + + +## StepLinkList Component + +### Basic Navigation Steps + + + +### Tutorial Series + + + +### Learning Path + + + +## UpdateLinkList Component + +### Feature Updates + + + +### Documentation Sections + + + +### Product Updates + + + +## Combined Examples + +### Complete Onboarding Flow + + + + + + + +### Migration Guide + + + diff --git a/snippets/components/layout/examples/steps-examples.mdx b/snippets/components/layout/examples/steps-examples.mdx new file mode 100644 index 000000000..00ffc095e --- /dev/null +++ b/snippets/components/layout/examples/steps-examples.mdx @@ -0,0 +1,238 @@ +--- +title: "Styled Steps Components Examples" +description: "Examples of using StyledSteps and StyledStep components" +--- + +import { StyledSteps, StyledStep } from "/snippets/components/layout/steps.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## Basic Usage + + + + Sign up for a Livepeer Studio account at studio.livepeer.com + + + Navigate to the Developers section and generate a new API key + + + Use the API key in your application to start streaming + + + +## Custom Colors + +### Green Theme (Default) + + + + This uses the default Livepeer green color scheme + + + Icons, titles, and connecting lines are all green + + + Perfect for maintaining brand consistency + + + +### Blue Theme + + + + Custom blue color scheme for different sections + + + All colors can be customized to match your needs + + + Use hex color codes for precise color control + + + +### Purple Theme + + + + Purple theme for creative sections + + + Mix and match colors as needed + + + Create unique visual hierarchies + + + +## Installation Guide + + + + Ensure you have the following installed: + - Node.js 16 or higher + - npm or yarn package manager + - A code editor (VS Code recommended) + + + ```bash + npm install @livepeer/react + ``` + Or using yarn: + ```bash + yarn add @livepeer/react + ``` + + + ```javascript + import { LivepeerConfig, Player } from '@livepeer/react'; + ``` + + + ```javascript + + + + ``` + + + You're all set! Start building with Livepeer components. + + + +## API Integration Steps + + + + Include your API key in the request headers: + ``` + Authorization: Bearer YOUR_API_KEY + ``` + + + Send a POST request to create a stream: + ``` + POST https://livepeer.studio/api/stream + ``` + + + Parse the JSON response to get your stream details + + + Use the streamKey to start broadcasting + + + +## Troubleshooting Guide + + + + Check error messages and logs to understand what's going wrong + + + Review the relevant documentation section for guidance + + + Look for similar issues in Discord or GitHub discussions + + + Implement suggested fixes and test your application + + + If unresolved, reach out to support with detailed information + + + +## Deployment Workflow + + + + Run your build command to create production assets + + + Execute your test suite to ensure everything works + + + Deploy to staging environment for final verification + + + Deploy to production and monitor for issues + + + Verify all services are running correctly + + + +## Migration Steps + + + + Create a complete backup of your current setup before proceeding + + + Read the migration guide and understand all breaking changes + + + Update package versions in your package.json file + + + Update your code to match the new API patterns + + + Run comprehensive tests to ensure everything works + + + Use a phased rollout approach to minimize risk + + + +## Quick Start + + + + ```bash + git clone https://github.com/livepeer/example-app.git + cd example-app + ``` + + + ```bash + npm install + ``` + + + ```bash + cp .env.example .env + # Edit .env with your API key + ``` + + + ```bash + npm run dev + ``` + + + diff --git a/snippets/components/layout/examples/table-examples.mdx b/snippets/components/layout/examples/table-examples.mdx new file mode 100644 index 000000000..aa7b11587 --- /dev/null +++ b/snippets/components/layout/examples/table-examples.mdx @@ -0,0 +1,166 @@ +--- +title: "DynamicTable Component Examples" +description: "Examples of using the DynamicTable component" +--- + +import { DynamicTable } from "/snippets/components/layout/table.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## Basic Usage + + + +## API Endpoints Table + + + +## With Monospace Columns + + + +## Pricing Table + + + +## Configuration Options + + + +## Response Codes + + + +## Transcoding Profiles + + + +## Webhook Events + + + +## SDK Comparison + + + +## Feature Comparison + + + +## Environment Variables + + + +## Rate Limits + + + diff --git a/snippets/components/layout/lists.jsx b/snippets/components/layout/lists.jsx new file mode 100644 index 000000000..d4bda5d5a --- /dev/null +++ b/snippets/components/layout/lists.jsx @@ -0,0 +1,154 @@ +import { GotoLink } from "/snippets/components/primitives/links.jsx"; + +/** + * BasicList - A basic list component (placeholder) + * + * @description + * Placeholder component for basic list functionality. Currently returns empty fragment. + * + * @param {Array} listItems - Array of list items + * + * @author Livepeer Documentation Team + */ +export const BasicList = ({ listItems: array }) => { + return <>; +}; + +/** + * IconList - A list component with icons (placeholder) + * + * @description + * Placeholder component for icon list functionality. Currently returns empty fragment. + * + * @param {Array} listItems - Array of list items with icons + * + * @author Livepeer Documentation Team + */ +export const IconList = ({ listItems: array }) => { + return <>; +}; + +/** + * StepList - Renders a list of items as Steps + * + * @description + * Displays an array of items using the Steps/Step components. + * Each item includes a title, optional icon, and content. + * + * @param {Array} listItems - Array of step objects + * @param {string} listItems[].title - Step title + * @param {string} [listItems[].icon] - Optional icon name + * @param {React.ReactNode} listItems[].content - Step content + * + * @example + * const steps = [ + * { title: "Install", icon: "download", content: "Run npm install" }, + * { title: "Configure", icon: "gear", content: "Set up your config" } + * ]; + * + * + * @author Livepeer Documentation Team + */ +export const StepList = ({ listItems }) => { + console.log("listItems", listItems); + return ( + + {listItems.map(({ title, icon, content }, idx) => ( + + {content} + + ))} + + ); +}; + +/** + * StepLinkList - Renders a list of steps with navigation links + * + * @description + * Similar to StepList but each step contains a GotoLink component for navigation. + * + * @param {Array} listItems - Array of step objects with links + * @param {string} listItems[].title - Step title + * @param {string} [listItems[].icon] - Optional icon name + * @param {string} listItems[].content - Link label text + * @param {string} listItems[].link - Relative path for the link + * + * @example + * const steps = [ + * { title: "Getting Started", icon: "rocket", content: "Start Here", link: "/guides/start" }, + * { title: "Advanced", icon: "star", content: "Learn More", link: "/guides/advanced" } + * ]; + * + * + * @author Livepeer Documentation Team + */ +export const StepLinkList = ({ listItems }) => { + console.log("listItems", listItems); + return ( + + {listItems.map(({ title, icon, content, link }, idx) => ( + + + + ))} + + ); +}; + +/** + * UpdateList - Displays an update/announcement list (placeholder) + * + * @description + * Placeholder component for displaying updates. Currently shows hardcoded content. + * + * @param {Array} listItems - Array of update items + * + * @author Livepeer Documentation Team + */ +export const UpdateList = ({ listItems: array }) => { + return ( + +
+ Learn what Livepeer is and how it can benefit you + [About Livepeer](../../01_about/about-home/) +
+
+ ); +}; + +/** + * UpdateLinkList - Renders a list of updates with links + * + * @description + * Displays multiple Update components, each with a title, content, and navigation link. + * + * @param {Array} listItems - Array of update objects + * @param {string} listItems[].title - Update title/label + * @param {string} [listItems[].icon] - Optional icon for the link + * @param {React.ReactNode} listItems[].content - Update content + * @param {string} listItems[].link - Relative path for the link + * + * @example + * const updates = [ + * { title: "New Feature", icon: "star", content: "Check out our new feature", link: "/features/new" }, + * { title: "Bug Fix", icon: "bug", content: "Important bug fix", link: "/changelog" } + * ]; + * + * + * @author Livepeer Documentation Team + */ +export const UpdateLinkList = ({ listItems: array }) => { + return ( + <> + {array.map(({ title, icon, content, link }, idx) => ( + +
+ {content} + +
+
+ ))} + + ); +}; diff --git a/snippets/components/layout/steps.jsx b/snippets/components/layout/steps.jsx new file mode 100644 index 000000000..9dabbb465 --- /dev/null +++ b/snippets/components/layout/steps.jsx @@ -0,0 +1,81 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * StyledSteps - A customizable Steps component with color and styling support + * + * @description + * Wraps the standard Steps component with custom CSS styling for icons, titles, and connecting lines. + * Uses scoped styles with a unique ID to avoid conflicts. + * + * @param {React.ReactNode} children - Step components to render + * @param {string} [iconColor] - Background color for step icons (defaults to theme accentDark) + * @param {string} [titleColor] - Color for step titles (defaults to theme accent) + * @param {string} [lineColor] - Color for the connecting line between steps (defaults to theme accent) + * @param {string} [iconSize="24px"] - Size of the step icons (currently unused in implementation) + * + * @example + * + * Content here + * More content + * + * + * @author Livepeer Documentation Team + */ +export const StyledSteps = ({ + children, + iconColor, + titleColor, + lineColor, + iconSize = "24px", +}) => { + const stepsId = `styled-steps-${Math.random().toString(36).substr(2, 9)}`; + const resolvedIconColor = iconColor || ThemeData.light.accentDark; + const resolvedTitleColor = titleColor || ThemeData.light.accent; + const resolvedLineColor = lineColor || ThemeData.light.accent; + + return ( + <> + +
+ {children} +
+ + ); +}; + +/** + * StyledStep - A wrapper for the Step component with customizable title size + * + * @description + * Wraps the standard Step component to provide consistent styling and title size control. + * Designed to be used within StyledSteps. + * + * @param {string} title - The title of the step + * @param {string} icon - Icon name to display + * @param {string} [titleSize="h3"] - HTML heading size for the title (e.g., "h1", "h2", "h3") + * @param {React.ReactNode} children - Content to display in the step + * + * @example + * + * Run npm install to get started + * + * + * @author Livepeer Documentation Team + */ +export const StyledStep = ({ title, icon, titleSize = "h3", children }) => { + return ( + + {children} + + ); +}; diff --git a/snippets/components/layout/table.jsx b/snippets/components/layout/table.jsx new file mode 100644 index 000000000..6ec6f8add --- /dev/null +++ b/snippets/components/layout/table.jsx @@ -0,0 +1,95 @@ +import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + +/** + * DynamicTable - A reusable table component with site-consistent styling + * + * Props: + * - headerList: Array of strings for column headers + * - itemsList: Array of objects where keys match headerList values + * - monospaceColumns: Optional array of column indices (0-based) to render in monospace + */ +export const DynamicTable = ({ + headerList = [], + itemsList = [], + monospaceColumns = [], +}) => { + if (!headerList.length) { + return
No headers provided
; + } + + return ( + <> + +
+ + + + {headerList.map((header, index) => ( + + ))} + + + + {itemsList.map((item, rowIndex) => ( + + {headerList.map((header, colIndex) => { + const value = + item[header] ?? item[header.toLowerCase()] ?? "-"; + const isMonospace = monospaceColumns.includes(colIndex); + + return ( + + ); + })} + + ))} + +
+ {header} +
+ {isMonospace ? {value} : value} +
+
+ + ); +}; diff --git a/snippets/components/layouts/ListSteps.jsx b/snippets/components/layouts/ListSteps.jsx deleted file mode 100644 index 7d502592c..000000000 --- a/snippets/components/layouts/ListSteps.jsx +++ /dev/null @@ -1,14 +0,0 @@ -// listItems = array of objects with props and children props=any -// stepsConfig = object with props - -export const ListSteps = (listItems, stepsConfig) => { - return ( - - {listItems.map(({ title, icon, ...props }, idx) => ( - - {children} - - ))} - - ); -}; diff --git a/snippets/components/links.jsx b/snippets/components/links.jsx deleted file mode 100644 index 33e15df7a..000000000 --- a/snippets/components/links.jsx +++ /dev/null @@ -1,186 +0,0 @@ -export const CustomCallout = ({ - children, - icon = "lightbulb", - color = "#2d9a67", - iconSize = 16, - textSize = "0.875rem", - textColor, -}) => { - // Default textColor to match the icon color if not specified - const resolvedTextColor = textColor || color; - // Convert hex to rgba for proper opacity - const hexToRgba = (hex, alpha) => { - const r = parseInt(hex.slice(1, 3), 16); - const g = parseInt(hex.slice(3, 5), 16); - const b = parseInt(hex.slice(5, 7), 16); - return `rgba(${r}, ${g}, ${b}, ${alpha})`; - }; - - return ( -
-
- -
-
- {children} -
-
- ); -}; - -export const BlinkingIcon = ({ - icon = "terminal", - size = 16, - color = "#2d9a67", -}) => { - return ( - - - - - ); -}; - -// Alias for backwards compatibility -export const BlinkingTerminal = BlinkingIcon; - -export const DoubleIconLink = ({ - label = "", - href = "#", - text = "", - iconLeft = "github", - iconRight = "arrow-up-right", -}) => { - return ( - - {text && {text}} - - {label} - - - ); -}; - -export const GotoLink = ({ - label, - relativePath, - text = "", - icon = "arrow-turn-down-right", -}) => { - return ( - -

{text}

- - - {label} - -
- ); -}; - -export const GotoCard = ({ label, relativePath, icon, text, cta = "" }) => { - icon = icon ? icon : "arrow-turn-down-right"; - return ( - - {text} - - ); -}; - -export const TipWithArrow = ({ - children, - icon = "lightbulb", - arrowIcon = "arrow-up-right", - color = "#2d9a67", - iconSize = 16, - arrowSize = 16, -}) => { - // Convert hex to rgba for proper opacity - const hexToRgba = (hex, alpha) => { - const r = parseInt(hex.slice(1, 3), 16); - const g = parseInt(hex.slice(3, 5), 16); - const b = parseInt(hex.slice(5, 7), 16); - return `rgba(${r}, ${g}, ${b}, ${alpha})`; - }; - - return ( -
-
- -
-
- {children} -
-
- -
-
- ); -}; diff --git a/snippets/components/lists.jsx b/snippets/components/lists.jsx deleted file mode 100644 index 0571ad603..000000000 --- a/snippets/components/lists.jsx +++ /dev/null @@ -1,62 +0,0 @@ -// Lists -import { GotoLink } from "./links"; - -export const BasicList = ({ listItems: array }) => { - return <>; -}; - -export const IconList = ({ listItems: array }) => { - return <>; -}; - -export const StepList = ({ listItems }) => { - console.log("listItems", listItems); - return ( - - {listItems.map(({ title, icon, content }, idx) => ( - - {content} - - ))} - - ); -}; - -export const StepLinkList = ({ listItems }) => { - console.log("listItems", listItems); - return ( - - {listItems.map(({ title, icon, content, link }, idx) => ( - - - - ))} - - ); -}; - -export const UpdateList = ({ listItems: array }) => { - return ( - -
- Learn what Livepeer is and how it can benefit you - [About Livepeer](../../01_about/about-home/) -
-
- ); -}; - -export const UpdateLinkList = ({ listItems: array }) => { - return ( - <> - {array.map(({ title, icon, content, link }, idx) => ( - -
- {content} - -
-
- ))} - - ); -}; diff --git a/snippets/components/primitives/README.md b/snippets/components/primitives/README.md new file mode 100644 index 000000000..0e18a8f6c --- /dev/null +++ b/snippets/components/primitives/README.md @@ -0,0 +1,15 @@ +Primitives are the building blocks of the UI. They are the smallest units of UI +that can be combined to create more complex components. They are also the most +reusable and should be used as often as possible. + +Index of Primitives + +- Button +- Card +- Divider +- Icon +- Image +- Link +- List +- Table +- Video diff --git a/snippets/components/buttons.jsx b/snippets/components/primitives/buttons.jsx similarity index 64% rename from snippets/components/buttons.jsx rename to snippets/components/primitives/buttons.jsx index 61defcc06..b5a1b8b3b 100644 --- a/snippets/components/buttons.jsx +++ b/snippets/components/primitives/buttons.jsx @@ -1,7 +1,42 @@ +/** + * BasicBtn - Basic button component (placeholder) + * + * @description + * Placeholder component for basic button functionality. Currently returns empty div. + * + * @example + * + * + * @author Livepeer Documentation Team + */ export const BasicBtn = () => { return
; }; +/** + * DownloadButton - Interactive download button with lazy loading + * + * @description + * A download button that uses IntersectionObserver for lazy rendering. + * Only renders the full button when it becomes visible in the viewport. + * Supports custom icons, labels, and optional border styling. + * + * @param {string} [label="Download"] - Button text label + * @param {string} [icon="download"] - Left icon name + * @param {string} downloadLink - URL of the file to download + * @param {string} [rightIcon=""] - Optional right icon name + * @param {boolean} [border=false] - Whether to show a border around the button + * + * @example + * + * + * @author Livepeer Documentation Team + */ export const DownloadButton = ({ label = "Download", icon = "download", diff --git a/snippets/components/primitives/divider.jsx b/snippets/components/primitives/divider.jsx new file mode 100644 index 000000000..d1fa46cef --- /dev/null +++ b/snippets/components/primitives/divider.jsx @@ -0,0 +1,90 @@ +/** + * CustomDivider - Decorative divider with Livepeer branding + * + * @description + * Displays a horizontal divider line with theme-aware Livepeer logo icons on both ends. + * Optionally includes centered text between the divider lines. + * + * Icons automatically adapt to light/dark theme using theme-aware SVG. + * + * @param {string} [color] - Color for the middle text + * @param {string} [middleText] - Optional text to display in the center of the divider + * + * @requires ThemeData must be imported in the MDX file where this component is used: + * import { ThemeData } from "/snippets/styles/themeStyles.jsx"; + * + * @example + * + * + * + * + * @author Livepeer Documentation Team + */ +export const CustomDivider = ({ color, middleText }) => { + return ( + <> + +
+ + + +
+ {middleText && ( + <> + + + {middleText} + + + + )} +
+ + + + + +
+ + ); +}; diff --git a/snippets/components/primitives/examples/buttons-examples.mdx b/snippets/components/primitives/examples/buttons-examples.mdx new file mode 100644 index 000000000..68a4c271c --- /dev/null +++ b/snippets/components/primitives/examples/buttons-examples.mdx @@ -0,0 +1,229 @@ +--- +title: "Button Components Examples" +description: "Examples of using DownloadButton component" +--- + +import { DownloadButton } from "/snippets/components/primitives/buttons.jsx"; + +## Basic Usage + + + +## Custom Label + + + + + +## Custom Icons + +### Different Left Icon + + + + + + + +### With Right Icon + + + + + +## With Border + + + + + +## Use Cases + +### Download Release Binaries + + +

Download the latest version of go-livepeer for your platform:

+ + + + + + +
+ +### Download Documentation + + +

Get all the documentation you need:

+ + + + + + +
+ +### Download in Steps + + + + Select the appropriate binary for your operating system. + + + + + + Extract the downloaded archive and follow the installation instructions. + + + +### Multiple Download Options + + + + + + + + + + + +### Download with Instructions + + + **Before downloading:** Make sure you have the required dependencies installed. + + + + + + **After downloading:** Verify the checksum before running the binary. + + +### Inline Download Links + +Download the latest release to get started. + +You can also download the for offline reading. + +### Download Table + +| Resource | Description | Download | +|----------|-------------|----------| +| Binary | Latest compiled binary | | +| Source | Source code archive | | +| Docs | PDF documentation | | + +## Styled Examples + +
+ + + +
+ diff --git a/snippets/components/primitives/examples/divider-examples.mdx b/snippets/components/primitives/examples/divider-examples.mdx new file mode 100644 index 000000000..cd2ca4b5d --- /dev/null +++ b/snippets/components/primitives/examples/divider-examples.mdx @@ -0,0 +1,240 @@ +--- +title: "CustomDivider Component Examples" +description: "Examples of using the CustomDivider component" +--- + +import { CustomDivider } from "/snippets/components/primitives/divider.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## Basic Usage + + + +## With Middle Text + + + + + + + +## Section Separators + +### Introduction + +This is the introduction section with important information about Livepeer. + + + +### Features + +Here are the key features of Livepeer: +- Decentralized video infrastructure +- Cost-effective transcoding +- Global CDN delivery + + + +### Getting Started + +Follow these steps to get started with Livepeer... + +## Use Cases + +### Separating Content Sections + + +

API Key Authentication

+

Use your API key in the Authorization header.

+ + + +

OAuth Authentication

+

Authenticate using OAuth 2.0 flow.

+
+ +### Tutorial Steps + +

Step 1: Setup

+

Install the required dependencies and configure your environment.

+ + + +

Step 2: Implementation

+

Implement the core functionality in your application.

+ + + +

Step 3: Deploy

+

Deploy your application to production.

+ +### Comparison Sections + + +
+

Before Livepeer

+
    +
  • Expensive infrastructure
  • +
  • Complex setup
  • +
  • Limited scalability
  • +
+
+
+

After Livepeer

+
    +
  • Cost-effective solution
  • +
  • Simple integration
  • +
  • Infinite scalability
  • +
+
+
+ + + +### Multiple Choice Sections + +

Choose Your Path

+ + + Build applications with Livepeer's powerful APIs + + + + + + Run infrastructure and earn rewards + + + + + + Stake tokens and participate in the network + + +### Documentation Sections + +## API Reference + +Complete documentation for all API endpoints. + + + +## SDK Documentation + +Learn how to use Livepeer SDKs in your favorite language. + + + +## Examples + +Browse code examples and tutorials. + +### Timeline Sections + +

2020

+

Livepeer protocol launched on mainnet

+ + + +

Major protocol upgrades and improvements

+ + + +

Livepeer Studio platform launched

+ + + +

Continued growth and ecosystem expansion

+ + + +

New features and integrations

+ +### FAQ Sections + + + Livepeer is a decentralized video infrastructure network. + + + + + + Livepeer uses a network of nodes to process and deliver video content. + + + + + + Pricing varies based on usage. Check our pricing page for details. + + +### Alternative Options + +

Option A: Self-Hosted

+

Host and manage your own video infrastructure.

+ + + +

Option B: Livepeer

+

Use Livepeer's decentralized network for video processing.

+ +### Content Breaks + +

This is a long article with multiple sections. The divider helps break up the content and improve readability.

+ + + +

Each section can focus on a different topic or aspect of the subject matter.

+ + + +

The visual separation makes it easier for readers to scan and navigate the content.

+ +### Themed Sections + +
+

Free Tier

+

Perfect for getting started and testing

+
+ + + +
+

Pro Tier

+

For production applications and businesses

+
+ +### Simple Section Breaks + +Introduction to the topic. + + + +Main content and detailed explanation. + + + +Conclusion and next steps. + +### With Custom Styling + +
+ +
+ +
+ +
+ +### In Cards + + +

Method 1: NPM

+ npm install @livepeer/react + + + +

Method 2: Yarn

+ yarn add @livepeer/react +
+ diff --git a/snippets/components/primitives/examples/icons-examples.mdx b/snippets/components/primitives/examples/icons-examples.mdx new file mode 100644 index 000000000..b7fbf77d7 --- /dev/null +++ b/snippets/components/primitives/examples/icons-examples.mdx @@ -0,0 +1,235 @@ +--- +title: "Icon Components Examples" +description: "Examples of using LivepeerIcon and LivepeerSVG components" +--- + +import { LivepeerIcon, LivepeerIconFlipped, LivepeerSVG } from "/snippets/components/primitives/icons.jsx"; + +## LivepeerIcon Component + +### Basic Usage + + + +### Custom Size + + + + + + +### Custom Color + + + + + + +### Different Sizes in a Row + +
+ + + + + +
+ +## LivepeerIconFlipped Component + +### Basic Flipped Icon + + + +### Custom Size Flipped + + + + +### Comparison: Normal vs Flipped + +
+
+ +

Normal

+
+
+ +

Flipped

+
+
+ +## LivepeerSVG Component + +### Basic SVG + + + +### Custom Size SVG + + + + + +## Use Cases + +### In Headers + +

Livepeer Documentation

+

Getting Started

+

Quick Start Guide

+ +### In Cards + +}> + Learn about the decentralized video infrastructure network. + + +### In Lists + +
    +
  • Decentralized video processing
  • +
  • Cost-effective transcoding
  • +
  • Global CDN delivery
  • +
+ +### As Decorative Elements + +
+ +
+

Welcome to Livepeer

+

Start building with decentralized video infrastructure

+
+
+ +### In Navigation + + + +### As Bullet Points + +
+
Feature one
+
Feature two
+
Feature three
+
+ +### In Callouts + + + This is an important note about Livepeer functionality. + + + + Make sure to configure your API key before proceeding. + + +### Decorative Borders + +
+ +

Powered by Livepeer

+ +
+ +### In Steps + + + }> + Configure your Livepeer environment + + }> + Develop your application + + }> + Launch to production + + + +### Color Variations + +
+
+ +

Green

+
+
+ +

Blue

+
+
+ +

Purple

+
+
+ +

Red

+
+
+ +

Orange

+
+
+ +### As Loading Indicator + +
+
+ +
+

Loading...

+ +
+ +### In Footer + +
+
+ + © 2024 Livepeer +
+
Documentation
+
+ +### Inline with Text + +Built with Livepeer technology. + +Powered by for reliable video streaming. + diff --git a/snippets/components/primitives/examples/links-examples.mdx b/snippets/components/primitives/examples/links-examples.mdx new file mode 100644 index 000000000..59db94597 --- /dev/null +++ b/snippets/components/primitives/examples/links-examples.mdx @@ -0,0 +1,311 @@ +--- +title: "Link and Callout Components Examples" +description: "Examples of using link components and callouts from links.jsx" +--- + +import { + CustomCallout, + BlinkingIcon, + DoubleIconLink, + GotoLink, + GotoCard, + TipWithArrow +} from "/snippets/components/primitives/links.jsx"; +import { ThemeData } from '/snippets/styles/themeStyles.jsx' + +## CustomCallout Component + +### Basic Usage + + + This is a basic callout with default settings. + + +### Custom Icon + + + This callout uses a rocket icon instead of the default lightbulb. + + + + This is a warning callout with a warning icon. + + + + This is an informational callout. + + +### Custom Color + + + This callout uses a blue color scheme. + + + + This callout uses a red color scheme for warnings. + + + + This callout uses a purple color scheme. + + +### Custom Sizes + + + This callout has larger icon and text. + + + + This callout has smaller icon and text. + + +### All Custom Options + + + This callout combines all custom options: icon, color, and sizes. + + +## BlinkingIcon Component + +### Basic Blinking Icon + + This icon blinks to draw attention. + +### Custom Icon + + New notification + + Important alert + +### Different Colors + + Online + + Offline + +### In Context + +
+ + Stream is live +
+ +## DoubleIconLink Component + +### Basic Usage + + + +### Custom Icons + + + + + +### With Text Prefix + + + +## GotoLink Component + +### Basic Usage + + + +### Custom Icon + + + + + +### With Text + + + +## GotoCard Component + +### Basic Card Link + + + +### With Custom Icon + + + +### With CTA + + + +### Multiple Cards + + + + + + +## TipWithArrow Component + +### Basic Usage + + + Use the Dropdown at the top-right of this page to view the Quickstart Guide for your preferred OS. + + +### Custom Icon + + + This tip uses a rocket icon instead of the default lightbulb. + + + + Pro tip: Use keyboard shortcuts to navigate faster! + + +### Custom Arrow Icon + + + This tip uses a different arrow icon in the corner. + + + + Click the link icon to open in a new tab. + + +### Custom Color + + + This tip uses a blue color scheme. + + + + This tip uses a purple color scheme. + + +### Custom Sizes + + + This tip has larger icons (20px instead of default 16px). + + + + This tip has smaller icons for subtle hints. + + +### All Custom Options + + + This tip combines all custom options: custom icon, arrow, color, and sizes. + + +## Combined Examples + +### Navigation Section + + + Choose your learning path below: + + + + + + +### Alert with Link + + + Important: Make sure to read the + + before deploying to production. + + +### Live Status Indicator + +
+
+ + System Status: Online +
+

All systems operational

+
+ diff --git a/snippets/components/primitives/icons.jsx b/snippets/components/primitives/icons.jsx new file mode 100644 index 000000000..6dd407da6 --- /dev/null +++ b/snippets/components/primitives/icons.jsx @@ -0,0 +1,129 @@ +/** + * LivepeerSVG - Inline SVG version of the Livepeer logo + * + * @description + * Renders the Livepeer logo as an inline SVG element. + * Uses em units for responsive sizing. + * + * @param {number} [size=24] - Size of the icon (currently unused, uses 1em) + * @param {Object} props - Additional SVG props + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const LivepeerSVG = ({ size = 24, ...props }) => { + return ( + + + + ); +}; + +/** + * LivepeerIconOld - Legacy Livepeer icon component + * + * @description + * Displays the Livepeer logo using the light symbol SVG file. + * This is the older version of the icon component. + * + * @param {Object} props - Icon component props + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const LivepeerIconOld = ({ ...props }) => { + return ( + + ); +}; + +/** + * LivepeerIconFlipped - Horizontally flipped Livepeer icon + * + * @description + * Displays the Livepeer logo flipped horizontally using CSS transform. + * Useful for decorative purposes or directional indicators. + * + * @param {Object} props - Icon component props + * + * @example + * + * + * @author Livepeer Documentation Team + */ +export const LivepeerIconFlipped = ({ ...props }) => { + return ( + + + + ); +}; + +/** + * LivepeerIcon - Theme-aware Livepeer icon component + * + * @description + * Displays the Livepeer logo with automatic color adaptation for light/dark themes. + * Uses CSS custom properties for theme-aware coloring. + * + * @param {number} [size=16] - Size of the icon in pixels + * @param {string} [color] - Custom color override (defaults to theme-aware color) + * @param {Object} props - Additional Icon component props + * + * @example + * + * + * + * @author Livepeer Documentation Team + */ +export const LivepeerIcon = ({ size = 16, color, ...props }) => { + return ( + + + + + ); +}; diff --git a/snippets/components/primitives/links.jsx b/snippets/components/primitives/links.jsx new file mode 100644 index 000000000..5a104d17f --- /dev/null +++ b/snippets/components/primitives/links.jsx @@ -0,0 +1,392 @@ +/** + * CustomCallout - Customizable callout/alert box component + * + * @description + * Displays a styled callout box with an icon and custom colors. + * Automatically converts hex colors to rgba for proper opacity handling. + * + * @param {React.ReactNode} children - Content to display in the callout + * @param {string} [icon="lightbulb"] - Icon name to display + * @param {string} [color] - Primary color for icon, border, and background (defaults to theme accent) + * @param {number} [iconSize=16] - Size of the icon in pixels + * @param {string} [textSize="0.875rem"] - Font size for the text content + * @param {string} [textColor] - Text color (defaults to match icon color) + * + * @example + * + * This is an important message! + * + * + * @author Livepeer Documentation Team + */ +const CustomCallout = ({ + children, + icon = "lightbulb", + color, + iconSize = 16, + textSize = "0.875rem", + textColor, +}) => { + // Use theme accent if no color specified + const defaultColor = "var(--custom-callout-color)"; + const resolvedColor = color || defaultColor; + const resolvedTextColor = textColor || resolvedColor; + + // Convert hex to rgba for proper opacity + const hexToRgba = (hex, alpha) => { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; + }; + + return ( + <> + +
+
+ +
+
+ {children} +
+
+ + ); +}; + +/** + * BlinkingIcon - Animated blinking icon component + * + * @description + * Displays an icon with a smooth blinking animation (fades between full and 30% opacity). + * Animation cycles every 3 seconds. + * + * @param {string} [icon="terminal"] - Icon name to display + * @param {number} [size=16] - Size of the icon in pixels + * @param {string} [color] - Color of the icon (defaults to theme accent) + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const BlinkingIcon = ({ icon = "terminal", size = 16, color }) => { + const resolvedColor = color || "var(--blinking-icon-color)"; + return ( + <> + + + + + + ); +}; + +/** + * BlinkingTerminal - Alias for BlinkingIcon (backwards compatibility) + * + * @description + * Legacy alias for BlinkingIcon component. Use BlinkingIcon instead. + * + * @deprecated Use BlinkingIcon instead + * @author Livepeer Documentation Team + */ +const BlinkingTerminal = BlinkingIcon; + +/** + * DoubleIconLink - Link component with icons on both sides + * + * @description + * Displays a link with an icon on the left and right, plus optional text prefix. + * Commonly used for external links (e.g., GitHub links with external link indicator). + * + * @param {string} [label=""] - Link text/label + * @param {string} [href="#"] - Link URL + * @param {string} [text=""] - Optional text to display before the link + * @param {string} [iconLeft="github"] - Icon to display on the left + * @param {string} [iconRight="arrow-up-right"] - Icon to display on the right + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const DoubleIconLink = ({ + label = "", + href = "#", + text = "", + iconLeft = "github", + iconRight = "arrow-up-right", +}) => { + return ( + <> + + + {text && {text}} + + {label} + + + + ); +}; + +/** + * GotoLink - Simple navigation link with icon + * + * @description + * Displays a link with an icon, typically used for internal navigation. + * + * @param {string} label - Link text/label + * @param {string} relativePath - Relative URL path + * @param {string} [text=""] - Optional text to display before the link + * @param {string} [icon="arrow-turn-down-right"] - Icon to display + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const GotoLink = ({ + label, + relativePath, + text = "", + icon = "arrow-turn-down-right", +}) => { + return ( + +

{text}

+ + + {label} + +
+ ); +}; + +/** + * GotoCard - Card component for navigation + * + * @description + * Wraps content in a Card component with a link, icon, and optional CTA. + * + * @param {string} label - Card title + * @param {string} relativePath - Relative URL path + * @param {string} [icon] - Icon to display (defaults to "arrow-turn-down-right") + * @param {React.ReactNode} text - Card content + * @param {string} [cta=""] - Call-to-action button text + * + * @example + * + * + * @author Livepeer Documentation Team + */ +const GotoCard = ({ label, relativePath, icon, text, cta = "" }) => { + icon = icon ? icon : "arrow-turn-down-right"; + return ( + + {text} + + ); +}; + +/** + * TipWithArrow - Callout box with an arrow indicator + * + * @description + * Similar to CustomCallout but includes an arrow icon in the top-right corner. + * Useful for tips that point to related content or actions. + * + * @param {React.ReactNode} children - Content to display in the tip + * @param {string} [icon="lightbulb"] - Main icon to display on the left + * @param {string} [arrowIcon="arrow-up-right"] - Arrow icon to display in top-right + * @param {string} [color] - Primary color for icons, border, and background (defaults to theme accent) + * @param {number} [iconSize=16] - Size of the main icon in pixels + * @param {number} [arrowSize=16] - Size of the arrow icon in pixels + * + * @example + * + * Check out the related documentation for more details! + * + * + * @author Livepeer Documentation Team + */ +const TipWithArrow = ({ + children, + icon = "lightbulb", + arrowIcon = "arrow-up-right", + color, + iconSize = 16, + arrowSize = 16, +}) => { + // Use theme accent if no color specified + const resolvedColor = color || "var(--tip-with-arrow-color)"; + + // Convert hex to rgba for proper opacity + const hexToRgba = (hex, alpha) => { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; + }; + + return ( + <> + +
+
+ +
+
+ {children} +
+
+ +
+
+ + ); +}; + +const LinkArrow = ({ href, label, newline = true }) => { + const linkArrowStyle = { + display: "inline-flex", + alignItems: "center", + gap: "4px", + paddingTop: "0.2rem", + }; + return ( + <> + {newline &&
} + + {label} + + + + ); +}; + +export { + CustomCallout, + BlinkingIcon, + BlinkingTerminal, + DoubleIconLink, + GotoLink, + GotoCard, + TipWithArrow, + LinkArrow, +}; diff --git a/snippets/components/release.jsx b/snippets/components/release.jsx deleted file mode 100644 index 4f3ae3486..000000000 --- a/snippets/components/release.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import { useState, useEffect } from "react"; - -/** - * LatestRelease - Fetches and displays the latest release version from GitHub - * Usage: - * import { LatestRelease, LatestReleaseUrl } from '/snippets/components/release.jsx' - * - * Latest version: - * Download here - */ - -export const LatestRelease = ({ - repo = "livepeer/go-livepeer", - fallback = "latest", -}) => { - const [version, setVersion] = useState(fallback); - const [loading, setLoading] = useState(true); - - useEffect(() => { - fetch(`https://api.github.com/repos/${repo}/releases/latest`) - .then((res) => res.json()) - .then((data) => { - if (data.tag_name) { - setVersion(data.tag_name); - } - setLoading(false); - }) - .catch(() => { - setLoading(false); - }); - }, [repo]); - - return version; -}; - -export const LatestReleaseUrl = ({ - repo = "livepeer/go-livepeer", - asset = "livepeer-linux-amd64.tar.gz", - children, -}) => { - const [url, setUrl] = useState(`https://github.com/${repo}/releases/latest`); - - useEffect(() => { - fetch(`https://api.github.com/repos/${repo}/releases/latest`) - .then((res) => res.json()) - .then((data) => { - if (data.tag_name) { - setUrl( - `https://github.com/${repo}/releases/download/${data.tag_name}/${asset}` - ); - } - }) - .catch(() => {}); - }, [repo, asset]); - - return ( - - {children || url} - - ); -}; diff --git a/snippets/components/steps.jsx b/snippets/components/steps.jsx deleted file mode 100644 index bf86f7b3c..000000000 --- a/snippets/components/steps.jsx +++ /dev/null @@ -1,38 +0,0 @@ -// Custom Steps component with styling support - -export const StyledSteps = ({ - children, - iconColor = "#18794e", - titleColor = "#2b9a66", - lineColor = "#2b9a66", - iconSize = "24px", -}) => { - const stepsId = `styled-steps-${Math.random().toString(36).substr(2, 9)}`; - - return ( - <> - -
- {children} -
- - ); -}; - -export const StyledStep = ({ title, icon, titleSize = "h3", children }) => { - return ( - - {children} - - ); -}; diff --git a/snippets/components/stuff.js b/snippets/components/stuff.js deleted file mode 100644 index 918dc8560..000000000 --- a/snippets/components/stuff.js +++ /dev/null @@ -1,9 +0,0 @@ -// export const embedUrl = url.replace('watch?v=', 'embed/') - -// import { Video } from '/snippets/video.jsx' -//