Compare commits

..

1 Commits

Author SHA1 Message Date
Lei Nelissen
da9653cfe8 feat: base setup for carplay 2025-05-24 17:41:28 +02:00
59 changed files with 326 additions and 427 deletions

View File

@@ -25,27 +25,26 @@ GEM
json (>= 1.5.1) json (>= 1.5.1)
artifactory (3.0.17) artifactory (3.0.17)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.4.0) aws-eventstream (1.3.2)
aws-partitions (1.1141.0) aws-partitions (1.1097.0)
aws-sdk-core (3.229.0) aws-sdk-core (3.223.0)
aws-eventstream (~> 1, >= 1.3.0) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0) aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9) aws-sigv4 (~> 1.9)
base64 base64
bigdecimal
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
logger logger
aws-sdk-kms (1.110.0) aws-sdk-kms (1.100.0)
aws-sdk-core (~> 3, >= 3.228.0) aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5) aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.196.0) aws-sdk-s3 (1.185.0)
aws-sdk-core (~> 3, >= 3.228.0) aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5) aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1) aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4) babosa (1.0.4)
base64 (0.3.0) base64 (0.2.0)
benchmark (0.4.0) benchmark (0.4.0)
bigdecimal (3.1.9) bigdecimal (3.1.9)
claide (1.1.0) claide (1.1.0)
@@ -119,10 +118,10 @@ GEM
faraday (>= 0.8.0) faraday (>= 0.8.0)
http-cookie (~> 1.0.0) http-cookie (~> 1.0.0)
faraday-em_http (1.0.0) faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.1) faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0) faraday-excon (1.1.0)
faraday-httpclient (1.0.1) faraday-httpclient (1.0.1)
faraday-multipart (1.1.1) faraday-multipart (1.1.0)
multipart-post (~> 2.0) multipart-post (~> 2.0)
faraday-net_http (1.0.2) faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0) faraday-net_http_persistent (1.2.0)
@@ -132,7 +131,7 @@ GEM
faraday_middleware (1.2.1) faraday_middleware (1.2.1)
faraday (~> 1.0) faraday (~> 1.0)
fastimage (2.4.0) fastimage (2.4.0)
fastlane (2.228.0) fastlane (2.227.2)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0) addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0) artifactory (~> 3.0)
@@ -228,27 +227,27 @@ GEM
i18n (1.14.7) i18n (1.14.7)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
jmespath (1.6.2) jmespath (1.6.2)
json (2.13.2) json (2.11.3)
jwt (2.10.2) jwt (2.10.1)
base64 base64
logger (1.7.0) logger (1.7.0)
mini_magick (4.13.2) mini_magick (4.13.2)
mini_mime (1.1.5) mini_mime (1.1.5)
minitest (5.25.5) minitest (5.25.5)
molinillo (0.8.0) molinillo (0.8.0)
multi_json (1.17.0) multi_json (1.15.0)
multipart-post (2.4.1) multipart-post (2.4.1)
mutex_m (0.3.0) mutex_m (0.3.0)
nanaimo (0.3.0) nanaimo (0.3.0)
nap (1.1.0) nap (1.1.0)
naturally (2.3.0) naturally (2.2.1)
netrc (0.11.0) netrc (0.11.0)
nkf (0.2.0) nkf (0.2.0)
optparse (0.6.0) optparse (0.6.0)
os (1.1.4) os (1.1.4)
plist (3.7.2) plist (3.7.2)
public_suffix (4.0.7) public_suffix (4.0.7)
rake (13.3.0) rake (13.2.1)
representable (3.2.0) representable (3.2.0)
declarative (< 0.1.0) declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0) trailblazer-option (>= 0.1.1, < 0.2.0)

View File

@@ -87,8 +87,8 @@ android {
applicationId "nl.moeilijkedingen.jellyfinaudioplayer" applicationId "nl.moeilijkedingen.jellyfinaudioplayer"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 40 versionCode 38
versionName "2.4.6" versionName "2.4.5"
} }
signingConfigs { signingConfigs {

View File

@@ -1,7 +0,0 @@
Ens alegra oferir-te algunes millores útils en aquesta actualització!
El rendiment per a grans col·leccions d'àlbums ha estat significativament millorat, fent que la navegació per la teva biblioteca musical sigui més fluida i responsiva.
També hem solucionat un problema que feia que la part superior de l'aplicació es tallés en Android 15 i versions més recents. L'aplicació ara hauria de mostrar-se correctament en els dispositius Android més recents.
Gràcies per usar Fintunes!

View File

@@ -1,7 +0,0 @@
Jsme rádi, že vám můžeme přinést několik užitečných vylepšení v této aktualizaci!
Výkon pro velké kolekce alb byl výrazně vylepšen, což činí procházení vaší hudební knihovny plynulejším a více responzivním.
Také jsme opravili problém, který způsoboval, že horní část aplikace byla ořezána na Androidu 15 a novějších verzích. Aplikace by se nyní měla správně zobrazovat na nejnovějších Android zařízeních.
Děkujeme za používání Fintunes!

View File

@@ -1,7 +0,0 @@
Nützliche Verbesserungen in diesem Update!
Die Leistung für große Albumsammlungen wurde erheblich verbessert, wodurch das Durchsuchen Ihrer Musikbibliothek reibungsloser wird.
Wir haben auch ein Problem behoben, das dazu führte, dass der obere Teil der App auf Android 15+ abgeschnitten wurde.
Vielen Dank, dass Sie Fintunes verwenden!

View File

@@ -1,7 +0,0 @@
We're pleased to bring you some useful improvements in this update!
Performance for large album collections has been significantly enhanced, making browsing through your music library smoother and more responsive.
We've also fixed an issue that was causing the top part of the app to be cut off on Android 15 and newer versions. The app should now display properly on the latest Android devices.
Thanks for using Fintunes!

View File

@@ -1,7 +0,0 @@
¡Mejoras útiles en esta actualización!
El rendimiento para grandes colecciones de álbumes ha sido significativamente mejorado, haciendo que la navegación por tu biblioteca musical sea más fluida.
También hemos solucionado un problema que causaba que la parte superior de la aplicación se cortara en Android 15+.
¡Gracias por usar Fintunes!

View File

@@ -1,7 +0,0 @@
Améliorations utiles dans cette mise à jour !
Les performances pour les grandes collections d'albums ont été considérablement améliorées, rendant la navigation plus fluide.
Nous avons également corrigé un problème qui causait la coupure de la partie supérieure de l'application sur Android 15+.
Merci d'utiliser Fintunes !

View File

@@ -1,7 +0,0 @@
Siamo lieti di offrirti alcuni miglioramenti utili in questo aggiornamento!
Le prestazioni per grandi collezioni di album sono state significativamente migliorate, rendendo la navigazione nella tua libreria musicale più fluida e reattiva.
Abbiamo anche risolto un problema che causava il taglio della parte superiore dell'app su Android 15 e versioni più recenti. L'app ora dovrebbe visualizzarsi correttamente sui dispositivi Android più recenti.
Grazie per aver usato Fintunes!

View File

@@ -1,7 +0,0 @@
有用な改善をお届けします!
大規模なアルバムコレクションのパフォーマンスが大幅に向上し、音楽ライブラリの閲覧がよりスムーズになりました。
また、Android 15+でアプリの上部が切れる問題を修正しました。
Fintunesをご利用いただき、ありがとうございます

View File

@@ -1,7 +0,0 @@
We zijn blij je enkele nuttige verbeteringen te kunnen brengen in deze update!
De prestaties voor grote albumcollecties zijn aanzienlijk verbeterd, waardoor het browsen door je muziekbibliotheek soepeler en responsiever wordt.
We hebben ook een probleem opgelost dat ervoor zorgde dat het bovenste deel van de app werd afgesneden op Android 15 en nieuwere versies. De app zou nu correct moeten worden weergegeven op de nieuwste Android-apparaten.
Bedankt voor het gebruik van Fintunes!

View File

@@ -1,7 +0,0 @@
Vi er glade for å bringe deg noen nyttige forbedringer i denne oppdateringen!
Ytelsen for store albumsamlinger har blitt betydelig forbedret, noe som gjør surfing gjennom musikk-biblioteket ditt jevnere og mer responsivt.
Vi har også fikset et problem som forårsaket at den øverste delen av appen ble kuttet av på Android 15 og nyere versjoner. Appen bør nå vises riktig på de nyeste Android-enhetene.
Takk for at du bruker Fintunes!

View File

@@ -1,7 +0,0 @@
Przydatne ulepszenia w tej aktualizacji!
Wydajność dla dużych kolekcji albumów została znacznie poprawiona, dzięki czemu przeglądanie biblioteki muzycznej jest płynniejsze.
Naprawiliśmy również problem, który powodował obcinanie górnej części aplikacji na Androidzie 15+.
Dziękujemy za korzystanie z Fintunes!

View File

@@ -1,7 +0,0 @@
Estamos satisfeitos em trazer algumas melhorias úteis nesta atualização!
O desempenho para grandes coleções de álbuns foi significativamente aprimorado, tornando a navegação pela sua biblioteca musical mais suave e responsiva.
Também corrigimos um problema que estava causando o corte da parte superior do aplicativo no Android 15 e versões mais recentes. O aplicativo agora deve ser exibido corretamente nos dispositivos Android mais recentes.
Obrigado por usar o Fintunes!

View File

@@ -1,7 +0,0 @@
Полезные улучшения в обновлении!
Производительность для больших коллекций альбомов значительно улучшена, что делает просмотр музыкальной библиотеки более плавным.
Исправили проблему обрезания верхней части приложения на Android 15+.
Спасибо за использование Fintunes!

View File

@@ -1,7 +0,0 @@
Vi är glada att kunna erbjuda dig några användbara förbättringar i denna uppdatering!
Prestandan för stora albumsamlingar har förbättrats betydligt, vilket gör surfandet genom ditt musikbibliotek smidigare och mer responsivt.
Vi har också åtgärdat ett problem som orsakade att den övre delen av appen blev avskuren på Android 15 och nyare versioner. Appen bör nu visas korrekt på de senaste Android-enheterna.
Tack för att du använder Fintunes!

View File

@@ -1,7 +0,0 @@
Корисні покращення в цьому оновленні!
Продуктивність для великих колекцій альбомів була значно покращена, роблячи перегляд музичної бібліотеки плавнішим.
Ми також виправили проблему обрізання верхньої частини додатку на Android 15+.
Дякуємо за використання Fintunes!

View File

@@ -1,7 +0,0 @@
我们很高兴为您带来此次更新中的一些实用改进!
大型专辑集合的性能得到了显著提升,使您浏览音乐库更加流畅和响应迅速。
我们还修复了一个在Android 15及更新版本上导致应用程序顶部被截断的问题。应用程序现在应该在最新的Android设备上正确显示。
感谢您使用Fintunes

View File

@@ -1,7 +0,0 @@
我們很高興為您帶來此次更新中的一些實用改進!
大型專輯集合的性能得到了顯著提升,使您瀏覽音樂庫更加流暢和響應迅速。
我們還修復了一個在Android 15及更新版本上導致應用程序頂部被截斷的問題。應用程序現在應該在最新的Android設備上正確顯示。
感謝您使用Fintunes

View File

@@ -1,7 +1 @@
Ens alegra oferir-te algunes millores útils en aquesta actualització! Aquesta versió soluciona un problema on Fintunes només podia reproduir el primer disc en un àlbum de múltiples discs. A més, gràcies als nostres increïbles col·laboradors lingüístics, Fintunes ara està disponible en tàmil. A més, s'han actualitzat 12 idiomes. Gaudeix d'aquesta nova versió de Fintunes i considera unir-te al nostre servidor Discord!
El rendiment per a grans col·leccions d'àlbums ha estat significativament millorat, fent que la navegació per la teva biblioteca musical sigui més fluida i responsiva.
També hem solucionat un problema que feia que la part superior de l'aplicació es tallés en Android 15 i versions més recents. L'aplicació ara hauria de mostrar-se correctament en els dispositius Android més recents.
Gràcies per usar Fintunes!

View File

@@ -1,7 +1 @@
Jsme rádi, že vám můžeme přinést několik užitečných vylepšení v této aktualizaci! Tato verze opravuje problém, kdy Fintunes mohl přehrávat pouze první disk v albu s více disky. Navíc díky našim úžasným jazykovým přispěvatelům je Fintunes nyní k dispozici v tamilštině. Dále bylo aktualizováno 12 jazyků. Užijte si tuto novou verzi Fintunes a připojte se k našemu Discord serveru!
Výkon pro velké kolekce alb byl výrazně vylepšen, což činí procházení vaší hudební knihovny plynulejším a více responzivním.
Také jsme opravili problém, který způsoboval, že horní část aplikace byla ořezána na Androidu 15 a novějších verzích. Aplikace by se nyní měla správně zobrazovat na nejnovějších Android zařízeních.
Děkujeme za používání Fintunes!

View File

@@ -1,7 +1 @@
Wir freuen uns, Ihnen einige nützliche Verbesserungen in diesem Update zu bieten! Diese Version behebt ein Problem, bei dem Fintunes nur die erste CD eines Mehrfach-CD-Albums abspielen konnte. Außerdem ist Fintunes dank unserer großartigen Sprachmitwirkenden jetzt auch auf Tamilisch verfügbar. Zusätzlich wurden 12 Sprachen aktualisiert. Genießen Sie diese neue Version von Fintunes und treten Sie gerne unserem Discord-Server bei!
Die Leistung für große Albumsammlungen wurde erheblich verbessert, wodurch das Durchsuchen Ihrer Musikbibliothek reibungsloser und reaktionsschneller wird.
Wir haben auch ein Problem behoben, das dazu führte, dass der obere Teil der App auf Android 15 und neueren Versionen abgeschnitten wurde. Die App sollte nun ordnungsgemäß auf den neuesten Android-Geräten angezeigt werden.
Vielen Dank, dass Sie Fintunes verwenden!

View File

@@ -1,7 +1 @@
We're pleased to bring you some useful improvements in this update! This version fixes an issue where Fintunes was only able to play back the first disc in a multi-disc album. Also, thanks to our amazing language contributors, Fintunes is now available in Tamil. Additionally, there's 12 languages that have been updated. Enjoy this new version of Fintunes and consider joining our Discord server!
Performance for large album collections has been significantly enhanced, making browsing through your music library smoother and more responsive.
We've also fixed an issue that was causing the top part of the app to be cut off on Android 15 and newer versions. The app should now display properly on the latest Android devices.
Thanks for using Fintunes!

View File

@@ -1,7 +1 @@
¡Nos complace ofrecerte algunas mejoras útiles en esta actualización! Esta versión soluciona un problema donde Fintunes solo podía reproducir el primer disco en un álbum de múltiples discos. Además, gracias a nuestros increíbles colaboradores de idiomas, Fintunes ahora está disponible en tamil. También se han actualizado 12 idiomas. ¡Disfruta de esta nueva versión de Fintunes y considera unirte a nuestro servidor de Discord!
El rendimiento para grandes colecciones de álbumes ha sido significativamente mejorado, haciendo que la navegación por tu biblioteca musical sea más fluida y responsiva.
También hemos solucionado un problema que causaba que la parte superior de la aplicación se cortara en Android 15 y versiones más recientes. La aplicación ahora debería mostrarse correctamente en los dispositivos Android más recientes.
¡Gracias por usar Fintunes!

View File

@@ -1,7 +1 @@
Nous sommes heureux de vous apporter quelques améliorations utiles dans cette mise à jour ! Cette version corrige un problème où Fintunes ne pouvait lire que le premier disque d'un album multi-disques. De plus, grâce à nos incroyables contributeurs linguistiques, Fintunes est maintenant disponible en tamoul. En outre, 12 langues ont été mises à jour. Profitez de cette nouvelle version de Fintunes et rejoignez notre serveur Discord !
Les performances pour les grandes collections d'albums ont été considérablement améliorées, rendant la navigation dans votre bibliothèque musicale plus fluide et plus réactive.
Nous avons également corrigé un problème qui causait la coupure de la partie supérieure de l'application sur Android 15 et les versions plus récentes. L'application devrait maintenant s'afficher correctement sur les derniers appareils Android.
Merci d'utiliser Fintunes !

View File

@@ -1,7 +1 @@
Siamo lieti di offrirti alcuni miglioramenti utili in questo aggiornamento! Questa versione risolve un problema in cui Fintunes poteva riprodurre solo il primo disco in un album multi-disco. Inoltre, grazie ai nostri fantastici collaboratori linguistici, Fintunes è ora disponibile in tamil. Inoltre, sono state aggiornate 12 lingue. Goditi questa nuova versione di Fintunes e unisciti al nostro server Discord!
Le prestazioni per grandi collezioni di album sono state significativamente migliorate, rendendo la navigazione nella tua libreria musicale più fluida e reattiva.
Abbiamo anche risolto un problema che causava il taglio della parte superiore dell'app su Android 15 e versioni più recenti. L'app ora dovrebbe visualizzarsi correttamente sui dispositivi Android più recenti.
Grazie per aver usato Fintunes!

View File

@@ -1,7 +1 @@
このアップデートで、いくつかの有用な改善をお届けできることを嬉しく思います! このバージョンでは、マルチディスクアルバムの最初のディスクしか再生できなかった問題を修正しました。また、素晴らしい言語コントリビューターのおかげで、Fintunesはタミル語でも利用可能になりました。さらに、12の言語が更新されました。Fintunesの新バージョンをお楽しみください。Discordサーバーへの参加もお待ちしています!
大規模なアルバムコレクションのパフォーマンスが大幅に向上し、音楽ライブラリの閲覧がよりスムーズで反応性の良いものになりました。
また、Android 15以降のバージョンでアプリの上部が切れてしまう問題も修正しました。最新のAndroidデバイスでアプリが正しく表示されるようになりました。
Fintunesをご利用いただき、ありがとうございます

View File

@@ -1,7 +1 @@
We zijn blij je enkele nuttige verbeteringen te kunnen brengen in deze update! Deze versie lost een probleem op waarbij Fintunes alleen de eerste schijf van een album met meerdere schijven kon afspelen. Bovendien is Fintunes dankzij onze geweldige taalbijdragers nu beschikbaar in het Tamil. Daarnaast zijn er 12 talen bijgewerkt. Geniet van deze nieuwe versie van Fintunes en overweeg om lid te worden van onze Discord-server!
De prestaties voor grote albumcollecties zijn aanzienlijk verbeterd, waardoor het browsen door je muziekbibliotheek soepeler en responsiever wordt.
We hebben ook een probleem opgelost dat ervoor zorgde dat het bovenste deel van de app werd afgesneden op Android 15 en nieuwere versies. De app zou nu correct moeten worden weergegeven op de nieuwste Android-apparaten.
Bedankt voor het gebruik van Fintunes!

View File

@@ -1,7 +1 @@
Vi er glade for å bringe deg noen nyttige forbedringer i denne oppdateringen! Denne versjonen løser et problem hvor Fintunes bare kunne spille av den første disken i et flerdisk-album. I tillegg, takket være våre fantastiske språkbidragsytere, er Fintunes nå tilgjengelig på tamil. Dessuten er 12 språk oppdatert. Nyt denne nye versjonen av Fintunes og vurder å bli med på vår Discord-server!
Ytelsen for store albumsamlinger har blitt betydelig forbedret, noe som gjør surfing gjennom musikk-biblioteket ditt jevnere og mer responsivt.
Vi har også fikset et problem som forårsaket at den øverste delen av appen ble kuttet av på Android 15 og nyere versjoner. Appen bør nå vises riktig på de nyeste Android-enhetene.
Takk for at du bruker Fintunes!

View File

@@ -1,7 +1 @@
Cieszymy się, że możemy dostarczyć Ci kilka przydatnych ulepszeń w tej aktualizacji! Ta wersja naprawia problem, w którym Fintunes mógł odtwarzać tylko pierwszy dysk w albumie wielopłytowym. Ponadto, dzięki naszym wspaniałym współtwórcom językowym, Fintunes jest teraz dostępny w języku tamilskim. Dodatkowo zaktualizowano 12 języków. Ciesz się tą nową wersją Fintunes i dołącz do naszego serwera Discord!
Wydajność dla dużych kolekcji albumów została znacznie poprawiona, dzięki czemu przeglądanie biblioteki muzycznej jest płynniejsze i bardziej responsywne.
Naprawiliśmy również problem, który powodował obcinanie górnej części aplikacji na Androidzie 15 i nowszych wersjach. Aplikacja powinna teraz wyświetlać się prawidłowo na najnowszych urządzeniach z Androidem.
Dziękujemy za korzystanie z Fintunes!

View File

@@ -1,7 +1 @@
Estamos satisfeitos em trazer algumas melhorias úteis nesta atualização! Esta versão corrige um problema em que o Fintunes só conseguia reproduzir o primeiro disco em um álbum com múltiplos discos. Além disso, graças aos nossos incríveis colaboradores de idiomas, o Fintunes agora está disponível em tâmil. Adicionalmente, 12 idiomas foram atualizados. Aproveite esta nova versão do Fintunes e considere entrar em nosso servidor Discord!
O desempenho para grandes coleções de álbuns foi significativamente aprimorado, tornando a navegação pela sua biblioteca musical mais suave e responsiva.
Também corrigimos um problema que estava causando o corte da parte superior do aplicativo no Android 15 e versões mais recentes. O aplicativo agora deve ser exibido corretamente nos dispositivos Android mais recentes.
Obrigado por usar o Fintunes!

View File

@@ -1,7 +1 @@
Мы рады предоставить вам несколько полезных улучшений в этом обновлении! Эта версия исправляет проблему, при которой Fintunes мог воспроизводить только первый диск в альбоме с несколькими дисками. Кроме того, благодаря нашим замечательным языковым контрибьюторам, Fintunes теперь доступен на тамильском языке. Также обновлены 12 языков. Наслаждайтесь новой версией Fintunes и присоединяйтесь к нашему серверу Discord!
Производительность для больших коллекций альбомов была значительно улучшена, что делает просмотр вашей музыкальной библиотеки более плавным и отзывчивым.
Мы также исправили проблему, которая приводила к обрезанию верхней части приложения на Android 15 и более новых версиях. Приложение теперь должно корректно отображаться на новейших Android-устройствах.
Спасибо за использование Fintunes!

View File

@@ -1,7 +1 @@
Vi är glada att kunna erbjuda dig några användbara förbättringar i denna uppdatering! Denna version åtgärdar ett problem där Fintunes bara kunde spela upp den första skivan i ett flerskivsalbum. Dessutom, tack vare våra fantastiska språkbidragsgivare, är Fintunes nu tillgängligt på tamil. Dessutom har 12 språk uppdaterats. Njut av denna nya version av Fintunes och överväg att gå med i vår Discord-server!
Prestandan för stora albumsamlingar har förbättrats betydligt, vilket gör surfandet genom ditt musikbibliotek smidigare och mer responsivt.
Vi har också åtgärdat ett problem som orsakade att den övre delen av appen blev avskuren på Android 15 och nyare versioner. Appen bör nu visas korrekt på de senaste Android-enheterna.
Tack för att du använder Fintunes!

View File

@@ -1,7 +1 @@
Ми раді принести вам кілька корисних покращень у цьому оновленні! Ця версія виправляє проблему, коли Fintunes міг відтворювати лише перший диск у багатодисковому альбомі. Крім того, завдяки нашим чудовим мовним учасникам, Fintunes тепер доступний тамільською мовою. Також оновлено 12 мов. Насолоджуйтесь цією новою версією Fintunes та приєднуйтесь до нашого сервера Discord!
Продуктивність для великих колекцій альбомів була значно покращена, роблячи перегляд вашої музичної бібліотеки плавнішим та більш відгукливим.
Ми також виправили проблему, яка спричиняла обрізання верхньої частини додатку на Android 15 і новіших версіях. Додаток тепер повинен правильно відображатися на найновіших Android-пристроях.
Дякуємо за використання Fintunes!

View File

@@ -1,7 +1 @@
我们很高兴为您带来此次更新中的一些实用改进! 此版本修复了Fintunes只能播放多碟专辑中第一张碟片的问题。此外感谢我们出色的语言贡献者Fintunes现在支援泰米尔语。另外还有12种语言已更新。享受这个新版本的Fintunes并考虑加入我们的Discord伺服器
大型专辑集合的性能得到了显著提升,使您浏览音乐库更加流畅和响应迅速。
我们还修复了一个在Android 15及更新版本上导致应用程序顶部被截断的问题。应用程序现在应该在最新的Android设备上正确显示。
感谢您使用Fintunes

View File

@@ -1,7 +1 @@
我們很高興為您帶來此次更新中的一些實用改進! 此版本修復了Fintunes只能播放多碟專輯中第一張碟片的問題。此外感謝我們出色的語言貢獻者Fintunes現在支援泰米爾語。另外還有12種語言已更新。享受這個新版本的Fintunes並考慮加入我們的Discord伺服器
大型專輯集合的性能得到了顯著提升,使您瀏覽音樂庫更加流暢和響應迅速。
我們還修復了一個在Android 15及更新版本上導致應用程序頂部被截斷的問題。應用程序現在應該在最新的Android設備上正確顯示。
感謝您使用Fintunes

View File

@@ -1,48 +0,0 @@
import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "Fintunes",
in: window,
launchOptions: launchOptions
)
return true
}
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}

View File

@@ -13,7 +13,9 @@
4C04FC6E055249ABB204D3BC /* Inter-VariableFont_slnt,wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4B4A0465FF364579B28CF5D7 /* Inter-VariableFont_slnt,wght.ttf */; }; 4C04FC6E055249ABB204D3BC /* Inter-VariableFont_slnt,wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4B4A0465FF364579B28CF5D7 /* Inter-VariableFont_slnt,wght.ttf */; };
AB393FCA2857CC8400773469 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB393FC92857CC8400773469 /* SnapshotHelper.swift */; }; AB393FCA2857CC8400773469 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB393FC92857CC8400773469 /* SnapshotHelper.swift */; };
AB4A8DFE2857C8DA005A1ED0 /* FintunesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */; }; AB4A8DFE2857C8DA005A1ED0 /* FintunesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */; };
AB7AA5F92DC8E5D600578CAC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB7AA5F82DC8E5D600578CAC /* AppDelegate.swift */; }; ABB40BB92DE211A6002112FC /* PhoneSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABB40BB82DE211A6002112FC /* PhoneSceneDelegate.swift */; };
ABB40BBA2DE211A6002112FC /* CarSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABB40BB72DE211A6002112FC /* CarSceneDelegate.swift */; };
ABB40BBC2DE2137E002112FC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABB40BBB2DE2137E002112FC /* AppDelegate.swift */; };
FA01635F2599C28FC19F2EC3 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3896494129CBC30258D9BB1C /* PrivacyInfo.xcprivacy */; }; FA01635F2599C28FC19F2EC3 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3896494129CBC30258D9BB1C /* PrivacyInfo.xcprivacy */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -40,7 +42,10 @@
AB393FC92857CC8400773469 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; }; AB393FC92857CC8400773469 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; };
AB4A8DFB2857C8DA005A1ED0 /* FintunesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FintunesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; AB4A8DFB2857C8DA005A1ED0 /* FintunesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FintunesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FintunesUITests.swift; sourceTree = "<group>"; }; AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FintunesUITests.swift; sourceTree = "<group>"; };
AB7AA5F82DC8E5D600578CAC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; ABB40BB42DE20F50002112FC /* Fintunes-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Fintunes-Bridging-Header.h"; path = "Fintunes/Fintunes-Bridging-Header.h"; sourceTree = "<group>"; };
ABB40BB72DE211A6002112FC /* CarSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CarSceneDelegate.swift; path = Fintunes/CarSceneDelegate.swift; sourceTree = "<group>"; };
ABB40BB82DE211A6002112FC /* PhoneSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PhoneSceneDelegate.swift; path = Fintunes/PhoneSceneDelegate.swift; sourceTree = "<group>"; };
ABB40BBB2DE2137E002112FC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Fintunes/AppDelegate.swift; sourceTree = "<group>"; };
E22EC545298DA9F9017776C0 /* libPods-Fintunes.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E22EC545298DA9F9017776C0 /* libPods-Fintunes.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes.a"; sourceTree = BUILT_PRODUCTS_DIR; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
@@ -68,7 +73,10 @@
13B07FAE1A68108700A75B9A /* Fintunes */ = { 13B07FAE1A68108700A75B9A /* Fintunes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
AB7AA5F82DC8E5D600578CAC /* AppDelegate.swift */, ABB40BBB2DE2137E002112FC /* AppDelegate.swift */,
ABB40BB72DE211A6002112FC /* CarSceneDelegate.swift */,
ABB40BB82DE211A6002112FC /* PhoneSceneDelegate.swift */,
ABB40BB42DE20F50002112FC /* Fintunes-Bridging-Header.h */,
13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
@@ -348,7 +356,9 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
AB7AA5F92DC8E5D600578CAC /* AppDelegate.swift in Sources */, ABB40BBC2DE2137E002112FC /* AppDelegate.swift in Sources */,
ABB40BB92DE211A6002112FC /* PhoneSceneDelegate.swift in Sources */,
ABB40BBA2DE211A6002112FC /* CarSceneDelegate.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -391,11 +401,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 124; CURRENT_PROJECT_VERSION = 118;
DEVELOPMENT_TEAM = HD2D35G9Y4; DEVELOPMENT_TEAM = HD2D35G9Y4;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = HD2D35G9Y4;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
@@ -416,7 +424,7 @@
PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.jellyfinaudioplayer; PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.jellyfinaudioplayer;
PRODUCT_NAME = Fintunes; PRODUCT_NAME = Fintunes;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "nl.moeilijkedingen.jellyfinaudioplayer AppStore 1754345870"; SWIFT_OBJC_BRIDGING_HEADER = "Fintunes/Fintunes-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@@ -432,7 +440,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 124; CURRENT_PROJECT_VERSION = 118;
DEVELOPMENT_TEAM = HD2D35G9Y4; DEVELOPMENT_TEAM = HD2D35G9Y4;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = HD2D35G9Y4; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = HD2D35G9Y4;
INFOPLIST_FILE = Fintunes/Info.plist; INFOPLIST_FILE = Fintunes/Info.plist;
@@ -451,7 +459,8 @@
PRODUCT_NAME = Fintunes; PRODUCT_NAME = Fintunes;
PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb"; PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "nl.moeilijkedingen.jellyfinaudioplayer AppStore 1754345870"; "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "nl.moeilijkedingen.jellyfinaudioplayer AppStore";
SWIFT_OBJC_BRIDGING_HEADER = "Fintunes/Fintunes-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
@@ -612,7 +621,7 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 124; CURRENT_PROJECT_VERSION = 118;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = HD2D35G9Y4; DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
@@ -647,7 +656,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 124; CURRENT_PROJECT_VERSION = 118;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = HD2D35G9Y4; DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;

View File

@@ -1,19 +1,20 @@
import UIKit import UIKit
import CarPlay
import React import React
import React_RCTAppDelegate import React_RCTAppDelegate
import ReactAppDependencyProvider import ReactAppDependencyProvider
@main @main
class AppDelegate: UIResponder, UIApplicationDelegate { class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate? var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory? var reactNativeFactory: RCTReactNativeFactory?
func application( func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate() let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate) let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider() delegate.dependencyProvider = RCTAppDependencyProvider()
@@ -31,6 +32,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true return true
} }
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if (connectingSceneSession.role == UISceneSession.Role.carTemplateApplication) {
let scene = UISceneConfiguration(name: "CarPlay", sessionRole: connectingSceneSession.role)
scene.delegateClass = CarSceneDelegate.self
return scene
} else {
let scene = UISceneConfiguration(name: "Phone", sessionRole: connectingSceneSession.role)
scene.delegateClass = PhoneSceneDelegate.self
return scene
}
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
} }
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate { class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {

View File

@@ -0,0 +1,17 @@
import CarPlay
class CarSceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {
func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {
print("CarPlay: Scene did connect")
print("CarPlay: About to connect to RNCarPlay")
// Dispatch connect to RNCarPlay
RNCarPlay.connect(with: interfaceController, window: templateApplicationScene.carWindow)
print("CarPlay: RNCarPlay.connect called")
}
func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didDisconnect interfaceController: CPInterfaceController) {
print("CarPlay: Scene did disconnect")
// Dispatch disconnect to RNCarPlay
RNCarPlay.disconnect()
}
}

View File

@@ -0,0 +1 @@
#import "RNCarPlay.h"

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>124</string> <string>118</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key> <key>LSSupportsOpeningDocumentsInPlace</key>
@@ -60,5 +60,41 @@
<true/> <true/>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneConfigurationName</key>
<string>CarPlay</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).CarSceneDelegate</string>
</dict>
</array>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>Phone</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).PhoneSceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>CPApplicationIdentifier</key>
<string>nl.moeilijkedingen.fintunes.carplay</string>
<key>CPApplicationName</key>
<string>Fintunes</string>
<key>CPApplicationCategory</key>
<string>CPApplicationCategoryAudio</string>
</dict> </dict>
</plist> </plist>

View File

@@ -0,0 +1,24 @@
import UIKit
import React
class PhoneSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(
_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
guard let windowScene = scene as? UIWindowScene else { return }
guard let appRootView = appDelegate.window?.rootViewController?.view else { return }
let containerViewController = UIViewController()
containerViewController.view.addSubview(appRootView)
appRootView.frame = containerViewController.view.bounds
let window = UIWindow(windowScene: windowScene)
window.rootViewController = containerViewController
self.window = window
window.makeKeyAndVisible()
}
}

View File

@@ -1399,6 +1399,8 @@ PODS:
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- Yoga - Yoga
- react-native-carplay (2.4.1-beta.0):
- React
- react-native-netinfo (11.4.1): - react-native-netinfo (11.4.1):
- React-Core - React-Core
- react-native-safe-area-context (5.4.0): - react-native-safe-area-context (5.4.0):
@@ -2310,6 +2312,7 @@ DEPENDENCIES:
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- react-native-accessibility-settings (from `../node_modules/react-native-accessibility-settings`) - react-native-accessibility-settings (from `../node_modules/react-native-accessibility-settings`)
- "react-native-blur (from `../node_modules/@react-native-community/blur`)" - "react-native-blur (from `../node_modules/@react-native-community/blur`)"
- react-native-carplay (from `../node_modules/react-native-carplay`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-skia (from `../node_modules/@shopify/react-native-skia`)" - "react-native-skia (from `../node_modules/@shopify/react-native-skia`)"
@@ -2455,6 +2458,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-accessibility-settings" :path: "../node_modules/react-native-accessibility-settings"
react-native-blur: react-native-blur:
:path: "../node_modules/@react-native-community/blur" :path: "../node_modules/@react-native-community/blur"
react-native-carplay:
:path: "../node_modules/react-native-carplay"
react-native-netinfo: react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo" :path: "../node_modules/@react-native-community/netinfo"
react-native-safe-area-context: react-native-safe-area-context:
@@ -2597,6 +2602,7 @@ SPEC CHECKSUMS:
React-microtasksnativemodule: 054f34e9b82f02bd40f09cebd4083828b5b2beb6 React-microtasksnativemodule: 054f34e9b82f02bd40f09cebd4083828b5b2beb6
react-native-accessibility-settings: 87f2276eb146ed5656bef2073e0c077e94a83f88 react-native-accessibility-settings: 87f2276eb146ed5656bef2073e0c077e94a83f88
react-native-blur: 06d0f9906ecd6cde3a42de16c6cd829a2bf0710c react-native-blur: 06d0f9906ecd6cde3a42de16c6cd829a2bf0710c
react-native-carplay: 8f388f6f73e5e0f73ed154ad8794371343ee20c0
react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187
react-native-safe-area-context: 562163222d999b79a51577eda2ea8ad2c32b4d06 react-native-safe-area-context: 562163222d999b79a51577eda2ea8ad2c32b4d06
react-native-skia: 2f725d0747756d57f0a51417c91e33bc42272c56 react-native-skia: 2f725d0747756d57f0a51417c91e33bc42272c56

View File

@@ -35,6 +35,7 @@
"react-airplay": "^1.2.0", "react-airplay": "^1.2.0",
"react-native": "^0.79.2", "react-native": "^0.79.2",
"react-native-accessibility-settings": "^0.1.2", "react-native-accessibility-settings": "^0.1.2",
"react-native-carplay": "2.4.1-beta.0",
"react-native-collapsible": "^1.6.2", "react-native-collapsible": "^1.6.2",
"react-native-dotenv": "^3.4.11", "react-native-dotenv": "^3.4.11",
"react-native-fs": "^2.20.0", "react-native-fs": "^2.20.0",

19
pnpm-lock.yaml generated
View File

@@ -88,6 +88,9 @@ importers:
react-native-accessibility-settings: react-native-accessibility-settings:
specifier: ^0.1.2 specifier: ^0.1.2
version: 0.1.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0) version: 0.1.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0)
react-native-carplay:
specifier: 2.4.1-beta.0
version: 2.4.1-beta.0(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0)
react-native-collapsible: react-native-collapsible:
specifier: ^1.6.2 specifier: ^1.6.2
version: 1.6.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0) version: 1.6.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0)
@@ -3829,6 +3832,17 @@ packages:
react: '*' react: '*'
react-native: '*' react-native: '*'
react-native-carplay@2.4.1-beta.0:
resolution: {integrity: sha512-tYJymLgJi+0516niv4ApGVC+VgENX/uCYqCX81tewSILWnS6KR7M0A9+bHyNk8xoheFyYGruX7onYxU2U8ykPA==}
peerDependencies:
react: ^17.0.2 || ^18.0.0
react-native: ^0.60.0
peerDependenciesMeta:
react:
optional: true
react-native:
optional: true
react-native-collapsible@1.6.2: react-native-collapsible@1.6.2:
resolution: {integrity: sha512-MCOBVJWqHNjnDaGkvxX997VONmJeebh6wyJxnHEgg0L1PrlcXU1e/bo6eK+CDVFuMrCafw8Qh4DOv/C4V/+Iew==} resolution: {integrity: sha512-MCOBVJWqHNjnDaGkvxX997VONmJeebh6wyJxnHEgg0L1PrlcXU1e/bo6eK+CDVFuMrCafw8Qh4DOv/C4V/+Iew==}
peerDependencies: peerDependencies:
@@ -9366,6 +9380,11 @@ snapshots:
react: 19.0.0 react: 19.0.0
react-native: 0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0) react-native: 0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0)
react-native-carplay@2.4.1-beta.0(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0):
optionalDependencies:
react: 19.0.0
react-native: 0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0)
react-native-collapsible@1.6.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0): react-native-collapsible@1.6.2(react-native@0.79.2(@babel/core@7.27.1)(@react-native-community/cli@18.0.0(typescript@5.8.3))(@types/react@18.3.20)(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
react: 19.0.0 react: 19.0.0

View File

@@ -12,7 +12,7 @@ import {
import { ColorSchemeProvider, themes, useUserOrSystemScheme } from './Colors'; import { ColorSchemeProvider, themes, useUserOrSystemScheme } from './Colors';
import DownloadManager from './DownloadManager'; import DownloadManager from './DownloadManager';
import AppLoading from './AppLoading'; import AppLoading from './AppLoading';
import { captureException } from '@sentry/react-native'; import CarPlayScreen from '@/screens/carplay';
const LightTheme = { const LightTheme = {
...DefaultTheme, ...DefaultTheme,
@@ -53,9 +53,7 @@ export default function App(): JSX.Element | null {
useEffect(() => { useEffect(() => {
async function setupTrackPlayer() { async function setupTrackPlayer() {
await TrackPlayer.setupPlayer({ await TrackPlayer.setupPlayer({ autoHandleInterruptions: true });
autoHandleInterruptions: true,
});
await TrackPlayer.updateOptions({ await TrackPlayer.updateOptions({
capabilities: [ capabilities: [
Capability.Play, Capability.Play,
@@ -71,12 +69,7 @@ export default function App(): JSX.Element | null {
} }
if (!hasSetupPlayer) { if (!hasSetupPlayer) {
setupTrackPlayer() setupTrackPlayer();
.catch((e: unknown) => {
console.error(e);
captureException(e);
setHasSetupPlayer(true);
});
} }
}, [hasSetupPlayer]); }, [hasSetupPlayer]);
@@ -92,6 +85,7 @@ export default function App(): JSX.Element | null {
<ThemedNavigationContainer> <ThemedNavigationContainer>
<Routes /> <Routes />
<DownloadManager /> <DownloadManager />
<CarPlayScreen />
</ThemedNavigationContainer> </ThemedNavigationContainer>
</ColorSchemeProvider> </ColorSchemeProvider>
</PersistGate> </PersistGate>

View File

@@ -49,7 +49,7 @@
"download-track": "Download Track", "download-track": "Download Track",
"download-album": "Download Album", "download-album": "Download Album",
"download-playlist": "Download Playlist", "download-playlist": "Download Playlist",
"no-downloads": "You have not downloaded any tracks yet", "no-downloads": "You have not yet downloaded any tracks",
"delete-track": "Delete Track", "delete-track": "Delete Track",
"delete-all-tracks": "Delete All Tracks", "delete-all-tracks": "Delete All Tracks",
"confirm-delete-all-tracks": "Are you sure you want to delete all currently downloaded tracks?", "confirm-delete-all-tracks": "Are you sure you want to delete all currently downloaded tracks?",

View File

@@ -182,7 +182,7 @@ function Downloads() {
</View> </View>
); );
} }
return ( return (
<SafeAreaView style={{ flex: 1 }}> <SafeAreaView style={{ flex: 1 }}>
{ListHeaderComponent} {ListHeaderComponent}

View File

@@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import { StatusBar, StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import { createStackNavigator } from '@react-navigation/stack'; import { createStackNavigator } from '@react-navigation/stack';
import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { t } from '@/localisation'; import { t } from '@/localisation';
import useDefaultStyles, { ColoredBlurView, useUserOrSystemScheme } from '@/components/Colors'; import useDefaultStyles, { ColoredBlurView } from '@/components/Colors';
import { StackParams } from '@/screens/types'; import { StackParams } from '@/screens/types';
import NowPlaying from './overlays/NowPlaying'; import NowPlaying from './overlays/NowPlaying';
@@ -14,36 +14,31 @@ import Playlists from './stacks/Playlists';
import Playlist from './stacks/Playlist'; import Playlist from './stacks/Playlist';
import Artists from './stacks/Artists'; import Artists from './stacks/Artists';
import Artist from './stacks/Artist'; import Artist from './stacks/Artist';
import { SafeAreaProvider } from 'react-native-safe-area-context';
const Stack = createStackNavigator<StackParams>(); const Stack = createStackNavigator<StackParams>();
function MusicStack() { function MusicStack() {
const defaultStyles = useDefaultStyles(); const defaultStyles = useDefaultStyles();
const scheme = useUserOrSystemScheme();
return ( return (
<SafeAreaProvider> <GestureHandlerRootView style={{ flex: 1 }}>
<GestureHandlerRootView style={{ flex: 1 }}> <Stack.Navigator initialRouteName="RecentAlbums" screenOptions={{
<StatusBar backgroundColor="transparent" barStyle={scheme === 'dark' ? 'light-content' : 'dark-content'} /> headerTintColor: defaultStyles.themeColor.color,
<Stack.Navigator initialRouteName="RecentAlbums" screenOptions={{ headerTitleStyle: defaultStyles.stackHeader,
headerTintColor: defaultStyles.themeColor.color, cardStyle: defaultStyles.view,
headerTitleStyle: defaultStyles.stackHeader, headerTransparent: true,
cardStyle: defaultStyles.view, headerBackground: () => <ColoredBlurView style={StyleSheet.absoluteFill} />,
headerTransparent: true, }}>
headerBackground: () => <ColoredBlurView style={StyleSheet.absoluteFill} />, <Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: t('recent-albums'), headerShown: false }} />
}}> <Stack.Screen name="Albums" component={Albums} options={{ headerTitle: t('albums') }} />
<Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: t('recent-albums'), headerShown: false }} /> <Stack.Screen name="Album" component={Album} options={{ headerTitle: t('album') }} />
<Stack.Screen name="Albums" component={Albums} options={{ headerTitle: t('albums') }} /> <Stack.Screen name="Artists" component={Artists} options={{ headerTitle: t('artists') }} />
<Stack.Screen name="Album" component={Album} options={{ headerTitle: t('album') }} /> <Stack.Screen name="Artist" component={Artist} options={({ route }) => ({ headerTitle: route.params.Name })} />
<Stack.Screen name="Artists" component={Artists} options={{ headerTitle: t('artists') }} /> <Stack.Screen name="Playlists" component={Playlists} options={{ headerTitle: t('playlists') }} />
<Stack.Screen name="Artist" component={Artist} options={({ route }) => ({ headerTitle: route.params.Name })} /> <Stack.Screen name="Playlist" component={Playlist} options={{ headerTitle: t('playlist') }} />
<Stack.Screen name="Playlists" component={Playlists} options={{ headerTitle: t('playlists') }} /> </Stack.Navigator>
<Stack.Screen name="Playlist" component={Playlist} options={{ headerTitle: t('playlist') }} /> <NowPlaying />
</Stack.Navigator> </GestureHandlerRootView>
<NowPlaying />
</GestureHandlerRootView>
</SafeAreaProvider>
); );
} }

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect } from 'react'; import React, { useCallback, useEffect } from 'react';
import { useGetImage } from '@/utility/JellyfinApi/lib'; import { useGetImage } from '@/utility/JellyfinApi/lib';
import { Text, StyleSheet, View } from 'react-native'; import { Text, SafeAreaView, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { useAppDispatch, useTypedSelector } from '@/store'; import { useAppDispatch, useTypedSelector } from '@/store';
import { fetchRecentAlbums } from '@/store/music/actions'; import { fetchRecentAlbums } from '@/store/music/actions';
@@ -18,7 +18,6 @@ import styled from 'styled-components/native';
import { ShadowWrapper } from '@/components/Shadow'; import { ShadowWrapper } from '@/components/Shadow';
import { NavigationProp } from '@/screens/types'; import { NavigationProp } from '@/screens/types';
import { SafeFlatList } from '@/components/SafeNavigatorView'; import { SafeFlatList } from '@/components/SafeNavigatorView';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
columnWrapper: { columnWrapper: {
@@ -37,7 +36,7 @@ const NavigationHeader: React.FC = () => {
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]); const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
const handlePlaylistsClick = useCallback(() => { navigation.navigate('Playlists'); }, [navigation]); const handlePlaylistsClick = useCallback(() => { navigation.navigate('Playlists'); }, [navigation]);
const handleArtistsClick = useCallback(() => { navigation.navigate('Artists'); }, [navigation]); const handleArtistsClick = useCallback(() => { navigation.navigate('Artists'); }, [navigation]);
return ( return (
<> <>
<ListButton onPress={handleAllAlbumsClick} testID="all-albums"> <ListButton onPress={handleAllAlbumsClick} testID="all-albums">
@@ -66,7 +65,7 @@ const RecentAlbums: React.FC = () => {
const { entities: albums } = useTypedSelector((state) => state.music.albums); const { entities: albums } = useTypedSelector((state) => state.music.albums);
const recentAlbums = useRecentAlbums(24); const recentAlbums = useRecentAlbums(24);
const isLoading = useTypedSelector((state) => state.music.albums.isLoading); const isLoading = useTypedSelector((state) => state.music.albums.isLoading);
// Initialise helpers // Initialise helpers
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const navigation = useNavigation<NavigationProp>(); const navigation = useNavigation<NavigationProp>();
@@ -75,20 +74,14 @@ const RecentAlbums: React.FC = () => {
// Set callbacks // Set callbacks
const retrieveData = useCallback(() => dispatch(fetchRecentAlbums()), [dispatch]); const retrieveData = useCallback(() => dispatch(fetchRecentAlbums()), [dispatch]);
const selectAlbum = useCallback((id: string) => navigation.navigate('Album', { id, album: albums[id] as Album }), [navigation, albums]); const selectAlbum = useCallback((id: string) => navigation.navigate('Album', { id, album: albums[id] as Album }), [navigation, albums]);
// Retrieve data on mount // Retrieve data on mount
useEffect(() => { retrieveData(); }, [retrieveData]); useEffect(() => { retrieveData(); }, [retrieveData]);
const insets = useSafeAreaInsets();
return ( return (
<View <SafeAreaView>
style={{
paddingTop: insets.top,
paddingBottom: 1 * insets.bottom,
}}>
<SafeFlatList <SafeFlatList
data={recentAlbums as string[]} data={recentAlbums as string[]}
refreshing={isLoading} refreshing={isLoading}
onRefresh={retrieveData} onRefresh={retrieveData}
numColumns={2} numColumns={2}
@@ -107,7 +100,7 @@ const RecentAlbums: React.FC = () => {
</TouchableHandler> </TouchableHandler>
)} )}
/> />
</View> </SafeAreaView>
); );
}; };

View File

@@ -8,7 +8,6 @@ import Album from '@/screens/Music/stacks/Album';
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import NowPlaying from '@/screens/Music/overlays/NowPlaying'; import NowPlaying from '@/screens/Music/overlays/NowPlaying';
import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
const Stack = createStackNavigator<StackParams>(); const Stack = createStackNavigator<StackParams>();
@@ -17,29 +16,27 @@ function SearchStack() {
const [isInitialRoute, setIsInitialRoute] = useState(true); const [isInitialRoute, setIsInitialRoute] = useState(true);
return ( return (
<SafeAreaProvider> <GestureHandlerRootView style={{ flex: 1 }}>
<GestureHandlerRootView style={{ flex: 1 }}> <Stack.Navigator initialRouteName="Search"
<Stack.Navigator initialRouteName="Search" screenOptions={{
screenOptions={{ headerTintColor: defaultStyles.themeColor.color,
headerTintColor: defaultStyles.themeColor.color, headerTitleStyle: defaultStyles.stackHeader,
headerTitleStyle: defaultStyles.stackHeader, cardStyle: defaultStyles.view,
cardStyle: defaultStyles.view, headerTransparent: true,
headerTransparent: true, headerBackground: () => <ColoredBlurView style={StyleSheet.absoluteFill} />,
headerBackground: () => <ColoredBlurView style={StyleSheet.absoluteFill} />, }}
}} screenListeners={{
screenListeners={{ state: (e) => {
state: (e) => { const { state: { routes } } = e.data as { state: { routes?: { key: string, name: string }[] } };
const { state: { routes } } = e.data as { state: { routes?: { key: string, name: string }[] } }; setIsInitialRoute(routes?.length === 1);
setIsInitialRoute(routes?.length === 1); }
} }}
}} >
> <Stack.Screen name="Search" component={Search} options={{ headerTitle: t('search'), headerShown: false }} />
<Stack.Screen name="Search" component={Search} options={{ headerTitle: t('search'), headerShown: false }} /> <Stack.Screen name="Album" component={Album} options={{ headerTitle: t('album') }} />
<Stack.Screen name="Album" component={Album} options={{ headerTitle: t('album') }} /> </Stack.Navigator>
</Stack.Navigator> <NowPlaying offset={isInitialRoute ? 64 : 0} />
<NowPlaying offset={isInitialRoute ? 64 : 0} /> </GestureHandlerRootView>
</GestureHandlerRootView>
</SafeAreaProvider>
); );
} }

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback, useMemo } from 'react'; import React, { useState, useEffect, useCallback, useMemo } from 'react';
import Input from '@/components/Input'; import Input from '@/components/Input';
import { ActivityIndicator, Animated, KeyboardAvoidingView, Platform, View } from 'react-native'; import { ActivityIndicator, Animated, KeyboardAvoidingView, Platform, SafeAreaView, View } from 'react-native';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import { useAppDispatch, useTypedSelector } from '@/store'; import { useAppDispatch, useTypedSelector } from '@/store';
import Fuse, { IFuseOptions } from 'fuse.js'; import Fuse, { IFuseOptions } from 'fuse.js';
@@ -21,7 +21,6 @@ import { ShadowWrapper } from '@/components/Shadow';
import { NavigationProp } from '@/screens/types'; import { NavigationProp } from '@/screens/types';
import { useNavigationOffsets } from '@/components/SafeNavigatorView'; import { useNavigationOffsets } from '@/components/SafeNavigatorView';
import BaseAlbumImage from '@/screens/Music/stacks/components/AlbumImage'; import BaseAlbumImage from '@/screens/Music/stacks/components/AlbumImage';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
// import MicrophoneIcon from '@/assets/icons/microphone.svg'; // import MicrophoneIcon from '@/assets/icons/microphone.svg';
// import AlbumIcon from '@/assets/icons/collection.svg'; // import AlbumIcon from '@/assets/icons/collection.svg';
// import TrackIcon from '@/assets/icons/note.svg'; // import TrackIcon from '@/assets/icons/note.svg';
@@ -32,8 +31,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
const KEYBOARD_OFFSET = Platform.select({ const KEYBOARD_OFFSET = Platform.select({
ios: 0, ios: 0,
// Android 15+ has edge-to-edge support, changing the keyboard offset to 0 android: 72,
android: Number.parseInt(Platform.Version as string) >= 35 ? 0 : 72,
}); });
const SEARCH_INPUT_HEIGHT = 62; const SEARCH_INPUT_HEIGHT = 62;
@@ -268,10 +266,8 @@ export default function Search() {
...jellyfinResults, ...jellyfinResults,
]), [fuseResults, jellyfinResults]); ]), [fuseResults, jellyfinResults]);
const insets = useSafeAreaInsets();
return ( return (
<View style={{ flex: 1, paddingTop: insets.top, marginBottom: offsets.bottom }}> <SafeAreaView style={{ flex: 1, marginBottom: offsets.bottom }}>
<KeyboardAvoidingView behavior="height" style={{ flex: 1 }} keyboardVerticalOffset={KEYBOARD_OFFSET}> <KeyboardAvoidingView behavior="height" style={{ flex: 1 }} keyboardVerticalOffset={KEYBOARD_OFFSET}>
<FlatList <FlatList
keyboardShouldPersistTaps="handled" keyboardShouldPersistTaps="handled"
@@ -327,6 +323,6 @@ export default function Search() {
) : null} ) : null}
{SearchInput} {SearchInput}
</KeyboardAvoidingView> </KeyboardAvoidingView>
</View> </SafeAreaView>
); );
} }

View File

@@ -2,6 +2,7 @@ import { Paragraph } from '@/components/Typography';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { Switch } from 'react-native-gesture-handler'; import { Switch } from 'react-native-gesture-handler';
import { t } from '@/localisation'; import { t } from '@/localisation';
import { SafeScrollView } from '@/components/SafeNavigatorView';
import { useAppDispatch, useTypedSelector } from '@/store'; import { useAppDispatch, useTypedSelector } from '@/store';
import { setEnablePlaybackReporting } from '@/store/settings/actions'; import { setEnablePlaybackReporting } from '@/store/settings/actions';
import Container from '../components/Container'; import Container from '../components/Container';
@@ -16,12 +17,14 @@ export default function PlaybackReporting() {
}, [isEnabled, dispatch]); }, [isEnabled, dispatch]);
return ( return (
<Container> <SafeScrollView>
<Paragraph>{t('playback-reporting-description')}</Paragraph> <Container>
<SwitchContainer> <Paragraph>{t('playback-reporting-description')}</Paragraph>
<SwitchLabel>{t('playback-reporting')}</SwitchLabel> <SwitchContainer>
<Switch value={isEnabled} onValueChange={toggleSwitch} /> <SwitchLabel>{t('playback-reporting')}</SwitchLabel>
</SwitchContainer> <Switch value={isEnabled} onValueChange={toggleSwitch} />
</Container> </SwitchContainer>
</Container>
</SafeScrollView>
); );
} }

View File

@@ -0,0 +1,62 @@
import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import { CarPlay, ListTemplate, ListItem } from 'react-native-carplay';
const CarPlayScreen: React.FC = () => {
useEffect(() => {
console.log('CarPlay: Screen mounted');
const onConnect = () => {
console.log('CarPlay: React Native connected');
// Create a list template with some items
const template = new ListTemplate({
title: 'Fintunes',
sections: [
{
header: 'Library',
items: [
{
text: 'Songs',
detailText: 'Browse your music library',
},
{
text: 'Albums',
detailText: 'Browse your albums',
},
{
text: 'Artists',
detailText: 'Browse your artists',
},
],
},
],
onItemSelect: (item) => {
console.log('Selected item:', item);
},
});
// Set the template as root
CarPlay.setRootTemplate(template);
};
const onDisconnect = () => {
console.log('CarPlay: React Native disconnected');
};
// Register for CarPlay connection events
CarPlay.registerOnConnect(onConnect);
CarPlay.registerOnDisconnect(onDisconnect);
return () => {
console.log('CarPlay: Screen unmounting');
// Cleanup listeners
CarPlay.unregisterOnConnect(onConnect);
CarPlay.unregisterOnDisconnect(onDisconnect);
};
}, []);
return null;
};
export default CarPlayScreen;

View File

@@ -98,7 +98,7 @@ export default function Routes() {
}} id="MAIN"> }} id="MAIN">
<Stack.Screen name="Screens" component={Screens} /> <Stack.Screen name="Screens" component={Screens} />
<Stack.Screen name="SetJellyfinServer" component={SetJellyfinServer} /> <Stack.Screen name="SetJellyfinServer" component={SetJellyfinServer} />
<Stack.Screen name="TrackPopupMenu" component={TrackPopupMenu} options={{ presentation: 'formSheet', sheetCornerRadius: 10, sheetAllowedDetents: [0.85, 1.0]}} /> <Stack.Screen name="TrackPopupMenu" component={TrackPopupMenu} options={{ presentation: 'formSheet' }} />
<Stack.Screen name="ErrorReporting" component={ErrorReportingPopup} /> <Stack.Screen name="ErrorReporting" component={ErrorReportingPopup} />
<Stack.Screen name="Player" component={Player} /> <Stack.Screen name="Player" component={Player} />
<Stack.Screen name="Lyrics" component={Lyrics} /> <Stack.Screen name="Lyrics" component={Lyrics} />

View File

@@ -1,11 +1,11 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import XmarkIcon from '@/assets/icons/xmark.svg'; import XmarkIcon from '@/assets/icons/xmark.svg';
import { TouchableOpacity } from 'react-native';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
const Container = styled.TouchableOpacity` const Container = styled.View`
padding: 12px 0px; padding: 6px 12px;
z-index: 2;
`; `;
function BackButton() { function BackButton() {
@@ -16,8 +16,10 @@ function BackButton() {
}, [navigation]); }, [navigation]);
return ( return (
<Container onPress={handlePress}> <Container>
<XmarkIcon /> <TouchableOpacity onPress={handlePress}>
<XmarkIcon />
</TouchableOpacity>
</Container> </Container>
); );
} }

View File

@@ -6,7 +6,7 @@ import Queue from './components/Queue';
import ConnectionNotice from './components/ConnectionNotice'; import ConnectionNotice from './components/ConnectionNotice';
import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { GestureHandlerRootView } from 'react-native-gesture-handler';
import StreamStatus from './components/StreamStatus'; import StreamStatus from './components/StreamStatus';
import { Platform } from 'react-native'; import {Platform} from 'react-native';
import BackButton from './components/Backbutton'; import BackButton from './components/Backbutton';
import Timer from './components/Timer'; import Timer from './components/Timer';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
@@ -23,11 +23,9 @@ export default function Player() {
return ( return (
<GestureHandlerRootView style={{ flex: 1 }}> <GestureHandlerRootView style={{ flex: 1 }}>
<ColoredBlurView> <ColoredBlurView>
{Platform.OS === 'android' && (<BackButton />)}
<Queue header={( <Queue header={(
<> <>
{Platform.OS === 'android' && (
<BackButton />
)}
<NowPlaying /> <NowPlaying />
<ConnectionNotice /> <ConnectionNotice />
<StreamStatus /> <StreamStatus />

View File

@@ -75,7 +75,7 @@ function TrackPopupMenu() {
}, [trackId, dispatch, closeModal]); }, [trackId, dispatch, closeModal]);
return ( return (
<ColoredBlurView style={{flex: 1}}> <ColoredBlurView>
<Container> <Container>
<Artwork src={getImage(track)} /> <Artwork src={getImage(track)} />
<Header>{track?.Name}</Header> <Header>{track?.Name}</Header>