studio-engine 0.61.2 → 0.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/views/studio/modals/_crop_photo.html.erb +1 -1
- data/app/views/studio/modals/_web3_step_up.html.erb +1 -1
- data/app/views/studio/modals/auth/_resend_footer.html.erb +1 -1
- data/app/views/studio/modals/blocks/_birthday.html.erb +1 -1
- data/app/views/studio/modals/blocks/_entry_confirmed.html.erb +32 -2
- data/app/views/studio/modals/blocks/_error_card.html.erb +5 -1
- data/app/views/studio/modals/blocks/_leveling_activity.html.erb +1 -1
- data/app/views/studio/modals/blocks/_success_card.html.erb +19 -4
- data/app/views/studio/modals/blocks/_wallet_brand_sprite.html.erb +20 -3
- data/app/views/studio/modals/onboarding/_first_name.html.erb +1 -1
- data/app/views/studio/modals/shared/_age_attestation.html.erb +1 -1
- data/app/views/style/modals/_auth.html.erb +2 -2
- data/app/views/style/modals/_wallet_connect.html.erb +1 -1
- data/lib/studio/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d7bb00518e41485eb5c86076482d82bf7e178c3de53ebe7e7cb86b727d2ebdf2
|
|
4
|
+
data.tar.gz: a56bfe30c698b1943312c078e6030e4224540adf074832d942997d0812303824
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c9e71c552cbb8078ca4b6e01d18de197e7a6ec6bb633ce6987d63793610f01387466f653584e5acd3c4a6e0da85d7692b941e0358591e429e51ee29aea46b20
|
|
7
|
+
data.tar.gz: 4f4f23cc7ce10e40da54465a29f9022c234848a481cd99138ec2946c281bbc11e293279a10136019db19c1de57a779c21d552f3728b7a7ffb212d36e6daefc45
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<h3 class="text-heading font-bold text-lg text-center mb-4">Crop Photo</h3>
|
|
31
31
|
|
|
32
32
|
<template x-if="error">
|
|
33
|
-
<p class="text-red-400 text-sm mb-3 text-center" x-text="error"></p>
|
|
33
|
+
<p role="alert" class="text-red-400 text-sm mb-3 text-center" x-text="error"></p>
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<input type="file" x-ref="filePicker" @change="onFilePicked($event)" accept="image/*" class="hidden">
|
|
@@ -261,7 +261,7 @@
|
|
|
261
261
|
</template>
|
|
262
262
|
|
|
263
263
|
<template x-if="error">
|
|
264
|
-
<p class="text-red-400 text-sm mt-3 text-center" x-text="error"></p>
|
|
264
|
+
<p role="alert" class="text-red-400 text-sm mt-3 text-center" x-text="error"></p>
|
|
265
265
|
</template>
|
|
266
266
|
|
|
267
267
|
<%# SECONDARY — always reachable, so a user whose remembered wallet is the
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
<span x-text="props.submitting === 'magic-link' ? 'Resending…' : ((props.resendCooldown || 0) > 0 ? ('Resend available in ' + props.resendCooldown + 's') : 'Resend link')"></span>
|
|
22
22
|
</span>
|
|
23
23
|
</button>
|
|
24
|
-
<p x-show="props.resendError" x-cloak class="text-xs text-red-400 mt-3 text-center" x-text="props.resendError"></p>
|
|
24
|
+
<p role="alert" x-show="props.resendError" x-cloak class="text-xs text-red-400 mt-3 text-center" x-text="props.resendError"></p>
|
|
25
25
|
<button @click="$store.<%= modal_store %>.close()" class="block mx-auto mt-3 text-sm text-secondary hover:text-heading transition">Close</button>
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
A refusal is not an error, and showing them in the same red paragraph is
|
|
113
113
|
what let the dead end hide. %>
|
|
114
114
|
<template x-if="error">
|
|
115
|
-
<p class="text-red-400 text-sm mb-3" x-text="error"></p>
|
|
115
|
+
<p role="alert" class="text-red-400 text-sm mb-3" x-text="error"></p>
|
|
116
116
|
</template>
|
|
117
117
|
|
|
118
118
|
<%# Disabled ONLY for an incomplete date or an in-flight submit. It used to be
|
|
@@ -23,6 +23,23 @@
|
|
|
23
23
|
|
|
24
24
|
Locals (all optional; sensible props.* / static defaults):
|
|
25
25
|
modal_store — Alpine store name backing props/close. Default "modals".
|
|
26
|
+
props_expr — Alpine expression yielding the PROPS OBJECT. Default reads
|
|
27
|
+
$store.<modal_store>.current().props, which is the shape
|
|
28
|
+
the engine's own host uses. A consumer whose store is a
|
|
29
|
+
DIRECT-FIELD object with no .current() — turf-monster's
|
|
30
|
+
$store.solanaModal is one — passes that store itself here.
|
|
31
|
+
Without it every props.* default below resolves to {} and
|
|
32
|
+
the card renders complete with none of its numbers.
|
|
33
|
+
above_seeds — partial path rendered INSIDE the card, above the seeds bar
|
|
34
|
+
(e.g. a contest kickoff countdown). Named locals rather
|
|
35
|
+
than a second block: _success_card's yield is already
|
|
36
|
+
spent on the leveling enrichment, and blocks/_card_header
|
|
37
|
+
documents the Rails hazard where a partial's block_given?
|
|
38
|
+
reads TRUE off a layout yield with no block passed.
|
|
39
|
+
above_seeds_locals — locals for it. Default {}.
|
|
40
|
+
slot_position — passed through to _success_card. Default :above_cta here,
|
|
41
|
+
because a celebration's button is where the card ENDS:
|
|
42
|
+
anything under it is furniture behind the exit.
|
|
26
43
|
title_key — Alpine expr for the headline. Default "props.title || 'Good Luck'".
|
|
27
44
|
subtitle — static sub-headline. Default "Entry Confirmed".
|
|
28
45
|
subtitle_key — Alpine expr for the sub-headline (priority over subtitle).
|
|
@@ -37,6 +54,11 @@
|
|
|
37
54
|
%>
|
|
38
55
|
<%
|
|
39
56
|
modal_store = local_assigns.fetch(:modal_store, "modals")
|
|
57
|
+
props_expr = local_assigns.fetch(:props_expr,
|
|
58
|
+
"(function () { var c = $store.#{modal_store}.current(); return (c && c.props) || {}; })()")
|
|
59
|
+
above_seeds = local_assigns[:above_seeds]
|
|
60
|
+
above_seeds_locals = local_assigns.fetch(:above_seeds_locals, {})
|
|
61
|
+
slot_position = local_assigns.fetch(:slot_position, :above_cta)
|
|
40
62
|
title_key = local_assigns.fetch(:title_key, "props.title || 'Good Luck'")
|
|
41
63
|
subtitle = local_assigns.fetch(:subtitle, "Entry Confirmed")
|
|
42
64
|
subtitle_key = local_assigns[:subtitle_key]
|
|
@@ -59,7 +81,8 @@
|
|
|
59
81
|
cta_href_key: lobby_url_key,
|
|
60
82
|
cta_drain: true,
|
|
61
83
|
auto_redirect_url_key: lobby_url_key,
|
|
62
|
-
confetti: true
|
|
84
|
+
confetti: true,
|
|
85
|
+
slot_position: slot_position
|
|
63
86
|
}
|
|
64
87
|
if subtitle_key
|
|
65
88
|
sc_locals[:message_key] = subtitle_key
|
|
@@ -70,8 +93,15 @@
|
|
|
70
93
|
<%# props getter + clusterParam live on the root scope so _success_card's nested
|
|
71
94
|
Alpine expressions (props.txSignature, props.lobbyUrl, clusterParam) resolve up
|
|
72
95
|
the scope chain. clusterParam feeds _success_card's branded tx-link URL. %>
|
|
73
|
-
<div x-data="{ get props() {
|
|
96
|
+
<div x-data="{ get props() { return <%= props_expr %>; }, clusterParam: '<%= cluster_param %>' }">
|
|
74
97
|
<%= render "studio/modals/blocks/success_card", sc_locals do %>
|
|
98
|
+
<%# The app's own enrichment, above the seeds bar. turf puts its kickoff
|
|
99
|
+
countdown here — "when does it start" reads before the celebratory seeds
|
|
100
|
+
animation, not after it. %>
|
|
101
|
+
<% if above_seeds.present? %>
|
|
102
|
+
<%= render above_seeds, **above_seeds_locals %>
|
|
103
|
+
<% end %>
|
|
104
|
+
|
|
75
105
|
<% if Studio.feature?(:leveling) %>
|
|
76
106
|
<%# Leveling enrichment — mounts only when this entry awarded seeds. %>
|
|
77
107
|
<template x-if="(<%= seeds_earned_key %>) > 0">
|
|
@@ -25,7 +25,11 @@
|
|
|
25
25
|
icon_emoji = local_assigns[:icon_emoji] || "⏳" # ⏳
|
|
26
26
|
cta_label = local_assigns[:cta_label] || 'Refresh'
|
|
27
27
|
%>
|
|
28
|
-
|
|
28
|
+
<%# role="alert" on the CARD, not on its message: the message is server-rendered
|
|
29
|
+
static text, so it never "changes" for a live region to notice. The modal host
|
|
30
|
+
renders content through <template x-if>, so this whole card ENTERS the DOM when
|
|
31
|
+
the failure happens — which is the event a screen reader can announce. %>
|
|
32
|
+
<div role="alert" class="text-center py-6">
|
|
29
33
|
<div class="text-5xl mb-4 leading-none"><%= icon_emoji %></div>
|
|
30
34
|
<p class="text-sm text-heading font-semibold mb-2"><%= title %></p>
|
|
31
35
|
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<% end %>
|
|
132
132
|
|
|
133
133
|
<template x-if="error">
|
|
134
|
-
<p class="text-red-400 text-sm mb-3" x-text="error"></p>
|
|
134
|
+
<p role="alert" class="text-red-400 text-sm mb-3" x-text="error"></p>
|
|
135
135
|
</template>
|
|
136
136
|
|
|
137
137
|
<form @submit.prevent="save()" class="space-y-4">
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
on the left and a launch arrow on the
|
|
36
36
|
right. The "canonical" tx link.
|
|
37
37
|
|
|
38
|
+
slot_position: :below_cta (default) or :above_cta — where the block
|
|
39
|
+
renders. See the note on the slot itself.
|
|
38
40
|
cta_label: primary CTA button text.
|
|
39
41
|
cta_href_key: Alpine expression for the button's href.
|
|
40
42
|
Mutually exclusive with cta_event.
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
fire_confetti = !!local_assigns[:confetti]
|
|
71
73
|
large_title = !!local_assigns[:large_title]
|
|
72
74
|
use_drain = has_redirect && !!local_assigns[:cta_drain]
|
|
75
|
+
slot_position = local_assigns.fetch(:slot_position, :below_cta).to_sym
|
|
73
76
|
|
|
74
77
|
data_attr = "{
|
|
75
78
|
_remaining: #{redirect_secs},
|
|
@@ -182,6 +185,18 @@
|
|
|
182
185
|
</p>
|
|
183
186
|
<% end %>
|
|
184
187
|
|
|
188
|
+
<%# The block, when the caller wants it ABOVE the button.
|
|
189
|
+
WHY THE POSITION IS A CHOICE. Below the CTA is right for an afterthought —
|
|
190
|
+
a badge, a stat that ticks. It is wrong for anything the person is meant to
|
|
191
|
+
READ before deciding, because the button is where a celebration card ends:
|
|
192
|
+
put a countdown under it and it is furniture behind the exit. turf's entry
|
|
193
|
+
card has always run its kickoff timer and seeds bar above the button for
|
|
194
|
+
that reason, and this is what lets the engine's card do the same instead of
|
|
195
|
+
the app forking one to keep the order. %>
|
|
196
|
+
<% if block_given? && slot_position == :above_cta %>
|
|
197
|
+
<div class="mb-4"><%= yield %></div>
|
|
198
|
+
<% end %>
|
|
199
|
+
|
|
185
200
|
<%# Primary CTA — three flavors:
|
|
186
201
|
1. cta_drain + auto_redirect: countdown drains over the button
|
|
187
202
|
2. cta_href_key: anchor
|
|
@@ -219,10 +234,10 @@
|
|
|
219
234
|
</button>
|
|
220
235
|
<% end %>
|
|
221
236
|
|
|
222
|
-
<%#
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<% if block_given? %>
|
|
237
|
+
<%# ...or below it, which stays the DEFAULT: every existing caller renders here
|
|
238
|
+
and none of them asked to move. A partial can only yield once, so exactly
|
|
239
|
+
one of these two branches runs. %>
|
|
240
|
+
<% if block_given? && slot_position != :above_cta %>
|
|
226
241
|
<div class="mt-3"><%= yield %></div>
|
|
227
242
|
<% end %>
|
|
228
243
|
</div>
|
|
@@ -15,14 +15,31 @@
|
|
|
15
15
|
the name and returns it only for a known brand, else null → letter fallback).
|
|
16
16
|
|
|
17
17
|
The sprite is visually hidden (zero-box, absolute) and aria-hidden; only the
|
|
18
|
-
<use> references paint. Each <symbol> carries the OFFICIAL
|
|
18
|
+
<use> references paint. Each BRAND <symbol> carries the OFFICIAL asset embedded
|
|
19
19
|
inline as a base64 PNG data-URI <image> — byte-identical to the real logos each
|
|
20
20
|
wallet ships (matching Turf Monster's public/wallet-*.png), so no hand-drawn
|
|
21
|
-
approximation drifts from the brand.
|
|
22
|
-
|
|
21
|
+
approximation drifts from the brand.
|
|
22
|
+
|
|
23
|
+
se-wallet-default is the ONE exception, and deliberately so. It stands for "a
|
|
24
|
+
wallet, brand unknown", which has no official artwork to be faithful to — so it
|
|
25
|
+
is drawn in PATHS rather than embedded as a raster. That buys two things a PNG
|
|
26
|
+
could not: it scales to any size without a second asset, and it paints in
|
|
27
|
+
currentColor, so a caller can tint it to whatever it is standing in for. Use it
|
|
28
|
+
whenever a brand is absent or unrecognised, instead of hiding the avatar and
|
|
29
|
+
giving the surface two different shapes.
|
|
23
30
|
%>
|
|
24
31
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"
|
|
25
32
|
style="position:absolute;width:0;height:0;overflow:hidden" data-wallet-brand-sprite>
|
|
33
|
+
<%# Default — a wallet, brand unknown. Paths, not a raster: it scales and it
|
|
34
|
+
takes currentColor. The clasp is an evenodd hole rather than a second fill,
|
|
35
|
+
so the whole mark is one colour and cannot half-tint. %>
|
|
36
|
+
<symbol id="se-wallet-default" viewBox="0 0 24 24">
|
|
37
|
+
<path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"
|
|
38
|
+
d="M6.5 4H17a1 1 0 1 1 0 2H6.5a.5.5 0 0 0 0 1H18a2 2 0 0 1 2 2v8a2 2 0
|
|
39
|
+
0 1-2 2H6.5A2.5 2.5 0 0 1 4 16.5v-10A2.5 2.5 0 0 1 6.5 4Zm9.5
|
|
40
|
+
8.2a1.3 1.3 0 1 0 0 2.6 1.3 1.3 0 0 0 0-2.6Z"/>
|
|
41
|
+
</symbol>
|
|
42
|
+
|
|
26
43
|
<%# Phantom — official brand mark (light-purple tile, cream ghost). %>
|
|
27
44
|
<symbol id="se-wallet-phantom" viewBox="0 0 460 460">
|
|
28
45
|
<image width="460" height="460" href="data:image/png;base64,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"/>
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
class="input-field">
|
|
123
123
|
</div>
|
|
124
124
|
<template x-if="error">
|
|
125
|
-
<p class="text-red-400 text-xs mb-3" x-text="error"></p>
|
|
125
|
+
<p role="alert" class="text-red-400 text-xs mb-3" x-text="error"></p>
|
|
126
126
|
</template>
|
|
127
127
|
<button type="submit" :disabled="submitting"
|
|
128
128
|
class="btn btn-primary btn-lg w-full gap-2 disabled:cursor-wait">
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
state (18+ in most states; 19+ in AL/NE; 21+ in IA/MA/VA).
|
|
29
29
|
</span>
|
|
30
30
|
</label>
|
|
31
|
-
<p x-show="<%= error_model %>" x-cloak class="text-xs text-red-400 mt-1.5 ml-6">
|
|
31
|
+
<p role="alert" x-show="<%= error_model %>" x-cloak class="text-xs text-red-400 mt-1.5 ml-6">
|
|
32
32
|
Please confirm you are of legal age to continue.
|
|
33
33
|
</p>
|
|
34
34
|
</div>
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
<span x-text="props.submitting === 'google' ? 'Waiting for Google…' : 'Google'"></span>
|
|
165
165
|
</button>
|
|
166
166
|
<template x-if="props.googleError">
|
|
167
|
-
<p class="text-red-400 text-xs -mt-2 mb-3" x-text="props.googleError"></p>
|
|
167
|
+
<p role="alert" class="text-red-400 text-xs -mt-2 mb-3" x-text="props.googleError"></p>
|
|
168
168
|
</template>
|
|
169
169
|
|
|
170
170
|
<%# 2. Solana — progresses to the Connect Wallet picker modal. Gated on
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
disabled_expr: "!!props.submitting" %>
|
|
201
201
|
</div>
|
|
202
202
|
<template x-if="props.formError">
|
|
203
|
-
<p class="text-red-400 text-xs mb-3" x-text="props.formError"></p>
|
|
203
|
+
<p role="alert" class="text-red-400 text-xs mb-3" x-text="props.formError"></p>
|
|
204
204
|
</template>
|
|
205
205
|
<button type="submit" :disabled="!!props.submitting"
|
|
206
206
|
class="btn btn-neutral btn-lg w-full gap-2 disabled:cursor-wait">
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
</div>
|
|
167
167
|
|
|
168
168
|
<template x-if="error">
|
|
169
|
-
<p class="text-red-400 text-sm mt-3 text-center" x-text="error"></p>
|
|
169
|
+
<p role="alert" class="text-red-400 text-sm mt-3 text-center" x-text="error"></p>
|
|
170
170
|
</template>
|
|
171
171
|
|
|
172
172
|
<button type="button" @click="back()" :disabled="connecting"
|
data/lib/studio/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: studio-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.62.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex McRitchie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|