276 lines
6.9 KiB
TypeScript
276 lines
6.9 KiB
TypeScript
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>
|
||
);
|
||
}
|