-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ enabled ? 'Microphone enabled' : 'Microphone disabled' }}
-
-
-
-
-
-
-
-
-
-
+
+
-
+
+
+
+
+
-
+
+
+
diff --git a/apps/stage-web/src/components/Widgets/ChatActionButtons.vue b/apps/stage-web/src/components/Widgets/ChatActionButtons.vue
new file mode 100644
index 000000000..74ff275ab
--- /dev/null
+++ b/apps/stage-web/src/components/Widgets/ChatActionButtons.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/apps/stage-web/src/components/Widgets/ChatArea.vue b/apps/stage-web/src/components/Widgets/ChatArea.vue
new file mode 100644
index 000000000..40efd3157
--- /dev/null
+++ b/apps/stage-web/src/components/Widgets/ChatArea.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ enabled ? 'Microphone enabled' : 'Microphone disabled' }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/stage-web/src/components/Widgets/ChatContainer.vue b/apps/stage-web/src/components/Widgets/ChatContainer.vue
new file mode 100644
index 000000000..a89207d67
--- /dev/null
+++ b/apps/stage-web/src/components/Widgets/ChatContainer.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/apps/stage-web/src/components/Widgets/ChatHistory.vue b/apps/stage-web/src/components/Widgets/ChatHistory.vue
index 8c6218fe2..2b626cfc0 100644
--- a/apps/stage-web/src/components/Widgets/ChatHistory.vue
+++ b/apps/stage-web/src/components/Widgets/ChatHistory.vue
@@ -39,7 +39,7 @@ watch(sending, () => {
-
+
diff --git a/packages/ui/src/composables/use-deferred-mount.ts b/packages/ui/src/composables/use-deferred-mount.ts
new file mode 100644
index 000000000..883f046a7
--- /dev/null
+++ b/packages/ui/src/composables/use-deferred-mount.ts
@@ -0,0 +1,20 @@
+import { onMounted, ref } from 'vue'
+
+export function useDeferredMount() {
+ const isReady = ref(false)
+
+ onMounted(() => {
+ // NOTICE: yield the main thread to the browser to paint.
+ // Other approaches work too, e.g. double RAF like here, or a setTimeout 0, or Suspense with async component, etc.
+ // Virtualization somewhat helps, however, virtual list may break Ctrl-F and Ctrl-A.
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ isReady.value = true
+ })
+ })
+ })
+
+ return {
+ isReady,
+ }
+}
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index c17592d69..67e64d3ea 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -2,4 +2,5 @@ import './fallback.css'
export * from './components/Animations'
export * from './components/Form'
+export * from './composables/use-deferred-mount'
export * from './composables/use-theme'