Compare commits

..

2 commits

Author SHA1 Message Date
d69c37089e Fix bug where item preview loading indicator sometimes doesn't delay
The loading indicator *should* fade in after two seconds, to avoid a
flash of a loading indicator when the page loads quickly - but in some
circumstances it wouldn't delay:

1. Visit an item page. (It delays correctly the first time!)
2. Click "Infinite Closet", then click a link to another item page.
3. The loading indicator appears immediately, because this time the
   web component JS is already loaded, so the `outfit-layer` elements
   enter `:state(loading)` *immediately*. The element starts at
   `opacity: 1`, and the delay doesn't matter, because it was never at
   anything else.

In this change, we have the `outfit-viewer` web component take on a
`:state(after-first-frame)`, after a `setTimeout(0)` resolves. That
enables the loading state CSS to *never* apply on the first frame, but
then sometimes kick in on the *second* frame, so that the element is
correctly perceived as "transitioning" from hidden to visible, and the
two-second delay will apply.
2024-09-06 12:13:10 -07:00
5001a50a60 Add announcement about new item page, replacing the hidden Neopass one 2024-09-06 11:47:17 -07:00
9 changed files with 41 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View file

@ -21,6 +21,10 @@ class OutfitViewer extends HTMLElement {
this.#setIsPlaying(playPauseToggle.checked);
this.#setIsPlayingCookie(playPauseToggle.checked);
});
// Tell the CSS our first frame has rendered, which we use for loading
// state transitions.
this.#internals.states.add("after-first-frame");
}
#setIsPlaying(isPlaying) {

View file

@ -135,15 +135,24 @@ body.items-show
margin-bottom: .5em
display: none
// When loading, fade in the loading spinner after a brief delay. (We only
// apply the delay here, because fading *out* on load should be instant.)
// We are loading when the <turbo-frame> is busy, or when at least one layer
// When loading, fade in the loading spinner after a brief delay. We are
// loading when the <turbo-frame> is busy, or when at least one layer
// is loading.
//
// We only apply the delay here, not on the base styles, because fading
// *out* on load should be instant. We also wait for the outfit-viewer to
// execute a `setTimeout(0)`, to make sure we always *start* in the
// non-loading state. This is because it's sometimes possible for the page to
// start with the web component already in `state(loading)`, and we need to
// make sure we *start* in *non-loading* state for the transition delay to
// happen. (This can happen when you Turbo-navigate between multiple items.)
#item-preview[busy] outfit-viewer, outfit-viewer:has(outfit-layer:state(loading))
cursor: wait
.loading-indicator
opacity: 1
transition-delay: 2s
&:state(after-first-frame)
.loading-indicator
opacity: 1
transition-delay: 2s
#item-preview:has(outfit-layer:state(error))
outfit-viewer

View file

@ -7,9 +7,8 @@ body.outfits-new
#pet-not-found
display: none
.neopass-announcement
border: 1px solid #cd8400
color: #764a00
.announcement
border: 1px solid $module-border-color
padding: .5em
display: grid
grid-template-areas: "thumbnail content"
@ -24,9 +23,6 @@ body.outfits-new
p:last-of-type
margin-bottom: 0
a
color: #be7a00
#outfit-forms
+clearfix
+module

View file

@ -1,7 +1,7 @@
module OutfitsHelper
LAST_DAY_OF_NEOPASS_ANNOUNCEMENT = Date.parse("2024-05-05")
def show_neopass_announcement?
Date.today <= LAST_DAY_OF_NEOPASS_ANNOUNCEMENT
LAST_DAY_OF_ANNOUNCEMENT = Date.parse("2024-09-13")
def show_announcement?
Date.today <= LAST_DAY_OF_ANNOUNCEMENT
end
def destination_tag(value)

View file

@ -4,26 +4,27 @@
%p#pet-not-found.alert= t 'pets.load.not_found'
- if show_neopass_announcement?
%section.neopass-announcement
= image_tag "about/neopass-survey.png", width: 70, height: 70,
srcset: {"about/neopass-survey@2x.png": "2x"},
- if show_announcement?
%section.announcement
= image_tag "about/announcement.png", width: 70, height: 70,
srcset: {"about/announcement@2x.png": "2x"},
class: "neopass-thumbnail"
.neopass-content
.content
%p
%strong
💭 Thank you for sending us your NeoPass feedback!
= link_to "We've updated the item page!",
item_path("37002-Floating-Negg-Faerie-Doll")
It should load faster, work better on phones, and be more reliable—no
more "failed to fetch"! Please try it out and let us know if it does
anything weird!!
%p
We're working with TNT now to build new integrations, based on what you
told us! We're glad
= link_to "log in with NeoPass", about_neopass_path
is working well, and we're excited to do the next part! More info soon!
%p
Thanks again to everyone for helping us out! We're grateful, as always 💖
%p{style: "font-style: italic; opacity: .85; font-size: 85%"}
By the way, our integration work with TNT is on pause while they focus
on the
= link_to "~Void Within plot~!", "https://www.neopets.com/tvw/",
target: "_blank", style: "color: purple; font-weight: bold"
%br
%em —Matchu
We'll start it back up closer to the new year.
#outfit-forms
- localized_cache :action_suffix => 'outfit_forms_intro' do
@ -134,4 +135,4 @@
= javascript_include_tag 'ajax_auth', 'lib/jquery.timeago', defer: true
- content_for :javascripts_body do
= javascript_include_tag 'outfits/new', defer: true
= javascript_include_tag 'outfits/new', defer: true