diff --git a/README.md b/README.md
index 949f7a1..7757a22 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
#
Subtracks is an Android open source music streaming app for [Subsonic-API-compatible](http://www.subsonic.org/pages/api.jsp) servers ([Subsonic](http://www.subsonic.org/pages/index.jsp), [Navidrome](https://www.navidrome.org/), [Airsonic](https://airsonic.github.io/), and more). It's designed to give you clean and convenient access to your music in the style of modern media players.
+[](https://hosted.weblate.org/engage/subtracks/)   
+
# Screenshots
@@ -45,3 +47,10 @@ Subtracks is an Android open source music streaming app for [Subsonic-API-compat
# Building
See [Building from source](BUILDING.md).
+
+# Translations
+Want to see Subtracks in your language? Visit the project on [Weblate](https://hosted.weblate.org/engage/subtracks/) to help!
+
+
+
+
diff --git a/android/app/src/main/assets/custom/i18n/en.json b/android/app/src/main/assets/custom/i18n/en.json
new file mode 100644
index 0000000..74f5f08
--- /dev/null
+++ b/android/app/src/main/assets/custom/i18n/en.json
@@ -0,0 +1,151 @@
+{
+ "resources": {
+ "song": {
+ "name": "Song",
+ "name_plural": "Songs",
+ "lists": {
+ "artistTopSongs": "Top Songs"
+ }
+ },
+ "album": {
+ "name": "Album",
+ "name_plural": "Albums",
+ "lists": {
+ "sort": "Sort Albums",
+ "random": "Random",
+ "newest": "Recently Added",
+ "frequent": "Frequently Played",
+ "recent": "Recently Played",
+ "starred": "Starred",
+ "alphabeticalByName": "By Name",
+ "alphabeticalByArtist": "By Artist",
+ "byYear": "By Year",
+ "byGenre": "By Genre"
+ },
+ "actions": {
+ "play": "Play Album",
+ "view": "View Album"
+ }
+ },
+ "artist": {
+ "name": "Artist",
+ "name_plural": "Artists",
+ "lists": {
+ "sort": "Sort Artists",
+ "random": "Random",
+ "starred": "Starred",
+ "alphabeticalByName": "By Name"
+ },
+ "actions": {
+ "view": "View Artist"
+ }
+ },
+ "playlist": {
+ "name": "Playlist",
+ "name_plural": "Playlists",
+ "actions": {
+ "play": "Play Playlist"
+ }
+ },
+ "queue": {
+ "name": "Queue",
+ "name_plural": "Queues"
+ }
+ },
+ "context": {
+ "actions": {
+ "star": "Star",
+ "unstar": "Unstar"
+ }
+ },
+ "navigation": {
+ "tabs": {
+ "home": "Home",
+ "library": "Library",
+ "search": "Search",
+ "settings": "Settings"
+ }
+ },
+ "messages": {
+ "nothingHere": "Nothing here…"
+ },
+ "search": {
+ "inputPlaceholder": "Search",
+ "headerTitle": "Search: {{query}}",
+ "moreResults": "More…",
+ "nowPlayingContext": "Search Results"
+ },
+ "settings": {
+ "servers": {
+ "name": "Servers",
+ "fields": {
+ "address": "Address",
+ "username": "Username",
+ "password": "Password"
+ },
+ "options": {
+ "forcePlaintextPassword": {
+ "title": "Force plaintext password",
+ "descriptionOn": "Send password in plaintext (legacy, make sure your connection is secure!)",
+ "descriptionOff": "Send password as token + salt"
+ }
+ },
+ "actions": {
+ "add": "Add Server",
+ "testConnection": "Test Connection",
+ "delete": "Delete",
+ "save": "Save"
+ },
+ "messages": {
+ "connectionOk": "Connection to {{address}} OK!",
+ "connectionFailed": "Connection to {{address}} failed, check settings or server"
+ }
+ },
+ "network": {
+ "name": "Network",
+ "values": {
+ "kbps": "{{value}}kbps",
+ "unlimitedKbps": "Unlimited",
+ "seconds": "{{value}} seconds"
+ },
+ "options": {
+ "maxBitrateWifi": {
+ "title": "Maximum bitrate (Wi-Fi)"
+ },
+ "maxBitrateMobile": {
+ "title": "Maximum bitrate (mobile)"
+ },
+ "minBuffer": {
+ "title": "Minimum buffer time"
+ },
+ "maxBuffer": {
+ "title": "Maximum buffer time"
+ }
+ }
+ },
+ "music": {
+ "name": "Music",
+ "options": {
+ "scrobble": {
+ "title": "Scrobble plays",
+ "descriptionOn": "Scrobble play history",
+ "descriptionOff": "Don't scrobble play history"
+ }
+ }
+ },
+ "reset": {
+ "name": "Reset",
+ "actions": {
+ "clearImageCache": "Clear Image Cache"
+ }
+ },
+ "about": {
+ "name": "About",
+ "version": "version {{version}}",
+ "actions": {
+ "projectHomepage": "Project Homepage",
+ "licenses": "Licenses"
+ }
+ }
+ }
+}
diff --git a/android/app/src/main/assets/custom/i18n/fr.json b/android/app/src/main/assets/custom/i18n/fr.json
new file mode 100644
index 0000000..4588807
--- /dev/null
+++ b/android/app/src/main/assets/custom/i18n/fr.json
@@ -0,0 +1,151 @@
+{
+ "resources": {
+ "album": {
+ "name": "Album",
+ "name_plural": "Albums",
+ "lists": {
+ "random": "Aléatoire",
+ "newest": "Récemment Ajouté",
+ "frequent": "Fréquemment Joué",
+ "recent": "Récemment Joué",
+ "alphabeticalByName": "Par Nom",
+ "byYear": "Par Année",
+ "alphabeticalByArtist": "Par Artiste",
+ "byGenre": "Par Genre",
+ "starred": "Favoris",
+ "sort": "Trier les albums"
+ },
+ "actions": {
+ "play": "Jouer l'album",
+ "view": "Voir l'album"
+ }
+ },
+ "song": {
+ "name": "Chanson",
+ "name_plural": "Chansons",
+ "lists": {
+ "artistTopSongs": "Meilleures Chansons"
+ }
+ },
+ "artist": {
+ "name": "Artiste",
+ "name_plural": "Artistes",
+ "lists": {
+ "random": "Aléatoire",
+ "starred": "Favoris",
+ "alphabeticalByName": "Par Nom",
+ "sort": "Trier les artistes"
+ },
+ "actions": {
+ "view": "Voir l'artiste"
+ }
+ },
+ "playlist": {
+ "actions": {
+ "play": "Lire la playlist"
+ },
+ "name": "Playlist",
+ "name_plural": "Playlists"
+ },
+ "queue": {
+ "name": "File d'attente",
+ "name_plural": "Files d'attente"
+ }
+ },
+ "settings": {
+ "network": {
+ "values": {
+ "seconds": "{{value}} secondes",
+ "unlimitedKbps": "Illimité",
+ "kbps": "{{value}}kbit/s"
+ },
+ "options": {
+ "maxBitrateWifi": {
+ "title": "Débit binaire maximum (Wi-Fi)"
+ },
+ "maxBitrateMobile": {
+ "title": "Débit binaire maximum (mobile)"
+ },
+ "maxBuffer": {
+ "title": "Temps maximum en mémoire tampon"
+ },
+ "minBuffer": {
+ "title": "Temps minimum en mémoire tampon"
+ }
+ },
+ "name": "Réseau"
+ },
+ "servers": {
+ "fields": {
+ "username": "Nom d'utilisateur",
+ "address": "Adresse",
+ "password": "Mot de passe"
+ },
+ "actions": {
+ "testConnection": "Tester la connexion",
+ "add": "Ajouter un serveur",
+ "delete": "Supprimer",
+ "save": "Sauvegarder"
+ },
+ "name": "Serveurs",
+ "options": {
+ "forcePlaintextPassword": {
+ "title": "Forcer le mot de passe en texte clair",
+ "descriptionOn": "Envoyer le mot de passe en test clair (héritage, assurez-vous que la connexion est sécurisée !)",
+ "descriptionOff": "Envoyer le mot de passe sous forme de jeton + salage"
+ }
+ },
+ "messages": {
+ "connectionOk": "Connexion à {{address}} OK !",
+ "connectionFailed": "Échec de la connexion à {{address}}, vérifiez les paramètres ou le serveur"
+ }
+ },
+ "music": {
+ "name": "Musique",
+ "options": {
+ "scrobble": {
+ "descriptionOff": "Ne pas scrobbler l'historique de lecture",
+ "descriptionOn": "Scrobbler l'historique de lecture",
+ "title": "Scrobbler la lecture"
+ }
+ }
+ },
+ "about": {
+ "version": "version {{version}}",
+ "name": "À propos",
+ "actions": {
+ "licenses": "Licenses",
+ "projectHomepage": "Page d'accueil du projet"
+ }
+ },
+ "reset": {
+ "actions": {
+ "clearImageCache": "Vider le cache d'images"
+ },
+ "name": "Réinitialiser"
+ }
+ },
+ "navigation": {
+ "tabs": {
+ "library": "Bibliothèque",
+ "home": "Accueil",
+ "search": "Recherche",
+ "settings": "Paramètres"
+ }
+ },
+ "search": {
+ "headerTitle": "Recherche : {{query}}",
+ "inputPlaceholder": "Recherche",
+ "moreResults": "Plus…",
+ "nowPlayingContext": "Résultats de recherche"
+ },
+ "context": {
+ "actions": {
+ "star": "Mettre en favoris",
+ "unstar": "Enlever des favoris"
+ }
+ },
+ "messages": {
+ "nothingHere": "Rien ici…"
+ }
+}
diff --git a/android/app/src/main/assets/custom/i18n/ja.json b/android/app/src/main/assets/custom/i18n/ja.json
new file mode 100644
index 0000000..b894777
--- /dev/null
+++ b/android/app/src/main/assets/custom/i18n/ja.json
@@ -0,0 +1,15 @@
+{
+ "resources": {
+ "album": {
+ "lists": {
+ "random": "ランダムアルバム",
+ "frequent": "よく聴くアルバム",
+ "recent": "最近再生した",
+ "starred": "星付きアルバム"
+ }
+ },
+ "song": {
+ "name": "歌"
+ }
+ }
+}
diff --git a/android/app/src/main/assets/custom/i18n/nb_NO.json b/android/app/src/main/assets/custom/i18n/nb_NO.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/android/app/src/main/assets/custom/i18n/nb_NO.json
@@ -0,0 +1 @@
+{}
diff --git a/android/app/src/main/assets/licenses.html b/android/app/src/main/assets/licenses.html
index 10a3be8..96563a8 100644
--- a/android/app/src/main/assets/licenses.html
+++ b/android/app/src/main/assets/licenses.html
@@ -27165,6 +27165,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
+The following software may be included in this product: html-escaper. A copy of the source code may be downloaded from https://github.com/WebReflection/html-escaper.git. This software contains the following license and notice below:
+
+Copyright (C) 2017-present by Andrea Giammarchi - @WebReflection
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+-----
+
The following software may be included in this product: http-errors. A copy of the source code may be downloaded from https://github.com/jshttp/http-errors.git. This software contains the following license and notice below:
The MIT License (MIT)
@@ -27192,6 +27216,32 @@ THE SOFTWARE.
-----
+The following software may be included in this product: i18next. A copy of the source code may be downloaded from https://github.com/i18next/i18next.git. This software contains the following license and notice below:
+
+The MIT License (MIT)
+
+Copyright (c) 2022 i18next
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: ieee754. A copy of the source code may be downloaded from git://github.com/feross/ieee754.git. This software contains the following license and notice below:
Copyright 2008 Fair Oaks Labs, Inc.
@@ -29386,6 +29436,32 @@ SOFTWARE.
-----
+The following software may be included in this product: react-i18next. A copy of the source code may be downloaded from https://github.com/i18next/react-i18next.git. This software contains the following license and notice below:
+
+The MIT License (MIT)
+
+Copyright (c) 2022 i18next
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: react-native-blob-util. A copy of the source code may be downloaded from https://github.com/RonRadtke/react-native-blob-util. This software contains the following license and notice below:
MIT License
@@ -29542,6 +29618,32 @@ SOFTWARE.
-----
+The following software may be included in this product: react-native-localize. A copy of the source code may be downloaded from https://github.com/zoontek/react-native-localize.git. This software contains the following license and notice below:
+
+MIT License
+
+Copyright (c) 2017-present, Mathieu Acthernoene
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: react-native-popup-menu. A copy of the source code may be downloaded from git+ssh://git@github.com:instea/react-native-popup-menu.git. This software contains the following license and notice below:
ISC License
@@ -31559,6 +31661,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-----
+The following software may be included in this product: void-elements. A copy of the source code may be downloaded from https://github.com/pugjs/void-elements.git. This software contains the following license and notice below:
+
+(The MIT License)
+
+Copyright (c) 2014 hemanth
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-----
+
The following software may be included in this product: walker. A copy of the source code may be downloaded from https://github.com/daaku/nodejs-walker. This software contains the following license and notice below:
Copyright 2013 Naitik Shah
diff --git a/android/app/src/main/assets/licenses/npm.txt b/android/app/src/main/assets/licenses/npm.txt
index 7465c4b..7373ba8 100644
--- a/android/app/src/main/assets/licenses/npm.txt
+++ b/android/app/src/main/assets/licenses/npm.txt
@@ -3863,6 +3863,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
+The following software may be included in this product: html-escaper. A copy of the source code may be downloaded from https://github.com/WebReflection/html-escaper.git. This software contains the following license and notice below:
+
+Copyright (C) 2017-present by Andrea Giammarchi - @WebReflection
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+-----
+
The following software may be included in this product: http-errors. A copy of the source code may be downloaded from https://github.com/jshttp/http-errors.git. This software contains the following license and notice below:
The MIT License (MIT)
@@ -3890,6 +3914,32 @@ THE SOFTWARE.
-----
+The following software may be included in this product: i18next. A copy of the source code may be downloaded from https://github.com/i18next/i18next.git. This software contains the following license and notice below:
+
+The MIT License (MIT)
+
+Copyright (c) 2022 i18next
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: ieee754. A copy of the source code may be downloaded from git://github.com/feross/ieee754.git. This software contains the following license and notice below:
Copyright 2008 Fair Oaks Labs, Inc.
@@ -6084,6 +6134,32 @@ SOFTWARE.
-----
+The following software may be included in this product: react-i18next. A copy of the source code may be downloaded from https://github.com/i18next/react-i18next.git. This software contains the following license and notice below:
+
+The MIT License (MIT)
+
+Copyright (c) 2022 i18next
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: react-native-blob-util. A copy of the source code may be downloaded from https://github.com/RonRadtke/react-native-blob-util. This software contains the following license and notice below:
MIT License
@@ -6240,6 +6316,32 @@ SOFTWARE.
-----
+The following software may be included in this product: react-native-localize. A copy of the source code may be downloaded from https://github.com/zoontek/react-native-localize.git. This software contains the following license and notice below:
+
+MIT License
+
+Copyright (c) 2017-present, Mathieu Acthernoene
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+-----
+
The following software may be included in this product: react-native-popup-menu. A copy of the source code may be downloaded from git+ssh://git@github.com:instea/react-native-popup-menu.git. This software contains the following license and notice below:
ISC License
@@ -8257,6 +8359,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-----
+The following software may be included in this product: void-elements. A copy of the source code may be downloaded from https://github.com/pugjs/void-elements.git. This software contains the following license and notice below:
+
+(The MIT License)
+
+Copyright (c) 2014 hemanth
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-----
+
The following software may be included in this product: walker. A copy of the source code may be downloaded from https://github.com/daaku/nodejs-walker. This software contains the following license and notice below:
Copyright 2013 Naitik Shah
diff --git a/android/app/src/main/java/com/subtracks/MainActivity.java b/android/app/src/main/java/com/subtracks/MainActivity.java
index 8b2893c..838a88b 100644
--- a/android/app/src/main/java/com/subtracks/MainActivity.java
+++ b/android/app/src/main/java/com/subtracks/MainActivity.java
@@ -14,6 +14,9 @@ public class MainActivity extends ReactActivity {
return "subtracks";
}
+ // required by react-native-screens
+ // "This change is required to avoid crashes related to View state being not persisted consistently across Activity restarts."
+ // https://reactnavigation.org/docs/getting-started
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
diff --git a/app/App.tsx b/app/App.tsx
index bfe7ab4..5865b0d 100644
--- a/app/App.tsx
+++ b/app/App.tsx
@@ -2,12 +2,12 @@ import RootNavigator from '@app/navigation/RootNavigator'
import SplashPage from '@app/screens/SplashPage'
import colors from '@app/styles/colors'
import React from 'react'
-import { StatusBar, View, StyleSheet } from 'react-native'
-import ProgressHook from './components/ProgressHook'
-import { useStore } from './state/store'
+import { StatusBar, StyleSheet, View } from 'react-native'
import { MenuProvider } from 'react-native-popup-menu'
import { QueryClientProvider } from 'react-query'
+import ProgressHook from './components/ProgressHook'
import queryClient from './queryClient'
+import { useStore } from './state/store'
const Debug = () => {
const currentTrackTitle = useStore(store => store.currentTrack?.title)
diff --git a/app/components/Button.tsx b/app/components/Button.tsx
index 7ed49af..b98422c 100644
--- a/app/components/Button.tsx
+++ b/app/components/Button.tsx
@@ -16,7 +16,13 @@ const Button: React.FC<{
onPress={onPress}
disabled={disabled}
style={[styles.container, buttonStyle !== undefined ? styles[buttonStyle] : {}, style]}>
- {title ? {title} : children}
+ {title ? (
+
+ {title}
+
+ ) : (
+ children
+ )}
)
}
@@ -26,6 +32,7 @@ const styles = StyleSheet.create({
backgroundColor: colors.accent,
paddingHorizontal: 10,
minHeight: 42,
+ maxHeight: 42,
justifyContent: 'center',
borderRadius: 1000,
},
@@ -43,6 +50,7 @@ const styles = StyleSheet.create({
fontFamily: font.bold,
color: colors.text.primary,
paddingHorizontal: 14,
+ textAlign: 'center',
},
})
diff --git a/app/components/ContextMenu.tsx b/app/components/ContextMenu.tsx
index 9d0649a..b8ff6a4 100644
--- a/app/components/ContextMenu.tsx
+++ b/app/components/ContextMenu.tsx
@@ -6,12 +6,14 @@ import font from '@app/styles/font'
import { NavigationProp, useNavigation } from '@react-navigation/native'
import { ReactComponentLike } from 'prop-types'
import React from 'react'
+import { useTranslation } from 'react-i18next'
import { ScrollView, StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native'
import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from 'react-native-popup-menu'
import IconFA from 'react-native-vector-icons/FontAwesome'
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
import CoverArt from './CoverArt'
import { Star } from './Star'
+import { withSuspenseMemo } from './withSuspense'
const { SlideInMenu } = renderers
@@ -106,7 +108,9 @@ const ContextMenuIconTextOption = React.memo(
return (
{Icon}
- {text}
+
+ {text}
+
)
},
@@ -154,27 +158,30 @@ const MenuHeader = React.memo<{
))
-const OptionStar = React.memo<{
+const OptionStar = withSuspenseMemo<{
id: string
type: StarrableItemType
additionalText?: string
}>(({ id, type, additionalText: text }) => {
const { query, toggle } = useStar(id, type)
+ const { t } = useTranslation('context.actions')
return (
}
- text={(query.data ? 'Unstar' : 'Star') + (text ? ` ${text}` : '')}
+ text={(query.data ? t('unstar') : t('star')) + (text ? ` ${text}` : '')}
onSelect={() => toggle.mutate()}
/>
)
})
-const OptionViewArtist = React.memo<{
+const OptionViewArtist = withSuspenseMemo<{
navigation: NavigationProp
artist?: string
artistId?: string
}>(({ navigation, artist, artistId }) => {
+ const { t } = useTranslation('resources.artist.actions')
+
if (!artist || !artistId) {
return <>>
}
@@ -184,17 +191,19 @@ const OptionViewArtist = React.memo<{
IconComponent={IconFA}
name="microphone"
size={26}
- text="View Artist"
+ text={t('view')}
onSelect={() => navigation.navigate('artist', { id: artistId, title: artist })}
/>
)
})
-const OptionViewAlbum = React.memo<{
+const OptionViewAlbum = withSuspenseMemo<{
navigation: NavigationProp
album?: string
albumId?: string
}>(({ navigation, album, albumId }) => {
+ const { t } = useTranslation('resources.album.actions')
+
if (!album || !albumId) {
return <>>
}
@@ -204,7 +213,7 @@ const OptionViewAlbum = React.memo<{
IconComponent={IconFA5}
name="compact-disc"
size={26}
- text="View Album"
+ text={t('view')}
onSelect={() => navigation.navigate('album', { id: albumId, title: album })}
/>
)
@@ -318,6 +327,8 @@ const styles = StyleSheet.create({
},
optionsWrapper: {
// marginBottom: 10,
+ paddingHorizontal: 20,
+ // backgroundColor: 'purple',
},
menuHeader: {
paddingTop: 14,
@@ -348,9 +359,11 @@ const styles = StyleSheet.create({
},
option: {
paddingVertical: 8,
- paddingHorizontal: 20,
+ // paddingHorizontal: 100,
flexDirection: 'row',
alignItems: 'center',
+ // backgroundColor: 'blue',
+ overflow: 'hidden',
},
icon: {
marginRight: 10,
diff --git a/app/components/FilterButton.tsx b/app/components/FilterButton.tsx
index 17f4c56..3871684 100644
--- a/app/components/FilterButton.tsx
+++ b/app/components/FilterButton.tsx
@@ -1,10 +1,13 @@
import colors from '@app/styles/colors'
import font from '@app/styles/font'
import React from 'react'
-import { Text, StyleSheet } from 'react-native'
-import { MenuOption, Menu, MenuTrigger, MenuOptions } from 'react-native-popup-menu'
+import { Text, StyleSheet, View } from 'react-native'
+import { MenuOption, Menu, MenuTrigger, MenuOptions, renderers } from 'react-native-popup-menu'
import PressableOpacity from './PressableOpacity'
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
+import { ScrollView } from 'react-native-gesture-handler'
+
+const { SlideInMenu } = renderers
export type OptionData = {
value: string
@@ -17,12 +20,14 @@ const Option = React.memo<{
selected?: boolean
}>(({ text, value, selected }) => (
- {text}
{selected ? (
-
+
) : (
-
+
)}
+
+ {text}
+
))
@@ -30,9 +35,10 @@ const FilterButton = React.memo<{
value?: string
data: OptionData[]
onSelect?: (selection: string) => void
-}>(({ value, data, onSelect }) => {
+ title: string
+}>(({ value, data, onSelect, title }) => {
return (
-