d3b73464e4
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>
107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
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";
|
|
|
|
const title = props.description.trim() || "Timer running";
|
|
const subtitle = [props.clientName, props.invoiceLabel].filter(Boolean).join(" · ");
|
|
|
|
return {
|
|
banner: (
|
|
<HStack modifiers={[padding({ all: 14 })]}>
|
|
<BrandLogo uri={props.logoImageUri} />
|
|
<ElapsedText value={props.elapsedShort} size={20} weight="bold" />
|
|
</HStack>
|
|
),
|
|
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 })]}>
|
|
<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 })]}>
|
|
<ElapsedText value={props.elapsedShort} size={32} weight="bold" />
|
|
<Text modifiers={[font({ size: 12 }), foregroundStyle(SUBTLE_TEXT)]}>elapsed</Text>
|
|
</VStack>
|
|
),
|
|
expandedBottom: (
|
|
<VStack modifiers={[padding({ horizontal: 12, bottom: 12 })]}>
|
|
<Text modifiers={[font({ weight: "semibold", size: 15 }), foregroundStyle("#FFFFFF")]}>
|
|
{title}
|
|
</Text>
|
|
{subtitle ? (
|
|
<Text modifiers={[font({ size: 13 }), foregroundStyle(SUBTLE_TEXT)]}>{subtitle}</Text>
|
|
) : null}
|
|
<HStack>
|
|
<ElapsedText value={props.elapsed} size={12} weight="regular" />
|
|
<Text modifiers={[font({ size: 12 }), foregroundStyle(MUTED_TEXT)]}> total</Text>
|
|
</HStack>
|
|
</VStack>
|
|
),
|
|
};
|
|
}
|
|
|
|
export default createLiveActivity("TimeClockActivity", TimeClockActivity);
|