showNewsMarkerDetailsSheet function

void showNewsMarkerDetailsSheet(
  1. BuildContext context,
  2. NewsMarker newsMarker
)

Shows detailed information about a news marker in a bottom sheet.

Implementation

void showNewsMarkerDetailsSheet(BuildContext context, NewsMarker newsMarker) {
  showModalBottomSheet(
    context: context,
    isScrollControlled: false,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
    ),
    builder: (sheetContext) => Padding(
      padding: const EdgeInsets.all(18.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Header with news icon.
          Row(
            children: [
              Icon(
                Icons.article_outlined,
                color: Colors.blue.shade700,
                size: 28,
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Text(
                  'News Article',
                  style: Theme.of(
                    context,
                  ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
                ),
              ),
            ],
          ),
          const Divider(height: 24),

          // News title.
          Text(
            newsMarker.title,
            style: Theme.of(
              context,
            ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600),
          ),
          const SizedBox(height: 12),

          // Source and date.
          if (newsMarker.source != null || newsMarker.publishedAt != null)
            Row(
              children: [
                if (newsMarker.source != null) ...[
                  Icon(Icons.public, size: 16, color: Colors.grey.shade600),
                  const SizedBox(width: 4),
                  Text(
                    newsMarker.source!,
                    style: TextStyle(color: Colors.grey.shade600, fontSize: 14),
                  ),
                ],
                if (newsMarker.source != null && newsMarker.publishedAt != null)
                  Text(' • ', style: TextStyle(color: Colors.grey.shade600)),
                if (newsMarker.publishedAt != null) ...[
                  Icon(
                    Icons.access_time,
                    size: 16,
                    color: Colors.grey.shade600,
                  ),
                  const SizedBox(width: 4),
                  Text(
                    _formatDateTime(newsMarker.publishedAt!),
                    style: TextStyle(color: Colors.grey.shade600, fontSize: 14),
                  ),
                ],
              ],
            ),

          // Tone indicator.
          if (newsMarker.tone != null) ...[
            const SizedBox(height: 8),
            Row(
              children: [
                Icon(
                  newsMarker.tone! > 0
                      ? Icons.sentiment_satisfied
                      : newsMarker.tone! < 0
                      ? Icons.sentiment_dissatisfied
                      : Icons.sentiment_neutral,
                  size: 16,
                  color: newsMarker.tone! > 0
                      ? Colors.green
                      : newsMarker.tone! < 0
                      ? Colors.red
                      : Colors.grey,
                ),
                const SizedBox(width: 4),
                Text(
                  'Tone: ${newsMarker.tone!.toStringAsFixed(1)}',
                  style: TextStyle(color: Colors.grey.shade600, fontSize: 14),
                ),
              ],
            ),
          ],

          const SizedBox(height: 16),

          // Location info.
          Row(
            children: [
              Icon(Icons.location_on, size: 16, color: Colors.grey.shade600),
              const SizedBox(width: 4),
              Expanded(
                child: Text(
                  '${newsMarker.location.latitude.toStringAsFixed(4)}, ${newsMarker.location.longitude.toStringAsFixed(4)}',
                  style: TextStyle(color: Colors.grey.shade600, fontSize: 12),
                ),
              ),
            ],
          ),

          const SizedBox(height: 20),

          // Action buttons.
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              TextButton(
                onPressed: () => Navigator.of(sheetContext).pop(),
                child: const Text('Close'),
              ),
              if (newsMarker.url != null) ...[
                const SizedBox(width: 8),
                ElevatedButton.icon(
                  onPressed: () {
                    Navigator.of(sheetContext).pop();
                    _launchUrl(context, newsMarker.url!);
                  },
                  icon: const Icon(Icons.open_in_new, size: 18),
                  label: const Text('Read Article'),
                ),
              ],
            ],
          ),
          const SizedBox(height: 20),
        ],
      ),
    ),
  );
}