Merge branch 'main' into cron-minutely
This commit is contained in:
commit
bb1a7982dc
5 changed files with 60 additions and 19 deletions
|
|
@ -39,6 +39,7 @@ const sample = {
|
|||
},
|
||||
],
|
||||
unsubscribeUrl: 'https://app.flotilla.social/unsubscribe?token=abc123',
|
||||
settingsUrl: 'https://app.flotilla.social/settings/alerts',
|
||||
}
|
||||
|
||||
const source = readFileSync(templatePath, 'utf8')
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ export class Digest {
|
|||
for (const pk of pubkeys) {
|
||||
try {
|
||||
await loadProfile(pk)
|
||||
await waitForProfile(pk)
|
||||
} catch {
|
||||
// pass
|
||||
}
|
||||
|
|
@ -175,4 +176,18 @@ const getFormatter = () => {
|
|||
timeStyle: 'short',
|
||||
timeZone: 'UTC',
|
||||
})
|
||||
}
|
||||
|
||||
// Poll until the profile lands in the repository or hits a timeout. The load
|
||||
// promise can resolve before sharedLoad writes the event to the store, so only
|
||||
// the profile's presence here guarantees its avatar/name.
|
||||
const waitForProfile = async (pubkey: string, timeoutMs = 5000) => {
|
||||
const deadline = Date.now() + timeoutMs
|
||||
|
||||
while (Date.now() < deadline) {
|
||||
if (profilesByPubkey.get().get(pubkey)) {
|
||||
return
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 200))
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
.event-stats { margin-top: 8px; color: #64748b; font-size: 13px; }
|
||||
.stat-item { display: inline-flex; align-items: center; margin-right: 12px; }
|
||||
.footer { font-family: Inter, Helvetica, Arial, sans-serif; color: #94a3b8; font-size: 12px; line-height: 1.5; }
|
||||
.footer a { color: #7161FF; text-decoration: underline; }
|
||||
.logo { max-width: 48px; max-height: 48px; }
|
||||
a { text-decoration: none; }
|
||||
</mj-style>
|
||||
|
|
@ -57,7 +58,7 @@
|
|||
<span class="event-timestamp">at {{Timestamp}}</span>
|
||||
</div>
|
||||
<div class="event-link">
|
||||
<a href="{{Link}}">View in {{brandName}}</a>
|
||||
<a href="{{Link}}">Open</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="event-content">{{{Content}}}</div>
|
||||
|
|
@ -81,11 +82,8 @@
|
|||
<mj-divider border-color="#e2e8f0" />
|
||||
<mj-text css-class="footer">
|
||||
You're receiving this email because you subscribed to {{brandName}} notifications.
|
||||
We'll send you updates based on your subscription preferences.
|
||||
You can manage your subscriptions <a href="{{settingsUrl}}">here</a> or <a href="{{unsubscribeUrl}}">unsubscribe</a>.
|
||||
</mj-text>
|
||||
<mj-button background-color="{{brandAccent}}" color="#ffffff" href="{{unsubscribeUrl}}" padding-top="16px">
|
||||
Unsubscribe
|
||||
</mj-button>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
</mj-body>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ export const sendDigest = async (sub: Subscription, variables: Record<string, an
|
|||
brandName: BRAND_NAME,
|
||||
brandAccent: BRAND_ACCENT,
|
||||
brandLogo: BRAND_LOGO,
|
||||
settingsUrl: `${EVENT_VIEWER_URL.replace(/\/$/, '')}/settings/alerts`,
|
||||
}),
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
|||
|
|
@ -1,36 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Confirmation Successful</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Email Confirmed</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
background: #f5f5f5;
|
||||
background: #f0f2f5;
|
||||
color: #1e293b;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 480px;
|
||||
margin: 16px;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
padding: 40px 32px;
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.logo { height: 40px; width: auto; margin: 0 auto 16px; display: block; }
|
||||
.brand {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 28px;
|
||||
color: {{brandAccent}};
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 12px;
|
||||
color: #1e293b;
|
||||
}
|
||||
.message {
|
||||
margin-top: 1rem;
|
||||
color: #2ecc71;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
color: #64748b;
|
||||
margin: 0;
|
||||
}
|
||||
.message a { color: {{brandAccent}}; text-decoration: none; font-weight: 600; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Email Alert Confirmed</h2>
|
||||
<div class="message">
|
||||
Your alert has been successfully confirmed. You will now receive notifications.
|
||||
</div>
|
||||
{{#brandLogo}}<img class="logo" src="{{brandLogo}}" alt="{{brandName}}" />{{/brandLogo}}
|
||||
<div class="brand">{{brandName}}</div>
|
||||
<h1 class="title">Email confirmed</h1>
|
||||
<p class="message">
|
||||
Your email has been successfully confirmed. You will start receiving notifications shortly.
|
||||
Visit <a href="{{settingsUrl}}">{{brandName}}</a> to manage your notification settings.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Loading…
Reference in a new issue