Compare commits

...

6 Commits

Author SHA1 Message Date
Lei Nelissen
9d995d795b chore: release v2.4.3 for android 2025-01-29 15:54:29 +01:00
Lei Nelissen
b8a2c0d889 fix: crash in android player modal 2025-01-29 15:27:21 +01:00
Lei Nelissen
bf4b9bd446 chore: release v2.4.2 2025-01-29 12:29:35 +01:00
Lei Nelissen
55bfbee3b0 chore: update release notes 2025-01-29 12:13:55 +01:00
Lei Nelissen
614066c11e fix: missing fallback cover images 2025-01-29 11:25:00 +01:00
Lei Nelissen
b381537b62 fix: missing images causing download errors 2025-01-29 11:10:49 +01:00
32 changed files with 270 additions and 136 deletions

View File

@@ -85,8 +85,8 @@ android {
applicationId "nl.moeilijkedingen.jellyfinaudioplayer"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 31
versionName "2.4.1"
versionCode 33
versionName "2.4.3"
}
signingConfigs {

View File

@@ -1,4 +1,4 @@
# The Deliverfile allows you to store various App Store Connect metadata
# For more information, check out the docs
# https://docs.fastlane.tools/actions/deliver/
overwrite_screenshots(true)
overwrite_screenshots(false)

View File

@@ -37,7 +37,9 @@ platform :ios do
workspace: "ios/Fintunes.xcworkspace",
export_method: "app-store",
)
upload_to_app_store
upload_to_app_store(
precheck_include_in_app_purchases: false
)
end
lane :beta do

View File

@@ -1 +1,7 @@
Aquesta és una correcció ràpida que permet tornar a accedir al vostre servidor Jellyfin mitjançant HTTP. Si us plau, utilitzeu HTTPS si el teniu disponible.
Fintunes ara admet la visualització de lletres perquè puguis cantar les teves cançons preferides! A més, ara pots utilitzar Fintunes com a client per a Emby. Les característiques menors daquesta versió inclouen:
• Les imatges de portada es desen per a les pistes descarregades (torna a descarregar les teves pistes per assegurar-te que apareguin)
• Una pantalla que mostra informació sobre el còdec de les pistes que sestan reproduint
• Moltes noves traduccions, com el polonès, tàmil, xinès tradicional, finès i indonesi. Gràcies a tots els col·laboradors lingüístics!
La versió 2.4.2 corregeix un error introduït a la versió 2.4.0 que impedia descarregar pistes sense portada.

View File

@@ -1 +1,7 @@
Toto je oprava hotfix, která umožňuje znovu přistupovat k serveru Jellyfin přes HTTP. Použijte prosím HTTPS, pokud je to pro vás dostupné.
Fintunes nyní podporuje zobrazování textů písní, takže si můžete zpívat své oblíbené skladby! Také nyní můžete používat Fintunes jako klienta pro Emby. Menší funkce v této verzi zahrnují:
• Ukládání obalů alb pro stažené skladby (znovu si stáhněte skladby, aby se obaly zobrazily)
• Displej zobrazující informace o kodeku právě přehrávaných skladeb
• Spousta nových překladů, například polština, tamilština, tradiční čínština, finština a indonéština. Děkujeme všem překladatelům!
Verze 2.4.2 opravuje chybu zavedenou ve verzi 2.4.0, která znemožňovala stahování skladeb bez obalu.

View File

@@ -1 +1,7 @@
Hierbei handelt es sich um einen Hotfix, der es wieder möglich macht, über HTTP auf Ihren Jellyfin-Server zuzugreifen. Bitte verwenden Sie HTTPS, sofern Ihnen dies zur Verfügung steht.
Fintunes unterstützt jetzt die Anzeige von Liedtexten, sodass du deine Lieblingssongs mitsingen kannst! Außerdem kannst du Fintunes jetzt als Client für Emby nutzen. Kleinere Funktionen in dieser Version umfassen:
• Coverbilder werden für heruntergeladene Titel gespeichert (lade deine Titel erneut herunter, um sicherzustellen, dass sie angezeigt werden)
• Eine Anzeige, die Codec-Informationen für die aktuell abgespielten Titel zeigt
• Viele neue Übersetzungen, darunter Polnisch, Tamil, Traditionelles Chinesisch, Finnisch und Indonesisch. Vielen Dank an alle Sprachbeiträger!
Version 2.4.2 behebt einen Fehler aus Version 2.4.0, der das Herunterladen von Titeln ohne Cover verhinderte.

View File

@@ -1 +1,7 @@
This is a hotfix that makes it possible to access your Jellyfin server over HTTP again. Do please use HTTPS if that's available to you.
Fintunes now supports displaying lyrics so you can sign along to your favourite tunes! Also, you can now use Fintunes as a client for Emby. Minor features in this release include:
• Cover images being saved for downloaded tracks (re-download your tracks to make sure they appear)
• A display that shows codec information for your currently playing tracks
• Loads of new translations, such as Polish, Tamil, Traditional Chinese, Finnish and Indonesian. Thanks to all language contributors!
v2.4.2 contains a fix for an error introduced with v2.4.0 that prohibited downloading tracks without cover art.

View File

@@ -1 +1,7 @@
Esta es una revisión que permite acceder nuevamente a su servidor Jellyfin a través de HTTP. Utilice HTTPS si está disponible para usted.
Fintunes ahora admite la visualización de letras para que puedas cantar tus canciones favoritas. Además, ahora puedes usar Fintunes como cliente para Emby. Las características menores de esta versión incluyen:
• Se guardan las imágenes de portada para las pistas descargadas (vuelve a descargar tus pistas para asegurarte de que aparezcan)
• Una pantalla que muestra información del códec de las pistas que estás reproduciendo
• Muchas nuevas traducciones, como polaco, tamil, chino tradicional, finlandés e indonesio. ¡Gracias a todos los colaboradores de idiomas!
La versión 2.4.2 corrige un error introducido en la versión 2.4.0 que impedía descargar pistas sin portada.

View File

@@ -1 +1,7 @@
Il s'agit d'un correctif qui permet d'accéder à nouveau à votre serveur Jellyfin via HTTP. Veuillez utiliser HTTPS si vous en avez la possibilité.
Fintunes prend désormais en charge laffichage des paroles, afin que vous puissiez chanter vos morceaux préférés ! De plus, vous pouvez maintenant utiliser Fintunes comme client pour Emby. Les fonctionnalités mineures de cette version incluent :
• Les images de couverture sont enregistrées pour les morceaux téléchargés (retéléchargez vos morceaux pour vous assurer quelles apparaissent)
• Un affichage indiquant les informations du codec des morceaux en cours de lecture
• De nombreuses nouvelles traductions, notamment en polonais, tamoul, chinois traditionnel, finnois et indonésien. Merci à tous les contributeurs linguistiques !
La version 2.4.2 corrige une erreur introduite avec la version 2.4.0 qui empêchait le téléchargement des morceaux sans pochette.

View File

@@ -1 +1,7 @@
Questo è un hotfix che rende possibile accedere nuovamente al tuo server Jellyfin tramite HTTP. Ti preghiamo di utilizzare HTTPS se è disponibile per te.
Fintunes ora supporta la visualizzazione dei testi, così puoi cantare le tue canzoni preferite! Inoltre, ora puoi usare Fintunes come client per Emby. Le funzionalità minori di questa versione includono:
• Le immagini di copertina vengono salvate per i brani scaricati (riscarica i brani per assicurarti che appaiano)
• Un display che mostra le informazioni sul codec per i brani attualmente in riproduzione
• Molte nuove traduzioni, come polacco, tamil, cinese tradizionale, finlandese e indonesiano. Grazie a tutti i contributori linguistici!
La versione 2.4.2 corregge un errore introdotto con la versione 2.4.0 che impediva il download di brani senza copertina.

View File

@@ -1 +1,7 @@
これは、HTTP 経由で Jellyfin サーバーに再びアクセスできるようにするホットフィックスです。 HTTPS が利用可能な場合は、HTTPS を使用してください。
Fintunesは歌詞の表示をサポートするようになり、お気に入りの曲を一緒に歌えるようになりましたさらに、FintunesをEmbyのクライアントとして使用できるようになりました。このリリースの小さな新機能には以下が含まれます:
• ダウンロードした曲のカバー画像を保存(曲を再ダウンロードすると表示されるようになります)
• 現在再生中の曲のコーデック情報を表示する画面
• ポーランド語、タミル語、繁体字中国語、フィンランド語、インドネシア語など、多くの新しい翻訳。すべての翻訳者の皆さんに感謝します!
バージョン 2.4.2 は、バージョン 2.4.0 で発生したカバーアートなしの曲をダウンロードできないバグを修正しました。

View File

@@ -1 +1,7 @@
Dit is een hotfix die het mogelijk maakt om weer via HTTP toegang te krijgen tot je Jellyfin-server. Gebruik alsjeblieft HTTPS als dat voor jou beschikbaar is.
Fintunes ondersteunt nu het weergeven van songteksten, zodat je kunt meezingen met je favoriete nummers! Daarnaast kun je Fintunes nu gebruiken als een client voor Emby. Kleine functies in deze release zijn onder andere:
• Coverafbeeldingen worden opgeslagen voor gedownloade nummers (download je nummers opnieuw om ervoor te zorgen dat ze verschijnen)
• Een weergave die codec-informatie toont voor de nummers die je momenteel afspeelt
• Veel nieuwe vertalingen, zoals Pools, Tamil, Traditioneel Chinees, Fins en Indonesisch. Bedankt aan alle taalbijdragers!
Versie 2.4.2 lost een fout op die in versie 2.4.0 werd geïntroduceerd en die verhinderde dat nummers zonder cover konden worden gedownload.

View File

@@ -1 +1,7 @@
Dette er en hurtigreparasjon som gjør det mulig å få tilgang til Jellyfin-serveren din over HTTP igjen. Vennligst bruk HTTPS hvis det er tilgjengelig for deg.
Fintunes støtter nå visning av sangtekster, slik at du kan synge med til favorittsangene dine! I tillegg kan du nå bruke Fintunes som en klient for Emby. Mindre funksjoner i denne utgivelsen inkluderer:
• Coverbilder lagres for nedlastede spor (last ned sporene dine på nytt for å sikre at de vises)
• En visning som viser kodekinformasjon for sporene du spiller av
• Massevis av nye oversettelser, som polsk, tamil, tradisjonell kinesisk, finsk og indonesisk. Takk til alle språkbidragsytere!
Versjon 2.4.2 inneholder en feilretting for en feil som ble introdusert i versjon 2.4.0, som forhindret nedlasting av spor uten cover.

View File

@@ -1 +1,7 @@
Jest to poprawka umożliwiająca ponowne uzyskanie dostępu do serwera Jellyfin za pośrednictwem protokołu HTTP. Jeśli masz taką możliwość, użyj protokołu HTTPS.
Fintunes obsługuje teraz wyświetlanie tekstów piosenek, dzięki czemu możesz śpiewać razem ze swoimi ulubionymi utworami! Dodatkowo możesz teraz używać Fintunes jako klienta dla Emby. Drobne zmiany w tej wersji obejmują:
• Zapisywanie okładek dla pobranych utworów (ponownie pobierz utwory, aby upewnić się, że okładki się pojawią)
• Wyświetlanie informacji o kodeku dla aktualnie odtwarzanych utworów
• Wiele nowych tłumaczeń, takich jak polski, tamilski, tradycyjny chiński, fiński i indonezyjski. Dziękujemy wszystkim tłumaczom!
Wersja 2.4.2 naprawia błąd wprowadzony w wersji 2.4.0, który uniemożliwiał pobieranie utworów bez okładki.

View File

@@ -1 +1,7 @@
Este é um hotfix que torna possível acessar novamente o servidor Jellyfin por HTTP. Use HTTPS se estiver disponível para você.
O Fintunes agora suporta a exibição de letras, para que você possa cantar junto com suas músicas favoritas! Além disso, agora você pode usar o Fintunes como cliente para o Emby. Pequenas melhorias nesta versão incluem:
• As imagens de capa agora são salvas para faixas baixadas (baixe novamente suas faixas para garantir que apareçam)
• Uma exibição que mostra informações do codec para as faixas que estão sendo reproduzidas
• Muitas novas traduções, incluindo polonês, tâmil, chinês tradicional, finlandês e indonésio. Obrigado a todos os colaboradores de idiomas!
A versão 2.4.2 corrige um erro introduzido na versão 2.4.0 que impedia o download de faixas sem capa.

View File

@@ -1 +1,7 @@
Это исправление, которое позволяет снова получить доступ к вашему серверу Jellyfin через HTTP. Пожалуйста, используйте HTTPS, если он вам доступен.
Fintunes теперь поддерживает отображение текстов песен, чтобы вы могли подпевать своим любимым мелодиям! Кроме того, теперь вы можете использовать Fintunes в качестве клиента для Emby. Незначительные изменения в этом выпуске включают:
• Сохранение обложек для загруженных треков (перекачайте треки, чтобы убедиться, что обложки отображаются)
• Отображение информации о кодеке для текущих воспроизводимых треков
• Множество новых переводов, таких как польский, тамильский, традиционный китайский, финский и индонезийский. Спасибо всем переводчикам!
Версия 2.4.2 исправляет ошибку, появившуюся в версии 2.4.0, которая препятствовала загрузке треков без обложек.

View File

@@ -1 +1,7 @@
Detta är en snabbkorrigering som gör det möjligt att komma åt din Jellyfin-server över HTTP igen. Använd HTTPS om det är tillgängligt för dig.
Fintunes har nu stöd för att visa låttexter så att du kan sjunga med i dina favoritlåtar! Dessutom kan du nu använda Fintunes som en klient för Emby. Mindre funktioner i denna version inkluderar:
• Omslagsbilder sparas för nedladdade låtar (ladda ner låtarna igen för att säkerställa att omslagen visas)
• En visning som visar codec-information för låtar du spelar upp
• Massor av nya översättningar, såsom polska, tamilska, traditionell kinesiska, finska och indonesiska. Tack till alla språkbidragsgivare!
Version 2.4.2 innehåller en fix för ett fel som introducerades i version 2.4.0, vilket förhindrade nedladdning av låtar utan omslagsbild.

View File

@@ -1 +1,7 @@
Це виправлення, яке знову робить можливим доступ до вашого сервера Jellyfin через HTTP. Використовуйте HTTPS, якщо він доступний.
Fintunes тепер підтримує відображення текстів пісень, щоб ви могли підспівувати улюбленим мелодіям! Також тепер ви можете використовувати Fintunes як клієнт для Emby. Незначні оновлення у цьому випуску включають:
• Збереження обкладинок для завантажених треків (перезавантажте ваші треки, щоб переконатися, що обкладинки відображаються)
• Дисплей, що показує інформацію про кодек для поточно відтворюваних треків
• Багато нових перекладів, таких як польська, тамільська, традиційна китайська, фінська та індонезійська. Дякуємо всім, хто допоміг із перекладами!
Версія 2.4.2 виправляє помилку, яка з’явилася у версії 2.4.0 і заважала завантаженню треків без обкладинок.

View File

@@ -1 +1,7 @@
这是一个修补程序,可以再次通过 HTTP 访问 Jellyfin 服务器。 如果您可以使用 HTTPS请务必使用它。
Fintunes 现在支持歌词显示,让你可以跟唱你最喜欢的歌曲!此外,你现在可以将 Fintunes 用作 Emby 的客户端。本次更新的其他小功能包括:
• 下载的歌曲现在会保存封面图像(请重新下载歌曲以确保封面显示)
• 显示当前播放歌曲的编解码器信息
• 许多新翻译,例如波兰语、泰米尔语、繁体中文、芬兰语和印尼语。感谢所有语言贡献者!
版本 2.4.2 修复了在 2.4.0 版本中引入的一个错误,该错误阻止了无封面歌曲的下载。

View File

@@ -1 +1,7 @@
這是一個緊急修復,讓可以再次透過 HTTP 訪問您的 Jellyfin 伺服器。如果可能,請優先使用 HTTPS。
Fintunes 現在支援顯示歌詞,讓可以跟唱你最喜愛的歌曲!此外,你現在可以將 Fintunes 用作 Emby 的客戶端。本次更新的其他小功能包括:
• 下載的歌曲現在會儲存封面圖片(請重新下載歌曲以確保封面顯示)
• 顯示當前播放歌曲的編解碼器資訊
• 許多新翻譯,例如波蘭語、泰米爾語、繁體中文、芬蘭語和印尼語。感謝所有語言貢獻者!
版本 2.4.2 修復了在 2.4.0 版本中引入的一個錯誤,該錯誤阻止了無封面歌曲的下載。

View File

@@ -578,7 +578,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 102;
CURRENT_PROJECT_VERSION = 106;
DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -616,7 +616,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 102;
CURRENT_PROJECT_VERSION = 106;
DEVELOPMENT_TEAM = HD2D35G9Y4;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = HD2D35G9Y4;
INFOPLIST_FILE = Fintunes/Info.plist;
@@ -796,7 +796,7 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 102;
CURRENT_PROJECT_VERSION = 106;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_C_LANGUAGE_STANDARD = gnu11;
@@ -831,7 +831,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 102;
CURRENT_PROJECT_VERSION = 106;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_C_LANGUAGE_STANDARD = gnu11;

View File

@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.4.0</string>
<string>2.4.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>102</string>
<string>106</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>

View File

@@ -970,7 +970,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-blur (4.4.0):
- react-native-blur (4.4.1):
- DoubleConversion
- glog
- hermes-engine
@@ -1610,66 +1610,66 @@ SPEC CHECKSUMS:
RCTRequired: d530a0f489699c8500e944fde963102c42dcd0c2
RCTTypeSafety: b20878506b094fa3d9007d7b9e4be0faa3562499
React: 2f9da0177233f60fa3462d83fcccde245759f81a
react-airplay: 8197767f12cae11a7623b1507d29a89482a720ad
react-airplay: 7cfb97ebe4ee2e81a3674d5585fa3915b2491494
React-callinvoker: d0205f0dcebf72ec27263ab41e3a5ad827ed503f
React-Codegen: b4457c8557cb61a27508745f8b03f16afeb9ef59
React-Core: 690ebbbf8f8dcfba6686ce8927731d3f025c3114
React-CoreModules: 185da31f5eb2e6043c3d19b10c64c4661322ed6a
React-cxxreact: c53d2ac9246235351086b8c588feaf775b4ec7f7
React-Codegen: 5e5ea1445e92a34b60dfedb3f231ea9fde102118
React-Core: 77ec025801a9c03613ec3744918e5a3d58f96227
React-CoreModules: dc1e1d2724273ae4594596c4105d15fb2f6a98b0
React-cxxreact: efa12baf9dbf0170209633acc125e0de5991e335
React-debug: dd8f7c772fda4196814a3b12620863d1d98b3a53
React-Fabric: 68935648d5c81e6b84445d9e726a79301f1fac8f
React-FabricImage: c92bd5ed4b553c800ca39aee305aaf8dd3e9f4b0
React-Fabric: d0ffc842b849a8223f23e6184b99ca6f8bdebf3c
React-FabricImage: 8f9753fbbfa379b1a74f3bdd9a68ce0ead81305a
React-featureflags: ead50fe0ee4ab9278b5fd9f3f2f0f63e316452f4
React-graphics: 71c87b09041e45c61809cd357436e570dea5ed48
React-hermes: 917b7ab4c3cb9204c2ad020d74f313830097148b
React-ImageManager: 1086d48d00fcb511ea119bfc58fb12a72c4dcb95
React-jserrorhandler: 84d45913636750c2e620a8c8e049964967040405
React-jsi: 024b933267079f80c30a5cae97bf5ce521217505
React-jsiexecutor: 45cb079c87db3f514da3acfc686387a0e01de5c5
React-jsinspector: 1066f8b3da937daf8ced4cf3786eb29e1e4f9b30
React-jsitracing: 6b3c8c98313642140530f93c46f5a6ca4530b446
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
React-Mapbuffer: 9f68550e7c6839d01411ac8896aea5c868eff63a
react-native-accessibility-settings: 0262dd0c27543f39670729f2a1ad7b6e4c834548
react-native-blur: a2acf22fd7bd13621df5e0b1c130b81adea7009c
react-native-netinfo: 8a7fd3f7130ef4ad2fb4276d5c9f8d3f28d2df3d
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
react-native-skia: dc11459441dd994f77baa92357b13af3977acba0
react-native-track-player: 97d76dbbd35f27cc709e5f04540615e54264b3f9
react-native-webview: e507c4058331c43546200e8e8529453e73a98635
React-graphics: a2fe5d65b470eb8d6187e4a9791aa71ad68105cb
React-hermes: 92709612ce5cdce3a2b9e07183e581548101a8d8
React-ImageManager: b8e0cb2e430c52daf823fb08318ea8cda101d269
React-jserrorhandler: 39694c5b1cd4c773c89196bcd1e846ae3b8a5bda
React-jsi: c391df50eb8766c2ea12dba2e3112c77a99b371d
React-jsiexecutor: 679632acd5792dd8dc6c090b7313b15eccdd9e45
React-jsinspector: 1bf2fa762cf0e67c5632e5e95c0db180cdbe3bcc
React-jsitracing: eee70a10f1e17690d33fb46a0989a19657c546a3
React-logger: bbd09ad59f304e718962b2867534204710873bd9
React-Mapbuffer: da4470fdf42b2e389efbc4e7af958bf96e921a0b
react-native-accessibility-settings: 6e8630983d893f86b2a963695051089e58ebdfe7
react-native-blur: 207ec2bf853b9a3b7751e3a29f7f497e69010b44
react-native-netinfo: f084f2324cb11b986503a39a3ccbb5d15e2a56d3
react-native-safe-area-context: b72c4611af2e86d80a59ac76279043d8f75f454c
react-native-skia: e0979ddcd929ac07474d07fe37c980b2c213e272
react-native-track-player: 5c2e08a38dd7e69c0f0ad6b382ac3257637d4a0b
react-native-webview: 5a4de0fb0241b16cfaef4138aef94b786dbcf1cd
React-nativeconfig: fa5de9d8f4dbd5917358f8ad3ad1e08762f01dcb
React-NativeModulesApple: 585d1b78e0597de364d259cb56007052d0bda5e5
React-NativeModulesApple: 714d4a6ea3c580c31b25ad01f9650b259fad9818
React-perflogger: 7bb9ba49435ff66b666e7966ee10082508a203e8
React-RCTActionSheet: a2816ae2b5c8523c2bc18a8f874a724a096e6d97
React-RCTAnimation: e78f52d7422bac13e1213e25e9bcbf99be872e1a
React-RCTAppDelegate: 24f46de486cfa3a9f46e4b0786eaf17d92e1e0c6
React-RCTBlob: 9f9d6599d1b00690704dadc4a4bc33a7e76938be
React-RCTFabric: 609e66bb0371b9082c62ed677ee0614efe711bf2
React-RCTImage: 39dd5aee6b92213845e1e7a7c41865801dc33493
React-RCTLinking: 35d742a982f901f9ea416d772763e2da65c2dc7d
React-RCTNetwork: b078576c0c896c71905f841716b9f9f5922111dc
React-RCTSettings: 900aab52b5b1212f247c2944d88f4defbf6146f2
React-RCTText: a3895ab4e5df4a5fd41b6f059eed484a0c7016d1
React-RCTVibration: ab4912e1427d8de00ef89e9e6582094c4c25dc05
React-rendererdebug: 542934058708a643fa5743902eb2fedc0833770a
React-RCTAnimation: 082083adea9e61f75be6564120e3f266e9dd2040
React-RCTAppDelegate: 5075f1d00c9353105f5b0906ba477db1dd3f4993
React-RCTBlob: 43976a6aa15df43b12136de396bd72bdced5eb23
React-RCTFabric: 5351cfc7d92a1ed66a3fe87fa24fb27db5a5b4d8
React-RCTImage: 0ed46bd0092e0ca29ed7269831934e32b809a934
React-RCTLinking: 9eeefa11941ce0faded2c9eb2242f0c96db1e23c
React-RCTNetwork: ec125edeac233d33638b40361238bfbd698e13f6
React-RCTSettings: 47195b7e31bba95d38dbdd2c8a1b1fc6d7c1a7f2
React-RCTText: 14b0bd5b70e058b2b62b47945057602bc67f9e68
React-RCTVibration: 084119dd03a27c975c382d9b71a48722ee74b2e7
React-rendererdebug: 94a00e425316b11b2891e3b7a1232c2cd7f4e7ea
React-rncore: f6c23d9810c8de9e369781bb7b1d5511e9d9f4e7
React-RuntimeApple: ce41ba7df744c7a6c2cc490a9b2e15fc58019508
React-RuntimeCore: 350218ac9ee1412ddc9806f248141c8fb9bccd8b
React-RuntimeApple: 70840b529724c0f9dae0b9efcc0b05a26495776d
React-RuntimeCore: f679bc2949b36d7d210f3860360c7e0694fe939c
React-runtimeexecutor: 69cab8ddf409de6d6a855a71c8af9e7290c4e55b
React-RuntimeHermes: 9d0812e3370111dd175aa1fa8bd4da93a9efc4fd
React-runtimescheduler: 0c80752bceb80924cb8a4babc2a8e3ed70d41e87
React-utils: a06061b3887c702235d2dac92dacbd93e1ea079e
ReactCommon: f00e436b3925a7ae44dfa294b43ef360fbd8ccc4
RNCAsyncStorage: 618d03a5f52fbccb3d7010076bc54712844c18ef
RNDateTimePicker: fc2e4f2795877d45e84d85659bebe627eba5c931
RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: 9b113eb9b7a4cbe66e1dbf4d9914281863ee0703
RNLocalize: 4222a3756cdbe2dc9a5bdf445765a4d2572107cb
RNReanimated: f4ff116e33e0afc3d127f70efe928847c7c66355
RNScreens: 23dad53fc9db1da2c93e647ae33fd7ce2bd49d60
RNSentry: 85fe1023bf60ead12d059d9c845de19de0ed6f0d
RNSVG: ba3e7232f45e34b7b47e74472386cf4e1a676d0a
React-RuntimeHermes: df3172370e3fbb593189afe23baa9c583cc6c853
React-runtimescheduler: 444c28666d8e9d275c600fe3a3cc7f014fa86406
React-utils: 595335727912553f56aad7f580254ce4ca95a09c
ReactCommon: 57d127dbf2ca045a07604e13f51c8e97ba176e56
RNCAsyncStorage: a03b770a50541a761447cea9c24536047832124d
RNDateTimePicker: 078355128345a5c07ec26ce51fd648d46678de97
RNFastImage: 462a183c4b0b6b26fdfd639e1ed6ba37536c3b87
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
RNGestureHandler: 293aea360e79439e2272b8a5ffebd582a1e4c486
RNLocalize: 4d11b58a95c6f8c77156911f7df9906f86f23c2c
RNReanimated: fe62058b0e1ecb46e252d63d27580f36cd6d9eb2
RNScreens: 5d770465a09cbb7cf83e2ad43d6f049b52e62bad
RNSentry: 95749b709b85c9da2015c3fd69978cda34f04df8
RNSVG: 6d5ed33b6635ed6d6ecb50744dcf127580c39ed5
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
Sentry: 9c1188876ea1291d1a9db4b38c3f17ebd8e6985e
@@ -1679,4 +1679,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: c602c315882be26f4a1eb7ed171506d9af16c238
COCOAPODS: 1.15.2
COCOAPODS: 1.16.2

63
package-lock.json generated
View File

@@ -1,17 +1,17 @@
{
"name": "fintunes",
"version": "2.4.1",
"version": "2.4.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "fintunes",
"version": "2.4.1",
"version": "2.4.3",
"hasInstallScript": true,
"dependencies": {
"@react-native-async-storage/async-storage": "^1.21.0",
"@react-native-community/blur": "^4.4.1",
"@react-native-community/datetimepicker": "^7.6.2",
"@react-native-community/datetimepicker": "^8.2.0",
"@react-native-community/netinfo": "^11.2.1",
"@react-navigation/bottom-tabs": "^6.5.12",
"@react-navigation/elements": "^1.3.22",
@@ -25,7 +25,7 @@
"fuse.js": "^7.0.0",
"i18n-js": "^4.3.2",
"lodash": "^4.17.21",
"mime-db": "^1.53.0",
"mime": "^4.0.6",
"react": "^18.2.0",
"react-airplay": "^1.2.0",
"react-native": "0.74.3",
@@ -59,7 +59,6 @@
"@sentry/react-native": "^5.26.0",
"@types/i18n-js": "^3.8.9",
"@types/lodash": "^4.14.202",
"@types/mime-db": "^1.43.5",
"@types/node": "^20.11.17",
"@types/react": "^18.2.55",
"@typescript-eslint/eslint-plugin": "^6.21.0",
@@ -2158,6 +2157,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-community/cli-tools/node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/@react-native-community/cli-tools/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -2251,11 +2262,26 @@
}
},
"node_modules/@react-native-community/datetimepicker": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.6.2.tgz",
"integrity": "sha512-ogZnvCmNG/lGHhEQypqz/mPymiIWD5jv6uKczg/l/aWgiKs1RDPQH1abh+R0I26aKoXmgamJJPuXKeC5eRWtZg==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.2.0.tgz",
"integrity": "sha512-qrUPhiBvKGuG9Y+vOqsc56RPFcHa1SU2qbAMT0hfGkoFIj3FodE0VuPVrEa8fgy7kcD5NQmkZIKgHOBLV0+hWg==",
"license": "MIT",
"dependencies": {
"invariant": "^2.2.4"
},
"peerDependencies": {
"expo": ">=50.0.0",
"react": "*",
"react-native": "*",
"react-native-windows": "*"
},
"peerDependenciesMeta": {
"expo": {
"optional": true
},
"react-native-windows": {
"optional": true
}
}
},
"node_modules/@react-native-community/netinfo": {
@@ -3785,13 +3811,6 @@
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
"dev": true
},
"node_modules/@types/mime-db": {
"version": "1.43.5",
"resolved": "https://registry.npmjs.org/@types/mime-db/-/mime-db-1.43.5.tgz",
"integrity": "sha512-/bfTiIUTNPUBnwnYvUxXAre5MhD88jgagLEQiQtIASjU+bwxd8kS/ASDA4a8ufd8m0Lheu6eeMJHEUpLHoJ28A==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "20.11.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz",
@@ -8414,14 +8433,18 @@
}
},
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-4.0.6.tgz",
"integrity": "sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A==",
"funding": [
"https://github.com/sponsors/broofa"
],
"license": "MIT",
"bin": {
"mime": "cli.js"
"mime": "bin/cli.js"
},
"engines": {
"node": ">=4.0.0"
"node": ">=16"
}
},
"node_modules/mime-db": {

View File

@@ -1,6 +1,6 @@
{
"name": "fintunes",
"version": "2.4.1",
"version": "2.4.3",
"main": "src/index.js",
"private": true,
"scripts": {
@@ -14,7 +14,7 @@
"dependencies": {
"@react-native-async-storage/async-storage": "^1.21.0",
"@react-native-community/blur": "^4.4.1",
"@react-native-community/datetimepicker": "^7.6.2",
"@react-native-community/datetimepicker": "^8.2.0",
"@react-native-community/netinfo": "^11.2.1",
"@react-navigation/bottom-tabs": "^6.5.12",
"@react-navigation/elements": "^1.3.22",
@@ -28,7 +28,7 @@
"fuse.js": "^7.0.0",
"i18n-js": "^4.3.2",
"lodash": "^4.17.21",
"mime-db": "^1.53.0",
"mime": "^4.0.6",
"react": "^18.2.0",
"react-airplay": "^1.2.0",
"react-native": "0.74.3",
@@ -62,7 +62,6 @@
"@sentry/react-native": "^5.26.0",
"@types/i18n-js": "^3.8.9",
"@types/lodash": "^4.14.202",
"@types/mime-db": "^1.43.5",
"@types/node": "^20.11.17",
"@types/react": "^18.2.55",
"@typescript-eslint/eslint-plugin": "^6.21.0",

View File

@@ -11,11 +11,11 @@ import Button from '@/components/Button';
import DownloadIcon from '@/components/DownloadIcon';
import styled from 'styled-components/native';
import { Text } from '@/components/Typography';
import FastImage from 'react-native-fast-image';
import { useGetImage } from '@/utility/JellyfinApi/lib';
import { ShadowWrapper } from '@/components/Shadow';
import { SafeFlatList } from '@/components/SafeNavigatorView';
import { t } from '@/localisation';
import BaseAlbumImage from '../Music/stacks/components/AlbumImage';
const DownloadedTrack = styled.View`
flex: 1 0 auto;
@@ -25,7 +25,7 @@ const DownloadedTrack = styled.View`
margin: 0 20px;
`;
const AlbumImage = styled(FastImage)`
const AlbumImage = styled(BaseAlbumImage)`
height: 32px;
width: 32px;
border-radius: 4px;

View File

@@ -1,6 +1,5 @@
import React, { useCallback, useContext, useEffect, useRef } from 'react';
import { ActivityIndicator, Animated, Dimensions, Platform, Pressable, View } from 'react-native';
import FastImage from 'react-native-fast-image';
import styled, { css } from 'styled-components/native';
import PlayIcon from '@/assets/icons/play.svg';
@@ -18,6 +17,7 @@ import { NavigationProp } from '@/screens/types';
import { ShadowWrapper } from '@/components/Shadow';
import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import AlbumImage from '../../stacks/components/AlbumImage';
export const NOW_PLAYING_POPOVER_MARGIN = 6;
export const NOW_PLAYING_POPOVER_WIDTH = Dimensions.get('screen').width - 2 * NOW_PLAYING_POPOVER_MARGIN;
@@ -62,7 +62,7 @@ const ShadowOverlay = styled.View`
bottom: 0;
`;
const Cover = styled(FastImage)`
const Cover = styled(AlbumImage)`
height: 32px;
width: 32px;
border-radius: 4px;

View File

@@ -9,7 +9,6 @@ import { FlatList } from 'react-native-gesture-handler';
import TouchableHandler from '@/components/TouchableHandler';
import { useNavigation } from '@react-navigation/native';
import { useGetImage } from '@/utility/JellyfinApi/lib';
import FastImage from 'react-native-fast-image';
import { t } from '@/localisation';
import useDefaultStyles, { ColoredBlurView } from '@/components/Colors';
import { searchAndFetchAlbums } from '@/store/music/actions';
@@ -22,6 +21,7 @@ import { ShadowWrapper } from '@/components/Shadow';
import { useKeyboardHeight } from '@/utility/useKeyboardHeight';
import { NavigationProp } from '@/screens/types';
import { useNavigationOffsets } from '@/components/SafeNavigatorView';
import BaseAlbumImage from '@/screens/Music/stacks/components/AlbumImage';
// import MicrophoneIcon from '@/assets/icons/microphone.svg';
// import AlbumIcon from '@/assets/icons/collection.svg';
// import TrackIcon from '@/assets/icons/note.svg';
@@ -52,7 +52,7 @@ const Loading = styled.View`
justify-content: center;
`;
const AlbumImage = styled(FastImage)`
const AlbumImage = styled(BaseAlbumImage)`
border-radius: 4px;
width: 32px;
height: 32px;

View File

@@ -22,13 +22,13 @@ const Info = styled.View`
flex-shrink: 1;
`;
const Label = styled(Text)<{ overflow?: boolean }>`
const Label = styled(Text)<{ $overflow?: boolean }>`
opacity: 0.5;
font-size: 13px;
${(props) => props?.overflow && css`
${(props) => props?.$overflow ? css`
flex: 0 1 auto;
`}
`: null}
`;
/**
@@ -51,7 +51,7 @@ export default function MediaInformation() {
<Container>
<WaveformIcon fill={styles.icon.color} height={16} width={16} />
<Info>
<Label numberOfLines={1} overflow>
<Label numberOfLines={1} $overflow>
{albumTrack.Codec?.isDirectPlay ? t('direct-play') : t('transcoded')}
</Label>
<Label numberOfLines={1}>

View File

@@ -7,8 +7,8 @@ import TimerIcon from '@/assets/icons/timer.svg';
import { setTimerDate } from '@/store/sleep-timer';
import ticksToDuration from '@/utility/ticksToDuration';
import useDefaultStyles from '@/components/Colors';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { t } from '@/localisation';
import { TouchableOpacity } from 'react-native';
const Container = styled.View`
align-self: flex-start;

View File

@@ -10,7 +10,7 @@ import { getExtensionForUrl } from '@/utility/mimeType';
export const downloadAdapter = createEntityAdapter<DownloadEntity>();
export const queueTrackForDownload = createAction<string>('download/queue');
export const initializeDownload = createAction<{ id: string, size?: number, jobId?: number, location: string, image: string }>('download/initialize');
export const initializeDownload = createAction<{ id: string, size?: number, jobId?: number, location: string, image?: string }>('download/initialize');
export const progressDownload = createAction<{ id: string, progress: number, jobId?: number }>('download/progress');
export const completeDownload = createAction<{ id: string, location: string, size?: number, image?: string }>('download/complete');
export const failDownload = createAction<{ id: string }>('download/fail');
@@ -25,12 +25,13 @@ export const downloadTrack = createAsyncThunk(
// Get the content-type from the URL by doing a HEAD-only request
const [audioExt, imageExt] = await Promise.all([
getExtensionForUrl(audioUrl),
getExtensionForUrl(imageUrl)
// Image files may be absent
getExtensionForUrl(imageUrl).catch(() => null)
]);
// Then generate the proper location
const audioLocation = `${DocumentDirectoryPath}/${id}.${audioExt}`;
const imageLocation = `${DocumentDirectoryPath}/${id}.${imageExt}`;
const imageLocation = imageExt ? `${DocumentDirectoryPath}/${id}.${imageExt}` : undefined;
// Actually kick off the download
const { promise: audioPromise } = downloadFile({
@@ -48,24 +49,26 @@ export const downloadTrack = createAsyncThunk(
toFile: audioLocation,
});
const { promise: imagePromise } = downloadFile({
fromUrl: imageUrl,
toFile: imageLocation,
background: true,
});
const { promise: imagePromise } = imageExt && imageLocation
? downloadFile({
fromUrl: imageUrl,
toFile: imageLocation,
background: true,
})
: { promise: Promise.resolve(null) };
// Await job completion
const [audioResult, imageResult] = await Promise.all([audioPromise, imagePromise]);
const totalSize = audioResult.bytesWritten + imageResult.bytesWritten;
const totalSize = audioResult.bytesWritten + (imageResult?.bytesWritten || 0);
dispatch(completeDownload({ id, location: audioLocation, size: totalSize, image: imageLocation }));
},
);
export const removeDownloadedTrack = createAsyncThunk(
'/downloads/remove/track',
async(id: string, { getState }) => {
async (id: string, { getState }) => {
// Retrieve the state
const { downloads: { entities }} = getState() as AppState;
const { downloads: { entities } } = getState() as AppState;
// Attempt to retrieve the entity from the state
const download = entities[id];

View File

@@ -1,8 +1,9 @@
import db from 'mime-db';
import mime from 'mime';
const MIME_OVERRIDES: Record<string, string> = {
'audio/mpeg': 'mp3',
'audio/ogg': '.ogg'
'audio/ogg': '.ogg',
'audio/flac': '.flac',
};
/**
@@ -12,6 +13,11 @@ export async function getExtensionForUrl(url: string) {
const response = await fetch(url, { method: 'HEAD' });
const contentType = response.headers.get('Content-Type');
// GUARD: Check that the request actually returned something
if (!response.ok) {
throw new Error('Failed to retrieve extension for URL: ' + response.statusText);
}
// GUARD: Check that we received a content type
if (!contentType) {
throw new Error('Jellyfin did not return a Content-Type for a streaming URL.');
@@ -23,21 +29,20 @@ export async function getExtensionForUrl(url: string) {
}
// Alternatively, retrieve it from mime-db
const extensions = db[contentType]?.extensions;
const extension = mime.getExtension(contentType);
// GUARD: Check that we received an extension
if (!extensions?.length) {
if (!extension) {
console.error({ contentType, extension, url });
throw new Error(`Unsupported MIME-type ${contentType}`);
}
return extensions[0];
return extension;
}
/**
* Find a mime type by its extension
*/
export function getMimeTypeForExtension(extension: string) {
return Object.keys(db).find((type) => {
return db[type].extensions?.includes(extension);
});
return mime.getType(extension);
}