@oxy.so/bloom 7.0.1 → 7.1.1
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/assets/character-runtime/README.md +55 -0
- package/assets/character-runtime/appearance-codec.mjs +149 -0
- package/assets/character-runtime/integrity.json +6 -0
- package/assets/character-runtime/legacy-engine.mjs +105 -0
- package/assets/character-runtime/legacy-geometry.mjs +166 -0
- package/assets/character-runtime/legacy-worker.mjs +85 -0
- package/assets/character-runtime/managed-avatar.mjs +258 -0
- package/assets/character-runtime/orbit-characters.data +0 -0
- package/assets/character-runtime/orbit-characters.mjs +30 -0
- package/assets/character-runtime/orbit-characters.wasm +0 -0
- package/assets/character-runtime/preparation-worker.mjs +19 -0
- package/assets/character-runtime/render-budget.mjs +144 -0
- package/assets/character-runtime/runtime.mjs +851 -0
- package/assets/character-runtime/thumbnails/eyes/crescent_inset.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/dots.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/double_highlights.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/highlight_capsules.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/oval.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/round_inset.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/sleepy_lids.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/sparkle_capsules.png +0 -0
- package/assets/character-runtime/thumbnails/eyes/swept_lids.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/capsule.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/circle.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/circle_two_ears.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/four_lobed_butterfly.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/heart.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/rounded_cube.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/rounded_diamond.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/rounded_head_two_ears.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/rounded_triangle.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/six_lobed_flower.png +0 -0
- package/assets/character-runtime/thumbnails/shapes/twelve_scalloped_rosette.png +0 -0
- package/docs/adoption-matrix.mdx +9 -9
- package/docs/agent-avatar.mdx +44 -10
- package/docs/agent-creator.mdx +12 -4
- package/docs/multi-agent-chat.mdx +12 -0
- package/docs/project-board.mdx +3 -3
- package/lib/commonjs/agent-avatar/AgentAvatar.js +15 -203
- package/lib/commonjs/agent-avatar/AgentAvatar.js.map +1 -1
- package/lib/commonjs/agent-avatar/AgentAvatarProvider.js +69 -0
- package/lib/commonjs/agent-avatar/AgentAvatarProvider.js.map +1 -0
- package/lib/commonjs/agent-avatar/CharacterAvatar.js +212 -0
- package/lib/commonjs/agent-avatar/CharacterAvatar.js.map +1 -0
- package/lib/commonjs/agent-avatar/ProceduralAvatar.js +216 -0
- package/lib/commonjs/agent-avatar/ProceduralAvatar.js.map +1 -0
- package/lib/commonjs/agent-avatar/artwork.js +4 -3
- package/lib/commonjs/agent-avatar/artwork.js.map +1 -1
- package/lib/commonjs/agent-avatar/avatar-color.js +16 -0
- package/lib/commonjs/agent-avatar/avatar-color.js.map +1 -0
- package/lib/commonjs/agent-avatar/character-html.js +25 -0
- package/lib/commonjs/agent-avatar/character-html.js.map +1 -0
- package/lib/commonjs/agent-avatar/character-runtime-module.js +39 -0
- package/lib/commonjs/agent-avatar/character-runtime-module.js.map +1 -0
- package/lib/commonjs/agent-avatar/character-webview.js +18 -0
- package/lib/commonjs/agent-avatar/character-webview.js.map +1 -0
- package/lib/commonjs/agent-avatar/config-character.js +36 -0
- package/lib/commonjs/agent-avatar/config-character.js.map +1 -0
- package/lib/commonjs/agent-avatar/context.js +6 -1
- package/lib/commonjs/agent-avatar/context.js.map +1 -1
- package/lib/commonjs/agent-avatar/index.js +7 -0
- package/lib/commonjs/agent-avatar/index.js.map +1 -1
- package/lib/commonjs/agent-avatar/legacy-contours.js +57 -0
- package/lib/commonjs/agent-avatar/legacy-contours.js.map +1 -0
- package/lib/commonjs/agent-avatar/legacy-recipe.js +112 -0
- package/lib/commonjs/agent-avatar/legacy-recipe.js.map +1 -0
- package/lib/commonjs/agent-avatar/messages.js +2 -1
- package/lib/commonjs/agent-avatar/messages.js.map +1 -1
- package/lib/commonjs/agent-avatar/model.js +2 -0
- package/lib/commonjs/agent-avatar/model.js.map +1 -1
- package/lib/commonjs/agent-creator/AgentCreatorBase.js +251 -25
- package/lib/commonjs/agent-creator/AgentCreatorBase.js.map +1 -1
- package/lib/commonjs/agent-creator/CharacterControls.js +115 -0
- package/lib/commonjs/agent-creator/CharacterControls.js.map +1 -0
- package/lib/commonjs/agent-creator/EmotionPicker.js +51 -18
- package/lib/commonjs/agent-creator/EmotionPicker.js.map +1 -1
- package/lib/commonjs/agent-creator/ShapeArc.js +56 -26
- package/lib/commonjs/agent-creator/ShapeArc.js.map +1 -1
- package/lib/commonjs/agent-creator/ShapeSilhouette.js +62 -0
- package/lib/commonjs/agent-creator/ShapeSilhouette.js.map +1 -0
- package/lib/commonjs/agent-creator/constants.js +48 -1
- package/lib/commonjs/agent-creator/constants.js.map +1 -1
- package/lib/commonjs/agent-creator/messages.js +9 -0
- package/lib/commonjs/agent-creator/messages.js.map +1 -1
- package/lib/commonjs/agent-creator/shared.js +7 -10
- package/lib/commonjs/agent-creator/shared.js.map +1 -1
- package/lib/commonjs/agent-thinking/AgentThinking.js +4 -62
- package/lib/commonjs/agent-thinking/AgentThinking.js.map +1 -1
- package/lib/commonjs/agent-thinking/ThinkingLabel.js +77 -0
- package/lib/commonjs/agent-thinking/ThinkingLabel.js.map +1 -0
- package/lib/commonjs/chart-cards/TokensChartCard.js +20 -5
- package/lib/commonjs/chart-cards/TokensChartCard.js.map +1 -1
- package/lib/commonjs/locale/translations/ar.js +11 -1
- package/lib/commonjs/locale/translations/ar.js.map +1 -1
- package/lib/commonjs/locale/translations/bn.js +11 -1
- package/lib/commonjs/locale/translations/bn.js.map +1 -1
- package/lib/commonjs/locale/translations/ca.js +11 -1
- package/lib/commonjs/locale/translations/ca.js.map +1 -1
- package/lib/commonjs/locale/translations/de.js +11 -1
- package/lib/commonjs/locale/translations/de.js.map +1 -1
- package/lib/commonjs/locale/translations/es.js +11 -1
- package/lib/commonjs/locale/translations/es.js.map +1 -1
- package/lib/commonjs/locale/translations/fr.js +11 -1
- package/lib/commonjs/locale/translations/fr.js.map +1 -1
- package/lib/commonjs/locale/translations/hi.js +11 -1
- package/lib/commonjs/locale/translations/hi.js.map +1 -1
- package/lib/commonjs/locale/translations/id.js +11 -1
- package/lib/commonjs/locale/translations/id.js.map +1 -1
- package/lib/commonjs/locale/translations/it.js +11 -1
- package/lib/commonjs/locale/translations/it.js.map +1 -1
- package/lib/commonjs/locale/translations/ja.js +11 -1
- package/lib/commonjs/locale/translations/ja.js.map +1 -1
- package/lib/commonjs/locale/translations/pt.js +11 -1
- package/lib/commonjs/locale/translations/pt.js.map +1 -1
- package/lib/commonjs/locale/translations/ru.js +11 -1
- package/lib/commonjs/locale/translations/ru.js.map +1 -1
- package/lib/commonjs/locale/translations/tr.js +11 -1
- package/lib/commonjs/locale/translations/tr.js.map +1 -1
- package/lib/commonjs/locale/translations/zh.js +11 -1
- package/lib/commonjs/locale/translations/zh.js.map +1 -1
- package/lib/commonjs/multi-agent-chat/AvatarHandoff.js +2 -4
- package/lib/commonjs/multi-agent-chat/AvatarHandoff.js.map +1 -1
- package/lib/commonjs/multi-agent-chat/ChatAgentProfile.js +97 -0
- package/lib/commonjs/multi-agent-chat/ChatAgentProfile.js.map +1 -0
- package/lib/commonjs/multi-agent-chat/EditorRail.js +4 -0
- package/lib/commonjs/multi-agent-chat/EditorRail.js.map +1 -1
- package/lib/commonjs/multi-agent-chat/MultiAgentChatBase.js +89 -126
- package/lib/commonjs/multi-agent-chat/MultiAgentChatBase.js.map +1 -1
- package/lib/commonjs/multi-agent-chat/ReplyRow.js +8 -11
- package/lib/commonjs/multi-agent-chat/ReplyRow.js.map +1 -1
- package/lib/commonjs/multi-agent-chat/handoff.js +5 -5
- package/lib/commonjs/multi-agent-chat/handoff.js.map +1 -1
- package/lib/commonjs/project-board/CreateTicketDialog.js +33 -2
- package/lib/commonjs/project-board/CreateTicketDialog.js.map +1 -1
- package/lib/commonjs/project-board/ProjectBoardBase.js +137 -38
- package/lib/commonjs/project-board/ProjectBoardBase.js.map +1 -1
- package/lib/commonjs/project-board/TicketCornerGenieSurface.web.js +34 -28
- package/lib/commonjs/project-board/TicketCornerGenieSurface.web.js.map +1 -1
- package/lib/commonjs/project-board/TicketDetailDialog.js +6 -3
- package/lib/commonjs/project-board/TicketDetailDialog.js.map +1 -1
- package/lib/commonjs/project-board/TicketGenieSurface.js +17 -7
- package/lib/commonjs/project-board/TicketGenieSurface.js.map +1 -1
- package/lib/commonjs/project-board/TicketGenieSurface.web.js +1 -1
- package/lib/commonjs/project-board/TicketGenieSurface.web.js.map +1 -1
- package/lib/commonjs/project-board/TicketPresence.js +125 -0
- package/lib/commonjs/project-board/TicketPresence.js.map +1 -0
- package/lib/commonjs/project-board/TicketTokenChart.js +23 -0
- package/lib/commonjs/project-board/TicketTokenChart.js.map +1 -0
- package/lib/commonjs/project-board/context.js +3 -1
- package/lib/commonjs/project-board/context.js.map +1 -1
- package/lib/commonjs/search/Search.js +12 -3
- package/lib/commonjs/search/Search.js.map +1 -1
- package/lib/commonjs/sidebar/SidebarToolbar.js +28 -14
- package/lib/commonjs/sidebar/SidebarToolbar.js.map +1 -1
- package/lib/commonjs/text-field/TextField.js +13 -7
- package/lib/commonjs/text-field/TextField.js.map +1 -1
- package/lib/module/agent-avatar/AgentAvatar.js +16 -204
- package/lib/module/agent-avatar/AgentAvatar.js.map +1 -1
- package/lib/module/agent-avatar/AgentAvatarProvider.js +65 -0
- package/lib/module/agent-avatar/AgentAvatarProvider.js.map +1 -0
- package/lib/module/agent-avatar/CharacterAvatar.js +208 -0
- package/lib/module/agent-avatar/CharacterAvatar.js.map +1 -0
- package/lib/module/agent-avatar/ProceduralAvatar.js +212 -0
- package/lib/module/agent-avatar/ProceduralAvatar.js.map +1 -0
- package/lib/module/agent-avatar/artwork.js +3 -3
- package/lib/module/agent-avatar/artwork.js.map +1 -1
- package/lib/module/agent-avatar/avatar-color.js +12 -0
- package/lib/module/agent-avatar/avatar-color.js.map +1 -0
- package/lib/module/agent-avatar/character-html.js +19 -0
- package/lib/module/agent-avatar/character-html.js.map +1 -0
- package/lib/module/agent-avatar/character-runtime-module.js +35 -0
- package/lib/module/agent-avatar/character-runtime-module.js.map +1 -0
- package/lib/module/agent-avatar/character-webview.js +14 -0
- package/lib/module/agent-avatar/character-webview.js.map +1 -0
- package/lib/module/agent-avatar/config-character.js +32 -0
- package/lib/module/agent-avatar/config-character.js.map +1 -0
- package/lib/module/agent-avatar/context.js +5 -0
- package/lib/module/agent-avatar/context.js.map +1 -1
- package/lib/module/agent-avatar/index.js +1 -0
- package/lib/module/agent-avatar/index.js.map +1 -1
- package/lib/module/agent-avatar/legacy-contours.js +53 -0
- package/lib/module/agent-avatar/legacy-contours.js.map +1 -0
- package/lib/module/agent-avatar/legacy-recipe.js +104 -0
- package/lib/module/agent-avatar/legacy-recipe.js.map +1 -0
- package/lib/module/agent-avatar/messages.js +2 -1
- package/lib/module/agent-avatar/messages.js.map +1 -1
- package/lib/module/agent-avatar/model.js +2 -0
- package/lib/module/agent-avatar/model.js.map +1 -1
- package/lib/module/agent-creator/AgentCreatorBase.js +248 -22
- package/lib/module/agent-creator/AgentCreatorBase.js.map +1 -1
- package/lib/module/agent-creator/CharacterControls.js +112 -0
- package/lib/module/agent-creator/CharacterControls.js.map +1 -0
- package/lib/module/agent-creator/EmotionPicker.js +52 -19
- package/lib/module/agent-creator/EmotionPicker.js.map +1 -1
- package/lib/module/agent-creator/ShapeArc.js +58 -28
- package/lib/module/agent-creator/ShapeArc.js.map +1 -1
- package/lib/module/agent-creator/ShapeSilhouette.js +57 -0
- package/lib/module/agent-creator/ShapeSilhouette.js.map +1 -0
- package/lib/module/agent-creator/constants.js +47 -0
- package/lib/module/agent-creator/constants.js.map +1 -1
- package/lib/module/agent-creator/messages.js +9 -0
- package/lib/module/agent-creator/messages.js.map +1 -1
- package/lib/module/agent-creator/shared.js +1 -9
- package/lib/module/agent-creator/shared.js.map +1 -1
- package/lib/module/agent-thinking/AgentThinking.js +5 -63
- package/lib/module/agent-thinking/AgentThinking.js.map +1 -1
- package/lib/module/agent-thinking/ThinkingLabel.js +73 -0
- package/lib/module/agent-thinking/ThinkingLabel.js.map +1 -0
- package/lib/module/chart-cards/TokensChartCard.js +20 -5
- package/lib/module/chart-cards/TokensChartCard.js.map +1 -1
- package/lib/module/locale/translations/ar.js +11 -1
- package/lib/module/locale/translations/ar.js.map +1 -1
- package/lib/module/locale/translations/bn.js +11 -1
- package/lib/module/locale/translations/bn.js.map +1 -1
- package/lib/module/locale/translations/ca.js +11 -1
- package/lib/module/locale/translations/ca.js.map +1 -1
- package/lib/module/locale/translations/de.js +11 -1
- package/lib/module/locale/translations/de.js.map +1 -1
- package/lib/module/locale/translations/es.js +11 -1
- package/lib/module/locale/translations/es.js.map +1 -1
- package/lib/module/locale/translations/fr.js +11 -1
- package/lib/module/locale/translations/fr.js.map +1 -1
- package/lib/module/locale/translations/hi.js +11 -1
- package/lib/module/locale/translations/hi.js.map +1 -1
- package/lib/module/locale/translations/id.js +11 -1
- package/lib/module/locale/translations/id.js.map +1 -1
- package/lib/module/locale/translations/it.js +11 -1
- package/lib/module/locale/translations/it.js.map +1 -1
- package/lib/module/locale/translations/ja.js +11 -1
- package/lib/module/locale/translations/ja.js.map +1 -1
- package/lib/module/locale/translations/pt.js +11 -1
- package/lib/module/locale/translations/pt.js.map +1 -1
- package/lib/module/locale/translations/ru.js +11 -1
- package/lib/module/locale/translations/ru.js.map +1 -1
- package/lib/module/locale/translations/tr.js +11 -1
- package/lib/module/locale/translations/tr.js.map +1 -1
- package/lib/module/locale/translations/zh.js +11 -1
- package/lib/module/locale/translations/zh.js.map +1 -1
- package/lib/module/multi-agent-chat/AvatarHandoff.js +3 -5
- package/lib/module/multi-agent-chat/AvatarHandoff.js.map +1 -1
- package/lib/module/multi-agent-chat/ChatAgentProfile.js +94 -0
- package/lib/module/multi-agent-chat/ChatAgentProfile.js.map +1 -0
- package/lib/module/multi-agent-chat/EditorRail.js +4 -0
- package/lib/module/multi-agent-chat/EditorRail.js.map +1 -1
- package/lib/module/multi-agent-chat/MultiAgentChatBase.js +89 -126
- package/lib/module/multi-agent-chat/MultiAgentChatBase.js.map +1 -1
- package/lib/module/multi-agent-chat/ReplyRow.js +9 -12
- package/lib/module/multi-agent-chat/ReplyRow.js.map +1 -1
- package/lib/module/multi-agent-chat/handoff.js +4 -4
- package/lib/module/multi-agent-chat/handoff.js.map +1 -1
- package/lib/module/project-board/CreateTicketDialog.js +33 -2
- package/lib/module/project-board/CreateTicketDialog.js.map +1 -1
- package/lib/module/project-board/ProjectBoardBase.js +138 -39
- package/lib/module/project-board/ProjectBoardBase.js.map +1 -1
- package/lib/module/project-board/TicketCornerGenieSurface.web.js +35 -29
- package/lib/module/project-board/TicketCornerGenieSurface.web.js.map +1 -1
- package/lib/module/project-board/TicketDetailDialog.js +7 -4
- package/lib/module/project-board/TicketDetailDialog.js.map +1 -1
- package/lib/module/project-board/TicketGenieSurface.js +17 -7
- package/lib/module/project-board/TicketGenieSurface.js.map +1 -1
- package/lib/module/project-board/TicketGenieSurface.web.js +1 -1
- package/lib/module/project-board/TicketGenieSurface.web.js.map +1 -1
- package/lib/module/project-board/TicketPresence.js +119 -0
- package/lib/module/project-board/TicketPresence.js.map +1 -0
- package/lib/module/project-board/TicketTokenChart.js +20 -0
- package/lib/module/project-board/TicketTokenChart.js.map +1 -0
- package/lib/module/project-board/context.js +2 -0
- package/lib/module/project-board/context.js.map +1 -1
- package/lib/module/search/Search.js +12 -3
- package/lib/module/search/Search.js.map +1 -1
- package/lib/module/sidebar/SidebarToolbar.js +29 -15
- package/lib/module/sidebar/SidebarToolbar.js.map +1 -1
- package/lib/module/text-field/TextField.js +13 -7
- package/lib/module/text-field/TextField.js.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/AgentAvatar.d.ts +2 -2
- package/lib/typescript/commonjs/agent-avatar/AgentAvatar.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/AgentAvatarProvider.d.ts +4 -0
- package/lib/typescript/commonjs/agent-avatar/AgentAvatarProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts +4 -0
- package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/ProceduralAvatar.d.ts +6 -0
- package/lib/typescript/commonjs/agent-avatar/ProceduralAvatar.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/artwork.d.ts +2 -1
- package/lib/typescript/commonjs/agent-avatar/artwork.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/avatar-color.d.ts +3 -0
- package/lib/typescript/commonjs/agent-avatar/avatar-color.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/character-html.d.ts +4 -0
- package/lib/typescript/commonjs/agent-avatar/character-html.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/character-runtime-module.d.ts +2 -0
- package/lib/typescript/commonjs/agent-avatar/character-runtime-module.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/character-webview.d.ts +24 -0
- package/lib/typescript/commonjs/agent-avatar/character-webview.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/config-character.d.ts +11 -0
- package/lib/typescript/commonjs/agent-avatar/config-character.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/context.d.ts +15 -0
- package/lib/typescript/commonjs/agent-avatar/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/index.d.ts +3 -1
- package/lib/typescript/commonjs/agent-avatar/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/legacy-contours.d.ts +5 -0
- package/lib/typescript/commonjs/agent-avatar/legacy-contours.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts +40 -0
- package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-avatar/messages.d.ts +1 -0
- package/lib/typescript/commonjs/agent-avatar/messages.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/model.d.ts +3 -0
- package/lib/typescript/commonjs/agent-avatar/model.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/types.d.ts +10 -1
- package/lib/typescript/commonjs/agent-avatar/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/AgentCreatorBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts +8 -0
- package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts +12 -1
- package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/ShapeArc.d.ts +11 -2
- package/lib/typescript/commonjs/agent-creator/ShapeArc.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts +6 -0
- package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts.map +1 -0
- package/lib/typescript/commonjs/agent-creator/constants.d.ts +44 -0
- package/lib/typescript/commonjs/agent-creator/constants.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/context.d.ts +9 -0
- package/lib/typescript/commonjs/agent-creator/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/messages.d.ts +10 -0
- package/lib/typescript/commonjs/agent-creator/messages.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/shared.d.ts +1 -1
- package/lib/typescript/commonjs/agent-creator/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-thinking/AgentThinking.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-thinking/ThinkingLabel.d.ts +7 -0
- package/lib/typescript/commonjs/agent-thinking/ThinkingLabel.d.ts.map +1 -0
- package/lib/typescript/commonjs/chart-cards/TokensChartCard.d.ts +3 -1
- package/lib/typescript/commonjs/chart-cards/TokensChartCard.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/ar.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/bn.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/ca.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/de.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/es.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/fr.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/hi.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/id.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/it.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/ja.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/pt.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/ru.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/tr.d.ts.map +1 -1
- package/lib/typescript/commonjs/locale/translations/zh.d.ts.map +1 -1
- package/lib/typescript/commonjs/multi-agent-chat/AvatarHandoff.d.ts.map +1 -1
- package/lib/typescript/commonjs/multi-agent-chat/ChatAgentProfile.d.ts +11 -0
- package/lib/typescript/commonjs/multi-agent-chat/ChatAgentProfile.d.ts.map +1 -0
- package/lib/typescript/commonjs/multi-agent-chat/EditorRail.d.ts.map +1 -1
- package/lib/typescript/commonjs/multi-agent-chat/MultiAgentChatBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/multi-agent-chat/ReplyRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/multi-agent-chat/handoff.d.ts +2 -2
- package/lib/typescript/commonjs/multi-agent-chat/handoff.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/CreateTicketDialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/ProjectBoardBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/TicketCornerGenieSurface.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/TicketDetailDialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/TicketGenieSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/project-board/TicketPresence.d.ts +17 -0
- package/lib/typescript/commonjs/project-board/TicketPresence.d.ts.map +1 -0
- package/lib/typescript/commonjs/project-board/TicketTokenChart.d.ts +5 -0
- package/lib/typescript/commonjs/project-board/TicketTokenChart.d.ts.map +1 -0
- package/lib/typescript/commonjs/project-board/context.d.ts +2 -0
- package/lib/typescript/commonjs/project-board/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/search/Search.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/SidebarToolbar.d.ts.map +1 -1
- package/lib/typescript/commonjs/text-field/TextField.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/AgentAvatar.d.ts +2 -2
- package/lib/typescript/module/agent-avatar/AgentAvatar.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/AgentAvatarProvider.d.ts +4 -0
- package/lib/typescript/module/agent-avatar/AgentAvatarProvider.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts +4 -0
- package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/ProceduralAvatar.d.ts +6 -0
- package/lib/typescript/module/agent-avatar/ProceduralAvatar.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/artwork.d.ts +2 -1
- package/lib/typescript/module/agent-avatar/artwork.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/avatar-color.d.ts +3 -0
- package/lib/typescript/module/agent-avatar/avatar-color.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/character-html.d.ts +4 -0
- package/lib/typescript/module/agent-avatar/character-html.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/character-runtime-module.d.ts +2 -0
- package/lib/typescript/module/agent-avatar/character-runtime-module.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/character-webview.d.ts +24 -0
- package/lib/typescript/module/agent-avatar/character-webview.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/config-character.d.ts +11 -0
- package/lib/typescript/module/agent-avatar/config-character.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/context.d.ts +15 -0
- package/lib/typescript/module/agent-avatar/context.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/index.d.ts +3 -1
- package/lib/typescript/module/agent-avatar/index.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/legacy-contours.d.ts +5 -0
- package/lib/typescript/module/agent-avatar/legacy-contours.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts +40 -0
- package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts.map +1 -0
- package/lib/typescript/module/agent-avatar/messages.d.ts +1 -0
- package/lib/typescript/module/agent-avatar/messages.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/model.d.ts +3 -0
- package/lib/typescript/module/agent-avatar/model.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/types.d.ts +10 -1
- package/lib/typescript/module/agent-avatar/types.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/AgentCreatorBase.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/CharacterControls.d.ts +8 -0
- package/lib/typescript/module/agent-creator/CharacterControls.d.ts.map +1 -0
- package/lib/typescript/module/agent-creator/EmotionPicker.d.ts +12 -1
- package/lib/typescript/module/agent-creator/EmotionPicker.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/ShapeArc.d.ts +11 -2
- package/lib/typescript/module/agent-creator/ShapeArc.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts +6 -0
- package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts.map +1 -0
- package/lib/typescript/module/agent-creator/constants.d.ts +44 -0
- package/lib/typescript/module/agent-creator/constants.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/context.d.ts +9 -0
- package/lib/typescript/module/agent-creator/context.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/messages.d.ts +10 -0
- package/lib/typescript/module/agent-creator/messages.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/shared.d.ts +1 -1
- package/lib/typescript/module/agent-creator/shared.d.ts.map +1 -1
- package/lib/typescript/module/agent-thinking/AgentThinking.d.ts.map +1 -1
- package/lib/typescript/module/agent-thinking/ThinkingLabel.d.ts +7 -0
- package/lib/typescript/module/agent-thinking/ThinkingLabel.d.ts.map +1 -0
- package/lib/typescript/module/chart-cards/TokensChartCard.d.ts +3 -1
- package/lib/typescript/module/chart-cards/TokensChartCard.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/ar.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/bn.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/ca.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/de.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/es.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/fr.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/hi.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/id.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/it.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/ja.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/pt.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/ru.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/tr.d.ts.map +1 -1
- package/lib/typescript/module/locale/translations/zh.d.ts.map +1 -1
- package/lib/typescript/module/multi-agent-chat/AvatarHandoff.d.ts.map +1 -1
- package/lib/typescript/module/multi-agent-chat/ChatAgentProfile.d.ts +11 -0
- package/lib/typescript/module/multi-agent-chat/ChatAgentProfile.d.ts.map +1 -0
- package/lib/typescript/module/multi-agent-chat/EditorRail.d.ts.map +1 -1
- package/lib/typescript/module/multi-agent-chat/MultiAgentChatBase.d.ts.map +1 -1
- package/lib/typescript/module/multi-agent-chat/ReplyRow.d.ts.map +1 -1
- package/lib/typescript/module/multi-agent-chat/handoff.d.ts +2 -2
- package/lib/typescript/module/multi-agent-chat/handoff.d.ts.map +1 -1
- package/lib/typescript/module/project-board/CreateTicketDialog.d.ts.map +1 -1
- package/lib/typescript/module/project-board/ProjectBoardBase.d.ts.map +1 -1
- package/lib/typescript/module/project-board/TicketCornerGenieSurface.web.d.ts.map +1 -1
- package/lib/typescript/module/project-board/TicketDetailDialog.d.ts.map +1 -1
- package/lib/typescript/module/project-board/TicketGenieSurface.d.ts.map +1 -1
- package/lib/typescript/module/project-board/TicketPresence.d.ts +17 -0
- package/lib/typescript/module/project-board/TicketPresence.d.ts.map +1 -0
- package/lib/typescript/module/project-board/TicketTokenChart.d.ts +5 -0
- package/lib/typescript/module/project-board/TicketTokenChart.d.ts.map +1 -0
- package/lib/typescript/module/project-board/context.d.ts +2 -0
- package/lib/typescript/module/project-board/context.d.ts.map +1 -1
- package/lib/typescript/module/search/Search.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/SidebarToolbar.d.ts.map +1 -1
- package/lib/typescript/module/text-field/TextField.d.ts.map +1 -1
- package/package.json +8 -3
- package/src/agent-avatar/AgentAvatar.tsx +16 -296
- package/src/agent-avatar/AgentAvatarProvider.tsx +79 -0
- package/src/agent-avatar/CharacterAvatar.tsx +260 -0
- package/src/agent-avatar/ProceduralAvatar.tsx +303 -0
- package/src/agent-avatar/artwork.ts +3 -3
- package/src/agent-avatar/avatar-color.ts +17 -0
- package/src/agent-avatar/character-html.ts +21 -0
- package/src/agent-avatar/character-runtime-module.ts +37 -0
- package/src/agent-avatar/character-webview.ts +24 -0
- package/src/agent-avatar/config-character.ts +40 -0
- package/src/agent-avatar/context.ts +17 -0
- package/src/agent-avatar/index.ts +4 -1
- package/src/agent-avatar/legacy-contours.ts +76 -0
- package/src/agent-avatar/legacy-recipe.ts +123 -0
- package/src/agent-avatar/messages.ts +1 -0
- package/src/agent-avatar/model.ts +5 -0
- package/src/agent-avatar/types.ts +12 -1
- package/src/agent-creator/AgentCreatorBase.tsx +338 -39
- package/src/agent-creator/CharacterControls.tsx +150 -0
- package/src/agent-creator/EmotionPicker.tsx +43 -21
- package/src/agent-creator/ShapeArc.tsx +83 -29
- package/src/agent-creator/ShapeSilhouette.tsx +65 -0
- package/src/agent-creator/constants.ts +30 -0
- package/src/agent-creator/messages.ts +19 -0
- package/src/agent-creator/shared.ts +1 -15
- package/src/agent-thinking/AgentThinking.tsx +7 -70
- package/src/agent-thinking/ThinkingLabel.tsx +74 -0
- package/src/chart-cards/TokensChartCard.tsx +10 -6
- package/src/locale/translations/ar.ts +10 -1
- package/src/locale/translations/bn.ts +10 -1
- package/src/locale/translations/ca.ts +10 -1
- package/src/locale/translations/de.ts +10 -1
- package/src/locale/translations/es.ts +10 -1
- package/src/locale/translations/fr.ts +10 -1
- package/src/locale/translations/hi.ts +10 -1
- package/src/locale/translations/id.ts +10 -1
- package/src/locale/translations/it.ts +10 -1
- package/src/locale/translations/ja.ts +10 -1
- package/src/locale/translations/pt.ts +10 -1
- package/src/locale/translations/ru.ts +10 -1
- package/src/locale/translations/tr.ts +10 -1
- package/src/locale/translations/zh.ts +10 -1
- package/src/multi-agent-chat/AvatarHandoff.tsx +2 -5
- package/src/multi-agent-chat/ChatAgentProfile.tsx +116 -0
- package/src/multi-agent-chat/EditorRail.tsx +2 -0
- package/src/multi-agent-chat/MultiAgentChatBase.tsx +123 -175
- package/src/multi-agent-chat/ReplyRow.tsx +10 -9
- package/src/multi-agent-chat/handoff.ts +4 -4
- package/src/project-board/CreateTicketDialog.tsx +28 -4
- package/src/project-board/ProjectBoardBase.tsx +115 -21
- package/src/project-board/TicketCornerGenieSurface.web.tsx +11 -6
- package/src/project-board/TicketDetailDialog.tsx +5 -4
- package/src/project-board/TicketGenieSurface.tsx +9 -0
- package/src/project-board/TicketGenieSurface.web.tsx +1 -1
- package/src/project-board/TicketPresence.tsx +137 -0
- package/src/project-board/TicketTokenChart.tsx +14 -0
- package/src/project-board/context.ts +2 -0
- package/src/search/Search.tsx +6 -5
- package/src/sidebar/SidebarToolbar.tsx +27 -15
- package/src/text-field/TextField.tsx +12 -7
|
@@ -12,16 +12,18 @@ import {
|
|
|
12
12
|
ScrollView,
|
|
13
13
|
useWindowDimensions,
|
|
14
14
|
type View,
|
|
15
|
+
type ViewStyle,
|
|
15
16
|
} from 'react-native';
|
|
16
17
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
17
18
|
import Animated, {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
LinearTransition,
|
|
19
|
+
cancelAnimation,
|
|
20
|
+
Easing,
|
|
21
21
|
runOnJS,
|
|
22
22
|
useAnimatedStyle,
|
|
23
23
|
useReducedMotion,
|
|
24
24
|
useSharedValue,
|
|
25
|
+
withTiming,
|
|
26
|
+
type AnimatedStyle,
|
|
25
27
|
} from 'react-native-reanimated';
|
|
26
28
|
import { Avatar } from '../avatar';
|
|
27
29
|
import { Breadcrumb, BreadcrumbItem } from '../breadcrumb';
|
|
@@ -48,6 +50,7 @@ import {
|
|
|
48
50
|
SourceView,
|
|
49
51
|
} from './SourcePrimitives';
|
|
50
52
|
import { TicketDetailDialog } from './TicketDetailDialog';
|
|
53
|
+
import { TicketPresenceList } from './TicketPresence';
|
|
51
54
|
import { cx, PRIORITY_STYLES } from './constants';
|
|
52
55
|
import { useProjectBoardPlatform } from './context';
|
|
53
56
|
import { PROJECT_BOARD_MESSAGES } from './messages';
|
|
@@ -260,18 +263,34 @@ export function ProjectBoardBase({
|
|
|
260
263
|
const boardRect = useRef<BoardRect | null>(null);
|
|
261
264
|
const boardNode = useRef<View>(null);
|
|
262
265
|
const [activeTicket, setActiveTicket] = useState<ProjectTicket | null>(null);
|
|
266
|
+
const [droppingId, setDroppingId] = useState<string | null>(null);
|
|
263
267
|
const activeId = useRef<string | null>(null);
|
|
264
268
|
const [over, setOver] = useState<{ columnId: string; index: number } | null>(
|
|
265
269
|
null,
|
|
266
270
|
);
|
|
267
271
|
const targetRef = useRef<typeof over>(null);
|
|
268
272
|
const beforeKeyboard = useRef<ProjectColumn[] | null>(null);
|
|
273
|
+
const beforePointer = useRef<ProjectColumn[] | null>(null);
|
|
269
274
|
const keyboardActive = useRef(false);
|
|
270
275
|
const lastDragEnd = useRef(0);
|
|
271
276
|
const draggedWidth = useSharedValue(261);
|
|
272
277
|
const dragX = useSharedValue(0);
|
|
273
278
|
const dragY = useSharedValue(0);
|
|
274
279
|
const fingerOffset = useRef({ x: 0, y: 0 });
|
|
280
|
+
const dropFrame = useRef(0);
|
|
281
|
+
const dropGeneration = useRef(0);
|
|
282
|
+
useEffect(() => () => {
|
|
283
|
+
dropGeneration.current++;
|
|
284
|
+
if (dropFrame.current) cancelAnimationFrame(dropFrame.current);
|
|
285
|
+
cancelAnimation(dragX);
|
|
286
|
+
cancelAnimation(dragY);
|
|
287
|
+
cancelAnimation(draggedWidth);
|
|
288
|
+
}, [dragX, dragY, draggedWidth]);
|
|
289
|
+
const finishDrop = useCallback((generation?: number) => {
|
|
290
|
+
if (generation !== undefined && generation !== dropGeneration.current) return;
|
|
291
|
+
setActiveTicket(null);
|
|
292
|
+
setDroppingId(null);
|
|
293
|
+
}, []);
|
|
275
294
|
const overlayStyle = useAnimatedStyle(
|
|
276
295
|
() => ({
|
|
277
296
|
position: 'absolute',
|
|
@@ -341,6 +360,13 @@ export function ProjectBoardBase({
|
|
|
341
360
|
measure();
|
|
342
361
|
const rect = ticketRects.current[id];
|
|
343
362
|
activeId.current = id;
|
|
363
|
+
beforePointer.current = cloneColumns(columnsRef.current);
|
|
364
|
+
dropGeneration.current++;
|
|
365
|
+
cancelAnimation(dragX);
|
|
366
|
+
cancelAnimation(dragY);
|
|
367
|
+
cancelAnimation(draggedWidth);
|
|
368
|
+
if (dropFrame.current) cancelAnimationFrame(dropFrame.current);
|
|
369
|
+
setDroppingId(null);
|
|
344
370
|
fingerOffset.current = {
|
|
345
371
|
x: rect ? x - rect.x : 0,
|
|
346
372
|
y: rect ? y - rect.y : 0,
|
|
@@ -373,6 +399,15 @@ export function ProjectBoardBase({
|
|
|
373
399
|
targetRef.current = next;
|
|
374
400
|
setOver(next);
|
|
375
401
|
}
|
|
402
|
+
if (next) {
|
|
403
|
+
const current = columnsRef.current;
|
|
404
|
+
const source = current.find((column) => column.tickets.some((ticket) => ticket.id === activeId.current));
|
|
405
|
+
if (source && source.id !== next.columnId) {
|
|
406
|
+
const preview = moveTicket(current, activeId.current, next.columnId, next.index);
|
|
407
|
+
columnsRef.current = preview;
|
|
408
|
+
setColumns(preview);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
376
411
|
const board = boardRect.current;
|
|
377
412
|
if (board && (x < board.x + 32 || x > board.x + board.width - 32)) {
|
|
378
413
|
scrollX.current = Math.max(
|
|
@@ -419,14 +454,45 @@ export function ProjectBoardBase({
|
|
|
419
454
|
AccessibilityInfo.announceForAccessibility?.(
|
|
420
455
|
`${activeTicket?.code ?? ''}, ${columnsRef.current.find((column) => column.id === target.columnId)?.title ?? target.columnId}`,
|
|
421
456
|
);
|
|
457
|
+
} else if (beforePointer.current) {
|
|
458
|
+
columnsRef.current = beforePointer.current;
|
|
459
|
+
setColumns(beforePointer.current);
|
|
422
460
|
}
|
|
461
|
+
beforePointer.current = null;
|
|
423
462
|
activeId.current = null;
|
|
424
463
|
targetRef.current = null;
|
|
425
464
|
lastDragEnd.current = Date.now();
|
|
426
|
-
setActiveTicket(null);
|
|
427
465
|
setOver(null);
|
|
466
|
+
if (reducedMotion) {
|
|
467
|
+
finishDrop();
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
setDroppingId(id);
|
|
471
|
+
const generation = ++dropGeneration.current;
|
|
472
|
+
// React first mounts the destination ticket; its window rect is the
|
|
473
|
+
// landing position even after a column reorder or a scaled preview.
|
|
474
|
+
dropFrame.current = requestAnimationFrame(() => {
|
|
475
|
+
const node = ticketNodes.current[id];
|
|
476
|
+
if (!node) {
|
|
477
|
+
finishDrop(generation);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
node.measureInWindow((x, y, width) => {
|
|
481
|
+
if (generation !== dropGeneration.current) return;
|
|
482
|
+
if (![x, y, width].every(Number.isFinite) || width <= 0) {
|
|
483
|
+
finishDrop(generation);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const config = { duration: 320, easing: Easing.bezier(0.22, 1, 0.36, 1) };
|
|
487
|
+
dragX.value = withTiming(x, config);
|
|
488
|
+
draggedWidth.value = withTiming(width, config);
|
|
489
|
+
dragY.value = withTiming(y, config, (finished) => {
|
|
490
|
+
if (finished) runOnJS(finishDrop)(generation);
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
});
|
|
428
494
|
},
|
|
429
|
-
[visibleColumns, activeTicket, commit],
|
|
495
|
+
[visibleColumns, activeTicket, commit, reducedMotion, finishDrop, dragX, dragY, draggedWidth],
|
|
430
496
|
);
|
|
431
497
|
function keyboardMove(id: string, key: string) {
|
|
432
498
|
const current = columnsRef.current;
|
|
@@ -792,8 +858,6 @@ export function ProjectBoardBase({
|
|
|
792
858
|
contentContainerStyle={{
|
|
793
859
|
paddingHorizontal: 6,
|
|
794
860
|
paddingTop: 8,
|
|
795
|
-
paddingBottom: 6,
|
|
796
|
-
gap: 6,
|
|
797
861
|
}}
|
|
798
862
|
accessibilityLabel={column.title}
|
|
799
863
|
onScroll={(event) => {
|
|
@@ -803,18 +867,23 @@ export function ProjectBoardBase({
|
|
|
803
867
|
}}
|
|
804
868
|
scrollEventThrottle={16}
|
|
805
869
|
>
|
|
806
|
-
{column.tickets.
|
|
870
|
+
<TicketPresenceList tickets={column.tickets} retainId={beforePointer.current ? activeTicket?.id : undefined}>
|
|
871
|
+
{({ ticket, present }, paintStyle, onHeight) => present || (activeTicket?.id === ticket.id && beforePointer.current !== null) ? (
|
|
807
872
|
<DraggableTicket
|
|
808
873
|
key={ticket.id}
|
|
809
874
|
nativeID={`${boardId}-${ticket.id}`}
|
|
810
875
|
ticket={ticket}
|
|
876
|
+
interactive={present}
|
|
811
877
|
members={members}
|
|
812
878
|
dragging={activeTicket?.id === ticket.id}
|
|
879
|
+
landing={droppingId === ticket.id}
|
|
880
|
+
paintStyle={paintStyle}
|
|
881
|
+
onHeight={onHeight}
|
|
813
882
|
target={
|
|
814
|
-
over?.columnId === column.id && over.index ===
|
|
883
|
+
over?.columnId === column.id && over.index === column.tickets.findIndex((item) => item.id === ticket.id)
|
|
815
884
|
}
|
|
816
885
|
register={(node) => {
|
|
817
|
-
ticketNodes.current[ticket.id] = node;
|
|
886
|
+
if (present) ticketNodes.current[ticket.id] = node;
|
|
818
887
|
}}
|
|
819
888
|
onLayout={measure}
|
|
820
889
|
onOpen={() => openDetail(ticket.id)}
|
|
@@ -851,7 +920,16 @@ export function ProjectBoardBase({
|
|
|
851
920
|
}
|
|
852
921
|
}}
|
|
853
922
|
/>
|
|
854
|
-
|
|
923
|
+
) : (
|
|
924
|
+
<SourceView onLayout={(event) => onHeight(event.nativeEvent.layout.height)}>
|
|
925
|
+
<AnimatedView style={paintStyle}>
|
|
926
|
+
<SourceView className="pointer-events-none opacity-20">
|
|
927
|
+
<TicketCard overlay ticket={ticket} members={members} />
|
|
928
|
+
</SourceView>
|
|
929
|
+
</AnimatedView>
|
|
930
|
+
</SourceView>
|
|
931
|
+
)}
|
|
932
|
+
</TicketPresenceList>
|
|
855
933
|
{over?.columnId === column.id &&
|
|
856
934
|
over.index >= column.tickets.length && (
|
|
857
935
|
<StyledView
|
|
@@ -868,7 +946,14 @@ export function ProjectBoardBase({
|
|
|
868
946
|
{activeTicket && (
|
|
869
947
|
<Portal>
|
|
870
948
|
<OverlayRoot>
|
|
871
|
-
<AnimatedView
|
|
949
|
+
<AnimatedView
|
|
950
|
+
testID="project-board-drag-overlay"
|
|
951
|
+
pointerEvents="none"
|
|
952
|
+
aria-hidden
|
|
953
|
+
accessibilityElementsHidden
|
|
954
|
+
importantForAccessibility="no-hide-descendants"
|
|
955
|
+
style={overlayStyle}
|
|
956
|
+
>
|
|
872
957
|
<TicketCard overlay ticket={activeTicket} members={members} />
|
|
873
958
|
</AnimatedView>
|
|
874
959
|
</OverlayRoot>
|
|
@@ -915,8 +1000,12 @@ export function ProjectBoardBase({
|
|
|
915
1000
|
function DraggableTicket({
|
|
916
1001
|
nativeID,
|
|
917
1002
|
ticket,
|
|
1003
|
+
interactive,
|
|
918
1004
|
members,
|
|
919
1005
|
dragging,
|
|
1006
|
+
landing,
|
|
1007
|
+
paintStyle,
|
|
1008
|
+
onHeight,
|
|
920
1009
|
target,
|
|
921
1010
|
register,
|
|
922
1011
|
onLayout,
|
|
@@ -928,8 +1017,12 @@ function DraggableTicket({
|
|
|
928
1017
|
}: {
|
|
929
1018
|
nativeID: string;
|
|
930
1019
|
ticket: ProjectTicket;
|
|
1020
|
+
interactive: boolean;
|
|
931
1021
|
members: Readonly<Record<string, ProjectMember>>;
|
|
932
1022
|
dragging: boolean;
|
|
1023
|
+
landing: boolean;
|
|
1024
|
+
paintStyle: AnimatedStyle<ViewStyle>;
|
|
1025
|
+
onHeight: (height: number) => void;
|
|
933
1026
|
target: boolean;
|
|
934
1027
|
register: (node: View | null) => void;
|
|
935
1028
|
onLayout: () => void;
|
|
@@ -940,7 +1033,6 @@ function DraggableTicket({
|
|
|
940
1033
|
onAccessibleMove: (direction: 'up' | 'down' | 'next' | 'previous') => void;
|
|
941
1034
|
}) {
|
|
942
1035
|
const { colors } = useTheme();
|
|
943
|
-
const reducedMotion = useReducedMotion();
|
|
944
1036
|
const { messages: m } = useMessages(PROJECT_BOARD_MESSAGES);
|
|
945
1037
|
const callbacks = useRef({ onStart, onUpdate, onEnd });
|
|
946
1038
|
callbacks.current = { onStart, onUpdate, onEnd };
|
|
@@ -976,21 +1068,21 @@ function DraggableTicket({
|
|
|
976
1068
|
return (
|
|
977
1069
|
<GestureDetector gesture={gesture}>
|
|
978
1070
|
<AnimatedView
|
|
979
|
-
entering={reducedMotion ? undefined : FadeIn.duration(320)}
|
|
980
|
-
exiting={reducedMotion ? undefined : FadeOut.duration(320)}
|
|
981
|
-
layout={reducedMotion ? undefined : LinearTransition.duration(260)}
|
|
982
1071
|
className="shrink-0 touch-manipulation rounded-xl outline-none focus-visible:ring-[2.5px] focus-visible:ring-border-button-hover"
|
|
983
1072
|
style={{
|
|
984
|
-
opacity: dragging ? 0.2 : 1,
|
|
1073
|
+
opacity: landing ? 0 : dragging ? 0.2 : 1,
|
|
985
1074
|
borderTopWidth: target ? 3 : 0,
|
|
986
1075
|
borderTopColor: colors.primary,
|
|
987
1076
|
}}
|
|
988
1077
|
>
|
|
989
1078
|
<StyledPressable
|
|
990
|
-
nativeID={nativeID}
|
|
1079
|
+
nativeID={interactive ? nativeID : undefined}
|
|
991
1080
|
ref={register}
|
|
992
|
-
onLayout={
|
|
993
|
-
|
|
1081
|
+
onLayout={(event) => {
|
|
1082
|
+
onHeight(event.nativeEvent.layout.height);
|
|
1083
|
+
onLayout();
|
|
1084
|
+
}}
|
|
1085
|
+
onPress={interactive ? onOpen : undefined}
|
|
994
1086
|
accessibilityRole="button"
|
|
995
1087
|
accessibilityLabel={m.openTicket(ticket.code, ticket.title)}
|
|
996
1088
|
aria-haspopup="dialog"
|
|
@@ -1014,7 +1106,9 @@ function DraggableTicket({
|
|
|
1014
1106
|
);
|
|
1015
1107
|
}}
|
|
1016
1108
|
>
|
|
1017
|
-
<
|
|
1109
|
+
<AnimatedView style={paintStyle}>
|
|
1110
|
+
<TicketCard ticket={ticket} members={members} />
|
|
1111
|
+
</AnimatedView>
|
|
1018
1112
|
</StyledPressable>
|
|
1019
1113
|
</AnimatedView>
|
|
1020
1114
|
</GestureDetector>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useEffect, useRef, type ReactNode } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState, type ReactNode } from 'react';
|
|
2
2
|
import { useReducedMotion } from 'react-native-reanimated';
|
|
3
3
|
import { useDialogContext } from '../dialog/context';
|
|
4
4
|
import { adoptStyleSheet } from '../styles/adopt-style-sheet';
|
|
5
|
+
import { TicketGenieEnteredContext } from './context';
|
|
5
6
|
const styles = {
|
|
6
|
-
'animate-chart-reveal': 'bloom-ticket-detail-animate-chart-reveal',
|
|
7
7
|
band: 'bloom-ticket-detail-band',
|
|
8
8
|
bands: 'bloom-ticket-detail-bands',
|
|
9
9
|
genie: 'bloom-ticket-detail-genie',
|
|
@@ -12,7 +12,7 @@ const styles = {
|
|
|
12
12
|
surface: 'bloom-ticket-detail-surface',
|
|
13
13
|
};
|
|
14
14
|
const CSS =
|
|
15
|
-
'/* React Aria keeps the panel mounted for the shared Genie timeline.\n * Its pixels bend into the bottom-right dock; the shell never slides. */\n.bloom-ticket-detail-panel[data-entering], .bloom-ticket-detail-panel[data-exiting] { animation: bloom-ticket-detail-detail-presence 560ms linear both; }\n.bloom-ticket-detail-panel[data-exiting] { pointer-events: none; }\n@keyframes bloom-ticket-detail-detail-presence {\n from { opacity: 0.9999; }\n to { opacity: 1; }\n}\n.bloom-ticket-detail-genie, .bloom-ticket-detail-surface { position: relative; height: 100%; min-height: 0; }\n.bloom-ticket-detail-genie { isolation: isolate; }\n/* Start the chart\'s own drawing animation only after the visual bands hand\n * back to the live panel, so it never flashes a completed copy first. */\n.bloom-ticket-detail-genie:not([data-entered="true"])
|
|
15
|
+
'/* React Aria keeps the panel mounted for the shared Genie timeline.\n * Its pixels bend into the bottom-right dock; the shell never slides. */\n.bloom-ticket-detail-panel[data-entering], .bloom-ticket-detail-panel[data-exiting] { animation: bloom-ticket-detail-detail-presence 560ms linear both; }\n.bloom-ticket-detail-panel[data-exiting] { pointer-events: none; }\n@keyframes bloom-ticket-detail-detail-presence {\n from { opacity: 0.9999; }\n to { opacity: 1; }\n}\n.bloom-ticket-detail-genie, .bloom-ticket-detail-surface { position: relative; height: 100%; min-height: 0; }\n.bloom-ticket-detail-genie { isolation: isolate; }\n/* Start the chart\'s own drawing animation only after the visual bands hand\n * back to the live panel, so it never flashes a completed copy first. */\n.bloom-ticket-detail-genie:not([data-entered="true"]) .bloom-ticket-detail-chart svg {\n visibility: hidden;\n}\n.bloom-ticket-detail-shadow {\n position: absolute;\n inset: 0;\n border-radius: 24px;\n pointer-events: none;\n transform-origin: right bottom;\n box-shadow: -10px 0 34px rgb(0 0 0 / 0.05), -10px 0 250px rgb(0 0 0 / 0.25);\n}\n.bloom-ticket-detail-bands { position: absolute; inset: 0; pointer-events: none; opacity: 0; }\n.bloom-ticket-detail-band {\n position: absolute;\n top: 0;\n left: 0;\n overflow: hidden;\n contain: strict;\n transform-origin: 0 0;\n will-change: transform;\n backface-visibility: hidden;\n}\n@media (prefers-reduced-motion: reduce) {\n .bloom-ticket-detail-panel[data-entering], .bloom-ticket-detail-panel[data-exiting] { animation: none; }\n}\n';
|
|
16
16
|
|
|
17
17
|
const DURATION = 480;
|
|
18
18
|
const FRAMES = 32;
|
|
@@ -93,8 +93,8 @@ function rebaseIds(copy: HTMLElement, prefix: string) {
|
|
|
93
93
|
* gradient fills differently in each perspective-transformed clipping band.
|
|
94
94
|
* A shared bitmap keeps every band on the same paint, at device resolution. */
|
|
95
95
|
async function snapshotCharts(source: HTMLDivElement, copy: HTMLDivElement) {
|
|
96
|
-
const charts = source.querySelectorAll<SVGSVGElement>('
|
|
97
|
-
const copies = copy.querySelectorAll<SVGSVGElement>('
|
|
96
|
+
const charts = source.querySelectorAll<SVGSVGElement>('.bloom-ticket-detail-chart svg');
|
|
97
|
+
const copies = copy.querySelectorAll<SVGSVGElement>('.bloom-ticket-detail-chart svg');
|
|
98
98
|
await Promise.allSettled(
|
|
99
99
|
Array.from(charts, async (chart, index) => {
|
|
100
100
|
const { width, height } = chart.getBoundingClientRect();
|
|
@@ -206,6 +206,7 @@ export function TicketCornerGenieSurface({
|
|
|
206
206
|
const shadowRef = useRef<HTMLDivElement>(null);
|
|
207
207
|
const progressRef = useRef(1);
|
|
208
208
|
const reducedMotion = useReducedMotion();
|
|
209
|
+
const [entered, setEntered] = useState(reducedMotion);
|
|
209
210
|
|
|
210
211
|
useEffect(() => {
|
|
211
212
|
const root = rootRef.current;
|
|
@@ -215,6 +216,7 @@ export function TicketCornerGenieSurface({
|
|
|
215
216
|
if (!root || !surface || !bands || !shadow) return;
|
|
216
217
|
if (reducedMotion) {
|
|
217
218
|
root.dataset.entered = 'true';
|
|
219
|
+
setEntered(true);
|
|
218
220
|
surface.style.opacity = '1';
|
|
219
221
|
shadow.style.opacity = '1';
|
|
220
222
|
bands.replaceChildren();
|
|
@@ -247,7 +249,7 @@ export function TicketCornerGenieSurface({
|
|
|
247
249
|
// invisible plot adds SVG serialization, PNG encoding, and two decodes
|
|
248
250
|
// to the cold opening path without contributing any visible pixels.
|
|
249
251
|
template
|
|
250
|
-
.querySelectorAll('
|
|
252
|
+
.querySelectorAll('.bloom-ticket-detail-chart svg')
|
|
251
253
|
.forEach((chart) => chart.remove());
|
|
252
254
|
}
|
|
253
255
|
if (cancelled) return;
|
|
@@ -346,6 +348,7 @@ export function TicketCornerGenieSurface({
|
|
|
346
348
|
progressRef.current = to;
|
|
347
349
|
if (!exiting) {
|
|
348
350
|
root.dataset.entered = 'true';
|
|
351
|
+
setEntered(true);
|
|
349
352
|
surface.style.opacity = '1';
|
|
350
353
|
shadow.style.opacity = '1';
|
|
351
354
|
shadow.style.transform = 'none';
|
|
@@ -381,6 +384,7 @@ export function TicketCornerGenieSurface({
|
|
|
381
384
|
}, [exiting, reducedMotion]);
|
|
382
385
|
|
|
383
386
|
return (
|
|
387
|
+
<TicketGenieEnteredContext.Provider value={entered}>
|
|
384
388
|
<div ref={rootRef} className={styles.genie}>
|
|
385
389
|
<div
|
|
386
390
|
ref={shadowRef}
|
|
@@ -397,5 +401,6 @@ export function TicketCornerGenieSurface({
|
|
|
397
401
|
</div>
|
|
398
402
|
<div ref={bandsRef} aria-hidden inert className={styles.bands} />
|
|
399
403
|
</div>
|
|
404
|
+
</TicketGenieEnteredContext.Provider>
|
|
400
405
|
);
|
|
401
406
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Linking, Platform, ScrollView } from 'react-native';
|
|
3
|
-
import {
|
|
2
|
+
import { Linking, Platform, ScrollView, useWindowDimensions } from 'react-native';
|
|
3
|
+
import { TicketTokenChart } from './TicketTokenChart';
|
|
4
4
|
import { useDialogControl } from '../dialog/context';
|
|
5
5
|
import { useIsRtl } from '../hooks/use-is-rtl';
|
|
6
6
|
import { useMessages } from '../locale/messages';
|
|
@@ -93,6 +93,7 @@ export function TicketDetailDialog({
|
|
|
93
93
|
} = useProjectBoardPlatform();
|
|
94
94
|
const control = useDialogControl();
|
|
95
95
|
const rtl = useIsRtl();
|
|
96
|
+
const { width: viewportWidth } = useWindowDimensions();
|
|
96
97
|
const [comment, setComment] = useState('');
|
|
97
98
|
const [editingDescription, setEditingDescription] = useState(false);
|
|
98
99
|
const [draft, setDraft] = useState(ticket.description ?? '');
|
|
@@ -175,7 +176,7 @@ export function TicketDetailDialog({
|
|
|
175
176
|
containerStyle={{
|
|
176
177
|
alignItems: 'flex-end',
|
|
177
178
|
justifyContent: 'flex-start',
|
|
178
|
-
padding: 12,
|
|
179
|
+
padding: viewportWidth < 640 ? 8 : 12,
|
|
179
180
|
}}
|
|
180
181
|
panelStyle={{
|
|
181
182
|
width: '100%',
|
|
@@ -605,7 +606,7 @@ export function TicketDetailDialog({
|
|
|
605
606
|
</View>
|
|
606
607
|
)}
|
|
607
608
|
{ticket.tokenUsage && (
|
|
608
|
-
<
|
|
609
|
+
<TicketTokenChart
|
|
609
610
|
title={m.tokens}
|
|
610
611
|
{...ticket.tokenUsage}
|
|
611
612
|
plotHeight={190}
|
|
@@ -9,6 +9,7 @@ import Animated, {
|
|
|
9
9
|
} from 'react-native-reanimated';
|
|
10
10
|
import { useDialogContext } from '../dialog/context';
|
|
11
11
|
import { StyledView } from '../styles/styled-primitives';
|
|
12
|
+
import { TicketGenieEnteredContext } from './context';
|
|
12
13
|
const AnimatedView = Animated.createAnimatedComponent(StyledView);
|
|
13
14
|
function phase(start: number, end: number, value: number) {
|
|
14
15
|
'worklet';
|
|
@@ -26,6 +27,7 @@ export function TicketGenieSurface({
|
|
|
26
27
|
const reduced = useReducedMotion();
|
|
27
28
|
const progress = useSharedValue(reduced ? 0 : 1);
|
|
28
29
|
const [height, setHeight] = useState(280);
|
|
30
|
+
const [entered, setEntered] = useState(reduced || !corner);
|
|
29
31
|
const { height: viewportHeight } = useWindowDimensions();
|
|
30
32
|
useEffect(() => {
|
|
31
33
|
progress.value = withTiming(isClosing ? 1 : 0, {
|
|
@@ -33,6 +35,11 @@ export function TicketGenieSurface({
|
|
|
33
35
|
easing: Easing.bezier(0.42, 0, 0.58, 1),
|
|
34
36
|
});
|
|
35
37
|
}, [isClosing, progress, reduced]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isClosing || !corner) return;
|
|
40
|
+
const timer = setTimeout(() => setEntered(true), reduced ? 0 : 480);
|
|
41
|
+
return () => clearTimeout(timer);
|
|
42
|
+
}, [isClosing, corner, reduced]);
|
|
36
43
|
const style = useAnimatedStyle(() => {
|
|
37
44
|
const p = reduced ? 0 : progress.value;
|
|
38
45
|
const extension = 64 * phase(0, 0.42, p);
|
|
@@ -56,12 +63,14 @@ export function TicketGenieSurface({
|
|
|
56
63
|
};
|
|
57
64
|
}, [progress, reduced, corner, height, viewportHeight]);
|
|
58
65
|
return (
|
|
66
|
+
<TicketGenieEnteredContext.Provider value={entered}>
|
|
59
67
|
<AnimatedView
|
|
60
68
|
onLayout={(event) => setHeight(event.nativeEvent.layout.height || 280)}
|
|
61
69
|
style={[corner ? { flex: 1, minHeight: 0 } : {}, style]}
|
|
62
70
|
>
|
|
63
71
|
{children}
|
|
64
72
|
</AnimatedView>
|
|
73
|
+
</TicketGenieEnteredContext.Provider>
|
|
65
74
|
);
|
|
66
75
|
}
|
|
67
76
|
export function TicketCornerGenieSurface({
|
|
@@ -11,7 +11,7 @@ const styles = {
|
|
|
11
11
|
surface: 'bloom-ticket-create-surface',
|
|
12
12
|
};
|
|
13
13
|
const CSS =
|
|
14
|
-
'.bloom-ticket-create-panel {\n transform-origin: center bottom;\n}\n\n.bloom-ticket-create-genie {\n position: relative;\n isolation: isolate;\n}\n\n.bloom-ticket-create-surface {\n position: relative;\n transform-origin: center bottom;\n}\n\n/* Paint once on a sibling layer, then animate only transform/opacity. The\n * broad shadows no longer sample and re-blur the changing dialog pixels. */\n.bloom-ticket-create-shadow {\n position: absolute;\n inset: 0;\n border-radius: 24px;\n pointer-events: none;\n transform-origin: center bottom;\n box-shadow:\n 0 1px 1px rgb(0 0 0 / 0.04),\n 0 4px 4px rgb(0 0 0 / 0.02),\n 0 0 120px rgb(0 0 0 / 0.1),\n 0 0 48px rgb(0 0 0 / 0.2);\n}\n\n
|
|
14
|
+
'.bloom-ticket-create-panel {\n transform-origin: center bottom;\n}\n\n.bloom-ticket-create-genie {\n position: relative;\n isolation: isolate;\n}\n\n.bloom-ticket-create-surface {\n position: relative;\n transform-origin: center bottom;\n}\n\n/* Paint once on a sibling layer, then animate only transform/opacity. The\n * broad shadows no longer sample and re-blur the changing dialog pixels. */\n.bloom-ticket-create-shadow {\n position: absolute;\n inset: 0;\n border-radius: 24px;\n pointer-events: none;\n transform-origin: center bottom;\n box-shadow:\n 0 1px 1px rgb(0 0 0 / 0.04),\n 0 4px 4px rgb(0 0 0 / 0.02),\n 0 0 120px rgb(0 0 0 / 0.1),\n 0 0 48px rgb(0 0 0 / 0.2);\n}\n\n.dark .bloom-ticket-create-shadow {\n box-shadow:\n 0 1px 1px rgb(0 0 0 / 0.14),\n 0 4px 4px rgb(0 0 0 / 0.1),\n 0 0 120px rgb(0 0 0 / 0.1),\n 0 0 48px rgb(0 0 0 / 0.2);\n}\n\n/* React Aria waits for this animation before unmounting. Geometry is driven\n * by one Motion timeline on the surface, so the panel itself never slides. */\n.bloom-ticket-create-panel[data-entering],\n.bloom-ticket-create-panel[data-exiting] {\n animation: bloom-ticket-create-ticket-presence 480ms linear both;\n}\n\n.bloom-ticket-create-panel[data-exiting] {\n pointer-events: none;\n}\n\n.bloom-ticket-create-panel[data-entering] .bloom-ticket-create-surface,\n.bloom-ticket-create-panel[data-exiting] .bloom-ticket-create-surface,\n.bloom-ticket-create-panel[data-entering] .bloom-ticket-create-shadow,\n.bloom-ticket-create-panel[data-exiting] .bloom-ticket-create-shadow {\n will-change: transform, opacity;\n}\n\n@keyframes bloom-ticket-create-ticket-presence {\n from { opacity: 0.9999; }\n to { opacity: 1; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .bloom-ticket-create-panel[data-entering],\n .bloom-ticket-create-panel[data-exiting] {\n animation: none;\n }\n\n .bloom-ticket-create-panel[data-entering] .bloom-ticket-create-surface,\n .bloom-ticket-create-panel[data-exiting] .bloom-ticket-create-surface,\n .bloom-ticket-create-panel[data-entering] .bloom-ticket-create-shadow,\n .bloom-ticket-create-panel[data-exiting] .bloom-ticket-create-shadow {\n will-change: auto;\n }\n}\n';
|
|
15
15
|
|
|
16
16
|
// A smooth, steep center gradient creates a narrow neck with a displacement
|
|
17
17
|
// no larger than the dialog width. Its cubic mask leaves the top broad while
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { useEffect, useRef, useState, type ReactNode } from 'react';
|
|
2
|
+
import { Platform, type ViewStyle } from 'react-native';
|
|
3
|
+
import Animated, {
|
|
4
|
+
cancelAnimation,
|
|
5
|
+
Easing,
|
|
6
|
+
LinearTransition,
|
|
7
|
+
useAnimatedStyle,
|
|
8
|
+
useReducedMotion,
|
|
9
|
+
useSharedValue,
|
|
10
|
+
withTiming,
|
|
11
|
+
type AnimatedStyle,
|
|
12
|
+
} from 'react-native-reanimated';
|
|
13
|
+
import { StyledView } from '../styles/styled-primitives';
|
|
14
|
+
import type { ProjectTicket } from './types';
|
|
15
|
+
|
|
16
|
+
const AnimatedView = Animated.createAnimatedComponent(StyledView);
|
|
17
|
+
const DURATION = 320;
|
|
18
|
+
const WEB = Platform.OS === 'web';
|
|
19
|
+
|
|
20
|
+
export interface PresentTicket {
|
|
21
|
+
ticket: ProjectTicket;
|
|
22
|
+
present: boolean;
|
|
23
|
+
initial: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Removed tickets retain only their pixels; interactive nodes leave immediately. */
|
|
27
|
+
export function reconcileTicketPresence(
|
|
28
|
+
previous: PresentTicket[],
|
|
29
|
+
tickets: ProjectTicket[],
|
|
30
|
+
): PresentTicket[] {
|
|
31
|
+
const ids = new Set(tickets.map((ticket) => ticket.id));
|
|
32
|
+
const next = tickets.map((ticket) => ({
|
|
33
|
+
ticket,
|
|
34
|
+
present: true,
|
|
35
|
+
initial: previous.find((entry) => entry.ticket.id === ticket.id)?.initial ?? false,
|
|
36
|
+
}));
|
|
37
|
+
previous.forEach((entry, index) => {
|
|
38
|
+
if (!ids.has(entry.ticket.id))
|
|
39
|
+
next.splice(Math.min(index, next.length), 0, { ...entry, present: false });
|
|
40
|
+
});
|
|
41
|
+
return next;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function TicketPresenceList({
|
|
45
|
+
tickets,
|
|
46
|
+
retainId,
|
|
47
|
+
children,
|
|
48
|
+
}: {
|
|
49
|
+
tickets: ProjectTicket[];
|
|
50
|
+
retainId?: string | null;
|
|
51
|
+
children: (entry: PresentTicket, paintStyle: AnimatedStyle<ViewStyle>, onHeight: (height: number) => void) => ReactNode;
|
|
52
|
+
}) {
|
|
53
|
+
const [state, setState] = useState(() => ({
|
|
54
|
+
tickets,
|
|
55
|
+
entries: tickets.map((ticket) => ({ ticket, present: true, initial: true })),
|
|
56
|
+
}));
|
|
57
|
+
if (state.tickets !== tickets) {
|
|
58
|
+
setState({ tickets, entries: reconcileTicketPresence(state.entries, tickets) });
|
|
59
|
+
}
|
|
60
|
+
return state.entries.map((entry) => (
|
|
61
|
+
<TicketPresence
|
|
62
|
+
key={entry.ticket.id}
|
|
63
|
+
present={entry.present}
|
|
64
|
+
initial={entry.initial}
|
|
65
|
+
retain={entry.ticket.id === retainId}
|
|
66
|
+
onExit={() => setState((current) => ({
|
|
67
|
+
...current,
|
|
68
|
+
entries: current.entries.filter((item) => item.present || item.ticket.id !== entry.ticket.id),
|
|
69
|
+
}))}
|
|
70
|
+
>
|
|
71
|
+
{(paintStyle, onHeight) => children(entry, paintStyle, onHeight)}
|
|
72
|
+
</TicketPresence>
|
|
73
|
+
));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** A shared-value timeline avoids web layout-animation clones and frozen positions. */
|
|
77
|
+
function TicketPresence({
|
|
78
|
+
present,
|
|
79
|
+
initial,
|
|
80
|
+
retain,
|
|
81
|
+
onExit,
|
|
82
|
+
children,
|
|
83
|
+
}: {
|
|
84
|
+
present: boolean;
|
|
85
|
+
initial: boolean;
|
|
86
|
+
retain: boolean;
|
|
87
|
+
onExit: () => void;
|
|
88
|
+
children: (paintStyle: AnimatedStyle<ViewStyle>, onHeight: (height: number) => void) => ReactNode;
|
|
89
|
+
}) {
|
|
90
|
+
const reduced = useReducedMotion();
|
|
91
|
+
const progress = useSharedValue(initial || reduced ? 1 : 0);
|
|
92
|
+
const height = useSharedValue(0);
|
|
93
|
+
const exit = useRef(onExit);
|
|
94
|
+
exit.current = onExit;
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
progress.value = reduced ? Number(present) : withTiming(Number(present), {
|
|
97
|
+
duration: DURATION,
|
|
98
|
+
easing: Easing.bezier(0.22, 1, 0.36, 1),
|
|
99
|
+
});
|
|
100
|
+
return () => cancelAnimation(progress);
|
|
101
|
+
}, [present, reduced, progress]);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (present || retain) return;
|
|
104
|
+
const timer = setTimeout(() => exit.current(), reduced ? 0 : DURATION);
|
|
105
|
+
return () => clearTimeout(timer);
|
|
106
|
+
}, [present, reduced, retain]);
|
|
107
|
+
const slotStyle = useAnimatedStyle(() => {
|
|
108
|
+
const p = Math.min(1, Math.max(0, progress.value));
|
|
109
|
+
return {
|
|
110
|
+
height: height.value > 0 ? (height.value + 6) * p : undefined,
|
|
111
|
+
paddingBottom: 6 * p,
|
|
112
|
+
};
|
|
113
|
+
}, [height, progress]);
|
|
114
|
+
const paintStyle = useAnimatedStyle<ViewStyle>(() => {
|
|
115
|
+
const p = Math.min(1, Math.max(0, progress.value));
|
|
116
|
+
const blur = 6 * (1 - p);
|
|
117
|
+
return {
|
|
118
|
+
opacity: p,
|
|
119
|
+
transform: [{ scale: 0.7 + 0.3 * p }],
|
|
120
|
+
filter: WEB ? `blur(${blur}px)` : [{ blur }],
|
|
121
|
+
} satisfies ViewStyle;
|
|
122
|
+
}, [progress]);
|
|
123
|
+
return (
|
|
124
|
+
<AnimatedView
|
|
125
|
+
className="relative shrink-0 pb-1.5"
|
|
126
|
+
layout={reduced ? undefined : LinearTransition.duration(260)}
|
|
127
|
+
style={slotStyle}
|
|
128
|
+
pointerEvents={present ? 'auto' : 'none'}
|
|
129
|
+
aria-hidden={!present}
|
|
130
|
+
accessibilityElementsHidden={!present}
|
|
131
|
+
importantForAccessibility={present ? 'auto' : 'no-hide-descendants'}
|
|
132
|
+
{...(WEB && !present ? { inert: true } : {})}
|
|
133
|
+
>
|
|
134
|
+
{children(paintStyle, (value) => { height.value = value; })}
|
|
135
|
+
</AnimatedView>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useContext, type ComponentProps } from 'react';
|
|
2
|
+
import { TokensChartCard } from '../chart-cards/TokensChartCard';
|
|
3
|
+
import { StyledView } from '../styles/styled-primitives';
|
|
4
|
+
import { TicketGenieEnteredContext } from './context';
|
|
5
|
+
|
|
6
|
+
/** Keep the card's geometry in the entrance copy, then restart its live plot clock. */
|
|
7
|
+
export function TicketTokenChart(props: ComponentProps<typeof TokensChartCard>) {
|
|
8
|
+
const entered = useContext(TicketGenieEnteredContext);
|
|
9
|
+
return (
|
|
10
|
+
<StyledView className="bloom-ticket-detail-chart">
|
|
11
|
+
<TokensChartCard {...props} animate={entered} />
|
|
12
|
+
</StyledView>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -36,6 +36,8 @@ export interface ProjectBoardPlatform {
|
|
|
36
36
|
}
|
|
37
37
|
export const ProjectBoardPlatformContext =
|
|
38
38
|
createContext<ProjectBoardPlatform | null>(null);
|
|
39
|
+
/** The plot starts its own reveal after the panel has reached its live pixels. */
|
|
40
|
+
export const TicketGenieEnteredContext = createContext(true);
|
|
39
41
|
export function useProjectBoardPlatform() {
|
|
40
42
|
const platform = useContext(ProjectBoardPlatformContext);
|
|
41
43
|
if (!platform)
|
package/src/search/Search.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { forwardRef, useCallback, useMemo, useRef } from 'react';
|
|
|
2
2
|
import { Platform, type TextInput, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { mergeRefs } from '../hooks/merge-refs';
|
|
5
|
+
import { useDirectionProps, useIsRtl } from '../hooks/use-is-rtl';
|
|
5
6
|
import { useCommonMessages } from '../locale/common-messages';
|
|
6
7
|
import { useMessages } from '../locale/messages';
|
|
7
8
|
import { SEARCH_MESSAGES } from './messages';
|
|
@@ -25,6 +26,8 @@ type SearchProps = Omit<TextFieldInputProps, 'label'> & {
|
|
|
25
26
|
export const Search = forwardRef<TextInput, SearchProps>(
|
|
26
27
|
function Search({ value, label: labelProp, onClearText, onFocus, onPressIn, ...rest }, ref) {
|
|
27
28
|
const theme = useTheme();
|
|
29
|
+
const direction = useDirectionProps();
|
|
30
|
+
const rtl = useIsRtl();
|
|
28
31
|
const common = useCommonMessages();
|
|
29
32
|
const { messages } = useMessages(SEARCH_MESSAGES);
|
|
30
33
|
const label = labelProp ?? common.search;
|
|
@@ -66,7 +69,7 @@ export const Search = forwardRef<TextInput, SearchProps>(
|
|
|
66
69
|
);
|
|
67
70
|
|
|
68
71
|
return (
|
|
69
|
-
<View style={[a.w_full, a.relative]}>
|
|
72
|
+
<View {...direction} style={[a.w_full, a.relative]}>
|
|
70
73
|
<TextField radius={borderRadius.full}>
|
|
71
74
|
<TextFieldIcon icon={MagnifyingGlassIcon} />
|
|
72
75
|
<TextFieldInput
|
|
@@ -81,7 +84,7 @@ export const Search = forwardRef<TextInput, SearchProps>(
|
|
|
81
84
|
autoCorrect={false}
|
|
82
85
|
autoComplete="off"
|
|
83
86
|
autoCapitalize="none"
|
|
84
|
-
style={showClear ? { paddingRight: 24 } : undefined}
|
|
87
|
+
style={showClear ? (rtl ? { paddingLeft: 24 } : { paddingRight: 24 }) : undefined}
|
|
85
88
|
{...rest}
|
|
86
89
|
onPressIn={handlePressIn}
|
|
87
90
|
onFocus={handleFocus}
|
|
@@ -94,10 +97,8 @@ export const Search = forwardRef<TextInput, SearchProps>(
|
|
|
94
97
|
a.absolute,
|
|
95
98
|
a.z_20,
|
|
96
99
|
a.my_auto,
|
|
97
|
-
a.inset_0,
|
|
98
100
|
a.justify_center,
|
|
99
|
-
|
|
100
|
-
{ left: 'auto' },
|
|
101
|
+
{ top: 0, bottom: 0, insetInlineEnd: 0, paddingInlineEnd: 8 },
|
|
101
102
|
]}>
|
|
102
103
|
{/* Neutral and transparent. `variant="ghost"` painted an accent
|
|
103
104
|
wash inside the field, which read as a state the field was not
|