|
19 | 19 | :enableSecondaryAction="calculateShowSecondaryAction" |
20 | 20 | :sizeClass="tw`h-[28px]`" |
21 | 21 | secondaryActionIcon="edit2" |
| 22 | + :hoverBorder="false" |
| 23 | + :class="youHaveNewChangeSet && 'new-change-set-alert'" |
22 | 24 | @select="onSelectChangeSet" |
23 | 25 | @secondaryAction="openRenameModal" |
| 26 | + @click="clearAnimation" |
24 | 27 | > |
25 | 28 | <template #afterOptions> |
26 | 29 | <DropdownMenuItem |
@@ -158,6 +161,27 @@ const ctx = useContext(); |
158 | 161 |
|
159 | 162 | const { openChangeSets, changeSet } = useChangeSets(computed(() => ctx)); |
160 | 163 |
|
| 164 | +// when change set list updates with new data |
| 165 | +// are any of the new CS from me (or my AI agent?) |
| 166 | +const youHaveNewChangeSet = ref(false); |
| 167 | +watch([openChangeSets, ctx.changeSetId], ([newCS, _], [oldCS, _c]) => { |
| 168 | + const myOld = new Set( |
| 169 | + oldCS.filter((c) => c.createdByUserId === ctx.user?.pk).map((c) => c.id), |
| 170 | + ); |
| 171 | + const myNew = new Set( |
| 172 | + newCS.filter((c) => c.createdByUserId === ctx.user?.pk).map((c) => c.id), |
| 173 | + ); |
| 174 | + const diff = [...myNew].filter((id) => !myOld.has(id)); |
| 175 | + if (diff.length > 1) youHaveNewChangeSet.value = true; |
| 176 | + else if (diff.length === 0) youHaveNewChangeSet.value = false; |
| 177 | + else if (diff[0] && diff[0] !== ctx.changeSetId.value) |
| 178 | + youHaveNewChangeSet.value = true; |
| 179 | +}); |
| 180 | +
|
| 181 | +const clearAnimation = () => { |
| 182 | + youHaveNewChangeSet.value = false; |
| 183 | +}; |
| 184 | +
|
161 | 185 | const dropdownMenuRef = ref<InstanceType<typeof DropdownMenuButton>>(); |
162 | 186 |
|
163 | 187 | const changeSetDropdownOptions = computed(() => [ |
@@ -297,3 +321,60 @@ function openCreateModal() { |
297 | 321 |
|
298 | 322 | defineExpose({ openCreateModal }); |
299 | 323 | </script> |
| 324 | + |
| 325 | +<style scoped> |
| 326 | +/* |
| 327 | + Taken right from the lobby with minimal alterations (jobelenus) |
| 328 | + Note*(victor): These styles exist to power the spinning border on the lobby terminal */ |
| 329 | +
|
| 330 | +/* |
| 331 | + We need to declare --angle as a property with an initial value so that keyframes can correctly interpolate it |
| 332 | + If we don't, the keyframes below would only blip between the declared states |
| 333 | + */ |
| 334 | +@property --angle { |
| 335 | + syntax: "<angle>"; |
| 336 | + inherits: false; |
| 337 | + initial-value: 0deg; |
| 338 | +} |
| 339 | +@keyframes borderRotate { |
| 340 | + 100% { |
| 341 | + --angle: 360deg; |
| 342 | + } |
| 343 | +} |
| 344 | +
|
| 345 | +@keyframes pulse { |
| 346 | + 0%, |
| 347 | + 35%, |
| 348 | + 70%, |
| 349 | + 100% { |
| 350 | + background-color: #000; |
| 351 | + } |
| 352 | + 50% { |
| 353 | + background-color: rgba(134, 239, 172, 0.25); /* success-300 */ |
| 354 | + } |
| 355 | +} |
| 356 | +
|
| 357 | +.new-change-set-alert { |
| 358 | + border: 1px solid; |
| 359 | + /* |
| 360 | + use a spinning conic-gradient as the border image. It looks like this: https://www.geeksforgeeks.org/css/css-conic-gradient-function/ |
| 361 | + But "masked" through the border |
| 362 | + */ |
| 363 | + border-image: conic-gradient( |
| 364 | + from var(--angle), |
| 365 | + #333, |
| 366 | + #333 0.65turn, |
| 367 | + #86efac 1turn /* success-300 */ |
| 368 | + ) |
| 369 | + 1; |
| 370 | + /* |
| 371 | + Enable the animation. Although the rotation is linear, since it's showing through a rectangular shape, |
| 372 | + both the moving speed and the trail length vary depending on the position. We could fudge the border speed by |
| 373 | + compensating on the keyframes vs the "radius" of each border position but this wouldn't fix the trail so |
| 374 | + we chose to use this as is. |
| 375 | + */ |
| 376 | + animation: borderRotate 1500ms linear infinite forwards, pulse 5s infinite; |
| 377 | + /* border-radius does not interact with border images, so this all black mask that takes the size of the div makes it round again */ |
| 378 | + mask-image: radial-gradient(#000 0, #000 0); |
| 379 | +} |
| 380 | +</style> |
0 commit comments