Skip to content

Commit 33f5527

Browse files
committed
update: reactivity, svelte5 syntax and last item removal logic.
1 parent 2c11691 commit 33f5527

File tree

1 file changed

+48
-35
lines changed

1 file changed

+48
-35
lines changed

src/lib/components/bottomModalAlert.svelte

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import { hideNotification, shouldShowNotification } from '$lib/helpers/notifications';
44
import { app } from '$lib/stores/app';
55
import {
6-
type BottomModalAlertAction,
76
type BottomModalAlertItem,
87
bottomModalAlertsConfig,
98
dismissBottomModalAlert,
@@ -15,23 +14,23 @@
1514
import { upgradeURL } from '$lib/stores/billing';
1615
import { addBottomModalAlerts } from '$routes/(console)/bottomAlerts';
1716
import { project } from '$routes/(console)/project-[region]-[project]/store';
18-
import { page } from '$app/stores';
17+
import { page } from '$app/state';
1918
import { Click, trackEvent } from '$lib/actions/analytics';
2019
import { goto } from '$app/navigation';
2120
import { Typography } from '@appwrite.io/pink-svelte';
2221
23-
let currentIndex = 0;
24-
let openModalOnMobile = false;
22+
let currentIndex = $state(0);
23+
let openModalOnMobile = $state(false);
2524
26-
function getPageScope(pathname: string) {
27-
const isProjectPage = pathname.includes('project-[region]-[project]');
28-
const isOrganizationPage = pathname.includes('organization-[organization]');
25+
function getPageScope(route: string) {
26+
const isProjectPage = route.includes('project-[region]-[project]');
27+
const isOrganizationPage = route.includes('organization-[organization]');
2928
3029
return { isProjectPage, isOrganizationPage };
3130
}
3231
33-
function filterModalAlerts(alerts: BottomModalAlertItem[], pathname: string) {
34-
const { isProjectPage, isOrganizationPage } = getPageScope(pathname);
32+
function filterModalAlerts(alerts: BottomModalAlertItem[], route: string) {
33+
const { isProjectPage, isOrganizationPage } = getPageScope(route);
3534
3635
return alerts
3736
.sort((a, b) => b.importance - a.importance)
@@ -51,19 +50,32 @@
5150
});
5251
}
5352
54-
$: filteredModalAlerts = filterModalAlerts($bottomModalAlertsConfig.alerts, $page.route.id);
53+
const bottomModalAlerts = $derived($bottomModalAlertsConfig.alerts);
5554
56-
$: currentModalAlert = filteredModalAlerts[currentIndex] as BottomModalAlertItem;
55+
const filteredModalAlerts = $derived(filterModalAlerts(bottomModalAlerts, page.route.id));
5756
58-
$: hasOnlyPrimaryCta = typeof currentModalAlert?.learnMore === 'undefined';
57+
const currentModalAlert = $derived(filteredModalAlerts[currentIndex] as BottomModalAlertItem);
5958
60-
function handleClose() {
61-
filteredModalAlerts.forEach((alert) => {
59+
const hasOnlyPrimaryCta = $derived(typeof currentModalAlert?.learnMore === 'undefined');
60+
61+
const isOnOnboarding = $derived(page.route.id.includes('(console)/onboarding'));
62+
63+
function handleClose(id: string | null = null) {
64+
const alerts = !id
65+
? filteredModalAlerts
66+
: filteredModalAlerts.filter((alert) => alert.id === id);
67+
68+
alerts.forEach((alert) => {
6269
const modalAlert = alert;
6370
dismissBottomModalAlert(modalAlert.id);
6471
hideNotification(modalAlert.id, { coolOffPeriod: 24 * 365 });
6572
if (modalAlert.closed) modalAlert.closed();
6673
});
74+
75+
// reset `currentIndex` if we removed the last item
76+
if (currentIndex >= filteredModalAlerts.length - 1) {
77+
currentIndex = Math.max(0, filteredModalAlerts.length - 2);
78+
}
6779
}
6880
6981
function showNext() {
@@ -114,8 +126,13 @@
114126
}
115127
116128
// the button component cannot have both href and on:click!
117-
function triggerWindowLink(alertAction: BottomModalAlertAction, event?: string) {
129+
function triggerWindowLink(alert: BottomModalAlertItem, event?: string) {
130+
const alertAction = alert.cta;
118131
const shouldShowUpgrade = showUpgrade();
132+
133+
// for correct event tracking after removal
134+
const currentModalId = currentModalAlert.id;
135+
119136
const url = shouldShowUpgrade
120137
? $upgradeURL
121138
: alertAction.link({
@@ -130,14 +147,12 @@
130147
}
131148
132149
if (alertAction?.hideOnClick === true) {
133-
// be careful of this one.
134-
// once clicked, its gone!
135-
handleClose();
150+
handleClose(alert.id); // gone!
136151
}
137152
138153
trackEvent(Click.PromoClick, {
139-
promo: currentModalAlert.id,
140-
type: shouldShowUpgrade ? 'upgrade' : (event ?? `cta_click_${currentModalAlert.id}`)
154+
promo: currentModalId,
155+
type: shouldShowUpgrade ? 'upgrade' : (event ?? `cta_click_${currentModalId}`)
141156
});
142157
}
143158
@@ -156,12 +171,10 @@
156171
}
157172
}
158173
159-
onMount(() => {
160-
addBottomModalAlerts();
161-
});
174+
onMount(addBottomModalAlerts);
162175
</script>
163176

164-
{#if filteredModalAlerts.length > 0 && currentModalAlert && !$page.url.pathname.includes('console/onboarding')}
177+
{#if !isOnOnboarding && filteredModalAlerts.length > 0 && currentModalAlert}
165178
{@const shouldShowUpgrade = showUpgrade()}
166179
<div class="main-alert-wrapper is-not-mobile">
167180
<div class="alert-container">
@@ -170,7 +183,7 @@
170183
<button
171184
aria-label="Close modal"
172185
class="icon-inline-tag"
173-
on:click={() => handleClose()}>
186+
onclick={() => handleClose()}>
174187
<svg
175188
xmlns="http://www.w3.org/2000/svg"
176189
width="20"
@@ -209,14 +222,14 @@
209222
aria-label="Previous"
210223
class="icon-cheveron-left"
211224
style:cursor={currentIndex !== 0 ? 'pointer' : undefined}
212-
on:click={showPrevious}
225+
onclick={showPrevious}
213226
disabled={currentIndex === 0}
214227
class:active={currentIndex > 0}></button>
215228

216229
<button
217230
aria-label="Next"
218231
class="icon-cheveron-right"
219-
on:click={showNext}
232+
onclick={showNext}
220233
style:cursor={currentIndex !==
221234
filteredModalAlerts.length - 1
222235
? 'pointer'
@@ -248,7 +261,7 @@
248261
fullWidthMobile
249262
secondary={!hasOnlyPrimaryCta}
250263
class={`${hasOnlyPrimaryCta ? 'only-primary-cta' : ''}`}
251-
on:click={() => triggerWindowLink(currentModalAlert.cta)}>
264+
on:click={() => triggerWindowLink(currentModalAlert)}>
252265
{currentModalAlert.cta.text}
253266
</Button>
254267

@@ -281,7 +294,7 @@
281294
<button
282295
aria-label="Close modal"
283296
class="icon-inline-tag"
284-
on:click={() => handleClose()}>
297+
onclick={() => handleClose()}>
285298
<svg
286299
xmlns="http://www.w3.org/2000/svg"
287300
width="20"
@@ -322,14 +335,14 @@
322335
style:cursor={currentIndex !== 0
323336
? 'pointer'
324337
: undefined}
325-
on:click={showPrevious}
338+
onclick={showPrevious}
326339
disabled={currentIndex === 0}
327340
class:active={currentIndex > 0}></button>
328341

329342
<button
330343
aria-label="Next"
331344
class="icon-cheveron-right"
332-
on:click={showNext}
345+
onclick={showNext}
333346
style:cursor={currentIndex !==
334347
filteredModalAlerts.length - 1
335348
? 'pointer'
@@ -364,7 +377,7 @@
364377
fullWidthMobile
365378
on:click={() => {
366379
openModalOnMobile = false;
367-
triggerWindowLink(currentModalAlert.cta);
380+
triggerWindowLink(currentModalAlert);
368381
}}>
369382
{shouldShowUpgrade
370383
? 'Upgrade plan'
@@ -394,13 +407,13 @@
394407
{:else}
395408
{@const mobileConfig = getMobileWindowConfig()}
396409
<!-- we don't need keydown because we show this only on mobile -->
397-
<!-- svelte-ignore a11y-click-events-have-key-events -->
410+
<!-- svelte-ignore a11y_click_events_have_key_events -->
398411
<div
399412
tabindex="0"
400413
role="button"
401414
class:showing={!openModalOnMobile}
402415
class="card notification-card u-width-full-line"
403-
on:click={() => {
416+
onclick={() => {
404417
if (mobileConfig.cta) {
405418
// navigate manually!
406419
triggerMobileWindowLink();
@@ -413,7 +426,7 @@
413426
<Typography.Text variant="m-500" color="--fgcolor-neutral-primary">
414427
{currentModalAlert.title}
415428
</Typography.Text>
416-
<button on:click={hideAllModalAlerts} aria-label="Close">
429+
<button onclick={hideAllModalAlerts} aria-label="Close">
417430
<span class="icon-x"></span>
418431
</button>
419432
</div>

0 commit comments

Comments
 (0)