UX: minor adjustments for image caption size, behavior (#484)
This commit is contained in:
parent
cbb3807237
commit
0f761234f9
|
@ -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);
|
||||||
|
|
||||||
|
if (matchingPlaceholder) {
|
||||||
const match = matchingPlaceholder[index];
|
const match = matchingPlaceholder[index];
|
||||||
const replacement = match.replace(
|
const replacement = match.replace(
|
||||||
IMAGE_MARKDOWN_REGEX,
|
IMAGE_MARKDOWN_REGEX,
|
||||||
``
|
``
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
this.appEvents.trigger("composer:replace-text", match, replacement);
|
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">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue