84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
/**
|
|
* rMaps applet definitions — Location Pin + Route Summary.
|
|
*/
|
|
|
|
import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types";
|
|
|
|
const locationPin: AppletDefinition = {
|
|
id: "location-pin",
|
|
label: "Location Pin",
|
|
icon: "📍",
|
|
accentColor: "#1d4ed8",
|
|
ports: [
|
|
{ name: "location-in", type: "json", direction: "input" },
|
|
{ name: "coords-out", type: "json", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const label = (snapshot.label as string) || "Location";
|
|
const lat = (snapshot.lat as number) || 0;
|
|
const lng = (snapshot.lng as number) || 0;
|
|
const hasCoords = lat !== 0 || lng !== 0;
|
|
|
|
return `
|
|
<div style="text-align:center">
|
|
<div style="font-size:28px;margin-bottom:4px">📍</div>
|
|
<div style="font-size:13px;font-weight:600;margin-bottom:4px">${label}</div>
|
|
${hasCoords
|
|
? `<div style="font-size:10px;color:#94a3b8;font-family:monospace">${lat.toFixed(4)}, ${lng.toFixed(4)}</div>`
|
|
: `<div style="font-size:10px;color:#94a3b8;font-style:italic">No coordinates</div>`
|
|
}
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "location-in" && value && typeof value === "object") {
|
|
const loc = value as Record<string, unknown>;
|
|
ctx.emitOutput("coords-out", { lat: loc.lat, lng: loc.lng });
|
|
}
|
|
},
|
|
};
|
|
|
|
const routeSummary: AppletDefinition = {
|
|
id: "route-summary",
|
|
label: "Route Summary",
|
|
icon: "🗺️",
|
|
accentColor: "#1d4ed8",
|
|
ports: [
|
|
{ name: "route-in", type: "json", direction: "input" },
|
|
{ name: "distance-out", type: "number", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const from = (snapshot.from as string) || "Start";
|
|
const to = (snapshot.to as string) || "End";
|
|
const distance = (snapshot.distance as string) || "—";
|
|
const duration = (snapshot.duration as string) || "—";
|
|
|
|
return `
|
|
<div>
|
|
<div style="display:flex;align-items:center;gap:6px;margin-bottom:8px">
|
|
<span style="font-size:11px;color:#94a3b8">From</span>
|
|
<span style="font-size:12px;font-weight:600;color:#e2e8f0">${from}</span>
|
|
</div>
|
|
<div style="display:flex;align-items:center;gap:6px;margin-bottom:8px">
|
|
<span style="font-size:11px;color:#94a3b8">To</span>
|
|
<span style="font-size:12px;font-weight:600;color:#e2e8f0">${to}</span>
|
|
</div>
|
|
<div style="display:flex;justify-content:space-between;border-top:1px solid #334155;padding-top:6px">
|
|
<span style="font-size:11px;color:#60a5fa">${distance}</span>
|
|
<span style="font-size:11px;color:#94a3b8">${duration}</span>
|
|
</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "route-in" && value && typeof value === "object") {
|
|
const route = value as Record<string, unknown>;
|
|
ctx.emitOutput("distance-out", Number(route.distanceKm) || 0);
|
|
}
|
|
},
|
|
};
|
|
|
|
export const mapsApplets: AppletDefinition[] = [locationPin, routeSummary];
|