Files
jrshikoku/components/AndroidWidget/ShortcutWidget.tsx

276 lines
6.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from "react";
import { FlexWidget, TextWidget } from "react-native-android-widget";
import dayjs from "dayjs";
import { getDelayData } from "./TraInfoEXWidget";
import { getInfoString } from "./InfoWidget";
import { getFelicaQuickAccessData } from "./FelicaQuickAccessWidget";
export async function getShortcutData() {
const nowText = dayjs().format("HH:mm");
const [delayResult, infoResult, felicaResult] = await Promise.allSettled([
getDelayData(),
getInfoString(),
getFelicaQuickAccessData(),
]);
const delayCount =
delayResult.status === "fulfilled" && delayResult.value.delayString
? delayResult.value.delayString.length
: 0;
const hasInfo =
infoResult.status === "fulfilled" &&
infoResult.value.text != null &&
infoResult.value.text.length > 0;
const amountText =
felicaResult.status === "fulfilled"
? felicaResult.value.amountText
: "未読取";
return { nowText, delayCount, hasInfo, amountText };
}
export type ShortcutWidgetProps = {
nowText: string;
delayCount: number;
hasInfo: boolean;
amountText: string;
};
const TILE_BG = "#E8F4FB";
/** アイコン+ラベルのみ(バッジなし・サブテキストなし) */
function SimpleTile({ icon, label, uri }: { icon: string; label: string; uri: string }) {
return (
<FlexWidget
style={{
flex: 1,
backgroundColor: TILE_BG,
borderRadius: 10,
padding: 8,
alignItems: "center",
justifyContent: "center",
}}
clickAction="OPEN_URI"
clickActionData={{ uri }}
>
<TextWidget text={icon} style={{ fontSize: 24 }} />
<TextWidget
text={label}
style={{ color: "#000000", fontSize: 14, fontWeight: "bold", marginTop: 4 }}
/>
</FlexWidget>
);
}
/** アイコン+ラベル+バッジ */
function BadgeTile({
icon,
label,
badgeText,
badgeColor,
uri,
}: {
icon: string;
label: string;
badgeText: string;
badgeColor: string;
uri: string;
}) {
return (
<FlexWidget
style={{
flex: 1,
backgroundColor: TILE_BG,
borderRadius: 10,
padding: 8,
alignItems: "center",
justifyContent: "center",
}}
clickAction="OPEN_URI"
clickActionData={{ uri }}
>
<FlexWidget style={{ flexDirection: "row", alignItems: "center" }}>
<TextWidget text={icon} style={{ fontSize: 24 }} />
<FlexWidget
style={{
backgroundColor: badgeColor as any,
borderRadius: 8,
paddingLeft: 5,
paddingRight: 5,
paddingTop: 2,
paddingBottom: 2,
marginLeft: 4,
}}
>
<TextWidget
text={badgeText}
style={{ color: "#ffffff", fontSize: 11, fontWeight: "bold" }}
/>
</FlexWidget>
</FlexWidget>
<TextWidget
text={label}
style={{ color: "#000000", fontSize: 14, fontWeight: "bold", marginTop: 4 }}
/>
</FlexWidget>
);
}
/** アイコンラベルサブテキストICカード残高用 */
function SubTile({
icon,
label,
sub,
uri,
}: {
icon: string;
label: string;
sub: string;
uri: string;
}) {
return (
<FlexWidget
style={{
flex: 1,
backgroundColor: TILE_BG,
borderRadius: 10,
padding: 8,
alignItems: "center",
justifyContent: "center",
}}
clickAction="OPEN_URI"
clickActionData={{ uri }}
>
<TextWidget text={icon} style={{ fontSize: 24 }} />
<TextWidget
text={label}
style={{ color: "#000000", fontSize: 14, fontWeight: "bold", marginTop: 4 }}
/>
<TextWidget
text={sub}
style={{ color: "#0099CC", fontSize: 12, marginTop: 2 }}
/>
</FlexWidget>
);
}
export function ShortcutWidget({ nowText, delayCount, hasInfo, amountText }: ShortcutWidgetProps) {
return (
<FlexWidget
style={{
height: "match_parent",
width: "match_parent",
backgroundColor: "#ffffff",
borderRadius: 16,
}}
>
{/* Header */}
<FlexWidget
style={{
justifyContent: "center",
alignItems: "center",
backgroundColor: "#0099CC",
width: "match_parent",
flexDirection: "row",
paddingTop: 10,
paddingBottom: 10,
}}
>
<TextWidget
text="クイックアクセス"
style={{
fontSize: 30,
fontWeight: "bold",
fontFamily: "Inter",
color: "#ffffff",
textAlign: "left",
marginLeft: 10,
}}
/>
<FlexWidget style={{ flex: 1 }} />
<TextWidget
text={nowText}
style={{
fontSize: 30,
fontFamily: "Inter",
color: "#ffffff",
textAlign: "right",
marginRight: 10,
}}
/>
</FlexWidget>
{/* Row 1: 走行位置 | 遅延速報EX */}
<FlexWidget
style={{
flexDirection: "row",
width: "match_parent",
paddingLeft: 8,
paddingRight: 8,
paddingTop: 8,
flex: 1,
}}
>
<SimpleTile icon="🚃" label="走行位置" uri="jrshikoku://open/traininfo" />
<FlexWidget style={{ width: 6, height: "match_parent" }}>
<TextWidget text="" style={{ fontSize: 1 }} />
</FlexWidget>
<BadgeTile
icon="⚡"
label="遅延速報EX"
uri="jrshikoku://open/traininfo"
badgeText={delayCount > 0 ? `${delayCount}` : "なし"}
badgeColor={delayCount > 0 ? "#E53935" : "#9E9E9E"}
/>
</FlexWidget>
{/* Row 2: 運行情報 | ICカード */}
<FlexWidget
style={{
flexDirection: "row",
width: "match_parent",
paddingLeft: 8,
paddingRight: 8,
paddingTop: 6,
flex: 1,
}}
>
<BadgeTile
icon="📋"
label="運行情報"
uri="jrshikoku://open/operation"
badgeText={hasInfo ? "あり" : "なし"}
badgeColor={hasInfo ? "#FF7043" : "#9E9E9E"}
/>
<FlexWidget style={{ width: 6, height: "match_parent" }}>
<TextWidget text="" style={{ fontSize: 1 }} />
</FlexWidget>
<SubTile
icon="💳"
label="ICカード"
sub={amountText}
uri="jrshikoku://open/felica"
/>
</FlexWidget>
{/* Row 3: トップメニュー(全幅) */}
<FlexWidget
style={{
flexDirection: "row",
width: "match_parent",
paddingLeft: 8,
paddingRight: 8,
paddingTop: 6,
paddingBottom: 8,
flex: 1,
}}
>
<SimpleTile icon="🏠" label="トップメニュー" uri="jrshikoku://open/topmenu" />
</FlexWidget>
</FlexWidget>
);
}