Image library: - "Clean up duplicates" finds byte-identical images by md5, keeps one file per group (preferring the most-used, then the oldest), merges the tags/descriptions and captions of the copies, repoints slides in open decks and in .md presentations on disk, and deletes the copies after a confirmation that lists every group. - A header toggle filters to images without tags/description, so it is easy to see which ones still need attention. - The delete warning now also lists presentations on disk that still reference the image (marked "not open"), next to the open decks. Editor and accessibility (already in tree): - Interface text scaling up to 200%, keyboard-operable panel divider, keyboard-first add-slide dialog, and screen-reader improvements. - Paste a spreadsheet/CSV/markdown selection into a table cell to fill the whole grid. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
53 lines
1.8 KiB
Dart
53 lines
1.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'l10n/app_localizations.dart';
|
|
import 'state/settings_provider.dart';
|
|
import 'theme/app_theme.dart';
|
|
import 'widgets/app_shell.dart';
|
|
|
|
class OciDeckApp extends ConsumerWidget {
|
|
const OciDeckApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final languageCode = ref.watch(
|
|
settingsProvider.select((s) => s.languageCode),
|
|
);
|
|
final appearance = ref.watch(
|
|
settingsProvider.select((s) => s.appAppearanceProfile),
|
|
);
|
|
final uiTextScale = ref.watch(
|
|
settingsProvider.select((s) => s.uiTextScale),
|
|
);
|
|
AppLocalizations.setActiveLanguageCode(languageCode);
|
|
return MaterialApp(
|
|
title: 'OciDeck',
|
|
theme: AppTheme.fromProfile(appearance),
|
|
debugShowCheckedModeBanner: false,
|
|
// Interface text scaling (WCAG 1.4.4): the user's setting multiplies
|
|
// whatever the OS already asks for. Slides themselves opt out — they
|
|
// are a fixed design canvas (see SlidePreviewWidget).
|
|
builder: (context, child) {
|
|
final media = MediaQuery.of(context);
|
|
return MediaQuery(
|
|
data: media.copyWith(
|
|
textScaler: TextScaler.linear(
|
|
(media.textScaler.scale(1.0) * uiTextScale).clamp(1.0, 2.0),
|
|
),
|
|
),
|
|
child: child!,
|
|
);
|
|
},
|
|
locale: AppLocalizations.materialLocaleFor(languageCode),
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
localizationsDelegates: const [
|
|
AppLocalizations.delegate,
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
],
|
|
home: const AppShell(),
|
|
);
|
|
}
|
|
}
|