<html data-bs-theme="dark"> <head> <title>Event-Feed</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/bootstrap@5.3/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5/css/all.min.css"> <style> [v-cloak] { display: none; } .border-event { border-left-width: 5px !important; border-left-style: solid !important; border-left-color: #9147ff; } .border-event.event-bits { border-left-color: #5cffbe !important; } .border-event.event-channelpoint { border-left-color: #ffd37a !important; } .border-event.event-follow { border-left-color: #ff38db !important; } .border-event.event-raid { border-left-color: #ebeb00 !important; } .border-event.event-streamOffline { border-left-color: rgb(var(--bs-danger-rgb)) !important; } .border-event.event-subs { border-left-color: #1f69ff !important; } .m50 { max-height: 40vh; overflow-y: auto; } .premono { font-family: monospace; font-size: 0.9em; white-space: pre-wrap; } </style> </head> <body> <div id="app" v-cloak> <div class="container-fluid py-3"> <div class="row"> <div class="col"> <!-- Stream-Summary --> <div class="card mb-3"> <div class="card-body"> <div class="d-flex align-items-center justify-content-between"> <span v-for="item in sortedStats" class="me-2 d-inline-flex align-items-center" :key="item.key" > <i :class="`fa-fw ${item.icon}`"></i> <span class="badge rounded-pill text-bg-primary ms-1"> {{ item.value }} </span> </span> </div> </div> </div> <!-- Event-List --> <div class="card"> <div class="card-header d-flex justify-content-between align-items-center"> Recent events <div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm"> <button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" > <i class="fas fa-filter fa-fw me-1"></i> Filters ({{ filterCount }}) </button> <ul class="dropdown-menu dropdown-menu-end"> <li v-for="(filter, filterKey) in filters" :key="filterKey" > <a :class="{'dropdown-item': true, 'active': filter.visible}" href="#" @click.prevent="toggleFilterVisibility(filterKey)" > {{ filter.name }} </a> </li> </ul> </div> <button class="btn btn-secondary" @click="markRead" > <i class="fas fa-eye fa-fw me-1"></i> Mark read </button> </div> </div> <div class="list-group list-group-flush"> <!-- Active Hypetrain pin --> <div class="list-group-item" v-if="hypetrain.active"> <div class="d-flex w-100 align-items-center"> <h5 class="mb-0"> <i :class="`fas fa-train fa-fw me-2`"></i> Hypetrain in progress towards Level {{ hypetrain.level }}… </h5> </div> <div class="progress my-3"> <div class="progress-bar progress-bar-striped" :style="`width: ${(hypetrain.progress * 100).toFixed(2)}%`" ></div> </div> </div> <!-- Event-Item --> <div :class="eventClass(event)" v-for="event in recentEvents" :key="event.time.getTime()" > <div class="d-flex w-100 align-items-center"> <h5 class="mb-0 me-auto"><i :class="`${event.icon} fa-fw me-2`"></i> {{ event.title }}</h5> <button class="btn btn-sm me-1" v-if="event.hasReplay" @click="repeatEvent(event.eventId)" title="Re-Play Event" > <i class="fas fa-share fa-fw"></i> </button> <small :title="timeDisplay(event.time)"> {{ timeSince(event.time) }} </small> </div> <div class="d-flex my-1 w-100 justify-content-between align-items-start premono" v-if="event.text"> {{ event.text }} </div> <p class="mb-1" v-if="resolveSubtext(event.subtext)"> <small> <span class="premono">{{ resolveSubtext(event.subtext) }}</span> </small> </p> </div> </div> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3/dist/js/bootstrap.bundle.min.js"></script> <script src="eventfeed.js" type="module"></script> </body> </html>