From 6d5ff9ac922f833883a388da0d3c2c528ee60813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20Vassb=C3=B8?= Date: Fri, 28 Jun 2024 14:14:24 +0200 Subject: [PATCH] v1.1.9 (#620) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 📝 Updated playwright * ✔ Fixed freeze when adding new action and media tab was open - Fixed slide background showing when clear action was set - Fixed update popup in prerelease - Better shows loading - Fixed shows not loading when loading many - Fixed thumbnails not generating after failed attempts * ✨ Optimizations - Lessons.church updates - Fixed main screen showing in output window - Added main loading - Fixed Windows maximized state - Fixed thumbnails not generating if video is not ready - Fixed some thumbnails getting corrupted - Fixed slide title zoom - Slide background loop indicator * 🚩 Added Dutch language - Updated Italian * ✨ Improved transitions - Better export - Audio will not start if error - Fixed VideoPsalm issue - Open Cache folder button - Fixed capitalize with special chars first - Fixed output paint freeze - New version --- .github/workflows/playwright.yml | 6 +- package.json | 2 +- public/lang/en.json | 1 + public/lang/it.json | 52 +- public/lang/nl.json | 1115 +++++++++++++++++ src/electron/data/export.ts | 40 +- src/electron/data/thumbnails.ts | 148 +-- src/electron/index.ts | 2 +- src/electron/preload.ts | 2 +- src/electron/utils/responses.ts | 3 +- src/frontend/App.svelte | 26 +- src/frontend/components/actions/actions.ts | 4 + src/frontend/components/context/menuClick.ts | 6 +- src/frontend/components/draw/Paint.svelte | 2 +- src/frontend/components/draw/Slide.svelte | 2 +- .../components/drawer/bible/Scripture.svelte | 1 - .../components/drawer/bible/scripture.ts | 9 + .../components/drawer/live/NDIStreams.svelte | 2 +- .../components/drawer/live/Screens.svelte | 2 +- .../components/drawer/live/Windows.svelte | 2 +- .../components/drawer/media/Media.svelte | 2 +- .../drawer/media/MediaLoader.svelte | 23 +- .../components/drawer/timers/timers.ts | 49 +- .../components/edit/MediaTools.svelte | 2 +- .../edit/editors/SlideEditor.svelte | 3 +- src/frontend/components/helpers/T.svelte | 48 +- src/frontend/components/helpers/array.ts | 2 +- src/frontend/components/helpers/audio.ts | 15 +- .../components/helpers/historyActions.ts | 105 +- src/frontend/components/helpers/media.ts | 53 +- src/frontend/components/helpers/output.ts | 14 +- src/frontend/components/helpers/setShow.ts | 1 + .../components/helpers/showActions.ts | 24 +- src/frontend/components/helpers/timerTick.ts | 32 +- .../components/inputs/ShowButton.svelte | 2 +- src/frontend/components/main/Loader.svelte | 6 +- .../components/main/popups/Export.svelte | 42 +- .../components/main/popups/NextTimer.svelte | 2 +- src/frontend/components/output/clear.ts | 9 +- .../output/layers/SlideContent.svelte | 98 +- .../components/settings/tabs/Other.svelte | 8 +- src/frontend/components/show/Slides.svelte | 62 +- .../components/show/tools/Media.svelte | 18 +- src/frontend/components/slide/Icons.svelte | 38 +- .../components/slide/Reference.svelte | 42 +- src/frontend/components/slide/Slide.svelte | 19 +- .../components/slide/views/Timer.svelte | 3 +- src/frontend/components/system/Center.svelte | 3 +- src/frontend/converters/lessonsChurch.ts | 11 +- src/frontend/converters/videopsalm.ts | 37 +- src/frontend/stores.ts | 18 +- src/frontend/utils/checkForUpdates.ts | 23 +- src/frontend/utils/common.ts | 2 + src/frontend/utils/languageData.ts | 4 +- src/frontend/utils/receivers.ts | 2 +- src/frontend/utils/save.ts | 5 +- src/frontend/utils/startup.ts | 4 +- src/frontend/utils/updateSettings.ts | 16 +- src/frontend/values/icons.ts | 2 + 59 files changed, 1775 insertions(+), 501 deletions(-) create mode 100644 public/lang/nl.json diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 9b3796a8..ffe5aa75 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,9 +1,9 @@ name: Playwright Tests on: push: - branches: [main, dev] + branches: [dev] pull_request: - branches: [main, dev] + branches: [dev] workflow_dispatch: jobs: @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@master with: - node-version: 18 + node-version: 20 - name: Install dependencies run: npm install - name: Install Playwright Browsers diff --git a/package.json b/package.json index 903bee3b..3f3856ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "freeshow", - "version": "1.1.8", + "version": "1.1.9", "private": true, "main": "build/electron/index.js", "description": "Show song lyrics and more for free!", diff --git a/public/lang/en.json b/public/lang/en.json index 6f94fe79..7f1356ae 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -540,6 +540,7 @@ "delete_shows_not_indexed": "Delete shows in 'Shows' folder that are not indexed", "delete_thumbnail_cache": "Delete thumbnail cache", "open_log_file": "Open log file", + "open_cache_folder": "Open cache folder", "refresh_all_shows": "Get all shows in 'Shows' folder", "start_timer": "Start timer", "stop_timers": "Stop active timers", diff --git a/public/lang/it.json b/public/lang/it.json index 9e2ca20f..0276d4e5 100644 --- a/public/lang/it.json +++ b/public/lang/it.json @@ -159,6 +159,13 @@ "online": "Online", "recommended": "Raccomandato" }, + "audio": { + "metronome": "Metronomo", + "toggle_metronome": "Attiva metronomo", + "tempo": "Tempo", + "bpm": "BPM", + "beats": "Battiti" + }, "menu": { "show": "Mostra", "_title_show": "Mostrare", @@ -314,6 +321,8 @@ "current": "Corrente", "global": "Globale", "toggle_global_group": "Attiva/disattiva i gruppi globali", + "group_shortcut": "Scorciatoia del gruppo", + "group_template": "Modello del gruppo", "intro": "Introduzione", "verse": "Versetto", "pre_chorus": "Pre Ritornello", @@ -361,7 +370,7 @@ "manage_colors": "Gestisci i colori", "choose_camera": "Scegli camera", "initialize": "Benvenuto su FreeShow", - "unsaved": "Non hai ancora salvato! Sei sicuro di voler uscire?", + "unsaved": "Sei sicuro di voler uscire?", "cancel": "Cancella", "continue": "Continua", "reset_all": "Ripristina tutto", @@ -387,7 +396,7 @@ "no_name": "Nessun nome", "media_replaced": "Missing media file replaced with match.", "lyrics_undefined": "Impossibile trovare alcun testo!", - "lyrics_copied": "Testi copiati da ", + "lyrics_copied": "Testi copiati da", "no_pdf_linux": "Impossibile esportare come PDF su Linux.", "one_output": "Devi avere almeno un output attivo!", "empty_cache": "La cache è vuota.", @@ -431,7 +440,11 @@ "lyrics": "Vista testi brani", "text": "Modifica testo", "update": "Aggiorna scena", - "slide_template": "Modello di diapositiva" + "slide_template": "Modello di diapositiva", + "search_results": "Risultati della ricerca", + "source": "Sorgente", + "artist": "Artista", + "song": "Canzone" }, "actions": { "rename": "Rinomina", @@ -514,6 +527,7 @@ "change_drawer_category": "Cambia categoria del cassetto", "toggle_drawer": "Attiva cassetto", "slide_actions": "Azioni diapositiva", + "item_actions": "Azioni degli elementi", "clear_history": "Pulisci cronologia", "set_key": "Imposta chiave", "custom_key": "Imposta valore personalizzato", @@ -531,12 +545,12 @@ "remove_layers": "Rimuovi livelli", "start_recording": "Inizia a registrare", "stop_recording": "Ferma registrazione", - "activate_on_startup": "Attiva all'avvio", "index_select_project": "Seleziona progetto per indice", "next_project_item": "Elemento successivo del progetto", "previous_project_item": "Elemento del progetto precedente", "index_select_project_item": "Seleziona l'elemento del progetto in base all'indice", "name_select_show": "Seleziona spettacolo per nome", + "random_slide": "Riproduci diapositive casuali", "index_select_slide": "Seleziona la diapositiva per indice", "name_select_slide": "Seleziona la diapositiva per nome", "toggle_output_lock": "Attiva/disattiva il blocco dell'uscita", @@ -547,13 +561,21 @@ "name_select_overlay": "Seleziona la sovrapposizione per nome", "change_volume": "Modifica volume", "start_audio_stream": "Avvia il flusso audio", + "start_playlist": "Avvia la playlist", + "start_metronome": "Avvia il metronomo", "start_slide_timers": "Avvia i timer sulla diapositiva attiva", "id_select_output_style": "Seleziona lo stile di output in base all'ID", "change_output_style": "Cambia stile di output", "change_transition": "Cambia transizione", "change_variable": "Cambia variabile", "start_trigger": "Avvia trigger", - "run_action": "Esegui l'azione" + "run_action": "Esegui l'azione", + "custom_activation": "Attivazione personalizzata", + "activate_on_startup": "Attiva all'avvio", + "activate_save": "Attiva durante il salvataggio", + "activate_slide_clicked": "Attiva al clic della diapositiva", + "activate_scripture_start": "Attiva quando viene avviata la scrittura", + "activate_show_created": "Attiva quando viene creato lo spettacolo" }, "animate": { "change": "cambia", @@ -619,6 +641,7 @@ "createNew": "Crea nuovo", "selectAll": "Seleziona tutto", "force_outputs": "Forza output", + "align_with_screen": "Allineare con lo schermo", "toggle_output": "Attiva/disattiva output", "move_to_front": "Muovi in avanti", "lock_to_output": "Blocca sull'output", @@ -656,6 +679,9 @@ "background_color": "Colore di sfondo", "background_opacity": "Opacità dello sfondo", "background_image": "Immagine di sfondo", + "background_media": "Supporti di sfondo", + "overlay_content": "Aggiungi contenuto in sovrapposizione", + "different_first_template": "Modello personalizzato sulla prima diapositiva", "media_fit": "Adatta media", "size": "Dimensione", "chords": "Accordi", @@ -845,7 +871,9 @@ "font-size": "Dimensione font", "zeros": "Zero", "overrun": "Colore in eccesso", - "auto_stretch": "Estensione automatica dei contenuti" + "source_output": "Sorgente di uscita", + "auto_stretch": "Estensione automatica dei contenuti", + "labels": "Mostra etichette" }, "settings": { "general": "Generale", @@ -857,6 +885,8 @@ "connection": "Connessione", "cloud": "Cloud", "calendar": "Calendario", + "text_import": "Testo", + "media_import": "Media", "other": "Altro", "language": "Lingua", "autosave": "Salvataggio automatico", @@ -871,6 +901,7 @@ "select_display": "Fare clic sullo schermo in cui non si desidera visualizzare la finestra di output.", "manual_input_hint": "Non riesci a trovare il display? Fare clic qui per modificare manualmente la posizione.", "manual_drag_hint": "Puoi anche tenere premuto ctrl/cmd su una finestra di output attiva per trascinarla manualmente.", + "allow_main_screen": "Consenti l'output sulla schermata principale", "identify_screens": "Identificare gli schermi", "new_output": "Nuovo output", "enable_key_output": "Abilita l'output della chiave alfa", @@ -882,7 +913,8 @@ "color_when_active": "Colore quando attivo", "fixed": "Corretto", "lines": "Linee", - "override_with_template": "Sovrascrivi stile con modello", + "override_with_template": "Sostituisci la diapositiva con il modello", + "override_scripture_with_template": "Sostituisci le scritture con il modello", "active_layers": "Livelli attivi", "window": "Finestra", "active_style": "Usa stile", @@ -909,9 +941,11 @@ "show_location": "Mostra posizione", "data_location": "Posizione dei dati", "user_data_location": "Salva le impostazioni utente in \"Posizione dati\"", + "popup_before_close": "Visualizza sempre il popup prima della chiusura", "font": "Font", "font_family": "Famiglia font", "font_size": "Dimensione font", + "border_radius": "Raggio di confine", "colors": "Colori", "add_group": "Aggiungi gruppo", "group_shortcut": "Scorciatoia per attivare il gruppo", @@ -938,6 +972,7 @@ "preview_frame_rate": "Anteprima frequenza fotogrammi", "auto": "Auto", "optimized": "Ottimizzato", + "reduced": "Ridotto", "full": "Pieno" }, "sort": { @@ -981,6 +1016,7 @@ "custom": "Oppure importa la tua", "max_verses": "Numero massimo di versi per diapositiva", "verse_numbers": "Numeri di versi", + "verses_on_individual_lines": "Versetti su versi individuali", "version": "Mostra versione", "reference": "Mostra referenze", "combine_with_text": "Combina con testo", @@ -1010,6 +1046,8 @@ "current_slide": "per la diapositiva corrente", "text": "Transizione del testo", "media": "Transizione multimediale", + "slide_transition": "Transizione diapositiva", + "background_transition": "Transizione dello sfondo", "duration": "Durata", "easing": "Facilità", "type": "Tipo", diff --git a/public/lang/nl.json b/public/lang/nl.json new file mode 100644 index 00000000..5daa8fcd --- /dev/null +++ b/public/lang/nl.json @@ -0,0 +1,1115 @@ +{ + "main": { + "welcome": "Welkom", + "quit": "Afsluiten", + "docs": "Documentatie", + "about": "Over", + "unnamed": "Naamloos", + "drop": "Hier neerzetten", + "search": "Zoeken", + "none": "Geen", + "finished": "Afgelopen", + "system_open": "In systeem openen" + }, + "titlebar": { + "file": "Bestand", + "edit": "Bewerken", + "view": "Bekijken", + "help": "Hulp" + }, + "screen": { + "width": "Breedte", + "height": "Hoogte", + "pixels": "pixels", + "top": "Top", + "right": "Rechts", + "bottom": "Bodem", + "left": "Links" + }, + "about": { + "check_updates": "Zoek naar updates", + "made": "Gemaakt in Noorwegen door", + "report": "Wil je een probleem melden? Meldt een issue bij GitHub", + "help": "Wil je helpen vertalen of een functie aanvragen? Stuur een mail naar", + "support": "Steun het project?", + "assets": "Gebruikte assets", + "libraries": "Bibliotheken gebruikt", + "thanks": "Met dank aan", + "new_update": "Nieuwe update beschikbaar", + "download": "Start de applicatie opnieuw om te updaten, of ga naar freeshow.app om handmatig te downloaden", + "changes": "Wat is nieuw" + }, + "tooltip": { + "project": "Maak een nieuw project aan waar je shows kunt toevoegen en regelen.", + "show": "Maak een nieuwe show waaraan je liedteksten, presentaties en media kunt toevoegen. Houd Ctrl/Cmd ingedrukt om een leeg bestand te maken.", + "groups": "Alle groepen in de huidige show en alle globale groepen. Klik of sleep ze om ze aan de huidige lay-out toe te voegen.", + "layout": "Voeg overgangen en volgende timers toe aan dia's in de huidige lay-out.", + "media": "Alle media in de huidige show. Toon ze of sleep ze naar de huidige lay-out.", + "metadata": "Bewerk metadata voor de huidige show.", + "notes": "Schrijf notities.", + "text": "Bewerk de inhoud van alle geselecteerde items.", + "item": "Bewerk alle geselecteerde items.", + "items": "Items toevoegen en rangschikken.", + "slide": "Bewerk huidige dia.", + "filters": "Verander het uiterlijk van het geselecteerde element.", + "options": "Meer opties.", + "scripture": "Houd Ctrl/Cmd of Shift ingedrukt om meerdere verzen te selecteren." + }, + "tips": { + "trigger": "Triggers worden vaak gebruikt om een HTTP-verzoek te verzenden om de voorinstelling van camera’s te wijzigen." + }, + "setup": { + "good_luck": "Ik hoop dat je deze software nuttig vindt. Veel succes met het showen! :)", + "tips": "Op de website vind je handige tips en tutorials.", + "change_later": "Je kunt deze instellingen later wijzigen", + "get_started": "Begin!" + }, + "example": { + "welcome": "Welkom", + "meetings": "Bijeenkomsten", + "example": "Voorbeeld", + "example_note": "Schrijf hier notities", + "watermark": "Watermerk", + "recording": "Opname", + "clock": "Klok", + "rounded": "Afgerond", + "call": "Video-oproep", + "header": "Koptekst", + "text": "Tekst", + "big": "Groot", + "default": "Standaard", + "small": "Klein", + "bold": "Vetgedrukt" + }, + "create_show": { + "search_web": "Zoek naar een lied op internet", + "more_options": "Meer opties", + "format_new_show": "Tekst opmaken", + "split_lines": "Aantal regels", + "quick_lyrics_example_text": "Regel" + }, + "preview": { + "_previous_show": "Vorige show", + "_previous_slide": "Vorige dia", + "_lock": "Uitgang vergrendelen", + "_unlock": "Uitgang ontgrendelen", + "_start": "Show starten", + "_update": "Uitgang bijwerken", + "_next_slide": "Volgende dia", + "_next_show": "Volgende show", + "_hide_preview": "Voorbeeld verbergen", + "show_preview": "Voorbeeld tonen", + "restore_output": "Uitgang herstellen", + "enable_controls": "Besturingselementen voor mediavoorbeelden weergeven", + "background": "Achtergrond", + "foreground": "Voorgrond", + "slide": "Dia", + "overlays": "Overlays", + "audio": "Audio", + "to_start": "Ga naar start", + "nextTimer": "Volgende diatimer", + "lock": "Vergrendelen", + "unlock": "Ontgrendelen" + }, + "clear": { + "all": "Alles wissen", + "background": "Achtergrond wissen", + "slide": "Dia wissen", + "overlays": "Overlays wissen", + "audio": "Audio wissen", + "nextTimer": "Wis de volgende dia-timer" + }, + "remove": { + "background": "Achtergrond verwijderen", + "overlays": "Overlays verwijderen", + "audio": "Audio verwijderen", + "nextTimer": "Verwijder de volgende diatimer", + "to_start": "Verwijder ga naar start", + "timer": "Timer verwijderen", + "transition": "Overgang verwijderen" + }, + "media": { + "_loop": "Lus", + "play": "Afspelen", + "play_multiple": "Meerdere afspelen", + "toggle_shuffle": "Shuffle schakelen", + "next": "Volgende", + "previous": "Vorige", + "play_no_filters": "Zonder filter afspelen", + "favourite": "Favoriet", + "pause": "Pauzeren", + "stop": "Stoppen", + "back10": "Ga 10 seconden terug", + "forward10": "Ga 10 seconden vooruit", + "volume": "Volume", + "gain": "Gain", + "speed": "Snelheid", + "show": "Show", + "flip": "Omdraaien", + "flip_horizontally": "Horizontaal omkeren", + "flip_vertically": "Verticaal omkeren", + "all": "Mappen, afbeeldingingen & video's", + "folder": "Alleen mappen", + "image": "Alleen afbeeldingingen", + "video": "Alleen video's", + "fit": "Passend", + "contain": "Bevatten", + "fill": "Vullen", + "cover": "Bedekken", + "online": "Online", + "recommended": "Aanbevolen" + }, + "audio": { + "metronome": "Metronoom", + "toggle_metronome": "Schakel metronoom", + "tempo": "Tempo", + "bpm": "BPM", + "beats": "Beats" + }, + "menu": { + "show": "Show", + "_title_show": "Presenteren", + "edit": "Bewerken", + "_title_edit": "Bewerken", + "stage": "Podium", + "_title_stage": "Podiumweergave", + "draw": "Schetsen", + "_title_draw": "Schets", + "calendar": "Kalender", + "_title_calendar": "Gebeurtenissen", + "settings": "Instellingen", + "_title_settings": "Instellingen", + "_title_display": "Presenteren", + "_title_display_stop": "Presentatie stoppen" + }, + "empty": { + "general": "Niets hier", + "project_select": "Selecteer een project", + "show": "Geen show geselecteerd", + "shows": "Geen shows", + "slides": "Geen dia's", + "slide": "Geen dia geselecteerd", + "items": "Geen items geselecteerd", + "search": "Geen match", + "media": "Geen media in show", + "stage_show": "Geen podiumshow", + "stage_shows": "Geen podiumshows", + "player": "Geen video's", + "groups": "Geen groepen", + "events": "Geen gebeurtenissen", + "text": "Typ iets", + "timers": "Geen timers", + "input": "Ontbrekende waarde in invoer", + "recording": "Klik met de rechtermuisknop op een scherm of venster om een opname te starten." + }, + "remote": { + "projects": "Projecten", + "project": "Project", + "shows": "Show's", + "show": "Show", + "slide": "Dia", + "lyrics": "Liedteksten", + "end": "Einde", + "no_output": "Geen uitvoer", + "remember": "Onthoud me", + "loading": "Bezig met laden...", + "submit": "Indienen", + "password": "Wachtwoord", + "wrong_password": "Foutief wachtwoord" + }, + "error": { + "no_show": "Kon de show niet vinden", + "no_layouts": "Kon geen lay-outs vinden", + "load": "Kon niet laden", + "bible": "Kon de plaatselijke bijbeltekst niet vinden", + "bible_api": "Kon de bijbeltekst niet laden vanuit API.Bible, heeft u een internetverbinding?", + "not_found": "Niet gevonden", + "display": "Kon het uitvoervenster niet weergeven op het huidige scherm", + "keep_one_layout": "Je moet minimaal één lay-out hebben", + "video_unavailable": "Is de video niet beschikbaar? De maker heeft het insluiten van de video uitgeschakeld.", + "folder_exists": "Deze map bestaat al" + }, + "meta": { + "title": "Titel", + "artist": "Artiest", + "author": "Auteur", + "composer": "Componist", + "publisher": "Uitgever", + "copyright": "Auteursrecht", + "CCLI": "Licentie (CCLI)", + "year": "Jaar", + "message": "Bericht", + "message_tip": "Laat iets zien op alle dia's", + "auto_media": "Haal meta uit media-inhoud", + "override_output": "Stijl in uitvoer overschrijven", + "display_metadata": "Metagegevens weergeven", + "meta_template": "Metagegevenssjabloon", + "text_divider": "Tekstscheidingsteken", + "message_template": "Berichtsjabloon" + }, + "show_at": { + "never": "Geen dia's", + "always": "Alle dia's", + "first": "Eerste dia", + "last": "Laatste dia", + "first_last": "Eerste en laatste dia" + }, + "themes": { + "default": "Standaard", + "dark": "Donker", + "light": "Licht", + "white": "Wit", + "black": "Zwart" + }, + "theme": { + "primary": "Primair", + "primary-lighter": "Primair lichter", + "primary-darker": "Primair donkerder", + "primary-darkest": "Primair donkerst", + "text": "Tekst", + "textInvert": "Omgekeerde tekst", + "secondary-text": "Secundaire tekst", + "secondary": "Ondergeschikt", + "secondary-opacity": "Secundaire dekking", + "hover": "Zweven", + "focus": "Focus" + }, + "inputs": { + "name": "Naam", + "url": "URL", + "video_id": "Video ID/URL", + "close_ad": "Sluit de weergave op het uitvoerscherm", + "start": "Start", + "end": "Einde", + "change_folder": "Kies een andere locatie" + }, + "tabs": { + "shows": "Shows", + "media": "Media", + "overlays": "Overlays", + "audio": "Audio", + "effects": "Effecten", + "scripture": "Bijbeltekst", + "calendar": "Kalender", + "functions": "Functies", + "actions": "Acties", + "player": "Speler", + "live": "Live", + "timers": "Timers", + "variables": "Variabelen", + "triggers": "Triggers", + "templates": "Sjablonen", + "web": "Web" + }, + "category": { + "all": "Alles", + "unlabeled": "Ongelabeld", + "favourites": "Favorieten", + "song": "Liederen", + "presentation": "Presentaties", + "info": "Informatie", + "scripture": "Bijbeltekst", + "events": "Gebeurtenissen", + "pictures": "Afbeeldingen", + "videos": "Video's", + "music": "Muziek", + "offers": "Collectes", + "notice": "Mededelingen", + "visuals": "Beeldmaterialen" + }, + "groups": { + "current": "Huidig", + "global": "Globaal", + "toggle_global_group": "Globale groepen schakelen", + "group_shortcut": "Groep snelkoppeling", + "group_template": "Groepssjabloon", + "intro": "Inleiding", + "verse": "Vers", + "pre_chorus": "Pre refrein", + "chorus": "Refrein", + "break": "Onderbreking", + "tag": "Label", + "bridge": "Brug", + "outro": "Outro" + }, + "popup": { + "show": "Nieuwe show", + "select_show": "Show selecteren", + "rename": "Hernoemen", + "color": "Kleur", + "find_replace": "Zoek en vervang", + "edit_list": "Lijst bewerken", + "timer": "Timer", + "variable": "Variabele", + "trigger": "Trigger", + "audio_stream": "Audio stream", + "transition": "Overgang", + "delete_show": "Show verwijderen", + "delete_show_confirmation": "Weet je zeker dat je wil verwijderen", + "change_name": "Naam wijzigen aan", + "choose_screen": "Scherm kiezen", + "change_output_values": "Uitvoerwaarden wijzigen", + "set_time": "Tijd instellen", + "animate": "Animeren", + "next_timer": "Volgende diatimer", + "import": "Import", + "export": "Export", + "importing": "Importeren", + "import_scripture": "Bijbeltekst importeren", + "player": "Speler", + "edit_event": "Gebeurtenis bewerken", + "about": "Over", + "history": "Geschiedenis", + "action": "Actie", + "connect": "Verbinden", + "cloud_update": "Synchroniseren met de cloud", + "cloud_method": "Datalocatie", + "shortcuts": "Snelkoppelingen", + "icon": "Pictogrammen", + "manage_icons": "Beheer pictogrammen", + "manage_colors": "Beheer kleuren", + "choose_camera": "Kies camera", + "initialize": "Welkom bij FreeShow", + "unsaved": "Weet je zeker dat je wilt afsluiten?", + "cancel": "Annuleren", + "continue": "Doorgaan", + "reset_all": "Alles opnieuw instellen", + "reset_all_confirm": "Weet je zeker dat je alles opnieuw wil instellen?", + "reset_all_action": "Hierdoor wordt het hele programma opnieuw ingesteld, maar worden de .show-bestanden in uw map \"Shows\" niet verwijderd.", + "quit": "Afsluiten zonder opslaan", + "save_quit": "Opslaan & Sluiten" + }, + "toast": { + "saving": "Opslaan...", + "saved": "Opgeslagen", + "error_media": "Kan geen media ophalen.", + "empty_styles": "Geen stijlen", + "chapter_undefined": "Hoofdstuk {} bestaat niet in dit boek.", + "verse_undefined": "Vers {} bestaat niet in dit hoofdstuk.", + "recording_started": "Opname gestart!", + "recording_stopped": "Opname gestopt", + "starting_show": "Beginnende show", + "less_than_minute": "in minder dan een minuut.", + "less_than_seconds": "in minder dan {} seconden.", + "now": "nu!", + "no_video_id": "Geen video-ID", + "no_name": "Geen naam", + "media_replaced": "Ontbrekend mediabestand vervangen door overeenkomst.", + "lyrics_undefined": "Kon geen liedtekst vinden!", + "lyrics_copied": "Liedtekst gekopieerd van", + "no_pdf_linux": "Kan niet exporteren als PDF op Linux.", + "one_output": "Er moet minimaal één actieve uitgang zijn!", + "empty_cache": "Cache is leeg.", + "deleted_cache": "Cache van mediaminiaturen verwijderd.", + "no_songswords_easyworship": "Ontbrekend SongsWords.db-bestand.", + "delete_shows_empty": "Er zijn geen shows om te verwijderen.", + "midi_no_project": "Trigger ontvangen om van project te veranderen, maar geen project gevonden in index:", + "midi_no_show": "Trigger ontvangen om dia te starten, maar geen show actief.", + "midi_no_slide": "Trigger ontvangen om dia te starten, maar geen dia gevonden bij index:", + "midi_no_velocity": "MIDI-signaal ontvangen, maar geen velocity, standaard ingesteld op de eerste index." + }, + "new": { + "show": "Nieuwe show", + "empty_show": "Nieuwe lege show", + "project": "Nieuw project", + "section": "Nieuwe sectie", + "timer": "Nieuwe timer", + "variable": "Nieuwe variabele", + "trigger": "Nieuwe trigger", + "audio_stream": "Nieuwe audio stream", + "playlist": "Nieuw afspeellijst", + "category": "Nieuwe categorie", + "private": "Nieuwe privé show", + "folder": "Nieuwe map", + "slide": "Nieuwe dia", + "overlay": "Nieuwe overlay", + "template": "Nieuw sjabloon", + "scripture": "Nieuwe bijbeltekst", + "collection": "Nieuwe collectie", + "action": "Nieuwe actie", + "event": "Nieuwe gebeurtenis" + }, + "show": { + "name": "Naam", + "category": "Categorie", + "quick_lyrics": "Snelle liedteksten", + "new_layout": "Nieuwe lay-out", + "grid": "Rasterweergave", + "simple": "Eenvoudige weergave", + "list": "Lijstweergave", + "lyrics": "Liedtekstweergave", + "text": "Tekst bewerken", + "update": "Show bijwerken", + "slide_template": "Dia sjabloon", + "search_results": "Zoekresultaten", + "source": "Bron", + "artist": "Artiest", + "song": "Lied" + }, + "actions": { + "rename": "Hernoemen", + "recolor": "Kleur wijzigen", + "remove": "Verwijderen", + "remove_group": "Groep verwijderen", + "choose_group": "Groep kiezen", + "goto_group": "Naar groep gaan", + "active_outputs": "Actieve uitgangen", + "all_outputs": "Alle uitgangen", + "specific_outputs": "Specifieke uitgangen", + "toggle_private": "Privé", + "view_private": "Privé weergeven", + "import": "Importeren", + "export": "Exporteren", + "duplicate": "Dupliceren", + "delete": "Verwijderen", + "delete_slide": "Dia verwijderen", + "delete_group": "Groep verijwderen", + "delete_all": "Alles verwijderen", + "close": "Sluiten", + "save": "Opslaan", + "done": "Gereed", + "disable": "Uitzetten", + "enable": "Aanzetten", + "undo": "Ongedaan maken", + "redo": "Opnieuw doen", + "cut": "Knippen", + "copy": "Kopiëren", + "paste": "Plakken", + "pasteAndMatchStyle": "Stijl plakken en matchen", + "selectAll": "Alles selecteren", + "remove_selection": "Selectie verwijderen", + "speech": "Toespraak", + "startSpeaking": "Begin met praten", + "stopSpeaking": "Stop met praten", + "fullscreen": "Volledig scherm schakelen", + "resetZoom": "Zoom opnieuw instellen", + "zoom": "Zoom", + "zoomIn": "Inzoomen", + "zoomOut": "Uitzoomen", + "reset": "Opnieuw instellen", + "reset_defaults": "Standaardwaarden opnieuw instellen", + "to_all": "Toepassen op alles", + "to_following": "Toepassen op het volgende", + "back": "Ga terug", + "home": "Thuis", + "mute": "Dempen", + "unmute": "Dempen opheffen", + "increase_volume": "Volume verhogen", + "decrease_volume": "Volume verlagen", + "toggle_time_marker": "Tijdmarkeringen schakelen", + "add_time_marker": "Tijdmarkering toevoegen", + "bind_to": "Specifieke uitgangen", + "remove_binding": "Specifieke uitgangen verwijderen", + "dynamic_values": "Dynamische waarden", + "show_timer": "Tijd tot show", + "hide_timer": "Tijd tot verbergen", + "choose_custom": "Aangepast kiezen", + "add_color": "Voeg kleur toe", + "format": "Opmaak", + "find_replace": "Tekst zoeken en vervangen", + "cut_in_half": "Gehalveerd", + "find": "Zoek", + "replace": "Vervang", + "case_sensitive": "Hoofdlettergevoelig", + "uppercase": "Maak hoofdletters", + "lowercase": "Maak kleine letters", + "capitalize": "Kapitaliseren", + "trim": "Trimmen", + "click_disable": "Klik op een willekeurige optie om uit te schakelen", + "svg_clipboard": "Importeer SVG vanaf het klembord", + "fullscreen_preview": "Voorbeeld op volledig scherm schakelen", + "toggle_output": "Uitvoerscherm schakelen", + "change_tab": "Tabblad wijzigen", + "change_drawer_tab": "Wijzig het tabblad van de tekenpen", + "change_slide": "Dia wijzigen", + "change_project_item": "Projectitem wijzigen", + "change_drawer_item": "Lade-item wijzigen", + "change_drawer_category": "Ladecategorie wijzigen", + "toggle_drawer": "Tekenpen schakelen", + "slide_actions": "Dia-acties", + "item_actions": "Item acties", + "clear_history": "Geschiedenis wissen", + "set_key": "Sleutel instellen", + "custom_key": "Aangepaste waarde instellen", + "play_on_midi": "Activeren op MIDI-signaal", + "play_on_midi_tip": "Activeer deze specifieke dia bij ontvangst van het gekozen MIDI-signaal", + "send_midi": "MIDI-signaal verzenden", + "delete_shows_not_indexed": "Verwijder shows in de map 'Shows' die niet zijn geïndexeerd", + "delete_thumbnail_cache": "Miniatuurcache verwijderen", + "open_log_file": "Logbestand openen", + "refresh_all_shows": "Haal alle shows op in de map 'Shows'", + "start_timer": "Start timer", + "stop_timers": "Actieve timers stoppen", + "next_after_media": "Volgende wanneer media klaar is", + "remove_media": "Media verwijderen", + "remove_layers": "Lagen verwijderen", + "start_recording": "Opname starten", + "stop_recording": "Opname stoppen", + "index_select_project": "Selecteer project op index", + "next_project_item": "Volgende projectitem", + "previous_project_item": "Vorige projectitem", + "index_select_project_item": "Selecteer projectitem op index", + "name_select_show": "Selecteer show op naam", + "random_slide": "Willekeurige dia afspelen", + "index_select_slide": "Selecteer dia op index", + "name_select_slide": "Selecteer dia op naam", + "toggle_output_lock": "Uitgang vergrendelen", + "toggle_output_windows": "Uitvoervensters schakelen", + "id_select_group": "Selecteer groep op ID", + "id_change_stage_layout": "Toneelindeling wijzigen op ID", + "index_select_overlay": "Selecteer overlay op index", + "name_select_overlay": "Selecteer overlay op naam", + "change_volume": "Volume veranderen", + "start_audio_stream": "Audio stream starten", + "start_playlist": "Afspeellijst starten", + "start_metronome": "Metronoom starten", + "start_slide_timers": "Start timers op actieve dia", + "id_select_output_style": "Selecteer uitvoerstijl op ID", + "change_output_style": "Wijzig de uitvoerstijl", + "change_transition": "Overgang veranderen", + "change_variable": "Verander variabele", + "start_trigger": "Start trigger", + "run_action": "Actie uitvoeren", + "custom_activation": "Aangepaste activering", + "activate_on_startup": "Activeren bij opstarten", + "activate_save": "Activeren bij opslaan", + "activate_slide_clicked": "Activeren bij klikken op dia", + "activate_scripture_start": "Activeer wanneer bijbeltekst wordt gestart", + "activate_show_created": "Activeren wanneer show wordt gemaakt" + }, + "animate": { + "change": "Wijzigen", + "set": "Set", + "wait": "Wachten", + "background": "achtergrond", + "text": "tekst", + "item": "item", + "to": "naar", + "for": "tot", + "seconds": "seconden" + }, + "cloud": { + "info": "Synchroniseer bestanden met Google Drive voor back-ups of als je op meerdere computers werkt.", + "tip_api": "Je moet je eigen gratis Google API-sleutel opgeven, zodat het programma automatisch bestanden naar jouw Google Drive kan uploaden.", + "tip_how": "Weet je niet hoe je er een kunt krijgen?", + "tip_guide": "Klik hier voor een handleiding.", + "enable": "Automatische synchronisatie bij opstarten en afsluiten", + "disable_upload": "Schakel het uploaden van gegevens uit", + "media_id": "Mediapad-ID", + "google_drive_api": "Accountsleutel voor Google API-service", + "select_key": "Sleutelbestand importeren", + "update_key": "Sleutelbestand bijwerken", + "main_folder": "Stel de hoofdmap handmatig in", + "media_folder": "Map voor cloudmedia", + "reconnect": "Maak opnieuw verbinding", + "sync": "Nu synchroniseren", + "choose_method_tip": "Er zijn bestaande gegevens in de cloud. Kies voor uploaden vanaf lokaal of downloaden vanaf cloud. De andere locatie wordt overschreven.", + "local": "Lokaal", + "syncing": "Synchroniseren naar de cloud", + "sync_complete": "Synchronisatie voltooid" + }, + "export": { + "export": "Exporteren", + "export_as": "Exporteer {} als", + "exported": "Geëxporteerd!", + "oneFile": "Eén bestand", + "selected_shows": "Geselecteerde shows", + "current_project": "Huidig project", + "all_shows": "Alle shows", + "all_projects": "Alle projecten", + "project": "Project", + "options": "Opties", + "preview": "Voorbeeld", + "title": "Titel", + "metadata": "Metadata", + "page_numbers": "Paginanummers", + "groups": "Groepen", + "numbers": "Genummerde dia's", + "invert": "Dia's omkeren", + "original_text_size": "Oorspronkelijke tekstgrootte", + "text": "Platte tekst", + "slides": "Dia's", + "rows": "Rijen", + "columns": "Kolommen" + }, + "context": { + "enabledTabs": "Tabbladen schakelen", + "addToProject": "Toevoegen aan project", + "newCategory": "Nieuwe categorie", + "changeIcon": "Pictogram wijzigen", + "changeGroup": "Groep wijzigen", + "createNew": "Nieuw maken", + "selectAll": "Alles selecteren", + "force_outputs": "Forceer uitgangen", + "align_with_screen": "Uitlijnen met scherm", + "toggle_output": "Uitvoer schakelen", + "move_to_front": "Naar voorgrond verplaatsen", + "lock_to_output": "Vergrendelen naar uitvoer", + "place_under_slide": "Onder dia plaatsen", + "toggle_clock": "Klok schakelen", + "move_connections": "Verplaats alle verbindingen hierheen" + }, + "tools": { + "notes": "Notities", + "--schedule": "Inplannen", + "--actions": "Acties", + "groups": "Groepen", + "metadata": "Metadata", + "media": "Media", + "audio": "Audio", + "layout": "Lay-out", + "item": "Item", + "items": "Items", + "slide": "Dia" + }, + "edit": { + "text": "Tekst", + "font": "Lettertype", + "family": "Lettertypefamilie", + "font_size": "Lettertypegrootte", + "text_color": "Tekst kleur", + "style": "Stijl", + "lines": "Regels", + "options": "Opties", + "_title_bold": "Vetgedrukt", + "_title_italic": "Cursief", + "_title_underline": "Onderstrepen", + "_title_strikethrough": "Doorhalen", + "color": "Kleur", + "background_color": "Achtergrondkleur", + "background_opacity": "Achtergronddekking", + "background_image": "Achtergrondafbeelding", + "background_media": "Achtergrond media", + "overlay_content": "Overlappende inhoud toevoegen", + "different_first_template": "Aangepaste sjabloon op eerste dia", + "media_fit": "Media passend", + "size": "Grootte", + "chords": "Akkoorden", + "transpose": "Transponeer", + "auto_size": "Automatische grootte", + "no_wrap": "Tekst op één regel", + "line_spacing": "Regelafstand", + "line_height": "Regelhoogte", + "letter_spacing": "Letterafstand", + "word_spacing": "Woordafstand", + "transform": "Transformeren", + "text_transform": "Tekst transformeren", + "uppercase": "Hoofdletters", + "lowercase": "Kleine letters", + "capitalize": "Kapitaliseren", + "align": "Uitlijnen", + "_title_left": "Links uitlijnen", + "_title_center": "In het midden uitlijnen", + "_title_right": "Rechts uitlijnen", + "_title_justify": "Uitlijnen uitvullen", + "_title_top": "Bovenkant uitlijnen", + "_title_bottom": "Onderkant uitlijnen", + "outline": "Uitlijnen", + "shadow": "Schaduw", + "shadow_inset": "Schaduw inzet", + "offsetX": "Offset X", + "offsetY": "Offset Y", + "blur": "Vervagen", + "item": "Item", + "width": "Breedte", + "height": "Hoogte", + "rotation": "Rotatie", + "tilt": "Kantelen", + "perspective": "Perspectief", + "opacity": "Dekking", + "corner_radius": "Hoekradius", + "border": "Rand", + "length": "Lengte", + "x": "X", + "y": "Y", + "add_items": "Items toevoegen", + "add_icons": "Pictogrammen toevoegen", + "arrange_items": "Items rangschikken", + "filters": "Filters", + "backdrop_filters": "Achtergrondfilters", + "interval": "Interval", + "video": "Video", + "choose_media": "Media kiezen", + "recent": "Recent bewerkt", + "enable_stage": "Schakel podium in", + "select_stage": "Podium selecteren", + "next_slide": "Volgende dia weergeven", + "use_slide_index": "Gebruik actieve index", + "slide_index": "Dia-index", + "padding": "Opvulling", + "special": "Speciaal", + "scrolling": "Scrollen", + "scrolling_speed": "Scrollsnelheid", + "top_bottom": "Boven naar beneden", + "bottom_top": "Beneden naar boven", + "left_right": "Links naar rechts", + "right_left": "Rechts naar links", + "max_events": "Maximaal aantal gebeurtenissen", + "start_days_from_today": "Begin op dagen vanaf vandaag", + "just_one_day": "Maar één dag", + "enable_start_date": "Startdatum inschakelen" + }, + "items": { + "text": "Tekstvak", + "list": "Lijst", + "media": "Media", + "image": "Afbeelding", + "camera": "Camera", + "video": "Video", + "mirror": "Spiegel", + "clock": "Klok", + "events": "Gebeurtenissen", + "live": "Live", + "audio": "Audio", + "timer": "Timer", + "variable": "Variabele", + "web": "Website", + "visualizer": "Visualisator", + "icon": "Pictogram" + }, + "borders": { + "solid": "Stevig", + "dashed": "Gestreept", + "dotted": "Gestippeld", + "double": "Dubbel", + "inset": "Inset", + "outset": "Outset", + "groove": "Groef", + "ridge": "Rand" + }, + "list": { + "disc": "Schijf", + "circle": "Cirkel", + "square": "Vierkant", + "disclosure-closed": "Pijl", + "disclosure-open": "Driehoek", + "decimal": "Getal", + "decimal-leading-zero": "Getal met nul", + "lower-alpha": "Letter", + "upper-alpha": "Hoofdletter", + "lower-roman": "Romeins cijfer", + "upper-roman": "Grote romeinse cijfers", + "lower-greek": "Grieks" + }, + "timer": { + "from_to": "Van begin to eind", + "to_time": "Naar een tijd", + "to_event": "Tijd tot gebeurtenis", + "counter": "Countdown", + "time": "Tijd", + "seconds": "Seconden", + "from": "Van", + "to": "Naar", + "overflow": "Overloop bij einde", + "overflow_color": "Overloop kleur", + "preview": "Voorbeeld", + "clock": "Klok", + "event": "Gebeurtenis", + "no_events": "Er zijn geen aankomende gebeurtenissen", + "edit": "Bewerken", + "create": "Maken", + "line": "Regel", + "mask": "Verbergen" + }, + "clock": { + "type": "Type", + "digital": "Digitaal", + "analog": "Analoog", + "seconds": "Seconden" + }, + "midi": { + "midi": "MIDI", + "activate": "Activeren door MIDI-signaal", + "name": "Naam", + "input": "Ingang", + "output": "Uitgang", + "type": "Type", + "note": "Notitie", + "velocity": "Snelheid", + "channel": "Kanaal", + "start_action": "Actie starten", + "use_default_values": "Gebruik standaardwaarden", + "auto_values": "Werk waarden bij bij ontvangst van een MIDI-invoer", + "tip_velocity": "Stel de snelheid in op -1 om uit te schakelen.", + "tip_action": "Om specifieke dia's te activeren, klik je met de rechtermuisknop op een dia en kies je de midi in actie.", + "tip_index_by_velocity": "De index wordt bepaald door de ontvangen snelheid, beginnend bij 0." + }, + "draw": { + "focus": "Focus", + "pointer": "Wijzer", + "fill": "Vullen", + "paint": "Kleuren", + "particles": "Fragmenten", + "color": "Kleur", + "opacity": "Dekking", + "size": "Grootte", + "radius": "Straal", + "glow": "Gloed", + "hollow": "Hol", + "hold": "Vasthouden", + "rainbow": "Regenboog", + "threed": "3D", + "dots": "Punten" + }, + "stage": { + "slide": "Dia", + "current_slide_text": "Huidige diatekst", + "current_slide": "Huidige dia", + "current_slide_notes": "Huidige dianotities", + "next_slide_text": "Volgende diatekst", + "next_slide": "Volgende dia", + "next_slide_notes": "Volgende dianotities", + "output": "Uitvoer", + "current_output": "Huidige uitvoer", + "time": "Tijd", + "system_clock": "Systeemklok", + "video_time": "Videotijd", + "video_countdown": "Video aftellen", + "other": "Andere", + "message": "Bericht", + "color": "Kleur", + "font-size": "Lettertypegrootte", + "zeros": "Nullen", + "overrun": "Overloop kleur", + "source_output": "Bron output", + "auto_stretch": "Inhoud automatisch uitrekken", + "labels": "Labels tonen" + }, + "settings": { + "general": "Algemeen", + "theme": "Thema", + "groups": "Groepen", + "styles": "Stijlen", + "display_settings": "Uitgangen", + "display": "Beeldscherm", + "connection": "Verbinding", + "cloud": "Cloud", + "calendar": "Kalender", + "text_import": "Tekst", + "media_import": "Media", + "other": "Ander", + "language": "Taal", + "autosave": "Automatisch opslaan", + "never": "Nooit", + "minutes": "minuten", + "use24hClock": "24-uursklok gebruiken", + "styles_hint": "Maak verschillende stijlen die op de uitvoer kunnen worden toegepast om het uiterlijk te veranderen.", + "hide_output_hint": "Dubbelklik op het uitvoervenster om het te verbergen. Houd CTRL ingedrukt om slepen in te schakelen.", + "hide_menubar_hint": "Om de menubalk te verbergen, schakel je de kioskmodus in, of schakel je \"De menubalk automatisch verbergen of tonen\" in de algemene MacOS-instellingen in.", + "show_output_hint": "Houd ctrl/cmd ingedrukt terwijl je op de weergaveknop klikt om de weergave op deze monitor te forceren.", + "move_output_hint": "Kun je je beeldscherm niet vinden? Verander de positie totdat het venster op het tweede scherm verschijnt.", + "select_display": "Klik op het scherm waar je het uitvoervenster wil weergeven.", + "manual_input_hint": "Kun je het scherm niet vinden? Klik hier om de positie handmatig te wijzigen.", + "manual_drag_hint": "Je kunt ook ctrl/cmd ingedrukt houden boven een actief uitvoervenster om het handmatig te slepen.", + "allow_main_screen": "Uitvoer op hoofdscherm toestaan", + "identify_screens": "Schermen identificeren", + "new_output": "Nieuwe uitvoer", + "enable_key_output": "Schakel alpha key van uitgang in", + "always_on_top": "Altijd bovenop", + "kiosk_mode": "Kioskmodus", + "change_key_output_position": "Wijzig de sleuteluitvoerpositie", + "position": "Positie", + "enabled": "Ingeschakeld", + "color_when_active": "Kleur indien actief", + "fixed": "Vast", + "lines": "Regels", + "override_with_template": "Dia overschrijven met sjabloon", + "override_scripture_with_template": "Bijbeltekst overschrijven met sjabloon", + "active_layers": "Actieve lagen", + "window": "Venster", + "active_style": "Stijl gebruiken ", + "alert_updates": "Waarschuw wanneer er een nieuwe update beschikbaar is", + "auto_updates": "Auto updates", + "disable_labels": "Schakel labels uit", + "group_numbers": "Groepsnummers", + "full_colors": "Volledige diagroepkleuren", + "auto_output": "Activeer het uitvoerscherm bij het opstarten", + "hide_cursor_in_output": "Verberg cursor in uitvoer", + "disable_presenter_controller_keys": "Toetsen van presentatorbesturing uitschakelen", + "default_project_name": "Standaard projectnaam", + "audio_fade_duration": "Audio fade duur", + "max_auto_font_size": "Max. automatische lettergrootte", + "resolution": "Resolutie", + "cropping": "Bijsnijden", + "frame_rate": "Frame rate", + "transparent": "Transparant", + "video_extensions": "Video-extensies", + "image_extensions": "Afbeeldingsextensies", + "add": "Toevoegen", + "remove": "Verwijderen", + "change_name": "Naam wijzigen", + "show_location": "Showlocatie", + "data_location": "Datalocatie", + "user_data_location": "Gebruikersinstellingen opslaan op datalocatie", + "popup_before_close": "Pop-up altijd weergeven voor sluiten", + "font": "Lettertype", + "font_family": "Lettertypefamilie", + "font_size": "Lettertypegrootte", + "border_radius": "Grensradius", + "colors": "Kleuren", + "add_group": "Groep toevoegen", + "group_shortcut": "Sneltoets om groep te activeren", + "output_screen": "Uitvoerscherm", + "device_name": "Apparaatnaam", + "password": "wachtwoord", + "port": "Poort", + "connections": "Verbindingen", + "max_connections": "Maximale verbindingen", + "allowed_connections": "Toegestane verbindingen", + "connect": "Maak verbinding door dit in een webbrowser te typen", + "connect_qr": "Of scan deze QR-code", + "restart": "Start servers opnieuw op", + "reset_all": "Alles resetten", + "reset_theme": "Thema opnieuw instellen", + "reset_themes": "Thema's opnieuw instellen", + "capitalize_words": "Woorden kapitaliseren", + "backup_all": "Maak een back-up van alles", + "restore": "Herstel", + "backup_started": "Back-up aan het maken...", + "restore_started": "Herstellen...", + "backup_finished": "Back-up voltooid!", + "restore_finished": "Herstel voltooid!", + "preview_frame_rate": "Voorbeeld framerate", + "auto": "Automatisch", + "optimized": "Geoptimaliseerd", + "reduced": "Verminderd", + "full": "Vol" + }, + "sort": { + "sort_by": "Sorteer op", + "name": "Naam", + "date": "Datum", + "size": "Grootte", + "type": "Type", + "custom": "Aangepast" + }, + "calendar": { + "type": "Type", + "event": "Gebeurtenis", + "show": "Show inplannen", + "name": "Naam", + "color": "Kleur", + "time": "Tijd", + "from_date": "Vanaf datum", + "to_date": "Tot datum", + "from_time": "Vanaf tijd", + "to_time": "Tot tijd", + "location": "Locatie", + "notes": "Notities", + "today": "Vandaag", + "tomorrow": "Morgen", + "repeat": "Herhaal", + "repeat_every": "Herhaal elke", + "repeat_until": "tot", + "day": "dag", + "week": "week", + "month": "maand", + "year": "jaar", + "ending_the": "de", + "ending_repeated": "herhaald", + "ending_times": "tijden", + "save_all": "Opslaan en update alles", + "add_slides_from_show": "Voeg dia's van de show toe" + }, + "scripture": { + "bibles": "Bijbels van API.Bible", + "custom": "Of importeer je eigen", + "max_verses": "Max. verzen per dia", + "verse_numbers": "Versnummers", + "verses_on_individual_lines": "Verzen op afzonderlijke regels", + "version": "Toon versie", + "reference": "Toon referentie", + "combine_with_text": "Combineer met tekst", + "reference_at_bottom": "Verplaats naar beneden", + "red_jesus": "Jezus woorden in rood", + "search": "Zoek in de Bijbel" + }, + "filter": { + "blur": "Vervagen", + "brightness": "Helderheid", + "contrast": "Contrast", + "grayscale": "Grijswaarden", + "hue-rotate": "Tint roteren", + "invert": "Omkeren", + "opacity": "Dekking", + "saturate": "Verzadigen", + "sepia": "Sepia" + }, + "live": { + "screens": "Schermen", + "windows": "Vensters", + "cameras": "Camera's", + "microphones": "Microfoons", + "audio_streams": "Audio streams" + }, + "transition": { + "current_slide": "voor huidige dia", + "text": "Tekstovergang", + "media": "Mediaovergang", + "slide_transition": "Overgang dia", + "background_transition": "Overgang achtergrond", + "duration": "Duur", + "easing": "Versoepel", + "type": "Type", + "none": "Geen", + "fade": "Vervagen", + "blur": "Vervagen", + "scale": "Schalen", + "spin": "Draaien", + "slide": "Dia" + }, + "easings": { + "linear": "Lineair", + "ease": "Versoepelen", + "ease-in": "Versoepel in", + "ease-out": "Versoepel uit", + "ease-in-out": "Versoepel in & uit", + "elastic": "Elastisch", + "bounce": "Stuiteren", + "back": "Springen", + "circ": "Circulair", + "cubic": "Kubiek", + "sine": "Vloeien" + }, + "variables": { + "number": "Nummer", + "text": "Tekst", + "step": "Stap", + "value": "Waarde" + }, + "month": { + "1": "Januari", + "2": "Februari", + "3": "Maart", + "4": "April", + "5": "Mei", + "6": "Juni", + "7": "Juli", + "8": "Augustus", + "9": "September", + "10": "Oktober", + "11": "November", + "12": "December" + }, + "weekday": { + "1": "Maandag", + "2": "Dinsdag", + "3": "Woensdag", + "4": "Donderdag", + "5": "Vrijdag", + "6": "Zaterdag", + "7": "Zondag" + }, + "info": { + "created": "Gemaakt", + "modified": "Gewijzigd", + "used": "Gebruikt", + "changed": "Gewijzigd", + "extension": "Bestandsextensie", + "size": "Grootte", + "slides": "Dia's", + "words": "Woorden", + "template": "Sjabloon", + "category": "Categorie" + } +} diff --git a/src/electron/data/export.ts b/src/electron/data/export.ts index f5f68afe..44562b09 100644 --- a/src/electron/data/export.ts +++ b/src/electron/data/export.ts @@ -7,9 +7,10 @@ import fs from "fs" import { join } from "path" import { EXPORT, MAIN, STARTUP } from "../../types/Channels" import { isProd, toApp } from "../index" -import { dataFolderNames, doesPathExist, getDataFolder, openSystemFolder, selectFolderDialog } from "../utils/files" +import { dataFolderNames, doesPathExist, getDataFolder, openSystemFolder, parseShow, readFile, selectFolderDialog } from "../utils/files" import { exportOptions } from "../utils/windowOptions" import { Message } from "../../types/Socket" +import { getAllShows } from "../utils/responses" // SHOW: .show, PROJECT: .project, BIBLE: .fsb const customJSONExtensions: any = { @@ -35,6 +36,11 @@ export function startExport(_e: any, msg: Message) { return } + if (msg.channel === "ALL_SHOWS") { + exportAllShows(msg.data) + return + } + if (msg.channel !== "GENERATE") return if (msg.data.type === "pdf") createPDFWindow(msg.data) @@ -44,16 +50,16 @@ export function startExport(_e: any, msg: Message) { // only open once per session let systemOpened: boolean = false -function doneWritingFile(err: any, exportFolder: string) { +function doneWritingFile(err: any, exportFolder: string, toMain: boolean = true) { let msg: string = "export.exported" // open export location in system when completed if (!err && !systemOpened) { openSystemFolder(exportFolder) systemOpened = true - } else msg = err + } else if (err) msg = err - toApp(MAIN, { channel: "ALERT", data: msg }) + if (toMain) toApp(MAIN, { channel: "ALERT", data: msg }) } // ----- PDF ----- @@ -118,8 +124,8 @@ export function exportJSON(content: any, extension: string, path: string) { // ----- TXT ----- export function exportTXT(data: any) { - data.shows.forEach((show: any) => { - writeFile(join(data.path, show.name), ".txt", getSlidesText(show), "utf-8", (err: any) => doneWritingFile(err, data.path)) + data.shows.forEach((show: any, i: number) => { + writeFile(join(data.path, show.name), ".txt", getSlidesText(show), "utf-8", (err: any) => doneWritingFile(err, data.path, i >= data.shows.length - 1)) }) } @@ -168,6 +174,28 @@ function getSlidesText(show: any) { return text.trim() } +// ----- ALL SHOWS ----- + +function exportAllShows(data: any) { + let type = data.type || "txt" + + if (type !== "txt") return + + let allShows: string[] = getAllShows({ path: data.showsPath }) + let shows: any[] = [] + for (let i = 0; i < allShows.length; i++) { + const showName: string = allShows[i] + const showFilePath = join(data.showsPath, showName) + // WIP override existing instead of creating new? + const showContent: any = parseShow(readFile(showFilePath)) + + if (showContent?.[1]) shows.push(showContent[1]) + } + + if (shows.length) exportTXT({ ...data, shows }) + else toApp(MAIN, { channel: "ALERT", data: "Exported 0 shows!" }) +} + // ----- PROJECT ----- export function exportProject(data: any) { diff --git a/src/electron/data/thumbnails.ts b/src/electron/data/thumbnails.ts index 683f441c..71ddd309 100644 --- a/src/electron/data/thumbnails.ts +++ b/src/electron/data/thumbnails.ts @@ -5,7 +5,6 @@ import { isProd, toApp } from ".." import { MAIN } from "../../types/Channels" import { doesPathExist } from "../utils/files" import { waitUntilValueIsDefined } from "../utils/helpers" -import { defaultSettings } from "./defaults" export function getThumbnail(data: any) { let output = createThumbnail(data.input, data.size || 500) @@ -62,7 +61,7 @@ async function generateThumbnail(data: Thumbnail) { } let thumbnailFolderPath: string = "" -function getThumbnailFolderPath() { +export function getThumbnailFolderPath() { if (thumbnailFolderPath) return thumbnailFolderPath let p: string = path.join(app.getPath("temp"), "freeshow-cache") @@ -90,127 +89,6 @@ function hashCode(str: string) { return "a" + hash.toString() } -///// CUSTOM WINDOW ///// - -// const JS_IMAGE = 'document.querySelector("img")' -// const JS_IMAGE_LOADED = JS_IMAGE + "?.complete" -// const JS_IMAGE_WIDTH = JS_IMAGE + ".naturalWidth" -// const JS_IMAGE_HEIGHT = JS_IMAGE + ".naturalHeight" - -// const JS_VIDEO = 'document.querySelector("video")' -// const JS_VIDEO_READY = JS_VIDEO + "?.readyState" -// const JS_GET_DURATION = JS_VIDEO + ".duration" -// const JS_PAUSE_VIDEO = JS_VIDEO + ".pause()" -// const JS_REMOVE_CONTROLS = JS_VIDEO + '.removeAttribute("controls")' -// const JS_SET_TIME = JS_VIDEO + ".currentTime=" -// const JS_VIDEO_WIDTH = JS_VIDEO + ".videoWidth" -// const JS_VIDEO_HEIGHT = JS_VIDEO + ".videoHeight" - -// let captureWindow: BrowserWindow | null = null -// async function createCaptureWindow(data: any) { -// if (!captureWindow) captureWindow = new BrowserWindow(captureOptions) - -// captureWindow?.loadFile(data.input) - -// // wait until loaded -// let contentLoaded: boolean = false -// captureWindow?.once("ready-to-show", () => { -// contentLoaded = true -// }) -// await waitUntilValueIsDefined(() => contentLoaded, 20, 1000) -// if (!contentLoaded) return exit() - -// let extension = getExtension(data.input) -// if (customImageCapture.includes(extension)) return checkImage() - -// let videoLoaded: any = await waitUntilValueIsDefined(checkIfVideoHasLoaded, 20, 2000) -// if (!videoLoaded) { -// // probably unsupported codec -// if (extension === "mp4") return exit() -// return checkImage() -// } - -// let videoDuration = await captureWindow?.webContents.executeJavaScript(JS_GET_DURATION) -// if (!videoDuration) return exit() - -// let seekTo = Math.floor(videoDuration) * (data.seek ?? 0.5) - -// captureWindow?.webContents.executeJavaScript(JS_PAUSE_VIDEO) -// captureWindow?.webContents.executeJavaScript(JS_REMOVE_CONTROLS) -// captureWindow?.webContents.executeJavaScript(JS_SET_TIME + seekTo) - -// // check if video seek has loaded properly -// await waitUntilValueIsDefined(checkIfVideoHasLoaded, 20) - -// let videoWidth = await captureWindow?.webContents.executeJavaScript(JS_VIDEO_WIDTH) -// let videoHeight = await captureWindow?.webContents.executeJavaScript(JS_VIDEO_HEIGHT) - -// await setWindowSize(videoWidth, videoHeight) - -// captureContent() - -// async function checkImage() { -// let hasLoaded: any = await waitUntilValueIsDefined(checkIfImageHasLoaded, 20, 2000) -// if (!hasLoaded) return exit() - -// let imageWidth = await captureWindow?.webContents.executeJavaScript(JS_IMAGE_WIDTH) -// let imageHeight = await captureWindow?.webContents.executeJavaScript(JS_IMAGE_HEIGHT) - -// await setWindowSize(imageWidth, imageHeight) - -// captureContent() -// return -// } - -// async function setWindowSize(contentWidth: number, contentHeight: number) { -// if (!contentWidth) contentWidth = 1920 -// if (!contentHeight) contentHeight = 1080 - -// const ratio = contentWidth / contentHeight -// let width = data.size?.width -// let height = data.size?.height -// if (!width) width = height ? Math.floor(height * ratio) : contentWidth -// if (!height) height = data.size?.width ? Math.floor(width / ratio) : contentHeight - -// captureWindow?.setSize(width, height) - -// // wait for window and content to get resized -// await wait(50) -// } - -// async function checkIfImageHasLoaded() { -// let imageComplete = await captureWindow?.webContents.executeJavaScript(JS_IMAGE_LOADED) -// return imageComplete -// } - -// async function checkIfVideoHasLoaded() { -// let readyState = await captureWindow?.webContents.executeJavaScript(JS_VIDEO_READY) -// return readyState === 4 -// } - -// async function captureContent() { -// let image = await captureWindow?.webContents.capturePage() -// if (!image) return exit() - -// removeCaptureWindow() -// saveToDisk(data.output, image) -// } - -// function exit() { -// generationFinished() -// } -// } -// function removeCaptureWindow() { -// if (!captureWindow) return -// if (captureWindow.isDestroyed()) { -// captureWindow = null -// return -// } - -// captureWindow.on("closed", () => (captureWindow = null)) -// captureWindow.destroy() -// } - ///// GENERATE ///// interface Config { @@ -218,7 +96,7 @@ interface Config { // format?: "jpg" | "jpeg" | "png" // quality?: number // 0-100 } -const customImageCapture = ["gif", "webp"] +// const customImageCapture = ["gif", "webp"] async function generate(input: string, output: string, size: string, config: Config = {}) { if (!input || !output) { generationFinished() @@ -226,17 +104,11 @@ async function generate(input: string, output: string, size: string, config: Con } const parsedSize = parseSize(size) - let extension = getExtension(input) - - // // mov files can't be opened directly, but can be played as video elem - // if (extension === "mov") return captureWithCanvas({ input, output, size: parsedSize, config }) - // // capture images directly from electron nativeImage (fastest) - // if (!customImageCapture.includes(extension) && defaultSettings.imageExtensions.includes(extension)) return captureImage(input, output, parsedSize) - // // capture videos in custom window (to reduce load on main window) - // createCaptureWindow({ input, output, size: parsedSize, config }) // WIP this would many times create a save dialog window in some cases + // let extension = getExtension(input) // capture images directly from electron nativeImage (fastest) - if (!customImageCapture.includes(extension) && defaultSettings.imageExtensions.includes(extension)) return captureImage(input, output, parsedSize) + // WIP this was unreliable + // if (!customImageCapture.includes(extension) && defaultSettings.imageExtensions.includes(extension)) return captureImage(input, output, parsedSize) // capture other media with canvas in main window await captureWithCanvas({ input, output, size: parsedSize, extension: getExtension(input), config }) @@ -265,12 +137,12 @@ export function saveImage(data: any) { } // https://www.electronjs.org/docs/latest/api/native-image -function captureImage(input: string, output: string, size: ResizeOptions) { - let outputImage = nativeImage.createFromPath(input) - outputImage = outputImage.resize(size) +// function captureImage(input: string, output: string, size: ResizeOptions) { +// let outputImage = nativeImage.createFromPath(input) +// outputImage = outputImage.resize(size) - saveToDisk(output, outputImage) -} +// saveToDisk(output, outputImage) +// } function getExtension(filePath: string) { return path.extname(filePath).slice(1).toLowerCase() diff --git a/src/electron/index.ts b/src/electron/index.ts index 77701683..8d7873ae 100644 --- a/src/electron/index.ts +++ b/src/electron/index.ts @@ -87,7 +87,7 @@ function mainWindowLoaded() { initialize() - if (config.get("maximized")) mainWindow!.maximize() + if (config.get("maximized")) maximizeMain() mainWindow?.show() loadingWindow?.close() diff --git a/src/electron/preload.ts b/src/electron/preload.ts index 889573c1..c49caca1 100644 --- a/src/electron/preload.ts +++ b/src/electron/preload.ts @@ -11,7 +11,7 @@ import type { ValidChannels } from "../types/Channels" // wait to log messages until after intial load is done let appLoaded: boolean = false const LOG_MESSAGES: boolean = process.env.NODE_ENV !== "production" -const filteredChannels: any[] = ["AUDIO_MAIN", "VIZUALISER_DATA", "STREAM", "PREVIEW", "REQUEST_STREAM", "MAIN_TIME"] +const filteredChannels: any[] = ["AUDIO_MAIN", "VIZUALISER_DATA", "STREAM", "PREVIEW", "REQUEST_STREAM", "MAIN_TIME", "GET_THUMBNAIL"] let storedReceivers: any = {} diff --git a/src/electron/utils/responses.ts b/src/electron/utils/responses.ts index 25500b6f..dce9fc2e 100644 --- a/src/electron/utils/responses.ts +++ b/src/electron/utils/responses.ts @@ -13,7 +13,7 @@ import { restoreFiles } from "../data/backup" import { downloadMedia } from "../data/downloadMedia" import { importShow } from "../data/import" import { error_log } from "../data/store" -import { getThumbnail, saveImage } from "../data/thumbnails" +import { getThumbnail, getThumbnailFolderPath, saveImage } from "../data/thumbnails" import { outputWindows } from "../output/output" import { closeServers, startServers } from "../servers" import { Message } from "./../../types/Socket" @@ -107,6 +107,7 @@ const mainResponses: any = { DATA_PATH: (): string => getDocumentsFolder(null, ""), LOG_ERROR: (data: any) => logError(data), OPEN_LOG: () => openSystemFolder(error_log.path), + OPEN_CACHE: () => openSystemFolder(getThumbnailFolderPath()), // SHOWS DELETE_SHOWS: (data: any) => deleteShowsNotIndexed(data), REFRESH_SHOWS: (data: any) => refreshAllShows(data), diff --git a/src/frontend/App.svelte b/src/frontend/App.svelte index e35a8bb8..34b5c62e 100644 --- a/src/frontend/App.svelte +++ b/src/frontend/App.svelte @@ -4,11 +4,13 @@ import ContextMenu from "./components/context/ContextMenu.svelte" import Pdf from "./components/export/Pdf.svelte" import { startEventTimer, startTimer } from "./components/helpers/timerTick" + import Loader from "./components/main/Loader.svelte" import MenuBar from "./components/main/MenuBar.svelte" import Popup from "./components/main/Popup.svelte" import Recorder from "./components/main/Recorder.svelte" import Toast from "./components/main/Toast.svelte" - import { activeTimers, autosave, closeAd, currentWindow, disabledServers, events, os, outputDisplay } from "./stores" + import Center from "./components/system/Center.svelte" + import { activeTimers, autosave, closeAd, currentWindow, disabledServers, events, loaded, os, outputDisplay } from "./stores" import { focusArea, logerror, startAutosave, toggleRemoteStream } from "./utils/common" import { keydown } from "./utils/shortcuts" import { startup } from "./utils/startup" @@ -29,7 +31,7 @@ $: if ($autosave) startAutosave() // stream to OutputShow - $: if (!$currentWindow && ($disabledServers.output_stream !== "" || !$outputDisplay)) toggleRemoteStream() + $: if (($loaded && $disabledServers.output_stream !== "") || !$outputDisplay) setTimeout(toggleRemoteStream, 1000) // close youtube ad $: if ($closeAd) setTimeout(() => closeAd.set(false), 10) @@ -40,6 +42,7 @@ {#if $currentWindow === "pdf"} {:else} + {#if isWindows} {/if} @@ -49,15 +52,16 @@ {#if $currentWindow === "output"} - {:else} - - - + {:else if $loaded} + {:else} +
+ +
{/if} {/if} @@ -73,14 +77,4 @@ .closeAd { height: 1px; } - - /* .black { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: black; - z-index: 500; - } */ diff --git a/src/frontend/components/actions/actions.ts b/src/frontend/components/actions/actions.ts index ebc57c5b..45b4d9c9 100644 --- a/src/frontend/components/actions/actions.ts +++ b/src/frontend/components/actions/actions.ts @@ -93,6 +93,10 @@ export function addSlideAction(slideIndex: number, actionId: string, actionValue history({ id: "SHOW_LAYOUT", newData: { key: "actions", data: actions, indexes: [slideIndex] } }) } +export function slideHasAction(actions: any, key: string) { + return actions?.slideActions?.find((a) => a.triggers?.includes(key)) +} + // extra names const namedObjects = { diff --git a/src/frontend/components/context/menuClick.ts b/src/frontend/components/context/menuClick.ts index 9e8940ff..3a4b6d2a 100644 --- a/src/frontend/components/context/menuClick.ts +++ b/src/frontend/components/context/menuClick.ts @@ -83,7 +83,11 @@ const actions: any = { save: () => save(), import: () => activePopup.set("import"), export_more: () => activePopup.set("export"), - settings: () => activePage.set("settings"), + settings: () => { + if (get(activePage) === "stage") settingsTab.set("connection") + else if (get(activePage) === "settings") settingsTab.set("general") + activePage.set("settings") + }, quit: () => { if (get(saved)) send(MAIN, ["CLOSE"]) else activePopup.set("unsaved") diff --git a/src/frontend/components/draw/Paint.svelte b/src/frontend/components/draw/Paint.svelte index f36e753e..b70b1142 100644 --- a/src/frontend/components/draw/Paint.svelte +++ b/src/frontend/components/draw/Paint.svelte @@ -6,7 +6,7 @@ export let settings: any = {} - $: currentOutput = $outputs[getActiveOutputs()[0]] + $: currentOutput = $outputs[getActiveOutputs()[0]] || {} $: currentLayout = currentOutput.out?.slide ? _show(currentOutput.out.slide.id).layouts([currentOutput.out.slide.layout]).ref()[0] : [] $: currentSlide = currentOutput.out?.slide ? (currentOutput.out.slide.id === "temp" ? { items: currentOutput.out.slide.tempItems } : _show(currentOutput.out.slide.id).slides([currentLayout![currentOutput.out.slide.index!].id]).get()[0]) : null $: resolution = getResolution(currentSlide?.settings?.resolution, { $outputs, $styles }) diff --git a/src/frontend/components/draw/Slide.svelte b/src/frontend/components/draw/Slide.svelte index 6215da7f..2d917171 100644 --- a/src/frontend/components/draw/Slide.svelte +++ b/src/frontend/components/draw/Slide.svelte @@ -66,7 +66,7 @@
-
+
diff --git a/src/frontend/components/drawer/bible/Scripture.svelte b/src/frontend/components/drawer/bible/Scripture.svelte index b65dc715..8a6ded6c 100644 --- a/src/frontend/components/drawer/bible/Scripture.svelte +++ b/src/frontend/components/drawer/bible/Scripture.svelte @@ -31,7 +31,6 @@ let chapterId: any = cachedRef?.chapterId ?? "GEN.1" let activeVerses: string[] = cachedRef?.activeVerses || ["1"] - $: console.log(verses, bibles) $: if (bookId || chapterId || verses || activeVerses) updateActive() function updateActive() { if (!loaded) return diff --git a/src/frontend/components/drawer/bible/scripture.ts b/src/frontend/components/drawer/bible/scripture.ts index 13149693..05731abf 100644 --- a/src/frontend/components/drawer/bible/scripture.ts +++ b/src/frontend/components/drawer/bible/scripture.ts @@ -7,6 +7,7 @@ import { clone, removeDuplicates } from "../../helpers/array" const api = "https://api.scripture.api.bible/v1/bibles/" let tempCache: any = {} +let fetchTimeout: any = null export async function fetchBible(load: string, active: string, ref: any = { versesList: [], bookId: "GEN", chapterId: "GEN.1" }) { let versesId: any = null if (ref.versesList.length) { @@ -22,19 +23,27 @@ export async function fetchBible(load: string, active: string, ref: any = { vers versesText: `${api}${active}/verses/${versesId}`, } + if (fetchTimeout) clearTimeout(fetchTimeout) if (tempCache[urls[load]]) return tempCache[urls[load]] return new Promise((resolve, reject) => { if (!get(bibleApiKey)) return reject("No API key!") if (urls[load].includes("null")) return reject("Something went wrong!") + fetchTimeout = setTimeout(() => { + // WIP display error messages... + reject("Timed out!") + }, 10000) + fetch(urls[load], { headers: { "api-key": get(bibleApiKey) } }) .then((response) => response.json()) .then((data) => { tempCache[urls[load]] = data.data + clearTimeout(fetchTimeout) resolve(data.data) }) .catch((e) => { + clearTimeout(fetchTimeout) reject(e) }) }) diff --git a/src/frontend/components/drawer/live/NDIStreams.svelte b/src/frontend/components/drawer/live/NDIStreams.svelte index 03680935..da6e35a6 100644 --- a/src/frontend/components/drawer/live/NDIStreams.svelte +++ b/src/frontend/components/drawer/live/NDIStreams.svelte @@ -9,7 +9,7 @@ let sources: any[] = [] - $: currentOutput = $outputs[getActiveOutputs()[0]] + $: currentOutput = $outputs[getActiveOutputs()[0]] || {} const receiveNDI: any = { RECEIVE_LIST: (msg) => { diff --git a/src/frontend/components/drawer/live/Screens.svelte b/src/frontend/components/drawer/live/Screens.svelte index b7c289e4..3a1223f9 100644 --- a/src/frontend/components/drawer/live/Screens.svelte +++ b/src/frontend/components/drawer/live/Screens.svelte @@ -13,7 +13,7 @@ receive(MAIN, { GET_SCREENS: (d: any) => (screens = d) }, "GET_SCREENS") onDestroy(() => destroy(MAIN, "GET_SCREENS")) - $: currentOutput = $outputs[getActiveOutputs()[0]] + $: currentOutput = $outputs[getActiveOutputs()[0]] || {} $: console.log(screens) diff --git a/src/frontend/components/drawer/live/Windows.svelte b/src/frontend/components/drawer/live/Windows.svelte index 1c9943fb..b3f37c37 100644 --- a/src/frontend/components/drawer/live/Windows.svelte +++ b/src/frontend/components/drawer/live/Windows.svelte @@ -27,7 +27,7 @@ if (searchValue.length > 1) fullFilteredWindows = fullFilteredWindows.filter((a) => filter(a.name).includes(searchValue)) } - $: currentOutput = $outputs[getActiveOutputs()[0]] + $: currentOutput = $outputs[getActiveOutputs()[0]] || {} {#if fullFilteredWindows.length} diff --git a/src/frontend/components/drawer/media/Media.svelte b/src/frontend/components/drawer/media/Media.svelte index 9d408947..d87fafb0 100644 --- a/src/frontend/components/drawer/media/Media.svelte +++ b/src/frontend/components/drawer/media/Media.svelte @@ -238,7 +238,7 @@ zoomOpened = false } - $: currentOutput = $outputs[getActiveOutputs()[0]] + $: currentOutput = $outputs[getActiveOutputs()[0]] || {} // select all $: if ($selectAllMedia) selectAll() diff --git a/src/frontend/components/drawer/media/MediaLoader.svelte b/src/frontend/components/drawer/media/MediaLoader.svelte index 1636d8f8..39022919 100644 --- a/src/frontend/components/drawer/media/MediaLoader.svelte +++ b/src/frontend/components/drawer/media/MediaLoader.svelte @@ -21,6 +21,7 @@ export let loaded: boolean = false export let resolution: Resolution | null = null export let duration: number = 0 + export let getDuration: boolean = false export let videoElem: any = null $: if (path) loaded = false @@ -39,7 +40,7 @@ $: if (mediaStyle.speed && videoElem) videoElem.playbackRate = mediaStyle.speed $: if (!videoElem) duration = 0 - function getDuration() { + function getCurrentDuration() { if (!videoElem || duration) return duration = videoElem.duration @@ -71,15 +72,17 @@ $: useOriginal = hover || loadFullImage || retryCount > 5 || !thumbnailPath // get duration - $: if (type === "video" && thumbnailPath) getVideoDuration() + $: if (getDuration && type === "video" && thumbnailPath) getVideoDuration() function getVideoDuration() { - let video = document.createElement("video") - video.onloadeddata = () => { - duration = video.duration || 0 - // video.pause() - video.src = "" - } - video.src = path + setTimeout(() => { + let video = document.createElement("video") + video.onloadeddata = () => { + duration = video.duration || 0 + // video.pause() + video.src = "" + } + video.src = path + }, 20) } @@ -109,7 +112,7 @@ {/key} {/if} {#if type === "video" && useOriginal} -