1<template> 2 <div> 3 4 <div v-if="source.type === 'vsyncEvent'" class="vsync"> 5 <div class="vsync-dot" /> 6 <md-tooltip md-direction="left"> 7 VSync 8 </md-tooltip> 9 </div> 10 11 <div v-else 12 class="entry" 13 :class="{ 14 inactive: source.timestamp > currentTimestamp, 15 selected: isSelected 16 }" 17 @click="onClick(source)" 18 > 19 <div class="time-column"> 20 <a @click="e => setTimelineTime(e, source.timestamp)" class="time-link"> 21 {{source.time}} 22 </a> 23 <div 24 class="new-badge" 25 :style="{visibility: source.new ? 'visible' : 'hidden'} " 26 > 27 New 28 </div> 29 </div> 30 <div class="type-column">{{transactionTypeOf(source)}}</div> 31 <div class="affected-surfaces-column"> 32 <span 33 v-for="(surface, index) in sufacesAffectedBy(source)" 34 v-bind:key="surface.id" 35 > 36 <!-- eslint-disable-next-line max-len --> 37 <span v-if="surface.name" class="surface-name">{{ surface.name }}</span> 38 <span class="surface-id"> 39 <!-- eslint-disable-next-line max-len --> 40 <span v-if="surface.name">(</span>{{surface.id}}<span v-if="surface.name">)</span> 41 </span> 42 <!-- eslint-disable-next-line max-len --> 43 <span v-if="index + 1 < sufacesAffectedBy(source).length">, </span> 44 </span> 45 </div> 46 <div class="extra-info-column"> 47 <span v-if="source.identifier"> 48 <!-- eslint-disable-next-line max-len --> 49 Tx Id: <span class="light">{{ prettifyTransactionId(source.identifier) }}</span><br/> 50 </span> 51 <span v-if="source.origin"> 52 PID: <span class="light">{{ source.origin.pid }}</span><br/> 53 UID: <span class="light">{{ source.origin.uid }}</span><br/> 54 </span> 55 </div> 56 </div> 57 58 </div> 59</template> 60 61<script> 62export default { 63 name: 'transaction-entry', 64 props: { 65 index: { 66 type: Number, 67 }, 68 source: { 69 type: Object, 70 default() { 71 return {}; 72 }, 73 }, 74 onClick: { 75 type: Function, 76 }, 77 selectedTransaction: { 78 type: Object, 79 }, 80 transactionsTrace: { 81 type: Object, 82 }, 83 prettifyTransactionId: { 84 type: Function, 85 }, 86 }, 87 computed: { 88 currentTimestamp() { 89 return this.$store.state.currentTimestamp; 90 }, 91 isSelected() { 92 return this.source === this.selectedTransaction; 93 }, 94 hasOverrideChangeDueToMerge() { 95 const transaction = this.source; 96 97 if (!transaction.identifier) { 98 return; 99 } 100 101 // console.log('transaction', transaction.identifier); 102 103 // const history = this.transactionsTrace.transactionHistory; 104 105 // const allTransactionsMergedInto = history 106 // .allTransactionsMergedInto(transaction.identifier); 107 // console.log('All merges', allTransactionsMergedInto); 108 109 // console.log('Direct merges', 110 // history.allDirectMergesInto(transaction.identifier)); 111 112 113 return true; 114 }, 115 }, 116 methods: { 117 setTimelineTime(e, timestamp) { 118 e.preventDefault(); 119 e.stopPropagation(); 120 this.$store.dispatch('updateTimelineTime', timestamp); 121 }, 122 transactionTypeOf(transaction) { 123 if (transaction.type !== 'transaction') { 124 return transaction.type; 125 } 126 127 if (transaction.transactions.length === 0) { 128 return 'Empty Transaction'; 129 } 130 131 const types = new Set(); 132 transaction.transactions.forEach((t) => types.add(t.type)); 133 134 return Array.from(types).join(', '); 135 }, 136 sufacesAffectedBy(transaction) { 137 if (transaction.type !== 'transaction') { 138 // TODO (b/162402459): Shorten layer name 139 return [{name: transaction.layerName, id: transaction.obj.id}]; 140 } 141 142 const surfaceIds = new Set(); 143 const affectedSurfaces = []; 144 for (const transaction of transaction.transactions) { 145 const id = transaction.obj.id; 146 if (!surfaceIds.has(id)) { 147 surfaceIds.add(id); 148 affectedSurfaces.push({name: transaction.layerName, id}); 149 } 150 } 151 152 return affectedSurfaces; 153 }, 154 }, 155}; 156</script> 157<style scoped> 158.time-column { 159 display: inline-flex; 160 width: 13em; 161} 162 163.time-column .time-link { 164 width: 9em; 165} 166 167.type-column { 168 width: 12em; 169} 170 171.origin-column { 172 width: 9em; 173} 174 175.affected-surfaces-column { 176 word-wrap: break-word; 177 width: 30em; 178} 179 180.extra-info-column { 181 width: 20em; 182} 183 184.entry { 185 display: inline-flex; 186 cursor: pointer; 187} 188 189.entry > div { 190 padding: 6px 10px; 191 border-bottom: 1px solid #f1f1f1; 192} 193 194.entry.selected { 195 background-color: #365179; 196 color: white; 197} 198 199.entry.selected a { 200 color: white; 201} 202 203.entry:not(.selected):hover { 204 background: #f1f1f1; 205} 206 207a { 208 cursor: pointer; 209} 210 211.inactive { 212 color: gray; 213} 214 215.inactive a { 216 color: gray; 217} 218 219.new-badge { 220 display: inline-block; 221 background: rgb(84, 139, 247); 222 border-radius: 3px; 223 color: white; 224 padding: 0 5px; 225 margin-left: 5px; 226 font-size: 10px; 227} 228 229.affected-surfaces-column .surface-id { 230 color: #999999 231} 232 233.inactive .affected-surfaces-column .surface-id { 234 color: #b4b4b4 235} 236 237.light { 238 color: #999999 239} 240 241.inactive .light { 242 color: #b4b4b4 243} 244 245.vsync { 246 position: relative; 247} 248 249.vsync-dot:before { 250 content: ""; 251 position: absolute; 252 left: 0; 253 top: -5px; 254 height: 10px; 255 width: 10px; 256 background-color: rgb(170, 65, 255); 257 border-radius: 50%; 258 display: inline-block; 259} 260 261.vsync-dot:after { 262 content: ""; 263 position: absolute; 264 left: 0; 265 top: 0; 266 height: 1px; 267 width: 100%; 268 background-color: rgb(170, 65, 255); 269 display: inline-block; 270} 271</style> 272