Skip to content
9 changes: 0 additions & 9 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@
"value": "same-origin"
}
]
},
{
"source": "/@(service-worker|firebase-messaging-sw).js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
}
]
}
]
},
Expand Down
94 changes: 46 additions & 48 deletions functions/src/prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,34 @@ import express from 'express';
import { getFirestore } from 'firebase-admin/firestore';
import * as functions from 'firebase-functions';
import fetch from 'node-fetch';
import url, { URL } from 'url';

const app = express();

const getSiteDomain = async () => {
const doc = await getFirestore().collection('config').doc('site').get();
return doc.data().domain;
};

const getRendertronServer = async () => {
const doc = await getFirestore().collection('config').doc('rendertron').get();
return doc.data().server;
};

/**
* generateUrl() - Piece together request parts to form FQDN URL
* @param {Object} request
*/
const generateUrl = async (request) => {
// Why do we use config site.domain instead of the domain from
// the request? Because it'll give you the wrong domain (pointed at the
// cloudfunctions.net)
return url.format({
protocol: request.protocol,
host: await getSiteDomain(),
pathname: request.originalUrl,
});
const normalizeHost = (h: string) =>
h.replace(/^https?:\/\//, '').replace(/\/+$/, '');

const resolveHost = (req): string => {
// 1. Prefer Hosting/CDN header
const headerHost =
req.get('x-forwarded-host') || req.get('host') || req.hostname;

if (headerHost) {
return normalizeHost(headerHost);
}

// 2. Fallback to Firebase config
const cfgHost = functions.config()?.site?.domain as string | undefined;
if (cfgHost) {
return normalizeHost(cfgHost);
}

// 3. Last fallback (safe default for dev)
return 'localhost:5000';
};

/**
Expand All @@ -55,38 +56,35 @@ const checkForBots = (userAgent) => {
//
// The trick is on L66, pwaShell(): You must update that file! Open for explainer.
app.get('*', async (req, res) => {
// What say you bot tester?
const host = resolveHost(req);
const botResult = checkForBots(req.headers['user-agent']);

if (botResult) {
// Get me the url all nice
const targetUrl = generateUrl(req);

// Did you read the README? You should have set rendertron document
// to where ever you deployed https://github.com/GoogleChrome/rendertron on AppEngine
fetch(`${await getRendertronServer()}/render/${targetUrl}`)
.then((res) => res.text())
.then((body) => {
// We set Vary because we only want to cache this result for the bots
// which we know based on the user-agent. Vary is very useful.
// Reading about Vary header:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
// https://www.fastly.com/blog/best-practices-using-vary-header/
res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.set('Vary', 'User-Agent');

res.send(body.toString());
});
} else {
// 1. Umm, Justin, why not just point to index.html?
// 2. Umm, Justin, why not just fetch() index.html from the domain?
//
// Valid things to ask internet peoples
// 1. function doesn't know about the public hosting as far as I can tell (docs don't offer opinion/example)
// 2. Could fetch and return...but I found copy+paste the index.html PWA shell into file returns faster
// const indexHTML = fs.readFileSync('./index.html').toString();
const path = new URL('./index.html', import.meta.url).pathname;
res.sendFile(path);
// Bot path via Rendertron (you can keep your caching here if you want)
const targetUrl = `https://${host}${req.originalUrl}`;
const rendertron = await getRendertronServer();

const botResp = await fetch(`${rendertron}/render/${targetUrl}`);
const body = await botResp.text();

res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.set('Vary', 'User-Agent');
return res.send(body.toString());
}

// ✅ Non-bot path: fetch the current Hosting HTML so it’s never stale
const htmlResp = await fetch(`https://${host}/index.html`, {
// prevent node-fetch from reusing cached responses
headers: { 'Cache-Control': 'no-cache' }
});
const html = await htmlResp.text();

// No-cache for HTML so users revalidate on each load
res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
res.set('Pragma', 'no-cache');
res.set('Expires', '0');

return res.status(htmlResp.status || 200).send(html);
});

export const prerender = functions.https.onRequest(app);
38 changes: 38 additions & 0 deletions public/data/meet-the-talent.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,44 @@
"name": "X/Twitter"
}
]
},{
"fullName": "Jaydip Umaretiya",
"location": "Surat, Gujarat, India",
"bio": "Experienced Android developer with 10+ years of expertise in building native mobile and TV applications, including digital signage solutions. Proficient in Kotlin, Java, Jetpack Compose, and native libraries, with strong skills in creating modern, responsive UIs. Well-versed in Kotlin Multiplatform (KMP) and Compose Multiplatform (CMP) to deliver scalable cross-platform solutions. Adept at project leadership, team mentoring, and managing complex, high-impact applications. Committed to innovation, exceeding client expectations, and fostering long-term partnerships.",
"email": "jaynumaretiya@gmail.com",
"phone": "+91-9510086772",
"imageUrl": "https://www.jaydip.tech/static/media/img-mobile.ec99727dfdae5c2cdd64.png",
"website": "https://jaydip.tech/",
"skills": [
"Android",
"Kotlin",
"Jetpack Compose",
"Android TV Development",
"Kotlin MultiPlatform",
"Compose MultiPlatform"
],
"links": [
{
"icon": "website",
"link": "https://jaydip.tech/",
"name": "Portfolio"
},
{
"icon": "github",
"link": "https://github.com/jaydipumaretiya",
"name": "Github"
},
{
"icon": "linkedin",
"link": "https://www.linkedin.com/in/jaydipumaretiya",
"name": "LinkedIn"
},
{
"icon": "twitter",
"link": "https://x.com/jaydipumaretiya",
"name": "X/Twitter"
}
]
}
]
}
16 changes: 0 additions & 16 deletions rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,6 @@ import { compileBufferTemplate, production } from './utils/build';
const { ROLLUP_WATCH } = process.env;

export default [
{
input: 'src/firebase-messaging-sw.ts',
treeshake: production,
output: {
file: 'dist/firebase-messaging-sw.js',
sourcemap: production,
},
plugins: [
nodeResolve(),
typescript({
noEmitOnError: true,
sourceMap: production,
}),
production && terser(),
],
},
{
treeshake: production,
output: {
Expand Down
42 changes: 0 additions & 42 deletions src/firebase-messaging-sw.ts

This file was deleted.

46 changes: 46 additions & 0 deletions src/pages/registration-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,39 @@ export class RegistrationPage extends PolymerElement {
font-weight: 700;
padding-bottom: 8px;
}

.ticket-coupon-info {
margin: 32px 0;
padding: 24px;
background-color: #fef7f7;
border-left: 6px solid #e53935;
border-radius: 10px;
font-size: 16px;
line-height: 1.6;
color: #333;
}

.ticket-coupon-info strong {
font-weight: bold;
}

.ticket-coupon-info ul {
list-style: none;
padding-left: 8px;
margin: 12px 0;
}

.ticket-coupon-info ul li::before {
content: '';
margin-right: 8px;
}

@media (max-width: 768px) {
.ticket-coupon-info {
font-size: 15px;
padding: 20px;
}
}
</style>

<simple-hero page="registration"></simple-hero>
Expand Down Expand Up @@ -408,6 +441,19 @@ export class RegistrationPage extends PolymerElement {
<p>This helps us avoid overcrowding and ensures that everyone gets the most out of the sessions they’re truly
passionate about.</p>
</div>
<section class="ticket-coupon-info">
<p>🚫 <strong>Coupon code? Seriously?!</strong></p>
<p>🎟️ અમારી ટિકિટની કિંમત પહેલાંથી જ community ને ધ્યાનમાં રાખીને રાખવામાં આવી છે — it's already a highly subsidized price considering the amazing value you get!</p>
<ul>
<li>🍱 Delicious food.</li>
<li>👕 Swags you’ll love.</li>
<li>🧠 Expert talks.</li>
<li>💡 Immense learning.</li>
<li>🎉 And a full-day networking with like-minded tech folks.</li>
</ul>
<p>💬 Coupon code માંગીને શરમાવશો નહીં — એક દિવસ પિઝ્ઝા પાર્ટી ના ખર્ચે, તમારું ભવિષ્ય સુધારવાની તક છે.</p>
<p>👉 <strong>Knowledge મા investment કરશો, regret નહીં થાય.</strong></p>
</section>
<section class="ticket-types">
<h1>Ticket Types</h1>
<div class="ticket-container">
Expand Down