| |
|
|
| import { StateManager } from '../services/state-manager.js'; |
| import { ApiService } from '../services/api-service.js'; |
| import { TranslationService } from '../services/translation-service.js'; |
| import { Utils } from '../utils.js'; |
|
|
| export const FeedbackComponent = { |
| elements: { |
| feedbackOverlay: null, |
| closeFeedbackBtn: null, |
| cancelFeedbackBtn: null, |
| submitFeedbackBtn: null, |
| feedbackInput: null, |
| feedbackRatingDisplay: null, |
| feedbackMessagePreview: null |
| }, |
|
|
| currentFeedback: { |
| messageIndex: null, |
| modelType: null, |
| rating: null, |
| messageContent: null, |
| replyId: null |
| }, |
|
|
| |
| |
| |
| init() { |
| |
| this.elements.feedbackOverlay = document.getElementById('feedback-overlay'); |
| this.elements.closeFeedbackBtn = document.getElementById('closeFeedbackBtn'); |
| this.elements.cancelFeedbackBtn = document.getElementById('cancelFeedbackBtn'); |
| this.elements.submitFeedbackBtn = document.getElementById('submitFeedbackBtn'); |
| this.elements.feedbackInput = document.getElementById('feedbackInput'); |
| this.elements.feedbackRatingDisplay = document.getElementById('feedbackRatingDisplay'); |
| this.elements.feedbackMessagePreview = document.getElementById('feedbackMessagePreview'); |
|
|
| this.attachOutsideClickListener(); |
| this.attachEventListeners(); |
| }, |
|
|
| attachOutsideClickListener() { |
| this.elements.feedbackOverlay.addEventListener('click', (e) => { |
| |
| if (e.target === this.elements.feedbackOverlay) { |
| this.closeModal(); |
| } |
| }); |
| }, |
| |
| |
| |
| |
| attachEventListeners() { |
| this.elements.closeFeedbackBtn.addEventListener('click', () => this.closeModal()); |
| this.elements.cancelFeedbackBtn.addEventListener('click', () => this.closeModal()); |
| this.elements.submitFeedbackBtn.addEventListener('click', () => this.submitFeedback()); |
|
|
| |
| this.elements.feedbackInput.addEventListener('keydown', (e) => { |
| if (e.key === 'Enter' && !e.shiftKey) { |
| e.preventDefault(); |
| this.submitFeedback(); |
| } |
| }); |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| openModal(messageIndex, modelType, rating, messageContent, replyId) { |
| this.currentFeedback = { |
| messageIndex, |
| modelType, |
| rating, |
| messageContent, |
| replyId |
| }; |
|
|
| |
| this.updateModalContent(rating, messageContent); |
|
|
| |
| this.elements.feedbackOverlay.style.display = ''; |
| |
| |
| setTimeout(() => this.elements.feedbackInput.focus(), 100); |
| }, |
|
|
| |
| |
| |
| |
| |
| updateModalContent(rating, messageContent) { |
| |
| const ratingEmoji = { |
| 'like': '👍', |
| 'dislike': '👎', |
| 'mixed': '~' |
| }; |
| |
| const ratingText = { |
| 'like': 'feedback_like_title', |
| 'dislike': 'feedback_dislike_title', |
| 'mixed': 'feedback_neutral_title' |
| }; |
|
|
| this.elements.feedbackRatingDisplay.textContent = ratingEmoji[rating] + ' '; |
| this.elements.feedbackRatingDisplay.dataset.i18n = ratingText[rating]; |
|
|
| |
| const preview = messageContent.length > 150 |
| ? messageContent.substring(0, 150) + '...' |
| : messageContent; |
| this.elements.feedbackMessagePreview.textContent = preview; |
|
|
| |
| this.elements.feedbackInput.value = ''; |
|
|
| |
| TranslationService.applyTranslation(); |
| }, |
|
|
| |
| |
| |
| closeModal() { |
| this.elements.feedbackOverlay.style.display = 'none'; |
| this.currentFeedback = { |
| messageIndex: null, |
| modelType: null, |
| rating: null, |
| messageContent: null, |
| replyId: null |
| }; |
| }, |
|
|
| |
| |
| |
| async submitFeedback() { |
| const comment = this.elements.feedbackInput.value.trim(); |
| |
| const feedbackData = { |
| message_index: this.currentFeedback.messageIndex, |
| model_type: this.currentFeedback.modelType, |
| rating: this.currentFeedback.rating, |
| comment: comment || "", |
| reply_content: this.currentFeedback.messageContent, |
| reply_id: this.currentFeedback.replyId, |
| user_id: Utils.getMachineId(), |
| session_id: StateManager.sessionId, |
| conversation_id: StateManager.getConversationId(this.currentFeedback.modelType) |
| }; |
|
|
| try { |
| const result = await ApiService.submitFeedback(feedbackData); |
| |
| if (result.success) { |
| showSnackbar(translations[StateManager.currentLang]["feedback_submitted"], 'success'); |
| |
| |
| this.markMessageAsRated( |
| this.currentFeedback.modelType, |
| this.currentFeedback.messageIndex, |
| this.currentFeedback.rating |
| ); |
|
|
| this.closeModal(); |
| } else { |
| showSnackbar(translations[StateManager.currentLang]["feedback_failed_server_error"], 'error'); |
| } |
| } catch (err) { |
| showSnackbar(translations[StateManager.currentLang]["feedback_failed_network_error"], 'error'); |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| markMessageAsRated(modelType, messageIndex, rating) { |
| const messages = StateManager.getMessages(modelType); |
| if (messages[messageIndex]) { |
| messages[messageIndex].feedback = { |
| rated: true, |
| rating: rating |
| }; |
|
|
| window.dispatchEvent(new CustomEvent('feedbackSubmitted', { |
| detail: { modelType, messageIndex, rating } |
| })); |
| } |
| } |
| }; |