Polish Live Activity branding and add EAS build config.

Use brand mark and wordmark images in the time clock Live Activity, migrate file copies to the modern expo-file-system File API, and add eas.json for TestFlight production builds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-17 23:39:01 -04:00
parent 6d2711e36e
commit d3b73464e4
8 changed files with 172 additions and 36 deletions
+68 -35
View File
@@ -1,9 +1,61 @@
import { HStack, Text, VStack } from "@expo/ui/swift-ui";
import { font, foregroundStyle, padding } from "@expo/ui/swift-ui/modifiers";
import { HStack, Image, Text, VStack } from "@expo/ui/swift-ui";
import {
font,
foregroundStyle,
frame,
monospacedDigit,
padding,
} from "@expo/ui/swift-ui/modifiers";
import { createLiveActivity, type LiveActivityEnvironment } from "expo-widgets";
import type { TimeClockActivityProps } from "@/lib/time-clock-live-activity.types";
const TIMER_GREEN = "#4ADE80";
const SUBTLE_TEXT = "#E5E5E5";
const MUTED_TEXT = "#D4D4D4";
function ElapsedText({
value,
size,
weight = "semibold",
}: {
value: string;
size: number;
weight?: "regular" | "medium" | "semibold" | "bold";
}) {
return (
<Text
modifiers={[
font({ design: "monospaced", weight, size }),
monospacedDigit(),
foregroundStyle(TIMER_GREEN),
]}
>
{value}
</Text>
);
}
function BrandMark({ uri, size }: { uri?: string; size: number }) {
if (uri) {
return <Image uiImage={uri} modifiers={[frame({ width: size, height: size })]} />;
}
return <Image systemName="dollarsign" color="#FAFAFA" size={size} />;
}
function BrandLogo({ uri, height = 18 }: { uri?: string; height?: number }) {
if (uri) {
return <Image uiImage={uri} modifiers={[frame({ width: 132, height })]} />;
}
return (
<Text modifiers={[font({ weight: "bold", size: 16 }), foregroundStyle("#FFFFFF")]}>
beenvoice
</Text>
);
}
function TimeClockActivity(props: TimeClockActivityProps, _environment: LiveActivityEnvironment) {
"widget";
@@ -13,45 +65,25 @@ function TimeClockActivity(props: TimeClockActivityProps, _environment: LiveActi
return {
banner: (
<HStack modifiers={[padding({ all: 14 })]}>
<Text modifiers={[font({ weight: "bold", size: 14 }), foregroundStyle("#FFFFFF")]}>
beenvoice
</Text>
<Text modifiers={[font({ weight: "bold", size: 20 }), foregroundStyle("#FFFFFF")]}>
{props.elapsedShort}
</Text>
<BrandLogo uri={props.logoImageUri} />
<ElapsedText value={props.elapsedShort} size={20} weight="bold" />
</HStack>
),
compactLeading: (
<Text modifiers={[font({ weight: "bold", size: 11 }), foregroundStyle("#FFFFFF")]}>
bv
</Text>
),
compactTrailing: (
<Text modifiers={[font({ weight: "semibold", size: 14 }), foregroundStyle("#FFFFFF")]}>
{props.elapsedShort}
</Text>
),
minimal: (
<Text modifiers={[font({ weight: "bold", size: 12 }), foregroundStyle("#FFFFFF")]}>
{props.elapsedShort}
</Text>
),
compactLeading: <BrandMark uri={props.markImageUri} size={18} />,
compactTrailing: <ElapsedText value={props.elapsedShort} size={14} />,
minimal: <ElapsedText value={props.elapsedShort} size={12} weight="bold" />,
expandedLeading: (
<VStack modifiers={[padding({ all: 12 })]}>
<Text modifiers={[font({ weight: "bold", size: 16 }), foregroundStyle("#FFFFFF")]}>
beenvoice
</Text>
<Text modifiers={[font({ size: 12 }), foregroundStyle("#E5E5E5")]}>
<BrandLogo uri={props.logoImageUri} height={20} />
<Text modifiers={[font({ size: 12, design: "monospaced" }), foregroundStyle(SUBTLE_TEXT)]}>
{props.clockTime}
</Text>
</VStack>
),
expandedTrailing: (
<VStack modifiers={[padding({ all: 12 })]}>
<Text modifiers={[font({ weight: "bold", size: 32 }), foregroundStyle("#FFFFFF")]}>
{props.elapsedShort}
</Text>
<Text modifiers={[font({ size: 12 }), foregroundStyle("#E5E5E5")]}>elapsed</Text>
<ElapsedText value={props.elapsedShort} size={32} weight="bold" />
<Text modifiers={[font({ size: 12 }), foregroundStyle(SUBTLE_TEXT)]}>elapsed</Text>
</VStack>
),
expandedBottom: (
@@ -60,11 +92,12 @@ function TimeClockActivity(props: TimeClockActivityProps, _environment: LiveActi
{title}
</Text>
{subtitle ? (
<Text modifiers={[font({ size: 13 }), foregroundStyle("#E5E5E5")]}>{subtitle}</Text>
<Text modifiers={[font({ size: 13 }), foregroundStyle(SUBTLE_TEXT)]}>{subtitle}</Text>
) : null}
<Text modifiers={[font({ size: 12 }), foregroundStyle("#D4D4D4")]}>
{props.elapsed} total
</Text>
<HStack>
<ElapsedText value={props.elapsed} size={12} weight="regular" />
<Text modifiers={[font({ size: 12 }), foregroundStyle(MUTED_TEXT)]}> total</Text>
</HStack>
</VStack>
),
};