Skip to content

Commit 10dae65

Browse files
chapoikeegangeorge
andauthored
UX: style & position AI helper in composer (#758)
Co-authored-by: Keegan George <kgeorge13@gmail.com>
1 parent 64641b6 commit 10dae65

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

assets/javascripts/discourse/components/ai-composer-helper-menu.gjs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ export default class AiComposerHelperMenu extends Component {
162162
return true;
163163
}
164164

165+
get isExpanded() {
166+
if (this.aiComposerHelper.menuState === this.MENU_STATES.triggers) {
167+
return "";
168+
}
169+
170+
return "is-expanded";
171+
}
172+
165173
@bind
166174
onKeyDown(event) {
167175
if (event.key === "Escape") {
@@ -306,7 +314,10 @@ export default class AiComposerHelperMenu extends Component {
306314
}
307315

308316
<template>
309-
<div class="ai-composer-helper-menu" {{this.documentListeners}}>
317+
<div
318+
class="ai-composer-helper-menu {{this.isExpanded}}"
319+
{{this.documentListeners}}
320+
>
310321
{{#if (eq this.aiComposerHelper.menuState this.MENU_STATES.triggers)}}
311322
<ul class="ai-composer-helper-menu__triggers">
312323
<li>

assets/javascripts/discourse/connectors/after-d-editor/ai-composer-helper.gjs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default class AiComposerHelper extends Component {
1414
return showComposerAIHelper(outletArgs, helper, "context_menu");
1515
}
1616

17+
@service site;
1718
@service menu;
1819
@service aiComposerHelper;
1920
@tracked caretCoords;
@@ -31,6 +32,9 @@ export default class AiComposerHelper extends Component {
3132
document.addEventListener("mousedown", this.onMouseDown, { passive: true });
3233
document.addEventListener("mouseup", this.onMouseUp, { passive: true });
3334
document.addEventListener("selectionchange", this.onSelectionChanged);
35+
window.visualViewport.addEventListener("resize", this.onResize, {
36+
passive: true,
37+
});
3438

3539
this.dEditorInput = document.querySelector(".d-editor-input");
3640

@@ -42,6 +46,7 @@ export default class AiComposerHelper extends Component {
4246
document.removeEventListener("mousedown", this.onMouseDown);
4347
document.removeEventListener("mouseup", this.onMouseUp);
4448
document.removeEventListener("selectionchange", this.onSelectionChanged);
49+
window.visualViewport.removeEventListener("resize", this.onResize);
4550

4651
if (this.dEditorInput) {
4752
this.dEditorInput.removeEventListener("scroll", this.updatePosition);
@@ -54,6 +59,18 @@ export default class AiComposerHelper extends Component {
5459
this.menuInstance?.close();
5560
}
5661

62+
@bind
63+
onResize() {
64+
if (!this.site.mobileView) {
65+
return;
66+
}
67+
68+
document.documentElement.style.setProperty(
69+
"--mobile-virtual-screen-height",
70+
`${window.visualViewport.height}px`
71+
);
72+
}
73+
5774
@bind
5875
onSelectionChanged() {
5976
if (
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
:root {
2+
// Overridden in ai-composer-helper.gjs to adjust for virtual keyboard
3+
--mobile-virtual-screen-height: 100svh;
4+
}
5+
6+
.ai-composer-helper-menu:not(.is-expanded) {
7+
--composer-helper-menu-padding: 1rem;
8+
--composer-helper-menu-trigger-size: 3em;
9+
--composer-helper-menu-height: calc(1rem + 3em);
10+
11+
position: fixed;
12+
list-style: none;
13+
inset: auto;
14+
transform: none;
15+
max-width: unset;
16+
z-index: z("fullscreen");
17+
top: calc(
18+
var(--mobile-virtual-screen-height) - var(--composer-helper-menu-height)
19+
);
20+
right: 0;
21+
padding-right: 1rem;
22+
padding-bottom: var(--composer-helper-menu-padding);
23+
margin: 0px;
24+
width: 100vw;
25+
text-align: right;
26+
border: none;
27+
background: linear-gradient(
28+
to bottom,
29+
transparent 0,
30+
rgba(0, 0, 0, 0.3) 100%
31+
);
32+
box-shadow: none;
33+
34+
&.out-of-bounds {
35+
visibility: visible;
36+
pointer-events: initial;
37+
}
38+
39+
button {
40+
background: var(--secondary);
41+
border: 1px solid var(--primary-low);
42+
border-radius: 100%;
43+
box-shadow: var(--shadow-card);
44+
width: var(--composer-helper-menu-trigger-size);
45+
height: var(--composer-helper-menu-trigger-size);
46+
animation-duration: 0.15s;
47+
animation-timing-function: cubic-bezier(0, 0.7, 0.9, 1.2);
48+
animation-fill-mode: backwards;
49+
animation-name: slide-in;
50+
51+
&:hover {
52+
.discourse-no-touch & {
53+
background: var(--secondary);
54+
}
55+
}
56+
57+
.d-button-label {
58+
display: none;
59+
}
60+
.d-icon {
61+
margin: 0;
62+
}
63+
}
64+
}
65+
66+
@keyframes slide-in {
67+
0% {
68+
opacity: 0;
69+
transform: translateY(calc(100% + 1rem));
70+
}
71+
100% {
72+
opacity: 1;
73+
transform: translateY(0);
74+
}
75+
}

plugin.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
enabled_site_setting :discourse_ai_enabled
1515

1616
register_asset "stylesheets/modules/ai-helper/common/ai-helper.scss"
17+
register_asset "stylesheets/modules/ai-helper/mobile/ai-helper.scss", :mobile
1718

1819
register_asset "stylesheets/modules/summarization/common/ai-summary.scss"
1920
register_asset "stylesheets/modules/summarization/desktop/ai-summary.scss", :desktop

0 commit comments

Comments
 (0)