Merge remote-tracking branch 'origin/main' into claude/nip17-dm-cli-plan-vvtb5
This commit is contained in:
-1
@@ -217,7 +217,6 @@ private fun hasNonDefaultFilters(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Suppress("AssignedValueIsNeverRead")
|
||||
@Composable
|
||||
@Suppress("AssignedValueIsNeverRead")
|
||||
private fun SearchFilterRow(searchBarViewModel: SearchBarViewModel) {
|
||||
val currentScope by searchBarViewModel.scope.collectAsStateWithLifecycle()
|
||||
val currentSource by searchBarViewModel.source.collectAsStateWithLifecycle()
|
||||
|
||||
@@ -2164,4 +2164,66 @@
|
||||
<string name="emoji_private_badge">Soukromé emoji</string>
|
||||
<string name="emoji_public_explainer">Veřejná emoji jsou viditelná pro všechny a objeví se ve vaší nabídce reakcí a v automatickém doplňování \":\", když je tento balíček ve vašem seznamu emoji.</string>
|
||||
<string name="emoji_private_explainer">Soukromá emoji jsou šifrovaně uložena na relayích a viditelná pouze pro vás. Objeví se ve vaší nabídce reakcí a v automatickém doplňování \":\" stejně jako veřejná.</string>
|
||||
<string name="always_on_notif_channel_description">Udržuje připojení k vašim inbox relayím aktivní pro oznámení v reálném čase</string>
|
||||
<string name="always_on_notif_connected">Připojeno k %1$d inbox relayím</string>
|
||||
<string name="always_on_notif_connecting">Připojování k inbox relayím\u2026</string>
|
||||
<string name="always_on_notif_setting_description">Udržuje trvalé připojení k vašim inbox relayím pro okamžité doručování oznámení. Zobrazuje průběžné oznámení. Spotřebovává více baterie, ale zajišťuje, že nezmeškáte žádnou zprávu.</string>
|
||||
<string name="always_on_notif_setting_title">Služba trvalých oznámení</string>
|
||||
<string name="always_on_notif_stop">Pozastavit</string>
|
||||
<string name="always_on_notif_title">Amethyst oznámení aktivní</string>
|
||||
<string name="audio_room_audience">Publikum</string>
|
||||
<string name="audio_room_lower_hand">Dát ruku dolů</string>
|
||||
<string name="audio_room_raise_hand">Přihlásit se</string>
|
||||
<string name="audio_room_stage">Pódium</string>
|
||||
<string name="audio_rooms">Audio místnosti</string>
|
||||
<string name="badge_image_placeholder">https://example.com/badge.png</string>
|
||||
<string name="badge_thumb_placeholder">https://example.com/badge-thumb.png</string>
|
||||
<string name="battery_optimization_description">Android může omezit připojení k relayím na pozadí. Vypněte optimalizaci baterie pro Amethyst, aby byla oznámení spolehlivá.</string>
|
||||
<string name="battery_optimization_fix_now">Opravit</string>
|
||||
<string name="battery_optimization_title">Optimalizace baterie aktivní</string>
|
||||
<string name="bottom_bar_settings">Spodní navigační lišta</string>
|
||||
<string name="bottom_bar_settings_available">Dostupné</string>
|
||||
<string name="bottom_bar_settings_description">Přetažením změníte pořadí. Přepnutím položku přidáte nebo odeberete ze spodní lišty. S nulovým počtem položek bude lišta skryta.</string>
|
||||
<string name="bottom_bar_settings_reorder">Změnit pořadí</string>
|
||||
<string name="drawer_section_create">Vytvořit</string>
|
||||
<string name="drawer_section_feeds">Kanály</string>
|
||||
<string name="drawer_section_navigate">Navigace</string>
|
||||
<string name="drawer_section_system">Systém</string>
|
||||
<string name="drawer_section_you">Vy</string>
|
||||
<string name="emoji_sets">Emoji</string>
|
||||
<string name="follow_packs">Seznamy sledování</string>
|
||||
<string name="live_streams">Živé vysílání</string>
|
||||
<string name="public_chats">Veřejné chaty</string>
|
||||
<string name="search_filters_open">Filtry</string>
|
||||
<string name="search_filters_reset">Obnovit</string>
|
||||
<string name="search_filters_section_sort">Seřadit podle</string>
|
||||
<string name="search_filters_section_source">Zdroj</string>
|
||||
<string name="search_filters_title">Filtry</string>
|
||||
<string name="search_follows_only">Pouze sledovaní</string>
|
||||
<string name="search_scope_all">Vše</string>
|
||||
<string name="search_scope_notes">Poznámky</string>
|
||||
<string name="search_scope_people">Lidé</string>
|
||||
<string name="search_sort_newest">Nejnovější</string>
|
||||
<string name="search_sort_oldest">Nejstarší</string>
|
||||
<string name="search_sort_popular">Populární</string>
|
||||
<string name="search_sort_relevance">Relevance</string>
|
||||
<string name="search_source_local">Lokální</string>
|
||||
<string name="search_source_relays">Relaye</string>
|
||||
<string name="video_player_settings">Tlačítka přehrávače videa</string>
|
||||
<string name="video_player_settings_description">Zvolte, která tlačítka se objeví na přehrávači videa a která budou v nabídce přetečení. Přetažením změníte pořadí.</string>
|
||||
<string name="video_player_settings_reorder">Změnit pořadí</string>
|
||||
<string name="video_player_settings_location_top_bar">Horní lišta</string>
|
||||
<string name="video_player_settings_location_overflow">Nabídka přetečení</string>
|
||||
<string name="video_player_settings_action_fullscreen">Celá obrazovka</string>
|
||||
<string name="video_player_settings_action_fullscreen_description">Otevřít video v zobrazení na celou obrazovku</string>
|
||||
<string name="video_player_settings_action_mute">Ztlumit</string>
|
||||
<string name="video_player_settings_action_mute_description">Zapnout nebo vypnout zvuk</string>
|
||||
<string name="video_player_settings_action_quality">Kvalita videa</string>
|
||||
<string name="video_player_settings_action_quality_description">Vybrat rozlišení pro HLS videa (skryto pro jiná videa)</string>
|
||||
<string name="video_player_settings_action_share">Sdílet nebo uložit</string>
|
||||
<string name="video_player_settings_action_share_description">Sdílet odkaz na video externě</string>
|
||||
<string name="video_player_settings_action_download">Uložit do telefonu</string>
|
||||
<string name="video_player_settings_action_download_description">Stáhnout video do zařízení (skryto u živých vysílání)</string>
|
||||
<string name="video_player_settings_action_pip">Obraz v obraze</string>
|
||||
<string name="video_player_settings_action_pip_description">Přehrávat video v plovoucím okně (skryto, pokud není podporováno)</string>
|
||||
</resources>
|
||||
|
||||
@@ -2167,4 +2167,68 @@ anz der Bedingungen ist erforderlich</string>
|
||||
<string name="emoji_private_badge">Privates Emoji</string>
|
||||
<string name="emoji_public_explainer">Öffentliche Emojis sind für alle sichtbar und erscheinen in deinem Reaktionsmenü und in der \":\"-Autovervollständigungsauswahl, wenn dieses Paket in deiner Emoji-Liste ist.</string>
|
||||
<string name="emoji_private_explainer">Private Emojis werden verschlüsselt auf Relays gespeichert und sind nur für dich sichtbar. Sie erscheinen in deinem Reaktionsmenü und in der \":\"-Autovervollständigung wie öffentliche.</string>
|
||||
<string name="always_on_notif_channel_description">Hält Verbindungen zu deinen Inbox-Relays aktiv für Echtzeit-Benachrichtigungen</string>
|
||||
<string name="always_on_notif_connected">Mit %1$d Inbox-Relays verbunden</string>
|
||||
<string name="always_on_notif_connecting">Verbinde mit Inbox-Relays\u2026</string>
|
||||
<string name="always_on_notif_setting_description">Hält eine dauerhafte Verbindung zu deinen Inbox-Relays für sofortige Benachrichtigungen aufrecht. Zeigt eine fortlaufende Benachrichtigung an. Verbraucht mehr Akku, stellt aber sicher, dass du keine Nachricht verpasst.</string>
|
||||
<string name="always_on_notif_setting_title">Dauerhafter Benachrichtigungsdienst</string>
|
||||
<string name="always_on_notif_stop">Pausieren</string>
|
||||
<string name="always_on_notif_title">Amethyst-Benachrichtigungen aktiv</string>
|
||||
<string name="audio_room_audience">Publikum</string>
|
||||
<string name="audio_room_lower_hand">Hand senken</string>
|
||||
<string name="audio_room_raise_hand">Hand heben</string>
|
||||
<string name="audio_room_stage">Bühne</string>
|
||||
<string name="audio_rooms">Audioräume</string>
|
||||
<string name="badge_image_placeholder">https://example.com/badge.png</string>
|
||||
<string name="badge_thumb_placeholder">https://example.com/badge-thumb.png</string>
|
||||
<string name="battery_optimization_description">Android kann Relay-Verbindungen im Hintergrund einschränken. Deaktiviere die Akkuoptimierung für Amethyst, um zuverlässige Benachrichtigungen zu gewährleisten.</string>
|
||||
<string name="battery_optimization_fix_now">Jetzt beheben</string>
|
||||
<string name="battery_optimization_title">Akkuoptimierung aktiv</string>
|
||||
<string name="bottom_bar_settings">Untere Navigationsleiste</string>
|
||||
<string name="bottom_bar_settings_available">Verfügbar</string>
|
||||
<string name="bottom_bar_settings_description">Zum Umordnen ziehen. Zum Hinzufügen oder Entfernen eines Elements aus der unteren Leiste umschalten. Mit null Elementen wird die untere Leiste ausgeblendet.</string>
|
||||
<string name="bottom_bar_settings_reorder">Umordnen</string>
|
||||
<string name="drawer_section_create">Erstellen</string>
|
||||
<string name="drawer_section_feeds">Feeds</string>
|
||||
<string name="drawer_section_navigate">Navigieren</string>
|
||||
<string name="drawer_section_system">System</string>
|
||||
<string name="drawer_section_you">Du</string>
|
||||
<string name="emoji_sets">Emojis</string>
|
||||
<string name="follow_packs">Follow-Pakete</string>
|
||||
<string name="live_streams">Live-Streams</string>
|
||||
<string name="public_chats">Öffentliche Chats</string>
|
||||
<string name="search_filters_open">Filter</string>
|
||||
<string name="search_filters_reset">Zurücksetzen</string>
|
||||
<string name="search_filters_section_sort">Sortieren nach</string>
|
||||
<string name="search_filters_section_source">Quelle</string>
|
||||
<string name="search_filters_title">Filter</string>
|
||||
<string name="search_follows_only">Nur Gefolgte</string>
|
||||
<string name="search_scope_all">Alle</string>
|
||||
<string name="search_scope_notes">Notizen</string>
|
||||
<string name="search_scope_people">Personen</string>
|
||||
<string name="search_sort_newest">Neueste</string>
|
||||
<string name="search_sort_oldest">Älteste</string>
|
||||
<string name="search_sort_popular">Beliebte</string>
|
||||
<string name="search_sort_relevance">Relevanz</string>
|
||||
<string name="search_source_local">Lokal</string>
|
||||
<string name="search_source_relays">Relays</string>
|
||||
<string name="video_player_settings">Videoplayer-Schaltflächen</string>
|
||||
<string name="video_player_settings_description">Wähle, welche Schaltflächen im Videoplayer erscheinen und welche im Überlaufmenü liegen. Zum Umordnen ziehen.</string>
|
||||
<string name="video_player_settings_reorder">Umordnen</string>
|
||||
<string name="video_player_settings_location_top_bar">Obere Leiste</string>
|
||||
<string name="video_player_settings_location_overflow">Überlaufmenü</string>
|
||||
<string name="video_player_settings_action_fullscreen">Vollbild</string>
|
||||
<string name="video_player_settings_action_fullscreen_description">Video in einer Vollbildansicht öffnen</string>
|
||||
<string name="video_player_settings_action_mute">Stumm</string>
|
||||
<string name="video_player_settings_action_mute_description">Ton ein- oder ausschalten</string>
|
||||
<string name="video_player_settings_action_quality">Videoqualität</string>
|
||||
<string name="video_player_settings_action_quality_description">Auflösung für HLS-Videos wählen (bei Nicht-HLS-Videos ausgeblendet)</string>
|
||||
<string name="video_player_settings_action_share">Teilen oder speichern</string>
|
||||
<string name="video_player_settings_action_share_description">Den Videolink extern teilen</string>
|
||||
<string name="video_player_settings_action_download">Auf Telefon speichern</string>
|
||||
<string name="video_player_settings_action_download_description">Video auf dein Gerät herunterladen (bei Live-Streams ausgeblendet)</string>
|
||||
<string name="video_player_settings_action_pip">Bild-in-Bild</string>
|
||||
<string name="video_player_settings_action_pip_description">Video in einem schwebenden Fenster abspielen (ausgeblendet, wenn nicht unterstützt)</string>
|
||||
<string name="badge_name_label">Name</string>
|
||||
<string name="new_community_relays_section">Relays</string>
|
||||
</resources>
|
||||
|
||||
@@ -2161,4 +2161,69 @@
|
||||
<string name="emoji_private_badge">Emoji privado</string>
|
||||
<string name="emoji_public_explainer">Emojis públicos são visíveis para todos e aparecem no seu menu de reações e no seletor de autocompletar \":\" quando este pacote está na sua lista de emojis.</string>
|
||||
<string name="emoji_private_explainer">Emojis privados são armazenados criptografados em relays e visíveis apenas para você. Eles aparecem no seu menu de reações e no autocompletar \":\" assim como os públicos.</string>
|
||||
<string name="always_on_notif_channel_description">Mantém as conexões com seus relays de caixa de entrada ativas para notificações em tempo real</string>
|
||||
<string name="always_on_notif_connected">Conectado a %1$d relays de caixa de entrada</string>
|
||||
<string name="always_on_notif_connecting">Conectando aos relays de caixa de entrada\u2026</string>
|
||||
<string name="always_on_notif_setting_description">Mantém uma conexão persistente com seus relays de caixa de entrada para entrega instantânea de notificações. Mostra uma notificação contínua. Usa mais bateria, mas garante que você nunca perca uma mensagem.</string>
|
||||
<string name="always_on_notif_setting_title">Serviço de notificações sempre ativo</string>
|
||||
<string name="always_on_notif_stop">Pausar</string>
|
||||
<string name="always_on_notif_title">Notificações do Amethyst ativas</string>
|
||||
<string name="audio_room_audience">Plateia</string>
|
||||
<string name="audio_room_lower_hand">Abaixar mão</string>
|
||||
<string name="audio_room_raise_hand">Levantar mão</string>
|
||||
<string name="audio_room_stage">Palco</string>
|
||||
<string name="audio_rooms">Salas de áudio</string>
|
||||
<string name="badge_image_placeholder">https://example.com/badge.png</string>
|
||||
<string name="badge_thumb_placeholder">https://example.com/badge-thumb.png</string>
|
||||
<string name="battery_optimization_description">O Android pode restringir conexões de relay em segundo plano. Desative a otimização de bateria para o Amethyst para garantir notificações confiáveis.</string>
|
||||
<string name="battery_optimization_fix_now">Corrigir agora</string>
|
||||
<string name="battery_optimization_title">Otimização de bateria ativa</string>
|
||||
<string name="bottom_bar_settings">Barra de navegação inferior</string>
|
||||
<string name="bottom_bar_settings_available">Disponíveis</string>
|
||||
<string name="bottom_bar_settings_description">Arraste para reordenar. Alterne para adicionar ou remover um item da barra inferior. Com zero itens, a barra inferior fica oculta.</string>
|
||||
<string name="bottom_bar_settings_reorder">Reordenar</string>
|
||||
<string name="drawer_section_create">Criar</string>
|
||||
<string name="drawer_section_feeds">Feeds</string>
|
||||
<string name="drawer_section_navigate">Navegar</string>
|
||||
<string name="drawer_section_system">Sistema</string>
|
||||
<string name="drawer_section_you">Você</string>
|
||||
<string name="emoji_sets">Emojis</string>
|
||||
<string name="follow_packs">Pacotes de seguidos</string>
|
||||
<string name="live_streams">Transmissões ao vivo</string>
|
||||
<string name="public_chats">Chats públicos</string>
|
||||
<string name="search_filters_open">Filtros</string>
|
||||
<string name="search_filters_reset">Redefinir</string>
|
||||
<string name="search_filters_section_sort">Ordenar por</string>
|
||||
<string name="search_filters_section_source">Fonte</string>
|
||||
<string name="search_filters_title">Filtros</string>
|
||||
<string name="search_follows_only">Apenas seguidos</string>
|
||||
<string name="search_scope_all">Tudo</string>
|
||||
<string name="search_scope_notes">Notas</string>
|
||||
<string name="search_scope_people">Pessoas</string>
|
||||
<string name="search_sort_newest">Mais recentes</string>
|
||||
<string name="search_sort_oldest">Mais antigos</string>
|
||||
<string name="search_sort_popular">Populares</string>
|
||||
<string name="search_sort_relevance">Relevância</string>
|
||||
<string name="search_source_local">Local</string>
|
||||
<string name="search_source_relays">Relays</string>
|
||||
<string name="video_player_settings">Botões do reprodutor de vídeo</string>
|
||||
<string name="video_player_settings_description">Escolha quais botões aparecem no reprodutor de vídeo e quais ficam no menu de transbordo. Arraste para reordenar.</string>
|
||||
<string name="video_player_settings_reorder">Reordenar</string>
|
||||
<string name="video_player_settings_location_top_bar">Barra superior</string>
|
||||
<string name="video_player_settings_location_overflow">Menu de transbordo</string>
|
||||
<string name="video_player_settings_action_fullscreen">Tela cheia</string>
|
||||
<string name="video_player_settings_action_fullscreen_description">Abrir o vídeo em modo tela cheia</string>
|
||||
<string name="video_player_settings_action_mute">Silenciar</string>
|
||||
<string name="video_player_settings_action_mute_description">Ativar ou desativar o áudio</string>
|
||||
<string name="video_player_settings_action_quality">Qualidade do vídeo</string>
|
||||
<string name="video_player_settings_action_quality_description">Escolher uma resolução para vídeos HLS (oculto em vídeos não-HLS)</string>
|
||||
<string name="video_player_settings_action_share">Compartilhar ou salvar</string>
|
||||
<string name="video_player_settings_action_share_description">Compartilhar o link do vídeo externamente</string>
|
||||
<string name="video_player_settings_action_download">Salvar no telefone</string>
|
||||
<string name="video_player_settings_action_download_description">Baixar o vídeo para o dispositivo (oculto em transmissões ao vivo)</string>
|
||||
<string name="video_player_settings_action_pip">Picture-in-Picture</string>
|
||||
<string name="video_player_settings_action_pip_description">Reproduzir o vídeo em uma janela flutuante (oculto se não suportado)</string>
|
||||
<string name="emoji_pack_count">%1$d emojis</string>
|
||||
<string name="interest_set_hashtag_count">%1$d hashtag(s)</string>
|
||||
<string name="new_community_relays_section">Relays</string>
|
||||
</resources>
|
||||
|
||||
@@ -2162,4 +2162,67 @@
|
||||
<string name="emoji_private_badge">Privat emoji</string>
|
||||
<string name="emoji_public_explainer">Offentliga emojis är synliga för alla och visas i din reaktionsmeny och i \":\"-autokompletteringen när detta paket finns i din emoji-lista.</string>
|
||||
<string name="emoji_private_explainer">Privata emojis lagras krypterade på relän och är endast synliga för dig. De visas i din reaktionsmeny och i autokomplettering med \":\" precis som offentliga.</string>
|
||||
<string name="always_on_notif_channel_description">Håller anslutningarna till dina inbox-relän aktiva för realtidsnotifieringar</string>
|
||||
<string name="always_on_notif_connected">Ansluten till %1$d inbox-relän</string>
|
||||
<string name="always_on_notif_connecting">Ansluter till inbox-relän\u2026</string>
|
||||
<string name="always_on_notif_setting_description">Upprätthåller en konstant anslutning till dina inbox-relän för omedelbar leverans av notifieringar. Visar en pågående notifiering. Använder mer batteri men säkerställer att du aldrig missar ett meddelande.</string>
|
||||
<string name="always_on_notif_setting_title">Alltid på-notifieringstjänst</string>
|
||||
<string name="always_on_notif_stop">Pausa</string>
|
||||
<string name="always_on_notif_title">Amethyst-notifieringar aktiva</string>
|
||||
<string name="audio_room_audience">Publik</string>
|
||||
<string name="audio_room_lower_hand">Sänk handen</string>
|
||||
<string name="audio_room_raise_hand">Räck upp handen</string>
|
||||
<string name="audio_room_stage">Scen</string>
|
||||
<string name="audio_rooms">Ljudrum</string>
|
||||
<string name="badge_image_placeholder">https://example.com/badge.png</string>
|
||||
<string name="badge_thumb_placeholder">https://example.com/badge-thumb.png</string>
|
||||
<string name="battery_optimization_description">Android kan begränsa reläanslutningar i bakgrunden. Inaktivera batterioptimering för Amethyst för att säkerställa tillförlitliga notifieringar.</string>
|
||||
<string name="battery_optimization_fix_now">Åtgärda nu</string>
|
||||
<string name="battery_optimization_title">Batterioptimering aktiv</string>
|
||||
<string name="bottom_bar_settings">Nedre navigeringsfält</string>
|
||||
<string name="bottom_bar_settings_available">Tillgängliga</string>
|
||||
<string name="bottom_bar_settings_description">Dra för att ändra ordning. Växla för att lägga till eller ta bort ett objekt från nedre fältet. Med noll objekt döljs det nedre fältet.</string>
|
||||
<string name="bottom_bar_settings_reorder">Ändra ordning</string>
|
||||
<string name="drawer_section_create">Skapa</string>
|
||||
<string name="drawer_section_feeds">Flöden</string>
|
||||
<string name="drawer_section_navigate">Navigera</string>
|
||||
<string name="drawer_section_system">System</string>
|
||||
<string name="drawer_section_you">Du</string>
|
||||
<string name="emoji_sets">Emojis</string>
|
||||
<string name="follow_packs">Följpaket</string>
|
||||
<string name="live_streams">Livesändningar</string>
|
||||
<string name="public_chats">Offentliga chattar</string>
|
||||
<string name="search_filters_open">Filter</string>
|
||||
<string name="search_filters_reset">Återställ</string>
|
||||
<string name="search_filters_section_sort">Sortera efter</string>
|
||||
<string name="search_filters_section_source">Källa</string>
|
||||
<string name="search_filters_title">Filter</string>
|
||||
<string name="search_follows_only">Endast följda</string>
|
||||
<string name="search_scope_all">Alla</string>
|
||||
<string name="search_scope_notes">Anteckningar</string>
|
||||
<string name="search_scope_people">Personer</string>
|
||||
<string name="search_sort_newest">Nyaste</string>
|
||||
<string name="search_sort_oldest">Äldsta</string>
|
||||
<string name="search_sort_popular">Populära</string>
|
||||
<string name="search_sort_relevance">Relevans</string>
|
||||
<string name="search_source_local">Lokalt</string>
|
||||
<string name="search_source_relays">Relän</string>
|
||||
<string name="video_player_settings">Videospelarens knappar</string>
|
||||
<string name="video_player_settings_description">Välj vilka knappar som visas på videospelaren och vilka som finns i överflödsmenyn. Dra för att ändra ordning.</string>
|
||||
<string name="video_player_settings_reorder">Ändra ordning</string>
|
||||
<string name="video_player_settings_location_top_bar">Övre fält</string>
|
||||
<string name="video_player_settings_location_overflow">Överflödsmeny</string>
|
||||
<string name="video_player_settings_action_fullscreen">Helskärm</string>
|
||||
<string name="video_player_settings_action_fullscreen_description">Öppna videon i helskärmsläge</string>
|
||||
<string name="video_player_settings_action_mute">Tyst</string>
|
||||
<string name="video_player_settings_action_mute_description">Slå på eller av ljudet</string>
|
||||
<string name="video_player_settings_action_quality">Videokvalitet</string>
|
||||
<string name="video_player_settings_action_quality_description">Välj en upplösning för HLS-videor (dolt för icke-HLS-videor)</string>
|
||||
<string name="video_player_settings_action_share">Dela eller spara</string>
|
||||
<string name="video_player_settings_action_share_description">Dela videolänken externt</string>
|
||||
<string name="video_player_settings_action_download">Spara på telefonen</string>
|
||||
<string name="video_player_settings_action_download_description">Ladda ner videon till enheten (dolt vid livesändningar)</string>
|
||||
<string name="video_player_settings_action_pip">Bild-i-bild</string>
|
||||
<string name="video_player_settings_action_pip_description">Spela upp videon i ett flytande fönster (dolt om det inte stöds)</string>
|
||||
<string name="emoji_pack_count">%1$d emojis</string>
|
||||
</resources>
|
||||
|
||||
@@ -86,7 +86,7 @@ preflight() {
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
fail_msg "missing required tool: $cmd"; exit 1
|
||||
fi
|
||||
info "$cmd: $(command -v "$cmd")"
|
||||
printf ' %s: %s\n' "$cmd" "$(command -v "$cmd")" >>"$LOG_FILE"
|
||||
done
|
||||
|
||||
WN_BIN="$WN_REPO/target/release/wn"
|
||||
@@ -105,8 +105,7 @@ preflight() {
|
||||
( cd "$WN_REPO" && cargo build --release --features cli --bin wn --bin wnd ) \
|
||||
2>&1 | tee -a "$LOG_FILE"
|
||||
fi
|
||||
info "wn: $WN_BIN"
|
||||
info "wnd: $WND_BIN"
|
||||
printf ' wn: %s\n wnd: %s\n' "$WN_BIN" "$WND_BIN" >>"$LOG_FILE"
|
||||
}
|
||||
|
||||
# --- daemons -----------------------------------------------------------------
|
||||
@@ -310,16 +309,12 @@ discover_a_relays() {
|
||||
return
|
||||
fi
|
||||
|
||||
step "wn_b's cached view of A's relay lists (SELECT from user_relays)"
|
||||
# Screen: one-line summary (counts per list). Full rows to $LOG_FILE.
|
||||
local rows
|
||||
# wn's SQLite schema stores `users.pubkey` — we don't have a public
|
||||
# CLI to confirm the column type, and in practice it's been observed
|
||||
# stored as both BLOB (raw 32 bytes) and TEXT (lowercase hex) across
|
||||
# versions. Try both forms so the probe doesn't falsely report "NO
|
||||
# cached relay entries" when the cache is actually populated (symptom:
|
||||
# this diagnostic warned loudly even though Tests 02/03/04/05 were
|
||||
# delivering welcomes successfully — the welcomes were flowing, the
|
||||
# probe was just querying the wrong column encoding).
|
||||
# wn's SQLite schema stores `users.pubkey` — observed as both BLOB
|
||||
# (raw 32 bytes) and TEXT (lowercase hex) across versions. Try both
|
||||
# forms so the probe doesn't falsely report "NO cached relay entries"
|
||||
# when the cache is actually populated.
|
||||
rows=$(sqlite3 -readonly "$db" \
|
||||
"SELECT ur.relay_type, r.url FROM user_relays ur
|
||||
JOIN users u ON u.id = ur.user_id
|
||||
@@ -331,22 +326,25 @@ discover_a_relays() {
|
||||
warn "wn has NO cached relay entries for A ($A_HEX)."
|
||||
warn " → Either Amethyst hasn't published kind:10002/10050/10051 to any relay wn_b"
|
||||
warn " can reach, OR wn's SQLite schema changed pubkey column encoding again."
|
||||
warn " → If later tests deliver welcomes successfully, the schema is the culprit;"
|
||||
warn " grep the daemon's migration files for the users.pubkey column type."
|
||||
return
|
||||
fi
|
||||
|
||||
# Collate by relay_type for readability.
|
||||
# Collate by relay_type. Full lists go to $LOG_FILE, only a count
|
||||
# summary reaches stderr so the happy path stays quiet.
|
||||
local nip65 inbox kp
|
||||
nip65=$(printf '%s\n' "$rows" | awk -F'|' '$1=="nip65"{print " "$2}')
|
||||
inbox=$(printf '%s\n' "$rows" | awk -F'|' '$1=="inbox"{print " "$2}')
|
||||
kp=$(printf '%s\n' "$rows" | awk -F'|' '$1=="key_package"{print " "$2}')
|
||||
info "A's kind:10002 (nip65):"
|
||||
printf '%s\n' "${nip65:- <none — A hasn't published or wn can't reach that list>}" | tee -a "$LOG_FILE" >&2
|
||||
info "A's kind:10050 (DM inbox, used for Marmot welcome delivery):"
|
||||
printf '%s\n' "${inbox:- <none — Marmot welcomes will fall back to NIP-65 read relays>}" | tee -a "$LOG_FILE" >&2
|
||||
info "A's kind:10051 (KeyPackage relays):"
|
||||
printf '%s\n' "${kp:- <none — KeyPackage discovery may still work via NIP-65>}" | tee -a "$LOG_FILE" >&2
|
||||
nip65=$(printf '%s\n' "$rows" | awk -F'|' '$1=="nip65"{print $2}')
|
||||
inbox=$(printf '%s\n' "$rows" | awk -F'|' '$1=="inbox"{print $2}')
|
||||
kp=$(printf '%s\n' "$rows" | awk -F'|' '$1=="key_package"{print $2}')
|
||||
{
|
||||
printf "A's kind:10002 (nip65):\n%s\n" "${nip65:- <none>}"
|
||||
printf "A's kind:10050 (DM inbox):\n%s\n" "${inbox:- <none>}"
|
||||
printf "A's kind:10051 (KeyPackage relays):\n%s\n" "${kp:- <none>}"
|
||||
} >>"$LOG_FILE"
|
||||
local n_nip65 n_inbox n_kp
|
||||
n_nip65=$(printf '%s' "$nip65" | grep -c '.' || true)
|
||||
n_inbox=$(printf '%s' "$inbox" | grep -c '.' || true)
|
||||
n_kp=$(printf '%s' "$kp" | grep -c '.' || true)
|
||||
info "A's relay lists: nip65=$n_nip65, inbox=$n_inbox, key_package=$n_kp (full lists in $LOG_FILE)"
|
||||
|
||||
# Warn loudly if A's DM inbox is non-empty but shares no relay with
|
||||
# wn_b's own configured set — that's the exact failure mode the
|
||||
@@ -387,16 +385,24 @@ configure_relays() {
|
||||
else
|
||||
relays=( "${DEFAULT_RELAYS[@]}" )
|
||||
fi
|
||||
# Each relay × 3 types × 2 daemons produces a lot of repetitive "ok"
|
||||
# lines — the happy path doesn't need any of it on screen. Quiet the
|
||||
# per-add logging into $LOG_FILE and only surface real failures as
|
||||
# warnings. A single summary line prints at the end.
|
||||
local adds_ok=0 adds_dup=0 adds_fail=0
|
||||
add_relay() {
|
||||
local wn_fn="$1" r="$2" t add_out
|
||||
for t in nip65 inbox key_package; do
|
||||
if add_out=$("$wn_fn" relays add --type "$t" "$r" 2>&1); then
|
||||
info "$wn_fn relays add --type $t $r: ok"
|
||||
adds_ok=$((adds_ok+1))
|
||||
printf '%s relays add --type %s %s: ok\n' "$wn_fn" "$t" "$r" >>"$LOG_FILE"
|
||||
else
|
||||
case "$add_out" in
|
||||
*"already exists"*|*"already added"*|*"duplicate"*)
|
||||
info "$wn_fn relays add --type $t $r: already exists, skipping" ;;
|
||||
adds_dup=$((adds_dup+1))
|
||||
printf '%s relays add --type %s %s: already exists\n' "$wn_fn" "$t" "$r" >>"$LOG_FILE" ;;
|
||||
*)
|
||||
adds_fail=$((adds_fail+1))
|
||||
warn "$wn_fn relays add --type $t $r failed: $add_out"
|
||||
printf '%s relays add --type %s %s: %s\n' "$wn_fn" "$t" "$r" "$add_out" >>"$LOG_FILE" ;;
|
||||
esac
|
||||
@@ -404,11 +410,12 @@ configure_relays() {
|
||||
done
|
||||
}
|
||||
|
||||
step "adding ${#relays[@]} relay(s) × 3 types × 2 daemons"
|
||||
for r in "${relays[@]}"; do
|
||||
step "adding $r to both daemons"
|
||||
add_relay wn_b "$r"
|
||||
add_relay wn_c "$r"
|
||||
done
|
||||
info "relay add: $adds_ok ok, $adds_dup already-present, $adds_fail failed"
|
||||
|
||||
# Push a kind:0 profile for each wn identity BEFORE the kind:30443 /
|
||||
# 10050 / 1059 probes. Several public relays (damus.io in particular)
|
||||
@@ -424,8 +431,7 @@ configure_relays() {
|
||||
local about="Scripted wn identity for Amethyst<->whitenoise-rs interop harness"
|
||||
local out
|
||||
if out=$("$wnfn" profile update --name "$name" --about "$about" 2>&1); then
|
||||
info "$who kind:0 published (name=\"$name\")"
|
||||
printf '%s profile update: %s\n' "$who" "$out" >>"$LOG_FILE"
|
||||
printf '%s profile update ok: %s\n' "$who" "$out" >>"$LOG_FILE"
|
||||
else
|
||||
warn "$who profile update failed: $out"
|
||||
printf '%s profile update: %s\n' "$who" "$out" >>"$LOG_FILE"
|
||||
@@ -440,10 +446,10 @@ configure_relays() {
|
||||
# follows sometimes races ahead of the kind:0 commit).
|
||||
sleep 2
|
||||
|
||||
step "B relay list after configure"
|
||||
# Full relay list goes to $LOG_FILE only — the per-relay status rarely
|
||||
# matters unless a later test fails, and it's 5-10 noisy lines otherwise.
|
||||
local relay_list
|
||||
relay_list=$(wn_b --json relays list 2>/dev/null || true)
|
||||
info "B relays: $(printf '%s' "$relay_list" | jq -r '.result[]? | "\(.url) [\(.status)]"' 2>/dev/null | tr '\n' ' ')"
|
||||
printf 'B relay list: %s\n' "$relay_list" >>"$LOG_FILE"
|
||||
|
||||
# Sanity check is split across three relay-level surfaces so a failure
|
||||
@@ -460,35 +466,34 @@ configure_relays() {
|
||||
# anyway but at least the operator will have the diagnostic hint here.
|
||||
step "sanity-check kind:30443: B+C publish + symmetric discover"
|
||||
local publish_out
|
||||
if publish_out=$(wn_b keys publish 2>&1); then
|
||||
info "wn_b keys publish: ok"
|
||||
else
|
||||
if ! publish_out=$(wn_b keys publish 2>&1); then
|
||||
warn "wn_b keys publish failed: $publish_out"
|
||||
fi
|
||||
printf 'wn_b keys publish: %s\n' "$publish_out" >>"$LOG_FILE"
|
||||
fi
|
||||
if publish_out=$(wn_c keys publish 2>&1); then
|
||||
info "wn_c keys publish: ok"
|
||||
else
|
||||
if ! publish_out=$(wn_c keys publish 2>&1); then
|
||||
warn "wn_c keys publish failed: $publish_out"
|
||||
printf 'wn_c keys publish: %s\n' "$publish_out" >>"$LOG_FILE"
|
||||
fi
|
||||
printf 'wn_c keys publish: %s\n' "$publish_out" >>"$LOG_FILE"
|
||||
sleep 4
|
||||
local sanity_raw sanity_id
|
||||
local sanity_raw sanity_id sanity_cb="" sanity_bc=""
|
||||
sanity_raw=$(wn_c --json keys check "$B_NPUB" 2>>"$LOG_FILE" || true)
|
||||
sanity_id=$(printf '%s' "$sanity_raw" | jq -r '.result.event_id // .event_id // empty' 2>/dev/null || true)
|
||||
printf 'sanity keys check B raw: %s\n' "$sanity_raw" >>"$LOG_FILE"
|
||||
if [[ -n "$sanity_id" && "$sanity_id" != "null" ]]; then
|
||||
info "kind:30443 C->B ok (event_id: $sanity_id)"
|
||||
sanity_cb="$sanity_id"
|
||||
else
|
||||
warn "kind:30443 C->B failed — relays may be rejecting KeyPackages"
|
||||
printf 'sanity keys check B raw: %s\n' "$sanity_raw" >>"$LOG_FILE"
|
||||
fi
|
||||
sanity_raw=$(wn_b --json keys check "$C_NPUB" 2>>"$LOG_FILE" || true)
|
||||
sanity_id=$(printf '%s' "$sanity_raw" | jq -r '.result.event_id // .event_id // empty' 2>/dev/null || true)
|
||||
printf 'sanity keys check C raw: %s\n' "$sanity_raw" >>"$LOG_FILE"
|
||||
if [[ -n "$sanity_id" && "$sanity_id" != "null" ]]; then
|
||||
info "kind:30443 B->C ok (event_id: $sanity_id)"
|
||||
sanity_bc="$sanity_id"
|
||||
else
|
||||
warn "kind:30443 B->C failed — relays may be rejecting KeyPackages"
|
||||
printf 'sanity keys check C raw: %s\n' "$sanity_raw" >>"$LOG_FILE"
|
||||
fi
|
||||
if [[ -n "$sanity_cb" && -n "$sanity_bc" ]]; then
|
||||
info "kind:30443 B<->C ok (C->B=${sanity_cb:0:8}… B->C=${sanity_bc:0:8}…)"
|
||||
fi
|
||||
|
||||
step "sanity-check kinds 10050/1059/445: B creates group + invites C + exchanges a message"
|
||||
@@ -507,16 +512,15 @@ configure_relays() {
|
||||
if [[ -z "$sanity_gid" ]]; then
|
||||
warn "sanity group create failed — see $LOG_FILE (stale account state? rerun with 'rm -rf state/')"
|
||||
else
|
||||
info "sanity group id: $sanity_gid"
|
||||
printf 'sanity group id: %s\n' "$sanity_gid" >>"$LOG_FILE"
|
||||
if sanity_c_gid=$(wait_for_invite C 30 "$c_ignore"); then
|
||||
info "kind:10050+1059 ok — C received welcome (gid: $sanity_c_gid)"
|
||||
if [[ "$sanity_c_gid" != "$sanity_gid" ]]; then
|
||||
warn "gid mismatch — C saw $sanity_c_gid, B created $sanity_gid (likely a stale welcome slipped past the filter)"
|
||||
fi
|
||||
wn_c groups accept "$sanity_c_gid" >/dev/null 2>&1 || true
|
||||
wn_b messages send "$sanity_gid" "sanity-ping" >/dev/null 2>&1 || true
|
||||
if wait_for_message C "$sanity_c_gid" "sanity-ping" 30; then
|
||||
info "kind:445 ok — C decrypted sanity-ping"
|
||||
info "sanity kinds 10050/1059/445 ok (B->C welcome + message round-trip)"
|
||||
else
|
||||
warn "kind:445 failed — C never decrypted sanity-ping (relays may be dropping group messages)"
|
||||
warn "Consider rerunning with --local-relays."
|
||||
@@ -578,7 +582,6 @@ test_01_keypackage_discovery() {
|
||||
step "B fetches A's KeyPackage from relays"
|
||||
local kp_relays kp_raw kp_event_id
|
||||
kp_relays=$(wn_b --json relays list 2>/dev/null || wn_b relays list 2>/dev/null || true)
|
||||
info "B relay list: $kp_relays"
|
||||
printf 'B relay list: %s\n' "$kp_relays" >>"$LOG_FILE"
|
||||
|
||||
kp_raw=$(wn_b --json keys check "$A_NPUB" 2>>"$LOG_FILE" || true)
|
||||
@@ -590,7 +593,7 @@ test_01_keypackage_discovery() {
|
||||
record_result "01a KeyPackage A->B" pass
|
||||
else
|
||||
fail_msg "B cannot find A's KeyPackage. Did Amethyst publish to the same relays?"
|
||||
info "raw response from wn keys check: $kp_raw"
|
||||
printf 'raw response from wn keys check: %s\n' "$kp_raw" >>"$LOG_FILE"
|
||||
record_result "01a KeyPackage A->B" fail "wn keys check returned no event_id"
|
||||
fi
|
||||
|
||||
@@ -607,15 +610,9 @@ test_01_keypackage_discovery() {
|
||||
test_02_amethyst_creates_group() {
|
||||
banner "Test 02 — Amethyst creates group, invites B"
|
||||
|
||||
# Baseline dump BEFORE the human triggers the publish in Amethyst.
|
||||
# If this diagnostic shows B has no inbox relays (or the inbox relays
|
||||
# differ from the ones Amethyst has cached for B's kind:10050 list),
|
||||
# the welcome gift wrap will never reach B no matter how correctly
|
||||
# Amethyst sends it.
|
||||
dump_daemon_diagnostics B "pre-invite baseline"
|
||||
|
||||
# Snapshot B's already-pending invites so we can tell the new welcome
|
||||
# apart from a leftover from a previous run.
|
||||
# apart from a leftover from a previous run. Baseline daemon dump is
|
||||
# skipped on the happy path — dumped on timeout below instead.
|
||||
local b_ignore
|
||||
b_ignore=$(snapshot_invites B)
|
||||
[[ -n "$b_ignore" ]] && info "B already has stale invites, ignoring: $b_ignore"
|
||||
@@ -681,20 +678,13 @@ that's the bug."
|
||||
# Amethyst's subscription before we ask the operator to eyeball the UI.
|
||||
sleep 4
|
||||
|
||||
# Dump the B side up front — if B's own store doesn't contain the reply
|
||||
# or the MLS extension relays don't match what Amethyst subscribes to,
|
||||
# the operator can confirm "fail" with a specific reason instead of a
|
||||
# blind eyeball check.
|
||||
dump_outbound_diagnostics B "$gid" "hello from wn" "test_02 B->A reply"
|
||||
|
||||
if confirm "Does Amethyst now show 'hello from wn' in the same group?"; then
|
||||
record_result "02 Amethyst->B create+invite" pass
|
||||
else
|
||||
# The B-side dump above told us whether the send reached B's own DB and
|
||||
# which relays wn tagged on the kind:445. Now pull the Amethyst side so
|
||||
# the failure report has both halves of the pipe: which relays the
|
||||
# kind:445 subscription actually targets, whether the event arrived,
|
||||
# and (if it did) whether GroupEventHandler dropped it.
|
||||
# Dump the B side so the failure report shows whether the send reached
|
||||
# B's own DB and which relays wn tagged on the kind:445, then ask for
|
||||
# the Amethyst side so the report has both halves of the pipe.
|
||||
dump_outbound_diagnostics B "$gid" "hello from wn" "test_02 B->A reply"
|
||||
prompt_human "Capture Amethyst's side of the B->A kind:445 path. On the adb host:
|
||||
|
||||
adb logcat -d -v time | grep -E \
|
||||
@@ -770,8 +760,8 @@ test_04_three_member_group() {
|
||||
fi
|
||||
info "using group $gid"
|
||||
|
||||
dump_daemon_diagnostics C "pre-invite baseline (test_04)"
|
||||
|
||||
# Baseline C-side daemon dump is skipped on the happy path; the
|
||||
# invite-timeout branch below still dumps on failure.
|
||||
local c_ignore
|
||||
c_ignore=$(snapshot_invites C)
|
||||
[[ -n "$c_ignore" ]] && info "C already has stale invites, ignoring: $c_ignore"
|
||||
@@ -1204,7 +1194,30 @@ test_12_offline_catchup() {
|
||||
}
|
||||
|
||||
test_13_keypackage_rotation() {
|
||||
banner "Test 13 — KeyPackage rotation"
|
||||
banner "Test 13 — KeyPackage rotation (MIP-00 consumption-driven)"
|
||||
|
||||
# Per MIP-00, a KeyPackage is rotated when it's *consumed* by an incoming
|
||||
# Welcome — the init_key is effectively spent and the client must
|
||||
# publish a fresh KeyPackage to the same d-tag slot.
|
||||
#
|
||||
# Earlier revisions of this test asked the human to restart Amethyst or
|
||||
# toggle KP relays, on the assumption that either would republish a
|
||||
# fresh KP. Neither actually does in current Amethyst:
|
||||
# - Restart: `Account.ensureMarmotKeyPackagePublished` early-returns
|
||||
# whenever a bundle already exists on disk — no rotation.
|
||||
# - Toggle KP relays: `Account.saveKeyPackageRelayList` re-publishes
|
||||
# the existing kind:30443 to the new relay set, same event_id.
|
||||
#
|
||||
# So drive the real MIP-00 flow instead: have B create a one-off group
|
||||
# with A as invitee. The Welcome gift-wrap delivered to A consumes A's
|
||||
# KeyPackage, `DecryptAndIndexProcessor` sees `needsKeyPackageRotation`
|
||||
# on the ingest result, and calls `publishMarmotKeyPackages` which
|
||||
# rotates the consumed slot and publishes a new kind:30443 to the same
|
||||
# d-tag. B's `keys check` then returns a different event_id.
|
||||
#
|
||||
# Rotation fires on Welcome *receive* (decrypt), not on human accept, so
|
||||
# the operator's accept is nice-to-have for group hygiene but not on the
|
||||
# critical path for this test.
|
||||
|
||||
step "B records A's current KP event id"
|
||||
local before
|
||||
@@ -1214,12 +1227,24 @@ test_13_keypackage_rotation() {
|
||||
fail_msg "no existing KP for A"; record_result "13 keypackage rotation" fail "no KP found"; return
|
||||
fi
|
||||
|
||||
prompt_human "In Amethyst, trigger a KeyPackage rotation:
|
||||
Option 1: Settings -> Key Package Relays -> toggle OFF all KP relays, then toggle ON.
|
||||
Option 2: Restart the Amethyst app (KeyPackageRotationManager runs at startup).
|
||||
Press <Enter> when Amethyst has published a new KP."
|
||||
step "B creates group 'Interop-13-rotation' with A as sole invitee (consumes A's KP)"
|
||||
local out gid
|
||||
out=$(wn_b --json groups create "Interop-13-rotation" "$A_NPUB" 2>>"$LOG_FILE")
|
||||
printf 'wn groups create (test_13) raw output: %s\n' "$out" >>"$LOG_FILE"
|
||||
gid=$(printf '%s' "$out" | jq_group_id)
|
||||
if [[ -z "$gid" ]]; then
|
||||
fail_msg "could not create Interop-13-rotation"
|
||||
record_result "13 keypackage rotation" fail "create failed"
|
||||
return
|
||||
fi
|
||||
save_state GROUP_13 "$gid"
|
||||
info "group_id: $gid"
|
||||
|
||||
step "waiting for a new KP event id at B (60s)"
|
||||
prompt_human "In Amethyst, you should see a new invite 'Interop-13-rotation' from $B_NPUB.
|
||||
Accepting is NOT required for rotation (processing the Welcome is enough),
|
||||
but please accept it to keep group state tidy. Press <Enter> when done."
|
||||
|
||||
step "waiting for A's rotated KP event_id at B (60s)"
|
||||
local deadline=$(( $(date +%s) + 60 )) after=""
|
||||
while [[ $(date +%s) -lt $deadline ]]; do
|
||||
after=$(wn_b --json keys check "$A_NPUB" 2>/dev/null | jq -r '.result.event_id // .event_id // empty')
|
||||
@@ -1227,10 +1252,11 @@ test_13_keypackage_rotation() {
|
||||
sleep 3
|
||||
done
|
||||
if [[ -n "$after" && "$after" != "$before" ]]; then
|
||||
pass_msg "A's KP rotated: $before -> $after"
|
||||
pass_msg "A's KP rotated after Welcome consumption: $before -> $after"
|
||||
record_result "13 keypackage rotation" pass
|
||||
else
|
||||
record_result "13 keypackage rotation" fail "no new KP event_id observed"
|
||||
fail_msg "A's KP event_id unchanged ($before) 60s after Welcome — MIP-00 rotation did not fire"
|
||||
record_result "13 keypackage rotation" fail "no new KP event_id after invite"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1288,17 +1314,13 @@ main() {
|
||||
prompt_for_a_npub
|
||||
configure_relays
|
||||
|
||||
# Baseline dump after relays are configured but before any tests run.
|
||||
# This is the single most useful log to forward when Test 02 fails —
|
||||
# it shows whether B's kind:10050 (inbox) relay list actually landed
|
||||
# on the relays Amethyst will look at for the giftwrap delivery target.
|
||||
banner "Post-configure baseline diagnostics"
|
||||
dump_daemon_diagnostics B "post-configure"
|
||||
dump_daemon_diagnostics C "post-configure"
|
||||
# Baseline daemon dumps are no longer run unconditionally — they produce
|
||||
# 100+ lines per daemon and the happy path doesn't need them. Each test
|
||||
# that polls for an invite still calls `dump_daemon_diagnostics` on
|
||||
# timeout, which is the failure mode those dumps are meant to diagnose.
|
||||
|
||||
# Let wn discover A's advertised relays via its normal subscription
|
||||
# plane, then dump what wn actually sees. This is the "Am I going to
|
||||
# be able to reach this user?" probe — surfaces up front the kind of
|
||||
# plane, then summarise what wn sees. Surfaces up front the kind of
|
||||
# failure (A's 10050 unreachable from wn, missing KP list, etc.) that
|
||||
# would otherwise bite as a silent Test 03 timeout.
|
||||
if [[ "$USE_LOCAL_RELAYS" -ne 1 ]]; then
|
||||
|
||||
Reference in New Issue
Block a user