Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
468
extensions/line/src/flex-templates/schedule-cards.ts
Normal file
468
extensions/line/src/flex-templates/schedule-cards.ts
Normal file
@@ -0,0 +1,468 @@
|
||||
// Line plugin module implements schedule cards behavior.
|
||||
import { attachFooterText } from "./common.js";
|
||||
import type { Action, FlexBox, FlexBubble, FlexComponent, FlexText } from "./types.js";
|
||||
|
||||
function buildTitleSubtitleHeader(params: { title: string; subtitle?: string }): FlexComponent[] {
|
||||
const { title, subtitle } = params;
|
||||
const headerContents: FlexComponent[] = [
|
||||
{
|
||||
type: "text",
|
||||
text: title,
|
||||
weight: "bold",
|
||||
size: "xl",
|
||||
color: "#111111",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
];
|
||||
|
||||
if (subtitle) {
|
||||
headerContents.push({
|
||||
type: "text",
|
||||
text: subtitle,
|
||||
size: "sm",
|
||||
color: "#888888",
|
||||
margin: "sm",
|
||||
wrap: true,
|
||||
} as FlexText);
|
||||
}
|
||||
|
||||
return headerContents;
|
||||
}
|
||||
|
||||
function buildCardHeaderSections(headerContents: FlexComponent[]): FlexComponent[] {
|
||||
return [
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: headerContents,
|
||||
paddingBottom: "lg",
|
||||
} as FlexBox,
|
||||
{
|
||||
type: "separator",
|
||||
color: "#EEEEEE",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function createMegaBubbleWithFooter(params: {
|
||||
bodyContents: FlexComponent[];
|
||||
footer?: string;
|
||||
}): FlexBubble {
|
||||
const bubble: FlexBubble = {
|
||||
type: "bubble",
|
||||
size: "mega",
|
||||
body: {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: params.bodyContents,
|
||||
paddingAll: "xl",
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
};
|
||||
|
||||
if (params.footer) {
|
||||
attachFooterText(bubble, params.footer);
|
||||
}
|
||||
|
||||
return bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a receipt/summary card (for orders, transactions, data tables)
|
||||
*
|
||||
* Editorial design: Clean table layout with alternating row backgrounds,
|
||||
* prominent total section, and clear visual hierarchy.
|
||||
*/
|
||||
export function createReceiptCard(params: {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
items: Array<{ name: string; value: string; highlight?: boolean }>;
|
||||
total?: { label: string; value: string };
|
||||
footer?: string;
|
||||
}): FlexBubble {
|
||||
const { title, subtitle, items, total, footer } = params;
|
||||
|
||||
const itemRows: FlexComponent[] = items.slice(0, 12).map(
|
||||
(item, index) =>
|
||||
({
|
||||
type: "box",
|
||||
layout: "horizontal",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: item.name,
|
||||
size: "sm",
|
||||
color: item.highlight ? "#111111" : "#666666",
|
||||
weight: item.highlight ? "bold" : "regular",
|
||||
flex: 3,
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
{
|
||||
type: "text",
|
||||
text: item.value,
|
||||
size: "sm",
|
||||
color: item.highlight ? "#06C755" : "#333333",
|
||||
weight: item.highlight ? "bold" : "regular",
|
||||
flex: 2,
|
||||
align: "end",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
],
|
||||
paddingAll: "md",
|
||||
backgroundColor: index % 2 === 0 ? "#FFFFFF" : "#FAFAFA",
|
||||
}) as FlexBox,
|
||||
);
|
||||
|
||||
// Header section
|
||||
const headerContents = buildTitleSubtitleHeader({ title, subtitle });
|
||||
|
||||
const bodyContents: FlexComponent[] = [
|
||||
...buildCardHeaderSections(headerContents),
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: itemRows,
|
||||
margin: "md",
|
||||
cornerRadius: "md",
|
||||
borderWidth: "light",
|
||||
borderColor: "#EEEEEE",
|
||||
} as FlexBox,
|
||||
];
|
||||
|
||||
// Total section with emphasis
|
||||
if (total) {
|
||||
bodyContents.push({
|
||||
type: "box",
|
||||
layout: "horizontal",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: total.label,
|
||||
size: "lg",
|
||||
weight: "bold",
|
||||
color: "#111111",
|
||||
flex: 2,
|
||||
} as FlexText,
|
||||
{
|
||||
type: "text",
|
||||
text: total.value,
|
||||
size: "xl",
|
||||
weight: "bold",
|
||||
color: "#06C755",
|
||||
flex: 2,
|
||||
align: "end",
|
||||
} as FlexText,
|
||||
],
|
||||
margin: "xl",
|
||||
paddingAll: "lg",
|
||||
backgroundColor: "#F0FDF4",
|
||||
cornerRadius: "lg",
|
||||
} as FlexBox);
|
||||
}
|
||||
|
||||
return createMegaBubbleWithFooter({ bodyContents, footer });
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a calendar event card (for meetings, appointments, reminders)
|
||||
*
|
||||
* Editorial design: Date as hero, strong typographic hierarchy,
|
||||
* color-blocked zones, full text wrapping for readability.
|
||||
*/
|
||||
export function createEventCard(params: {
|
||||
title: string;
|
||||
date: string;
|
||||
time?: string;
|
||||
location?: string;
|
||||
description?: string;
|
||||
calendar?: string;
|
||||
isAllDay?: boolean;
|
||||
action?: Action;
|
||||
}): FlexBubble {
|
||||
const { title, date, time, location, description, calendar, isAllDay, action } = params;
|
||||
|
||||
// Hero date block - the most important information
|
||||
const dateBlock: FlexBox = {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: date.toUpperCase(),
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
color: "#06C755",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
{
|
||||
type: "text",
|
||||
text: isAllDay ? "ALL DAY" : (time ?? ""),
|
||||
size: "xxl",
|
||||
weight: "bold",
|
||||
color: "#111111",
|
||||
wrap: true,
|
||||
margin: "xs",
|
||||
} as FlexText,
|
||||
],
|
||||
paddingBottom: "lg",
|
||||
borderWidth: "none",
|
||||
};
|
||||
|
||||
// If no time and not all day, hide the time display
|
||||
if (!time && !isAllDay) {
|
||||
dateBlock.contents = [
|
||||
{
|
||||
type: "text",
|
||||
text: date,
|
||||
size: "xl",
|
||||
weight: "bold",
|
||||
color: "#111111",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
];
|
||||
}
|
||||
|
||||
// Event title with accent bar
|
||||
const titleBlock: FlexBox = {
|
||||
type: "box",
|
||||
layout: "horizontal",
|
||||
contents: [
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [],
|
||||
width: "4px",
|
||||
backgroundColor: "#06C755",
|
||||
cornerRadius: "2px",
|
||||
} as FlexBox,
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: title,
|
||||
size: "lg",
|
||||
weight: "bold",
|
||||
color: "#1a1a1a",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
...(calendar
|
||||
? [
|
||||
{
|
||||
type: "text",
|
||||
text: calendar,
|
||||
size: "xs",
|
||||
color: "#888888",
|
||||
margin: "sm",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
]
|
||||
: []),
|
||||
],
|
||||
flex: 1,
|
||||
paddingStart: "lg",
|
||||
} as FlexBox,
|
||||
],
|
||||
paddingTop: "lg",
|
||||
paddingBottom: "lg",
|
||||
borderWidth: "light",
|
||||
borderColor: "#EEEEEE",
|
||||
};
|
||||
|
||||
const bodyContents: FlexComponent[] = [dateBlock, titleBlock];
|
||||
|
||||
// Details section (location + description) in subtle background
|
||||
const hasDetails = location || description;
|
||||
if (hasDetails) {
|
||||
const detailItems: FlexComponent[] = [];
|
||||
|
||||
if (location) {
|
||||
detailItems.push({
|
||||
type: "box",
|
||||
layout: "horizontal",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: "📍",
|
||||
size: "sm",
|
||||
flex: 0,
|
||||
} as FlexText,
|
||||
{
|
||||
type: "text",
|
||||
text: location,
|
||||
size: "sm",
|
||||
color: "#444444",
|
||||
margin: "md",
|
||||
flex: 1,
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
],
|
||||
alignItems: "flex-start",
|
||||
} as FlexBox);
|
||||
}
|
||||
|
||||
if (description) {
|
||||
detailItems.push({
|
||||
type: "text",
|
||||
text: description,
|
||||
size: "sm",
|
||||
color: "#666666",
|
||||
wrap: true,
|
||||
margin: location ? "lg" : "none",
|
||||
} as FlexText);
|
||||
}
|
||||
|
||||
bodyContents.push({
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: detailItems,
|
||||
margin: "lg",
|
||||
paddingAll: "lg",
|
||||
backgroundColor: "#F8F9FA",
|
||||
cornerRadius: "lg",
|
||||
} as FlexBox);
|
||||
}
|
||||
|
||||
return {
|
||||
type: "bubble",
|
||||
size: "mega",
|
||||
body: {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: bodyContents,
|
||||
paddingAll: "xl",
|
||||
backgroundColor: "#FFFFFF",
|
||||
action,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a calendar agenda card showing multiple events
|
||||
*
|
||||
* Editorial timeline design: Time-focused left column with event details
|
||||
* on the right. Visual accent bars indicate event priority/recency.
|
||||
*/
|
||||
export function createAgendaCard(params: {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
events: Array<{
|
||||
title: string;
|
||||
time?: string;
|
||||
location?: string;
|
||||
calendar?: string;
|
||||
isNow?: boolean;
|
||||
}>;
|
||||
footer?: string;
|
||||
}): FlexBubble {
|
||||
const { title, subtitle, events, footer } = params;
|
||||
|
||||
// Header with title and optional subtitle
|
||||
const headerContents = buildTitleSubtitleHeader({ title, subtitle });
|
||||
|
||||
// Event timeline items
|
||||
const eventItems: FlexComponent[] = events.slice(0, 6).map((event, index) => {
|
||||
const isActive = event.isNow || index === 0;
|
||||
const accentColor = isActive ? "#06C755" : "#E5E5E5";
|
||||
|
||||
// Time column (fixed width)
|
||||
const timeColumn: FlexBox = {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [
|
||||
{
|
||||
type: "text",
|
||||
text: event.time ?? "—",
|
||||
size: "sm",
|
||||
weight: isActive ? "bold" : "regular",
|
||||
color: isActive ? "#06C755" : "#666666",
|
||||
align: "end",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
],
|
||||
width: "65px",
|
||||
justifyContent: "flex-start",
|
||||
};
|
||||
|
||||
// Accent dot
|
||||
const dotColumn: FlexBox = {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: [],
|
||||
width: "10px",
|
||||
height: "10px",
|
||||
backgroundColor: accentColor,
|
||||
cornerRadius: "5px",
|
||||
} as FlexBox,
|
||||
],
|
||||
width: "24px",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
paddingTop: "xs",
|
||||
};
|
||||
|
||||
// Event details column
|
||||
const detailContents: FlexComponent[] = [
|
||||
{
|
||||
type: "text",
|
||||
text: event.title,
|
||||
size: "md",
|
||||
weight: "bold",
|
||||
color: "#1a1a1a",
|
||||
wrap: true,
|
||||
} as FlexText,
|
||||
];
|
||||
|
||||
// Secondary info line
|
||||
const secondaryParts: string[] = [];
|
||||
if (event.location) {
|
||||
secondaryParts.push(event.location);
|
||||
}
|
||||
if (event.calendar) {
|
||||
secondaryParts.push(event.calendar);
|
||||
}
|
||||
|
||||
if (secondaryParts.length > 0) {
|
||||
detailContents.push({
|
||||
type: "text",
|
||||
text: secondaryParts.join(" · "),
|
||||
size: "xs",
|
||||
color: "#888888",
|
||||
wrap: true,
|
||||
margin: "xs",
|
||||
} as FlexText);
|
||||
}
|
||||
|
||||
const detailColumn: FlexBox = {
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: detailContents,
|
||||
flex: 1,
|
||||
};
|
||||
|
||||
return {
|
||||
type: "box",
|
||||
layout: "horizontal",
|
||||
contents: [timeColumn, dotColumn, detailColumn],
|
||||
margin: index > 0 ? "xl" : undefined,
|
||||
alignItems: "flex-start",
|
||||
} as FlexBox;
|
||||
});
|
||||
|
||||
const bodyContents: FlexComponent[] = [
|
||||
...buildCardHeaderSections(headerContents),
|
||||
{
|
||||
type: "box",
|
||||
layout: "vertical",
|
||||
contents: eventItems,
|
||||
paddingTop: "xl",
|
||||
} as FlexBox,
|
||||
];
|
||||
|
||||
return createMegaBubbleWithFooter({ bodyContents, footer });
|
||||
}
|
||||
Reference in New Issue
Block a user