@ateam-ai-mobile/ui 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ import { ada as ada7, useChatStore, pluginCommandEmitter as pluginCommandEmitter
14
14
  import { useState as useState4, useCallback as useCallback3 } from "react";
15
15
  import { View as View7, Text as Text6, Pressable as Pressable3, StyleSheet as StyleSheet6, Image, Platform as Platform4 } from "react-native";
16
16
  import Markdown from "react-native-markdown-display";
17
- import { TABLE_BLOCK_OPEN, TABLE_BLOCK_CLOSE, getConfig as getConfig2, ada as ada6, borderRadius as borderRadius3, fontSize as fontSize4 } from "@ateam-ai-mobile/core";
17
+ import { TABLE_BLOCK_OPEN, TABLE_BLOCK_CLOSE, getConfig as getConfig2, ada as ada6, borderRadius as borderRadius2, fontSize as fontSize4 } from "@ateam-ai-mobile/core";
18
18
  import { AdaOrb, getHaptics as getHaptics2 } from "@ateam-ai-mobile/plugin-runtime";
19
19
 
20
20
  // src/chat/JobProgressBar.tsx
@@ -28,7 +28,7 @@ var WARM_RED = "#C15545";
28
28
  var WARM_RED_SOFT = "rgba(193, 85, 69, 0.14)";
29
29
  var WARM_AMBER = "#D49A4E";
30
30
  var WARM_AMBER_SOFT = "rgba(212, 154, 78, 0.16)";
31
- function JobProgressBar({ progress }) {
31
+ function JobProgressBar({ progress, standalone }) {
32
32
  const pulseAnim = useRef(new Animated.Value(0.5)).current;
33
33
  const [elapsed, setElapsed] = useState(0);
34
34
  const isRunning = progress.status === "running";
@@ -42,8 +42,10 @@ function JobProgressBar({ progress }) {
42
42
  }
43
43
  const anim = Animated.loop(
44
44
  Animated.sequence([
45
- Animated.timing(pulseAnim, { toValue: 1, duration: 800, useNativeDriver: true }),
46
- Animated.timing(pulseAnim, { toValue: 0.5, duration: 800, useNativeDriver: true })
45
+ // Gentle breath — a soft fade rather than a hard blink, so the running
46
+ // indicator recedes into the bubble instead of demanding attention.
47
+ Animated.timing(pulseAnim, { toValue: 0.55, duration: 1100, useNativeDriver: true }),
48
+ Animated.timing(pulseAnim, { toValue: 0.22, duration: 1100, useNativeDriver: true })
47
49
  ])
48
50
  );
49
51
  anim.start();
@@ -64,33 +66,37 @@ function JobProgressBar({ progress }) {
64
66
  const statusColor = isDone ? WARM_GREEN : isError ? WARM_RED : isPaused ? WARM_AMBER : ada.orange;
65
67
  const statusBg = isDone ? WARM_GREEN_SOFT : isError ? WARM_RED_SOFT : isPaused ? WARM_AMBER_SOFT : ada.orangeSoft;
66
68
  if (isDone || isError) {
67
- return /* @__PURE__ */ jsx(View, { style: styles.container, children: /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
69
+ return /* @__PURE__ */ jsx(View, { style: [styles.container, standalone && styles.containerStandalone], children: /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
68
70
  /* @__PURE__ */ jsx(View, { style: [styles.dot, { backgroundColor: statusColor }] }),
69
71
  /* @__PURE__ */ jsx(Text, { style: [styles.label, { color: statusColor }], children: isDone ? "Completed" : "Failed" })
70
72
  ] }) });
71
73
  }
72
74
  if (isPaused) {
73
- return /* @__PURE__ */ jsx(View, { style: styles.container, children: /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
75
+ return /* @__PURE__ */ jsx(View, { style: [styles.container, standalone && styles.containerStandalone], children: /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
74
76
  /* @__PURE__ */ jsx(View, { style: [styles.dot, { backgroundColor: statusColor }] }),
75
77
  /* @__PURE__ */ jsx(Text, { style: [styles.label, { color: statusColor }], children: "Waiting for your reply" })
76
78
  ] }) });
77
79
  }
78
- const elapsedStr = progress.chainStartedAt ? `${Math.floor(elapsed / 60)}:${String(elapsed % 60).padStart(2, "0")}` : null;
80
+ const elapsedStr = progress.chainStartedAt ? elapsed < 60 ? `${elapsed}s` : `${Math.floor(elapsed / 60)}m ${elapsed % 60}s` : null;
79
81
  const metaParts = [
80
82
  progress.iteration != null && progress.iteration > 0 ? `iter ${progress.iteration}` : null,
81
83
  elapsedStr
82
84
  ].filter(Boolean);
85
+ const labels = progress.humanLabels;
86
+ const label = (t) => t && labels?.[t] || t;
87
+ const headline = progress.humanStatus || label(progress.skillSlug) || "Processing...";
88
+ const showRawTool = !progress.humanStatus && !!progress.currentTool;
83
89
  const lp = progress.liveProgress;
84
- return /* @__PURE__ */ jsxs(View, { style: styles.container, children: [
90
+ return /* @__PURE__ */ jsxs(View, { style: [styles.container, standalone && styles.containerStandalone], children: [
85
91
  /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
86
92
  /* @__PURE__ */ jsx(
87
93
  Animated.View,
88
94
  {
89
- style: [styles.dot, { backgroundColor: ada.orange, opacity: pulseAnim }]
95
+ style: [styles.dot, styles.dotRunning, { opacity: pulseAnim }]
90
96
  }
91
97
  ),
92
- /* @__PURE__ */ jsx(Text, { style: styles.skill, numberOfLines: 1, children: progress.skillSlug || "Processing..." }),
93
- !!progress.currentTool && /* @__PURE__ */ jsx(Text, { style: styles.tool, numberOfLines: 1, children: ` \u2192 ${progress.currentTool}` }),
98
+ /* @__PURE__ */ jsx(Text, { style: styles.skill, numberOfLines: 1, children: headline }),
99
+ showRawTool && /* @__PURE__ */ jsx(Text, { style: styles.tool, numberOfLines: 1, children: ` \u2192 ${label(progress.currentTool)}` }),
94
100
  metaParts.length > 0 && /* @__PURE__ */ jsx(Text, { style: styles.meta, numberOfLines: 1, children: ` \xB7 ${metaParts.join(" \xB7 ")}` })
95
101
  ] }),
96
102
  !!lp?.message && /* @__PURE__ */ jsxs(View, { style: styles.liveProgressRow, children: [
@@ -103,10 +109,10 @@ function JobProgressBar({ progress }) {
103
109
  ] }),
104
110
  /* @__PURE__ */ jsx(Text, { style: styles.liveProgressMsg, numberOfLines: 1, children: lp.message })
105
111
  ] }),
106
- /* @__PURE__ */ jsx(View, { style: [styles.progressTrack, { backgroundColor: statusBg }], children: /* @__PURE__ */ jsx(
112
+ /* @__PURE__ */ jsx(View, { style: styles.progressTrack, children: /* @__PURE__ */ jsx(
107
113
  Animated.View,
108
114
  {
109
- style: [styles.progressFill, { backgroundColor: ada.orange, opacity: pulseAnim }]
115
+ style: [styles.progressFill, { opacity: pulseAnim }]
110
116
  }
111
117
  ) })
112
118
  ] });
@@ -118,6 +124,12 @@ var styles = StyleSheet.create({
118
124
  borderTopWidth: 1,
119
125
  borderTopColor: ada.border
120
126
  },
127
+ // Standalone (transparent-bubble) placeholder — no divider/top spacing.
128
+ containerStandalone: {
129
+ marginTop: 0,
130
+ paddingTop: 0,
131
+ borderTopWidth: 0
132
+ },
121
133
  row: {
122
134
  flexDirection: "row",
123
135
  alignItems: "center",
@@ -125,21 +137,26 @@ var styles = StyleSheet.create({
125
137
  overflow: "hidden"
126
138
  },
127
139
  dot: {
128
- width: 7,
129
- height: 7,
130
- borderRadius: 4,
140
+ width: 6,
141
+ height: 6,
142
+ borderRadius: 3,
131
143
  marginRight: 6,
132
144
  flexShrink: 0
133
145
  },
146
+ // Running dot: soft orange, not the full-saturation accent.
147
+ dotRunning: {
148
+ backgroundColor: "rgba(255, 122, 40, 0.6)"
149
+ },
134
150
  label: {
135
151
  fontSize: fontSize.xs,
136
152
  fontWeight: "600"
137
153
  },
138
- // Running state text segments
154
+ // Running state text segments — muted so the indicator blends into the
155
+ // bubble rather than shouting in orange.
139
156
  skill: {
140
157
  fontSize: fontSize.xs,
141
- fontWeight: "600",
142
- color: ada.orange,
158
+ fontWeight: "500",
159
+ color: ada.inkSoft,
143
160
  flexShrink: 1
144
161
  },
145
162
  tool: {
@@ -165,19 +182,23 @@ var styles = StyleSheet.create({
165
182
  },
166
183
  liveProgressMsg: {
167
184
  fontSize: fontSize.xs,
168
- color: ada.orange,
185
+ color: ada.inkSoft,
169
186
  flex: 1
170
187
  },
171
188
  progressTrack: {
172
- height: 3,
173
- borderRadius: 2,
174
- marginTop: 6,
175
- overflow: "hidden"
189
+ height: 2,
190
+ borderRadius: 1,
191
+ marginTop: 8,
192
+ overflow: "hidden",
193
+ // Barely-there rail so the bar reads as a hint, not a status meter.
194
+ backgroundColor: "rgba(26, 20, 16, 0.05)"
176
195
  },
177
196
  progressFill: {
178
197
  height: "100%",
179
- width: "60%",
180
- borderRadius: 2
198
+ width: "55%",
199
+ borderRadius: 1,
200
+ // Muted orange — present but recessive.
201
+ backgroundColor: "rgba(255, 122, 40, 0.4)"
181
202
  }
182
203
  });
183
204
 
@@ -979,7 +1000,7 @@ var styles4 = StyleSheet4.create({
979
1000
 
980
1001
  // src/chat/TableCardBlock.tsx
981
1002
  import { View as View6, Text as Text5, StyleSheet as StyleSheet5, Platform as Platform3 } from "react-native";
982
- import { ada as ada5, borderRadius as borderRadius2, fontSize as fontSize3, spacing } from "@ateam-ai-mobile/core";
1003
+ import { ada as ada5, borderRadius, fontSize as fontSize3, spacing } from "@ateam-ai-mobile/core";
983
1004
  import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
984
1005
  var fontFam2 = Platform3.OS === "ios" ? "SF Pro Rounded" : void 0;
985
1006
  function TableCardBlock({ columns, rows }) {
@@ -1008,7 +1029,7 @@ var styles5 = StyleSheet5.create({
1008
1029
  },
1009
1030
  card: {
1010
1031
  backgroundColor: ada5.paper,
1011
- borderRadius: borderRadius2.md,
1032
+ borderRadius: borderRadius.md,
1012
1033
  borderWidth: 1,
1013
1034
  borderColor: ada5.border,
1014
1035
  padding: spacing.md
@@ -1104,6 +1125,8 @@ function MessageBubble({ message }) {
1104
1125
  const isUser = message.role === "user";
1105
1126
  const isSystem = message.role === "system";
1106
1127
  const isNotification = !isUser && message.kind === "notification";
1128
+ const st = message.jobProgress?.status;
1129
+ const isProgressOnly = !isUser && (st === "running" || st === "paused") && (!message.content?.trim() || message.content === "Working on it...");
1107
1130
  const [copied, setCopied] = useState4("");
1108
1131
  const showCopied = useCallback3((label) => {
1109
1132
  setCopied(label);
@@ -1139,7 +1162,8 @@ function MessageBubble({ message }) {
1139
1162
  styles6.bubble,
1140
1163
  isUser && styles6.bubbleUser,
1141
1164
  isSystem && styles6.bubbleSystem,
1142
- isNotification && styles6.bubbleNotification
1165
+ isNotification && styles6.bubbleNotification,
1166
+ isProgressOnly && styles6.bubbleProgress
1143
1167
  ],
1144
1168
  children: [
1145
1169
  isNotification && /* @__PURE__ */ jsxs6(View7, { style: styles6.notificationHeader, children: [
@@ -1172,12 +1196,15 @@ function MessageBubble({ message }) {
1172
1196
  isUser ? (
1173
1197
  // Hide the "See attachment" placeholder when the bubble already shows the photo.
1174
1198
  message.content && !(message.content === "See attachment" && message.attachments?.length) ? /* @__PURE__ */ jsx8(Text6, { selectable: true, style: styles6.userText, children: message.content }) : null
1199
+ ) : isProgressOnly ? (
1200
+ // No "Working on it…" text — the indicator below is the whole message.
1201
+ null
1175
1202
  ) : renderAssistantContent(message.content, copyText),
1176
1203
  !!copied && /* @__PURE__ */ jsx8(View7, { style: styles6.copiedBadge, children: /* @__PURE__ */ jsx8(Text6, { style: styles6.copiedText, children: copied }) }),
1177
1204
  message.toolCalls && message.toolCalls.length > 0 && /* @__PURE__ */ jsx8(ToolCallsBadge, { calls: message.toolCalls }),
1178
- message.jobProgress && /* @__PURE__ */ jsx8(JobProgressBar, { progress: message.jobProgress }),
1205
+ message.jobProgress && /* @__PURE__ */ jsx8(JobProgressBar, { progress: message.jobProgress, standalone: isProgressOnly }),
1179
1206
  !isUser && message.actions && message.actions.length > 0 && /* @__PURE__ */ jsx8(UIActionsRow, { actions: message.actions }),
1180
- /* @__PURE__ */ jsx8(Text6, { style: [styles6.timeText, isUser && styles6.timeTextUser], children: formatTime(message.timestamp) })
1207
+ !isProgressOnly && /* @__PURE__ */ jsx8(Text6, { style: [styles6.timeText, isUser && styles6.timeTextUser], children: formatTime(message.timestamp) })
1181
1208
  ]
1182
1209
  }
1183
1210
  ),
@@ -1292,7 +1319,7 @@ var styles6 = StyleSheet6.create({
1292
1319
  backgroundColor: ada6.botBubble,
1293
1320
  borderWidth: 1,
1294
1321
  borderColor: ada6.botBubbleBorder,
1295
- borderRadius: borderRadius3.xl,
1322
+ borderRadius: borderRadius2.xl,
1296
1323
  paddingHorizontal: 16,
1297
1324
  paddingVertical: 12
1298
1325
  },
@@ -1300,6 +1327,14 @@ var styles6 = StyleSheet6.create({
1300
1327
  backgroundColor: ada6.userBubble,
1301
1328
  borderColor: "transparent"
1302
1329
  },
1330
+ // Live-chain placeholder: no fill, no border, tighter padding — the
1331
+ // indicator floats over the background instead of sitting in a bubble.
1332
+ bubbleProgress: {
1333
+ backgroundColor: "transparent",
1334
+ borderColor: "transparent",
1335
+ paddingHorizontal: 4,
1336
+ paddingVertical: 2
1337
+ },
1303
1338
  bubbleSystem: {
1304
1339
  backgroundColor: ada6.orangeSoft,
1305
1340
  borderColor: ada6.orange,
@@ -1308,7 +1343,7 @@ var styles6 = StyleSheet6.create({
1308
1343
  bubbleNotification: {
1309
1344
  backgroundColor: ada6.orangeSoft,
1310
1345
  borderColor: "rgba(255, 122, 40, 0.35)",
1311
- borderRadius: borderRadius3.lg,
1346
+ borderRadius: borderRadius2.lg,
1312
1347
  maxWidth: "90%"
1313
1348
  },
1314
1349
  notificationLeftStripe: {
@@ -1380,7 +1415,7 @@ var styles6 = StyleSheet6.create({
1380
1415
  backgroundColor: "#5A8A5C",
1381
1416
  paddingHorizontal: 8,
1382
1417
  paddingVertical: 2,
1383
- borderRadius: borderRadius3.sm
1418
+ borderRadius: borderRadius2.sm
1384
1419
  },
1385
1420
  copiedText: {
1386
1421
  color: "#fff",
@@ -1496,7 +1531,7 @@ import {
1496
1531
  Platform as Platform5
1497
1532
  } from "react-native";
1498
1533
  import Svg, { Path, Line, Polygon } from "react-native-svg";
1499
- import { colors as colors2, borderRadius as borderRadius4 } from "@ateam-ai-mobile/core";
1534
+ import { colors as colors2, borderRadius as borderRadius3 } from "@ateam-ai-mobile/core";
1500
1535
  import { getHaptics as getHaptics3 } from "@ateam-ai-mobile/plugin-runtime";
1501
1536
  import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1502
1537
  function ChatInput({ onSend, onCallStart, loading, prefill, placeholder }) {
@@ -1564,7 +1599,7 @@ var styles8 = StyleSheet8.create({
1564
1599
  flexDirection: "row",
1565
1600
  alignItems: "flex-end",
1566
1601
  backgroundColor: colors2.light.bgInput,
1567
- borderRadius: borderRadius4.xl,
1602
+ borderRadius: borderRadius3.xl,
1568
1603
  borderWidth: 1,
1569
1604
  borderColor: colors2.light.border,
1570
1605
  paddingHorizontal: 4,
@@ -1893,12 +1928,13 @@ var styles11 = StyleSheet11.create({
1893
1928
  // src/TenantPicker.tsx
1894
1929
  import { useEffect as useEffect7, useState as useState8 } from "react";
1895
1930
  import { View as View13, Text as Text9, Pressable as Pressable7, ActivityIndicator as ActivityIndicator5, StyleSheet as StyleSheet12, Platform as Platform8 } from "react-native";
1896
- import { ada as ada9, fontSize as fontSize5, borderRadius as borderRadius5, listMyTenants, getTenant as getTenant4 } from "@ateam-ai-mobile/core";
1931
+ import { ada as ada9, fontSize as fontSize5, borderRadius as borderRadius4, listMyTenants, switchTenant, getTenant as getTenant4 } from "@ateam-ai-mobile/core";
1897
1932
  import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1898
1933
  var fontFam5 = Platform8.OS === "ios" ? "SF Pro Rounded" : void 0;
1899
- function TenantPicker({ onSelect, currentTenantId }) {
1934
+ function TenantPicker({ onSwitched, onSelect, currentTenantId }) {
1900
1935
  const [tenants, setTenants] = useState8(null);
1901
1936
  const [error, setError] = useState8(null);
1937
+ const [switching, setSwitching] = useState8(null);
1902
1938
  const active = currentTenantId ?? getTenant4();
1903
1939
  useEffect7(() => {
1904
1940
  let cancelled = false;
@@ -1911,6 +1947,23 @@ function TenantPicker({ onSelect, currentTenantId }) {
1911
1947
  cancelled = true;
1912
1948
  };
1913
1949
  }, []);
1950
+ const handlePress = async (t) => {
1951
+ if (t.id === active || switching) return;
1952
+ if (onSelect) {
1953
+ onSelect(t);
1954
+ return;
1955
+ }
1956
+ setError(null);
1957
+ setSwitching(t.id);
1958
+ try {
1959
+ const session = await switchTenant(t.id);
1960
+ onSwitched?.(session);
1961
+ } catch (e) {
1962
+ setError(e?.message || "Could not switch team");
1963
+ } finally {
1964
+ setSwitching(null);
1965
+ }
1966
+ };
1914
1967
  if (error) return /* @__PURE__ */ jsx14(Text9, { style: styles12.error, children: error });
1915
1968
  if (!tenants) {
1916
1969
  return /* @__PURE__ */ jsx14(View13, { style: styles12.loading, children: /* @__PURE__ */ jsx14(ActivityIndicator5, { color: ada9.orange }) });
@@ -1918,12 +1971,14 @@ function TenantPicker({ onSelect, currentTenantId }) {
1918
1971
  if (tenants.length === 0) return /* @__PURE__ */ jsx14(Text9, { style: styles12.empty, children: "No teams found for this account." });
1919
1972
  return /* @__PURE__ */ jsx14(View13, { style: styles12.list, children: tenants.map((t) => {
1920
1973
  const isActive = t.id === active;
1974
+ const isSwitching = switching === t.id;
1921
1975
  return /* @__PURE__ */ jsxs11(
1922
1976
  Pressable7,
1923
1977
  {
1924
1978
  accessibilityRole: "button",
1925
1979
  accessibilityLabel: `Team ${t.name}${isActive ? ", current" : ""}`,
1926
- onPress: () => onSelect(t),
1980
+ disabled: !!switching,
1981
+ onPress: () => handlePress(t),
1927
1982
  style: [styles12.row, isActive && styles12.rowActive],
1928
1983
  children: [
1929
1984
  /* @__PURE__ */ jsx14(View13, { style: styles12.dot }),
@@ -1931,7 +1986,7 @@ function TenantPicker({ onSelect, currentTenantId }) {
1931
1986
  /* @__PURE__ */ jsx14(Text9, { style: styles12.name, children: t.name }),
1932
1987
  /* @__PURE__ */ jsx14(Text9, { style: styles12.slug, children: t.id })
1933
1988
  ] }),
1934
- isActive && /* @__PURE__ */ jsx14(Text9, { style: styles12.check, children: "\u2713" })
1989
+ isSwitching ? /* @__PURE__ */ jsx14(ActivityIndicator5, { color: ada9.orange }) : isActive ? /* @__PURE__ */ jsx14(Text9, { style: styles12.check, children: "\u2713" }) : null
1935
1990
  ]
1936
1991
  },
1937
1992
  t.id
@@ -1947,7 +2002,7 @@ var styles12 = StyleSheet12.create({
1947
2002
  alignItems: "center",
1948
2003
  gap: 12,
1949
2004
  backgroundColor: ada9.paperSoft,
1950
- borderRadius: borderRadius5.lg,
2005
+ borderRadius: borderRadius4.lg,
1951
2006
  borderWidth: 1,
1952
2007
  borderColor: "transparent",
1953
2008
  paddingHorizontal: 16,