|
|
|
|
| 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 }
|
| }));
|
| }
|
| }
|
| }; |