Skip to content

Context menu actions fail due to unimplemented stub methods #10

@aaron-seq

Description

@aaron-seq

Problem Description

Users right-click on selected text or pages and choose context menu options like "Explain this concept", "Translate selection", or "Analyze sentiment", but nothing happens. The extension fails silently with no error messages or feedback.

Root Cause

The context menu handlers in background.js call methods that are only stub implementations returning empty objects or performing no operations. These methods were created as placeholders but never fully implemented.

Affected Context Menu Actions

The following context menu items are broken:

Selection-based actions:

  • Explain this concept → calls quickExplainConcept() (stub)
  • Translate selection → calls quickTranslateText() (stub)
  • Analyze sentiment → calls quickAnalyzeSentiment() (stub)

Page-based actions:

  • Summarize entire page → calls quickSummarizePage() (stub)
  • Extract key insights → calls quickExtractInsights() (stub)
  • Generate smart tags → calls quickGenerateTags() (stub)

Current Stub Implementations

These methods exist but do nothing:

// From background.js lines 427-445
async quickExplainConcept(_text) {}
async quickTranslateText(_text) {}
async quickAnalyzeSentiment(_text) {}
async quickSummarizePage(_tabId) {}
async quickExtractInsights(_tabId) {}
async quickGenerateTags(_tabId) {}

Impact

  • Severity: High
  • All context menu features are non-functional
  • Users cannot access core extension functionality via right-click
  • No error messages inform users why actions fail
  • Creates perception that extension is completely broken

Expected Behavior

Each context menu action should:

  1. Extract the selected text or page content
  2. Send it to the appropriate AI provider
  3. Display results in a notification or popup
  4. Show loading states during processing
  5. Display clear error messages if something fails

Proposed Implementation

Implement quickExplainConcept

async quickExplainConcept(text) {
  try {
    this.notificationManager.showInfo('Explaining concept...', 'Please wait');
    
    const explanation = await this.processContextualQuestion({
      question: `Explain the following concept in simple terms: "${text}"`,
      context: text
    });
    
    this.notificationManager.showSuccess(
      'Concept Explained',
      explanation.answer.text || explanation.answer,
      { requiresInteraction: true }
    );
  } catch (error) {
    this.errorHandler.handleError(error, 'Failed to explain concept');
    this.notificationManager.showError('Could not explain concept. Please try again.');
  }
}

Implement quickTranslateText

async quickTranslateText(text) {
  try {
    this.notificationManager.showInfo('Translating text...', 'Please wait');
    
    const targetLanguage = await this.configManager.getPreference('defaultTargetLanguage') || 'English';
    
    const translation = await this.processContentTranslation({
      content: text,
      targetLanguage: targetLanguage
    });
    
    this.notificationManager.showSuccess(
      `Translated to ${targetLanguage}`,
      translation.text,
      { requiresInteraction: true }
    );
  } catch (error) {
    this.errorHandler.handleError(error, 'Translation failed');
    this.notificationManager.showError('Could not translate text. Please try again.');
  }
}

Implement quickAnalyzeSentiment

async quickAnalyzeSentiment(text) {
  try {
    this.notificationManager.showInfo('Analyzing sentiment...', 'Please wait');
    
    const analysis = await this.processSentimentAnalysis({
      content: text
    });
    
    const emoji = {
      'positive': '😊',
      'negative': '😞',
      'neutral': '😐'
    }[analysis.sentiment] || '🤔';
    
    this.notificationManager.showSuccess(
      `Sentiment: ${emoji} ${analysis.sentiment}`,
      `Confidence: ${(analysis.confidence * 100).toFixed(0)}%\n${analysis.reasoning}`,
      { requiresInteraction: true }
    });
  } catch (error) {
    this.errorHandler.handleError(error, 'Sentiment analysis failed');
    this.notificationManager.showError('Could not analyze sentiment. Please try again.');
  }
}

Implement Page-Based Actions

async quickSummarizePage(tabId) {
  try {
    this.notificationManager.showInfo('Summarizing page...', 'Please wait');
    
    const content = await this.extractPageContent(tabId, {});
    
    const summary = await this.processContentSummary({
      content: content.text || content,
      summaryType: 'key-points',
      targetLength: 'medium'
    });
    
    // Open results in side panel or popup
    await chrome.tabs.sendMessage(tabId, {
      action: 'displaySummary',
      summary: summary.summary
    });
    
    this.notificationManager.showSuccess('Page summarized', 'Check the extension popup for results');
  } catch (error) {
    this.errorHandler.handleError(error, 'Page summarization failed');
    this.notificationManager.showError('Could not summarize page. Please try again.');
  }
}

async quickExtractInsights(tabId) {
  try {
    this.notificationManager.showInfo('Extracting insights...', 'Please wait');
    
    const content = await this.extractPageContent(tabId, {});
    
    const insights = await this.processContextualQuestion({
      question: 'Extract the 5 most important insights or takeaways from this content.',
      context: content.text || content
    });
    
    await chrome.tabs.sendMessage(tabId, {
      action: 'displayInsights',
      insights: insights.answer
    });
    
    this.notificationManager.showSuccess('Insights extracted', 'Check the extension popup for results');
  } catch (error) {
    this.errorHandler.handleError(error, 'Insight extraction failed');
    this.notificationManager.showError('Could not extract insights. Please try again.');
  }
}

async quickGenerateTags(tabId) {
  try {
    this.notificationManager.showInfo('Generating tags...', 'Please wait');
    
    const content = await this.extractPageContent(tabId, {});
    
    const tagsResponse = await this.processContextualQuestion({
      question: 'Generate 5-10 relevant tags or keywords for this content. Return only the tags, comma-separated.',
      context: content.text || content
    });
    
    const tags = (tagsResponse.answer.text || tagsResponse.answer)
      .split(',')
      .map(tag => tag.trim())
      .filter(tag => tag.length > 0);
    
    // Save tags to page metadata
    await this.storageService.savePageTags(content.url, tags);
    
    this.notificationManager.showSuccess(
      'Tags Generated',
      tags.join(', '),
      { requiresInteraction: true }
    );
  } catch (error) {
    this.errorHandler.handleError(error, 'Tag generation failed');
    this.notificationManager.showError('Could not generate tags. Please try again.');
  }
}

Required Changes

  1. Replace all stub methods with full implementations
  2. Add proper error handling for each action
  3. Implement loading states and user feedback
  4. Test each context menu action thoroughly
  5. Add integration tests for context menu workflows
  6. Update processContentTranslation() and processSentimentAnalysis() stubs

Testing Requirements

  • Test each context menu item with selected text
  • Test each context menu item on different page types
  • Test with no API keys configured (should show setup message)
  • Test with invalid/expired API keys (should show clear error)
  • Test with very long text selections
  • Test rapid successive context menu clicks (rate limiting)
  • Verify notifications display correctly and are dismissible

Dependencies

This issue blocks full context menu functionality and depends on:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions