diff --git a/public/import-logos/verseview.webp b/public/import-logos/verseview.webp index 8d50fd06..f9020de5 100644 Binary files a/public/import-logos/verseview.webp and b/public/import-logos/verseview.webp differ diff --git a/public/lang/en.json b/public/lang/en.json index e0f99ab3..d37ea38a 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -316,7 +316,7 @@ "primary-darkest": "Primary darkest", "text": "Text", "textInvert": "Inverted text", - "secondary-text": "Secondary text", + "secondary-text": "Selections", "secondary": "Secondary", "secondary-opacity": "Secondary opacity", "hover": "Hover", @@ -429,6 +429,7 @@ "manage_icons": "Manage icons", "manage_colors": "Manage colors", "choose_camera": "Choose camera", + "manage_tags": "Manage tags", "initialize": "Welcome to FreeShow", "unsaved": "Are you sure you want to quit?", "cancel": "Cancel", @@ -465,6 +466,7 @@ "deleted_cache": "Deleted media thumbnail cache.", "no_songswords_easyworship": "Missing SongsWords.db file.", "delete_shows_empty": "No shows to delete.", + "output_capture_enabled": "Output screen capture enabled, this may cause performance issues. Only use if needed!", "midi_no_project": "Received trigger to change project, but no project found at index:", "midi_no_show": "Received trigger to start slide, but no show active.", "midi_no_slide": "Received trigger to start slide, but no slide found at index:", diff --git a/public/lang/pt_BR.json b/public/lang/pt_BR.json index f64a1562..6731eded 100644 --- a/public/lang/pt_BR.json +++ b/public/lang/pt_BR.json @@ -163,6 +163,7 @@ "toggle_shuffle": "Aleatório", "next": "Próximo", "previous": "Anterior", + "play_no_audio": "Executar sem áudio", "play_no_filters": "Reproduzir sem filtros", "favourite": "Favoritar", "pause": "Pausa", @@ -194,7 +195,10 @@ "playlist_settings": "Configurações de listas de reprodução", "custom_output": "Saída de áudio personalizada", "mute_when_video_plays": "Tornar mudo quando um vídeo reproduzir", + "allow_gaining": "Permitir ganho", + "allow_gaining_tip": "Permitir configurar volume acima de 100% (Pode causar distorção)", "pre_fader_volume_meter": "Exibir volume antes do fader", + "mixer": "Mixer", "metronome": "Metrônomo", "toggle_metronome": "Metrônomo", "tempo": "Tempo", @@ -269,15 +273,17 @@ "ip": "Não foi possível obter o endereço IP do seu dispositivo. Acesse as configurações de Wi-Fi do computador para encontrar seu endereço IPv4 local." }, "meta": { + "number": "Número", "title": "Título", "artist": "Artista", "author": "Autor", "composer": "Compositor", "publisher": "Editor", "copyright": "Direitos autorais", - "CCLI": "Licença (CCLI)", + "CCLI": "ID da música (CCLI)", "year": "Ano", "key": "Chave", + "autofill": "Preencher automaticamente", "message": "Mensagem", "message_tip": "Mostra algo em todos os slides", "auto_media": "Copiar metadados da mídia", @@ -362,7 +368,8 @@ "music": "Musica", "offers": "Ofertas", "notice": "Avisos", - "visuals": "Visuais" + "visuals": "Visuais", + "action_tip": "Uma ação que será ativada toda vez que um Show desta categoria for apreesentado." }, "groups": { "current": "Atual", @@ -400,6 +407,7 @@ "change_output_values": "Mudar valores de saída", "choose_chord": "Escolha o acorde", "set_time": "Definir tempo", + "slide_shortcut": "Atalho para slide", "animate": "Animar", "translate": "Traduzir", "next_timer": "Temporizador do próximo slide", @@ -413,6 +421,7 @@ "about": "Sobre", "history": "Histórico", "action": "Ação", + "category_action": "Ação de categoria", "connect": "Conectar", "cloud_update": "Sincronizando com a nuvem", "cloud_method": "Dados", @@ -547,6 +556,8 @@ "zoomIn": "Mais Zoom", "zoomOut": "Menos Zoom", "reset": "Redefinir", + "create_template": "Criar modelo de projeto", + "project_template_tip": "Cria um novo projeto a partir deste modelo", "convert_to_images": "Converter para imagens", "converting": "Convertendo...", "remove_template_from_show": "Remover modelo da apresentação", @@ -587,10 +598,10 @@ "click_disable": "Clique em qualquer para desativar", "svg_clipboard": "Importar SVG da área de transferência", "fullscreen_preview": "Pré-visualização em tela cheia", - "toggle_output": "Alternar tela de saída", + "toggle_output": "Ativar tela de saída", "toggle_panels": "Esconder/Mostrar painéis", "change_tab": "Alterar guia", - "change_drawer_tab": "Alterar guia de desenho", + "change_drawer_tab": "Alterar guia do Drawer", "change_slide": "Mudar slide", "change_project_item": "Mudar item do projeto", "change_drawer_item": "Mudar item do Drawer", @@ -608,6 +619,8 @@ "set_key": "Definir chave", "custom_key": "Definir valor personalizado", "select_chord": "Selecione esse acorde", + "play_with_shortcut": "Ativar com atalho", + "press_to_assign": "Aperte qualquer letra para assinalar", "play_on_midi": "Ativar ao sinal MIDI", "play_on_midi_tip": "Ativar este específico slide quando receber sinal MIDI específico", "send_midi": "Enviar sinal MIDI", @@ -624,6 +637,7 @@ "next_after_media": "Depois da mídia concluir", "remove_media": "Remover mídia", "remove_layers": "Remover camadas", + "toggle_checkbox_tip": "A ação irá ativar se uma caixa de marcação não for alterada", "start_recording": "Iniciar gravação", "stop_recording": "Parar gravação", "export_recording": "Para de gravar e exportar", @@ -632,6 +646,7 @@ "previous_project_item": "Item anterior do projeto", "index_select_project_item": "Selecionar item do projeto pelo índice", "name_select_show": "Selecionar Show pelo nome", + "set_template_active": "Aplicar modelo no Show ativo", "random_slide": "Reproduzir slide aleatório", "index_select_slide": "Selecionar slide pelo índice", "name_select_slide": "Selecionar slide pelo nome", @@ -672,6 +687,7 @@ "activate_slide_cleared": "Ativar quando limpar o slide", "activate_background_cleared": "Ativar quando limpar o background", "activate_show_created": "Ativar quando um Show é criado", + "activate_show_opened": "Ativar quando um Show for aberto", "activate_audio_playlist_ended": "Ativar quando uma playlist de áudio termina" }, "recording": { @@ -679,7 +695,9 @@ "tip": "Grave e reproduza os tempos de cada slide. Sincronize com uma faixa de áudio no primeiro slide.", "layout_changed": "O layout mudou desde a última gravação!", "audio_synced": "Sincronizado com áudio!", - "start": "Iniciar gravação de slide" + "start": "Iniciar gravação de slide", + "use_duration": "Usar tempo de duração", + "use_duration_tip": "Usar tempo de duração ao invés de tempo marcado" }, "animate": { "change": "Mudar", @@ -738,6 +756,7 @@ }, "context": { "enabledTabs": "Alternar guias", + "setTag": "Adicionar tag", "filterByTags": "Filtrar por tags", "addToProject": "Adicionar ao projeto", "add_to_show": "Adicionar ao Show", @@ -796,6 +815,8 @@ "overlay_content": "Adicionar conteúdo de sobreposição", "different_first_template": "Usar outro modelo no primeiro slide", "media_fit": "Fazer mídia caber", + "one_letter": "Modo de letra única", + "sub_indexes": "Sub índices ", "size": "Tamanho", "max_lines": "Máximo de linhas", "invert_items": "Inverter items", @@ -916,6 +937,7 @@ "to_event": "Tempo até o evento", "counter": "Contagem regressiva", "time": "Tempo", + "minutes": "Minutos", "seconds": "Segundos", "from": "A partir de", "to": "Até", @@ -1063,6 +1085,7 @@ "group_numbers": "Números do grupo", "full_colors": "Ativar alto contraste entre grupos", "slide_number_keys": "Usar teclas de números para controlar slides", + "auto_shortcut_first_letter": "Usar a primeira letra como atalho", "auto_output": "Mostrar tela de saída na inicialização", "hide_cursor_in_output": "Esconder cursor na saída", "clear_media_when_finished": "Limpar mídia ao terminar", @@ -1124,7 +1147,8 @@ "auto": "Automático", "optimized": "Otimizado", "reduced": "Reduzido", - "full": "Completo" + "full": "Completo", + "section_trigger_action": "Ativar ação quando navegar de uma apresentação para uma seção" }, "sort": { "sort_by": "Ordenar por", @@ -1172,6 +1196,7 @@ "reference": "Mostrar referência", "split_reference": "Referência dividida", "combine_with_text": "Combinar com o texto", + "first_slide_reference": "Referência no primeiro slide", "reference_at_bottom": "Mover para o rodapé", "red_jesus": "Palavras de Jesus em vermelho", "search": "Procurar na Bíblia" diff --git a/public/lang/sk.json b/public/lang/sk.json index 41fd4942..c25487ee 100644 --- a/public/lang/sk.json +++ b/public/lang/sk.json @@ -7,25 +7,57 @@ "unnamed": "Bez názvu", "drop": "Pusti sem", "search": "Hľadať", + "quick_search": "Rýchle hľadanie", "none": "Nič", "finished": "Dokončené", + "open": "Otvoriť", "system_open": "Otvoriť v systéme" }, + "formats": { + "show": "Zobraziť", + "project": "Projekt", + "template": "Šablóna", + "theme": "Téma", + "clipboard": "Schránka", + "text": "Textový súbor" + }, + "guide": { + "start": "Príručka rýchleho štartu", + "skip": "Preskočiť" + }, + "titlebar": { + "file": "Súbor", + "edit": "Upraviť", + "view": "Zobrazenie", + "help": "Pomoc" + }, + "screen": { + "width": "Šírka", + "height": "Výška", + "pixels": "pixelov", + "top": "Hore", + "right": "Vpravo", + "bottom": "Dole", + "left": "Vľavo" + }, "about": { "check_updates": "Skontrolovať aktualizácie", "made": "Vyrobil v Nórsku", - "report": "Chcete nahlásiť problém? Vytvorte issue na GitHube", - "help": "Chcete pomôcť s prekladom alebo implementovať funkciu? Napíšte email na", + "more": "Zistite viac o našej aplikácii na", + "report": "Nahlásiť problém alebo požiadať o funkciu môžete na", + "translate": "Chcete pomôcť prekladať? Prosím prejdite na", + "mail": "Kontaktovať emailom", + "support": "Ak ste vďační za tento projekt, prosím zvážte jeho podporu", "assets": "Použité materiály", "libraries": "Použité knižnice", "thanks": "Ďakujeme", "new_update": "Aktualizácia je k dispozícii", - "download": "Stiahnite z freeshow.app", + "download": "Aplikáciu aktualizujete reštartovaní, alebo prejdite na freeshow.app a stiahnite ručne", "changes": "Čo je nové" }, "tooltip": { "project": "Vytvorí projekt, kde môžete pridávať a upravovať prezentácie.", - "show": "Vytvorí nové prezentácie, kde môžete pridávať texty piestí, prezentácie a médiá. Podržaním Ctrl/Cmd sa vytvorí prázdne.", + "show": "Vytvorí novú prezentáciu kde môžete pridávať texty piesní, snímky a médiá.", "groups": "Všetky skupiny v aktuálnej prezentácii a všetkých globálnych skupinách. Kliknutím alebo presunutím ich pridáte do aktuálneho rozloženia.", "layout": "Pridá prechody a časovače do snímkov v aktuálnom rozložení.", "media": "Všetky médiá v aktuálnej prezentácii. Môžete ich zobraziť alebo presunúť do aktuálneho rozloženia.", @@ -39,6 +71,9 @@ "options": "Viac možností.", "scripture": "Držaním Ctrl/Cmd alebo Shift označíte viac veršov." }, + "tips": { + "trigger": "Spúšťače sa zvyknú používať na odoslanie HTTP požiadavky na zmenu nastavení kamier." + }, "setup": { "good_luck": "Dúfam, že vám tento softvér bude užitočný. Veľa šťastia pri prezentácii! :)", "tips": "Na webstránke nájdete tipy a návody.", @@ -62,27 +97,22 @@ "small": "Malé", "bold": "Tučné" }, - "titlebar": { - "file": "Súbor", - "edit": "Upraviť", - "view": "Zobrazenie", - "help": "Pomoc" - }, - "screen": { - "width": "Šírka", - "height": "Výška", - "pixels": "pixelov", - "top": "Hore", - "right": "Vpravo", - "bottom": "Dole", - "left": "Vľavo" - }, "create_show": { + "web": "Hľadať na webe", "search_web": "Hľadať pieseň na webe", + "search_results": "Výsledky hľadania", "more_options": "Viac možností", + "auto_groups": "Automaticky priradené skupiny", "format_new_show": "Formátovať text", - "split_lines": "Počty riadkov", - "quick_lyrics_example_text": "Riadok" + "format_new_show_tip": "Vylepší formát textu automatickými kapitálkami, oreže/spojí text a iné.", + "split_lines": "Max počet riadkov na snímok", + "split_lines_tip": "Počet riadkov povolený na snímok pre automatickým rozdelením", + "quick_lyrics": "Rýchle texty", + "quick_lyrics_tip": "Vložte alebo napíšte text", + "quick_lyrics_example_tip": "Sem zadajte text", + "quick_lyrics_example_text": "Riadok", + "empty": "Prázdna prezentácia", + "exists": "Našla sa existujúca prezentácia s rovnakým názvom" }, "preview": { "_previous_show": "Predchádzajúca prezentácia", @@ -105,7 +135,8 @@ "to_start": "Prejsť a začiatok", "nextTimer": "Časovač ďalšieho snímku", "lock": "Zamknúť", - "unlock": "Odomknúť" + "unlock": "Odomknúť", + "test_pattern": "Testovací vzor" }, "clear": { "all": "Vyčistiť všetko", @@ -113,7 +144,8 @@ "slide": "Vyčistit snímok", "overlays": "Vyčistiť prvky", "audio": "Vyčistiť audio", - "nextTimer": "Vyčistit časovač ďalšieho snímku" + "nextTimer": "Vyčistit časovač ďalšieho snímku", + "drawing": "Vyčistiť kresbu" }, "remove": { "background": "Odstrániť pozadie", @@ -127,6 +159,11 @@ "media": { "_loop": "Slučka", "play": "Prehrať", + "play_multiple": "Prehrať viaceré", + "toggle_shuffle": "Prepnúť náhodné", + "next": "Ďalšie", + "previous": "Predošlé", + "play_no_audio": "Prehrať bez zvuku", "play_no_filters": "Prehrať bez filtrov", "favourite": "Obľúbené", "pause": "Pauza", @@ -138,6 +175,8 @@ "speed": "Rýchlosť", "show": "Zobraziť", "flip": "Preklopiť", + "flip_horizontally": "Prevrátiť horizontálne", + "flip_vertically": "Prevrátiť vertikálne", "all": "Priečinky, obrázky a videá", "folder": "Len priečinky", "image": "Len obrázky", @@ -146,7 +185,25 @@ "contain": "Obsiahnuť", "fill": "Vyplniť", "cover": "Pokryť", - "online": "Online" + "online": "Online", + "recommended": "Odporúčané", + "bundle_media_files": "Pripojiť všetky media súbory", + "bundle_media_files_tip": "Skopíruje media súbory zo všetkých prezentácií do jedného priečinka" + }, + "audio": { + "settings": "Audio nastavenia", + "playlist_settings": "Playlist nastavenia", + "custom_output": "Vlastný audio výstup", + "mute_when_video_plays": "Stíšiť keď hrá video", + "allow_gaining": "Povoliť hlasitosť", + "allow_gaining_tip": "Povolí zvýšenie hlasitosti na 100% (Môže skresliť zvuk)", + "pre_fader_volume_meter": "Pre fader ukazovateľ hlasitosti", + "mixer": "Mix", + "metronome": "Metronóm", + "toggle_metronome": "Prepnúť metronóm", + "tempo": "Tempo", + "bpm": "BPM", + "beats": "Takty" }, "menu": { "show": "Prezentácia", @@ -162,7 +219,8 @@ "settings": "Nastavenia", "_title_settings": "Nastavenia", "_title_display": "Prezentovať", - "_title_display_stop": "Zastaví prezentáciu" + "_title_display_stop": "Zastaví prezentáciu", + "again_confirm": "Kliknutím znova potvrdíte" }, "empty": { "general": "Prázdne", @@ -197,7 +255,8 @@ "loading": "Načítanie...", "submit": "Poslať", "password": "Heslo", - "wrong_password": "Nesprávne heslo" + "wrong_password": "Nesprávne heslo", + "quick_play": "Rýchle prehratie" }, "error": { "no_show": "Nenašla sa prezentácia", @@ -209,25 +268,33 @@ "display": "Nepodarilo sa zobraziť výstupné okno na aktuálnej obrazovke", "keep_one_layout": "Musíte mať aspoň jedno rozloženie", "video_unavailable": "Video nie je dostupné? Tvorca zakázal vkladanie videa.", - "folder_exists": "Tento priečinok už existuje" + "folder_exists": "Tento priečinok už existuje", + "uri": "Nepodarilo sa rozparsovať názov audia, prosím premenujte súbor", + "ip": "Nepodarilo sa zistiť IP adresu vášho zariadenia, prosím prejdite do nastavení Wi-Fi a nájdite vašu IPv4 adresu." }, "meta": { + "number": "Číslo", "title": "Názov", "artist": "Umelec", "author": "Autor", "composer": "Skladateľ", "publisher": "Vydavateľ", "copyright": "Copyright", - "CCLI": "Licencia (CCLI)", + "CCLI": "ID piesne (CCLI)", "year": "Rok", + "key": "Kľúč", + "autofill": "Autovyplnenie", "message": "Správa", "message_tip": "Zobrazí niečo na všetkých snímkoch", "auto_media": "Meta z mediálneho obsahu", - "override_output": "Prepísať štýl vo výstupe", + "override_output": "Prepíše výstupný štýl", "display_metadata": "Zobrazovať metadata", "meta_template": "Šablóna metadát", "text_divider": "Oddeľovač textu", - "message_template": "Šablóna správy" + "message_template": "Šablóna správy", + "tags": "Značky", + "new_tag": "Nová značka", + "clear_tag_filter": "Vymazať filter značiek" }, "show_at": { "never": "Žiadne snímky", @@ -256,14 +323,16 @@ "hover": "Hover", "focus": "Focus" }, - "buttons": { - "changeTheme": "Zmeniť tému" - }, "inputs": { "name": "Názov", "url": "URL", + "method": "Metóda", + "contentType": "Typ obsahu", + "payload": "Obsah", "video_id": "Video ID/URL", "close_ad": "Zavrieť reklamu na výstupnej obrazovke", + "start": "Začiatok", + "end": "Koniec", "change_folder": "Zvoliť iné umiestnenie" }, "tabs": { @@ -274,12 +343,16 @@ "effects": "Efekty", "scripture": "Biblia", "calendar": "Kalendár", + "functions": "Funkcie", + "actions": "Akcie", "player": "Prehrávač", "live": "Naživo", "timers": "Časovače", "variables": "Variables", + "triggers": "Spúšťače", "templates": "Šablóny", - "web": "Web" + "web": "Web", + "search_tip": "Vyhľadávanie v zásuvke" }, "category": { "all": "Všetko", @@ -295,12 +368,15 @@ "music": "Hudba", "offers": "Ponuky", "notice": "Oznamy", - "visuals": "Vizuály" + "visuals": "Vizuály", + "action_tip": "Akcia, ktorá sa spustí pri každej prezentácii s touto kategóriou." }, "groups": { "current": "Aktuálne", "global": "Globálne", "toggle_global_group": "Toggle global groups", + "group_shortcut": "Skupinové skratky", + "group_template": "Skupinová šablóna", "intro": "Úvod", "verse": "Verš", "pre_chorus": "Pre Chorus", @@ -319,17 +395,24 @@ "edit_list": "Upraviť zoznam", "timer": "Časovač", "variable": "Variable", + "trigger": "Spúšťač", + "audio_stream": "Audio stream", "transition": "Prechod", "delete_show": "Odstrániť prezentáciu", "delete_show_confirmation": "Naozaj ju chcete odstrániť?", + "delete_duplicated_shows": "Odstrániť duplicitné prezentácie", "change_name": "Premenovať", "choose_screen": "Vyberte obrazovku", + "choose_output": "Zvoľte typ výstupu", "change_output_values": "Zmeniť výstupné hodnoty", - "choose_style": "Vybrať štýl", + "choose_chord": "Zvoľte akord", "set_time": "Nastaviť čas", + "slide_shortcut": "Skratka snímku", "animate": "Animovať", + "translate": "Lokalizácia", "next_timer": "Časovač ďalšieho snímku", "import": "Import", + "songbeamer_import": "Songbeamer import", "export": "Export", "importing": "Importovanie", "import_scripture": "Import biblie", @@ -337,16 +420,18 @@ "edit_event": "Upraviť udalosť", "about": "Viac info", "history": "História", - "midi": "MIDI", + "action": "Akcia", + "category_action": "Akcia kategórie", "connect": "Pripojiť", "cloud_update": "Synchronizácia s cloudom", "cloud_method": "Miestp dát", "shortcuts": "Skratky", "icon": "Ikony", "manage_icons": "Spravovať ikony", + "manage_colors": "Spravovať farby", "choose_camera": "Zvoľte kameru", "initialize": "Vitajte vo FreeShow", - "unsaved": "Máte neuložené zmeny! Naozaj chcete ukončiť?", + "unsaved": "Naozaj si prajete skončiť?", "cancel": "Zrušiť", "continue": "Pokračovať", "reset_all": "Všetko resetovať", @@ -364,33 +449,39 @@ "verse_undefined": "Verš {} neexistuje v tejto kapitole.", "recording_started": "Nahrávanie začalo!", "recording_stopped": "Nahrávanie skončilo!", - "starting_show": "Začína prezentácia", + "starting_action": "Akcia pri štarte", "less_than_minute": "o menej než minútu.", "less_than_seconds": "o menej než {} sekúnd.", "now": "teraz!", + "unsupported_video": "Nepodporovan video!", "no_video_id": "Žiadne video ID", "no_name": "Žiadny názov", + "reverting_setting": "Táto zmena sa vráti o {} sekúnd, zapnite znova aby zmena ostala!", + "reverted": "Nastavenie vrátené! Zapnite len ak ste nemali žiadne problémy.", "media_replaced": "Chýbajúci media súbor nahradený iným.", "lyrics_undefined": "Nenašli sa žiadne texty!", - "lyrics_copied": "Texty skopírované z ", - "no_pdf_linux": "Nedá sa exportovať PDF na Linuxe.", + "lyrics_copied": "Texty skopírované z", "one_output": "Musíte mať aspoň jeden aktívny výstup!", "empty_cache": "Cache je prázdna.", "deleted_cache": "Cache náhľadov zmazaných médií.", "no_songswords_easyworship": "Chýba súbor SongsWords.db.", "delete_shows_empty": "Žiadne prezentácie na zmazanie.", - "midi_no_project": "Prijatý MIDI na zmenu projektu, ale nenašiel sa žiadny projekt na pozícii:", - "midi_no_show": "Prijatý MIDI na spustenie snímku, ale nie je aktívna prezentácia.", - "midi_no_slide": "Prijatý MIDI na spustenie snímku, ale nenašiel sa snímok na pozícii:", + "midi_no_project": "Prijatý spúšťač na zmenu projektu, ale žiadny projekt sa nenašiel na danom indexe:", + "midi_no_show": "Prijatý spúšťač na zmenu snímku, ale žiadna prezentácia nie je aktívna.", + "midi_no_slide": "Prijatý spúšťač na zmenu snímku, ale snímok sa nenašiel na danom indexe:", "midi_no_velocity": "Prijatý MIDI signál, ale bez velocity, predvolene ide na prvú pozíciu." }, "new": { + "create": "Vytvoriť nové", "show": "Nová prezentácia", "empty_show": "Nová prázdna prezentácia", "project": "Nový projekt", "section": "Nová sekcia", "timer": "Nový časovač", "variable": "Nová premenná", + "trigger": "Nový spúšťač", + "audio_stream": "Nový audio stream", + "playlist": "Nový playlist", "category": "Nová kategória", "private": "Nová súkromná prezentácia", "folder": "Nový priečinok", @@ -399,19 +490,29 @@ "template": "Nová šablóna", "scripture": "Nové písmo", "collection": "Nová kolekcia", + "action": "Nová akcia", "event": "Nová udalosť" }, "show": { "name": "Názov", "category": "Kategória", - "quick_lyrics": "Rýchle texty", "new_layout": "Nové rozloženie", "grid": "Zobrazenie v mriežke", "simple": "Jednoduchý pohľad", "list": "Zobrazenie v zozname", "lyrics": "Zobrazenie textov", "text": "Text edit", - "update": "Aktualizovať prezentáciu" + "update": "Aktualizovať prezentáciu", + "locked": "Táto prezentácia je zamknutá!", + "locked_info": "Táto prezentácia je zamknutá na úpravy. Odomknete ju v zásuvke prezentácií.", + "slide_template": "Šablóna snímku", + "source": "Zdroj", + "artist": "Umelec", + "song": "Pieseň", + "delete_manual": "Ručná kontrola", + "delete_match": "Odstrániť pri presnej zhode", + "delete_keep_last_modified": "Odstrániť všetky okrem naposledy upravenej", + "delete_keep_first_created": "Odstrániť všetky okrem prvej vytvorenej" }, "actions": { "rename": "Premenovať", @@ -420,7 +521,6 @@ "remove_group": "Odstrániť skupinu", "choose_group": "Vybrať skupiny", "goto_group": "Prejsť na skupinu", - "change_output_style": "Zmeniť výstupný štýl", "active_outputs": "Aktívne výstupy", "all_outputs": "Všetky výstupy", "specific_outputs": "Špecifické vystupy", @@ -430,6 +530,8 @@ "export": "Export", "duplicate": "Duplikovať", "delete": "Zmazať", + "delete_slide": "Odstrániť snímok", + "delete_group": "Odstrániť skupinu", "delete_all": "Zmazať všetko", "close": "Zavrieť", "save": "Uložiť", @@ -447,12 +549,18 @@ "speech": "Reč", "startSpeaking": "Začať hovorenie", "stopSpeaking": "Zastaviť hovorenie", + "focus_mode": "Prepne režim zamerania", "fullscreen": "Na celú obrazovku", "resetZoom": "Resetovať priblíženie", "zoom": "Zoom", "zoomIn": "Priblížiť", "zoomOut": "Oddialiť", "reset": "Resetovať", + "create_template": "Vytvoriť šablónu", + "project_template_tip": "Vytvorí nový projekt zo šablóny", + "convert_to_images": "Konvertovať obrázky", + "converting": "Konvertovanie...", + "remove_template_from_show": "Odstrániť šablónu z prezentácie", "reset_defaults": "Obnoviť predvolené", "to_all": "Použiť na všetky", "to_following": "Použiť na nasledovné", @@ -460,16 +568,26 @@ "home": "Domov", "mute": "Stíšiť", "unmute": "Zapnúť zvuk", + "increase_volume": "Zvýšiť hlasitosť", + "decrease_volume": "Znížiť hlasitosť", "toggle_time_marker": "Prepnúť časové značky", "add_time_marker": "Pridať časovú značku", - "bind_to": "Pripojiť na", - "remove_binding": "Odstrániť pripojenie", + "bind_to": "Špecifické výstupy", + "remove_binding": "Odstrániť špecifické výstupy", + "dynamic_values": "Dynamické hodnoty", + "rearrange": "Preusporiadať", + "to_front": "Presunúť dopredu", + "forward": "Presunúť dozadu", + "backward": "Presunúť dozadu", + "to_back": "Presunúť úplne dozadu", "show_timer": "Čas do prezentácie", "hide_timer": "Čas do skrytia", "choose_custom": "Vybrať vlastné", + "add_color": "Pridať farbu", "format": "Formát", "find_replace": "Nájsť a nahradiť text", - "cut_in_half": "Odrezať v polovici", + "cut_in_half": "Rozdeliť na dve", + "merge": "Zlúčiť", "find": "Nájsť", "replace": "Nahradiť", "case_sensitive": "Case sensitive", @@ -481,29 +599,105 @@ "svg_clipboard": "Importovať SVG zo schránky", "fullscreen_preview": "Prepnúť náhľad na celú obrazovku", "toggle_output": "Prepnúť výstupnú obrazovku", + "toggle_panels": "Prepnúť panely", "change_tab": "Zmeniť tab", "change_drawer_tab": "Zmeniť tab zásuviek", + "change_slide": "Zmeniť snímok", + "change_project_item": "Zmeniť položku projektu", + "change_drawer_item": "Zmeniť položku zásuvky", + "change_drawer_category": "Zmeniť kategóriu zásuvky", "toggle_drawer": "Prepnúť zásuvku", - "actions": "Akcie", + "slide_actions": "Akcie snímku", + "item_actions": "Akcie položky", "clear_history": "Vyčistiť históriu", + "chord_info": "Prosím kliknite na písmeno na pridanie akordu", + "chord_key": "Kľúč", + "chord_type": "Typ", + "chord_tension": "Napätie", + "chord_bass": "Basové", + "roman_keys": "Rímske kľúče", "set_key": "Nastaviť kľúč", "custom_key": "Nastaviť vlastnú hodnotu", - "play_on_midi": "Prehrať na MIDI vstup", - "send_midi": "Poslať MIDI", + "select_chord": "Vyberte akord", + "play_with_shortcut": "Aktivovať skratku", + "press_to_assign": "Stlačte písmenovú klávesu na priradenie", + "play_on_midi": "Aktivovať na MIDI signál", + "play_on_midi_tip": "Aktivuje tento konkrétny snímok pri prijatí zvoleného MIDI signálu", + "send_midi": "Poslať MIDI signál", "delete_shows_not_indexed": "Odstrániť nezaindexované prezentácie z priečinka 'Shows'", + "delete_empty_shows": "Odstrániť prázdne prezentácie", "delete_thumbnail_cache": "Delete thumbnail cache", + "export_usage_log": "Export záznamok o používaní", + "reset_usage_log": "Resetovať záznamy o používaní", "open_log_file": "Otvoriť log súbor", + "open_cache_folder": "Otvoriť priečinok cache", "refresh_all_shows": "Získať všetky prezentácie v priečinku 'Shows'", "start_timer": "Spustiť časovať", "stop_timers": "Zastaviť aktívne časovače", - "next_after_media": "Ďalšie po media", + "next_after_media": "Ďalší po ukončení média", "remove_media": "Odstrániť médium", "remove_layers": "Odstrániť vrstvy", + "toggle_checkbox_tip": "Akcia sa prepne ak je zaškrtávacia políčko nezmenené", + "start_recording": "Spustiť nahrávanie", + "stop_recording": "Zastaviť nahrávanie", + "export_recording": "Ukončiť nahrávanie a export", "index_select_project": "Vybrať projekt podľa pozície", - "index_select_project_show": "Vybrať položku projektu podľa pozície", + "next_project_item": "Ďalšia položka projektu", + "previous_project_item": "Predošlá položka projektu", + "index_select_project_item": "Vybrať položku projektu podľa indexu", + "name_select_show": "Vybrať prezentáciu podľa názvu", + "set_template_active": "Nastaviť šablónu na aktívnu prezentáciu", + "random_slide": "Prehrať náhodný snímok", "index_select_slide": "Vybrať snímok podľa pozície", - "start_recording": "Spustiť nahrávanie", - "stop_recording": "Zastaviť nahrávanie" + "name_select_slide": "Vybrať snímok podľa názvu", + "toggle_output_lock": "Prepnúť zámok výstupu", + "toggle_output_windows": "Prepnúť výstupné okno", + "id_select_group": "Vybrať skupinu podľa ID", + "id_change_stage_layout": "Zmeniť rozloženie stage podľa ID", + "start_camera": "Spustiť kameru", + "index_select_overlay": "Vybrať overlay podľa indexu", + "name_select_overlay": "Vybrať overlay podľa názvu", + "change_volume": "Zmeniť hlasitosť", + "start_audio_stream": "Spustiť audio stream", + "start_playlist": "Spustiť playlist", + "playlist_next": "Ďalšia položka v playliste", + "start_metronome": "Spustiť metronóm", + "name_start_timer": "Spustiť časovač podľa názvu", + "id_start_timer": "Spustiť časovač podľa ID", + "start_slide_timers": "Spustiť časovače na aktívnom snímku", + "id_select_output_style": "Vybrať štýl výstupu podľa ID", + "change_output_style": "Zmeniť výstupný štýl", + "change_stage_output_layout": "Zmeniť rozloženie stage výstupu", + "change_transition": "Zmeniť prechod", + "change_variable": "Zmeniť premennú", + "start_trigger": "Spustiť spúšťač", + "run_action": "Spustiť akciu", + "toggle_action": "Prepnúť akciu", + "send_rest_command": "Poslať HTTP požiadavku", + "custom_activation": "Vlastná aktivácia", + "activate_on_startup": "Aktivovať pri štarte", + "activate_save": "Aktivovať pri uložení", + "activate_slide_clicked": "Aktivovať pri kliku na snímok", + "activate_video_starting": "Aktivovať pri spustení videa", + "activate_video_ending": "Aktivovať pri ukončení videa", + "activate_audio_starting": "Aktivovať pri spustení audia", + "activate_audio_ending": "Aktivovať pri ukončení audia", + "activate_timer_ending": "Aktivovať pri ukončení časovača", + "activate_scripture_start": "Aktivovať pri spustení veršu", + "activate_slide_cleared": "Aktivovať pri vyčistení snímku", + "activate_background_cleared": "Aktivovať pri vyčistení pozadia", + "activate_show_created": "Aktivovať pri vytvorení prezentácie", + "activate_show_opened": "Aktivovať pri otvorení prezentácie", + "activate_audio_playlist_ended": "Aktivovať pri ukončení audio playlistu" + }, + "recording": { + "remove": "Odstrániť nahrávanie", + "tip": "Nahráva a prehráva časovania snímkov. Synchronizuje s audio stopou na prvom snímku.", + "layout_changed": "Rozloženie sa zmenilo od prvého nahrávania!", + "audio_synced": "Synchronizované s audiom!", + "start": "Spustiť nahrávanie snímku", + "use_duration": "Použiť čas trvania", + "use_duration_tip": "Použije čas trvania namiesto času timestamp" }, "animate": { "change": "Zmeniť", @@ -521,18 +715,21 @@ "tip_api": "Musíte nastaviť svoj Google API kľúč, aby program mohol automaticky nahrávať súbory na váš Google Drive.", "tip_how": "Neviete ako ho získať?", "tip_guide": "Tu nájdete návod.", - "enable": "Automaticky synchronizovať po spustení alebo uložení", + "enable": "Automaticky synchronizuje spustenie a zavretie", "disable_upload": "Vypnuť nahrávanie dát", "media_id": "Media path ID", "google_drive_api": "Google API service account key", "select_key": "Import keys file", "update_key": "Update keys file", + "enable_custom_folder_id": "Použiť vlastné ID priečinka", "main_folder": "Nastaviť ručne hlavný priečinok", "media_folder": "Cloud media priečinok", "reconnect": "Pripojiť znova", - "sync": "Synchronizovať", - "choose_method_tip": "Na cloude sa už nachádzajú dáta. Prosím vyberte odkiaľ chcete údaje zachovať. A prepísať na opačnom mieste.", - "local": "Lokálne" + "sync": "Sync teraz", + "choose_method_tip": "Na cloude sú existujúce údaje. Prosím zvoľte buď nahratie z lokálu alebo stiahnutie z cloudu. Druhá strana sa prepíše.", + "local": "Lokálne", + "syncing": "Synchronizácia na cloud", + "sync_complete": "Synchronizácia hotová" }, "export": { "export": "Export", @@ -544,7 +741,6 @@ "all_shows": "Všetky prezentácie", "all_projects": "Všetky projekty", "project": "Projekt", - "options": "Voľby", "preview": "Náhľad", "title": "Názov", "metadata": "Metadata", @@ -560,15 +756,22 @@ }, "context": { "enabledTabs": "Zobraziť/skryť taby", + "setTag": "Nastaviť značku", + "filterByTags": "Filter značiek", "addToProject": "Pridať do projektu", + "add_to_show": "Pridať do prezentácie", + "lockForChanges": "Zamknúť pre zmeny", + "use_as_archive": "Označiť ako archivované", "newCategory": "Nová kategória", "changeIcon": "Zmeniť ikonu", "changeGroup": "Zmeniť skupiny", "createNew": "Vytvoriť nové", "selectAll": "Vybrať všetky", "force_outputs": "Vynútiť výstupy", + "align_with_screen": "Zarovnať s obrazovkou", "toggle_output": "Prepnúť výstup", "move_to_front": "Presunúť dopredu", + "hide_from_preview": "Skryť z náhľadu", "lock_to_output": "Zamknúť na výstup", "place_under_slide": "Umiesniť pod snímok", "toggle_clock": "Prepnúť hodiny", @@ -588,27 +791,45 @@ "slide": "Snímok" }, "edit": { + "text": "Text", "font": "Písmo", - "family": "Rodina", + "family": "Rodina písma", + "font_size": "Veľkosť písma", + "text_fit": "Zmestenie textu", + "shrink_to_fit": "Stlač aby sa zmestil", + "grow_to_fit": "Natiahni aby sa zmestil", + "text_color": "Farba textu", "style": "Štýl", + "lines": "Riadky", "options": "Voľby", "_title_bold": "Tučné", "_title_italic": "Naklonené", "_title_underline": "Podčiarknuté", "_title_strikethrough": "Prečiarknuté", "color": "Farba", + "accent_color": "Odtieň farby", "background_color": "Farba pozadia", "background_opacity": "Priehľadnosť pozadia", "background_image": "Obrázok na pozadí", + "background_media": "Médium na pozadí", + "overlay_content": "Pridať obsah overlay", + "different_first_template": "Vlastná šablóna na prvom snímku", "media_fit": "Prispôsobenie Media", + "one_letter": "Režim jedného písmena", + "sub_indexes": "Pod indexy", "size": "Veľkosť", + "max_lines": "Max riadkov", + "invert_items": "Prevrátiť položky", "chords": "Akordy", + "transpose": "Transponovať", "auto_size": "Automatická veľkosť", + "no_wrap": "Text na jeden riadok", "line_spacing": "Riadkovania", "line_height": "Výška riadka", "letter_spacing": "Medzi písmenami", "word_spacing": "Medzi slovami", "transform": "Transformácia", + "text_transform": "Transformácia textu", "uppercase": "VEĽKÉ", "lowercase": "malé", "capitalize": "Kapitálky", @@ -620,13 +841,13 @@ "_title_top": "Zarovnať na vrch", "_title_bottom": "Zarovnať na spodok", "outline": "Obrys", - "width": "Šírka", "shadow": "Tieň", "shadow_inset": "Tieň vnútorný", "offsetX": "Odstup X", "offsetY": "Odstup Y", "blur": "Rozostrenie", "item": "Položka", + "width": "Šírka", "height": "Výška", "rotation": "Otočenie", "tilt": "Naklonenie", @@ -648,11 +869,13 @@ "recent": "Recently edited", "enable_stage": "Zapnúť pódium", "select_stage": "Vybrať pódium", + "next_slide": "Ukázať ďalší snímok", "use_slide_index": "Použiť aktívnu pozíciu", "slide_index": "Pozícia snímku", "padding": "Padding", "special": "Special", "scrolling": "Skrolovanie", + "scrolling_speed": "Rýchlosť skrolovania", "top_bottom": "Zhora nadol", "bottom_top": "Zdola nahor", "left_right": "Zľava doprava", @@ -660,14 +883,16 @@ "max_events": "Maximum udalostí", "start_days_from_today": "Začať dni od dnes", "just_one_day": "Len jeden deň", - "enable_start_date": "Zapnúť počiatočný dátum" + "enable_start_date": "Zapnúť počiatočný dátum", + "disable_navigation": "Vypnúť ovládanie navigácie", + "progress_bar": "Ukazovateľ priebehu" }, "items": { "text": "Textové pole", "list": "Zoznam", "media": "Mediá", - "camera": "Kamera", "image": "Obrázok", + "camera": "Kamera", "video": "Video", "mirror": "Zrkadlo", "clock": "Hodiny", @@ -677,7 +902,9 @@ "timer": "Časovač", "variable": "Premenná", "web": "Webstránka", + "slide_tracker": "Priebeh", "visualizer": "Visualizer", + "captions": "Titulky", "icon": "Ikona" }, "borders": { @@ -710,6 +937,7 @@ "to_event": "Čas do udalosti", "counter": "Odpočet", "time": "Čas", + "minutes": "Minúty", "seconds": "Sekundy", "from": "Od", "to": "Do", @@ -730,7 +958,23 @@ "analog": "Ručičkové", "seconds": "Sekundy" }, + "captions": { + "info": "Prosím kliknitím na URL ju otvorte v prehliadači ak ste tak ešte nespravili, alebo ju otvorte na inom zariadení! Prosím uistite sa, že ste povolili prístup k mikrofónu, a použite Google Chrome pre najlepší výkon.", + "language": "Jazyk prepisu", + "translate": "Preložiť do", + "showtime": "Zobraziť trvanie", + "powered_by": "Poháňa" + }, + "localization": { + "translate": "Preložiť", + "add": "Pridať preklad", + "update": "Upraviť preklad", + "remove": "Odstrániť preložené položky" + }, "midi": { + "midi": "MIDI", + "activate": "Aktivovať MIDI signálom", + "activate_keypress": "Aktivovať klávesou", "name": "Názov", "input": "Vstup", "output": "Výstup", @@ -748,6 +992,7 @@ "draw": { "focus": "Focus", "pointer": "Kurzor", + "zoom": "Priblíženie", "fill": "Výplň", "paint": "Maľba", "particles": "Častice", @@ -764,6 +1009,7 @@ }, "stage": { "slide": "Snímok", + "stage_layout": "Rozloženie stage", "current_slide_text": "Text aktuálneho snímku", "current_slide": "Aktuálny snímok", "current_slide_notes": "Poznámky aktuálneho snímku", @@ -772,17 +1018,22 @@ "next_slide_notes": "Poznámky ďalšieho snímku", "output": "Výstup", "current_output": "Aktuálny výstyp", + "slide_tracker": "Priebeh", "time": "Čas", "system_clock": "Systémové hodiny", "video_time": "Video čas", "video_countdown": "Video odpočet", + "first_active_timer": "Prvý aktívny časovač", "other": "Iné", "message": "Správa", "color": "Farba", "font-size": "Veľkosť písma", "zeros": "Nuly", "overrun": "Farba po ukončení", - "auto_stretch": "Automaticky roztiahnuť obsah" + "source_output": "Výstup zdroja", + "auto_stretch": "Automaticky roztiahnuť obsah", + "labels": "Zobraziť popisky", + "label_color": "Farba popisku" }, "settings": { "general": "Všeobecné", @@ -790,11 +1041,12 @@ "groups": "Skupiny", "styles": "Štýly", "display_settings": "Výstupy", - "actions": "Akcie", "display": "Obrazovka", "connection": "Pripojenia", "cloud": "Cloud", "calendar": "Kalendár", + "text_import": "Text", + "media_import": "Media", "other": "Iné", "language": "Jazyk", "autosave": "Automatické ukladanie", @@ -809,7 +1061,10 @@ "select_display": "Kliknite na obrazovku, na ktorú chcete zobrazovať výstupné okno.", "manual_input_hint": "Nenašli ste displej? Kliknite sem na zmenu pozície.", "manual_drag_hint": "Môžete tiež držať ctrl/cmd nad aktívnym výstupným oknom a ručne ho posúvať.", + "allow_main_screen": "Povoliť vlastnú výstupnú pozíciu a veľkosť", + "identify_screens": "Identifikovať obrazovky", "new_output": "Nový výstup", + "normal": "Normálne", "enable_key_output": "Zapnúť výstup alpha kľúčovania", "always_on_top": "Vždy na vrchu", "kiosk_mode": "Kiosk režim", @@ -819,32 +1074,50 @@ "color_when_active": "Farba aktívneho", "fixed": "Pevné", "lines": "Čiary", - "override_with_template": "Prepísať šablónou", + "override_with_template": "Prepísať snímok šablónou", + "override_scripture_with_template": "Prepísať verš šablónou", "active_layers": "Aktívne vrstvy", "window": "Okno", "active_style": "Použiť štýl", "alert_updates": "Upozorniť na dostupné aktualizácie", + "auto_updates": "Auto aktualizácie", "disable_labels": "Vypnúť popisky", "group_numbers": "Čísla skupín", - "full_colors": "Plné farby skupín snímok", + "full_colors": "Farby skupín s vysokým kontrastom", + "slide_number_keys": "Spúštať snímky čiselnými klávesmi", + "auto_shortcut_first_letter": "Automatická skratka na prvé písmeno textu", "auto_output": "Zobraziť výstupné okno pri spustení", + "hide_cursor_in_output": "Skryť kurzor na výstupe", + "clear_media_when_finished": "Vyčistiť médium pri ukončení", + "disable_presenter_controller_keys": "Vypnúť prezentačné ovládacie klávesy", "default_project_name": "Predvolený názov projektu", + "audio_fade_duration": "Trvanie auto fade", + "audio_crossfade": "Audio crossfade", + "clear_style_background_on_text": "Vyčistiť štýl pozadia pri aktivácii snímku", "resolution": "Rozlíšenie", "cropping": "Orezanie", "frame_rate": "Snímková rýchlosť", + "device": "Zariadenie", + "display_mode": "Režim zobrazenia", + "pixel_format": "Formát pixelov", + "alpha_key": "Alfa kľúč", "transparent": "Priehľadné", + "invisible_window": "Neviditeľné okno", "video_extensions": "Prípony videí", "image_extensions": "Prípony obrázkov", "add": "Pridať", "remove": "Odstrániť", "change_name": "Zmeniť názov", "show_location": "Zobraziť umiestnenie", - "export_location": "Miesto Exportov", - "scripture_location": "Miesto biblií", - "recording_location": "Miesto nahrávok", + "data_location": "Umiestnenie údajov", + "user_data_location": "Uložiť používateľské nastavenia na 'Umiestnenie dát'", + "popup_before_close": "Zapnúť potvrdzovanie ukončenia", + "disable_hardware_acceleration": "Vypnúť hardvérovú akceleráciu", + "restart_for_change": "Na prejavenie zmeny treba reštartovať program!", "font": "Písmo", "font_family": "Rodina písma", "font_size": "Veľkosť písma", + "border_radius": "Polomer rámiku", "colors": "Farby", "add_group": "Pridať skupinu", "group_shortcut": "Shortcut to activate group", @@ -861,16 +1134,21 @@ "reset_all": "Reset všetkého", "reset_theme": "Reset témy", "reset_themes": "Reset tém", + "capitalize_words": "Kapitalizovať slová", + "comma_seperated": "Oddelené čiarkou", "backup_all": "Zálohovať všetko", "restore": "Obnoviť", "backup_started": "Zálohuje sa ...", "restore_started": "Obnovuje sa...", "backup_finished": "Záloha hotová!", "restore_finished": "Obnova hotová!", + "auto_backup": "Auto zálohy", "preview_frame_rate": "Rýchlosť snímkov v náhľade", "auto": "Auto", "optimized": "Optimalizované", - "full": "Plné" + "reduced": "Znížené", + "full": "Plné", + "section_trigger_action": "Spustí akciu pri nevigovaní prezentácie do sekcie" }, "sort": { "sort_by": "Zoradiť podľa", @@ -883,7 +1161,7 @@ "calendar": { "type": "Typ", "event": "Nová udalosť", - "show": "Naplánovať prezentáciu", + "schedule_action": "Naplánovať akciu", "name": "Názov", "color": "Farba", "time": "Čas", @@ -902,7 +1180,7 @@ "week": "týždeň", "month": "mesiac", "year": "rok", - "ending_the": "", + "ending_the": "dátumu", "ending_repeated": "opakovať", "ending_times": "krát", "save_all": "Uložiť a aktualizovať všetko", @@ -913,9 +1191,15 @@ "custom": "Alebo importujete svoju vlastnú", "max_verses": "Maximum veršov na snímok", "verse_numbers": "Čísla veršov", + "verses_on_individual_lines": "Verše na jednotlivých riadkoch", "version": "Zobraziť preklad", "reference": "Zobraziť odkazy", - "red_jesus": "Ježišove slová červeným" + "split_reference": "Rozdeliť adresy", + "combine_with_text": "Kombinovať s textom", + "first_slide_reference": "Adresy na prvom snímku", + "reference_at_bottom": "Presunúť na spodok", + "red_jesus": "Ježišove slová červeným", + "search": "Hľadať v Biblii" }, "filter": { "blur": "Rozostrenie", @@ -932,14 +1216,32 @@ "screens": "Obrazovky", "windows": "Okná", "cameras": "Kamery", - "microphones": "Mikrofóny" + "microphones": "Mikrofóny", + "audio_streams": "Audio streamy" + }, + "presentation_control": { + "unsupported": "Prezentačný ovládač nie je podporovaný na", + "unsupported_tip": "Môžete ich konvertovať na obrázky a vytvoriť prezentáciu, alebo vypnúť 'Vždy na vrchu' a prezentovať z akejkoľvek aplikácie.", + "opening": "Otvára sa! Prosím čakajte...", + "retry": "Prosím skúste otvoriť ručne alebo", + "try_again": "Skúste znova", + "restart": "Reštart", + "start": "Štart", + "choose_window": "Prosím vyberte okno" }, "transition": { "current_slide": "pre aktuálny snímok", "text": "Prechod textu", "media": "Prechod média", + "slide_transition": "Prechod snímku", + "background_transition": "Prechod pozadia", + "specific": "Zapnúť konkrétnejšie prechody", + "between": "Medzi", + "in": "Do", + "out": "Z", "duration": "Trvanie", "easing": "Spomalenie", + "direction": "Smer", "type": "Typ", "none": "Žiadne", "fade": "Prelínanie", @@ -990,16 +1292,70 @@ "6": "Sobota", "7": "Nedeľa" }, + "interval": { + "daily": "Denne", + "weekly": "Týždenne", + "mothly": "Mesačne" + }, "info": { "created": "Vytvorené", "modified": "Upravené", "used": "Použité", "changed": "Zmenené", + "recently_used": "Naposledy použité", "extension": "Prípona", "size": "Veľkosť", "slides": "Snímky", "words": "Slová", "template": "Šablóna", - "category": "Kategória" + "category": "Kategória", + "codecs": "Kódeky", + "mimeType": "MIME typ", + "photoUrl": "Foto URL", + "likes": "Páči sa", + "artist": "Umelec", + "artistUrl": "Stránka umelca" + }, + "guide_title": { + "projects": "Projekty", + "project": "Projekt", + "drawer": "Zásuvka", + "categories": "Kategórie", + "show_create": "Vytvorenie prezentácie", + "show": "Prezentácia", + "output": "Výstup", + "editing": "Upravovanie", + "end": "To sú základy!" + }, + "guide_description": { + "start": "Toto je krátka prehliadka niektorých základných funkcií! (Preskakovať môžete v pravom dolnom rohu.)", + "project_manage": "Spravujte všetky svoje projekty na jednom mieste.", + "project_create": "Vytvorte priečinky pre lepšiu organizáciu a vytvárajte nové projekty.", + "project_list": "Po otvorení projektu dostanete zoznam všetkých položiek tu na ľavej strane, presúvajte ich myšou zo zásuvky ak potrebujete viac.", + "drawer": "Nájdite všetky vaše prezentácie, médiá, overlay, atď. na jednom mieste.", + "drawer_search": "Hľadajte obsah v aktívnej zásuvke (piesne, atď.). Použite skratku Ctrl/Cmd+F na rýchlejší prístup.", + "drawer_shows": "Spravujte všetky rôzne prezentácie zaraďovaním do rôznych kategórií. Presúvajte vybraté prezentácie medzi nimi.", + "create_show_button": "Kliknite sem na vytvorenie novej prezentácie (pieseň, snímky, atď.", + "create_show_popup": "Vyplňte najdôležitejšie údaje o prezentácii, môžete tiež nájsť texty piesní na webe podľa názvu alebo ich zadať ručne.", + "show": "Prezentácia na hlavný typ obsahu, kliknite na akýkoľvek snímok na prezentovanie a používajte klávesy šípok na navigáciu. Taktiež môžete presúvač media súbory do snímku ako pozadie", + "show_slide": "Po kliknutí na snímok sa zobrazí vo výstupe a náhľad vidíte napravo, tu nájdete aj ďalšie akcie ako zastavenia videa.", + "output_clear": "Vyčistite jednotlivé vrstvy výstupu, alebo vyčistite všetky vrstvy naraz.", + "edit": "Úpravy snímku otvoríte jedným klikom hore", + "end": "Vždy môžete pozrieť na web ak potrebujete pomoc s ďalšími funkciami." + }, + "songbeamer_import": { + "options": "Voľby", + "encoding": "Enkódovanie", + "older_versions": "Pre Songbeamer verzie staršie ako 6.02a", + "category": "Kategória", + "utf8": "UTF-8", + "latin1": "Latin 1", + "translations": "Preklady", + "translation_multiline": "Viacriadkové", + "translation_textboxes": "Textové polia", + "translation_layouts": "Rozloženia", + "translation_description_multiline": "Pridá všetky jazyky v jednom textovom poli ako alternatívne riadky. (Ako v Songbeameri)", + "translation_description_textboxes": "Pridá každý jazyk ako oddelené pole v snímku.", + "translation_description_layouts": "Vytvorí unikátnu množinu snímkov rozloženia pre každý jazyk." } -} \ No newline at end of file +} diff --git a/src/electron/data/defaults.ts b/src/electron/data/defaults.ts index 99ad7dee..858187d7 100644 --- a/src/electron/data/defaults.ts +++ b/src/electron/data/defaults.ts @@ -123,6 +123,7 @@ export const defaultSyncedSettings: { [key in SaveListSyncedSettings]: any } = { groups: defaultGroups, midiIn: {}, videoMarkers: {}, + mediaTags: {}, customizedIcons: { disabled: [], svg: [] }, companion: {}, globalTags: {}, diff --git a/src/frontend/components/actions/CreateAction.svelte b/src/frontend/components/actions/CreateAction.svelte index e464dcd0..8477b08a 100644 --- a/src/frontend/components/actions/CreateAction.svelte +++ b/src/frontend/components/actions/CreateAction.svelte @@ -51,13 +51,13 @@ "change_transition", "change_variable", "start_camera", - "run_action", "toggle_action", "send_rest_command", ] // remove actions that are not fully implemented to CustomInput yet const removeActions = ["change_transition"] if (list) removeActions.push(...removeFromSlideAction) + if ($popupData.mode !== "template") removeActions.push("run_action") $: ACTIONS = [ ...Object.keys(API_ACTIONS) @@ -86,7 +86,7 @@ return true }), // custom special - ...(list ? [] : [{ id: "wait", name: $dictionary.animate?.wait, icon: "time_in", common: false }]), + ...(list ? [] : [{ id: "wait", name: $dictionary.animate?.wait || "", icon: "time_in", common: false }]), ] let pickAction: boolean = false diff --git a/src/frontend/components/actions/api.ts b/src/frontend/components/actions/api.ts index 82708f6c..a6f436d8 100644 --- a/src/frontend/components/actions/api.ts +++ b/src/frontend/components/actions/api.ts @@ -180,7 +180,7 @@ export const API_ACTIONS = { // start specific folder (playlist) // folder_select_audio: () => , change_volume: (data: API_volume) => updateVolume(data.volume ?? data.gain, data.gain !== undefined), // BC - start_audio_stream: (data: API_id) => startAudioStream(data.id), + start_audio_stream: (data: API_id) => startAudioStream(data), start_playlist: (data: API_id) => startPlaylist(data.id), playlist_next: () => audioPlaylistNext(), start_metronome: (data: API_metronome) => startMetronome(data), diff --git a/src/frontend/components/context/ContextItem.svelte b/src/frontend/components/context/ContextItem.svelte index b39b9ad9..62c83536 100644 --- a/src/frontend/components/context/ContextItem.svelte +++ b/src/frontend/components/context/ContextItem.svelte @@ -218,7 +218,7 @@ // don't hide context menu const keepOpen = ["uppercase", "lowercase", "capitalize", "trim"] // "dynamic_values" (caret position is lost) if (keepOpen.includes(id)) return - const keepOpenToggle = ["enabled_drawer_tabs", "tag_set", "tag_filter", "bind_slide", "bind_item"] + const keepOpenToggle = ["enabled_drawer_tabs", "tag_set", "tag_filter", "media_tag_set", "media_tag_filter", "bind_slide", "bind_item"] if (keepOpenToggle.includes(id)) { enabled = !enabled return diff --git a/src/frontend/components/context/ContextMenu.svelte b/src/frontend/components/context/ContextMenu.svelte index f48e0d04..5741a386 100644 --- a/src/frontend/components/context/ContextMenu.svelte +++ b/src/frontend/components/context/ContextMenu.svelte @@ -95,6 +95,7 @@ if (id === "format") return $contextData.textContent || $activePage !== "show" if (id === "remove_layers") return $contextData.layers if (id === "tag_set" || id === "tag_filter") return $contextData.tags + if (id === "media_tag_filter") return $contextData.media_tags return true } diff --git a/src/frontend/components/context/contextMenus.ts b/src/frontend/components/context/contextMenus.ts index 5e61c4e5..0597737c 100644 --- a/src/frontend/components/context/contextMenus.ts +++ b/src/frontend/components/context/contextMenus.ts @@ -42,6 +42,8 @@ export const contextMenuItems: { [key: string]: ContextMenuItem } = { enabledTabs: { label: "context.enabledTabs", items: ["LOAD_enabled_drawer_tabs"] }, tag_set: { label: "context.setTag", icon: "tag", items: ["LOAD_tag_set"] }, tag_filter: { label: "context.filterByTags", icon: "tag", items: ["LOAD_tag_filter"] }, + media_tag_set: { label: "context.setTag", icon: "tag", items: ["LOAD_media_tag_set"] }, + media_tag_filter: { label: "context.filterByTags", icon: "tag", items: ["LOAD_media_tag_filter"] }, newCategory: { label: "context.newCategory", icon: "add" }, newScripture: { label: "new.scripture", icon: "add" }, createCollection: { label: "new.collection", icon: "collection" }, @@ -198,7 +200,8 @@ export const contextMenuLayouts: { [key: string]: string[] } = { midi: ["play", "SEPERATOR", "edit", "delete"], // , "addToShow" // show_in_explorer!! - media_card: ["addToProject", "SEPERATOR", "edit", "preview", "favourite", "SEPERATOR", "play_no_audio", "play_no_filters", "SEPERATOR", "system_open"], + media: ["media_tag_filter"], + media_card: ["addToProject", "SEPERATOR", "edit", "preview", "favourite", "SEPERATOR", "play_no_audio", "play_no_filters", "SEPERATOR", "media_tag_set", "media_tag_filter", "SEPERATOR", "system_open"], // "addToFirstSlide", overlay_card: ["edit", "preview", "SEPERATOR", "lock_to_output", "place_under_slide", "SEPERATOR", "rename", "recolor", "duplicate", "delete"], // "addToShow", @@ -242,7 +245,7 @@ export const contextMenuLayouts: { [key: string]: string[] } = { // SHOWS // , "copy", "paste" - slide: ["slideGroups", "actions", "bind_to", "format", "remove_layers", "slide_transition", "disable", "edit", "SEPERATOR", "duplicate", "delete_slide", "remove_slide"], + slide: ["edit", "SEPERATOR", "slideGroups", "actions", "bind_to", "format", "remove_layers", "slide_transition", "disable", "SEPERATOR", "duplicate", "delete_slide", "remove_slide"], slideChild: ["slideGroups", "actions", "bind_to", "format", "remove_layers", "slide_transition", "disable", "edit", "SEPERATOR", "duplicate", "delete_slide", "remove_slide"], slideFocus: ["editSlideText"], group: ["rename", "recolor", "SEPERATOR", "selectAll", "SEPERATOR", "duplicate", "delete_group"], diff --git a/src/frontend/components/context/loadItems.ts b/src/frontend/components/context/loadItems.ts index 93afde4e..457799ad 100644 --- a/src/frontend/components/context/loadItems.ts +++ b/src/frontend/components/context/loadItems.ts @@ -1,5 +1,5 @@ import { get } from "svelte/store" -import { activeEdit, activeTagFilter, contextData, drawerTabsData, globalTags, groups, outputs, overlays, selected, shows, sorted } from "../../stores" +import { activeEdit, activeMediaTagFilter, activeTagFilter, contextData, drawerTabsData, globalTags, groups, media, mediaTags, outputs, overlays, selected, shows, sorted } from "../../stores" import { translate } from "../../utils/language" import { drawerTabs } from "../../values/tabs" import { actionData } from "../actions/actionData" @@ -33,6 +33,19 @@ const loadActions = { setContextData("tags", sortedTags.length) return sortedTags }, + media_tag_set: () => { + let selectedTags = get(media)[get(selected).data[0]?.path]?.tags || [] + let sortedTags = sortObject(sortByName(keysToID(get(mediaTags))), "color").map((a) => ({ ...a, label: a.name, enabled: selectedTags.includes(a.id), translate: false })) + const create = {label: "popup.manage_tags", icon: "edit", id: "create"} + if (sortedTags.length) sortedTags.push("SEPERATOR") + sortedTags.push(create) + return sortedTags + }, + media_tag_filter: () => { + let sortedTags = sortObject(sortByName(keysToID(get(mediaTags))), "color").map((a) => ({ ...a, label: a.name, enabled: get(activeMediaTagFilter).includes(a.id), translate: false })) + setContextData("media_tags", sortedTags.length) + return sortedTags + }, sort_shows: (items: ContextMenuItem[]) => sortItems(items, "shows"), sort_projects: (items: ContextMenuItem[]) => sortItems(items, "projects"), slide_groups: (items: ContextMenuItem[]) => { @@ -53,6 +66,7 @@ const loadActions = { let slideActions = [ { id: "action", label: "midi.start_action", icon: "actions" }, + "SEPERATOR", { id: "slide_shortcut", label: "actions.play_with_shortcut", icon: "play", enabled: currentActions?.slide_shortcut || false }, { id: "receiveMidi", label: "actions.play_on_midi", icon: "play", enabled: currentActions?.receiveMidi || false }, "SEPERATOR", diff --git a/src/frontend/components/context/menuClick.ts b/src/frontend/components/context/menuClick.ts index 6001ecab..b55b481f 100644 --- a/src/frontend/components/context/menuClick.ts +++ b/src/frontend/components/context/menuClick.ts @@ -9,6 +9,7 @@ import { activeDrawerTab, activeEdit, activeFocus, + activeMediaTagFilter, activePage, activePopup, activeRecording, @@ -17,6 +18,7 @@ import { activeTagFilter, audioFolders, categories, + contextActive, currentOutputSettings, currentWindow, dataPath, @@ -286,6 +288,44 @@ const actions: any = { activeTagFilter.set(activeTags || []) }, + media_tag_set: (obj: any) => { + let tagId = obj.menu.id + if (tagId === "create") { + contextActive.set(false) + popupData.set({type: "media"}) + activePopup.set("manage_tags") + return + } + + let disable = get(media)[get(selected).data[0]?.path]?.tags?.includes(tagId) + + obj.sel.data?.forEach(({ path }) => { + let tags = get(media)[path]?.tags || [] + + let existingIndex = tags.indexOf(tagId) + if (disable) { + if (existingIndex > -1) tags.splice(existingIndex, 1) + } else { + if (existingIndex < 0) tags.push(tagId) + } + + media.update((a) => { + if (!a[path]) a[path] = {} + a[path].tags = tags + return a + }) + }) + }, + media_tag_filter: (obj: any) => { + let tagId = obj.menu.id + + let activeTags = get(activeMediaTagFilter) + let currentIndex = activeTags.indexOf(tagId) + if (currentIndex < 0) activeTags.push(tagId) + else activeTags.splice(currentIndex, 1) + + activeMediaTagFilter.set(activeTags || []) + }, addToProject: (obj: any) => { if ((obj.sel.id !== "show" && obj.sel.id !== "show_drawer" && obj.sel.id !== "player" && obj.sel.id !== "media" && obj.sel.id !== "audio") || !get(activeProject)) return diff --git a/src/frontend/components/draw/DrawSettings.svelte b/src/frontend/components/draw/DrawSettings.svelte index 0823a7bd..b354ca86 100644 --- a/src/frontend/components/draw/DrawSettings.svelte +++ b/src/frontend/components/draw/DrawSettings.svelte @@ -78,35 +78,41 @@
{#key $drawTool} -
- {#key $drawSettings} - {#if $drawSettings[$drawTool]} - {#each Object.entries($drawSettings[$drawTool]) as [key, value]} - {#if key !== "clear" && (key !== "hold" || $drawTool !== "paint")} - - {#if key !== "clear" && (key !== "hold" || $drawTool !== "paint")} -

- {/if} - {#if key === "color"} - change(e, key)} style="width: 100%;" /> - {:else if ["glow", "hold", "rainbow", "hollow", "dots", "threed"].includes(key)} -
- check(e, key)} /> -
- {:else if key === "opacity"} - change(e, key)} /> - {:else if key === "radius"} - change(e, key)} /> - {:else if key !== "clear" && key !== "hold"} - change(e, key)} /> - {:else} -
- {/if} -
- {/if} - {/each} - {/if} - {/key} +
+ + +
+ +
+ {#key $drawSettings} + {#if $drawSettings[$drawTool]} + {#each Object.entries($drawSettings[$drawTool]) as [key, value]} + {#if key !== "clear" && (key !== "hold" || $drawTool !== "paint")} + + {#if key !== "clear" && (key !== "hold" || $drawTool !== "paint")} +

+ {/if} + {#if key === "color"} + change(e, key)} style="width: 100%;" /> + {:else if ["glow", "hold", "rainbow", "hollow", "dots", "threed"].includes(key)} +
+ check(e, key)} /> +
+ {:else if key === "opacity"} + change(e, key)} /> + {:else if key === "radius"} + change(e, key)} /> + {:else if key !== "clear" && key !== "hold"} + change(e, key)} /> + {:else} +
+ {/if} +
+ {/if} + {/each} + {/if} + {/key} +
{/key}
@@ -134,15 +140,35 @@ height: 100%; } + h6 { + display: flex; + align-items: center; + justify-content: center; + + font-weight: 600; + letter-spacing: 0.5px; + + padding: 0.3em 0.5em; + background-color: var(--primary-darkest); + border-radius: var(--border-radius); + + /* font-size: 0.9em; */ + text-transform: none !important; + margin: 0 !important; + } + .padding { display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden; - padding: 10px; height: 100%; } + .options { + padding: 10px; + } + .bottom { display: flex; flex-direction: column; diff --git a/src/frontend/components/draw/Paint.svelte b/src/frontend/components/draw/Paint.svelte index b70b1142..aff2dcb5 100644 --- a/src/frontend/components/draw/Paint.svelte +++ b/src/frontend/components/draw/Paint.svelte @@ -96,7 +96,7 @@ x: x, y: y, size: settings.size || 10, - color: settings.color || "white", + color: settings.color || "#ffffff", } lines.push(line) paintCache.set(lines) @@ -114,7 +114,7 @@ // ctx.moveTo(previousPos.x, previousPos.y) ctx.lineWidth = settings.size || 10 ctx.lineCap = "round" - ctx.strokeStyle = settings.color || "white" + ctx.strokeStyle = settings.color || "#ffffff" } else { previousPos = null if (lines.length && lines[lines.length - 1] !== "mouseup") lines.push("mouseup") diff --git a/src/frontend/components/drawer/media/Media.svelte b/src/frontend/components/drawer/media/Media.svelte index dd2116ed..c51ec9d1 100644 --- a/src/frontend/components/drawer/media/Media.svelte +++ b/src/frontend/components/drawer/media/Media.svelte @@ -4,7 +4,25 @@ import { slide } from "svelte/transition" import { uid } from "uid" import { MAIN, READ_FOLDER } from "../../../../types/Channels" - import { activeDrawerOnlineTab, activeEdit, activeFocus, activePopup, activeShow, dictionary, focusMode, labelsDisabled, media, mediaFolders, mediaOptions, outLocked, outputs, popupData, selectAllMedia, selected } from "../../../stores" + import { + activeDrawerOnlineTab, + activeEdit, + activeFocus, + activeMediaTagFilter, + activePopup, + activeShow, + dictionary, + focusMode, + labelsDisabled, + media, + mediaFolders, + mediaOptions, + outLocked, + outputs, + popupData, + selectAllMedia, + selected, + } from "../../../stores" import { destroy, send } from "../../../utils/request" import Icon from "../../helpers/Icon.svelte" import T from "../../helpers/T.svelte" @@ -33,7 +51,8 @@ let files: any[] = [] - let notFolders = ["all", "favourites", "online", "screens", "cameras"] + let specialTabs = ["online", "screens", "cameras"] + let notFolders = ["all", ...specialTabs] $: rootPath = notFolders.includes(active || "") ? "" : active !== null ? $mediaFolders[active]?.path! || "" : "" $: path = notFolders.includes(active || "") ? "" : rootPath @@ -137,7 +156,7 @@ // filter files let activeView: "all" | "folder" | "image" | "video" = "all" let filteredFiles: any[] = [] - $: if (activeView) filterFiles() + $: if (activeView || $activeMediaTagFilter) filterFiles() $: if (searchValue !== undefined) filterSearch() function filterFiles() { @@ -147,6 +166,11 @@ if (activeView === "all") filteredFiles = files.filter((a) => active !== "all" || !a.folder) else filteredFiles = files.filter((a) => (activeView === "folder" && active !== "all" && a.folder) || (!a.folder && activeView === getMediaType(a.extension))) + // filter by tag + if ($activeMediaTagFilter.length) { + filteredFiles = filteredFiles.filter((a) => !a.folder && $media[a.path]?.tags?.length && !$activeMediaTagFilter.find((tagId) => !$media[a.path].tags!.includes(tagId))) + } + // reset arrow selector loadAllFiles(filteredFiles) @@ -311,49 +335,53 @@ /> {:else if fullFilteredFiles.length} - {#key fullFilteredFiles} - {#if $mediaOptions.mode === "grid"} - - {#if item.folder} - - {:else} - ({ ...a, type: getMediaType(a.extension), name: removeExtension(a.name) }))} - bind:activeFile - {allFiles} - {active} - /> - {/if} - - {:else} - - {#if file.folder} - - {:else} - ({ ...a, type: getMediaType(a.extension), name: removeExtension(a.name) }))} - bind:activeFile - {allFiles} - {active} - /> - {/if} - - {/if} - {/key} +
+ {#key fullFilteredFiles} + {#if $mediaOptions.mode === "grid"} + + {#if item.folder} + + {:else} + ({ ...a, type: getMediaType(a.extension), name: removeExtension(a.name) }))} + bind:activeFile + {allFiles} + {active} + /> + {/if} + + {:else} + + {#if file.folder} + + {:else} + ({ ...a, type: getMediaType(a.extension), name: removeExtension(a.name) }))} + bind:activeFile + {allFiles} + {active} + /> + {/if} + + {/if} + {/key} +
{:else} -
- -
+
+
+ +
+
{/if} diff --git a/src/frontend/components/drawer/media/MediaCard.svelte b/src/frontend/components/drawer/media/MediaCard.svelte index 1ca86198..ecbc576b 100644 --- a/src/frontend/components/drawer/media/MediaCard.svelte +++ b/src/frontend/components/drawer/media/MediaCard.svelte @@ -1,10 +1,11 @@ @@ -127,6 +139,22 @@ on:mouseleave={() => (hover = false)} on:mousemove={move} > + +
+ {#if tags.length} +
+
+ +
+ +

{tags.length === 1 ? $mediaTags[tags[0]]?.name || "—" : tags.length}

+
+
+ {/if} +
+ {#if thumbnail} {:else} @@ -149,4 +177,38 @@ .icon :global(svg) { height: 100%; } + + /* icons */ + + .icons { + pointer-events: none; + display: flex; + flex-direction: column; + position: absolute; + left: 0; + z-index: 1; + font-size: 0.9em; + + height: 80%; + flex-wrap: wrap; + + max-width: calc(100% - 21px); + } + .icons div { + opacity: 0.9; + display: flex; + } + .icons .button { + background-color: rgb(0 0 0 / 0.6); + pointer-events: all; + } + .icons span { + pointer-events: all; + background-color: rgb(0 0 0 / 0.6); + padding: 3px; + font-size: 0.75em; + font-weight: bold; + display: flex; + align-items: center; + } diff --git a/src/frontend/components/helpers/audio.ts b/src/frontend/components/helpers/audio.ts index bbec8dcd..46cfea5a 100644 --- a/src/frontend/components/helpers/audio.ts +++ b/src/frontend/components/helpers/audio.ts @@ -13,7 +13,7 @@ import { checkNextAfterMedia } from "./showActions" // WIP use get(special).audio_fade_duration ?? 1.5 to fade in when starting song ?? (currently just when fading out) -export async function playAudio({ path, name = "", audio = null, stream = null }: any, pauseIfPlaying: boolean = true, startAt: number = 0, playMultiple: boolean = false, crossfade: number = 0) { +export async function playAudio({ path, name = "", audio = null, stream = null }: any, pauseIfPlaying: boolean = true, startAt: number = 0, playMultiple: boolean = false, crossfade: number = 0, playlistCrossfade: boolean = false) { let existing: any = get(playingAudio)[path] if (existing) { if (!pauseIfPlaying) { @@ -36,7 +36,7 @@ export async function playAudio({ path, name = "", audio = null, stream = null } let audioPlaying = Object.keys(get(playingAudio)).length if (crossfade) crossfadeAudio(crossfade) - else if (!playMultiple) clearAudio("", false) + else if (!playMultiple) clearAudio("", false, playlistCrossfade) let encodedPath = encodeFilePath(path) audio = audio || new Audio(encodedPath) @@ -252,7 +252,7 @@ export function playlistNext(previous: string = "", specificSong: string = "", c }) // if (crossfade) isCrossfading = true - playAudio({ path: nextSong }, false, 0, false, crossfade) + playAudio({ path: nextSong }, false, 0, false, crossfade, true) function getSongs(): string[] { if (previous && get(activePlaylist)?.songs) return get(activePlaylist).songs @@ -569,7 +569,7 @@ function getHighestNumber(numbers: number[]): number { let clearing = false let forceClear: boolean = false -export function clearAudio(path: string = "", clearPlaylist: boolean = true, playlistCrossfade: boolean = false) { +export function clearAudio(path: string = "", clearPlaylist: boolean = true, playlistCrossfade: boolean = false, commonClear: boolean = false) { // turn off any playlist if (clearPlaylist && (!path || get(activePlaylist)?.active === path)) activePlaylist.set(null) @@ -579,6 +579,7 @@ export function clearAudio(path: string = "", clearPlaylist: boolean = true, pla const clearTime = playlistCrossfade ? 0 : (get(special).audio_fade_duration ?? 1.5) if (clearing) { + if (!commonClear) return // force stop audio files (bypass timeout if already active) forceClear = true setTimeout(() => (forceClear = false), 100) diff --git a/src/frontend/components/helpers/historyHelpers.ts b/src/frontend/components/helpers/historyHelpers.ts index 16941c91..4a6c79a4 100644 --- a/src/frontend/components/helpers/historyHelpers.ts +++ b/src/frontend/components/helpers/historyHelpers.ts @@ -7,6 +7,7 @@ import { activeRename, activeShow, activeStage, + activeTagFilter, audioPlaylists, currentOutputSettings, dictionary, @@ -440,6 +441,9 @@ export const _updaters = { activeRename.set("tag_" + id) return data }, + deselect: () => { + activeTagFilter.set([]) + } }, tag_key: { store: globalTags }, diff --git a/src/frontend/components/helpers/media.ts b/src/frontend/components/helpers/media.ts index ca2d2854..6994bd50 100644 --- a/src/frontend/components/helpers/media.ts +++ b/src/frontend/components/helpers/media.ts @@ -60,6 +60,8 @@ export function joinPath(path: string[]): string { // fix for media files with special characters in file name not playing export function encodeFilePath(path: string): string { + if (!path) return "" + // already encoded if (path.match(/%\d+/g) || path.includes("http") || path.includes("data:")) return path diff --git a/src/frontend/components/helpers/output.ts b/src/frontend/components/helpers/output.ts index 38f96dfe..e5243549 100644 --- a/src/frontend/components/helpers/output.ts +++ b/src/frontend/components/helpers/output.ts @@ -41,6 +41,7 @@ import { fadeinAllPlayingAudio, fadeoutAllPlayingAudio } from "./audio" import { getExtension, getFileName, removeExtension } from "./media" import { replaceDynamicValues } from "./showActions" import { _show } from "./shows" +import { newToast } from "../../utils/common" export function displayOutputs(e: any = {}, auto: boolean = false) { // sort so display order can be changed! (needs app restart) @@ -318,12 +319,12 @@ export function getOutputResolution(outputId: string, _updater = get(outputs)) { return style || { width: 1920, height: 1080 } } -export function checkWindowCapture() { - getActiveOutputs(get(outputs), false, true, true).forEach(shouldBeCaptured) +export function checkWindowCapture(startup: boolean = false) { + getActiveOutputs(get(outputs), false, true, true).forEach((a) => shouldBeCaptured(a, startup)) } // NDI | OutputShow | Stage CurrentOutput -export function shouldBeCaptured(outputId: string) { +export function shouldBeCaptured(outputId: string, startup: boolean = false) { let output = get(outputs)[outputId] let captures: any = { ndi: !!output.ndi, @@ -331,6 +332,9 @@ export function shouldBeCaptured(outputId: string) { stage: stageHasOutput(outputId), } + // alert user that screen recording starts + if (!startup && Object.values(captures).filter(Boolean).length) newToast("$toast.output_capture_enabled") + send(OUTPUT, ["CAPTURE"], { id: outputId, captures }) } function stageHasOutput(outputId: string) { diff --git a/src/frontend/components/inputs/Color.svelte b/src/frontend/components/inputs/Color.svelte index c93cddbf..d814d561 100644 --- a/src/frontend/components/inputs/Color.svelte +++ b/src/frontend/components/inputs/Color.svelte @@ -11,6 +11,7 @@ export let enableNoColor: boolean = false export let showDisabled: boolean = false export let custom: boolean = false + export let rightAlign: boolean = false export let height: number = 0 export let width: number = 0 @@ -43,7 +44,7 @@ } let colorElem - let clipRight: boolean = false + let clipRight: boolean = rightAlign || false $: if (colorElem) { let pickerRect = colorElem.getBoundingClientRect() let pickerRight = pickerRect.left + 200 diff --git a/src/frontend/components/main/popups/ManageTags.svelte b/src/frontend/components/main/popups/ManageTags.svelte new file mode 100644 index 00000000..2e7df30c --- /dev/null +++ b/src/frontend/components/main/popups/ManageTags.svelte @@ -0,0 +1,96 @@ + + +
+ {#if tags.length} + {#each tags as tag} + + updateKey(e, tag.id, "name")} /> + updateKey(e, tag.id, "color")} rightAlign /> + + + + {/each} + {:else} +
+ +
+ {/if} + +
+ + + + +
+ + diff --git a/src/frontend/components/main/popups/SlideShortcut.svelte b/src/frontend/components/main/popups/SlideShortcut.svelte index ca4889e7..63cf6b0f 100644 --- a/src/frontend/components/main/popups/SlideShortcut.svelte +++ b/src/frontend/components/main/popups/SlideShortcut.svelte @@ -38,7 +38,7 @@ -

+

{#if currentShortcut}
diff --git a/src/frontend/components/output/clear.ts b/src/frontend/components/output/clear.ts index bb6b0926..2f20632a 100644 --- a/src/frontend/components/output/clear.ts +++ b/src/frontend/components/output/clear.ts @@ -41,7 +41,7 @@ export function clearAll(button: boolean = false) { clearBackground() clearSlide(true) clearOverlays() - clearAudio() + clearAudio("", true, false, true) clearTimers() } diff --git a/src/frontend/components/output/preview/ClearButtons.svelte b/src/frontend/components/output/preview/ClearButtons.svelte index 52db13ac..053d14f4 100644 --- a/src/frontend/components/output/preview/ClearButtons.svelte +++ b/src/frontend/components/output/preview/ClearButtons.svelte @@ -32,7 +32,7 @@ background: () => clearBackground(), slide: () => clearSlide(), overlays: () => clearOverlays(), - audio: () => clearAudio(), + audio: () => clearAudio("", true, false, true), nextTimer: () => clearTimers(), } diff --git a/src/frontend/components/settings/tabs/Groups.svelte b/src/frontend/components/settings/tabs/Groups.svelte index 659d85ba..ba41c024 100644 --- a/src/frontend/components/settings/tabs/Groups.svelte +++ b/src/frontend/components/settings/tabs/Groups.svelte @@ -88,6 +88,7 @@ special.update((a) => { delete a.numberKeys + delete a.autoLetterShortcut a.capitalize_words = "Jesus, Lord" // updateSettings.ts return a }) @@ -159,6 +160,7 @@ on:click={() => { history({ id: "UPDATE", newData: { id: group.id }, location: { page: "settings", id: "global_group" } }) }} + title={$dictionary.actions?.delete} > @@ -166,16 +168,19 @@ {/each} + + + +
-
diff --git a/src/frontend/components/settings/tabs/Outputs.svelte b/src/frontend/components/settings/tabs/Outputs.svelte index fa8eced4..cc7edb74 100644 --- a/src/frontend/components/settings/tabs/Outputs.svelte +++ b/src/frontend/components/settings/tabs/Outputs.svelte @@ -37,7 +37,7 @@ // auto revert special values if (autoRevert.includes(key) && value && !reverted.includes(key)) { - newToast($dictionary.toast?.reverting_setting?.replace("{}", revertTime.toString())) + newToast($dictionary.toast?.reverting_setting?.replace("{}", revertTime.toString()) || "") reverted.push(key) setTimeout(() => { updateOutput(key, false, outputId) @@ -45,7 +45,9 @@ }, revertTime * 1000) } - if (key === "blackmagic") { + if (key === "ndi") { + if (value) newToast("$toast.output_capture_enabled") + } else if (key === "blackmagic") { if (value === true) { // send(BLACKMAGIC, ["GET_DEVICES"]) updateOutput("transparent", true) diff --git a/src/frontend/components/settings/tabs/Theme.svelte b/src/frontend/components/settings/tabs/Theme.svelte index eae80ea2..d93f938c 100644 --- a/src/frontend/components/settings/tabs/Theme.svelte +++ b/src/frontend/components/settings/tabs/Theme.svelte @@ -22,8 +22,8 @@ "primary-darker", "primary-darkest", "secondary", - "secondary-text", "text", + "secondary-text", // "textInvert", // "secondary-opacity", // "hover", @@ -160,10 +160,12 @@ - + {#if Object.values($themes).length < 10} + + {/if}
diff --git a/src/frontend/components/slide/views/Timer.svelte b/src/frontend/components/slide/views/Timer.svelte index c898d767..7bc673a6 100644 --- a/src/frontend/components/slide/views/Timer.svelte +++ b/src/frontend/components/slide/views/Timer.svelte @@ -30,7 +30,7 @@ $: min = Math.min(timer.start || 0, timer.end || 0) $: max = Math.max(timer.start || 0, timer.end || 0) $: percentage = Math.max(0, Math.min(100, ((currentTime - min) / (max - min)) * 100)) - $: itemColor = getStyles(item?.style)?.color || "white" + $: itemColor = getStyles(item?.style)?.color || "#ffffff" $: overflow = getTimerOverflow(currentTime) $: negative = timer?.start! > timer?.end! || currentTime < 0 diff --git a/src/frontend/converters/opensong.ts b/src/frontend/converters/opensong.ts index 243eee6e..d7d829e7 100644 --- a/src/frontend/converters/opensong.ts +++ b/src/frontend/converters/opensong.ts @@ -4,8 +4,8 @@ import { checkName, formatToFileName } from "../components/helpers/show" import type { Bible } from "./../../types/Bible" import { ShowObj } from "./../classes/Show" import { activePopup, alertMessage, dictionary, groups, scriptures, scripturesCache } from "./../stores" -import { createCategory, setTempShows } from "./importHelpers" import { setActiveScripture } from "./bible" +import { createCategory, setTempShows } from "./importHelpers" interface Song { title: string @@ -39,7 +39,9 @@ export function convertOpenSong(data: any) { setTimeout(() => { data?.forEach(({ content }: any) => { - let song = XMLtoObject(content) + let song: any = {} + if (content.includes("")) song = HTMLtoObject(content) + else song = XMLtoObject(content) console.log(song) let layoutID = uid() @@ -239,3 +241,50 @@ function XMLtoBible(xml: string): Bible { } const getChildren = (parent: any, name: string) => parent.getElementsByTagName(name) + +function HTMLtoObject(content: string) { + let parser = new DOMParser() + let html = parser.parseFromString(content, "text/html").children[0]?.querySelector("body") + + // WIP chords + + const groups = content.split('').slice(1) + let lyrics: string = "" + groups.forEach(group =>{ + let linesEnd = group.lastIndexOf("
") + let g = group.slice(0, linesEnd) + const lines = group.indexOf(" -1 ? g.split("').slice(1) + + let groupName = group.slice(0, group.indexOf("
")).trim() + lyrics += `[${groupName}]\n` + + lines.forEach(line => { + const sections = line.indexOf('class="lyrics">') > -1 ? line.split('class="lyrics">').slice(1) : [line] + + sections.forEach(section => { + let text = section.slice(0, section.indexOf("")) + lyrics += text + }) + + lyrics += "\n" + }) + + lyrics = lyrics.trim() + "\n\n" + }) + + lyrics = lyrics.trim() + + let object: Song = { + title: html?.querySelector("#title")?.textContent || "", + author: html?.querySelector("#author")?.textContent || "", + ccli: html?.querySelector("#ccli")?.textContent || "", + copyright: html?.querySelector("#copyright")?.textContent || "", + time_sig: html?.querySelector("#time_sig")?.textContent || "", + lyrics, + hymn_number: html?.querySelector("#hymn_number")?.textContent || "", + key: html?.querySelector("#key")?.textContent || "", + backgrounds: html?.querySelector("#backgrounds")?.textContent || "", + } + + return object +} diff --git a/src/frontend/stores.ts b/src/frontend/stores.ts index 3e907bea..b1dc8049 100644 --- a/src/frontend/stores.ts +++ b/src/frontend/stores.ts @@ -9,7 +9,7 @@ import type { Draw, DrawSettings, DrawTools } from "../types/Draw" import type { ActiveEdit, Media, MediaOptions, NumberObject, Popups, Selected, SlidesOptions } from "../types/Main" import type { Folders, Projects, ShowRef } from "../types/Projects" import type { Dictionary, Styles, Themes } from "../types/Settings" -import type { ID, MidiIn, Overlays, ShowList, Shows, Templates, Timer, Transition } from "../types/Show" +import type { ID, MidiIn, Overlays, ShowList, Shows, Tag, Templates, Timer, Transition } from "../types/Show" import type { ActiveStage, StageLayouts } from "../types/Stage" import type { BibleCategories, Categories, DrawerTabs, SettingsTabs, TopViews } from "../types/Tabs" import type { Channels, Playlist } from "./../types/Audio" @@ -60,6 +60,7 @@ export const activeAnimate: Writable = writable({ slide: -1, index: -1 }) export const allOutputs: Writable = writable({}) // stage data in output windows export const activeScripture: Writable = writable({}) export const activeTagFilter: Writable = writable([]) +export const activeMediaTagFilter: Writable = writable([]) export const activeTriggerFunction: Writable = writable("") export const guideActive: Writable = writable(false) export const runningActions: Writable = writable([]) @@ -167,7 +168,7 @@ export const transitionData: Writable<{ text: Transition; media: Transition }> = media: { type: "fade", duration: 800, easing: "sine" }, }) // {default} export const slidesOptions: Writable = writable({ columns: 4, mode: "grid" }) // {default} -export const globalTags: Writable<{ [key: string]: { name: string; color: string } }> = writable({}) // {} +export const globalTags: Writable<{ [key: string]: Tag }> = writable({}) // {} // PROJECT export const openedFolders: Writable = writable([]) // [] @@ -189,6 +190,7 @@ export const triggers: Writable<{ [key: string]: any }> = writable({}) // {} export const media: Writable = writable({}) // {} export const mediaFolders: Writable = writable({}) // {default} export const videoMarkers: Writable<{ [key: string]: { name: string; time: number }[] }> = writable({}) // {} +export const mediaTags: Writable<{ [key: string]: Tag }> = writable({}) // {} export const checkedFiles: Writable = writable([]) // OVERLAYS diff --git a/src/frontend/utils/controllerTalk.ts b/src/frontend/utils/controllerTalk.ts index 5a225d8c..371d5919 100644 --- a/src/frontend/utils/controllerTalk.ts +++ b/src/frontend/utils/controllerTalk.ts @@ -53,7 +53,7 @@ export const receiveCONTROLLER = { draw.set(data.offset) drawTool.set(tool) - if (tool === "paint") paintCache.set([{ x: 0, y: 0, size: 0, color: "white" }]) + if (tool === "paint") paintCache.set([{ x: 0, y: 0, size: 0, color: "#ffffff" }]) }, GET_OUTPUT_ID: () => { return { channel: "GET_OUTPUT_ID", data: get(serverData)?.output_stream?.outputId || getActiveOutputs(get(outputs), false, true, true)[0] } diff --git a/src/frontend/utils/popup.ts b/src/frontend/utils/popup.ts index 1aadff9c..6c850238 100644 --- a/src/frontend/utils/popup.ts +++ b/src/frontend/utils/popup.ts @@ -47,6 +47,7 @@ import Unsaved from "../components/main/popups/Unsaved.svelte" import Variable from "../components/main/popups/Variable.svelte" import { activePopup, popupData } from "../stores" import CategoryAction from "../components/main/popups/CategoryAction.svelte" +import ManageTags from "../components/main/popups/ManageTags.svelte" export const popups: { [key in Popups]: ComponentType } = { initialize: Initialize, @@ -82,6 +83,7 @@ export const popups: { [key in Popups]: ComponentType } = { animate: Animate, translate: Translate, next_timer: NextTimer, + manage_tags: ManageTags, advanced_settings: AdvancedScreen, about: About, shortcuts: Shortcuts, diff --git a/src/frontend/utils/save.ts b/src/frontend/utils/save.ts index 4580ed0c..a245189d 100644 --- a/src/frontend/utils/save.ts +++ b/src/frontend/utils/save.ts @@ -38,6 +38,7 @@ import { media, mediaFolders, mediaOptions, + mediaTags, metronome, midiIn, openedFolders, @@ -159,6 +160,7 @@ export function save(closeWhenFinished: boolean = false, customTriggers: { backu audioPlaylists: get(audioPlaylists), midiIn: get(midiIn), videoMarkers: get(videoMarkers), + mediaTags: get(mediaTags), customizedIcons: get(customizedIcons), companion: get(companion), globalTags: get(globalTags), @@ -217,7 +219,7 @@ export function saveComplete({ closeWhenFinished, customTriggers }: any) { if (customTriggers?.backup || customTriggers?.changeUserData) return let mainFolderId = get(driveData)?.mainFolderId - if (!mainFolderId || get(driveData)?.disabled === true) { + if (!mainFolderId || get(driveData)?.disabled === true || !Object.keys(get(driveKeys)).length) { if (closeWhenFinished) closeApp() return @@ -352,6 +354,7 @@ const saveList: { [key in SaveList]: any } = { gain: null, midiIn: midiIn, videoMarkers: videoMarkers, + mediaTags: mediaTags, customizedIcons: customizedIcons, driveKeys: driveKeys, driveData: driveData, diff --git a/src/frontend/utils/shortcuts.ts b/src/frontend/utils/shortcuts.ts index 881de1e6..311a93e4 100644 --- a/src/frontend/utils/shortcuts.ts +++ b/src/frontend/utils/shortcuts.ts @@ -217,7 +217,7 @@ export const previewShortcuts: any = { if (!get(outLocked)) setOutput("overlays", []) }, F4: () => { - if (!get(outLocked)) clearAudio() + if (!get(outLocked)) clearAudio("", true, false, true) }, F5: () => { if (!get(special).disablePresenterControllerKeys) nextSlideIndividual(null) diff --git a/src/frontend/utils/updateSettings.ts b/src/frontend/utils/updateSettings.ts index 7f2e550b..c1161137 100644 --- a/src/frontend/utils/updateSettings.ts +++ b/src/frontend/utils/updateSettings.ts @@ -37,6 +37,7 @@ import { lockedOverlays, mediaFolders, mediaOptions, + mediaTags, metronome, midiIn, openedFolders, @@ -120,7 +121,7 @@ export function updateSettings(data: any) { setTimeout(() => { restartOutputs() if (get(autoOutput)) setTimeout(() => displayOutputs({}, true), 500) - setTimeout(checkWindowCapture, 1000) + setTimeout(() => checkWindowCapture(true), 1000) }, 1500) } @@ -282,6 +283,7 @@ const updateList: { [key in SaveListSettings | SaveListSyncedSettings]: any } = gain: (v: any) => gain.set(v), midiIn: (v: any) => midiIn.set(v), videoMarkers: (v: any) => videoMarkers.set(v), + mediaTags: (v: any) => mediaTags.set(v), customizedIcons: (v: any) => customizedIcons.set(v), driveData: (v: any) => driveData.set(v), calendarAddShow: (v: any) => calendarAddShow.set(v), diff --git a/src/types/Main.ts b/src/types/Main.ts index 1975fa11..33463088 100644 --- a/src/types/Main.ts +++ b/src/types/Main.ts @@ -107,6 +107,7 @@ export interface MediaStyle { volume?: number // audio rendering?: string // image rendering info?: any // cached codec/mime data + tags?: string[] // media tags } export type Popups = @@ -143,6 +144,7 @@ export type Popups = | "animate" | "translate" | "next_timer" + | "manage_tags" | "advanced_settings" | "about" | "shortcuts" diff --git a/src/types/Save.ts b/src/types/Save.ts index 4e47d231..83000ffd 100644 --- a/src/types/Save.ts +++ b/src/types/Save.ts @@ -15,6 +15,7 @@ export type SaveListSyncedSettings = | "groups" | "midiIn" | "videoMarkers" + | "mediaTags" | "customizedIcons" | "companion" | "globalTags" diff --git a/src/types/Show.ts b/src/types/Show.ts index ac005b54..7fb599f2 100644 --- a/src/types/Show.ts +++ b/src/types/Show.ts @@ -364,6 +364,11 @@ export interface OutTransition { duration: number } +export interface Tag { + name: string + color: string +} + // types export type ID = string