samples.template.mjs
1 import { html } from "uhtml/reactive" 2 3 function copyToClipboard(val) { 4 navigator.clipboard.writeText(val) 5 } 6 7 function sortSamples(a,b) { 8 if (a.status == b.status) return a.elapsed - b.elapsed 9 if (a.status == "ONGOING" && b.status != "ONGOING") return -1 10 if (a.status != "ONGOING" && b.status == "ONGOING") return 1 11 if (a.status == "CANCEL" && b.status == "COMPLETE") return 1 12 if (a.status == "COMPLETE" && b.status == "CANCEL") return -1 13 } 14 15 const SamplesTable = (rows) => { 16 return html` 17 <div class="table support-samples"> 18 <div class="table-header"> 19 <p class="table-value sample-channel">Channel</p> 20 <p class="table-value sample-elapsed">Elapsed</p> 21 <p class="table-value sample-viewers">Viewers</p> 22 <p class="table-value sample-chatters">Chatters</p> 23 <p class="table-value sample-messages">Messages</p> 24 <p class="table-value sample-questions">Questions</p> 25 <p class="table-value sample-bits">Bits</p> 26 <p class="table-value sample-status">Status</p> 27 </div> 28 ${rows.map(s => SampleRow(s))} 29 </div> 30 ` 31 } 32 33 const SampleRow = (sample) => { 34 const channelLink = `https://twitch.tv/${sample.userName}` 35 36 let addViewers 37 38 if (sample.add.viewers) { 39 addViewers = sample.add.viewers > 0 ? `+${sample.add.viewers}`:`${sample.add.viewers}` 40 } 41 42 addChatters = sample.add.chatters ? `+${sample.add.chatters}` : "" 43 addMessages = sample.add.messages ? `+${sample.add.messages}` : "" 44 addQuestions = sample.add.questions ? `+${sample.add.questions}` : "" 45 addBits = sample.add.bits ? `+${sample.add.bits}` : "" 46 47 showViewersAdd = addViewers ? "show" : "" 48 showChattersAdd = addChatters ? "show" : "" 49 showMessagesAdd = addMessages ? "show" : "" 50 showQuestionsAdd = addQuestions ? "show" : "" 51 showBitsAdd = addBits ? "show" : "" 52 53 const statusClass = `sample-status-${sample.status.toLowerCase()}` 54 55 return html` 56 <div class="table-row"> 57 <div class="table-value sample-channel table-value-double"> 58 <span class="sample-channel-name"> 59 <a href="${channelLink}">${sample.userName}</a> 60 </span> 61 <span class="sample-channel-id table-value-button" onclick="${() => { copyToClipboard(sample.channelId) }}">${sample.channelId}</span> 62 </div> 63 <p class="table-value sample-elapsed">${sample.elapsed}m</p> 64 <p class="table-value sample-viewers sample-add table-value-double"> 65 <span>${sample.viewers}</span> 66 <span class="${showViewersAdd}">${addViewers}</span> 67 </p> 68 <p class="table-value sample-chatters sample-add table-value-double"> 69 <span>${sample.chatters}</span> 70 <span class="${showChattersAdd}">${addChatters}</span> 71 </p> 72 <p class="table-value sample-messages sample-add table-value-double"> 73 <span>${sample.messages}</span> 74 <span class="${showMessagesAdd}">${addMessages}</span> 75 </p> 76 <p class="table-value sample-questions sample-add table-value-double"> 77 <span>${sample.questions}</span> 78 <span class="${showQuestionsAdd}">${addQuestions}</span> 79 </p> 80 <p class="table-value sample-bits sample-add table-value-double"> 81 <span>${sample.bits}</span> 82 <span class="${showBitsAdd}">${addBits}</span> 83 </p> 84 <p class="table-value sample-status"> 85 <span class="${statusClass}">${sample.status}</span> 86 </p> 87 </div> 88 ` 89 } 90 91 export const SamplesView = (state) => { 92 const { samples } = state 93 94 let rows = Array.from(samples.value.values()) 95 rows.sort(sortSamples) 96 97 return html` 98 <div class="samples"> 99 <h3 class="activity-headline">Samples</h3> 100 ${SamplesTable(rows)} 101 </div>` 102 } 103