UX: minor adjustments for image caption size, behavior (#484)

This commit is contained in:
Kris 2024-02-22 12:31:25 -05:00 committed by GitHub
parent cbb3807237
commit 0f761234f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 18 deletions

View File

@ -1,7 +1,9 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { fn } from "@ember/helper";
import { on } from "@ember/modifier"; import { on } from "@ember/modifier";
import { action } from "@ember/object"; import { action } from "@ember/object";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import didUpdate from "@ember/render-modifiers/modifiers/did-update";
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner"; import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
import DButton from "discourse/components/d-button"; import DButton from "discourse/components/d-button";
@ -27,22 +29,54 @@ export default class AiImageCaptionContainer extends Component {
const index = this.imageCaptionPopup.imageIndex; const index = this.imageCaptionPopup.imageIndex;
const matchingPlaceholder = const matchingPlaceholder =
this.composer.model.reply.match(IMAGE_MARKDOWN_REGEX); this.composer.model.reply.match(IMAGE_MARKDOWN_REGEX);
const match = matchingPlaceholder[index];
const replacement = match.replace( if (matchingPlaceholder) {
IMAGE_MARKDOWN_REGEX, const match = matchingPlaceholder[index];
`![${this.imageCaptionPopup.newCaption}|$2$3$4]($5)` const replacement = match.replace(
); IMAGE_MARKDOWN_REGEX,
this.appEvents.trigger("composer:replace-text", match, replacement); `![${this.imageCaptionPopup.newCaption}|$2$3$4]($5)`
);
if (match) {
this.appEvents.trigger("composer:replace-text", match, replacement);
}
}
this.hidePopup();
}
@action
resizeTextarea(target) {
const style = window.getComputedStyle(target);
// scrollbars will show based on scrollHeight alone
// so we need to consider borders too
const borderTopWidth = parseInt(style.borderTopWidth, 10);
const borderBottomWidth = parseInt(style.borderBottomWidth, 10);
target.scrollTop = 0;
target.style.height = `${
target.scrollHeight + borderTopWidth + borderBottomWidth
}px`;
}
@action
hidePopup() {
this.imageCaptionPopup.showPopup = false; this.imageCaptionPopup.showPopup = false;
} }
<template> <template>
{{#if this.imageCaptionPopup.showPopup}} {{#if this.imageCaptionPopup.showPopup}}
<div class="composer-popup education-message ai-caption-popup"> <div
class="composer-popup education-message ai-caption-popup"
{{willDestroy this.hidePopup}}
>
<ConditionalLoadingSpinner <ConditionalLoadingSpinner
@condition={{this.imageCaptionPopup.loading}} @condition={{this.imageCaptionPopup.loading}}
> >
<DTextarea <DTextarea
{{didInsert this.resizeTextarea}}
{{didUpdate this.resizeTextarea this.imageCaptionPopup.newCaption}}
@value={{this.imageCaptionPopup.newCaption}} @value={{this.imageCaptionPopup.newCaption}}
{{on "change" this.updateCaption}} {{on "change" this.updateCaption}}
{{autoFocus}} {{autoFocus}}
@ -59,7 +93,7 @@ export default class AiImageCaptionContainer extends Component {
<DButton <DButton
class="btn-flat" class="btn-flat"
@label="cancel" @label="cancel"
@action={{fn (mut this.imageCaptionPopup.showPopup) false}} @action={{this.hidePopup}}
/> />
<span class="credits"> <span class="credits">

View File

@ -34,6 +34,8 @@ export default apiInitializer("1.25.0", (api) => {
imageCaptionPopup.loading = true; imageCaptionPopup.loading = true;
imageCaptionPopup.showPopup = !imageCaptionPopup.showPopup; imageCaptionPopup.showPopup = !imageCaptionPopup.showPopup;
event.target.classList.add("disabled");
ajax(`/discourse-ai/ai-helper/caption_image`, { ajax(`/discourse-ai/ai-helper/caption_image`, {
method: "POST", method: "POST",
data: { data: {
@ -41,7 +43,6 @@ export default apiInitializer("1.25.0", (api) => {
}, },
}) })
.then(({ caption }) => { .then(({ caption }) => {
event.target.classList.add("disabled");
imageCaptionPopup.imageSrc = imageSrc; imageCaptionPopup.imageSrc = imageSrc;
imageCaptionPopup.imageIndex = imageIndex; imageCaptionPopup.imageIndex = imageIndex;
imageCaptionPopup.newCaption = caption; imageCaptionPopup.newCaption = caption;

View File

@ -465,6 +465,7 @@
color: var(--tertiary); color: var(--tertiary);
box-shadow: var(--shadow-dropdown); box-shadow: var(--shadow-dropdown);
position: absolute; position: absolute;
white-space: nowrap;
top: -3.15rem; top: -3.15rem;
left: 0.75rem; left: 0.75rem;
padding: 0.5em 0.75em; padding: 0.5em 0.75em;
@ -488,29 +489,31 @@
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
cursor: not-allowed; cursor: not-allowed;
opacity: 0.8; opacity: 0.7;
&:hover,
&:focus {
background: var(--primary-low);
color: var(--primary-high);
}
} }
} }
} }
.ai-caption-popup { .ai-caption-popup {
--ai-caption-popup-min-width: 20rem;
width: auto; width: auto;
right: unset; right: unset;
padding: 1em; padding: 1em;
top: unset; top: unset;
bottom: 0; bottom: 0;
.loading-container {
min-width: var(--ai-caption-popup-min-width);
}
textarea { textarea {
box-sizing: border-box;
width: 100%; width: 100%;
max-width: 40vw; max-width: 40dvw;
max-height: calc(100dvh - var(--header-offset) - 10em);
min-height: 3em; min-height: 3em;
height: 7em; height: 7em;
min-width: 20em; min-width: var(--ai-caption-popup-min-width);
@include breakpoint(tablet) { @include breakpoint(tablet) {
width: 100%; width: 100%;
max-width: unset; max-width: unset;