Remove Fizzy Ask

Since we are not going to ship it
This commit is contained in:
Jorge Manrubia
2025-10-27 13:29:25 +01:00
parent 0617303388
commit 9317a82570
70 changed files with 1284 additions and 4693 deletions
+1 -21
View File
@@ -2,11 +2,10 @@ import { Controller } from "@hotwired/stimulus"
import { post } from "@rails/request.js"
export default class extends Controller {
static targets = [ "turboFrame", "searchInput", "askInput", "buttonsContainer" ]
static targets = [ "turboFrame", "searchInput", "buttonsContainer" ]
static outlets = [ "dialog" ]
static values = {
searchUrl: String,
askUrl: String,
}
dialogOutletConnected(outlet, element) {
@@ -21,9 +20,6 @@ export default class extends Controller {
this.searchInputTarget.querySelector("input").value = ""
this.#showItem(this.buttonsContainerTarget)
this.#hideItem(this.searchInputTarget)
if (this.hasAskInputTarget) {
this.#hideItem(this.askInputTarget)
}
}
showModalAndSubmit(event) {
@@ -44,18 +40,6 @@ export default class extends Controller {
this.#showItem(this.searchInputTarget)
this.#hideItem(this.buttonsContainerTarget)
if (this.hasAskInputTarget) {
this.#hideItem(this.askInputTarget)
}
}
ask(event) {
this.#initializeConversation()
this.#openInTurboFrame(this.askUrlValue)
this.#showItem(this.askInputTarget)
this.#hideItem(this.searchInputTarget)
this.#hideItem(this.buttonsContainerTarget)
}
#clearTurboFrame() {
@@ -67,10 +51,6 @@ export default class extends Controller {
this.turboFrameTarget.src = url
}
#initializeConversation() {
post(this.askUrlValue)
}
#showItem(element) {
element.removeAttribute("hidden")
@@ -1,80 +0,0 @@
import { Controller } from "@hotwired/stimulus"
import { onNextEventLoopTick, nextFrame } from "helpers/timing_helpers"
export default class extends Controller {
static targets = [ "textInput", "submitButton", "clientMessageIdInput" ]
static outlets = [ "conversation--messages" ]
#submittingMessage
connect() {
this.#submittingMessage = false
onNextEventLoopTick(() => this.textInputTarget.focus())
}
submit(event) {
event.preventDefault()
if (!this.#submittingMessage) {
this.#submittingMessage = true
this.#submitMessage()
}
}
submitEnd(event) {
this.#submittingMessage = false
if (event.detail.success) {
this.#reset()
} else {
this.#failPendingMessage(
this.clientMessageIdInputTarget.value,
event.detail.fetchResponse
)
}
}
async #submitMessage() {
if (this.#validInput()) {
const messageId = this.#generateMessageId()
await this.conversationMessagesOutlet.insertPendingMessage(messageId, this.#messageText)
await nextFrame()
this.conversationMessagesOutlet.scrollToBottom()
this.clientMessageIdInputTarget.value = messageId
this.element.requestSubmit()
}
}
get #messageText() {
return this.textInputTarget.value
}
#validInput() {
return this.#messageText.trim().length > 0
}
#generateMessageId() {
return Math.random().toString(36).slice(2)
}
#reset() {
this.textInputTarget.value = ""
this.clientMessageIdInputTarget.value = ""
}
async #failPendingMessage(clientMessageId, response) {
let errorMessage = null
if (response?.contentType?.includes('application/json')) {
const error = JSON.parse(await response.responseText)
errorMessage = error.error
}
this.conversationMessagesOutlet.failPendingMessage(
this.clientMessageIdInputTarget.value,
errorMessage
)
}
}
@@ -1,112 +0,0 @@
import { Controller } from "@hotwired/stimulus"
import { nextFrame } from "helpers/timing_helpers"
export default class extends Controller {
static SCROLL_TRESHOLD = 100
static EMOJI_MATCHER = /^(\p{Emoji_Presentation}|\p{Extended_Pictographic}|\uFE0F)+$/gu
static targets = [ "messages", "messageTemplate" ]
static classes = [ "failedMessage", "emojiMessage" ]
connect() {
this.scrollToBottom()
}
failPendingMessage(clientMessageId, errorMessage) {
const message = this.element.querySelector(`#message_${clientMessageId}`)
if (message) {
message.classList.add(this.failedMessageClass)
if (errorMessage) {
message.dataset.error = errorMessage
}
}
}
async insertPendingMessage(clientMessageId, content) {
const html = this.#pendingMessageHtml({
clientMessageId: clientMessageId,
content: content,
extraClasses: this.#allEmoji(content) ? this.emojiMessageClass : ""
})
this.messagesTarget.insertAdjacentHTML("beforeend", html)
await nextFrame()
this.scrollToBottom()
}
scrollToBottom() {
this.element.scrollTop = this.element.scrollHeight
}
beforeStreamRender(event) {
const target = event.detail.newStream.getAttribute("target")
if (target === this.messagesTarget.id) {
this.#handleScrollPositionOnTurboStreamRender(event)
}
}
#pendingMessageHtml(data) {
let html = this.messageTemplateTarget.innerHTML
for (const key in data) {
html = html.replaceAll(`$${key}$`, data[key])
}
return html
}
#allEmoji(content) {
return content.match(this.constructor.EMOJI_MATCHER)
}
#handleScrollPositionOnTurboStreamRender(event) {
if (event.detail.newStream.action === "append") {
this.#scrollToBottomOnTurboStreamRender(event)
} else {
this.#preserveScrollPositionOnTurboStreamRender(event)
}
}
#scrollToBottomOnTurboStreamRender(event) {
const render = event.detail.render
event.detail.render = async (streamElement) => {
await render(streamElement)
await nextFrame()
this.scrollToBottom()
}
}
#preserveScrollPositionOnTurboStreamRender(event) {
const render = event.detail.render
event.detail.render = async (streamElement) => {
const previousScrollHeight = this.element.scrollHeight
const previousScrollTop = this.element.scrollTop
const previouslyWasAtBottom = this.#scrolledToBottom
await render(streamElement)
if (previouslyWasAtBottom) {
this.messagesTarget.scrollTop = this.messagesTarget.scrollHeight
} else {
const newScrollHeight = this.element.scrollHeight
const scrollDelta = newScrollHeight - previousScrollHeight
this.element.scrollTop = previousScrollTop + scrollDelta
}
await nextFrame()
}
}
get #scrolledToBottom() {
const scrollBottom = this.element.scrollTop + this.element.clientHeight
const contentBottom = this.element.scrollHeight - this.constructor.SCROLL_THRESHOLD
return scrollBottom >= contentBottom
}
}