fix(mobile): dark mode on auth screens + RepostCard, expand .easignore
Sign-in/sign-up and RepostCard used the static (light-only) color tokens instead of useTheme() — in dark mode the login screen kept a light background with light-theme-colored text baked in, and RepostCard's text color was hardcoded independent of its (already theme-aware) surrounding background, both landing on illegible low-contrast text. Same bug class as earlier dark-mode fixes this session, converted the same way (useTheme() + makeStyles(colors)). Also add a root-level .easignore (EAS Build's archive root may resolve above mobile/ for monorepo purposes) excluding backend/tooling directories the mobile app never needs at build or runtime (.claude, .impeccable, .planning, docker, prisma — the last is only a type-only dependency via mobile's tRPC router import, erased before Metro bundles anything).
This commit is contained in:
1 parent
212cff942b
commit
c04b69a11f
5 files changed
+90
-46
No files matched your search
+24
@@ -0,0 +1,24 @@
|
||||
# In case EAS Build's archive root resolves to this repo root rather than
|
||||
# mobile/ (it has its own .easignore too) — these are backend/tooling
|
||||
# directories the mobile app never needs at build or runtime. mobile/'s
|
||||
# only link to this repo is a `import type` (tRPC router shape) that's
|
||||
# erased before Metro ever bundles anything, so none of this needs to be
|
||||
# present for a build to succeed.
|
||||
|
||||
.claude
|
||||
.impeccable
|
||||
.planning
|
||||
docker
|
||||
|
||||
# Type-only dependency of mobile/'s tRPC import chain — needed for local
|
||||
# `tsc` checks, never bundled into the app (type-only imports are erased
|
||||
# before Metro sees them).
|
||||
prisma
|
||||
|
||||
# Already excluded from git; listed here too since .easignore isn't
|
||||
# strictly limited to git-tracked files.
|
||||
pentest-ai-agents
|
||||
scaffold-tmp
|
||||
node_modules
|
||||
.next
|
||||
.git
|
||||
@@ -15,6 +15,7 @@
|
||||
.idea
|
||||
.expo
|
||||
.vscode
|
||||
.claude
|
||||
|
||||
# Never needed — EAS installs dependencies itself on the build worker.
|
||||
node_modules
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { View, Text, Pressable, StyleSheet } from "react-native";
|
||||
import { useSignIn } from "@clerk/expo";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button } from "../../src/components/Button";
|
||||
import { TextField } from "../../src/components/TextField";
|
||||
import { colors, typography } from "../../src/theme/tokens";
|
||||
import { useTheme } from "../../src/context/ThemeContext";
|
||||
import { getTypography, type ColorTokens, type Typography } from "../../src/theme/tokens";
|
||||
|
||||
/**
|
||||
* Minimal email/password sign-in. Social sign-in is still follow-up work;
|
||||
@@ -24,6 +25,8 @@ export default function SignInScreen() {
|
||||
const { t } = useTranslation();
|
||||
const { signIn, fetchStatus } = useSignIn();
|
||||
const router = useRouter();
|
||||
const { colors } = useTheme();
|
||||
const styles = useMemo(() => makeStyles(colors), [colors]);
|
||||
const [emailAddress, setEmailAddress] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [code, setCode] = useState("");
|
||||
@@ -117,16 +120,19 @@ export default function SignInScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
padding: 24,
|
||||
gap: 12,
|
||||
backgroundColor: colors.porchWhite,
|
||||
},
|
||||
title: { ...typography.headline, marginBottom: 16 },
|
||||
hint: { ...typography.body, color: colors.quietGray, marginBottom: 8 },
|
||||
error: { ...typography.body, color: colors.alertRed },
|
||||
link: { ...typography.body, color: colors.marigoldDeep, textAlign: "center", marginTop: 8 },
|
||||
});
|
||||
function makeStyles(colors: ColorTokens) {
|
||||
const typography: Typography = getTypography(colors);
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
padding: 24,
|
||||
gap: 12,
|
||||
backgroundColor: colors.porchWhite,
|
||||
},
|
||||
title: { ...typography.headline, marginBottom: 16 },
|
||||
hint: { ...typography.body, color: colors.quietGray, marginBottom: 8 },
|
||||
error: { ...typography.body, color: colors.alertRed },
|
||||
link: { ...typography.body, color: colors.marigoldDeep, textAlign: "center", marginTop: 8 },
|
||||
});
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { View, Text, Pressable, StyleSheet } from "react-native";
|
||||
import { useSignUp } from "@clerk/expo";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button } from "../../src/components/Button";
|
||||
import { TextField } from "../../src/components/TextField";
|
||||
import { colors, typography } from "../../src/theme/tokens";
|
||||
import { useTheme } from "../../src/context/ThemeContext";
|
||||
import { getTypography, type ColorTokens, type Typography } from "../../src/theme/tokens";
|
||||
|
||||
/**
|
||||
* Email/password sign-up — the mobile app's other half of sign-in.tsx (that
|
||||
@@ -21,6 +22,8 @@ export default function SignUpScreen() {
|
||||
const { t } = useTranslation();
|
||||
const { signUp, fetchStatus } = useSignUp();
|
||||
const router = useRouter();
|
||||
const { colors } = useTheme();
|
||||
const styles = useMemo(() => makeStyles(colors), [colors]);
|
||||
const [emailAddress, setEmailAddress] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [code, setCode] = useState("");
|
||||
@@ -114,16 +117,19 @@ export default function SignUpScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
padding: 24,
|
||||
gap: 12,
|
||||
backgroundColor: colors.porchWhite,
|
||||
},
|
||||
title: { ...typography.headline, marginBottom: 16 },
|
||||
hint: { ...typography.body, color: colors.quietGray, marginBottom: 8 },
|
||||
error: { ...typography.body, color: colors.alertRed },
|
||||
link: { ...typography.body, color: colors.marigoldDeep, textAlign: "center", marginTop: 8 },
|
||||
});
|
||||
function makeStyles(colors: ColorTokens) {
|
||||
const typography: Typography = getTypography(colors);
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
padding: 24,
|
||||
gap: 12,
|
||||
backgroundColor: colors.porchWhite,
|
||||
},
|
||||
title: { ...typography.headline, marginBottom: 16 },
|
||||
hint: { ...typography.body, color: colors.quietGray, marginBottom: 8 },
|
||||
error: { ...typography.body, color: colors.alertRed },
|
||||
link: { ...typography.body, color: colors.marigoldDeep, textAlign: "center", marginTop: 8 },
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useMemo } from "react";
|
||||
import { View, Text, Pressable, StyleSheet, useWindowDimensions } from "react-native";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -5,7 +6,8 @@ import { Image } from "expo-image";
|
||||
import { PawPrint, Video, Trophy } from "lucide-react-native";
|
||||
import { PetAvatar } from "./PetAvatar";
|
||||
import { getMediaUrl } from "../lib/media-url";
|
||||
import { colors, typography, radii } from "../theme/tokens";
|
||||
import { useTheme } from "../context/ThemeContext";
|
||||
import { getTypography, radii, type ColorTokens, type Typography } from "../theme/tokens";
|
||||
import type { PostCardPost } from "./PostCard";
|
||||
|
||||
type Props = {
|
||||
@@ -25,6 +27,8 @@ export function RepostCard({ post }: Props) {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { width } = useWindowDimensions();
|
||||
const { colors } = useTheme();
|
||||
const styles = useMemo(() => makeStyles(colors), [colors]);
|
||||
const cardWidth = width - 32;
|
||||
const originalPost = post.repost?.originalPost;
|
||||
|
||||
@@ -72,18 +76,21 @@ export function RepostCard({ post }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: { gap: 8 },
|
||||
attribution: { flexDirection: "row", alignItems: "center", gap: 6 },
|
||||
attributionText: { ...typography.label, textTransform: "none", letterSpacing: 0, color: colors.quietGray },
|
||||
header: { flexDirection: "row", alignItems: "center", gap: 8 },
|
||||
name: { ...typography.body, fontFamily: typography.title.fontFamily },
|
||||
caption: { ...typography.body },
|
||||
placeholder: {
|
||||
aspectRatio: 1.2,
|
||||
borderRadius: radii.md,
|
||||
backgroundColor: colors.ink,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
});
|
||||
function makeStyles(colors: ColorTokens) {
|
||||
const typography: Typography = getTypography(colors);
|
||||
return StyleSheet.create({
|
||||
card: { gap: 8 },
|
||||
attribution: { flexDirection: "row", alignItems: "center", gap: 6 },
|
||||
attributionText: { ...typography.label, textTransform: "none", letterSpacing: 0, color: colors.quietGray },
|
||||
header: { flexDirection: "row", alignItems: "center", gap: 8 },
|
||||
name: { ...typography.body, fontFamily: typography.title.fontFamily },
|
||||
caption: { ...typography.body },
|
||||
placeholder: {
|
||||
aspectRatio: 1.2,
|
||||
borderRadius: radii.md,
|
||||
backgroundColor: colors.ink,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user