<!DOCTYPE html> <html lang="en" data-bs-theme="dark"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nostr Poster - Content Manager</title> <!-- Bootstrap & CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <link rel="stylesheet" href="/assets/css/style.css"> <!-- nostr-tools ESM (attaches nip19 to window.nostrTools) --> <script type="module"> import { nip19 } from 'https://esm.sh/nostr-tools@1.10.0?bundle'; window.nostrTools = { nip19 }; </script> <!-- Main JS --> <script src="/assets/js/main.js"></script> <!-- Content Page JS --> <script src="/assets/js/content.js"></script> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark"> <div class="container"> <a class="navbar-brand" href="/"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-send-fill me-2" viewBox="0 0 16 16"> <path d="M15.964.686a.5.5 0 0 0-.65-.65L.767 5.855H.766l-.452.18 a.5.5 0 0 0-.082.887l.41.26.001.002 4.995 3.178 3.178 4.995.002.002.26.41 a.5.5 0 0 0 .886-.083l6-15Zm-1.833 1.89L6.637 10.07l-.215-.338a.5.5 0 0 0-.154-.154l-.338-.215 7.494-7.494 1.178-.471-.47 1.178Z" /> </svg> Nostr Poster - Content </a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link" href="/"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-robot me-1" viewBox="0 0 16 16"> <path d="M6 12.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5ZM3 8.062C3 6.76 4.235 5.765 5.53 5.886a26.58 26.58 0 0 0 4.94 0C11.765 5.765 13 6.76 13 8.062v1.157a.933.933 0 0 1-.765.935c-.845.147-2.34.346-4.235.346-1.895 0-3.39-.2-4.235-.346A.933.933 0 0 1 3 9.219V8.062Zm4.542-.827a.25.25 0 0 0-.217.068l-.92.9a24.767 24.767 0 0 1-1.871-.183.25.25 0 0 0-.068.495c.55.076 1.232.149 2.02.193a.25.25 0 0 0 .189-.071l.754-.736.847 1.71a.25.25 0 0 0 .404.062l.932-.97a25.286 25.286 0 0 0 1.922-.188.25.25 0 0 0-.068-.495c-.538.074-1.207.145-1.98.189a.25.25 0 0 0-.166.076l-.754.785-.842-1.7a.25.25 0 0 0-.182-.135Z" /> <path d="M8.5 1.866a1 1 0 1 0-1 0V3h-2A4.5 4.5 0 0 0 1 7.5V8a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1v1a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1v-.5A4.5 4.5 0 0 0 10.5 3h-2V1.866ZM14 7.5V13a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7.5A3.5 3.5 0 0 1 5.5 4h5A3.5 3.5 0 0 1 14 7.5Z" /> </svg> Bots </a> </li> </ul> <ul class="navbar-nav ms-auto"> <li class="nav-item" id="userInfoRow"> <span class="me-3">Logged in as: <span id="userPubkey"></span></span> <button class="btn btn-sm btn-outline-danger" id="logoutButton2">Logout</button> </li> </ul> </div> </div> </nav> <div class="container mt-4"> <!-- Bot Selection Section --> <div class="bot-selection-container text-center"> <h3 class="mb-4">Select a Bot to Manage Content</h3> <div class="row justify-content-center"> <div class="col-md-6"> <div class="input-group"> <select id="botSelect" class="form-select"> <!-- Populated by loadBotChoices() in main.js --> <option value="">-- Select a Bot --</option> </select> <button class="btn btn-primary" id="loadContentBtn">Load Content</button> </div> </div> </div> <!-- Global Media Server Settings --> <div class="row justify-content-center mt-3" id="mediaServerSettings"> <div class="col-md-8"> <div class="card"> <div class="card-body"> <h5 class="card-title">Media Server Settings</h5> <div class="row"> <div class="col-md-6 mb-2"> <label for="primaryServer" class="form-label">Primary Media Server</label> <select id="primaryServer" class="form-select mb-2"> <option value="nip94">NIP-94 Server</option> <option value="blossom">Blossom Server</option> </select> <div class="mb-2"> <label for="primaryServerURL" class="form-label">Server URL</label> <input type="text" id="primaryServerURL" class="form-control" placeholder="https://your-nip94-server.com"> </div> </div> <div class="col-md-6 mb-2"> <label for="fallbackServer" class="form-label">Fallback Server</label> <select id="fallbackServer" class="form-select mb-2"> <option value="none">None</option> <option value="nip94">NIP-94 Server</option> <option value="blossom">Blossom Server</option> </select> <div class="mb-2"> <label for="fallbackServerURL" class="form-label">Fallback URL</label> <input type="text" id="fallbackServerURL" class="form-control" placeholder="https://your-fallback-server.com"> </div> </div> </div> <button class="btn btn-sm btn-primary mt-2" id="saveMediaSettingsBtn">Save Settings</button> </div> </div> </div> </div> </div> <!-- Content areas (only visible after bot selection) --> <div id="contentContainer" class="d-none"> <div class="row"> <!-- Content Upload Section (Left) --> <div class="col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h4>Content Files</h4> </div> <div class="card-body"> <!-- File list area - with scrollable container --> <div id="contentArea" style="max-height: 300px; overflow-y: auto;"> <!-- Files will be listed here --> <p>Select a bot and click "Load Content" to see files.</p> </div> <hr> <!-- Upload section - using existing structure without an ID --> <h5>Upload New Content</h5> <div class="mb-3"> <input type="file" id="uploadFileInput" class="form-control" accept="image/*,video/*"> <div id="uploadPreviewContainer" class="d-none"> <img id="uploadPreview" class="upload-preview img-fluid"> </div> </div> <button class="btn btn-primary" id="uploadButton" disabled>Upload</button> </div> </div> </div> <!-- Manual Post Section (Right) - FIXED: added col-md-6 wrapper --> <div class="col-md-6 mb-4"> <div class="card"> <div class="card-header"> <h4>Create Manual Post</h4> </div> <div class="card-body"> <!-- Post Type Selection --> <div class="mb-3"> <label class="form-label">Post Type</label> <div class="form-check"> <input class="form-check-input" type="radio" name="postKind" id="postKind1" value="1" checked> <label class="form-check-label" for="postKind1"> Standard Post (kind: 1) </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="postKind" id="postKind20" value="20"> <label class="form-check-label" for="postKind20"> <strong>Picture Post (kind: 20)</strong> - Images displayed in a gallery-like feed </label> </div> </div> <!-- Title Field (only for kind 20) --> <div class="mb-3 d-none" id="titleField"> <label for="postTitle" class="form-label">Title <span class="text-danger">*</span></label> <input type="text" class="form-control" id="postTitle" placeholder="Post title (required for kind: 20)"> <small class="form-text text-muted">Required for picture posts (kind: 20)</small> </div> <!-- Content Field --> <div class="mb-3"> <label for="manualPostContent" class="form-label">Content</label> <textarea class="form-control" id="manualPostContent" rows="4" placeholder="Write your post content here..."></textarea> </div> <!-- Hashtags Field --> <div class="mb-3"> <label for="postHashtags" class="form-label">Hashtags</label> <input type="text" class="form-control" id="postHashtags" placeholder="comma separated: art, photography, etc"> </div> <!-- Media Section - Enhanced for Kind 20 --> <div class="mb-3"> <h5 class="mb-2">Media Attachment</h5> <span class="badge bg-info" id="kind20MediaRequired" style="display: none;">Required for kind: 20</span> <!-- Upload Section --> <div class="mb-3"> <label class="form-label">Upload Image</label> <div class="input-group"> <input type="file" id="postMediaInput" class="form-control" accept="image/*"> <button class="btn btn-secondary" type="button" id="quickUploadBtn">Upload</button> </div> <small class="form-text text-muted">Upload to attach an image to your post</small> </div> <!-- Media URL Field (manually entered URL or populated after upload) --> <div class="mb-3"> <label for="mediaUrlInput" class="form-label">Media URL</label> <input type="text" class="form-control" id="mediaUrlInput" placeholder="Enter media URL or upload an image"> <small class="form-text text-muted">For kind: 20 posts, an image URL is required</small> </div> <!-- Alt Text Field (for accessibility) --> <div class="mb-3"> <label for="mediaAltText" class="form-label">Alt Text</label> <input type="text" class="form-control" id="mediaAltText" placeholder="Describe the image for accessibility"> <small class="form-text text-muted">Recommended for image description</small> </div> <!-- Media Preview --> <div id="mediaPreviewContainer" class="d-none mt-2"> <img id="mediaPreview" class="upload-preview img-fluid mb-2"> <div id="mediaLinkContainer" class="media-link"> <small class="text-muted">Media will appear here after upload</small> </div> </div> </div> <button type="button" class="btn btn-success mt-2" id="submitPostBtn">Post Now</button> </div> </div> </div> </div> </div> <div id="eventInfoContainer" class="mt-3"></div> </div> </body> </html>