bastd.ui.appinvite

UI functionality related to inviting people to try the game.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI functionality related to inviting people to try the game."""
  4
  5from __future__ import annotations
  6
  7import copy
  8import time
  9from typing import TYPE_CHECKING
 10
 11import ba
 12import ba.internal
 13
 14if TYPE_CHECKING:
 15    from typing import Any
 16
 17
 18class AppInviteWindow(ba.Window):
 19    """Window for showing different ways to invite people to try the game."""
 20
 21    def __init__(self) -> None:
 22        ba.set_analytics_screen('AppInviteWindow')
 23        self._data: dict[str, Any] | None = None
 24        self._width = 650
 25        self._height = 400
 26
 27        uiscale = ba.app.ui.uiscale
 28        super().__init__(
 29            root_widget=ba.containerwidget(
 30                size=(self._width, self._height),
 31                transition='in_scale',
 32                scale=(
 33                    1.8
 34                    if uiscale is ba.UIScale.SMALL
 35                    else 1.35
 36                    if uiscale is ba.UIScale.MEDIUM
 37                    else 1.0
 38                ),
 39            )
 40        )
 41
 42        self._cancel_button = ba.buttonwidget(
 43            parent=self._root_widget,
 44            scale=0.8,
 45            position=(60, self._height - 50),
 46            size=(50, 50),
 47            label='',
 48            on_activate_call=self.close,
 49            autoselect=True,
 50            color=(0.4, 0.4, 0.6),
 51            icon=ba.gettexture('crossOut'),
 52            iconscale=1.2,
 53        )
 54
 55        ba.containerwidget(
 56            edit=self._root_widget, cancel_button=self._cancel_button
 57        )
 58
 59        ba.textwidget(
 60            parent=self._root_widget,
 61            size=(0, 0),
 62            position=(self._width * 0.5, self._height * 0.5 + 110),
 63            autoselect=True,
 64            scale=0.8,
 65            maxwidth=self._width * 0.9,
 66            h_align='center',
 67            v_align='center',
 68            color=(0.3, 0.8, 0.3),
 69            flatness=1.0,
 70            text=ba.Lstr(
 71                resource='gatherWindow.earnTicketsForRecommendingAmountText',
 72                fallback_resource=(
 73                    'gatherWindow.earnTicketsForRecommendingText'
 74                ),
 75                subs=[
 76                    (
 77                        '${COUNT}',
 78                        str(
 79                            ba.internal.get_v1_account_misc_read_val(
 80                                'friendTryTickets', 300
 81                            )
 82                        ),
 83                    ),
 84                    (
 85                        '${YOU_COUNT}',
 86                        str(
 87                            ba.internal.get_v1_account_misc_read_val(
 88                                'friendTryAwardTickets', 100
 89                            )
 90                        ),
 91                    ),
 92                ],
 93            ),
 94        )
 95
 96        or_text = (
 97            ba.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')])
 98            .evaluate()
 99            .strip()
100        )
101        ba.buttonwidget(
102            parent=self._root_widget,
103            size=(250, 150),
104            position=(self._width * 0.5 - 125, self._height * 0.5 - 80),
105            autoselect=True,
106            button_type='square',
107            label=ba.Lstr(resource='gatherWindow.inviteFriendsText'),
108            on_activate_call=ba.WeakCall(self._google_invites),
109        )
110
111        ba.textwidget(
112            parent=self._root_widget,
113            size=(0, 0),
114            position=(self._width * 0.5, self._height * 0.5 - 94),
115            autoselect=True,
116            scale=0.9,
117            h_align='center',
118            v_align='center',
119            color=(0.5, 0.5, 0.5),
120            flatness=1.0,
121            text=or_text,
122        )
123
124        ba.buttonwidget(
125            parent=self._root_widget,
126            size=(180, 50),
127            position=(self._width * 0.5 - 90, self._height * 0.5 - 170),
128            autoselect=True,
129            color=(0.5, 0.5, 0.6),
130            textcolor=(0.7, 0.7, 0.8),
131            text_scale=0.8,
132            label=ba.Lstr(resource='gatherWindow.appInviteSendACodeText'),
133            on_activate_call=ba.WeakCall(self._send_code),
134        )
135
136        # kick off a transaction to get our code
137        ba.internal.add_transaction(
138            {
139                'type': 'FRIEND_PROMO_CODE_REQUEST',
140                'ali': False,
141                'expire_time': time.time() + 20,
142            },
143            callback=ba.WeakCall(self._on_code_result),
144        )
145        ba.internal.run_transactions()
146
147    def _on_code_result(self, result: dict[str, Any] | None) -> None:
148        if result is not None:
149            self._data = result
150
151    def _send_code(self) -> None:
152        handle_app_invites_press(force_code=True)
153
154    def _google_invites(self) -> None:
155        if self._data is None:
156            ba.screenmessage(
157                ba.Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
158                color=(1, 0, 0),
159            )
160            ba.playsound(ba.getsound('error'))
161            return
162
163        if ba.internal.get_v1_account_state() == 'signed_in':
164            ba.set_analytics_screen('App Invite UI')
165            ba.internal.show_app_invite(
166                ba.Lstr(
167                    resource='gatherWindow.appInviteTitleText',
168                    subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))],
169                ).evaluate(),
170                ba.Lstr(
171                    resource='gatherWindow.appInviteMessageText',
172                    subs=[
173                        ('${COUNT}', str(self._data['tickets'])),
174                        (
175                            '${NAME}',
176                            ba.internal.get_v1_account_name().split()[0],
177                        ),
178                        ('${APP_NAME}', ba.Lstr(resource='titleText')),
179                    ],
180                ).evaluate(),
181                self._data['code'],
182            )
183        else:
184            ba.playsound(ba.getsound('error'))
185
186    def close(self) -> None:
187        """Close the window."""
188        ba.containerwidget(edit=self._root_widget, transition='out_scale')
189
190
191class ShowFriendCodeWindow(ba.Window):
192    """Window showing a code for sharing with friends."""
193
194    def __init__(self, data: dict[str, Any]):
195        from ba.internal import is_browser_likely_available
196
197        ba.set_analytics_screen('Friend Promo Code')
198        self._width = 650
199        self._height = 400
200        uiscale = ba.app.ui.uiscale
201        super().__init__(
202            root_widget=ba.containerwidget(
203                size=(self._width, self._height),
204                color=(0.45, 0.63, 0.15),
205                transition='in_scale',
206                scale=(
207                    1.7
208                    if uiscale is ba.UIScale.SMALL
209                    else 1.35
210                    if uiscale is ba.UIScale.MEDIUM
211                    else 1.0
212                ),
213            )
214        )
215        self._data = copy.deepcopy(data)
216        ba.playsound(ba.getsound('cashRegister'))
217        ba.playsound(ba.getsound('swish'))
218
219        self._cancel_button = ba.buttonwidget(
220            parent=self._root_widget,
221            scale=0.7,
222            position=(50, self._height - 50),
223            size=(60, 60),
224            label='',
225            on_activate_call=self.close,
226            autoselect=True,
227            color=(0.45, 0.63, 0.15),
228            icon=ba.gettexture('crossOut'),
229            iconscale=1.2,
230        )
231        ba.containerwidget(
232            edit=self._root_widget, cancel_button=self._cancel_button
233        )
234
235        ba.textwidget(
236            parent=self._root_widget,
237            position=(self._width * 0.5, self._height * 0.8),
238            size=(0, 0),
239            color=ba.app.ui.infotextcolor,
240            scale=1.0,
241            flatness=1.0,
242            h_align='center',
243            v_align='center',
244            text=ba.Lstr(resource='gatherWindow.shareThisCodeWithFriendsText'),
245            maxwidth=self._width * 0.85,
246        )
247
248        ba.textwidget(
249            parent=self._root_widget,
250            position=(self._width * 0.5, self._height * 0.645),
251            size=(0, 0),
252            color=(1.0, 3.0, 1.0),
253            scale=2.0,
254            h_align='center',
255            v_align='center',
256            text=data['code'],
257            maxwidth=self._width * 0.85,
258        )
259
260        award_str: str | ba.Lstr | None
261        if self._data['awardTickets'] != 0:
262            award_str = ba.Lstr(
263                resource='gatherWindow.friendPromoCodeAwardText',
264                subs=[('${COUNT}', str(self._data['awardTickets']))],
265            )
266        else:
267            award_str = ''
268        ba.textwidget(
269            parent=self._root_widget,
270            position=(self._width * 0.5, self._height * 0.37),
271            size=(0, 0),
272            color=ba.app.ui.infotextcolor,
273            scale=1.0,
274            flatness=1.0,
275            h_align='center',
276            v_align='center',
277            text=ba.Lstr(
278                value='${A}\n${B}\n${C}\n${D}',
279                subs=[
280                    (
281                        '${A}',
282                        ba.Lstr(
283                            resource=(
284                                'gatherWindow.friendPromoCodeRedeemLongText'
285                            ),
286                            subs=[
287                                ('${COUNT}', str(self._data['tickets'])),
288                                (
289                                    '${MAX_USES}',
290                                    str(self._data['usesRemaining']),
291                                ),
292                            ],
293                        ),
294                    ),
295                    (
296                        '${B}',
297                        ba.Lstr(
298                            resource=(
299                                'gatherWindow.friendPromoCodeWhereToEnterText'
300                            )
301                        ),
302                    ),
303                    ('${C}', award_str),
304                    (
305                        '${D}',
306                        ba.Lstr(
307                            resource='gatherWindow.friendPromoCodeExpireText',
308                            subs=[
309                                (
310                                    '${EXPIRE_HOURS}',
311                                    str(self._data['expireHours']),
312                                )
313                            ],
314                        ),
315                    ),
316                ],
317            ),
318            maxwidth=self._width * 0.9,
319            max_height=self._height * 0.35,
320        )
321
322        if is_browser_likely_available():
323            xoffs = 0
324            ba.buttonwidget(
325                parent=self._root_widget,
326                size=(200, 40),
327                position=(self._width * 0.5 - 100 + xoffs, 39),
328                autoselect=True,
329                label=ba.Lstr(resource='gatherWindow.emailItText'),
330                on_activate_call=ba.WeakCall(self._email),
331            )
332
333    def _google_invites(self) -> None:
334        ba.set_analytics_screen('App Invite UI')
335        ba.internal.show_app_invite(
336            ba.Lstr(
337                resource='gatherWindow.appInviteTitleText',
338                subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))],
339            ).evaluate(),
340            ba.Lstr(
341                resource='gatherWindow.appInviteMessageText',
342                subs=[
343                    ('${COUNT}', str(self._data['tickets'])),
344                    ('${NAME}', ba.internal.get_v1_account_name().split()[0]),
345                    ('${APP_NAME}', ba.Lstr(resource='titleText')),
346                ],
347            ).evaluate(),
348            self._data['code'],
349        )
350
351    def _email(self) -> None:
352        import urllib.parse
353
354        # If somehow we got signed out.
355        if ba.internal.get_v1_account_state() != 'signed_in':
356            ba.screenmessage(
357                ba.Lstr(resource='notSignedInText'), color=(1, 0, 0)
358            )
359            ba.playsound(ba.getsound('error'))
360            return
361
362        ba.set_analytics_screen('Email Friend Code')
363        subject = (
364            ba.Lstr(resource='gatherWindow.friendHasSentPromoCodeText')
365            .evaluate()
366            .replace('${NAME}', ba.internal.get_v1_account_name())
367            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
368            .replace('${COUNT}', str(self._data['tickets']))
369        )
370        body = (
371            ba.Lstr(resource='gatherWindow.youHaveBeenSentAPromoCodeText')
372            .evaluate()
373            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
374            + '\n\n'
375            + str(self._data['code'])
376            + '\n\n'
377        )
378        body += (
379            (
380                ba.Lstr(resource='gatherWindow.friendPromoCodeRedeemShortText')
381                .evaluate()
382                .replace('${COUNT}', str(self._data['tickets']))
383            )
384            + '\n\n'
385            + ba.Lstr(resource='gatherWindow.friendPromoCodeInstructionsText')
386            .evaluate()
387            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
388            + '\n'
389            + ba.Lstr(resource='gatherWindow.friendPromoCodeExpireText')
390            .evaluate()
391            .replace('${EXPIRE_HOURS}', str(self._data['expireHours']))
392            + '\n'
393            + ba.Lstr(resource='enjoyText').evaluate()
394        )
395        ba.open_url(
396            'mailto:?subject='
397            + urllib.parse.quote(subject)
398            + '&body='
399            + urllib.parse.quote(body)
400        )
401
402    def close(self) -> None:
403        """Close the window."""
404        ba.containerwidget(edit=self._root_widget, transition='out_scale')
405
406
407def handle_app_invites_press(force_code: bool = False) -> None:
408    """(internal)"""
409    app = ba.app
410    do_app_invites = (
411        app.platform == 'android'
412        and app.subplatform == 'google'
413        and ba.internal.get_v1_account_misc_read_val('enableAppInvites', False)
414        and not app.on_tv
415    )
416    # Update: google's app invites are deprecated.
417    do_app_invites = False
418
419    if force_code:
420        do_app_invites = False
421
422    # FIXME: Should update this to grab a code before showing the invite UI.
423    if do_app_invites:
424        AppInviteWindow()
425    else:
426        ba.screenmessage(
427            ba.Lstr(resource='gatherWindow.requestingAPromoCodeText'),
428            color=(0, 1, 0),
429        )
430
431        def handle_result(result: dict[str, Any] | None) -> None:
432            with ba.Context('ui'):
433                if result is None:
434                    ba.screenmessage(
435                        ba.Lstr(resource='errorText'), color=(1, 0, 0)
436                    )
437                    ba.playsound(ba.getsound('error'))
438                else:
439                    ShowFriendCodeWindow(result)
440
441        ba.internal.add_transaction(
442            {
443                'type': 'FRIEND_PROMO_CODE_REQUEST',
444                'ali': False,
445                'expire_time': time.time() + 10,
446            },
447            callback=handle_result,
448        )
449        ba.internal.run_transactions()
class AppInviteWindow(ba.ui.Window):
 19class AppInviteWindow(ba.Window):
 20    """Window for showing different ways to invite people to try the game."""
 21
 22    def __init__(self) -> None:
 23        ba.set_analytics_screen('AppInviteWindow')
 24        self._data: dict[str, Any] | None = None
 25        self._width = 650
 26        self._height = 400
 27
 28        uiscale = ba.app.ui.uiscale
 29        super().__init__(
 30            root_widget=ba.containerwidget(
 31                size=(self._width, self._height),
 32                transition='in_scale',
 33                scale=(
 34                    1.8
 35                    if uiscale is ba.UIScale.SMALL
 36                    else 1.35
 37                    if uiscale is ba.UIScale.MEDIUM
 38                    else 1.0
 39                ),
 40            )
 41        )
 42
 43        self._cancel_button = ba.buttonwidget(
 44            parent=self._root_widget,
 45            scale=0.8,
 46            position=(60, self._height - 50),
 47            size=(50, 50),
 48            label='',
 49            on_activate_call=self.close,
 50            autoselect=True,
 51            color=(0.4, 0.4, 0.6),
 52            icon=ba.gettexture('crossOut'),
 53            iconscale=1.2,
 54        )
 55
 56        ba.containerwidget(
 57            edit=self._root_widget, cancel_button=self._cancel_button
 58        )
 59
 60        ba.textwidget(
 61            parent=self._root_widget,
 62            size=(0, 0),
 63            position=(self._width * 0.5, self._height * 0.5 + 110),
 64            autoselect=True,
 65            scale=0.8,
 66            maxwidth=self._width * 0.9,
 67            h_align='center',
 68            v_align='center',
 69            color=(0.3, 0.8, 0.3),
 70            flatness=1.0,
 71            text=ba.Lstr(
 72                resource='gatherWindow.earnTicketsForRecommendingAmountText',
 73                fallback_resource=(
 74                    'gatherWindow.earnTicketsForRecommendingText'
 75                ),
 76                subs=[
 77                    (
 78                        '${COUNT}',
 79                        str(
 80                            ba.internal.get_v1_account_misc_read_val(
 81                                'friendTryTickets', 300
 82                            )
 83                        ),
 84                    ),
 85                    (
 86                        '${YOU_COUNT}',
 87                        str(
 88                            ba.internal.get_v1_account_misc_read_val(
 89                                'friendTryAwardTickets', 100
 90                            )
 91                        ),
 92                    ),
 93                ],
 94            ),
 95        )
 96
 97        or_text = (
 98            ba.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')])
 99            .evaluate()
100            .strip()
101        )
102        ba.buttonwidget(
103            parent=self._root_widget,
104            size=(250, 150),
105            position=(self._width * 0.5 - 125, self._height * 0.5 - 80),
106            autoselect=True,
107            button_type='square',
108            label=ba.Lstr(resource='gatherWindow.inviteFriendsText'),
109            on_activate_call=ba.WeakCall(self._google_invites),
110        )
111
112        ba.textwidget(
113            parent=self._root_widget,
114            size=(0, 0),
115            position=(self._width * 0.5, self._height * 0.5 - 94),
116            autoselect=True,
117            scale=0.9,
118            h_align='center',
119            v_align='center',
120            color=(0.5, 0.5, 0.5),
121            flatness=1.0,
122            text=or_text,
123        )
124
125        ba.buttonwidget(
126            parent=self._root_widget,
127            size=(180, 50),
128            position=(self._width * 0.5 - 90, self._height * 0.5 - 170),
129            autoselect=True,
130            color=(0.5, 0.5, 0.6),
131            textcolor=(0.7, 0.7, 0.8),
132            text_scale=0.8,
133            label=ba.Lstr(resource='gatherWindow.appInviteSendACodeText'),
134            on_activate_call=ba.WeakCall(self._send_code),
135        )
136
137        # kick off a transaction to get our code
138        ba.internal.add_transaction(
139            {
140                'type': 'FRIEND_PROMO_CODE_REQUEST',
141                'ali': False,
142                'expire_time': time.time() + 20,
143            },
144            callback=ba.WeakCall(self._on_code_result),
145        )
146        ba.internal.run_transactions()
147
148    def _on_code_result(self, result: dict[str, Any] | None) -> None:
149        if result is not None:
150            self._data = result
151
152    def _send_code(self) -> None:
153        handle_app_invites_press(force_code=True)
154
155    def _google_invites(self) -> None:
156        if self._data is None:
157            ba.screenmessage(
158                ba.Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
159                color=(1, 0, 0),
160            )
161            ba.playsound(ba.getsound('error'))
162            return
163
164        if ba.internal.get_v1_account_state() == 'signed_in':
165            ba.set_analytics_screen('App Invite UI')
166            ba.internal.show_app_invite(
167                ba.Lstr(
168                    resource='gatherWindow.appInviteTitleText',
169                    subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))],
170                ).evaluate(),
171                ba.Lstr(
172                    resource='gatherWindow.appInviteMessageText',
173                    subs=[
174                        ('${COUNT}', str(self._data['tickets'])),
175                        (
176                            '${NAME}',
177                            ba.internal.get_v1_account_name().split()[0],
178                        ),
179                        ('${APP_NAME}', ba.Lstr(resource='titleText')),
180                    ],
181                ).evaluate(),
182                self._data['code'],
183            )
184        else:
185            ba.playsound(ba.getsound('error'))
186
187    def close(self) -> None:
188        """Close the window."""
189        ba.containerwidget(edit=self._root_widget, transition='out_scale')

Window for showing different ways to invite people to try the game.

AppInviteWindow()
 22    def __init__(self) -> None:
 23        ba.set_analytics_screen('AppInviteWindow')
 24        self._data: dict[str, Any] | None = None
 25        self._width = 650
 26        self._height = 400
 27
 28        uiscale = ba.app.ui.uiscale
 29        super().__init__(
 30            root_widget=ba.containerwidget(
 31                size=(self._width, self._height),
 32                transition='in_scale',
 33                scale=(
 34                    1.8
 35                    if uiscale is ba.UIScale.SMALL
 36                    else 1.35
 37                    if uiscale is ba.UIScale.MEDIUM
 38                    else 1.0
 39                ),
 40            )
 41        )
 42
 43        self._cancel_button = ba.buttonwidget(
 44            parent=self._root_widget,
 45            scale=0.8,
 46            position=(60, self._height - 50),
 47            size=(50, 50),
 48            label='',
 49            on_activate_call=self.close,
 50            autoselect=True,
 51            color=(0.4, 0.4, 0.6),
 52            icon=ba.gettexture('crossOut'),
 53            iconscale=1.2,
 54        )
 55
 56        ba.containerwidget(
 57            edit=self._root_widget, cancel_button=self._cancel_button
 58        )
 59
 60        ba.textwidget(
 61            parent=self._root_widget,
 62            size=(0, 0),
 63            position=(self._width * 0.5, self._height * 0.5 + 110),
 64            autoselect=True,
 65            scale=0.8,
 66            maxwidth=self._width * 0.9,
 67            h_align='center',
 68            v_align='center',
 69            color=(0.3, 0.8, 0.3),
 70            flatness=1.0,
 71            text=ba.Lstr(
 72                resource='gatherWindow.earnTicketsForRecommendingAmountText',
 73                fallback_resource=(
 74                    'gatherWindow.earnTicketsForRecommendingText'
 75                ),
 76                subs=[
 77                    (
 78                        '${COUNT}',
 79                        str(
 80                            ba.internal.get_v1_account_misc_read_val(
 81                                'friendTryTickets', 300
 82                            )
 83                        ),
 84                    ),
 85                    (
 86                        '${YOU_COUNT}',
 87                        str(
 88                            ba.internal.get_v1_account_misc_read_val(
 89                                'friendTryAwardTickets', 100
 90                            )
 91                        ),
 92                    ),
 93                ],
 94            ),
 95        )
 96
 97        or_text = (
 98            ba.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')])
 99            .evaluate()
100            .strip()
101        )
102        ba.buttonwidget(
103            parent=self._root_widget,
104            size=(250, 150),
105            position=(self._width * 0.5 - 125, self._height * 0.5 - 80),
106            autoselect=True,
107            button_type='square',
108            label=ba.Lstr(resource='gatherWindow.inviteFriendsText'),
109            on_activate_call=ba.WeakCall(self._google_invites),
110        )
111
112        ba.textwidget(
113            parent=self._root_widget,
114            size=(0, 0),
115            position=(self._width * 0.5, self._height * 0.5 - 94),
116            autoselect=True,
117            scale=0.9,
118            h_align='center',
119            v_align='center',
120            color=(0.5, 0.5, 0.5),
121            flatness=1.0,
122            text=or_text,
123        )
124
125        ba.buttonwidget(
126            parent=self._root_widget,
127            size=(180, 50),
128            position=(self._width * 0.5 - 90, self._height * 0.5 - 170),
129            autoselect=True,
130            color=(0.5, 0.5, 0.6),
131            textcolor=(0.7, 0.7, 0.8),
132            text_scale=0.8,
133            label=ba.Lstr(resource='gatherWindow.appInviteSendACodeText'),
134            on_activate_call=ba.WeakCall(self._send_code),
135        )
136
137        # kick off a transaction to get our code
138        ba.internal.add_transaction(
139            {
140                'type': 'FRIEND_PROMO_CODE_REQUEST',
141                'ali': False,
142                'expire_time': time.time() + 20,
143            },
144            callback=ba.WeakCall(self._on_code_result),
145        )
146        ba.internal.run_transactions()
def close(self) -> None:
187    def close(self) -> None:
188        """Close the window."""
189        ba.containerwidget(edit=self._root_widget, transition='out_scale')

Close the window.

Inherited Members
ba.ui.Window
get_root_widget
class ShowFriendCodeWindow(ba.ui.Window):
192class ShowFriendCodeWindow(ba.Window):
193    """Window showing a code for sharing with friends."""
194
195    def __init__(self, data: dict[str, Any]):
196        from ba.internal import is_browser_likely_available
197
198        ba.set_analytics_screen('Friend Promo Code')
199        self._width = 650
200        self._height = 400
201        uiscale = ba.app.ui.uiscale
202        super().__init__(
203            root_widget=ba.containerwidget(
204                size=(self._width, self._height),
205                color=(0.45, 0.63, 0.15),
206                transition='in_scale',
207                scale=(
208                    1.7
209                    if uiscale is ba.UIScale.SMALL
210                    else 1.35
211                    if uiscale is ba.UIScale.MEDIUM
212                    else 1.0
213                ),
214            )
215        )
216        self._data = copy.deepcopy(data)
217        ba.playsound(ba.getsound('cashRegister'))
218        ba.playsound(ba.getsound('swish'))
219
220        self._cancel_button = ba.buttonwidget(
221            parent=self._root_widget,
222            scale=0.7,
223            position=(50, self._height - 50),
224            size=(60, 60),
225            label='',
226            on_activate_call=self.close,
227            autoselect=True,
228            color=(0.45, 0.63, 0.15),
229            icon=ba.gettexture('crossOut'),
230            iconscale=1.2,
231        )
232        ba.containerwidget(
233            edit=self._root_widget, cancel_button=self._cancel_button
234        )
235
236        ba.textwidget(
237            parent=self._root_widget,
238            position=(self._width * 0.5, self._height * 0.8),
239            size=(0, 0),
240            color=ba.app.ui.infotextcolor,
241            scale=1.0,
242            flatness=1.0,
243            h_align='center',
244            v_align='center',
245            text=ba.Lstr(resource='gatherWindow.shareThisCodeWithFriendsText'),
246            maxwidth=self._width * 0.85,
247        )
248
249        ba.textwidget(
250            parent=self._root_widget,
251            position=(self._width * 0.5, self._height * 0.645),
252            size=(0, 0),
253            color=(1.0, 3.0, 1.0),
254            scale=2.0,
255            h_align='center',
256            v_align='center',
257            text=data['code'],
258            maxwidth=self._width * 0.85,
259        )
260
261        award_str: str | ba.Lstr | None
262        if self._data['awardTickets'] != 0:
263            award_str = ba.Lstr(
264                resource='gatherWindow.friendPromoCodeAwardText',
265                subs=[('${COUNT}', str(self._data['awardTickets']))],
266            )
267        else:
268            award_str = ''
269        ba.textwidget(
270            parent=self._root_widget,
271            position=(self._width * 0.5, self._height * 0.37),
272            size=(0, 0),
273            color=ba.app.ui.infotextcolor,
274            scale=1.0,
275            flatness=1.0,
276            h_align='center',
277            v_align='center',
278            text=ba.Lstr(
279                value='${A}\n${B}\n${C}\n${D}',
280                subs=[
281                    (
282                        '${A}',
283                        ba.Lstr(
284                            resource=(
285                                'gatherWindow.friendPromoCodeRedeemLongText'
286                            ),
287                            subs=[
288                                ('${COUNT}', str(self._data['tickets'])),
289                                (
290                                    '${MAX_USES}',
291                                    str(self._data['usesRemaining']),
292                                ),
293                            ],
294                        ),
295                    ),
296                    (
297                        '${B}',
298                        ba.Lstr(
299                            resource=(
300                                'gatherWindow.friendPromoCodeWhereToEnterText'
301                            )
302                        ),
303                    ),
304                    ('${C}', award_str),
305                    (
306                        '${D}',
307                        ba.Lstr(
308                            resource='gatherWindow.friendPromoCodeExpireText',
309                            subs=[
310                                (
311                                    '${EXPIRE_HOURS}',
312                                    str(self._data['expireHours']),
313                                )
314                            ],
315                        ),
316                    ),
317                ],
318            ),
319            maxwidth=self._width * 0.9,
320            max_height=self._height * 0.35,
321        )
322
323        if is_browser_likely_available():
324            xoffs = 0
325            ba.buttonwidget(
326                parent=self._root_widget,
327                size=(200, 40),
328                position=(self._width * 0.5 - 100 + xoffs, 39),
329                autoselect=True,
330                label=ba.Lstr(resource='gatherWindow.emailItText'),
331                on_activate_call=ba.WeakCall(self._email),
332            )
333
334    def _google_invites(self) -> None:
335        ba.set_analytics_screen('App Invite UI')
336        ba.internal.show_app_invite(
337            ba.Lstr(
338                resource='gatherWindow.appInviteTitleText',
339                subs=[('${APP_NAME}', ba.Lstr(resource='titleText'))],
340            ).evaluate(),
341            ba.Lstr(
342                resource='gatherWindow.appInviteMessageText',
343                subs=[
344                    ('${COUNT}', str(self._data['tickets'])),
345                    ('${NAME}', ba.internal.get_v1_account_name().split()[0]),
346                    ('${APP_NAME}', ba.Lstr(resource='titleText')),
347                ],
348            ).evaluate(),
349            self._data['code'],
350        )
351
352    def _email(self) -> None:
353        import urllib.parse
354
355        # If somehow we got signed out.
356        if ba.internal.get_v1_account_state() != 'signed_in':
357            ba.screenmessage(
358                ba.Lstr(resource='notSignedInText'), color=(1, 0, 0)
359            )
360            ba.playsound(ba.getsound('error'))
361            return
362
363        ba.set_analytics_screen('Email Friend Code')
364        subject = (
365            ba.Lstr(resource='gatherWindow.friendHasSentPromoCodeText')
366            .evaluate()
367            .replace('${NAME}', ba.internal.get_v1_account_name())
368            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
369            .replace('${COUNT}', str(self._data['tickets']))
370        )
371        body = (
372            ba.Lstr(resource='gatherWindow.youHaveBeenSentAPromoCodeText')
373            .evaluate()
374            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
375            + '\n\n'
376            + str(self._data['code'])
377            + '\n\n'
378        )
379        body += (
380            (
381                ba.Lstr(resource='gatherWindow.friendPromoCodeRedeemShortText')
382                .evaluate()
383                .replace('${COUNT}', str(self._data['tickets']))
384            )
385            + '\n\n'
386            + ba.Lstr(resource='gatherWindow.friendPromoCodeInstructionsText')
387            .evaluate()
388            .replace('${APP_NAME}', ba.Lstr(resource='titleText').evaluate())
389            + '\n'
390            + ba.Lstr(resource='gatherWindow.friendPromoCodeExpireText')
391            .evaluate()
392            .replace('${EXPIRE_HOURS}', str(self._data['expireHours']))
393            + '\n'
394            + ba.Lstr(resource='enjoyText').evaluate()
395        )
396        ba.open_url(
397            'mailto:?subject='
398            + urllib.parse.quote(subject)
399            + '&body='
400            + urllib.parse.quote(body)
401        )
402
403    def close(self) -> None:
404        """Close the window."""
405        ba.containerwidget(edit=self._root_widget, transition='out_scale')

Window showing a code for sharing with friends.

ShowFriendCodeWindow(data: dict[str, typing.Any])
195    def __init__(self, data: dict[str, Any]):
196        from ba.internal import is_browser_likely_available
197
198        ba.set_analytics_screen('Friend Promo Code')
199        self._width = 650
200        self._height = 400
201        uiscale = ba.app.ui.uiscale
202        super().__init__(
203            root_widget=ba.containerwidget(
204                size=(self._width, self._height),
205                color=(0.45, 0.63, 0.15),
206                transition='in_scale',
207                scale=(
208                    1.7
209                    if uiscale is ba.UIScale.SMALL
210                    else 1.35
211                    if uiscale is ba.UIScale.MEDIUM
212                    else 1.0
213                ),
214            )
215        )
216        self._data = copy.deepcopy(data)
217        ba.playsound(ba.getsound('cashRegister'))
218        ba.playsound(ba.getsound('swish'))
219
220        self._cancel_button = ba.buttonwidget(
221            parent=self._root_widget,
222            scale=0.7,
223            position=(50, self._height - 50),
224            size=(60, 60),
225            label='',
226            on_activate_call=self.close,
227            autoselect=True,
228            color=(0.45, 0.63, 0.15),
229            icon=ba.gettexture('crossOut'),
230            iconscale=1.2,
231        )
232        ba.containerwidget(
233            edit=self._root_widget, cancel_button=self._cancel_button
234        )
235
236        ba.textwidget(
237            parent=self._root_widget,
238            position=(self._width * 0.5, self._height * 0.8),
239            size=(0, 0),
240            color=ba.app.ui.infotextcolor,
241            scale=1.0,
242            flatness=1.0,
243            h_align='center',
244            v_align='center',
245            text=ba.Lstr(resource='gatherWindow.shareThisCodeWithFriendsText'),
246            maxwidth=self._width * 0.85,
247        )
248
249        ba.textwidget(
250            parent=self._root_widget,
251            position=(self._width * 0.5, self._height * 0.645),
252            size=(0, 0),
253            color=(1.0, 3.0, 1.0),
254            scale=2.0,
255            h_align='center',
256            v_align='center',
257            text=data['code'],
258            maxwidth=self._width * 0.85,
259        )
260
261        award_str: str | ba.Lstr | None
262        if self._data['awardTickets'] != 0:
263            award_str = ba.Lstr(
264                resource='gatherWindow.friendPromoCodeAwardText',
265                subs=[('${COUNT}', str(self._data['awardTickets']))],
266            )
267        else:
268            award_str = ''
269        ba.textwidget(
270            parent=self._root_widget,
271            position=(self._width * 0.5, self._height * 0.37),
272            size=(0, 0),
273            color=ba.app.ui.infotextcolor,
274            scale=1.0,
275            flatness=1.0,
276            h_align='center',
277            v_align='center',
278            text=ba.Lstr(
279                value='${A}\n${B}\n${C}\n${D}',
280                subs=[
281                    (
282                        '${A}',
283                        ba.Lstr(
284                            resource=(
285                                'gatherWindow.friendPromoCodeRedeemLongText'
286                            ),
287                            subs=[
288                                ('${COUNT}', str(self._data['tickets'])),
289                                (
290                                    '${MAX_USES}',
291                                    str(self._data['usesRemaining']),
292                                ),
293                            ],
294                        ),
295                    ),
296                    (
297                        '${B}',
298                        ba.Lstr(
299                            resource=(
300                                'gatherWindow.friendPromoCodeWhereToEnterText'
301                            )
302                        ),
303                    ),
304                    ('${C}', award_str),
305                    (
306                        '${D}',
307                        ba.Lstr(
308                            resource='gatherWindow.friendPromoCodeExpireText',
309                            subs=[
310                                (
311                                    '${EXPIRE_HOURS}',
312                                    str(self._data['expireHours']),
313                                )
314                            ],
315                        ),
316                    ),
317                ],
318            ),
319            maxwidth=self._width * 0.9,
320            max_height=self._height * 0.35,
321        )
322
323        if is_browser_likely_available():
324            xoffs = 0
325            ba.buttonwidget(
326                parent=self._root_widget,
327                size=(200, 40),
328                position=(self._width * 0.5 - 100 + xoffs, 39),
329                autoselect=True,
330                label=ba.Lstr(resource='gatherWindow.emailItText'),
331                on_activate_call=ba.WeakCall(self._email),
332            )
def close(self) -> None:
403    def close(self) -> None:
404        """Close the window."""
405        ba.containerwidget(edit=self._root_widget, transition='out_scale')

Close the window.

Inherited Members
ba.ui.Window
get_root_widget