feat: refine presenter and language options
This commit is contained in:
parent
d0bd1a85bf
commit
d59c6ee761
9 changed files with 752 additions and 222 deletions
|
|
@ -14,11 +14,12 @@ class OciDeckApp extends ConsumerWidget {
|
||||||
final languageCode = ref.watch(
|
final languageCode = ref.watch(
|
||||||
settingsProvider.select((s) => s.languageCode),
|
settingsProvider.select((s) => s.languageCode),
|
||||||
);
|
);
|
||||||
|
AppLocalizations.setActiveLanguageCode(languageCode);
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'OciDeck',
|
title: 'OciDeck',
|
||||||
theme: AppTheme.light,
|
theme: AppTheme.light,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
locale: Locale(languageCode),
|
locale: AppLocalizations.materialLocaleFor(languageCode),
|
||||||
supportedLocales: AppLocalizations.supportedLocales,
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
AppLocalizations.delegate,
|
AppLocalizations.delegate,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ class AppLocalizations {
|
||||||
Locale('de'),
|
Locale('de'),
|
||||||
Locale('fr'),
|
Locale('fr'),
|
||||||
Locale('es'),
|
Locale('es'),
|
||||||
|
Locale('fy'),
|
||||||
|
Locale('pap'),
|
||||||
];
|
];
|
||||||
|
|
||||||
static const languageNames = {
|
static const languageNames = {
|
||||||
|
|
@ -22,8 +24,31 @@ class AppLocalizations {
|
||||||
'de': 'Deutsch',
|
'de': 'Deutsch',
|
||||||
'fr': 'Français',
|
'fr': 'Français',
|
||||||
'es': 'Español',
|
'es': 'Español',
|
||||||
|
'fy': 'Frysk',
|
||||||
|
'pap': 'Papiamento',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const _materialLocaleFallbacks = {
|
||||||
|
'nl': Locale('nl'),
|
||||||
|
'en': Locale('en'),
|
||||||
|
'it': Locale('it'),
|
||||||
|
'de': Locale('de'),
|
||||||
|
'fr': Locale('fr'),
|
||||||
|
'es': Locale('es'),
|
||||||
|
'fy': Locale('en'),
|
||||||
|
'pap': Locale('en'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static String _activeLanguageCode = 'nl';
|
||||||
|
|
||||||
|
static void setActiveLanguageCode(String code) {
|
||||||
|
_activeLanguageCode = languageNames.containsKey(code) ? code : 'nl';
|
||||||
|
}
|
||||||
|
|
||||||
|
static Locale materialLocaleFor(String code) {
|
||||||
|
return _materialLocaleFallbacks[code] ?? const Locale('nl');
|
||||||
|
}
|
||||||
|
|
||||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||||
_AppLocalizationsDelegate();
|
_AppLocalizationsDelegate();
|
||||||
|
|
||||||
|
|
@ -32,13 +57,19 @@ class AppLocalizations {
|
||||||
const AppLocalizations(Locale('nl'));
|
const AppLocalizations(Locale('nl'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get languageCode => _activeLanguageCode;
|
||||||
|
|
||||||
String t(String key) {
|
String t(String key) {
|
||||||
return _strings[locale.languageCode]?[key] ?? _strings['nl']![key] ?? key;
|
if (languageCode == 'nl') return _strings['nl']![key] ?? key;
|
||||||
|
return _strings[languageCode]?[key] ??
|
||||||
|
_strings['en']?[key] ??
|
||||||
|
_strings['nl']![key] ??
|
||||||
|
key;
|
||||||
}
|
}
|
||||||
|
|
||||||
String d(String dutchText) {
|
String d(String dutchText) {
|
||||||
if (locale.languageCode == 'nl') return dutchText;
|
if (languageCode == 'nl') return dutchText;
|
||||||
return _dutchSourceStrings[locale.languageCode]?[dutchText] ??
|
return _dutchSourceStrings[languageCode]?[dutchText] ??
|
||||||
_dutchSourceStrings['en']?[dutchText] ??
|
_dutchSourceStrings['en']?[dutchText] ??
|
||||||
dutchText;
|
dutchText;
|
||||||
}
|
}
|
||||||
|
|
@ -567,6 +598,168 @@ const _strings = {
|
||||||
'of': 'de',
|
'of': 'de',
|
||||||
'exportedTo': 'Exportado a:',
|
'exportedTo': 'Exportado a:',
|
||||||
},
|
},
|
||||||
|
'fy': {
|
||||||
|
'newPresentation': 'Nije presintaasje',
|
||||||
|
'open': 'Iepenje...',
|
||||||
|
'openEllipsis': 'Iepenje…',
|
||||||
|
'recentPresentations': 'Resinte presintaasjes',
|
||||||
|
'newTab': 'Nij ljepblêd',
|
||||||
|
'undo': 'Ungedien meitsje (Ctrl/Cmd+Z)',
|
||||||
|
'redo': 'Opnij útfiere (Ctrl/Cmd+Shift+Z)',
|
||||||
|
'imageLibrary': 'Ofbyldingsbibleteek',
|
||||||
|
'presentFullscreen': 'Presintearje folslein skerm · P foar presenter view',
|
||||||
|
'visualMode': 'Fisuele modus',
|
||||||
|
'markdownMode': 'Markdown-modus',
|
||||||
|
'save': 'Bewarje',
|
||||||
|
'saveShortcut': 'Bewarje (Ctrl/Cmd+S)',
|
||||||
|
'more': 'Mear',
|
||||||
|
'export': 'Eksportearje',
|
||||||
|
'exportReady': 'Eksportearje (PDF/PPTX/HTML)',
|
||||||
|
'exportNeedsSave': 'Bewarje de presintaasje earst om te eksportearjen',
|
||||||
|
'exportNeedsClean': 'Bewarje dyn wizigingen earst om te eksportearjen',
|
||||||
|
'saved': 'Bewarre',
|
||||||
|
'unsaved': 'Net bewarre',
|
||||||
|
'unsavedChanges': 'Wizigingen bewarje (Ctrl/Cmd+S)',
|
||||||
|
'noUnsavedChanges': 'Gjin net-bewarre wizigingen',
|
||||||
|
'notSavedYet': 'Noch net bewarre',
|
||||||
|
'noFileYet': 'Dizze presintaasje hat noch gjin bestân',
|
||||||
|
'slides': 'slides',
|
||||||
|
'skipped': 'oerslein',
|
||||||
|
'allSlidesIncluded': 'Alle slides wurde presintearre en eksportearre',
|
||||||
|
'skippedSlidesExcluded': 'slide(s) wurde net presintearre of eksportearre',
|
||||||
|
'styleProfile': 'Stylprofyl',
|
||||||
|
'classification': 'Klassifikaasje',
|
||||||
|
'exportNextToDeck': 'Eksport neist deck',
|
||||||
|
'exportsNextToDeck': 'Eksporten wurde neist it deck bewarre',
|
||||||
|
'exportFolder': 'Eksport',
|
||||||
|
'newPresentationTab': 'Nije presintaasje (ljepblêd)',
|
||||||
|
'exportPackage': 'Pakket eksportearje…',
|
||||||
|
'importPackage': 'Pakket ymportearje…',
|
||||||
|
'importUrl': 'Ymportearje fan URL…',
|
||||||
|
'findReplace': 'Sykje en ferfange',
|
||||||
|
'fullDeckPreview': 'Hiel deck besjen',
|
||||||
|
'presentationProperties': 'Presintaasje-eigenskippen',
|
||||||
|
'settings': 'Ynstellingen',
|
||||||
|
'settingsGeneral': 'Algemien',
|
||||||
|
'settingsColors': 'Kleuren',
|
||||||
|
'settingsLogo': 'Logo',
|
||||||
|
'language': 'Taal',
|
||||||
|
'applicationLanguage': 'Applikaasjetaal',
|
||||||
|
'languageHelp':
|
||||||
|
'De interface wikselet daliks fan taal. Presintaasje-ynhâld bliuwt itselde.',
|
||||||
|
'presentationFolder': 'Presintaasjemap',
|
||||||
|
'exportFolderSetting': 'Eksportmap',
|
||||||
|
'notSet': 'Net ynsteld',
|
||||||
|
'nextToPresentationFile': 'Neist it presintaasjebestân',
|
||||||
|
'choose': 'Kieze',
|
||||||
|
'removeDefaultFolder': 'Standertmap fuortsmite',
|
||||||
|
'removeExportFolder': 'Eksportmap fuortsmite',
|
||||||
|
'exportFolderHelp':
|
||||||
|
'Alle eksporten (PDF/PPTX) wurde hjir bewarre. Net ynsteld? Dan komme se neist it presintaasjebestân.',
|
||||||
|
'cancel': 'Annulearje',
|
||||||
|
'close': 'Slute',
|
||||||
|
'saveSettings': 'Bewarje',
|
||||||
|
'exportDialogTitle': 'Eksportearje',
|
||||||
|
'exportAgain': 'Nochris eksportearje',
|
||||||
|
'exportIntro':
|
||||||
|
'De eksport brûkt krekt de werjefte út de editor, ynklusyf dyn stylprofyl.',
|
||||||
|
'imageQualityPdf': 'Ofbyldingskwaliteit (PDF)',
|
||||||
|
'normal': 'Normaal',
|
||||||
|
'compressed': 'Komprimearre',
|
||||||
|
'compressedHelp':
|
||||||
|
'JPEG op legere resolúsje, bedoeld as handout, mei in folle lytser bestân (apart bewarre as “-compact”).',
|
||||||
|
'losslessHelp': 'Ferliesfrije ôfbyldings op folsleine resolúsje.',
|
||||||
|
'exportAsPdf': 'Eksportearje as PDF',
|
||||||
|
'exportAsPptx': 'Eksportearje as PPTX',
|
||||||
|
'exportAsHtml': 'Eksportearje as HTML (Marp, offline)',
|
||||||
|
'renderingSlides': 'Slides renderje…',
|
||||||
|
'buildingHtml': 'HTML bouwe…',
|
||||||
|
'buildingExport': 'bouwe…',
|
||||||
|
'slideOf': 'Slide',
|
||||||
|
'of': 'fan',
|
||||||
|
'exportedTo': 'Eksportearre nei:',
|
||||||
|
},
|
||||||
|
'pap': {
|
||||||
|
'newPresentation': 'Presentashon nobo',
|
||||||
|
'open': 'Habri...',
|
||||||
|
'openEllipsis': 'Habri…',
|
||||||
|
'recentPresentations': 'Presentashonnan resien',
|
||||||
|
'newTab': 'Tab nobo',
|
||||||
|
'undo': 'Deshasí (Ctrl/Cmd+Z)',
|
||||||
|
'redo': 'Hasi atrobe (Ctrl/Cmd+Shift+Z)',
|
||||||
|
'imageLibrary': 'Biblioteka di imágen',
|
||||||
|
'presentFullscreen': 'Presentá na pantalla kompletu · P pa presenter view',
|
||||||
|
'visualMode': 'Modo visual',
|
||||||
|
'markdownMode': 'Modo Markdown',
|
||||||
|
'save': 'Warda',
|
||||||
|
'saveShortcut': 'Warda (Ctrl/Cmd+S)',
|
||||||
|
'more': 'Mas',
|
||||||
|
'export': 'Eksportá',
|
||||||
|
'exportReady': 'Eksportá (PDF/PPTX/HTML)',
|
||||||
|
'exportNeedsSave': 'Warda e presentashon promé ku eksportá',
|
||||||
|
'exportNeedsClean': 'Warda bo kambionan promé ku eksportá',
|
||||||
|
'saved': 'Wardá',
|
||||||
|
'unsaved': 'No wardá',
|
||||||
|
'unsavedChanges': 'Warda kambionan (Ctrl/Cmd+S)',
|
||||||
|
'noUnsavedChanges': 'No tin kambionan sin warda',
|
||||||
|
'notSavedYet': 'Ainda no wardá',
|
||||||
|
'noFileYet': 'E presentashon aki ainda no tin un file',
|
||||||
|
'slides': 'slides',
|
||||||
|
'skipped': 'saltá',
|
||||||
|
'allSlidesIncluded': 'Tur slides lo wordu presentá i eksportá',
|
||||||
|
'skippedSlidesExcluded': 'slide(s) no lo wordu presentá òf eksportá',
|
||||||
|
'styleProfile': 'Perfil di estilo',
|
||||||
|
'classification': 'Klasifikashon',
|
||||||
|
'exportNextToDeck': 'Eksportá banda di deck',
|
||||||
|
'exportsNextToDeck': 'Eksportnan ta wordu wardá banda di e deck',
|
||||||
|
'exportFolder': 'Eksport',
|
||||||
|
'newPresentationTab': 'Presentashon nobo (tab)',
|
||||||
|
'exportPackage': 'Eksportá pakete…',
|
||||||
|
'importPackage': 'Importá pakete…',
|
||||||
|
'importUrl': 'Importá for di URL…',
|
||||||
|
'findReplace': 'Busca i reemplasá',
|
||||||
|
'fullDeckPreview': 'Mira henter e deck',
|
||||||
|
'presentationProperties': 'Propiedatnan di presentashon',
|
||||||
|
'settings': 'Preferensianan',
|
||||||
|
'settingsGeneral': 'General',
|
||||||
|
'settingsColors': 'Kolónan',
|
||||||
|
'settingsLogo': 'Logo',
|
||||||
|
'language': 'Idioma',
|
||||||
|
'applicationLanguage': 'Idioma di aplikashon',
|
||||||
|
'languageHelp':
|
||||||
|
'E interface ta cambia idioma mesora. Kontenido di presentashon ta keda igual.',
|
||||||
|
'presentationFolder': 'Folder di presentashon',
|
||||||
|
'exportFolderSetting': 'Folder di eksport',
|
||||||
|
'notSet': 'No konfigurá',
|
||||||
|
'nextToPresentationFile': 'Banda di e file di presentashon',
|
||||||
|
'choose': 'Skohe',
|
||||||
|
'removeDefaultFolder': 'Kita folder standard',
|
||||||
|
'removeExportFolder': 'Kita folder di eksport',
|
||||||
|
'exportFolderHelp':
|
||||||
|
'Tur eksportnan (PDF/PPTX) ta wordu wardá aki. Si no konfigurá, nan ta wordu wardá banda di e file di presentashon.',
|
||||||
|
'cancel': 'Kanselá',
|
||||||
|
'close': 'Sera',
|
||||||
|
'saveSettings': 'Warda',
|
||||||
|
'exportDialogTitle': 'Eksportá',
|
||||||
|
'exportAgain': 'Eksportá atrobe',
|
||||||
|
'exportIntro':
|
||||||
|
'E eksport ta usa mesun bista ku e editor, inkluyendo bo perfil di estilo.',
|
||||||
|
'imageQualityPdf': 'Kalidat di imágen (PDF)',
|
||||||
|
'normal': 'Normal',
|
||||||
|
'compressed': 'Komprimí',
|
||||||
|
'compressedHelp':
|
||||||
|
'JPEG ku resolushon mas abou, pa handout, ku un file hopi mas chikí (wardá apart komo “-compact”).',
|
||||||
|
'losslessHelp': 'Imágennan sin pèrdida na resolushon kompletu.',
|
||||||
|
'exportAsPdf': 'Eksportá komo PDF',
|
||||||
|
'exportAsPptx': 'Eksportá komo PPTX',
|
||||||
|
'exportAsHtml': 'Eksportá komo HTML (Marp, offline)',
|
||||||
|
'renderingSlides': 'Render slides…',
|
||||||
|
'buildingHtml': 'Trahando HTML…',
|
||||||
|
'buildingExport': 'trahando…',
|
||||||
|
'slideOf': 'Slide',
|
||||||
|
'of': 'di',
|
||||||
|
'exportedTo': 'Eksportá na:',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const _dutchSourceStrings = {
|
const _dutchSourceStrings = {
|
||||||
|
|
@ -852,21 +1045,26 @@ const _dutchSourceStrings = {
|
||||||
'↑↓←→ navigeren · Enter kiezen · Dubbelklik selecteert':
|
'↑↓←→ navigeren · Enter kiezen · Dubbelklik selecteert':
|
||||||
'↑↓←→ navigate · Enter chooses · Double-click selects',
|
'↑↓←→ navigate · Enter chooses · Double-click selects',
|
||||||
'Sneltoetsen': 'Keyboard shortcuts',
|
'Sneltoetsen': 'Keyboard shortcuts',
|
||||||
|
'Toetsenlegenda': 'Key legend',
|
||||||
'spatie': 'space',
|
'spatie': 'space',
|
||||||
'klik': 'click',
|
'klik': 'click',
|
||||||
'cijfers': 'numbers',
|
'cijfers': 'numbers',
|
||||||
'Klik of druk op ? / H / Esc om te sluiten':
|
'Klik of druk op ? / H / Esc om te sluiten':
|
||||||
'Click or press ? / H / Esc to close',
|
'Click or press ? / H / Esc to close',
|
||||||
|
'Klik of druk op H / Esc om te sluiten': 'Click or press H / Esc to close',
|
||||||
'Naar slidenummer': 'Go to slide number',
|
'Naar slidenummer': 'Go to slide number',
|
||||||
'Eerste · laatste slide': 'First · last slide',
|
'Eerste · laatste slide': 'First · last slide',
|
||||||
'Slide-overzicht': 'Slide overview',
|
'Slide-overzicht': 'Slide overview',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Slide overview (arrows + Enter)',
|
||||||
'Presenter view (notities, klok)': 'Presenter view (notes, clock)',
|
'Presenter view (notities, klok)': 'Presenter view (notes, clock)',
|
||||||
|
'Scherm wisselen (meerdere schermen)': 'Switch screen (multiple displays)',
|
||||||
'Zwart · wit scherm': 'Black · white screen',
|
'Zwart · wit scherm': 'Black · white screen',
|
||||||
'Verstreken tijd resetten': 'Reset elapsed time',
|
'Verstreken tijd resetten': 'Reset elapsed time',
|
||||||
'Automatische modus aan/uit': 'Automatic mode on/off',
|
'Automatische modus aan/uit': 'Automatic mode on/off',
|
||||||
'Herhalen (loop) aan/uit': 'Repeat (loop) on/off',
|
'Herhalen (loop) aan/uit': 'Repeat (loop) on/off',
|
||||||
'Na audio automatisch doorgaan': 'Advance automatically after audio',
|
'Na audio automatisch doorgaan': 'Advance automatically after audio',
|
||||||
'Dit overzicht': 'This overview',
|
'Dit overzicht': 'This overview',
|
||||||
|
'Deze legenda': 'This legend',
|
||||||
'Terug / afsluiten': 'Back / exit',
|
'Terug / afsluiten': 'Back / exit',
|
||||||
'Auto (A)': 'Auto (A)',
|
'Auto (A)': 'Auto (A)',
|
||||||
'Handmatig (A)': 'Manual (A)',
|
'Handmatig (A)': 'Manual (A)',
|
||||||
|
|
@ -883,8 +1081,16 @@ const _dutchSourceStrings = {
|
||||||
'Verstreken': 'Elapsed',
|
'Verstreken': 'Elapsed',
|
||||||
'Klok': 'Clock',
|
'Klok': 'Clock',
|
||||||
'Geen notities voor deze slide.': 'No notes for this slide.',
|
'Geen notities voor deze slide.': 'No notes for this slide.',
|
||||||
|
'Wissel scherm (S)': 'Switch screen (S)',
|
||||||
|
'Kon niet van scherm wisselen.': 'Could not switch screens.',
|
||||||
'P publiek · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
'P publiek · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
'P audience · G overview · B/W black/white · R time · Esc stop',
|
'P audience · G overview · B/W black/white · R time · Esc stop',
|
||||||
|
'P publiek · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P audience · S screen · G overview · B/W black/white · R time · Esc stop',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P audience · H legend · G overview · B/W black/white · R time · Esc stop',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P audience · H legend · S screen · G overview · B/W black/white · R time · Esc stop',
|
||||||
'pijltjes + Enter of klik om te springen':
|
'pijltjes + Enter of klik om te springen':
|
||||||
'arrows + Enter or click to jump',
|
'arrows + Enter or click to jump',
|
||||||
'Afsluiten (Escape)': 'Exit (Escape)',
|
'Afsluiten (Escape)': 'Exit (Escape)',
|
||||||
|
|
@ -1033,12 +1239,35 @@ const _dutchSourceStrings = {
|
||||||
'Gekopieerd': 'Copiato',
|
'Gekopieerd': 'Copiato',
|
||||||
'Afbeelding verwijderen?': 'Eliminare immagine?',
|
'Afbeelding verwijderen?': 'Eliminare immagine?',
|
||||||
'Sneltoetsen': 'Scorciatoie da tastiera',
|
'Sneltoetsen': 'Scorciatoie da tastiera',
|
||||||
|
'Toetsenlegenda': 'Legenda tasti',
|
||||||
|
'spatie': 'spazio',
|
||||||
|
'klik': 'clic',
|
||||||
|
'cijfers': 'numeri',
|
||||||
|
'Klik of druk op H / Esc om te sluiten':
|
||||||
|
'Fai clic o premi H / Esc per chiudere',
|
||||||
|
'Naar slidenummer': 'Vai al numero slide',
|
||||||
|
'Eerste · laatste slide': 'Prima · ultima slide',
|
||||||
'Slide-overzicht': 'Panoramica slide',
|
'Slide-overzicht': 'Panoramica slide',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Panoramica slide (frecce + Enter)',
|
||||||
|
'Presenter view (notities, klok)': 'Vista relatore (note, orologio)',
|
||||||
|
'Scherm wisselen (meerdere schermen)': 'Cambia schermo (piu schermi)',
|
||||||
|
'Zwart · wit scherm': 'Schermo nero · bianco',
|
||||||
|
'Verstreken tijd resetten': 'Reimposta tempo trascorso',
|
||||||
|
'Automatische modus aan/uit': 'Modalita automatica on/off',
|
||||||
|
'Herhalen (loop) aan/uit': 'Ripetizione (loop) on/off',
|
||||||
|
'Na audio automatisch doorgaan': 'Avanza automaticamente dopo audio',
|
||||||
|
'Deze legenda': 'Questa legenda',
|
||||||
|
'Terug / afsluiten': 'Indietro / esci',
|
||||||
'HUIDIGE SLIDE': 'SLIDE ATTUALE',
|
'HUIDIGE SLIDE': 'SLIDE ATTUALE',
|
||||||
'VOLGENDE': 'PROSSIMA',
|
'VOLGENDE': 'PROSSIMA',
|
||||||
'NOTITIES': 'NOTE',
|
'NOTITIES': 'NOTE',
|
||||||
'Verstreken': 'Trascorso',
|
'Verstreken': 'Trascorso',
|
||||||
'Klok': 'Orologio',
|
'Klok': 'Orologio',
|
||||||
|
'Wissel scherm (S)': 'Cambia schermo (S)',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P pubblico · H legenda · G panoramica · B/W nero/bianco · R tempo · Esc stop',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P pubblico · H legenda · S schermo · G panoramica · B/W nero/bianco · R tempo · Esc stop',
|
||||||
},
|
},
|
||||||
'de': {
|
'de': {
|
||||||
'Geen': 'Keine',
|
'Geen': 'Keine',
|
||||||
|
|
@ -1158,12 +1387,36 @@ const _dutchSourceStrings = {
|
||||||
'Gekopieerd': 'Kopiert',
|
'Gekopieerd': 'Kopiert',
|
||||||
'Afbeelding verwijderen?': 'Bild löschen?',
|
'Afbeelding verwijderen?': 'Bild löschen?',
|
||||||
'Sneltoetsen': 'Tastenkürzel',
|
'Sneltoetsen': 'Tastenkürzel',
|
||||||
|
'Toetsenlegenda': 'Tastenlegende',
|
||||||
|
'spatie': 'Leertaste',
|
||||||
|
'klik': 'Klick',
|
||||||
|
'cijfers': 'Zahlen',
|
||||||
|
'Klik of druk op H / Esc om te sluiten':
|
||||||
|
'Klicken oder H / Esc drücken zum Schließen',
|
||||||
|
'Naar slidenummer': 'Zu Foliennummer',
|
||||||
|
'Eerste · laatste slide': 'Erste · letzte Folie',
|
||||||
'Slide-overzicht': 'Folienübersicht',
|
'Slide-overzicht': 'Folienübersicht',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Folienübersicht (Pfeile + Enter)',
|
||||||
|
'Presenter view (notities, klok)': 'Presenter-Ansicht (Notizen, Uhr)',
|
||||||
|
'Scherm wisselen (meerdere schermen)':
|
||||||
|
'Bildschirm wechseln (mehrere Bildschirme)',
|
||||||
|
'Zwart · wit scherm': 'Schwarzer · weißer Bildschirm',
|
||||||
|
'Verstreken tijd resetten': 'Vergangene Zeit zurücksetzen',
|
||||||
|
'Automatische modus aan/uit': 'Automatikmodus ein/aus',
|
||||||
|
'Herhalen (loop) aan/uit': 'Wiederholen (Loop) ein/aus',
|
||||||
|
'Na audio automatisch doorgaan': 'Nach Audio automatisch weiter',
|
||||||
|
'Deze legenda': 'Diese Legende',
|
||||||
|
'Terug / afsluiten': 'Zurück / beenden',
|
||||||
'HUIDIGE SLIDE': 'AKTUELLE FOLIE',
|
'HUIDIGE SLIDE': 'AKTUELLE FOLIE',
|
||||||
'VOLGENDE': 'NÄCHSTE',
|
'VOLGENDE': 'NÄCHSTE',
|
||||||
'NOTITIES': 'NOTIZEN',
|
'NOTITIES': 'NOTIZEN',
|
||||||
'Verstreken': 'Vergangen',
|
'Verstreken': 'Vergangen',
|
||||||
'Klok': 'Uhr',
|
'Klok': 'Uhr',
|
||||||
|
'Wissel scherm (S)': 'Bildschirm wechseln (S)',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P Publikum · H Legende · G Übersicht · B/W schwarz/weiß · R Zeit · Esc Stopp',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P Publikum · H Legende · S Bildschirm · G Übersicht · B/W schwarz/weiß · R Zeit · Esc Stopp',
|
||||||
},
|
},
|
||||||
'fr': {
|
'fr': {
|
||||||
'Geen': 'Aucun',
|
'Geen': 'Aucun',
|
||||||
|
|
@ -1283,12 +1536,35 @@ const _dutchSourceStrings = {
|
||||||
'Gekopieerd': 'Copié',
|
'Gekopieerd': 'Copié',
|
||||||
'Afbeelding verwijderen?': 'Supprimer l’image ?',
|
'Afbeelding verwijderen?': 'Supprimer l’image ?',
|
||||||
'Sneltoetsen': 'Raccourcis clavier',
|
'Sneltoetsen': 'Raccourcis clavier',
|
||||||
|
'Toetsenlegenda': 'Legende des touches',
|
||||||
|
'spatie': 'espace',
|
||||||
|
'klik': 'clic',
|
||||||
|
'cijfers': 'chiffres',
|
||||||
|
'Klik of druk op H / Esc om te sluiten':
|
||||||
|
'Cliquez ou appuyez sur H / Esc pour fermer',
|
||||||
|
'Naar slidenummer': 'Aller au numero de diapositive',
|
||||||
|
'Eerste · laatste slide': 'Premiere · derniere diapositive',
|
||||||
'Slide-overzicht': 'Vue d’ensemble',
|
'Slide-overzicht': 'Vue d’ensemble',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Vue d’ensemble (fleches + Entree)',
|
||||||
|
'Presenter view (notities, klok)': 'Vue presentateur (notes, horloge)',
|
||||||
|
'Scherm wisselen (meerdere schermen)': 'Changer d’ecran (plusieurs ecrans)',
|
||||||
|
'Zwart · wit scherm': 'Ecran noir · blanc',
|
||||||
|
'Verstreken tijd resetten': 'Reinitialiser le temps ecoule',
|
||||||
|
'Automatische modus aan/uit': 'Mode automatique active/desactive',
|
||||||
|
'Herhalen (loop) aan/uit': 'Boucle activee/desactivee',
|
||||||
|
'Na audio automatisch doorgaan': 'Avancer automatiquement apres l’audio',
|
||||||
|
'Deze legenda': 'Cette legende',
|
||||||
|
'Terug / afsluiten': 'Retour / quitter',
|
||||||
'HUIDIGE SLIDE': 'DIAPOSITIVE ACTUELLE',
|
'HUIDIGE SLIDE': 'DIAPOSITIVE ACTUELLE',
|
||||||
'VOLGENDE': 'SUIVANTE',
|
'VOLGENDE': 'SUIVANTE',
|
||||||
'NOTITIES': 'NOTES',
|
'NOTITIES': 'NOTES',
|
||||||
'Verstreken': 'Écoulé',
|
'Verstreken': 'Écoulé',
|
||||||
'Klok': 'Horloge',
|
'Klok': 'Horloge',
|
||||||
|
'Wissel scherm (S)': 'Changer d’ecran (S)',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P public · H legende · G vue d’ensemble · B/W noir/blanc · R temps · Esc arret',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P public · H legende · S ecran · G vue d’ensemble · B/W noir/blanc · R temps · Esc arret',
|
||||||
},
|
},
|
||||||
'es': {
|
'es': {
|
||||||
'Geen': 'Ninguno',
|
'Geen': 'Ninguno',
|
||||||
|
|
@ -1408,11 +1684,334 @@ const _dutchSourceStrings = {
|
||||||
'Gekopieerd': 'Copiado',
|
'Gekopieerd': 'Copiado',
|
||||||
'Afbeelding verwijderen?': '¿Eliminar imagen?',
|
'Afbeelding verwijderen?': '¿Eliminar imagen?',
|
||||||
'Sneltoetsen': 'Atajos de teclado',
|
'Sneltoetsen': 'Atajos de teclado',
|
||||||
|
'Toetsenlegenda': 'Leyenda de teclas',
|
||||||
|
'spatie': 'espacio',
|
||||||
|
'klik': 'clic',
|
||||||
|
'cijfers': 'números',
|
||||||
|
'Klik of druk op H / Esc om te sluiten':
|
||||||
|
'Haz clic o pulsa H / Esc para cerrar',
|
||||||
|
'Naar slidenummer': 'Ir al número de diapositiva',
|
||||||
|
'Eerste · laatste slide': 'Primera · última diapositiva',
|
||||||
'Slide-overzicht': 'Vista general',
|
'Slide-overzicht': 'Vista general',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Vista general (flechas + Enter)',
|
||||||
|
'Presenter view (notities, klok)': 'Vista de presentador (notas, reloj)',
|
||||||
|
'Scherm wisselen (meerdere schermen)':
|
||||||
|
'Cambiar pantalla (varias pantallas)',
|
||||||
|
'Zwart · wit scherm': 'Pantalla negra · blanca',
|
||||||
|
'Verstreken tijd resetten': 'Restablecer tiempo transcurrido',
|
||||||
|
'Automatische modus aan/uit': 'Modo automático activar/desactivar',
|
||||||
|
'Herhalen (loop) aan/uit': 'Repetir (bucle) activar/desactivar',
|
||||||
|
'Na audio automatisch doorgaan': 'Avanzar automáticamente tras el audio',
|
||||||
|
'Deze legenda': 'Esta leyenda',
|
||||||
|
'Terug / afsluiten': 'Volver / salir',
|
||||||
'HUIDIGE SLIDE': 'DIAPOSITIVA ACTUAL',
|
'HUIDIGE SLIDE': 'DIAPOSITIVA ACTUAL',
|
||||||
'VOLGENDE': 'SIGUIENTE',
|
'VOLGENDE': 'SIGUIENTE',
|
||||||
'NOTITIES': 'NOTAS',
|
'NOTITIES': 'NOTAS',
|
||||||
'Verstreken': 'Transcurrido',
|
'Verstreken': 'Transcurrido',
|
||||||
'Klok': 'Reloj',
|
'Klok': 'Reloj',
|
||||||
|
'Wissel scherm (S)': 'Cambiar pantalla (S)',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P público · H leyenda · G vista general · B/W negro/blanco · R tiempo · Esc detener',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P público · H leyenda · S pantalla · G vista general · B/W negro/blanco · R tiempo · Esc detener',
|
||||||
|
},
|
||||||
|
'fy': {
|
||||||
|
'Geen': 'Gjin',
|
||||||
|
'Nieuw': 'Nij',
|
||||||
|
'Verwijderen': 'Fuortsmite',
|
||||||
|
'Herstellen': 'Weromsette',
|
||||||
|
'Opslaan en sluiten': 'Bewarje en slute',
|
||||||
|
'Importeren via URL': 'Ymportearje fan URL',
|
||||||
|
'Ophalen': 'Ophelje',
|
||||||
|
'Titelpagina': 'Titelslide',
|
||||||
|
'Tussentitel': 'Tuskenkop',
|
||||||
|
'Alleen Bullets': 'Allinnich bullets',
|
||||||
|
'Twee Bulletkolommen': 'Twa bulletkolommen',
|
||||||
|
'Bullets + Afbeelding': 'Bullets + Ofbylding',
|
||||||
|
'Twee Afbeeldingen': 'Twa ôfbyldings',
|
||||||
|
'Grote Afbeelding': 'Grutte ôfbylding',
|
||||||
|
'Tabel': 'Tabel',
|
||||||
|
'Vrije Markdown': 'Frije Markdown',
|
||||||
|
'Overgeslagen': 'Oerslein',
|
||||||
|
'Kopiëren': 'Kopiearje',
|
||||||
|
'Kopieer als afbeelding': 'Kopiearje as ôfbylding',
|
||||||
|
'Dupliceren': 'Duplisearje',
|
||||||
|
'Niet meer overslaan': 'Net mear oerslaan',
|
||||||
|
'Overslaan': 'Oerslaan',
|
||||||
|
'Titel': 'Titel',
|
||||||
|
'Titel (optioneel)': 'Titel (opsjoneel)',
|
||||||
|
'Slide titel': 'Slidetitel',
|
||||||
|
'Ondertitel': 'Undertitel',
|
||||||
|
'Optionele subtitel': 'Opsjonele subtitel',
|
||||||
|
'Bullets': 'Bullets',
|
||||||
|
'Bullet toevoegen': 'Bullet tafoegje',
|
||||||
|
'Verwijder': 'Fuortsmite',
|
||||||
|
'Citaat': 'Sitaat',
|
||||||
|
'Auteur': 'Auteur',
|
||||||
|
'Achtergrondafbeelding': 'Eftergrûnôfbylding',
|
||||||
|
'Achtergrondafbeelding (optioneel)': 'Eftergrûnôfbylding (opsjoneel)',
|
||||||
|
'Zoom achtergrond': 'Eftergrûn zoom',
|
||||||
|
'Zoom afbeelding': 'Ofbylding zoom',
|
||||||
|
'Afbeelding (rechts)': 'Ofbylding (rjochts)',
|
||||||
|
'Bullets (links)': 'Bullets (lofts)',
|
||||||
|
'Linker afbeelding': 'Linker ôfbylding',
|
||||||
|
'Rechter afbeelding': 'Rjochter ôfbylding',
|
||||||
|
'Audio bij deze slide': 'Audio by dizze slide',
|
||||||
|
'Audio automatisch afspelen': 'Audio automatysk ôfspylje',
|
||||||
|
'Video automatisch afspelen': 'Fideo automatysk ôfspylje',
|
||||||
|
'Geen audiobestand gekozen': 'Gjin audiobestân keazen',
|
||||||
|
'Geen video gekozen': 'Gjin fideo keazen',
|
||||||
|
'Kiezen': 'Kieze',
|
||||||
|
'Uit bibliotheek…': 'Ut bibleteek…',
|
||||||
|
'Van computer…': 'Fan kompjûter…',
|
||||||
|
'Geen afbeelding gekozen': 'Gjin ôfbylding keazen',
|
||||||
|
'Caption / bronvermelding': 'Byskrift / boarne',
|
||||||
|
'Beschrijving (doorzoekbaar)': 'Beskriuwing (trochsykber)',
|
||||||
|
'Markdown inhoud': 'Markdown-ynhâld',
|
||||||
|
'Rij toevoegen': 'Rige tafoegje',
|
||||||
|
'Kolom toevoegen': 'Kolom tafoegje',
|
||||||
|
'Kolom': 'Kolom',
|
||||||
|
'Presentatie openen': 'Presintaasje iepenje',
|
||||||
|
'Opslaan als': 'Bewarje as',
|
||||||
|
'Pakket importeren': 'Pakket ymportearje',
|
||||||
|
'Pakket exporteren': 'Pakket eksportearje',
|
||||||
|
'Bladeren…': 'Blêdzje…',
|
||||||
|
'Geen map gekozen': 'Gjin map keazen',
|
||||||
|
'Map kiezen': 'Map kieze',
|
||||||
|
'Slide zoeken': 'Slide sykje',
|
||||||
|
'Slides importeren': 'Slides ymportearje',
|
||||||
|
'Importeren': 'Ymportearje',
|
||||||
|
'Klaar': 'Klear',
|
||||||
|
'Toevoegen': 'Tafoegje',
|
||||||
|
'Toegevoegd': 'Tafoege',
|
||||||
|
'Selecteer alles': 'Alles selektearje',
|
||||||
|
'Deselecteer alles': 'Alles deselektearje',
|
||||||
|
'Zoeken en vervangen': 'Sykje en ferfange',
|
||||||
|
'Zoeken naar': 'Sykje nei',
|
||||||
|
'Vervangen door': 'Ferfange troch',
|
||||||
|
'Hoofdlettergevoelig': 'Haadlettergefoelich',
|
||||||
|
'Vervang alles': 'Alles ferfange',
|
||||||
|
'Nieuwe presentatie': 'Nije presintaasje',
|
||||||
|
'Aanmaken': 'Oanmeitsje',
|
||||||
|
'Slide type kiezen': 'Slidetype kieze',
|
||||||
|
'Presentatie-eigenschappen': 'Presintaasje-eigenskippen',
|
||||||
|
'Versie': 'Ferzje',
|
||||||
|
'Organisatie': 'Organisaasje',
|
||||||
|
'Datum': 'Datum',
|
||||||
|
'Beschrijving': 'Beskriuwing',
|
||||||
|
'Trefwoorden': 'Trefwurden',
|
||||||
|
'Profielnaam': 'Profylnamme',
|
||||||
|
'Stijlprofiel': 'Stylprofyl',
|
||||||
|
'Lettertype': 'Lettertype',
|
||||||
|
'Kleuren': 'Kleuren',
|
||||||
|
'Tekst': 'Tekst',
|
||||||
|
'Logo': 'Logo',
|
||||||
|
'Geen logo ingesteld': 'Gjin logo ynsteld',
|
||||||
|
'Logo positie': 'Logoposysje',
|
||||||
|
'Linksboven': 'Loftsboppe',
|
||||||
|
'Rechtsboven': 'Rjochtsboppe',
|
||||||
|
'Linksonder': 'Loftsûnder',
|
||||||
|
'Rechtsonder': 'Rjochtsûnder',
|
||||||
|
'Footertekst': 'Footer-tekst',
|
||||||
|
'Footerpositie': 'Footer-posysje',
|
||||||
|
'Links': 'Lofts',
|
||||||
|
'Midden': 'Midden',
|
||||||
|
'Rechts': 'Rjochts',
|
||||||
|
'Voorvertoning': 'Foarbyld',
|
||||||
|
'Preview': 'Foarbyld',
|
||||||
|
'Uitzoomen': 'Utzoome',
|
||||||
|
'Inzoomen': 'Ynzoome',
|
||||||
|
'Zoom resetten': 'Zoom weromsette',
|
||||||
|
'Vorige slide': 'Foarige slide',
|
||||||
|
'Volgende slide': 'Folgjende slide',
|
||||||
|
'Thema': 'Tema',
|
||||||
|
'Afbeelding kiezen': 'Ofbylding kieze',
|
||||||
|
'Afbeeldingen laden…': 'Ofbyldings lade…',
|
||||||
|
'Sluiten (Esc)': 'Slute (Esc)',
|
||||||
|
'Raster': 'Raster',
|
||||||
|
'Geen afbeeldingen gevonden': 'Gjin ôfbyldings fûn',
|
||||||
|
'Gekopieerd': 'Kopiearre',
|
||||||
|
'Afbeelding verwijderen?': 'Ofbylding fuortsmite?',
|
||||||
|
'Sneltoetsen': 'Fluchtoetsen',
|
||||||
|
'Toetsenlegenda': 'Toetsleginda',
|
||||||
|
'spatie': 'spaasje',
|
||||||
|
'klik': 'klik',
|
||||||
|
'cijfers': 'sifers',
|
||||||
|
'Klik of druk op H / Esc om te sluiten':
|
||||||
|
'Klik of druk op H / Esc om te sluten',
|
||||||
|
'Naar slidenummer': 'Nei slidenûmer',
|
||||||
|
'Eerste · laatste slide': 'Earste · lêste slide',
|
||||||
|
'Slide-overzicht': 'Slide-oersjoch',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Slide-oersjoch (pylken + Enter)',
|
||||||
|
'Presenter view (notities, klok)': 'Presenter view (notysjes, klok)',
|
||||||
|
'Scherm wisselen (meerdere schermen)': 'Skerm wikselje (mear skermen)',
|
||||||
|
'Zwart · wit scherm': 'Swart · wyt skerm',
|
||||||
|
'Verstreken tijd resetten': 'Ferrûne tiid weromsette',
|
||||||
|
'Automatische modus aan/uit': 'Automatyske modus oan/út',
|
||||||
|
'Herhalen (loop) aan/uit': 'Werhelje (loop) oan/út',
|
||||||
|
'Na audio automatisch doorgaan': 'Nei audio automatysk trochgean',
|
||||||
|
'Deze legenda': 'Dizze leginda',
|
||||||
|
'Terug / afsluiten': 'Werom / ôfslute',
|
||||||
|
'HUIDIGE SLIDE': 'AKTUELE SLIDE',
|
||||||
|
'VOLGENDE': 'FOLGJENDE',
|
||||||
|
'NOTITIES': 'NOTYSJES',
|
||||||
|
'Verstreken': 'Ferrûn',
|
||||||
|
'Klok': 'Klok',
|
||||||
|
'Geen notities voor deze slide.': 'Gjin notysjes foar dizze slide.',
|
||||||
|
'Wissel scherm (S)': 'Skerm wikselje (S)',
|
||||||
|
'Kon niet van scherm wisselen.': 'Koe net fan skerm wikselje.',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P publyk · H leginda · G oersjoch · B/W swart/wyt · R tiid · Esc stop',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P publyk · H leginda · S skerm · G oersjoch · B/W swart/wyt · R tiid · Esc stop',
|
||||||
|
},
|
||||||
|
'pap': {
|
||||||
|
'Geen': 'Ningun',
|
||||||
|
'Nieuw': 'Nobo',
|
||||||
|
'Verwijderen': 'Kita',
|
||||||
|
'Herstellen': 'Restorá',
|
||||||
|
'Opslaan en sluiten': 'Warda i sera',
|
||||||
|
'Importeren via URL': 'Importá for di URL',
|
||||||
|
'Ophalen': 'Tuma',
|
||||||
|
'Titelpagina': 'Slide di título',
|
||||||
|
'Tussentitel': 'Título di sekshon',
|
||||||
|
'Alleen Bullets': 'Solamente bullets',
|
||||||
|
'Twee Bulletkolommen': 'Dos kolòm di bullets',
|
||||||
|
'Bullets + Afbeelding': 'Bullets + Imágen',
|
||||||
|
'Twee Afbeeldingen': 'Dos imágen',
|
||||||
|
'Grote Afbeelding': 'Imágen grandi',
|
||||||
|
'Tabel': 'Tabel',
|
||||||
|
'Vrije Markdown': 'Markdown liber',
|
||||||
|
'Overgeslagen': 'Saltá',
|
||||||
|
'Kopiëren': 'Kopia',
|
||||||
|
'Kopieer als afbeelding': 'Kopia komo imágen',
|
||||||
|
'Dupliceren': 'Dupliká',
|
||||||
|
'Niet meer overslaan': 'No salta mas',
|
||||||
|
'Overslaan': 'Salta',
|
||||||
|
'Titel': 'Título',
|
||||||
|
'Titel (optioneel)': 'Título (opshonal)',
|
||||||
|
'Slide titel': 'Título di slide',
|
||||||
|
'Ondertitel': 'Subtítulo',
|
||||||
|
'Optionele subtitel': 'Subtítulo opshonal',
|
||||||
|
'Bullets': 'Bullets',
|
||||||
|
'Bullet toevoegen': 'Añadí bullet',
|
||||||
|
'Verwijder': 'Kita',
|
||||||
|
'Citaat': 'Sitá',
|
||||||
|
'Auteur': 'Outor',
|
||||||
|
'Achtergrondafbeelding': 'Imágen di fondo',
|
||||||
|
'Achtergrondafbeelding (optioneel)': 'Imágen di fondo (opshonal)',
|
||||||
|
'Zoom achtergrond': 'Zoom di fondo',
|
||||||
|
'Zoom afbeelding': 'Zoom di imágen',
|
||||||
|
'Afbeelding (rechts)': 'Imágen (banda drechi)',
|
||||||
|
'Bullets (links)': 'Bullets (banda robes)',
|
||||||
|
'Linker afbeelding': 'Imágen robes',
|
||||||
|
'Rechter afbeelding': 'Imágen drechi',
|
||||||
|
'Audio bij deze slide': 'Audio pa e slide aki',
|
||||||
|
'Audio automatisch afspelen': 'Toka audio outomátiko',
|
||||||
|
'Video automatisch afspelen': 'Toka video outomátiko',
|
||||||
|
'Geen audiobestand gekozen': 'Ningun file di audio skohe',
|
||||||
|
'Geen video gekozen': 'Ningun video skohe',
|
||||||
|
'Kiezen': 'Skohe',
|
||||||
|
'Uit bibliotheek…': 'For di biblioteka…',
|
||||||
|
'Van computer…': 'For di kòmpiuter…',
|
||||||
|
'Geen afbeelding gekozen': 'Ningun imágen skohe',
|
||||||
|
'Caption / bronvermelding': 'Caption / fuente',
|
||||||
|
'Beschrijving (doorzoekbaar)': 'Deskripshon (buskabel)',
|
||||||
|
'Markdown inhoud': 'Kontenido Markdown',
|
||||||
|
'Rij toevoegen': 'Añadí rei',
|
||||||
|
'Kolom toevoegen': 'Añadí kolòm',
|
||||||
|
'Kolom': 'Kolòm',
|
||||||
|
'Presentatie openen': 'Habri presentashon',
|
||||||
|
'Opslaan als': 'Warda komo',
|
||||||
|
'Pakket importeren': 'Importá pakete',
|
||||||
|
'Pakket exporteren': 'Eksportá pakete',
|
||||||
|
'Bladeren…': 'Navegá…',
|
||||||
|
'Geen map gekozen': 'Ningun folder skohe',
|
||||||
|
'Map kiezen': 'Skohe folder',
|
||||||
|
'Slide zoeken': 'Busca slide',
|
||||||
|
'Slides importeren': 'Importá slides',
|
||||||
|
'Importeren': 'Importá',
|
||||||
|
'Klaar': 'Kla',
|
||||||
|
'Toevoegen': 'Añadí',
|
||||||
|
'Toegevoegd': 'Añadí',
|
||||||
|
'Selecteer alles': 'Selektá tur',
|
||||||
|
'Deselecteer alles': 'Deselektá tur',
|
||||||
|
'Zoeken en vervangen': 'Busca i reemplasá',
|
||||||
|
'Zoeken naar': 'Busca',
|
||||||
|
'Vervangen door': 'Reemplasá ku',
|
||||||
|
'Hoofdlettergevoelig': 'Sensitivo pa mayúskula',
|
||||||
|
'Vervang alles': 'Reemplasá tur',
|
||||||
|
'Nieuwe presentatie': 'Presentashon nobo',
|
||||||
|
'Aanmaken': 'Krea',
|
||||||
|
'Slide type kiezen': 'Skohe tipo di slide',
|
||||||
|
'Presentatie-eigenschappen': 'Propiedatnan di presentashon',
|
||||||
|
'Versie': 'Vershon',
|
||||||
|
'Organisatie': 'Organisashon',
|
||||||
|
'Datum': 'Fecha',
|
||||||
|
'Beschrijving': 'Deskripshon',
|
||||||
|
'Trefwoorden': 'Palabranan klave',
|
||||||
|
'Profielnaam': 'Nòmber di perfil',
|
||||||
|
'Stijlprofiel': 'Perfil di estilo',
|
||||||
|
'Lettertype': 'Font',
|
||||||
|
'Kleuren': 'Kolónan',
|
||||||
|
'Tekst': 'Teksto',
|
||||||
|
'Logo': 'Logo',
|
||||||
|
'Geen logo ingesteld': 'Ningun logo konfigurá',
|
||||||
|
'Logo positie': 'Posishon di logo',
|
||||||
|
'Linksboven': 'Ariba robes',
|
||||||
|
'Rechtsboven': 'Ariba drechi',
|
||||||
|
'Linksonder': 'Abou robes',
|
||||||
|
'Rechtsonder': 'Abou drechi',
|
||||||
|
'Footertekst': 'Teksto di footer',
|
||||||
|
'Footerpositie': 'Posishon di footer',
|
||||||
|
'Links': 'Robes',
|
||||||
|
'Midden': 'Meimei',
|
||||||
|
'Rechts': 'Drechi',
|
||||||
|
'Voorvertoning': 'Preview',
|
||||||
|
'Preview': 'Preview',
|
||||||
|
'Uitzoomen': 'Zoom out',
|
||||||
|
'Inzoomen': 'Zoom in',
|
||||||
|
'Zoom resetten': 'Reset zoom',
|
||||||
|
'Vorige slide': 'Slide anterior',
|
||||||
|
'Volgende slide': 'Siguiente slide',
|
||||||
|
'Thema': 'Tema',
|
||||||
|
'Afbeelding kiezen': 'Skohe imágen',
|
||||||
|
'Afbeeldingen laden…': 'Kargando imágennan…',
|
||||||
|
'Sluiten (Esc)': 'Sera (Esc)',
|
||||||
|
'Raster': 'Grid',
|
||||||
|
'Geen afbeeldingen gevonden': 'No a haña imágen',
|
||||||
|
'Gekopieerd': 'Kopiá',
|
||||||
|
'Afbeelding verwijderen?': 'Kita imágen?',
|
||||||
|
'Sneltoetsen': 'Atahonan di tekla',
|
||||||
|
'Toetsenlegenda': 'Legenda di tekla',
|
||||||
|
'spatie': 'spasio',
|
||||||
|
'klik': 'klik',
|
||||||
|
'cijfers': 'numbernan',
|
||||||
|
'Klik of druk op H / Esc om te sluiten': 'Klik òf primi H / Esc pa sera',
|
||||||
|
'Naar slidenummer': 'Bai na number di slide',
|
||||||
|
'Eerste · laatste slide': 'Promé · último slide',
|
||||||
|
'Slide-overzicht': 'Resumen di slides',
|
||||||
|
'Slide-overzicht (pijltjes + Enter)': 'Resumen di slides (flecha + Enter)',
|
||||||
|
'Presenter view (notities, klok)': 'Presenter view (notanan, oloshi)',
|
||||||
|
'Scherm wisselen (meerdere schermen)': 'Kambia pantalla (mas pantalla)',
|
||||||
|
'Zwart · wit scherm': 'Pantalla pretu · blanku',
|
||||||
|
'Verstreken tijd resetten': 'Reset tempu transkurí',
|
||||||
|
'Automatische modus aan/uit': 'Modo outomátiko on/off',
|
||||||
|
'Herhalen (loop) aan/uit': 'Ripití (loop) on/off',
|
||||||
|
'Na audio automatisch doorgaan': 'Sigui outomátiko despues di audio',
|
||||||
|
'Deze legenda': 'E legenda aki',
|
||||||
|
'Terug / afsluiten': 'Bèk / sali',
|
||||||
|
'HUIDIGE SLIDE': 'SLIDE AKTUAL',
|
||||||
|
'VOLGENDE': 'SIGUIENTE',
|
||||||
|
'NOTITIES': 'NOTANAN',
|
||||||
|
'Verstreken': 'Transkurí',
|
||||||
|
'Klok': 'Oloshi',
|
||||||
|
'Geen notities voor deze slide.': 'No tin nota pa e slide aki.',
|
||||||
|
'Wissel scherm (S)': 'Kambia pantalla (S)',
|
||||||
|
'Kon niet van scherm wisselen.': 'No por a kambia pantalla.',
|
||||||
|
'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P públiko · H legenda · G resumen · B/W pretu/blanku · R tempu · Esc stop',
|
||||||
|
'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop':
|
||||||
|
'P públiko · H legenda · S pantalla · G resumen · B/W pretu/blanku · R tempu · Esc stop',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1184,13 +1184,6 @@ class _MainLayoutState extends ConsumerState<_MainLayout> {
|
||||||
onPressed: saveDeck,
|
onPressed: saveDeck,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tooltip(
|
|
||||||
message: exportTooltip,
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(Icons.upload_file_outlined, size: 18),
|
|
||||||
onPressed: canExport ? exportDeck : null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const _ActionsDivider(),
|
const _ActionsDivider(),
|
||||||
// ── Overig (minder vaak gebruikt) ───────────────────────────
|
// ── Overig (minder vaak gebruikt) ───────────────────────────
|
||||||
PopupMenuButton<String>(
|
PopupMenuButton<String>(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:screen_retriever/screen_retriever.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
import '../../models/deck.dart';
|
import '../../models/deck.dart';
|
||||||
import '../../models/settings.dart';
|
import '../../models/settings.dart';
|
||||||
|
|
@ -107,6 +108,12 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
/// Met M te wisselen.
|
/// Met M te wisselen.
|
||||||
bool _advanceOnAudioEnd = true;
|
bool _advanceOnAudioEnd = true;
|
||||||
|
|
||||||
|
/// Known displays for moving the fullscreen presentation window. This is not
|
||||||
|
/// a second presenter window; it keeps the current output movable between
|
||||||
|
/// screens with S or the presenter-view button.
|
||||||
|
List<Display> _displays = const [];
|
||||||
|
int _displayIndex = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
@ -119,6 +126,7 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
});
|
});
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_focusNode.requestFocus();
|
_focusNode.requestFocus();
|
||||||
|
_loadDisplays();
|
||||||
_scheduleAdvance();
|
_scheduleAdvance();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -209,6 +217,55 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
_scheduleAdvance();
|
_scheduleAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _loadDisplays() async {
|
||||||
|
try {
|
||||||
|
final displays = await screenRetriever.getAllDisplays();
|
||||||
|
if (!mounted || displays.isEmpty) return;
|
||||||
|
final bounds = await windowManager.getBounds();
|
||||||
|
final center = bounds.center;
|
||||||
|
final current = displays.indexWhere((d) {
|
||||||
|
final p = d.visiblePosition ?? Offset.zero;
|
||||||
|
final s = d.visibleSize ?? d.size;
|
||||||
|
return Rect.fromLTWH(p.dx, p.dy, s.width, s.height).contains(center);
|
||||||
|
});
|
||||||
|
setState(() {
|
||||||
|
_displays = displays;
|
||||||
|
_displayIndex = current < 0 ? 0 : current;
|
||||||
|
});
|
||||||
|
} catch (_) {
|
||||||
|
// Screen detection is best-effort; presenting should still work.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _moveToDisplay(int index) async {
|
||||||
|
if (_displays.length < 2) return;
|
||||||
|
final display = _displays[index.clamp(0, _displays.length - 1)];
|
||||||
|
final position = display.visiblePosition ?? Offset.zero;
|
||||||
|
final size = display.visibleSize ?? display.size;
|
||||||
|
try {
|
||||||
|
await windowManager.setFullScreen(false);
|
||||||
|
await windowManager.setBounds(
|
||||||
|
Rect.fromLTWH(position.dx, position.dy, size.width, size.height),
|
||||||
|
);
|
||||||
|
await windowManager.setFullScreen(true);
|
||||||
|
if (mounted) setState(() => _displayIndex = index);
|
||||||
|
} catch (_) {
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(context.l10n.d('Kon niet van scherm wisselen.')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _cycleDisplay() async {
|
||||||
|
if (_displays.isEmpty) await _loadDisplays();
|
||||||
|
if (_displays.length < 2) return;
|
||||||
|
await _moveToDisplay((_displayIndex + 1) % _displays.length);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _exit() async {
|
Future<void> _exit() async {
|
||||||
_advanceTimer?.cancel();
|
_advanceTimer?.cancel();
|
||||||
await windowManager.setFullScreen(false);
|
await windowManager.setFullScreen(false);
|
||||||
|
|
@ -452,6 +509,9 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
case LogicalKeyboardKey.keyM:
|
case LogicalKeyboardKey.keyM:
|
||||||
_toggleAudioAdvance();
|
_toggleAudioAdvance();
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
|
case LogicalKeyboardKey.keyS:
|
||||||
|
_cycleDisplay();
|
||||||
|
return KeyEventResult.handled;
|
||||||
case LogicalKeyboardKey.escape:
|
case LogicalKeyboardKey.escape:
|
||||||
// Gelaagd: getypt nummer wissen, dan blanco scherm, dan pas afsluiten.
|
// Gelaagd: getypt nummer wissen, dan blanco scherm, dan pas afsluiten.
|
||||||
if (_typed.isNotEmpty) {
|
if (_typed.isNotEmpty) {
|
||||||
|
|
@ -587,12 +647,13 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
('Home · End', l10n.d('Eerste · laatste slide')),
|
('Home · End', l10n.d('Eerste · laatste slide')),
|
||||||
('G', l10n.d('Slide-overzicht (pijltjes + Enter)')),
|
('G', l10n.d('Slide-overzicht (pijltjes + Enter)')),
|
||||||
('P', l10n.d('Presenter view (notities, klok)')),
|
('P', l10n.d('Presenter view (notities, klok)')),
|
||||||
|
('S', l10n.d('Scherm wisselen (meerdere schermen)')),
|
||||||
('B · W', l10n.d('Zwart · wit scherm')),
|
('B · W', l10n.d('Zwart · wit scherm')),
|
||||||
('R', l10n.d('Verstreken tijd resetten')),
|
('R', l10n.d('Verstreken tijd resetten')),
|
||||||
('A', l10n.d('Automatische modus aan/uit')),
|
('A', l10n.d('Automatische modus aan/uit')),
|
||||||
('L', l10n.d('Herhalen (loop) aan/uit')),
|
('L', l10n.d('Herhalen (loop) aan/uit')),
|
||||||
('M', l10n.d('Na audio automatisch doorgaan')),
|
('M', l10n.d('Na audio automatisch doorgaan')),
|
||||||
('? · H', l10n.d('Dit overzicht')),
|
('H', l10n.d('Deze legenda')),
|
||||||
('Esc', l10n.d('Terug / afsluiten')),
|
('Esc', l10n.d('Terug / afsluiten')),
|
||||||
];
|
];
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
|
@ -627,7 +688,7 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
l10n.d('Sneltoetsen'),
|
l10n.d('Toetsenlegenda'),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
|
@ -668,7 +729,7 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.d('Klik of druk op ? / H / Esc om te sluiten'),
|
l10n.d('Klik of druk op H / Esc om te sluiten'),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white30,
|
color: Colors.white30,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|
@ -684,44 +745,6 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtiele statusindicator (linksonder) voor de automatische modus. Toont
|
|
||||||
/// of auto-play, herhalen en 'na audio doorgaan' actief zijn.
|
|
||||||
Widget _autoPlayStatus() {
|
|
||||||
final l10n = context.l10n;
|
|
||||||
final items = <(IconData, String, bool)>[
|
|
||||||
(
|
|
||||||
_autoPlay ? Icons.play_circle_outline : Icons.pause_circle_outline,
|
|
||||||
_autoPlay ? l10n.d('Auto (A)') : l10n.d('Handmatig (A)'),
|
|
||||||
_autoPlay,
|
|
||||||
),
|
|
||||||
(Icons.repeat, l10n.d('Herhalen (L)'), _loop),
|
|
||||||
(Icons.graphic_eq, l10n.d('Na audio (M)'), _advanceOnAudioEnd),
|
|
||||||
];
|
|
||||||
return Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
for (final (icon, label, active) in items)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 12),
|
|
||||||
child: Opacity(
|
|
||||||
opacity: active ? 0.7 : 0.28,
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(icon, size: 14, color: Colors.white),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 11),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Vol-vlak zwart/wit scherm dat met een klik weer verdwijnt.
|
/// Vol-vlak zwart/wit scherm dat met een klik weer verdwijnt.
|
||||||
Widget _blankFill() {
|
Widget _blankFill() {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
|
@ -783,148 +806,7 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: _next,
|
onTap: _next,
|
||||||
onSecondaryTap: _prev,
|
onSecondaryTap: _prev,
|
||||||
child: Stack(
|
child: SizedBox.expand(child: _slideCanvas(slide)),
|
||||||
children: [
|
|
||||||
// ── Slide canvas ─────────────────────────────────────────────────
|
|
||||||
Positioned.fill(child: _slideCanvas(slide)),
|
|
||||||
|
|
||||||
// ── Voortgangsbalk (auto-advance) ────────────────────────────────
|
|
||||||
if (_progress > 0)
|
|
||||||
Positioned(
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
child: LinearProgressIndicator(
|
|
||||||
value: _progress,
|
|
||||||
backgroundColor: Colors.white12,
|
|
||||||
color: Colors.white54,
|
|
||||||
minHeight: 3,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// ── Slide counter ────────────────────────────────────────────────
|
|
||||||
Positioned(
|
|
||||||
right: 24,
|
|
||||||
bottom: 10,
|
|
||||||
child: Text(
|
|
||||||
'${_index + 1} / $total',
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Colors.white38,
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// ── Auto-play status (linksonder) ────────────────────────────────
|
|
||||||
Positioned(left: 24, bottom: 10, child: _autoPlayStatus()),
|
|
||||||
|
|
||||||
// ── Navigation arrows ────────────────────────────────────────────
|
|
||||||
Positioned(
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
child: MouseRegion(
|
|
||||||
cursor: _index > 0 ? SystemMouseCursors.click : MouseCursor.defer,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: _prev,
|
|
||||||
child: Container(
|
|
||||||
width: 60,
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: _index > 0
|
|
||||||
? const Icon(
|
|
||||||
Icons.chevron_left,
|
|
||||||
color: Colors.white24,
|
|
||||||
size: 40,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
right: 0,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
child: MouseRegion(
|
|
||||||
cursor: _index < total - 1
|
|
||||||
? SystemMouseCursors.click
|
|
||||||
: MouseCursor.defer,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: _next,
|
|
||||||
child: Container(
|
|
||||||
width: 60,
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: _index < total - 1
|
|
||||||
? const Icon(
|
|
||||||
Icons.chevron_right,
|
|
||||||
color: Colors.white24,
|
|
||||||
size: 40,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
// ── Top-right controls (presenter view + afsluiten) ──────────────
|
|
||||||
Positioned(
|
|
||||||
top: 16,
|
|
||||||
right: 16,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Tooltip(
|
|
||||||
message: context.l10n.d('Sneltoetsen (?)'),
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: _toggleHelp,
|
|
||||||
icon: const Icon(Icons.help_outline),
|
|
||||||
color: Colors.white,
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
backgroundColor: Colors.black45,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Tooltip(
|
|
||||||
message: context.l10n.d('Slide-overzicht (G)'),
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: _toggleGrid,
|
|
||||||
icon: const Icon(Icons.grid_view_rounded),
|
|
||||||
color: Colors.white,
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
backgroundColor: Colors.black45,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Tooltip(
|
|
||||||
message: context.l10n.d('Presenter view (P)'),
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: _togglePresenterView,
|
|
||||||
icon: const Icon(Icons.co_present_outlined),
|
|
||||||
color: Colors.white,
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
backgroundColor: Colors.black45,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Tooltip(
|
|
||||||
message: context.l10n.d('Afsluiten (Escape)'),
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: _exit,
|
|
||||||
icon: const Icon(Icons.close),
|
|
||||||
color: Colors.white,
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
backgroundColor: Colors.black45,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1151,6 +1033,16 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
icon: Icons.chevron_right,
|
icon: Icons.chevron_right,
|
||||||
onTap: _index < total - 1 ? _next : null,
|
onTap: _index < total - 1 ? _next : null,
|
||||||
),
|
),
|
||||||
|
if (_displays.length > 1) ...[
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Tooltip(
|
||||||
|
message: l10n.d('Wissel scherm (S)'),
|
||||||
|
child: _NavButton(
|
||||||
|
icon: Icons.screen_share_outlined,
|
||||||
|
onTap: _cycleDisplay,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
Text(
|
Text(
|
||||||
'${l10n.d('Slide')} ${_index + 1} / $total',
|
'${l10n.d('Slide')} ${_index + 1} / $total',
|
||||||
|
|
@ -1164,7 +1056,9 @@ class _FullscreenPresenterState extends State<FullscreenPresenter> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.d(
|
l10n.d(
|
||||||
'P publiek · G overzicht · B/W zwart/wit · R tijd · Esc stop',
|
_displays.length > 1
|
||||||
|
? 'P publiek · H legenda · S scherm · G overzicht · B/W zwart/wit · R tijd · Esc stop'
|
||||||
|
: 'P publiek · H legenda · G overzicht · B/W zwart/wit · R tijd · Esc stop',
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
|
|
|
||||||
|
|
@ -654,7 +654,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.1"
|
version: "3.2.1"
|
||||||
screen_retriever:
|
screen_retriever:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: screen_retriever
|
name: screen_retriever
|
||||||
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ dependencies:
|
||||||
path_provider: ^2.1.5
|
path_provider: ^2.1.5
|
||||||
path: ^1.9.1
|
path: ^1.9.1
|
||||||
uuid: ^4.5.1
|
uuid: ^4.5.1
|
||||||
|
screen_retriever: ^0.2.0
|
||||||
window_manager: ^0.5.1
|
window_manager: ^0.5.1
|
||||||
shared_preferences: ^2.3.3
|
shared_preferences: ^2.3.3
|
||||||
pasteboard: ^0.5.0
|
pasteboard: ^0.5.0
|
||||||
|
|
|
||||||
35
test/app_localizations_test.dart
Normal file
35
test/app_localizations_test.dart
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:ocideck/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
tearDown(() => AppLocalizations.setActiveLanguageCode('nl'));
|
||||||
|
|
||||||
|
test('supports Frisian and Papiamento language choices', () {
|
||||||
|
expect(AppLocalizations.languageNames['fy'], 'Frysk');
|
||||||
|
expect(AppLocalizations.languageNames['pap'], 'Papiamento');
|
||||||
|
expect(AppLocalizations.supportedLocales, contains(const Locale('fy')));
|
||||||
|
expect(AppLocalizations.supportedLocales, contains(const Locale('pap')));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('uses app translations while Material falls back safely', () {
|
||||||
|
AppLocalizations.setActiveLanguageCode('fy');
|
||||||
|
expect(const AppLocalizations(Locale('en')).t('settings'), 'Ynstellingen');
|
||||||
|
expect(
|
||||||
|
const AppLocalizations(Locale('en')).d('Toetsenlegenda'),
|
||||||
|
'Toetsleginda',
|
||||||
|
);
|
||||||
|
expect(AppLocalizations.materialLocaleFor('fy'), const Locale('en'));
|
||||||
|
|
||||||
|
AppLocalizations.setActiveLanguageCode('pap');
|
||||||
|
expect(
|
||||||
|
const AppLocalizations(Locale('en')).t('settings'),
|
||||||
|
'Preferensianan',
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
const AppLocalizations(Locale('en')).d('Toetsenlegenda'),
|
||||||
|
'Legenda di tekla',
|
||||||
|
);
|
||||||
|
expect(AppLocalizations.materialLocaleFor('pap'), const Locale('en'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -29,9 +29,9 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('free Markdown renders display math', (tester) async {
|
testWidgets('free Markdown renders display math', (tester) async {
|
||||||
final slide = Slide.create(SlideType.freeMarkdown).copyWith(
|
final slide = Slide.create(
|
||||||
customMarkdown: 'Stelling:\n\n\$\$E = mc^2\$\$\n',
|
SlideType.freeMarkdown,
|
||||||
);
|
).copyWith(customMarkdown: 'Stelling:\n\n\$\$E = mc^2\$\$\n');
|
||||||
await tester.pumpWidget(_host(slide));
|
await tester.pumpWidget(_host(slide));
|
||||||
|
|
||||||
expect(find.byType(Math), findsOneWidget);
|
expect(find.byType(Math), findsOneWidget);
|
||||||
|
|
@ -40,9 +40,9 @@ void main() {
|
||||||
testWidgets('an unknown code language falls back without throwing', (
|
testWidgets('an unknown code language falls back without throwing', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
final slide = Slide.create(SlideType.freeMarkdown).copyWith(
|
final slide = Slide.create(
|
||||||
customMarkdown: '```nonexistentlang\nsome code\n```\n',
|
SlideType.freeMarkdown,
|
||||||
);
|
).copyWith(customMarkdown: '```nonexistentlang\nsome code\n```\n');
|
||||||
await tester.pumpWidget(_host(slide));
|
await tester.pumpWidget(_host(slide));
|
||||||
|
|
||||||
// No HighlightView (unknown language) and no exception during build.
|
// No HighlightView (unknown language) and no exception during build.
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,12 @@ void main() {
|
||||||
await tester.pumpWidget(_host(slides));
|
await tester.pumpWidget(_host(slides));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(find.text('1 / 2'), findsOneWidget); // slide counter
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
expect(find.text('1 / 2'), findsNothing); // no audience chrome
|
||||||
|
expect(find.byIcon(Icons.help_outline), findsNothing);
|
||||||
|
expect(find.byIcon(Icons.grid_view_rounded), findsNothing);
|
||||||
|
expect(find.byIcon(Icons.co_present_outlined), findsNothing);
|
||||||
|
expect(find.byIcon(Icons.close), findsNothing);
|
||||||
expect(find.text('NOTITIES'), findsNothing); // presenter-only
|
expect(find.text('NOTITIES'), findsNothing); // presenter-only
|
||||||
expect(find.text('VOLGENDE'), findsNothing);
|
expect(find.text('VOLGENDE'), findsNothing);
|
||||||
|
|
||||||
|
|
@ -88,17 +93,17 @@ void main() {
|
||||||
testWidgets('B blanks the audience screen and toggles back', (tester) async {
|
testWidgets('B blanks the audience screen and toggles back', (tester) async {
|
||||||
await tester.pumpWidget(_host(slides));
|
await tester.pumpWidget(_host(slides));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
// Blank to black: the slide (and its counter) disappears.
|
// Blank to black: the slide disappears.
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsNothing);
|
expect(find.text('Eerste'), findsNothing);
|
||||||
|
|
||||||
// Same key restores the slide.
|
// Same key restores the slide.
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -111,12 +116,12 @@ void main() {
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyB);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsNothing);
|
expect(find.text('Eerste'), findsNothing);
|
||||||
|
|
||||||
// First arrow un-blanks without advancing (still on slide 1).
|
// First arrow un-blanks without advancing (still on slide 1).
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -142,7 +147,7 @@ void main() {
|
||||||
|
|
||||||
// Grid closed and we jumped to slide 2.
|
// Grid closed and we jumped to slide 2.
|
||||||
expect(find.text('Slide-overzicht'), findsNothing);
|
expect(find.text('Slide-overzicht'), findsNothing);
|
||||||
expect(find.text('2 / 2'), findsOneWidget);
|
expect(find.text('Tweede'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -152,15 +157,15 @@ void main() {
|
||||||
) async {
|
) async {
|
||||||
await tester.pumpWidget(_host(slides));
|
await tester.pumpWidget(_host(slides));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.end);
|
await tester.sendKeyEvent(LogicalKeyboardKey.end);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('2 / 2'), findsOneWidget);
|
expect(find.text('Tweede'), findsOneWidget);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.home);
|
await tester.sendKeyEvent(LogicalKeyboardKey.home);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -187,7 +192,7 @@ void main() {
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
expect(find.text('Slide-overzicht'), findsNothing);
|
expect(find.text('Slide-overzicht'), findsNothing);
|
||||||
expect(find.text('2 / 2'), findsOneWidget);
|
expect(find.text('Tweede'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -199,7 +204,7 @@ void main() {
|
||||||
];
|
];
|
||||||
await tester.pumpWidget(_host(three));
|
await tester.pumpWidget(_host(three));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('1 / 3'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
// Type "3" → a badge appears, Enter jumps to slide 3.
|
// Type "3" → a badge appears, Enter jumps to slide 3.
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.digit3);
|
await tester.sendKeyEvent(LogicalKeyboardKey.digit3);
|
||||||
|
|
@ -208,8 +213,9 @@ void main() {
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
|
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
// Badge gone, now actually on slide 3 (counter shows it).
|
// Badge gone, now actually on slide 3.
|
||||||
expect(find.text('3 / 3'), findsOneWidget); // slide counter now
|
expect(find.text('Derde'), findsOneWidget);
|
||||||
|
expect(find.text('3 / 3'), findsNothing);
|
||||||
expect(find.byIcon(Icons.south_east), findsNothing); // badge icon gone
|
expect(find.byIcon(Icons.south_east), findsNothing); // badge icon gone
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
|
|
@ -218,17 +224,18 @@ void main() {
|
||||||
testWidgets('? toggles the shortcut cheatsheet', (tester) async {
|
testWidgets('? toggles the shortcut cheatsheet', (tester) async {
|
||||||
await tester.pumpWidget(_host(slides));
|
await tester.pumpWidget(_host(slides));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Sneltoetsen'), findsNothing);
|
expect(find.text('Toetsenlegenda'), findsNothing);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.keyH);
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyH);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Sneltoetsen'), findsOneWidget);
|
expect(find.text('Toetsenlegenda'), findsOneWidget);
|
||||||
|
expect(find.text('Scherm wisselen (meerdere schermen)'), findsOneWidget);
|
||||||
|
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Sneltoetsen'), findsNothing);
|
expect(find.text('Toetsenlegenda'), findsNothing);
|
||||||
// Esc closed the help, not the presentation.
|
// Esc closed the help, not the presentation.
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
@ -250,7 +257,7 @@ void main() {
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('Slide-overzicht'), findsNothing);
|
expect(find.text('Slide-overzicht'), findsNothing);
|
||||||
expect(find.text('1 / 2'), findsOneWidget);
|
expect(find.text('Eerste'), findsOneWidget);
|
||||||
|
|
||||||
await tester.pumpWidget(const SizedBox());
|
await tester.pumpWidget(const SizedBox());
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue