index.html (32710B)
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Bzl - Hives</title> 7 <link rel="stylesheet" href="/styles.css?v=130" /> 8 </head> 9 <body> 10 <div class="app"> 11 <button id="showSidebar" class="ghost smallBtn sidebarToggle hidden" type="button" title="Show sidebar">Show</button> 12 <button id="togglePeople" class="ghost smallBtn peopleToggle" type="button" title="Show people">People</button> 13 <button id="showRightRack" class="ghost smallBtn rightRackToggle hidden" type="button" title="Show right rack">Right</button> 14 <aside class="sidebar"> 15 <div class="sidebarScroll"> 16 <div class="brand"> 17 <div id="instanceTitle" class="logo">Bzl</div> 18 <div id="instanceSubtitle" class="subtitle">Ephemeral hives + chat</div> 19 </div> 20 21 <div class="statusBlock"> 22 <div id="connBadge" class="badge badge-warn">Connecting...</div> 23 <div class="row"> 24 <button id="enableNotifs" class="ghost smallBtn grow" type="button">Enable notifications</button> 25 </div> 26 <div id="notifStatus" class="small muted"></div> 27 </div> 28 29 <section id="viewPanel" class="panel"> 30 <div class="panelTitle">View</div> 31 <div class="uiHint">Use layout presets for quick panel setups. Shortcuts: <b>[</b>/<b>]</b> cycle presets, <b>-</b>/<b>=</b> cycle hives/chats in the active panel, <b>?</b> opens shortcut help.</div> 32 <label class="checkRow" style="margin-top:8px;"> 33 <span>Rack layout (experimental)</span> 34 <input id="toggleRackLayout" type="checkbox" /> 35 </label> 36 <label style="margin-top:10px;"> 37 <span>Layout preset</span> 38 <select id="layoutPreset"> 39 <option value="discordLike">Discord-like</option> 40 <option value="chat">Chat</option> 41 <option value="browsing">Browsing</option> 42 <option value="maps">Maps</option> 43 <option value="moderation">Moderation</option> 44 <option value="focus">Focus</option> 45 <option value="clean">Clean</option> 46 <option value="ops">Ops</option> 47 </select> 48 </label> 49 <label class="checkRow" style="margin-top:8px;"> 50 <span>Side panels</span> 51 <input id="toggleSideRack" type="checkbox" checked /> 52 </label> 53 <label class="checkRow" style="margin-top:8px;"> 54 <span>Right rack</span> 55 <input id="toggleRightRack" type="checkbox" checked /> 56 </label> 57 <label class="checkRow" style="margin-top:8px;"> 58 <span>Show reactions bar</span> 59 <input id="toggleReactions" type="checkbox" /> 60 </label> 61 <label class="checkRow" style="margin-top:8px;"> 62 <span>Stay connected</span> 63 <input id="stayConnected" type="checkbox" /> 64 </label> 65 <label class="checkRow" style="margin-top:8px;"> 66 <span>Enable hints</span> 67 <input id="enableHints" type="checkbox" /> 68 </label> 69 <label style="margin-top:10px;"> 70 <span>Chat send key</span> 71 <select id="chatEnterMode"> 72 <option value="ctrlEnter">Ctrl/Cmd + Enter sends</option> 73 <option value="enter">Enter sends (Shift+Enter newline)</option> 74 </select> 75 </label> 76 <div class="row" style="margin-top:8px; gap:8px; flex-wrap:wrap;"> 77 <button id="openShortcutHelp" class="ghost smallBtn" type="button">Shortcut help</button> 78 <button id="resetCurrentLayout" class="ghost smallBtn" type="button">Reset layout</button> 79 </div> 80 81 <details style="margin-top:10px;"> 82 <summary class="small muted" style="cursor:pointer;user-select:none;">Advanced display</summary> 83 <div style="margin-top:10px;"> 84 <label> 85 <span>Text size</span> 86 <select id="uiScale"> 87 <option value="auto" selected>Auto</option> 88 <option value="xs">Compact</option> 89 <option value="sm">Small</option> 90 <option value="md">Default</option> 91 <option value="lg">Large</option> 92 </select> 93 </label> 94 <label style="margin-top:10px;"> 95 <span>Device layout</span> 96 <select id="deviceLayout"> 97 <option value="auto" selected>Auto</option> 98 <option value="widescreen">16:9 / 16:10</option> 99 <option value="fourThree">4:3</option> 100 <option value="threeTwo">3:2</option> 101 <option value="ultrawide">Ultrawide</option> 102 <option value="portrait">Portrait</option> 103 </select> 104 </label> 105 </div> 106 </details> 107 </section> 108 109 <section id="accountPanel" class="panel"> 110 <div class="panelTitle">Account</div> 111 <div class="small muted" id="authHint">Sign in to post, chat, and boost.</div> 112 <div class="uiHint">New here: create an account, then open a hive and tap <b>Chat</b> to join a conversation.</div> 113 114 <div class="small muted">Signed in as</div> 115 <div id="userLabel" class="userLine">Signed out</div> 116 117 <form id="authForm" class="form"> 118 <label> 119 <span>Username</span> 120 <input id="authUser" autocomplete="username" /> 121 </label> 122 <label> 123 <span>Password</span> 124 <input id="authPass" type="password" autocomplete="current-password" /> 125 </label> 126 <label id="codeRow" class="hidden"> 127 <span>Registration code</span> 128 <input id="authCode" autocomplete="one-time-code" /> 129 </label> 130 <div class="row"> 131 <button class="primary grow" type="submit">Sign in</button> 132 <button id="registerBtn" class="ghost" type="button">Create account</button> 133 </div> 134 <button id="logoutBtn" class="ghost hidden" type="button">Sign out</button> 135 <div class="small muted"> 136 Note: this is a prototype; don't reuse important passwords. 137 </div> 138 </form> 139 <div id="onboardingCard" class="onboardingCard hidden"> 140 <div class="panelTitle">Onboarding</div> 141 <div id="onboardingBody" class="small muted"></div> 142 <div class="row" style="margin-top:8px;"> 143 <button id="onboardingAccept" class="primary grow hidden" type="button">Accept and continue</button> 144 <button id="onboardingRefresh" class="ghost" type="button">Refresh</button> 145 </div> 146 </div> 147 </section> 148 149 <section id="profilePanel" class="panel"> 150 <div class="panelTitle">Profile</div> 151 <div class="small muted">Set how your name appears.</div> 152 <div class="uiHint">Your profile card appears in People and when someone opens your profile from a post or chat.</div> 153 <label> 154 <span>Profile picture</span> 155 <input id="profileImage" type="file" accept="image/*" /> 156 </label> 157 <div class="row"> 158 <div class="pfpBox"> 159 <img id="profilePreview" alt="Profile preview" /> 160 </div> 161 <div class="grow"> 162 <label> 163 <span>Color</span> 164 <input id="nameColor" type="color" value="#ff3ea5" /> 165 </label> 166 <button id="removeProfileImage" class="ghost" type="button">Remove picture</button> 167 </div> 168 </div> 169 <button id="saveProfile" class="primary" type="button">Save profile</button> 170 <div id="profileStatus" class="small muted"></div> 171 </section> 172 173 </div> 174 175 <div class="sidebarFooter"> 176 <div class="poweredByTile" aria-label="Powered by Bzl"> 177 <img class="poweredByLogo" src="/assets/logobzl.png" alt="Bzl logo" /> 178 <div class="poweredByText"> 179 <div class="poweredByTitle">Powered by Bzl</div> 180 <div class="poweredByByline">by Azakaela Erin Redfire</div> 181 </div> 182 </div> 183 <button id="toggleSidebar" class="ghost smallBtn" type="button" title="Hide sidebar">Hide</button> 184 </div> 185 </aside> 186 187 <div id="sidebarResizeHandle" class="panelResizeHandle sidebarResizeHandle" title="Drag to resize sidebar" aria-hidden="true"></div> 188 189 <main class="main"> 190 <div id="mainRack" class="mainRack"> 191 <button id="showSideRack" class="ghost smallBtn sideRackToggle hidden" type="button" title="Show side panels">Side</button> 192 <div id="mainWorkspaceRack" class="workspaceRack" aria-label="Workspace"> 193 <section id="hivesPanel" class="panel panelFill"> 194 <div class="panelHeader"> 195 <div class="panelTitle">Hives</div> 196 <div class="filters"> 197 <input id="filterAuthor" placeholder="Filter by author (@name)" /> 198 <input id="filterKeywords" placeholder="Filter by keywords (comma separated)" /> 199 <select id="sortBy"> 200 <option value="activity">Most recent activity</option> 201 <option value="popular">Most popular</option> 202 <option value="expiring">About to expire</option> 203 </select> 204 <button id="mobileHiveSearch" class="ghost smallBtn mobileOnlyHiveControl" type="button" title="Search hives">🔎</button> 205 <button id="mobileSortCycle" class="ghost smallBtn mobileOnlyHiveControl" type="button" title="Cycle sort">Recent</button> 206 <button id="clearFilter" type="button">Clear</button> 207 <button id="toggleComposer" class="mobileComposerToggle" type="button">New Hive</button> 208 </div> 209 </div> 210 <div class="uiHint">Use filters to narrow posts, then tap <b>Chat</b> on a hive card. Cards now show latest chat/typing. Shortcut: <b>-</b>/<b>=</b> cycles collections/views.</div> 211 <div class="hiveTabs" id="hiveTabs"> 212 <button type="button" data-hiveview="all" class="primary">All</button> 213 <button type="button" data-hiveview="starred" class="ghost">Starred</button> 214 <button type="button" data-hiveview="hidden" class="ghost">Hidden</button> 215 </div> 216 <div id="feed" class="feed"></div> 217 </section> 218 219 <section id="onboardingPanel" class="panel panelFill hidden"> 220 <div class="panelHeader"> 221 <div> 222 <div class="panelTitle">Onboarding</div> 223 <div class="small muted">About, rules, and first steps.</div> 224 </div> 225 </div> 226 <div class="panelBody onboardingPanelBody"> 227 <div class="uiHint">Read About and Rules first. If required, accept rules to unlock posting and chat.</div> 228 <div id="onboardingPanelBody" class="small muted"></div> 229 <div class="row" style="margin-top:10px;"> 230 <button id="onboardingPanelAccept" class="primary grow hidden" type="button">Accept and continue</button> 231 <button id="onboardingPanelRefresh" class="ghost" type="button">Refresh</button> 232 </div> 233 </div> 234 </section> 235 236 <section id="profileViewPanel" class="panel panelFill hidden"> 237 <div class="panelHeader"> 238 <div> 239 <div class="panelTitle" id="profileViewTitle">Profile</div> 240 <div id="profileViewMeta" class="small muted"></div> 241 </div> 242 <div class="row"> 243 <button id="profileBackBtn" class="ghost smallBtn" type="button">Back to hives</button> 244 <button id="profileEditToggleBtn" class="ghost smallBtn hidden" type="button">Edit profile</button> 245 </div> 246 </div> 247 <div class="uiHint">Tip: open someone from People, a hive card, or a chat message to view their profile here.</div> 248 <div id="profileViewBody" class="profileViewBody"> 249 <div id="profileCard" class="profileCard"></div> 250 </div> 251 <div id="profileEditPanel" class="profileEditPanel hidden"> 252 <label> 253 <span>Pronouns</span> 254 <input id="profilePronouns" maxlength="40" placeholder="she/her, they/them, etc" /> 255 </label> 256 <label> 257 <span>Theme song</span> 258 <div class="row"> 259 <input id="profileThemeSongUrl" placeholder="Upload audio for your theme song" readonly /> 260 <button id="profileThemeSongUploadBtn" class="ghost" type="button">Upload audio</button> 261 <button id="profileThemeSongClearBtn" class="ghost" type="button">Remove</button> 262 </div> 263 <audio id="profileThemeSongPreview" controls preload="none" class="hidden"></audio> 264 <input id="profileThemeSongFile" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 265 </label> 266 <div class="editorShell"> 267 <div class="toolbar" id="profileBioToolbar" role="toolbar" aria-label="Profile bio formatting"> 268 <button type="button" data-profilecmd="bold"><b>B</b></button> 269 <button type="button" data-profilecmd="italic"><i>I</i></button> 270 <button type="button" data-profilecmd="underline"><u>U</u></button> 271 <button type="button" data-profilecmd="strikeThrough"><s>S</s></button> 272 <span class="sep"></span> 273 <button type="button" data-profilecmd="insertUnorderedList">List</button> 274 <button type="button" data-profilecmd="insertOrderedList">1. List</button> 275 <button type="button" data-profilelink="1">Link</button> 276 <button type="button" data-profileimg="1">GIF/Image</button> 277 <button type="button" data-profileaudio="1">Audio</button> 278 <button type="button" data-profileemoji="1">Emoji</button> 279 <button type="button" data-profilecmd="removeFormat">Clear</button> 280 </div> 281 <div id="profileBioEditor" class="editor profileBioEditor" contenteditable="true" aria-label="Profile bio editor"></div> 282 <input id="profileBioImageFile" class="hidden" type="file" accept="image/*,.gif" /> 283 <input id="profileBioAudioFile" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 284 </div> 285 <div class="profileLinksHead"> 286 <span>Social links</span> 287 <button id="profileAddLinkBtn" class="ghost smallBtn" type="button">Add link</button> 288 </div> 289 <div id="profileLinksEditor" class="profileLinksEditor"></div> 290 <div class="row"> 291 <button id="profileSaveBtn" class="primary" type="button">Save profile</button> 292 <button id="profileCancelBtn" class="ghost" type="button">Cancel</button> 293 </div> 294 </div> 295 </section> 296 297 <section id="pollinatePanel" class="panel composerCollapsed"> 298 <div class="panelHeader"> 299 <div class="panelTitle">Create Hive</div> 300 <button id="toggleComposerInline" class="ghost smallBtn" type="button">Hide</button> 301 </div> 302 <div class="uiHint">Keep titles short and clear. Add keywords so others can find your hive faster.</div> 303 <form id="newPostForm" class="form"> 304 <label> 305 <span>Title (max 96 chars)</span> 306 <input id="postTitle" maxlength="96" placeholder="Short title for this hive" /> 307 </label> 308 <div class="editorShell"> 309 <div class="toolbar" role="toolbar" aria-label="Formatting"> 310 <button type="button" data-cmd="bold"><b>B</b></button> 311 <button type="button" data-cmd="italic"><i>I</i></button> 312 <button type="button" data-cmd="underline"><u>U</u></button> 313 <button type="button" data-cmd="strikeThrough"><s>S</s></button> 314 <span class="sep"></span> 315 <button type="button" data-cmd="insertUnorderedList">List</button> 316 <button type="button" data-cmd="insertOrderedList">1. List</button> 317 <button type="button" data-link="1">Link</button> 318 <button type="button" data-postimg="1">GIF/Image</button> 319 <button type="button" data-postaudio="1">Audio</button> 320 <button type="button" data-postemoji="1">Emoji</button> 321 <button type="button" data-cmd="removeFormat">Clear</button> 322 </div> 323 <div id="editor" class="editor" contenteditable="true" aria-label="Post editor"></div> 324 <input id="postImage" class="hidden" type="file" accept="image/*,.gif" /> 325 <input id="postAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 326 </div> 327 328 <div class="row"> 329 <label class="grow"> 330 <span>Collection</span> 331 <select id="postCollection"></select> 332 </label> 333 <label class="grow"> 334 <span>Keywords (comma separated, up to 6)</span> 335 <input id="keywords" placeholder="hive, code, idea" /> 336 </label> 337 <label> 338 <span>TTL (minutes)</span> 339 <input id="ttlMinutes" type="number" min="1" max="2880" value="60" /> 340 </label> 341 </div> 342 343 <button class="primary" type="submit">Send</button> 344 <div class="row"> 345 <label class="grow"> 346 <span>Protected</span> 347 <input id="isProtected" type="checkbox" /> 348 </label> 349 <label class="grow"> 350 <span>Walkie Talkie</span> 351 <input id="isWalkie" type="checkbox" /> 352 </label> 353 <label class="grow"> 354 <span>Post password</span> 355 <input id="postPassword" type="password" autocomplete="new-password" placeholder="Required if protected" disabled /> 356 </label> 357 </div> 358 </form> 359 </section> 360 </div> 361 <div id="mainSideRack" class="sideRack" aria-label="Side panels"></div> 362 </div> 363 </main> 364 365 <div id="chatResizeHandle" class="panelResizeHandle chatResizeHandle" title="Drag to resize chat" aria-hidden="true"></div> 366 367 <aside class="chat"> 368 <div class="panelHeader"> 369 <div> 370 <div class="panelTitle" id="chatTitle">Chat</div> 371 <div id="chatMeta" class="small muted">Select a post to chat.</div> 372 </div> 373 <div class="row chatHeaderActions"> 374 <select id="chatContextSelect" class="chatContextSelect" aria-label="Open chats"></select> 375 <button id="chatBackToList" class="ghost smallBtn hidden" type="button">Back</button> 376 </div> 377 </div> 378 <div class="uiHint">Select a hive chat or DM first, then type your message and press Send. Shortcut in Chat: <b>-</b>/<b>=</b> cycles chat list entries.</div> 379 <div id="chatMessages" class="chatMessages"></div> 380 <div id="typingIndicator" class="typingIndicator small muted"></div> 381 <div id="walkieBar" class="walkieBar hidden" aria-label="Walkie talkie controls"> 382 <button id="walkieRecordBtn" class="primary" type="button">Hold to talk</button> 383 <div class="walkieHint small muted"> 384 Hold <span class="tag">~</span> or press-and-hold this button to record. Release to send. 385 </div> 386 <div id="walkieStatus" class="small muted"></div> 387 </div> 388 <form id="chatForm" class="chatForm"> 389 <div id="chatReplyBanner" class="chatReplyBanner hidden"> 390 <div class="small"> 391 Replying to <span id="chatReplyWho"></span> 392 <span id="chatReplyText" class="muted"></span> 393 </div> 394 <button id="chatReplyCancel" class="ghost smallBtn" type="button">Cancel</button> 395 </div> 396 <div class="chatComposer"> 397 <div class="toolbar" role="toolbar" aria-label="Chat formatting"> 398 <button type="button" data-chatcmd="bold"><b>B</b></button> 399 <button type="button" data-chatcmd="italic"><i>I</i></button> 400 <button type="button" data-chatcmd="underline"><u>U</u></button> 401 <button type="button" data-chatcmd="strikeThrough"><s>S</s></button> 402 <span class="sep"></span> 403 <button type="button" data-chatcmd="insertUnorderedList">List</button> 404 <button type="button" data-chatcmd="insertOrderedList">1. List</button> 405 <button type="button" data-chatlink="1">Link</button> 406 <button type="button" data-chatimg="1">GIF/Image</button> 407 <button type="button" data-chataudio="1">Audio</button> 408 <button type="button" data-chatemoji="1">Emoji</button> 409 <button type="button" data-chatcmd="removeFormat">Clear</button> 410 <label id="chatModToggleWrap" class="checkRow chatModToggle hidden" title="Send as moderator/system message (left rail)"> 411 <span>Mod</span> 412 <input id="chatModToggle" type="checkbox" /> 413 </label> 414 </div> 415 <div id="chatEditor" class="editor chatEditor" contenteditable="true" aria-label="Chat editor"></div> 416 <div id="mentionMenu" class="mentionMenu hidden" role="listbox" aria-label="Mention suggestions"></div> 417 <input id="chatImage" class="hidden" type="file" accept="image/*" /> 418 <input id="chatAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 419 </div> 420 <div class="uiHint">Use Link, GIF/Image, and Audio to attach media quickly.</div> 421 <button class="primary" type="submit">Send</button> 422 </form> 423 </aside> 424 425 <div id="mainResizeHandle" class="panelResizeHandle mainResizeHandle" title="Drag to resize moderation panel" aria-hidden="true"></div> 426 427 <aside id="modPanel" class="moderation hidden"> 428 <div class="panelHeader"> 429 <div class="panelTitle">Moderation</div> 430 </div> 431 <div class="uiHint">Use tabs to review reports, manage users/hives, configure server settings, and publish onboarding content.</div> 432 <div class="modTabs"> 433 <button type="button" class="ghost" data-modtab="reports">Reports</button> 434 <button type="button" class="ghost" data-modtab="users">Users</button> 435 <button type="button" class="ghost" data-modtab="hives">Hives</button> 436 <button type="button" class="ghost" data-modtab="server">Server</button> 437 <button type="button" class="ghost" data-modtab="onboarding">Onboarding</button> 438 <button type="button" class="ghost" data-modtab="log">Log</button> 439 </div> 440 <div class="modFilters"> 441 <select id="modReportStatus"> 442 <option value="open">Open reports</option> 443 <option value="resolved">Resolved reports</option> 444 <option value="dismissed">Dismissed reports</option> 445 <option value="">All reports</option> 446 </select> 447 <button id="modRefresh" class="ghost" type="button">Refresh</button> 448 </div> 449 <div id="modBody" class="modBody small"></div> 450 </aside> 451 452 <div id="mobileScreenHost" class="mobileScreenHost" aria-label="Mobile screen host"></div> 453 </div> 454 <aside id="peopleDrawer" class="peopleDrawer hidden"> 455 <div id="peopleResizeHandle" class="peopleResizeHandle" title="Drag to resize people panel" aria-hidden="true"></div> 456 <div class="panelHeader"> 457 <div class="panelTitle">People</div> 458 <button id="closePeople" class="ghost smallBtn" type="button">Close</button> 459 </div> 460 <div class="peopleTabs"> 461 <button id="peopleMembersTab" class="primary" type="button">Members</button> 462 <button id="peopleDmsTab" class="ghost" type="button">DMs</button> 463 </div> 464 <div id="peopleMembersView"> 465 <div class="uiHint">Members list lets you open profiles and start DMs. Mods can also send <b>Mod DM</b> from member/profile actions.</div> 466 <div class="peopleFilters"> 467 <input id="peopleSearch" placeholder="Search members" /> 468 </div> 469 <div id="peopleList" class="peopleList small"></div> 470 </div> 471 <div id="peopleDmsView" class="peopleDms small hidden"> 472 <div class="uiHint">DM requests must be accepted before chat opens. Active threads show <b>Open</b>, and mods get a <b>Mod DM</b> action.</div> 473 DMs coming soon. 474 </div> 475 </aside> 476 <div id="mobileNav" class="mobileNav hidden" aria-label="Mobile navigation"> 477 <button type="button" data-mobilescreen="account">Account</button> 478 <button type="button" data-mobilescreen="hives">Hives</button> 479 <button type="button" data-mobilescreen="chat">Chat</button> 480 <button id="mobileFourthBtn" type="button" data-mobilescreen="people">People</button> 481 <button type="button" data-mobilescreen="profile">Profile</button> 482 <button type="button" data-mobilescreen="more">More</button> 483 </div> 484 485 <div id="mobileMoreSheet" class="mobileMoreSheet hidden" role="dialog" aria-modal="true" aria-label="More"> 486 <div class="mobileMoreBackdrop" data-mobilemoreclose="1"></div> 487 <div class="mobileMoreCard panel"> 488 <div class="panelHeader"> 489 <div class="panelTitle">More</div> 490 <div class="row"> 491 <button id="mobileMoreClose" class="ghost smallBtn" type="button">Close</button> 492 </div> 493 </div> 494 <div class="mobileMoreBody"> 495 <input id="mobileMoreSearch" placeholder="Search…" /> 496 <div id="mobileMoreList" class="mobileMoreList"></div> 497 </div> 498 </div> 499 </div> 500 501 <div id="editModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Edit content"> 502 <div class="modalBackdrop" data-modalclose="1"></div> 503 <div class="modalCard panel"> 504 <div class="panelHeader"> 505 <div class="panelTitle" id="editModalTitle">Edit</div> 506 <div class="row"> 507 <button id="editModalClose" class="ghost smallBtn" type="button">Close</button> 508 </div> 509 </div> 510 <div class="modalBody"> 511 <label id="editModalPostTitleRow" class="hidden"> 512 <span>Title</span> 513 <input id="editModalPostTitle" maxlength="96" /> 514 </label> 515 516 <div id="editModalPostMeta" class="hidden editMetaGrid" aria-label="Post settings"> 517 <label> 518 <span>Keywords</span> 519 <input id="editModalKeywords" maxlength="120" placeholder="comma separated (max 6)" /> 520 </label> 521 <label> 522 <span>Collection</span> 523 <select id="editModalCollection"></select> 524 </label> 525 <label class="checkRow"> 526 <span>Password protected</span> 527 <input id="editModalProtected" type="checkbox" /> 528 </label> 529 <label class="checkRow"> 530 <span>Walkie-only</span> 531 <input id="editModalWalkie" type="checkbox" /> 532 </label> 533 <label id="editModalPasswordRow" class="hidden"> 534 <span>Password</span> 535 <input 536 id="editModalPassword" 537 type="password" 538 minlength="4" 539 maxlength="80" 540 placeholder="Leave blank to keep current" 541 autocomplete="new-password" 542 /> 543 </label> 544 </div> 545 546 <div class="editorShell"> 547 <div class="toolbar" id="editModalToolbar" role="toolbar" aria-label="Edit formatting"> 548 <button type="button" data-editcmd="bold"><b>B</b></button> 549 <button type="button" data-editcmd="italic"><i>I</i></button> 550 <button type="button" data-editcmd="underline"><u>U</u></button> 551 <button type="button" data-editcmd="strikeThrough"><s>S</s></button> 552 <span class="sep"></span> 553 <button type="button" data-editcmd="insertUnorderedList">List</button> 554 <button type="button" data-editcmd="insertOrderedList">1. List</button> 555 <button type="button" data-editlink="1">Link</button> 556 <button type="button" data-editimg="1">GIF/Image</button> 557 <button type="button" data-editaudio="1">Audio</button> 558 <button type="button" data-editemoji="1">Emoji</button> 559 <button type="button" data-editcmd="removeFormat">Clear</button> 560 </div> 561 <div id="editModalEditor" class="editor editModalEditor" contenteditable="true" aria-label="Edit content"></div> 562 <input id="editModalImage" class="hidden" type="file" accept="image/*,.gif" /> 563 <input id="editModalAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 564 </div> 565 566 <div class="row modalActions"> 567 <button id="editModalSave" class="primary" type="button">Save</button> 568 <button id="editModalCancel" class="ghost" type="button">Cancel</button> 569 </div> 570 <div id="editModalStatus" class="small muted"></div> 571 </div> 572 </div> 573 </div> 574 575 <div id="modModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Moderation"> 576 <div class="modalBackdrop" data-modmodalclose="1"></div> 577 <div class="modalCard panel"> 578 <div class="panelHeader"> 579 <div class="panelTitle" id="modModalTitle">Moderation</div> 580 <div class="row"> 581 <button id="modModalClose" class="ghost smallBtn" type="button">Close</button> 582 </div> 583 </div> 584 <div class="modalBody" id="modModalBody"></div> 585 <div class="row modalActions"> 586 <button id="modModalPrimary" class="primary" type="button">Save</button> 587 <button id="modModalCancel" class="ghost" type="button">Cancel</button> 588 </div> 589 <div id="modModalStatus" class="small muted" style="padding:0 12px 12px"></div> 590 </div> 591 </div> 592 593 <div id="mediaModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Media preview"> 594 <div class="modalBackdrop" data-mediamodalclose="1"></div> 595 <div class="modalCard panel"> 596 <div class="panelHeader"> 597 <div class="panelTitle" id="mediaModalTitle">Media</div> 598 <div class="row"> 599 <button id="mediaModalClose" class="ghost smallBtn" type="button">Close</button> 600 </div> 601 </div> 602 <div class="modalBody" id="mediaModalBody"> 603 <img id="mediaModalImg" alt="Expanded media" /> 604 <div class="row modalActions" style="justify-content:flex-start"> 605 <a id="mediaModalOpenLink" class="ghost" href="#" target="_blank" rel="noreferrer">Open original</a> 606 <button id="mediaModalCopyLink" class="ghost" type="button">Copy link</button> 607 </div> 608 <div id="mediaModalStatus" class="small muted"></div> 609 </div> 610 </div> 611 </div> 612 613 <div id="shortcutHelpModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Keyboard shortcuts"> 614 <div class="modalBackdrop" data-shortcutclose="1"></div> 615 <div class="modalCard panel"> 616 <div class="panelHeader"> 617 <div class="panelTitle">Keyboard Shortcuts</div> 618 <div class="row"> 619 <button id="shortcutHelpClose" class="ghost smallBtn" type="button">Close</button> 620 </div> 621 </div> 622 <div class="modalBody shortcutHelpBody"> 623 <div><span class="tag">[ / ]</span> Cycle layout presets</div> 624 <div><span class="tag">- / =</span> Cycle hives or chats in active panel</div> 625 <div><span class="tag">?</span> Open this shortcut help</div> 626 <div><span class="tag">`</span> Hold for walkie talkie (when enabled)</div> 627 <div><span class="tag">Esc</span> Close menus/modals</div> 628 </div> 629 </div> 630 </div> 631 632 <div id="dockHotbar" class="dockHotbar hidden" aria-label="Docked panels"></div> 633 <script src="/app.js?v=152"></script> 634 </body> 635 </html>