Ocideck/lib/utils/url_launcher_util.dart
Brenno de Winter ee9e2bfc58 Add logger; replace silent catch(_) with logged fallbacks (#2)
Introduce lib/utils/log.dart (logError / logWarning over dart:developer) and
route all 53 previously-bare `catch (_)` blocks through it. Behaviour is
unchanged: every fallback still fails soft (a broken sidecar, unreadable file
or unsupported platform must never crash a presentation) but the cause is now
observable. logError is used for unexpected parse/IO failures, logWarning for
expected best-effort fallbacks; no deck or file contents are ever logged.

Note: file_service, markdown_service, marp_html_service, fullscreen_presenter,
image_carousel_picker and url_launcher_util also carried pre-existing local
changes, bundled here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:16:39 +02:00

29 lines
1.1 KiB
Dart

import 'package:url_launcher/url_launcher.dart';
import 'log.dart';
/// Schemes a deck link may open. Anything else (file:, javascript:, custom app
/// schemes, …) is refused so a deck can't hand the OS a dangerous or
/// unexpected URI.
const _allowedUrlSchemes = {'https', 'http', 'mailto'};
/// Open een link uit slide-tekst in de externe browser. Kale domeinen
/// (zonder schema) krijgen automatisch `https://`. Faalt stil bij ongeldige,
/// niet-openbare of niet-toegestane URLs.
Future<void> openExternalUrl(String url) async {
var u = url.trim();
if (u.isEmpty) return;
if (!u.contains('://') && !u.startsWith('mailto:')) {
u = u.contains('@') ? 'mailto:$u' : 'https://$u';
}
final uri = Uri.tryParse(u);
if (uri == null) return;
if (!_allowedUrlSchemes.contains(uri.scheme.toLowerCase())) return;
try {
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
}
} catch (e) {
logWarning('openExternalUrl: launching external URL failed', e);
// Nooit de presentatie laten crashen op een kapotte link.
}
}