223 lines
6.1 KiB
TypeScript
223 lines
6.1 KiB
TypeScript
import React from "react";
|
|
import { FlexWidget, TextWidget } from "react-native-android-widget";
|
|
import { getDelayData } from "./TraInfoEXWidget";
|
|
import { getInfoString } from "./InfoWidget";
|
|
import { getFelicaQuickAccessData } from "./FelicaQuickAccessWidget";
|
|
|
|
export async function getShortcutData() {
|
|
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 { delayCount, hasInfo, amountText };
|
|
}
|
|
|
|
export type ShortcutWidgetProps = {
|
|
delayCount: number;
|
|
hasInfo: boolean;
|
|
amountText: string;
|
|
};
|
|
|
|
const TILE_BG = "#E8F4FB";
|
|
const SPACING = 6;
|
|
|
|
/** 汎用グリッドタイル */
|
|
function GridTile({
|
|
icon,
|
|
label,
|
|
sub,
|
|
subColor,
|
|
badgeText,
|
|
badgeColor,
|
|
bottomTrailing,
|
|
uri,
|
|
}: {
|
|
icon: string;
|
|
label: string;
|
|
sub?: string;
|
|
subColor?: string;
|
|
badgeText?: string;
|
|
badgeColor?: string;
|
|
bottomTrailing?: string;
|
|
uri: string;
|
|
}) {
|
|
return (
|
|
<FlexWidget
|
|
style={{
|
|
flex: 1,
|
|
backgroundColor: TILE_BG,
|
|
borderRadius: 10,
|
|
padding: 8,
|
|
justifyContent: "center",
|
|
}}
|
|
clickAction="OPEN_URI"
|
|
clickActionData={{ uri }}
|
|
>
|
|
<FlexWidget style={{ flexDirection: "row", alignItems: "center" }}>
|
|
<TextWidget text={icon} style={{ fontSize: 22 }} />
|
|
<FlexWidget style={{ marginLeft: 6, flex: 1 }}>
|
|
{badgeText !== undefined && badgeColor !== undefined ? (
|
|
<FlexWidget style={{ flexDirection: "row", alignItems: "center" }}>
|
|
<TextWidget
|
|
text={label}
|
|
style={{ color: "#000000", fontSize: 12, fontWeight: "bold" }}
|
|
/>
|
|
<FlexWidget
|
|
style={{
|
|
backgroundColor: badgeColor as any,
|
|
borderRadius: 6,
|
|
paddingLeft: 4,
|
|
paddingRight: 4,
|
|
paddingTop: 1,
|
|
paddingBottom: 1,
|
|
marginLeft: 3,
|
|
}}
|
|
>
|
|
<TextWidget
|
|
text={badgeText}
|
|
style={{ color: "#ffffff", fontSize: 9, fontWeight: "bold" }}
|
|
/>
|
|
</FlexWidget>
|
|
</FlexWidget>
|
|
) : (
|
|
<TextWidget
|
|
text={label}
|
|
style={{ color: "#000000", fontSize: 12, fontWeight: "bold" }}
|
|
/>
|
|
)}
|
|
{sub !== undefined ? (
|
|
<TextWidget
|
|
text={sub}
|
|
style={{ color: (subColor ?? "#555555") as any, fontSize: 10, marginTop: 1 }}
|
|
/>
|
|
) : (
|
|
<TextWidget text="" style={{ fontSize: 1 }} />
|
|
)}
|
|
</FlexWidget>
|
|
</FlexWidget>
|
|
{bottomTrailing !== undefined && (
|
|
<FlexWidget
|
|
style={{
|
|
flexDirection: "row",
|
|
justifyContent: "flex-end",
|
|
width: "match_parent",
|
|
}}
|
|
>
|
|
<TextWidget
|
|
text={bottomTrailing}
|
|
style={{ color: "#555555", fontSize: 8, fontWeight: "600" }}
|
|
/>
|
|
</FlexWidget>
|
|
)}
|
|
</FlexWidget>
|
|
);
|
|
}
|
|
|
|
export function ShortcutWidget({ delayCount, hasInfo, amountText }: ShortcutWidgetProps) {
|
|
return (
|
|
<FlexWidget
|
|
style={{
|
|
height: "match_parent",
|
|
width: "match_parent",
|
|
backgroundColor: "#ffffff",
|
|
borderRadius: 16,
|
|
padding: 8,
|
|
}}
|
|
>
|
|
{/* Row 1: 走行位置 | 遅延速報EX */}
|
|
<FlexWidget
|
|
style={{
|
|
flexDirection: "row",
|
|
width: "match_parent",
|
|
flex: 1,
|
|
}}
|
|
>
|
|
<GridTile icon="🚃" label="走行位置" sub="列車の現在位置" uri="jrshikoku://positions/apps" />
|
|
<FlexWidget style={{ width: SPACING, height: "match_parent" }}>
|
|
<TextWidget text="" style={{ fontSize: 1 }} />
|
|
</FlexWidget>
|
|
<GridTile
|
|
icon="⚡"
|
|
label="遅延速報EX"
|
|
sub="列車の遅延情報"
|
|
uri="jrshikoku://open/traininfo"
|
|
badgeText={delayCount > 0 ? `${delayCount}件` : "なし"}
|
|
badgeColor={delayCount > 0 ? "#E53935" : "#9E9E9E"}
|
|
/>
|
|
</FlexWidget>
|
|
|
|
{/* Spacer between rows */}
|
|
<FlexWidget style={{ height: SPACING, width: "match_parent" }}>
|
|
<TextWidget text="" style={{ fontSize: 1 }} />
|
|
</FlexWidget>
|
|
|
|
{/* Row 2: 運行情報 | ICカード */}
|
|
<FlexWidget
|
|
style={{
|
|
flexDirection: "row",
|
|
width: "match_parent",
|
|
flex: 1,
|
|
}}
|
|
>
|
|
<GridTile
|
|
icon="📋"
|
|
label="運行情報"
|
|
sub="列車の運行状況"
|
|
uri="jrshikoku://open/operation"
|
|
badgeText={hasInfo ? "あり" : "なし"}
|
|
badgeColor={hasInfo ? "#FF7043" : "#9E9E9E"}
|
|
/>
|
|
<FlexWidget style={{ width: SPACING, height: "match_parent" }}>
|
|
<TextWidget text="" style={{ fontSize: 1 }} />
|
|
</FlexWidget>
|
|
<GridTile
|
|
icon="💳"
|
|
label="ICカード"
|
|
sub={amountText}
|
|
subColor="#0099CC"
|
|
uri="jrshikoku://open/felica"
|
|
/>
|
|
</FlexWidget>
|
|
|
|
{/* Spacer between rows */}
|
|
<FlexWidget style={{ height: SPACING, width: "match_parent" }}>
|
|
<TextWidget text="" style={{ fontSize: 1 }} />
|
|
</FlexWidget>
|
|
|
|
{/* Row 3: トップメニュー(全幅) */}
|
|
<FlexWidget
|
|
style={{
|
|
flexDirection: "row",
|
|
width: "match_parent",
|
|
flex: 1,
|
|
}}
|
|
>
|
|
<GridTile
|
|
icon="🏠"
|
|
label="トップメニュー"
|
|
sub="アプリのトップへ"
|
|
bottomTrailing="クイックアクセス"
|
|
uri="jrshikoku://open/topmenu"
|
|
/>
|
|
</FlexWidget>
|
|
</FlexWidget>
|
|
);
|
|
}
|