UX: style & position AI helper in composer (#758)

Co-authored-by: Keegan George <kgeorge13@gmail.com>
This commit is contained in:
chapoi 2024-08-21 20:01:03 +02:00 committed by GitHub
parent 64641b6175
commit 10dae65740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 105 additions and 1 deletions

View File

@ -162,6 +162,14 @@ export default class AiComposerHelperMenu extends Component {
return true; return true;
} }
get isExpanded() {
if (this.aiComposerHelper.menuState === this.MENU_STATES.triggers) {
return "";
}
return "is-expanded";
}
@bind @bind
onKeyDown(event) { onKeyDown(event) {
if (event.key === "Escape") { if (event.key === "Escape") {
@ -306,7 +314,10 @@ export default class AiComposerHelperMenu extends Component {
} }
<template> <template>
<div class="ai-composer-helper-menu" {{this.documentListeners}}> <div
class="ai-composer-helper-menu {{this.isExpanded}}"
{{this.documentListeners}}
>
{{#if (eq this.aiComposerHelper.menuState this.MENU_STATES.triggers)}} {{#if (eq this.aiComposerHelper.menuState this.MENU_STATES.triggers)}}
<ul class="ai-composer-helper-menu__triggers"> <ul class="ai-composer-helper-menu__triggers">
<li> <li>

View File

@ -14,6 +14,7 @@ export default class AiComposerHelper extends Component {
return showComposerAIHelper(outletArgs, helper, "context_menu"); return showComposerAIHelper(outletArgs, helper, "context_menu");
} }
@service site;
@service menu; @service menu;
@service aiComposerHelper; @service aiComposerHelper;
@tracked caretCoords; @tracked caretCoords;
@ -31,6 +32,9 @@ export default class AiComposerHelper extends Component {
document.addEventListener("mousedown", this.onMouseDown, { passive: true }); document.addEventListener("mousedown", this.onMouseDown, { passive: true });
document.addEventListener("mouseup", this.onMouseUp, { passive: true }); document.addEventListener("mouseup", this.onMouseUp, { passive: true });
document.addEventListener("selectionchange", this.onSelectionChanged); document.addEventListener("selectionchange", this.onSelectionChanged);
window.visualViewport.addEventListener("resize", this.onResize, {
passive: true,
});
this.dEditorInput = document.querySelector(".d-editor-input"); this.dEditorInput = document.querySelector(".d-editor-input");
@ -42,6 +46,7 @@ export default class AiComposerHelper extends Component {
document.removeEventListener("mousedown", this.onMouseDown); document.removeEventListener("mousedown", this.onMouseDown);
document.removeEventListener("mouseup", this.onMouseUp); document.removeEventListener("mouseup", this.onMouseUp);
document.removeEventListener("selectionchange", this.onSelectionChanged); document.removeEventListener("selectionchange", this.onSelectionChanged);
window.visualViewport.removeEventListener("resize", this.onResize);
if (this.dEditorInput) { if (this.dEditorInput) {
this.dEditorInput.removeEventListener("scroll", this.updatePosition); this.dEditorInput.removeEventListener("scroll", this.updatePosition);
@ -54,6 +59,18 @@ export default class AiComposerHelper extends Component {
this.menuInstance?.close(); this.menuInstance?.close();
} }
@bind
onResize() {
if (!this.site.mobileView) {
return;
}
document.documentElement.style.setProperty(
"--mobile-virtual-screen-height",
`${window.visualViewport.height}px`
);
}
@bind @bind
onSelectionChanged() { onSelectionChanged() {
if ( if (

View File

@ -0,0 +1,75 @@
:root {
// Overridden in ai-composer-helper.gjs to adjust for virtual keyboard
--mobile-virtual-screen-height: 100svh;
}
.ai-composer-helper-menu:not(.is-expanded) {
--composer-helper-menu-padding: 1rem;
--composer-helper-menu-trigger-size: 3em;
--composer-helper-menu-height: calc(1rem + 3em);
position: fixed;
list-style: none;
inset: auto;
transform: none;
max-width: unset;
z-index: z("fullscreen");
top: calc(
var(--mobile-virtual-screen-height) - var(--composer-helper-menu-height)
);
right: 0;
padding-right: 1rem;
padding-bottom: var(--composer-helper-menu-padding);
margin: 0px;
width: 100vw;
text-align: right;
border: none;
background: linear-gradient(
to bottom,
transparent 0,
rgba(0, 0, 0, 0.3) 100%
);
box-shadow: none;
&.out-of-bounds {
visibility: visible;
pointer-events: initial;
}
button {
background: var(--secondary);
border: 1px solid var(--primary-low);
border-radius: 100%;
box-shadow: var(--shadow-card);
width: var(--composer-helper-menu-trigger-size);
height: var(--composer-helper-menu-trigger-size);
animation-duration: 0.15s;
animation-timing-function: cubic-bezier(0, 0.7, 0.9, 1.2);
animation-fill-mode: backwards;
animation-name: slide-in;
&:hover {
.discourse-no-touch & {
background: var(--secondary);
}
}
.d-button-label {
display: none;
}
.d-icon {
margin: 0;
}
}
}
@keyframes slide-in {
0% {
opacity: 0;
transform: translateY(calc(100% + 1rem));
}
100% {
opacity: 1;
transform: translateY(0);
}
}

View File

@ -14,6 +14,7 @@ gem "tiktoken_ruby", "0.0.9"
enabled_site_setting :discourse_ai_enabled enabled_site_setting :discourse_ai_enabled
register_asset "stylesheets/modules/ai-helper/common/ai-helper.scss" register_asset "stylesheets/modules/ai-helper/common/ai-helper.scss"
register_asset "stylesheets/modules/ai-helper/mobile/ai-helper.scss", :mobile
register_asset "stylesheets/modules/summarization/common/ai-summary.scss" register_asset "stylesheets/modules/summarization/common/ai-summary.scss"
register_asset "stylesheets/modules/summarization/desktop/ai-summary.scss", :desktop register_asset "stylesheets/modules/summarization/desktop/ai-summary.scss", :desktop