Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions apps/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@

<!-- Paint the right background immediately, so there is no white flash before the CSS loads. -->
<style>
html, body { margin: 0; background: #f6f5f1; }
@media (prefers-color-scheme: dark) { html, body { background: #141412; color: #efede6; } }
.boot { font-family: system-ui, sans-serif; text-align: center; padding: 40vh 16px 0; color: #6f6c64; }
.boot-header { display: flex; align-items: center; height: 57px; padding: 0 20px; background: #fff; border-bottom: 1px solid #e4e1d8; font: 700 1.2rem system-ui, sans-serif; color: #1c1b18; }
.boot-body { max-width: 620px; margin: 0 auto; padding: 24px 16px; font-family: system-ui, sans-serif; color: #5f5c55; }
.boot-body h1 { margin: 0 0 8px; font-size: 1.4rem; color: #1c1b18; }
@media (prefers-color-scheme: dark) { .boot-header { background: #1d1d1a; border-color: #2c2b27; color: #efede6; } .boot-body { color: #9a978d; } .boot-body h1 { color: #efede6; } }
html, body { margin: 0; background: #f3f4f9; }
@media (prefers-color-scheme: dark) { html, body { background: #0b0d13; color: #eceef5; } }
.boot-header { display: flex; align-items: center; height: 57px; padding: 0 20px; background: #fff; border-bottom: 1px solid #e2e5ee; font: 700 1.2rem system-ui, sans-serif; color: #12141c; }
.boot-body { max-width: 620px; margin: 0 auto; padding: 24px 16px; font-family: system-ui, sans-serif; color: #596073; }
.boot-body h1 { margin: 0 0 8px; font-size: 1.4rem; color: #12141c; }
@media (prefers-color-scheme: dark) { .boot-header { background: #141822; border-color: #262b3b; color: #eceef5; } .boot-body { color: #9aa2b7; } .boot-body h1 { color: #eceef5; } }
</style>

<!--
Expand Down Expand Up @@ -74,7 +73,7 @@

</head>
<body>
<div id="root">
<div id="root">
<div class="boot-header">Commune</div>
<div class="boot-body">
<h1>Commune</h1>
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@commune/shared": "0.1.0",
"@fontsource-variable/bricolage-grotesque": "^5.1.0",
"@tanstack/react-query": "^5.59.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
10 changes: 5 additions & 5 deletions apps/web/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/web/public/icons/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/web/public/icons/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/web/public/icons/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/web/public/icons/maskable-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions apps/web/public/manifest.webmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"scope": "/",
"display": "standalone",
"orientation": "portrait-primary",
"background_color": "#f6f5f1",
"theme_color": "#1f6f5c",
"background_color": "#f3f4f9",
"theme_color": "#1b2559",
"categories": ["social"],
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
Expand Down
289 changes: 172 additions & 117 deletions apps/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import PwaBanner from "./components/PwaBanner";
import ExplorePage from "./pages/ExplorePage";
import LeftNav from "./components/LeftNav";
import RightRail from "./components/RightRail";
import BottomNav from "./components/BottomNav";
import Brand from "./components/BrandMark";
import Icon from "./components/Icon";

const PostPage = lazy(() => import("./pages/PostPage"));
const LoginPage = lazy(() => import("./pages/LoginPage"));
Expand Down Expand Up @@ -84,135 +87,187 @@ function Home() {
return user ? <FeedPage /> : <ExplorePage />;
}

function AppRoutes() {
return (
<Suspense fallback={<p className="muted center route-loading">Loading…</p>}>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/explore" element={<ExplorePage />} />
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
<Route path="/reset-password" element={<ResetPasswordPage />} />
<Route path="/verify-email" element={<VerifyEmailPage />} />
<Route path="/" element={<Home />} />
<Route
path="/posts/:id"
element={
<Protected>
<PostPage />
</Protected>
}
/>
<Route
path="/u/:username"
element={
<Protected>
<ProfilePage />
</Protected>
}
/>
<Route
path="/notifications"
element={
<Protected>
<NotificationsPage />
</Protected>
}
/>
<Route
path="/admin"
element={
<Protected>
<AdminPage />
</Protected>
}
/>

<Route
path="/communities"
element={
<Protected>
<CommunitiesPage />
</Protected>
}
/>
<Route
path="/c/:slug"
element={
<Protected>
<CommunityPage />
</Protected>
}
/>
<Route
path="/search"
element={
<Protected>
<SearchPage />
</Protected>
}
/>
<Route
path="/plus"
element={
<Protected>
<PlusPage />
</Protected>
}
/>
<Route
path="/insights"
element={
<Protected>
<InsightsPage />
</Protected>
}
/>
<Route path="/news" element={<NewsPage />} />
<Route path="/contact" element={<ContactPage />} />
<Route
path="/messages"
element={
<Protected>
<MessagesPage />
</Protected>
}
/>
<Route
path="/messages/:id"
element={
<Protected>
<MessagesPage />
</Protected>
}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
);
}

/** Left panel of the sign-in screens (hidden on phones). */
function AuthArt() {
return (
<aside className="auth-art" aria-hidden="true">
<Brand size={40} />
<div className="auth-art-body">
<p className="art-title">Your people, your news, one open place.</p>
<ul>
<li>
<Icon name="users" size={20} /> Join communities and follow people
</li>
<li>
<Icon name="mail" size={20} /> Message friends privately
</li>
<li>
<Icon name="news" size={20} /> Live news beside your feed
</li>
</ul>
</div>
<span className="blob b1" />
<span className="blob b2" />
<span className="blob b3" />
</aside>
);
}

export default function App() {
const { pathname } = useLocation();
const { user } = useAuth();
const authPage = AUTH_PATHS.includes(pathname);
// Messages need room for two panes, so that page drops the news column.
const wide = pathname.startsWith("/messages");

const skip = (
<a href="#main" className="skip-link">
Skip to content
</a>
);

if (authPage) {
return (
<>
{skip}
<RouteMeta />
<PwaBanner />
<div className="auth-split">
<AuthArt />
<main id="main" tabIndex={-1} className="auth-main">
<Link to="/" className="auth-brand" aria-label="Commune home">
<Brand size={36} />
</Link>
<AppRoutes />
</main>
</div>
</>
);
}

return (
<>
<a href="#main" className="skip-link">
Skip to content
</a>
{skip}
<RouteMeta />
<Header />
{!authPage && <VerifyBanner />}
<VerifyBanner />
<PwaBanner />
<div className={authPage ? "shell-auth" : `shell${user ? " has-left" : ""}${wide ? " wide" : ""}`}>
{!authPage && user && <LeftNav />}
<main id="main" tabIndex={-1} className={authPage ? "container container-auth" : "container"}>
{authPage && (
<Link to="/" className="brand auth-brand">
Commune
</Link>
)}
<Suspense fallback={<p className="muted center route-loading">Loading…</p>}>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/explore" element={<ExplorePage />} />
<Route path="/forgot-password" element={<ForgotPasswordPage />} />
<Route path="/reset-password" element={<ResetPasswordPage />} />
<Route path="/verify-email" element={<VerifyEmailPage />} />
<Route path="/" element={<Home />} />
<Route
path="/posts/:id"
element={
<Protected>
<PostPage />
</Protected>
}
/>
<Route
path="/u/:username"
element={
<Protected>
<ProfilePage />
</Protected>
}
/>
<Route
path="/notifications"
element={
<Protected>
<NotificationsPage />
</Protected>
}
/>
<Route
path="/admin"
element={
<Protected>
<AdminPage />
</Protected>
}
/>

<Route
path="/communities"
element={
<Protected>
<CommunitiesPage />
</Protected>
}
/>
<Route
path="/c/:slug"
element={
<Protected>
<CommunityPage />
</Protected>
}
/>
<Route
path="/search"
element={
<Protected>
<SearchPage />
</Protected>
}
/>
<Route
path="/plus"
element={
<Protected>
<PlusPage />
</Protected>
}
/>
<Route
path="/insights"
element={
<Protected>
<InsightsPage />
</Protected>
}
/>
<Route path="/news" element={<NewsPage />} />
<Route path="/contact" element={<ContactPage />} />
<Route
path="/messages"
element={
<Protected>
<MessagesPage />
</Protected>
}
/>
<Route
path="/messages/:id"
element={
<Protected>
<MessagesPage />
</Protected>
}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</main>
{!authPage && !wide && <RightRail />}
<div className={`shell${user ? " has-left" : ""}${wide ? " wide" : ""}`}>
{user && <LeftNav />}
<main id="main" tabIndex={-1} className="container">
<AppRoutes />
</main>
{!wide && <RightRail />}
</div>
<BottomNav />
</>
);
}
8 changes: 7 additions & 1 deletion apps/web/src/components/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assetUrl } from "../lib/api";
import { hueFor } from "../lib/hue";

/** Profile photo, or a colored circle with the user's initial when there is none. */
export default function Avatar({
Expand All @@ -14,8 +15,13 @@ export default function Avatar({
if (url) {
return <img className="avatar" src={assetUrl(url)} alt="" style={style} loading="lazy" />;
}
const hue = hueFor(username);
return (
<span className="avatar avatar-fallback" style={style} aria-hidden="true">
<span
className="avatar avatar-fallback"
style={{ ...style, background: hue.bg, color: hue.fg }}
aria-hidden="true"
>
{username.charAt(0).toUpperCase()}
</span>
);
Expand Down
Loading
Loading