+96
-150
src/templates.rs
+96
-150
src/templates.rs
···
1
-
pub fn login_page() -> &'static str {
1
+
pub fn landing_page() -> &'static str {
2
2
r#"
3
3
<!DOCTYPE html>
4
4
<html>
···
102
102
z-index: 10;
103
103
}
104
104
105
-
.login-card {
105
+
.search-card {
106
106
background: transparent;
107
107
border: 1px solid rgba(255, 255, 255, 0.1);
108
108
padding: 2.5rem 3rem;
109
109
border-radius: 8px;
110
110
backdrop-filter: blur(2px);
111
111
text-align: center;
112
-
box-shadow: none;
113
-
max-width: min(450px, 90vw);
112
+
max-width: min(500px, 90vw);
114
113
}
115
114
116
115
h1 {
···
168
167
border-color: rgba(255, 255, 255, 0.4);
169
168
}
170
169
171
-
.hidden { display: none; }
172
-
.loading { color: rgba(255, 255, 255, 0.5); font-size: 0.9rem; }
173
-
174
-
.demo-btn {
175
-
font-family: inherit;
176
-
font-size: 0.9rem;
177
-
padding: 0.75rem 2rem;
178
-
cursor: pointer;
179
-
background: transparent;
180
-
border: 1px solid rgba(255, 255, 255, 0.15);
181
-
border-radius: 4px;
182
-
color: rgba(255, 255, 255, 0.6);
183
-
transition: all 0.2s;
184
-
width: 100%;
185
-
margin-top: 0.75rem;
186
-
}
187
-
188
-
.demo-btn:hover {
189
-
background: rgba(10, 10, 15, 0.5);
190
-
border-color: rgba(255, 255, 255, 0.3);
191
-
color: rgba(255, 255, 255, 0.8);
192
-
}
193
-
194
170
.divider {
195
171
display: flex;
196
172
align-items: center;
···
208
184
background: rgba(255, 255, 255, 0.1);
209
185
}
210
186
187
+
.suggestions {
188
+
display: flex;
189
+
gap: 0.75rem;
190
+
flex-wrap: wrap;
191
+
justify-content: center;
192
+
}
193
+
194
+
.suggestion-btn {
195
+
font-family: inherit;
196
+
font-size: 0.8rem;
197
+
padding: 0.5rem 1rem;
198
+
cursor: pointer;
199
+
background: transparent;
200
+
border: 1px solid rgba(255, 255, 255, 0.15);
201
+
border-radius: 4px;
202
+
color: rgba(255, 255, 255, 0.6);
203
+
transition: all 0.2s;
204
+
width: auto;
205
+
}
206
+
207
+
.suggestion-btn:hover {
208
+
background: rgba(10, 10, 15, 0.5);
209
+
border-color: rgba(255, 255, 255, 0.3);
210
+
color: rgba(255, 255, 255, 0.8);
211
+
}
212
+
211
213
.info-toggle {
212
214
margin-top: 1.5rem;
213
215
color: rgba(255, 255, 255, 0.5);
···
301
303
<div class="atmosphere" id="atmosphere"></div>
302
304
303
305
<div class="container">
304
-
<div class="login-card">
305
-
<div id="restoring" class="loading hidden">restoring session...</div>
306
-
<form id="loginForm" method="post" action="/login">
307
-
<h1>@me</h1>
308
-
<div class="subtitle">explore the atmosphere</div>
309
-
<input type="text" name="handle" placeholder="handle.bsky.social" required autofocus>
310
-
<button type="submit">enter</button>
306
+
<div class="search-card">
307
+
<h1>@me</h1>
308
+
<div class="subtitle">explore the atmosphere</div>
309
+
<form id="searchForm" onsubmit="event.preventDefault(); handleSearch();">
310
+
<input type="text" id="handleInput" placeholder="enter any handle" autofocus>
311
+
<button type="submit">explore</button>
312
+
</form>
311
313
312
-
<div class="divider">or</div>
313
-
<button type="button" class="demo-btn" id="demoBtn">explore demo</button>
314
+
<div class="divider">try these</div>
315
+
<div class="suggestions">
316
+
<button class="suggestion-btn" onclick="viewHandle('pfrazee.com')">pfrazee.com</button>
317
+
<button class="suggestion-btn" onclick="viewHandle('jay.bsky.team')">jay.bsky.team</button>
318
+
<button class="suggestion-btn" onclick="viewHandle('why.bsky.team')">why.bsky.team</button>
319
+
</div>
314
320
315
-
<button type="button" class="info-toggle" id="infoToggle">what is this?</button>
321
+
<button type="button" class="info-toggle" onclick="toggleInfo()">what is this?</button>
316
322
317
-
<div class="info-content" id="infoContent">
318
-
<div class="info-section">
319
-
<h3>your posts should be yours</h3>
320
-
<p>built 10k followers? wrote years of posts? on most platforms, if you leave, you lose it all. they own your network, not you.</p>
323
+
<div class="info-content" id="infoContent">
324
+
<div class="info-section">
325
+
<h3>your posts should be yours</h3>
326
+
<p>built 10k followers? wrote years of posts? on most platforms, if you leave, you lose it all. they own your network, not you.</p>
321
327
322
-
<h3>what if social media worked like email?</h3>
323
-
<p>with email, you can switch from gmail to protonmail and keep your contacts. same idea here: your posts and followers live on your own server (called a <a href="https://atproto.com/guides/data-repos" target="_blank" rel="noopener noreferrer">Personal Data Server</a>). apps like bluesky just connect to it.</p>
328
+
<h3>what if social media worked like email?</h3>
329
+
<p>with email, you can switch from gmail to protonmail and keep your contacts. same idea here: your posts and followers live on your own server (called a <a href="https://atproto.com/guides/data-repos" target="_blank" rel="noopener noreferrer">Personal Data Server</a>). apps like bluesky just connect to it.</p>
324
330
325
-
<h3>see it in action</h3>
326
-
<p>click "explore demo" to see how <a href="https://atproto.com" target="_blank" rel="noopener noreferrer">atproto</a> stores someone's real social data, or log in to explore your own.</p>
327
-
</div>
331
+
<h3>see it in action</h3>
332
+
<p>enter any handle above to see how <a href="https://atproto.com" target="_blank" rel="noopener noreferrer">atproto</a> stores their social data.</p>
328
333
</div>
329
-
</form>
334
+
</div>
330
335
</div>
331
336
</div>
332
337
···
334
339
by <a href="https://bsky.app/profile/zzstoatzz.io" target="_blank" rel="noopener noreferrer">@zzstoatzz.io</a>
335
340
</div>
336
341
337
-
<script src="/static/login.js"></script>
342
+
<script>
343
+
function handleSearch() {
344
+
const handle = document.getElementById('handleInput').value.trim();
345
+
if (handle) {
346
+
viewHandle(handle);
347
+
}
348
+
}
349
+
350
+
function viewHandle(handle) {
351
+
window.location.href = '/view?handle=' + encodeURIComponent(handle);
352
+
}
353
+
354
+
function toggleInfo() {
355
+
document.getElementById('infoContent').classList.toggle('expanded');
356
+
}
357
+
</script>
338
358
</body>
339
359
</html>
340
360
"#
341
361
}
342
362
343
-
pub fn app_page(did: &str, demo_mode: bool, demo_handle: Option<&str>) -> String {
344
-
let demo_banner = if demo_mode && demo_handle.is_some() {
345
-
format!(r#"
346
-
<div class="demo-banner" id="demoBanner">
347
-
<span>demo mode - viewing <strong>{}</strong></span>
348
-
<a href="/demo/exit" class="demo-exit">exit demo</a>
349
-
</div>"#, demo_handle.unwrap())
350
-
} else {
351
-
String::new()
352
-
};
353
-
363
+
pub fn app_page(did: &str) -> String {
354
364
format!(r#"
355
365
<!DOCTYPE html>
356
366
<html>
···
417
427
display: flex;
418
428
align-items: center;
419
429
justify-content: center;
420
-
}}
421
-
422
-
.logout {{
423
-
position: fixed;
424
-
top: clamp(1rem, 2vmin, 1.5rem);
425
-
right: clamp(1rem, 2vmin, 1.5rem);
426
-
font-size: clamp(0.65rem, 1.4vmin, 0.75rem);
427
-
color: var(--text-light);
428
-
text-decoration: none;
429
-
border: 1px solid var(--border);
430
-
padding: clamp(0.4rem, 1vmin, 0.5rem) clamp(0.8rem, 2vmin, 1rem);
431
-
transition: all 0.2s ease;
432
-
z-index: 100;
433
-
-webkit-tap-highlight-color: transparent;
434
-
cursor: pointer;
435
-
border-radius: 2px;
436
-
display: flex;
437
-
align-items: center;
438
-
}}
439
-
440
-
.logout:hover, .logout:active {{
441
-
background: var(--surface);
442
-
color: var(--text);
443
-
border-color: var(--text-light);
444
430
}}
445
431
446
432
.info {{
···
1325
1311
color: var(--text);
1326
1312
}}
1327
1313
1314
+
.home-btn {{
1315
+
position: fixed;
1316
+
top: clamp(1rem, 2vmin, 1.5rem);
1317
+
right: clamp(1rem, 2vmin, 1.5rem);
1318
+
font-family: inherit;
1319
+
font-size: clamp(0.65rem, 1.4vmin, 0.75rem);
1320
+
color: var(--text-light);
1321
+
border: 1px solid var(--border);
1322
+
background: var(--bg);
1323
+
padding: clamp(0.4rem, 1vmin, 0.5rem) clamp(0.8rem, 2vmin, 1rem);
1324
+
transition: all 0.2s ease;
1325
+
z-index: 100;
1326
+
cursor: pointer;
1327
+
border-radius: 2px;
1328
+
text-decoration: none;
1329
+
display: inline-flex;
1330
+
align-items: center;
1331
+
}}
1332
+
1333
+
.home-btn:hover {{
1334
+
background: var(--surface);
1335
+
color: var(--text);
1336
+
border-color: var(--text-light);
1337
+
}}
1338
+
1328
1339
.watch-live-btn {{
1329
1340
position: fixed;
1330
1341
top: clamp(1rem, 2vmin, 1.5rem);
···
1438
1449
max-width: none;
1439
1450
}}
1440
1451
}}
1441
-
1442
-
.demo-banner {{
1443
-
position: fixed;
1444
-
top: 0;
1445
-
left: 0;
1446
-
right: 0;
1447
-
background: rgba(255, 165, 0, 0.15);
1448
-
border-bottom: 1px solid rgba(255, 165, 0, 0.3);
1449
-
padding: 0.5rem 1rem;
1450
-
display: flex;
1451
-
align-items: center;
1452
-
justify-content: center;
1453
-
gap: 1rem;
1454
-
z-index: 200;
1455
-
font-size: 0.7rem;
1456
-
color: var(--text);
1457
-
}}
1458
-
1459
-
.demo-banner strong {{
1460
-
color: var(--text);
1461
-
font-weight: 600;
1462
-
}}
1463
-
1464
-
.demo-exit {{
1465
-
color: var(--text-light);
1466
-
text-decoration: none;
1467
-
border: 1px solid var(--border);
1468
-
padding: 0.25rem 0.75rem;
1469
-
border-radius: 2px;
1470
-
transition: all 0.2s ease;
1471
-
font-size: 0.65rem;
1472
-
}}
1473
-
1474
-
.demo-exit:hover {{
1475
-
background: var(--surface);
1476
-
border-color: var(--text-light);
1477
-
color: var(--text);
1478
-
}}
1479
-
1480
-
@media (prefers-color-scheme: dark) {{
1481
-
.demo-banner {{
1482
-
background: rgba(255, 165, 0, 0.1);
1483
-
border-bottom-color: rgba(255, 165, 0, 0.25);
1484
-
}}
1485
-
}}
1486
-
1487
-
/* Adjust elements when demo banner is present */
1488
-
.demo-banner ~ .info {{
1489
-
top: calc(clamp(1rem, 2vmin, 1.5rem) + 2.5rem);
1490
-
}}
1491
-
1492
-
.demo-banner ~ .watch-live-btn {{
1493
-
top: calc(clamp(1rem, 2vmin, 1.5rem) + 2.5rem);
1494
-
}}
1495
-
1496
-
.demo-banner ~ .logout {{
1497
-
top: calc(clamp(1rem, 2vmin, 1.5rem) + 2.5rem);
1498
-
}}
1499
-
1500
-
@media (max-width: 768px) {{
1501
-
.demo-banner ~ .watch-live-btn {{
1502
-
top: calc(clamp(4rem, 8vmin, 5rem) + 2.5rem);
1503
-
}}
1504
-
}}
1505
1452
</style>
1506
1453
</head>
1507
1454
<body>
1508
-
{}
1509
1455
<div class="info" id="infoBtn">?</div>
1456
+
<a href="/" class="home-btn">home</a>
1510
1457
<button class="watch-live-btn" id="watchLiveBtn">
1511
1458
<span class="watch-indicator"></span>
1512
1459
<span class="watch-label">watch live</span>
1513
1460
</button>
1514
-
<a href="javascript:void(0)" id="logoutBtn" class="logout">logout</a>
1515
1461
1516
1462
<div class="firehose-toast" id="firehoseToast">
1517
1463
<div class="firehose-toast-action"></div>
···
1556
1502
<script src="/static/onboarding.js"></script>
1557
1503
</body>
1558
1504
</html>
1559
-
"#, demo_banner, did)
1505
+
"#, did)
1560
1506
}