From ff23bf171db6b78f83158ddd4a3e772364cd60fc Mon Sep 17 00:00:00 2001 From: Violet Caulfield Date: Sun, 21 Dec 2025 19:30:56 -0600 Subject: [PATCH] asdf --- App.tsx | 2 +- android/app/src/main/res/values/styles.xml | 2 +- bun.lock | 82 ++++++++--- ios/Podfile.lock | 130 ++++++++++++++++++ package.json | 12 +- src/components/Album/footer.tsx | 11 +- src/components/Album/header.tsx | 2 +- src/components/Album/index.tsx | 2 +- src/components/Albums/component.tsx | 6 +- src/components/Artist/header.tsx | 4 +- src/components/Artist/similar.tsx | 6 +- src/components/Artists/component.tsx | 6 +- .../components/delete-playlist-row.tsx | 2 +- .../Context/components/multiple-artists.tsx | 5 +- src/components/Context/index.tsx | 2 +- src/components/Context/utils/navigation.ts | 2 +- .../Discover/helpers/just-added.tsx | 9 +- .../Discover/helpers/public-playlists.tsx | 8 +- .../Discover/helpers/suggested-artists.tsx | 9 +- src/components/Global/components/item-row.tsx | 2 +- src/components/Global/components/track.tsx | 2 +- .../Home/helpers/frequent-artists.tsx | 9 +- .../Home/helpers/frequent-tracks.tsx | 9 +- .../Home/helpers/recent-artists.tsx | 11 +- .../Home/helpers/recently-played.tsx | 9 +- .../Library/components/tracks-tab.tsx | 4 +- src/components/Player/components/footer.tsx | 4 +- src/components/Player/components/header.tsx | 2 +- .../Player/components/quality-badge.tsx | 2 +- .../Player/components/song-info.tsx | 2 +- src/components/Player/mini-player.tsx | 6 +- src/components/Playlist/components/header.tsx | 6 +- src/components/Playlist/index.tsx | 14 +- src/components/Playlists/component.tsx | 4 +- src/components/Search/suggestions.tsx | 6 +- .../Settings/components/account-tab.tsx | 6 +- .../Settings/components/usage-tab.tsx | 7 +- src/components/theme.ts | 8 +- navigation.ts => src/navigation/ref.ts | 2 +- src/providers/Player/hooks/mutations.ts | 41 +++--- src/screens/Discover/index.tsx | 6 + src/screens/Home/index.tsx | 6 + src/screens/Library/index.tsx | 6 + src/screens/Login/server-library.tsx | 7 +- src/screens/Player/index.tsx | 6 + src/screens/Search/index.tsx | 6 + src/screens/Settings/index.tsx | 6 + src/screens/Settings/sign-out-modal.tsx | 8 +- src/screens/Tabs/index.tsx | 122 +++++++++------- src/screens/index.tsx | 11 +- 50 files changed, 413 insertions(+), 229 deletions(-) rename navigation.ts => src/navigation/ref.ts (75%) diff --git a/App.tsx b/App.tsx index 367c3326..86df4136 100644 --- a/App.tsx +++ b/App.tsx @@ -23,7 +23,7 @@ import { requestStoragePermission } from './src/utils/permisson-helpers' import ErrorBoundary from './src/components/ErrorBoundary' import OTAUpdateScreen from './src/components/OtaUpdates' import { usePerformanceMonitor } from './src/hooks/use-performance-monitor' -import navigationRef from './navigation' +import navigationRef from './src/navigation/ref' import { BUFFERS, PROGRESS_UPDATE_EVENT_INTERVAL } from './src/player/config' import { useThemeSetting } from './src/stores/settings/app' diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 7ba83a2a..617a309a 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - diff --git a/bun.lock b/bun.lock index 9949f111..eb6bc711 100644 --- a/bun.lock +++ b/bun.lock @@ -5,16 +5,19 @@ "": { "name": "jellify", "dependencies": { + "@bottom-tabs/react-navigation": "^1.1.0", + "@callstack/liquid-glass": "^0.7.0", "@jellyfin/sdk": "0.13.0", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-community/cli": "20.0.0", "@react-native-community/netinfo": "^11.4.1", "@react-native-masked-view/masked-view": "^0.3.2", + "@react-native-vector-icons/get-image": "^12.3.0", "@react-native-vector-icons/material-design-icons": "12.4.0", - "@react-navigation/bottom-tabs": "7.9.0", - "@react-navigation/material-top-tabs": "7.4.11", - "@react-navigation/native": "7.1.26", - "@react-navigation/native-stack": "7.9.0", + "@react-navigation/bottom-tabs": "8.0.0-alpha.0", + "@react-navigation/material-top-tabs": "8.0.0-alpha.0", + "@react-navigation/native": "8.0.0-alpha.0", + "@react-navigation/native-stack": "8.0.0-alpha.0", "@sentry/react-native": "7.8.0", "@shopify/flash-list": "2.2.0", "@tamagui/config": "1.141.4", @@ -34,6 +37,7 @@ "react-native-background-actions": "^4.0.1", "react-native-blob-util": "^0.22.2", "react-native-blurhash": "^2.1.3", + "react-native-bottom-tabs": "^1.1.0", "react-native-carplay": "^2.4.1-beta.0", "react-native-config": "1.5.6", "react-native-device-info": "15.0.1", @@ -356,6 +360,10 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], + "@bottom-tabs/react-navigation": ["@bottom-tabs/react-navigation@1.1.0", "", { "dependencies": { "color": "^5.0.0" }, "peerDependencies": { "@react-navigation/native": ">=7", "react": "*", "react-native": "*", "react-native-bottom-tabs": "*" } }, "sha512-+4YppCodABcSNIgJiq95QUQ+3ClVBG+rLG3WmYI0+/nbxqKbCz6luFBep4KFOj98Iplj1JY2Ki6ix8CcOZVQ/Q=="], + + "@callstack/liquid-glass": ["@callstack/liquid-glass@0.7.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-ztPuQnXG3z9kPWT0srf+yIbVZih/aifbynzormDzsFMWR6IQk3e0h8DEYic3sgW7PUa7A/GyaBBCpq10ZZvboA=="], + "@egjs/hammerjs": ["@egjs/hammerjs@2.0.17", "", { "dependencies": { "@types/hammerjs": "^2.0.36" } }, "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A=="], "@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], @@ -528,6 +536,8 @@ "@react-native-vector-icons/common": ["@react-native-vector-icons/common@12.4.0", "", { "dependencies": { "find-up": "^7.0.0", "picocolors": "^1.1.1", "plist": "^3.1.0" }, "peerDependencies": { "@react-native-vector-icons/get-image": "^12.3.0", "react": "*", "react-native": "*" }, "optionalPeers": ["@react-native-vector-icons/get-image"], "bin": { "rnvi-update-plist": "lib/commonjs/scripts/updatePlist.js" } }, "sha512-t9W0q+AW7WH1Oj5aEg7wGNXDLZJb5sIVkAWo5qtad3PcbBADqoCdikRK/ToLK+xlB0TxjcuL0T74ogudMkYGeA=="], + "@react-native-vector-icons/get-image": ["@react-native-vector-icons/get-image@12.3.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-ch9mwFWePde7AR0DfhcuNDeMH7N/vLPvoiJbqm28oeJPnCS6XA98F5GPwpMO9IE/omTv2RYwBTmhMA+8Wlwv/A=="], + "@react-native-vector-icons/material-design-icons": ["@react-native-vector-icons/material-design-icons@12.4.0", "", { "dependencies": { "@react-native-vector-icons/common": "^12.4.0" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-4ewAiHdOCujqprUJYFnBcUJduNddAc+w3Plnl1NhJksAyOaHzCNBg01JgVtkysxPho6++OOMge3FhwyBT8Wtcg=="], "@react-native/assets-registry": ["@react-native/assets-registry@0.83.0", "", {}, "sha512-EmGSKDvmnEnBrTK75T+0Syt6gy/HACOTfziw5+392Kr1Bb28Rv26GyOIkvptnT+bb2VDHU0hx9G0vSy5/S3rmQ=="], @@ -566,19 +576,19 @@ "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.83.0", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "*" }, "optionalPeers": ["@types/react"] }, "sha512-AVnDppwPidQrPrzA4ETr4o9W+40yuijg3EVgFt2hnMldMZkqwPRrgJL2GSreQjCYe1NfM5Yn4Egyy4Kd0yp4Lw=="], - "@react-navigation/bottom-tabs": ["@react-navigation/bottom-tabs@7.9.0", "", { "dependencies": { "@react-navigation/elements": "^2.9.3", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { "@react-navigation/native": "^7.1.26", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-024FWdHp3ZsE5rP8tmGI4vh+1z3wg8u8E9Frep8eeGoYo1h9rQhvgofQDGxknmrKsb7t8o8Dim+IZSvl57cPFQ=="], + "@react-navigation/bottom-tabs": ["@react-navigation/bottom-tabs@8.0.0-alpha.0", "", { "dependencies": { "@react-navigation/elements": "^3.0.0-alpha.0", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { "@react-navigation/native": "^8.0.0-alpha.0", "react": ">= 19.0.0", "react-native": "*", "react-native-safe-area-context": ">= 5.5.0", "react-native-screens": ">= 4.19.0" } }, "sha512-3RN9XkCIaB+YsLU+YBhqdhWs3Q1yV++YBLQJPWNku5tfxI3gszHrMNS0IK3EMjK2VQPmyEhFnnJFynjtkdCAYQ=="], - "@react-navigation/core": ["@react-navigation/core@7.13.7", "", { "dependencies": { "@react-navigation/routers": "^7.5.3", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-k2ABo3250vq1ovOh/iVwXS6Hwr5PVRGXoPh/ewVFOOuEKTvOx9i//OBzt8EF+HokBxS2HBRlR2b+aCOmscRqBw=="], + "@react-navigation/core": ["@react-navigation/core@8.0.0-alpha.0", "", { "dependencies": { "@react-navigation/routers": "^8.0.0-alpha.0", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.3.2", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 19.0.0" } }, "sha512-xhFfK8H/x6mR/VRWtytGVwipNS8yvwpsV3EJ7pN1x1kHydm8cc4BN3e4UIHxFGYJpgHL6336KCTdpX18/GkfEQ=="], - "@react-navigation/elements": ["@react-navigation/elements@2.9.3", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.26", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-3+eyvWiVPIEf6tN9UdduhOEHcTuNe3R5WovgiVkfH9+jApHMTZDc2loePTpY/i2HDJhObhhChpJzO6BVjrpdYQ=="], + "@react-navigation/elements": ["@react-navigation/elements@3.0.0-alpha.0", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.3.2", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@callstack/liquid-glass": ">= 0.6.0", "@react-navigation/native": "^8.0.0-alpha.0", "react": ">= 19.0.0", "react-native": "*", "react-native-safe-area-context": ">= 5.5.0", "react-native-screens": ">= 4.19.0" } }, "sha512-lKaWPec0rG3xYf8pmsv6AwZDtupJl/6gfxzHsRHE1/Jb++/gFDUhYNYYderCOzxuQqtgCwo8ubDnrwO0y72s4Q=="], - "@react-navigation/material-top-tabs": ["@react-navigation/material-top-tabs@7.4.11", "", { "dependencies": { "@react-navigation/elements": "^2.9.3", "color": "^4.2.3", "react-native-tab-view": "^4.2.2" }, "peerDependencies": { "@react-navigation/native": "^7.1.26", "react": ">= 18.2.0", "react-native": "*", "react-native-pager-view": ">= 6.0.0", "react-native-safe-area-context": ">= 4.0.0" } }, "sha512-RSC/f1bSpodnx1oSXw7jNrwe83JddRhb12ehCY8oZZDtrNhm3atSHzlfvHN37i3E8cln7Tmc1ieLxjWrU65n/Q=="], + "@react-navigation/material-top-tabs": ["@react-navigation/material-top-tabs@8.0.0-alpha.0", "", { "dependencies": { "@react-navigation/elements": "^3.0.0-alpha.0", "color": "^4.2.3", "react-native-tab-view": "^5.0.0-alpha.0" }, "peerDependencies": { "@react-navigation/native": "^8.0.0-alpha.0", "react": ">= 19.0.0", "react-native": "*", "react-native-pager-view": ">= 7.0.0", "react-native-safe-area-context": ">= 5.5.0" } }, "sha512-xZ1tuJ++3FS1EFW7zyOiBSoT1wWIqu/Bb/qhryDptO4Yo++tssbREKo+A+pI4N+vhhnoBu9RTvEPy3NA0blBtg=="], - "@react-navigation/native": ["@react-navigation/native@7.1.26", "", { "dependencies": { "@react-navigation/core": "^7.13.7", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-RhKmeD0E2ejzKS6z8elAfdfwShpcdkYY8zJzvHYLq+wv183BBcElTeyMLcIX6wIn7QutXeI92Yi21t7aUWfqNQ=="], + "@react-navigation/native": ["@react-navigation/native@8.0.0-alpha.0", "", { "dependencies": { "@react-navigation/core": "^8.0.0-alpha.0", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "use-latest-callback": "^0.3.2" }, "peerDependencies": { "react": ">= 19.0.0", "react-native": "*" } }, "sha512-TWnlArpOfm8FsNnV9ca9ZQAdIEOUqEiMzj5CNk6UHVaBhUVY+KZtmBVmKZaT7Xhpm4BQRlzE9OQUA8rt/0/Kzg=="], - "@react-navigation/native-stack": ["@react-navigation/native-stack@7.9.0", "", { "dependencies": { "@react-navigation/elements": "^2.9.3", "color": "^4.2.3", "sf-symbols-typescript": "^2.1.0", "warn-once": "^0.1.1" }, "peerDependencies": { "@react-navigation/native": "^7.1.26", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-C/mNPhI0Pnerl7C2cB+6fAkdgSmfKECMERrbyfjx3P6JmEuTC54o+GV1c62FUmlRaRUassVHbtw4EeaY2uLh0g=="], + "@react-navigation/native-stack": ["@react-navigation/native-stack@8.0.0-alpha.0", "", { "dependencies": { "@react-navigation/elements": "^3.0.0-alpha.0", "sf-symbols-typescript": "^2.1.0", "warn-once": "^0.1.1" }, "peerDependencies": { "@react-navigation/native": "^8.0.0-alpha.0", "react": ">= 19.0.0", "react-native": "*", "react-native-safe-area-context": ">= 5.5.0", "react-native-screens": ">= 4.19.0" } }, "sha512-QIzCYNYYWLARMrrkFwM2Ld/f/rpiDfHCUXs2K8Rh5WhC1Zlm9Dzwb4VCM5+yO06xl7zfDriRnqPKQIxwXwY2Cw=="], - "@react-navigation/routers": ["@react-navigation/routers@7.5.3", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg=="], + "@react-navigation/routers": ["@react-navigation/routers@8.0.0-alpha.0", "", { "dependencies": { "nanoid": "^3.3.11" } }, "sha512-jMhHdY9Zrg6zmYrjOhO5f8yMVSmHh8m0YRjg+rH7xuKroJLeDaJS9/hFkSy9CAtaiY05vjis1Sy0G5+YcpdRLw=="], "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], @@ -1112,13 +1122,13 @@ "collect-v8-coverage": ["collect-v8-coverage@1.0.3", "", {}, "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw=="], - "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + "color": ["color@5.0.3", "", { "dependencies": { "color-convert": "^3.1.3", "color-string": "^2.1.3" } }, "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA=="], - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + "color-convert": ["color-convert@3.1.3", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg=="], - "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "color-name": ["color-name@2.1.0", "", {}, "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg=="], - "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + "color-string": ["color-string@2.1.4", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg=="], "color2k": ["color2k@2.0.3", "", {}, "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog=="], @@ -1904,6 +1914,8 @@ "react-native-blurhash": ["react-native-blurhash@2.1.3", "", { "peerDependencies": { "react": ">=16.8.1", "react-native": ">=0.60.0-rc.0 <1.0.x" } }, "sha512-tYyFketZkrrEIABJ5Z1Pt6N2dqPqtSp7w4Lce17sx1bvspdppgVu/ehtZoPRZu02fYyX92RkyCeGXtCbtUNntg=="], + "react-native-bottom-tabs": ["react-native-bottom-tabs@1.1.0", "", { "dependencies": { "react-freeze": "^1.0.0", "sf-symbols-typescript": "^2.0.0", "use-latest-callback": "^0.2.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-Uu1gvM3i1Hb4DjVvR/38J1QVQEs0RkPc7K6yon99HgvRWWOyLs7kjPDhUswtb8ije4pKW712skIXWJ0lgKzbyQ=="], + "react-native-carplay": ["react-native-carplay@2.4.1-beta.0", "", { "peerDependencies": { "react": "^17.0.2 || ^18.0.0", "react-native": "^0.60.0" }, "optionalPeers": ["react", "react-native"] }, "sha512-tYJymLgJi+0516niv4ApGVC+VgENX/uCYqCX81tewSILWnS6KR7M0A9+bHyNk8xoheFyYGruX7onYxU2U8ykPA=="], "react-native-cli-bump-version": ["react-native-cli-bump-version@1.5.1", "", {}, "sha512-C7Vss+BBD4iNMnn2YR00cU+GDDPZ+LDmIqWoh3FPwI/LBsJ/Vp5qanwtyVYRPcIe7Cg1PPB8WdeZ8XcnqF5Klw=="], @@ -1944,7 +1956,7 @@ "react-native-sortables": ["react-native-sortables@1.9.4", "", { "optionalDependencies": { "react-native-haptic-feedback": ">=2.0.0" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-gesture-handler": ">=2.0.0", "react-native-reanimated": ">=3.0.0" } }, "sha512-a6hxT+gl14HA5Sm8UiLXJqF8KMEQVa+mUJd75OnzoVsmrxUDtjAatlMdV0kI9qTQDT/ZSFLPRmdUhOR762IA4g=="], - "react-native-tab-view": ["react-native-tab-view@4.2.2", "", { "dependencies": { "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*", "react-native-pager-view": ">= 6.0.0" } }, "sha512-NXtrG6OchvbGjsvbySJGVocXxo4Y2vA17ph4rAaWtA2jh+AasD8OyikKBRg2SmllEfeQ+GEhcKe8kulHv8BhTg=="], + "react-native-tab-view": ["react-native-tab-view@5.0.0-alpha.0", "", { "dependencies": { "use-latest-callback": "^0.3.2" }, "peerDependencies": { "react": ">= 19.0.0", "react-native": "*", "react-native-pager-view": ">= 7.0.0" } }, "sha512-IQQbhs5x0Hbb0gnMMt6YaZ/JQqGEW/0DwvvEZL3v0b4pA3KVq62wOCoaJVn+YDsU8KYXg4/ovToGlZuGiDfEZg=="], "react-native-text-ticker": ["react-native-text-ticker@1.15.0", "", {}, "sha512-d/uK+PIOhsYMy1r8h825iq/nADiHsabz3WMbRJSnkpQYn+K9aykUAXRRhu8ZbTAzk4CgnUWajJEFxS5ZDygsdg=="], @@ -2206,7 +2218,7 @@ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], - "use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="], + "use-latest-callback": ["use-latest-callback@0.3.3", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-G9A/EL7okx4wzBfATt8bdGg0v1K0Gp0IClTzljffM63gtPisgDKCaLCLUb4g2M4CoXDg5yyHjOU+g3SUPbXwrA=="], "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], @@ -2364,6 +2376,12 @@ "@react-native/eslint-config/eslint-plugin-react-native": ["eslint-plugin-react-native@4.1.0", "", { "dependencies": { "eslint-plugin-react-native-globals": "^0.1.1" }, "peerDependencies": { "eslint": "^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8" } }, "sha512-QLo7rzTBOl43FvVqDdq5Ql9IoElIuTdjrz9SKAXCvULvBoRZ44JGSkx9z4999ZusCsb4rK3gjS8gOGyeYqZv2Q=="], + "@react-navigation/bottom-tabs/color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + + "@react-navigation/elements/color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + + "@react-navigation/material-top-tabs/color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + "@tanstack/react-query/@tanstack/query-core": ["@tanstack/query-core@5.90.12", "", {}, "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg=="], "@types/react-native/@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="], @@ -2386,6 +2404,8 @@ "ansi-fragments/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], + "ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + "babel-jest/@jest/transform": ["@jest/transform@29.7.0", "", { "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", "write-file-atomic": "^4.0.2" } }, "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw=="], "babel-jest/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], @@ -2570,6 +2590,8 @@ "react-native-blob-util/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + "react-native-bottom-tabs/use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="], + "react-native-reanimated/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], "react-native-worklets/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="], @@ -2662,10 +2684,24 @@ "@react-native-vector-icons/common/find-up/path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], + "@react-navigation/bottom-tabs/color/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "@react-navigation/bottom-tabs/color/color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + + "@react-navigation/elements/color/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "@react-navigation/elements/color/color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + + "@react-navigation/material-top-tabs/color/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "@react-navigation/material-top-tabs/color/color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "ansi-fragments/strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="], + "ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "babel-jest/@jest/transform/@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="], "babel-jest/@jest/transform/jest-haste-map": ["jest-haste-map@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA=="], @@ -2806,6 +2842,18 @@ "@react-native-vector-icons/common/find-up/locate-path/p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], + "@react-navigation/bottom-tabs/color/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "@react-navigation/bottom-tabs/color/color-string/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "@react-navigation/elements/color/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "@react-navigation/elements/color/color-string/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "@react-navigation/material-top-tabs/color/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "@react-navigation/material-top-tabs/color/color-string/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "babel-jest/@jest/transform/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="], "cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 591e75b3..74abadfa 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -12,6 +12,34 @@ PODS: - hermes-engine (0.14.0): - hermes-engine/Pre-built (= 0.14.0) - hermes-engine/Pre-built (0.14.0) + - LiquidGlass (0.7.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - MMKVCore (2.2.4) - NitroFetch (0.1.6): - boost @@ -2106,6 +2134,65 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga + - react-native-bottom-tabs (1.1.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-bottom-tabs/common (= 1.1.0) + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - SwiftUIIntrospect (~> 1.0) + - Yoga + - react-native-bottom-tabs/common (1.1.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - SwiftUIIntrospect (~> 1.0) + - Yoga - react-native-carplay (2.4.1-beta.0): - React - react-native-config (1.5.6): @@ -2262,6 +2349,34 @@ PODS: - SocketRocket - SwiftAudioEx (= 1.1.0) - Yoga + - react-native-vector-icons (12.3.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-vector-icons-material-design-icons (12.4.0) - react-native-worklets-core (1.6.2): - boost @@ -3243,6 +3358,7 @@ PODS: - SocketRocket (0.7.1) - SSZipArchive (2.4.3) - SwiftAudioEx (1.1.0) + - SwiftUIIntrospect (1.3.0) - Yoga (0.0.0) DEPENDENCIES: @@ -3254,6 +3370,7 @@ DEPENDENCIES: - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - "LiquidGlass (from `../node_modules/@callstack/liquid-glass`)" - NitroFetch (from `../node_modules/react-native-nitro-fetch`) - NitroMmkv (from `../node_modules/react-native-mmkv`) - NitroModules (from `../node_modules/react-native-nitro-modules`) @@ -3299,6 +3416,7 @@ DEPENDENCIES: - react-native-background-actions (from `../node_modules/react-native-background-actions`) - react-native-blob-util (from `../node_modules/react-native-blob-util`) - react-native-blurhash (from `../node_modules/react-native-blurhash`) + - react-native-bottom-tabs (from `../node_modules/react-native-bottom-tabs`) - react-native-carplay (from `../node_modules/react-native-carplay`) - react-native-config (from `../node_modules/react-native-config`) - react-native-google-cast (from `../node_modules/react-native-google-cast`) @@ -3306,6 +3424,7 @@ DEPENDENCIES: - react-native-pager-view (from `../node_modules/react-native-pager-view`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-track-player (from `../node_modules/react-native-track-player`) + - "react-native-vector-icons (from `../node_modules/@react-native-vector-icons/get-image`)" - "react-native-vector-icons-material-design-icons (from `../node_modules/@react-native-vector-icons/material-design-icons`)" - react-native-worklets-core (from `../node_modules/react-native-worklets-core`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) @@ -3367,6 +3486,7 @@ SPEC REPOS: - SocketRocket - SSZipArchive - SwiftAudioEx + - SwiftUIIntrospect EXTERNAL SOURCES: boost: @@ -3386,6 +3506,8 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-v0.14.0 + LiquidGlass: + :path: "../node_modules/@callstack/liquid-glass" NitroFetch: :path: "../node_modules/react-native-nitro-fetch" NitroMmkv: @@ -3474,6 +3596,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-blob-util" react-native-blurhash: :path: "../node_modules/react-native-blurhash" + react-native-bottom-tabs: + :path: "../node_modules/react-native-bottom-tabs" react-native-carplay: :path: "../node_modules/react-native-carplay" react-native-config: @@ -3488,6 +3612,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safe-area-context" react-native-track-player: :path: "../node_modules/react-native-track-player" + react-native-vector-icons: + :path: "../node_modules/@react-native-vector-icons/get-image" react-native-vector-icons-material-design-icons: :path: "../node_modules/@react-native-vector-icons/material-design-icons" react-native-worklets-core: @@ -3593,6 +3719,7 @@ SPEC CHECKSUMS: glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 google-cast-sdk: 1fb6724e94cc5ff23b359176e0cf6360586bb97a hermes-engine: 83ac7cadb2a3a158ae6d9e4192417c5232065e99 + LiquidGlass: a2ea1e5036efd0964d666b4b63b5bcb3509e1651 MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df NitroFetch: 660adfb47f84b28db664f97b50e5dc28506ab6c1 NitroMmkv: ce1df9b9f0e06dfbde2455d863047e0411fceb6e @@ -3640,6 +3767,7 @@ SPEC CHECKSUMS: react-native-background-actions: 48e6bad9e2a47e3b04858634c5a05ea11062f680 react-native-blob-util: e2162ce4757849682559754bca954b65dc7eeb2f react-native-blurhash: 93b024ff78f7912d22b1cdba262f3c91d3e2002e + react-native-bottom-tabs: e33312fc663d163f0be73d3474dfb448ba38dad8 react-native-carplay: 8f388f6f73e5e0f73ed154ad8794371343ee20c0 react-native-config: f1dde39f8468ad922fc7e8bd4308c8e6223d5ee8 react-native-google-cast: 7be68a5d0b7eeb95a5924c3ecef8d319ef6c0a44 @@ -3647,6 +3775,7 @@ SPEC CHECKSUMS: react-native-pager-view: 5c3098839820aa73d75873e7b1a7eb9f119602b7 react-native-safe-area-context: c00143b4823773bba23f2f19f85663ae89ceb460 react-native-track-player: 89d8e641c83a89bea5dee43c381be743282553e9 + react-native-vector-icons: 6ba2060e1b82ce0663f14375579fe1d48e9b668a react-native-vector-icons-material-design-icons: 76cd460b3540b80527b4a80fb7f867f7deedb498 react-native-worklets-core: 28a6e2121dcf62543b703e81bc4860e9a0150cee React-NativeModulesApple: 1a378198515f8e825c5931a7613e98da69320cee @@ -3698,6 +3827,7 @@ SPEC CHECKSUMS: SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef SwiftAudioEx: f6aa653770f3a0d3851edaf8d834a30aee4a7646 + SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e PODFILE CHECKSUM: 05d07b9cff134e4c27345bc2b588e090e4d3431c diff --git a/package.json b/package.json index ccde287d..0f22a4ef 100644 --- a/package.json +++ b/package.json @@ -37,16 +37,19 @@ "postinstall": "patch-package" }, "dependencies": { + "@bottom-tabs/react-navigation": "^1.1.0", + "@callstack/liquid-glass": "^0.7.0", "@jellyfin/sdk": "0.13.0", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-community/cli": "20.0.0", "@react-native-community/netinfo": "^11.4.1", "@react-native-masked-view/masked-view": "^0.3.2", + "@react-native-vector-icons/get-image": "^12.3.0", "@react-native-vector-icons/material-design-icons": "12.4.0", - "@react-navigation/bottom-tabs": "7.9.0", - "@react-navigation/material-top-tabs": "7.4.11", - "@react-navigation/native": "7.1.26", - "@react-navigation/native-stack": "7.9.0", + "@react-navigation/bottom-tabs": "8.0.0-alpha.0", + "@react-navigation/material-top-tabs": "8.0.0-alpha.0", + "@react-navigation/native": "8.0.0-alpha.0", + "@react-navigation/native-stack": "8.0.0-alpha.0", "@sentry/react-native": "7.8.0", "@shopify/flash-list": "2.2.0", "@tamagui/config": "1.141.4", @@ -66,6 +69,7 @@ "react-native-background-actions": "^4.0.1", "react-native-blob-util": "^0.22.2", "react-native-blurhash": "^2.1.3", + "react-native-bottom-tabs": "^1.1.0", "react-native-carplay": "^2.4.1-beta.0", "react-native-config": "1.5.6", "react-native-device-info": "15.0.1", diff --git a/src/components/Album/footer.tsx b/src/components/Album/footer.tsx index 81ad7a35..e419ac5a 100644 --- a/src/components/Album/footer.tsx +++ b/src/components/Album/footer.tsx @@ -1,20 +1,11 @@ -import DiscoverStackParamList from '../../screens/Discover/types' -import HomeStackParamList from '../../screens/Home/types' -import LibraryStackParamList from '../../screens/Library/types' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client' import { useNavigation } from '@react-navigation/native' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { FlashList } from '@shopify/flash-list' import { YStack, H5 } from 'tamagui' import { ItemCard } from '../Global/components/item-card' export default function AlbumTrackListFooter({ album }: { album: BaseItemDto }): React.JSX.Element { - const navigation = - useNavigation< - NativeStackNavigationProp< - HomeStackParamList | LibraryStackParamList | DiscoverStackParamList - > - >() + const navigation = useNavigation('Album') return ( diff --git a/src/components/Album/header.tsx b/src/components/Album/header.tsx index d51b2b2e..7abd6c68 100644 --- a/src/components/Album/header.tsx +++ b/src/components/Album/header.tsx @@ -39,7 +39,7 @@ export default function AlbumTrackListHeader({ album }: { album: BaseItemDto }): queryFn: () => fetchAlbumDiscs(api, album), }) - const navigation = useNavigation>() + const navigation = useNavigation('Album') const playAlbum = (shuffled: boolean = false) => { if (!discs || discs.length === 0) return diff --git a/src/components/Album/index.tsx b/src/components/Album/index.tsx index 61e343c3..a5b514cd 100644 --- a/src/components/Album/index.tsx +++ b/src/components/Album/index.tsx @@ -30,7 +30,7 @@ import { useStorageContext } from '../../providers/Storage' * @returns A React component */ export function Album({ album }: { album: BaseItemDto }): React.JSX.Element { - const navigation = useNavigation>() + const navigation = useNavigation('Album') const api = useApi() diff --git a/src/components/Albums/component.tsx b/src/components/Albums/component.tsx index 014b3d5c..0c4d2355 100644 --- a/src/components/Albums/component.tsx +++ b/src/components/Albums/component.tsx @@ -5,9 +5,7 @@ import { FlashList, FlashListRef } from '@shopify/flash-list' import { UseInfiniteQueryResult } from '@tanstack/react-query' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' import ItemRow from '../Global/components/item-row' -import { useNavigation } from '@react-navigation/native' -import LibraryStackParamList from '../../screens/Library/types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' +import { LibraryNavigator, useNavigation } from '@react-navigation/native' import AZScroller, { useAlphabetSelector } from '../Global/components/alphabetical-selector' import { isString } from 'lodash' import FlashListStickyHeader from '../Global/helpers/flashlist-sticky-header' @@ -32,7 +30,7 @@ export default function Albums({ const isFavorites = useLibraryStore((state) => state.isFavorites) - const navigation = useNavigation>() + const navigation = useNavigation() const sectionListRef = useRef>(null) diff --git a/src/components/Artist/header.tsx b/src/components/Artist/header.tsx index 56981835..647c5ea2 100644 --- a/src/components/Artist/header.tsx +++ b/src/components/Artist/header.tsx @@ -7,8 +7,6 @@ import { useArtistContext } from '../../providers/Artist' import FavoriteButton from '../Global/components/favorite-button' import { InstantMixIconButton } from '../Global/components/instant-mix-button' import { useNavigation } from '@react-navigation/native' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { BaseStackParamList } from '@/src/screens/types' import IconButton from '../Global/helpers/icon-button' import { fetchAlbumDiscs } from '../../api/queries/item' import { useLoadNewQueue } from '../../providers/Player/hooks/mutations' @@ -30,7 +28,7 @@ export default function ArtistHeader(): React.JSX.Element { const loadNewQueue = useLoadNewQueue() - const navigation = useNavigation>() + const navigation = useNavigation('Artist') const playArtist = async (shuffled: boolean = false) => { if (!albums || albums.length === 0) return diff --git a/src/components/Artist/similar.tsx b/src/components/Artist/similar.tsx index e6dcbfad..613249a8 100644 --- a/src/components/Artist/similar.tsx +++ b/src/components/Artist/similar.tsx @@ -1,5 +1,3 @@ -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { BaseStackParamList } from '../../screens/types' import { useNavigation } from '@react-navigation/native' import { Text } from '../Global/helpers/text' import { useArtistContext } from '../../providers/Artist' @@ -9,7 +7,7 @@ import { FlashList } from '@shopify/flash-list' import ItemRow from '../Global/components/item-row' export default function SimilarArtists(): React.JSX.Element { - const navigation = useNavigation>() + const navigation = useNavigation('Artist') const { artist, similarArtists, fetchingSimilarArtists } = useArtistContext() return ( @@ -26,7 +24,7 @@ export default function SimilarArtists(): React.JSX.Element { { - navigation.push('Artist', { + navigation.navigate('Artist', { artist, }) }} diff --git a/src/components/Artists/component.tsx b/src/components/Artists/component.tsx index c51e24ee..a2303267 100644 --- a/src/components/Artists/component.tsx +++ b/src/components/Artists/component.tsx @@ -7,9 +7,7 @@ import { FlashList, FlashListRef } from '@shopify/flash-list' import AZScroller, { useAlphabetSelector } from '../Global/components/alphabetical-selector' import { UseInfiniteQueryResult } from '@tanstack/react-query' import { isString } from 'lodash' -import { useNavigation } from '@react-navigation/native' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import LibraryStackParamList from '../../screens/Library/types' +import { LibraryNavigator, useNavigation } from '@react-navigation/native' import FlashListStickyHeader from '../Global/helpers/flashlist-sticky-header' import { closeAllSwipeableRows } from '../Global/components/swipeable-row-registry' import useLibraryStore from '../../stores/library' @@ -40,7 +38,7 @@ export default function Artists({ const isFavorites = useLibraryStore((state) => state.isFavorites) - const navigation = useNavigation>() + const navigation = useNavigation() const artists = artistsInfiniteQuery.data ?? [] const sectionListRef = useRef>(null) diff --git a/src/components/Context/components/delete-playlist-row.tsx b/src/components/Context/components/delete-playlist-row.tsx index 1343ce4b..5678e82b 100644 --- a/src/components/Context/components/delete-playlist-row.tsx +++ b/src/components/Context/components/delete-playlist-row.tsx @@ -1,4 +1,4 @@ -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client' import { StackActions, TabActions, useNavigation } from '@react-navigation/native' import { ListItem } from 'tamagui' diff --git a/src/components/Context/components/multiple-artists.tsx b/src/components/Context/components/multiple-artists.tsx index 013f9649..d32243e2 100644 --- a/src/components/Context/components/multiple-artists.tsx +++ b/src/components/Context/components/multiple-artists.tsx @@ -2,8 +2,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack' import ItemRow from '../../Global/components/item-row' import { FlashList } from '@shopify/flash-list' import { PlayerParamList } from '../../../screens/Player/types' -import { RouteProp, useNavigation } from '@react-navigation/native' -import { RootStackParamList } from '../../../screens/types' +import { RootNavigator, RouteProp, useNavigation } from '@react-navigation/native' import { getTokenValue } from 'tamagui' interface MultipleArtistsProps { @@ -14,7 +13,7 @@ export default function MultipleArtists({ navigation, route, }: MultipleArtistsProps): React.JSX.Element { - const rootNavigation = useNavigation>() + const rootNavigation = useNavigation() return ( >() + const navigation = useNavigation() const recentlyAddedExists = recentlyAddedAlbumsInfinityQuery.data && recentlyAddedAlbumsInfinityQuery.data.length > 0 diff --git a/src/components/Discover/helpers/public-playlists.tsx b/src/components/Discover/helpers/public-playlists.tsx index 2504b6ee..958c4165 100644 --- a/src/components/Discover/helpers/public-playlists.tsx +++ b/src/components/Discover/helpers/public-playlists.tsx @@ -1,12 +1,10 @@ import { H5, XStack } from 'tamagui' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import Icon from '../../Global/components/icon' import HorizontalCardList from '../../Global/components/horizontal-list' import { ItemCard } from '../../Global/components/item-card' import { useSafeAreaFrame } from 'react-native-safe-area-context' -import { useNavigation } from '@react-navigation/native' -import DiscoverStackParamList from '../../../screens/Discover/types' -import navigationRef from '../../../../navigation' +import { DiscoverNavigator, useNavigation } from '@react-navigation/native' +import navigationRef from '../../../navigation/ref' import { useJellifyServer } from '../../../stores' import { usePublicPlaylists } from '../../../api/queries/playlist' import Animated, { FadeIn, LinearTransition } from 'react-native-reanimated' @@ -21,7 +19,7 @@ export default function PublicPlaylists(): React.JSX.Element | null { refetch, } = usePublicPlaylists() - const navigation = useNavigation>() + const navigation = useNavigation() const [server] = useJellifyServer() const { width } = useSafeAreaFrame() diff --git a/src/components/Discover/helpers/suggested-artists.tsx b/src/components/Discover/helpers/suggested-artists.tsx index 06b363f4..57bf4494 100644 --- a/src/components/Discover/helpers/suggested-artists.tsx +++ b/src/components/Discover/helpers/suggested-artists.tsx @@ -1,11 +1,10 @@ -import { H5, View, XStack } from 'tamagui' +import { H5, XStack } from 'tamagui' import Icon from '../../Global/components/icon' import HorizontalCardList from '../../Global/components/horizontal-list' import { ItemCard } from '../../Global/components/item-card' import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { useNavigation } from '@react-navigation/native' -import DiscoverStackParamList from '../../../screens/Discover/types' -import navigationRef from '../../../../navigation' +import { DiscoverNavigator, useNavigation } from '@react-navigation/native' +import navigationRef from '../../../navigation/ref' import { pickFirstGenre } from '../../../utils/genre-formatting' import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated' import { useDiscoverArtists } from '../../../api/queries/suggestions' @@ -13,7 +12,7 @@ import { useDiscoverArtists } from '../../../api/queries/suggestions' export default function SuggestedArtists(): React.JSX.Element | null { const suggestedArtistsInfiniteQuery = useDiscoverArtists() - const navigation = useNavigation>() + const navigation = useNavigation() const suggestedArtistsExist = suggestedArtistsInfiniteQuery.data && suggestedArtistsInfiniteQuery.data.length > 0 diff --git a/src/components/Global/components/item-row.tsx b/src/components/Global/components/item-row.tsx index cc40606e..64f029e8 100644 --- a/src/components/Global/components/item-row.tsx +++ b/src/components/Global/components/item-row.tsx @@ -6,7 +6,7 @@ import { QueuingType } from '../../../enums/queuing-type' import { RunTimeTicks } from '../helpers/time-codes' import ItemImage from './image' import FavoriteIcon from './favorite-icon' -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { BaseStackParamList } from '../../../screens/types' import { useAddToQueue, useLoadNewQueue } from '../../../providers/Player/hooks/mutations' diff --git a/src/components/Global/components/track.tsx b/src/components/Global/components/track.tsx index 8ef7f4c2..f6d79d6c 100644 --- a/src/components/Global/components/track.tsx +++ b/src/components/Global/components/track.tsx @@ -10,7 +10,7 @@ import FavoriteIcon from './favorite-icon' import { networkStatusTypes } from '../../../components/Network/internetConnectionWatcher' import { useNetworkStatus } from '../../../stores/network' import DownloadedIcon from './downloaded-icon' -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { BaseStackParamList } from '../../../screens/types' import ItemImage from './image' diff --git a/src/components/Home/helpers/frequent-artists.tsx b/src/components/Home/helpers/frequent-artists.tsx index 6f9e3d51..a1b08db6 100644 --- a/src/components/Home/helpers/frequent-artists.tsx +++ b/src/components/Home/helpers/frequent-artists.tsx @@ -1,21 +1,18 @@ import HorizontalCardList from '../../../components/Global/components/horizontal-list' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import React, { useCallback } from 'react' import { ItemCard } from '../../../components/Global/components/item-card' import { H5, XStack } from 'tamagui' import Icon from '../../Global/components/icon' import { useDisplayContext } from '../../../providers/Display/display-provider' -import { useNavigation } from '@react-navigation/native' -import HomeStackParamList from '../../../screens/Home/types' -import { RootStackParamList } from '../../../screens/types' +import { HomeNavigator, RootNavigator, useNavigation } from '@react-navigation/native' import { useFrequentlyPlayedArtists } from '../../../api/queries/frequents' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client' import { pickFirstGenre } from '../../../utils/genre-formatting' import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated' export default function FrequentArtists(): React.JSX.Element { - const navigation = useNavigation>() - const rootNavigation = useNavigation>() + const navigation = useNavigation() + const rootNavigation = useNavigation() const frequentArtistsInfiniteQuery = useFrequentlyPlayedArtists() const { horizontalItems } = useDisplayContext() diff --git a/src/components/Home/helpers/frequent-tracks.tsx b/src/components/Home/helpers/frequent-tracks.tsx index feafa02c..ac8f58f2 100644 --- a/src/components/Home/helpers/frequent-tracks.tsx +++ b/src/components/Home/helpers/frequent-tracks.tsx @@ -1,4 +1,3 @@ -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { H5, XStack } from 'tamagui' import HorizontalCardList from '../../../components/Global/components/horizontal-list' import { ItemCard } from '../../../components/Global/components/item-card' @@ -6,9 +5,7 @@ import { QueuingType } from '../../../enums/queuing-type' import Icon from '../../Global/components/icon' import { useLoadNewQueue } from '../../../providers/Player/hooks/mutations' import { useDisplayContext } from '../../../providers/Display/display-provider' -import HomeStackParamList from '../../../screens/Home/types' -import { useNavigation } from '@react-navigation/native' -import { RootStackParamList } from '../../../screens/types' +import { RootNavigator, HomeNavigator, useNavigation } from '@react-navigation/native' import { useNetworkStatus } from '../../../stores/network' import useStreamingDeviceProfile from '../../../stores/device-profile' import { useFrequentlyPlayedTracks } from '../../../api/queries/frequents' @@ -24,9 +21,9 @@ export default function FrequentlyPlayedTracks(): React.JSX.Element { const tracksInfiniteQuery = useFrequentlyPlayedTracks() - const navigation = useNavigation>() + const navigation = useNavigation() - const rootNavigation = useNavigation>() + const rootNavigation = useNavigation() const loadNewQueue = useLoadNewQueue() const { horizontalItems } = useDisplayContext() diff --git a/src/components/Home/helpers/recent-artists.tsx b/src/components/Home/helpers/recent-artists.tsx index f77ef719..1e09e5f3 100644 --- a/src/components/Home/helpers/recent-artists.tsx +++ b/src/components/Home/helpers/recent-artists.tsx @@ -1,13 +1,10 @@ import React, { useCallback } from 'react' -import { H5, View, XStack } from 'tamagui' -import { RootStackParamList } from '../../../screens/types' +import { H5, XStack } from 'tamagui' import { ItemCard } from '../../Global/components/item-card' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import HorizontalCardList from '../../../components/Global/components/horizontal-list' import Icon from '../../Global/components/icon' import { useDisplayContext } from '../../../providers/Display/display-provider' -import { useNavigation } from '@react-navigation/native' -import HomeStackParamList from '../../../screens/Home/types' +import { HomeNavigator, RootNavigator, useNavigation } from '@react-navigation/native' import { useRecentArtists } from '../../../api/queries/recents' import { pickFirstGenre } from '../../../utils/genre-formatting' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models/base-item-dto' @@ -16,9 +13,9 @@ import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanim export default function RecentArtists(): React.JSX.Element { const recentArtistsInfiniteQuery = useRecentArtists() - const navigation = useNavigation>() + const navigation = useNavigation() - const rootNavigation = useNavigation>() + const rootNavigation = useNavigation() const { horizontalItems } = useDisplayContext() diff --git a/src/components/Home/helpers/recently-played.tsx b/src/components/Home/helpers/recently-played.tsx index 39a4a7a1..aa418562 100644 --- a/src/components/Home/helpers/recently-played.tsx +++ b/src/components/Home/helpers/recently-played.tsx @@ -1,15 +1,12 @@ import React from 'react' import { H5, XStack } from 'tamagui' import { ItemCard } from '../../Global/components/item-card' -import { RootStackParamList } from '../../../screens/types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { QueuingType } from '../../../enums/queuing-type' import HorizontalCardList from '../../../components/Global/components/horizontal-list' import Icon from '../../Global/components/icon' import { useLoadNewQueue } from '../../../providers/Player/hooks/mutations' import { useDisplayContext } from '../../../providers/Display/display-provider' -import { useNavigation } from '@react-navigation/native' -import HomeStackParamList from '../../../screens/Home/types' +import { HomeNavigator, RootNavigator, useNavigation } from '@react-navigation/native' import { useNetworkStatus } from '../../../stores/network' import useStreamingDeviceProfile from '../../../stores/device-profile' import { useRecentlyPlayedTracks } from '../../../api/queries/recents' @@ -23,8 +20,8 @@ export default function RecentlyPlayed(): React.JSX.Element { const deviceProfile = useStreamingDeviceProfile() - const navigation = useNavigation>() - const rootNavigation = useNavigation>() + const navigation = useNavigation() + const rootNavigation = useNavigation() const loadNewQueue = useLoadNewQueue() diff --git a/src/components/Library/components/tracks-tab.tsx b/src/components/Library/components/tracks-tab.tsx index 3fcee498..a70b2365 100644 --- a/src/components/Library/components/tracks-tab.tsx +++ b/src/components/Library/components/tracks-tab.tsx @@ -1,7 +1,7 @@ import React from 'react' import Tracks from '../../Tracks/component' -import { useNavigation } from '@react-navigation/native' +import { LibraryNavigator, useNavigation } from '@react-navigation/native' import LibraryStackParamList from '@/src/screens/Library/types' import { NativeStackNavigationProp } from '@react-navigation/native-stack' import useTracks from '../../../api/queries/track' @@ -12,7 +12,7 @@ function TracksTab(): React.JSX.Element { const { isFavorites, isDownloaded } = useLibraryStore() - const navigation = useNavigation>() + const navigation = useNavigation() return ( >() + const navigation = useNavigation() const playerEngineData = usePlayerEngineStore((state) => state.playerEngineData) const theme = useTheme() diff --git a/src/components/Player/components/header.tsx b/src/components/Player/components/header.tsx index 278b05d1..243dab37 100644 --- a/src/components/Player/components/header.tsx +++ b/src/components/Player/components/header.tsx @@ -10,7 +10,7 @@ import Animated, { } from 'react-native-reanimated' import { LayoutChangeEvent } from 'react-native' import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons' -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import { useCurrentTrack, useQueueRef } from '../../../stores/player/queue' import TextTicker from 'react-native-text-ticker' import { TextTickerConfig } from '../component.config' diff --git a/src/components/Player/components/quality-badge.tsx b/src/components/Player/components/quality-badge.tsx index e2d1ebb2..e189a39a 100644 --- a/src/components/Player/components/quality-badge.tsx +++ b/src/components/Player/components/quality-badge.tsx @@ -1,6 +1,6 @@ import { Spacer, Square } from 'tamagui' import { Text } from '../../Global/helpers/text' -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import { parseBitrateFromTranscodingUrl } from '../../../utils/url-parsers' import { BaseItemDto, MediaSourceInfo } from '@jellyfin/sdk/lib/generated-client' import { SourceType } from '../../../types/JellifyTrack' diff --git a/src/components/Player/components/song-info.tsx b/src/components/Player/components/song-info.tsx index 94acb022..43987e70 100644 --- a/src/components/Player/components/song-info.tsx +++ b/src/components/Player/components/song-info.tsx @@ -7,7 +7,7 @@ import { useQuery } from '@tanstack/react-query' import { fetchItem } from '../../../api/queries/item' import FavoriteButton from '../../Global/components/favorite-button' import { QueryKeys } from '../../../enums/query-keys' -import navigationRef from '../../../../navigation' +import navigationRef from '../../../navigation/ref' import Icon from '../../Global/components/icon' import { getItemName } from '../../../utils/text' import { CommonActions } from '@react-navigation/native' diff --git a/src/components/Player/mini-player.tsx b/src/components/Player/mini-player.tsx index fc5ab2e0..8eb7aed8 100644 --- a/src/components/Player/mini-player.tsx +++ b/src/components/Player/mini-player.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Progress, XStack, YStack } from 'tamagui' -import { useNavigation } from '@react-navigation/native' +import { RootNavigator, useNavigation } from '@react-navigation/native' import { Text } from '../Global/helpers/text' import TextTicker from 'react-native-text-ticker' import { PlayPauseIcon } from './components/buttons' @@ -19,8 +19,6 @@ import Animated, { withSpring, } from 'react-native-reanimated' import { runOnJS } from 'react-native-worklets' -import { RootStackParamList } from '../../screens/types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import ItemImage from '../Global/components/image' import { usePrevious, useSkip } from '../../providers/Player/hooks/mutations' import { useCurrentTrack } from '../../stores/player/queue' @@ -30,7 +28,7 @@ export default function Miniplayer(): React.JSX.Element { const skip = useSkip() const previous = usePrevious() - const navigation = useNavigation>() + const navigation = useNavigation() const translateX = useSharedValue(0) const translateY = useSharedValue(0) diff --git a/src/components/Playlist/components/header.tsx b/src/components/Playlist/components/header.tsx index a78da6fb..812ea2d0 100644 --- a/src/components/Playlist/components/header.tsx +++ b/src/components/Playlist/components/header.tsx @@ -1,12 +1,10 @@ import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { H5, Spacer, XStack, YStack } from 'tamagui' import { InstantMixButton } from '../../Global/components/instant-mix-button' import Icon from '../../Global/components/icon' import { useNetworkStatus } from '../../../stores/network' import { QueuingType } from '../../../enums/queuing-type' -import { useNavigation } from '@react-navigation/native' -import LibraryStackParamList from '@/src/screens/Library/types' +import { useNavigation, LibraryNavigator } from '@react-navigation/native' import { useLoadNewQueue } from '../../../providers/Player/hooks/mutations' import useStreamingDeviceProfile from '../../../stores/device-profile' import ItemImage from '../../Global/components/image' @@ -100,7 +98,7 @@ function PlaylistHeaderControls({ const [networkStatus] = useNetworkStatus() - const navigation = useNavigation>() + const navigation = useNavigation() const playPlaylist = (shuffled: boolean = false) => { if (!playlistTracks || playlistTracks.length === 0) return diff --git a/src/components/Playlist/index.tsx b/src/components/Playlist/index.tsx index 941d5373..f2eb8f75 100644 --- a/src/components/Playlist/index.tsx +++ b/src/components/Playlist/index.tsx @@ -2,21 +2,19 @@ import { ScrollView, Separator, Spinner, useTheme, XStack, YStack } from 'tamagu import Track from '../Global/components/track' import Icon from '../Global/components/icon' import { PlaylistProps } from './interfaces' -import { StackActions, useNavigation } from '@react-navigation/native' -import { RootStackParamList } from '../../screens/types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' +import { RootNavigator, StackActions, useNavigation } from '@react-navigation/native' import Sortable from 'react-native-sortables' import { useReducedHapticsSetting } from '../../stores/settings/app' import { RenderItemInfo } from 'react-native-sortables/dist/typescript/types' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client' import PlaylistTracklistHeader from './components/header' -import navigationRef from '../../../navigation' +import navigationRef from '../../navigation/ref' import { useLoadNewQueue } from '../../providers/Player/hooks/mutations' import { useNetworkStatus } from '../../stores/network' import { QueuingType } from '../../enums/queuing-type' import { useApi } from '../../stores' import useStreamingDeviceProfile from '../../stores/device-profile' -import { useCallback, useEffect, useLayoutEffect, useState } from 'react' +import { useEffect, useLayoutEffect, useState } from 'react' import { updatePlaylist } from '../../../src/api/mutations/playlists' import { usePlaylistTracks } from '../../../src/api/queries/playlist' import useHapticFeedback from '../../hooks/use-haptic-feedback' @@ -110,7 +108,7 @@ export default function Playlist({ * Fetches all remaining pages before entering edit mode. * This prevents data loss when saving a playlist that has unloaded tracks. */ - const handleEnterEditMode = useCallback(async () => { + const handleEnterEditMode = async () => { if (hasNextPage) { setIsPreparingEditMode(true) try { @@ -125,7 +123,7 @@ export default function Playlist({ } } setEditing(true) - }, [hasNextPage, fetchNextPage]) + } useEffect(() => { if (!isPending && isSuccess) setPlaylistTracks(tracks) @@ -257,7 +255,7 @@ export default function Playlist({ const streamingDeviceProfile = useStreamingDeviceProfile() - const rootNavigation = useNavigation>() + const rootNavigation = useNavigation() // Render item for Sortable.Grid (edit mode only) const renderSortableItem = ({ item: track, index }: RenderItemInfo) => { diff --git a/src/components/Playlists/component.tsx b/src/components/Playlists/component.tsx index 80e02fc2..76f67938 100644 --- a/src/components/Playlists/component.tsx +++ b/src/components/Playlists/component.tsx @@ -4,7 +4,7 @@ import { FlashList } from '@shopify/flash-list' import ItemRow from '../Global/components/item-row' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' import { FetchNextPageOptions } from '@tanstack/react-query' -import { useNavigation } from '@react-navigation/native' +import { LibraryNavigator, useNavigation } from '@react-navigation/native' import { BaseStackParamList } from '@/src/screens/types' import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { closeAllSwipeableRows } from '../Global/components/swipeable-row-registry' @@ -37,7 +37,7 @@ export default function Playlists({ }: PlaylistsProps): React.JSX.Element { const theme = useTheme() - const navigation = useNavigation>() + const navigation = useNavigation() // Memoized key extractor to prevent recreation on each render const keyExtractor = useCallback((item: BaseItemDto) => item.Id!, []) diff --git a/src/components/Search/suggestions.tsx b/src/components/Search/suggestions.tsx index 26554e8e..45f3d7a6 100644 --- a/src/components/Search/suggestions.tsx +++ b/src/components/Search/suggestions.tsx @@ -4,10 +4,8 @@ import { H5, Separator, Spinner, YStack } from 'tamagui' import { ItemCard } from '../Global/components/item-card' import HorizontalCardList from '../Global/components/horizontal-list' import { FlashList } from '@shopify/flash-list' -import SearchParamList from '../../screens/Search/types' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' -import { useNavigation } from '@react-navigation/native' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' +import { SearchNavigator, useNavigation } from '@react-navigation/native' import { closeAllSwipeableRows } from '../Global/components/swipeable-row-registry' export default function Suggestions({ @@ -15,7 +13,7 @@ export default function Suggestions({ }: { suggestions: BaseItemDto[] | undefined }): React.JSX.Element { - const navigation = useNavigation>() + const navigation = useNavigation() const handleScrollBeginDrag = () => { closeAllSwipeableRows() } diff --git a/src/components/Settings/components/account-tab.tsx b/src/components/Settings/components/account-tab.tsx index 9fb19dd6..df16ab58 100644 --- a/src/components/Settings/components/account-tab.tsx +++ b/src/components/Settings/components/account-tab.tsx @@ -1,8 +1,6 @@ import React, { useState } from 'react' import SignOut from './sign-out-button' -import { SettingsStackParamList } from '../../../screens/Settings/types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { useNavigation } from '@react-navigation/native' +import { SettingsNavigator, useNavigation } from '@react-navigation/native' import { Text } from '../../Global/helpers/text' import SettingsListGroup from './settings-list-group' import HTTPS from '../../../constants/protocols' @@ -25,7 +23,7 @@ export default function AccountTab(): React.JSX.Element { const [prId, setPrId] = usePrId() const [localPrId, setLocalPrId] = useState(prId) - const navigation = useNavigation>() + const navigation = useNavigation() const handleSubmitPr = () => { if (localPrId.trim()) { diff --git a/src/components/Settings/components/usage-tab.tsx b/src/components/Settings/components/usage-tab.tsx index e69be4c3..b0e9f9b3 100644 --- a/src/components/Settings/components/usage-tab.tsx +++ b/src/components/Settings/components/usage-tab.tsx @@ -8,16 +8,13 @@ import { useAutoDownload, useDownloadQuality, } from '../../../stores/settings/usage' -import { useNavigation } from '@react-navigation/native' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { SettingsStackParamList } from '../../../screens/Settings/types' +import { SettingsNavigator, useNavigation } from '@react-navigation/native' export default function StorageTab(): React.JSX.Element { const [autoDownload, setAutoDownload] = useAutoDownload() const [downloadQuality, setDownloadQuality] = useDownloadQuality() const { data: downloadedTracks } = useAllDownloadedTracks() - const navigation = - useNavigation>() + const navigation = useNavigation() return ( () diff --git a/src/providers/Player/hooks/mutations.ts b/src/providers/Player/hooks/mutations.ts index dca9f6c6..50ce21f3 100644 --- a/src/providers/Player/hooks/mutations.ts +++ b/src/providers/Player/hooks/mutations.ts @@ -1,7 +1,6 @@ import { useMutation } from '@tanstack/react-query' import TrackPlayer, { RepeatMode, State } from 'react-native-track-player' import { loadQueue, playLaterInQueue, playNextInQueue } from '../functions/queue' -import { isUndefined } from 'lodash' import { previous, skip } from '../functions/controls' import { AddToQueueMutation, QueueMutation, QueueOrderMutation } from '../interfaces' import { QueuingType } from '../../../enums/queuing-type' @@ -11,12 +10,10 @@ import JellifyTrack from '@/src/types/JellifyTrack' import calculateTrackVolume from '../utils/normalization' import usePlayerEngineStore, { PlayerEngine } from '../../../stores/player/engine' import { useRemoteMediaClient } from 'react-native-google-cast' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { RootStackParamList } from '../../../screens/types' -import { useNavigation } from '@react-navigation/native' import useHapticFeedback from '../../../hooks/use-haptic-feedback' import { usePlayerQueueStore } from '../../../stores/player/queue' import { useCallback } from 'react' +import navigationRef from '../../../navigation/ref' /** * A mutation to handle starting playback @@ -186,34 +183,30 @@ export const useLoadNewQueue = () => { const isCasting = usePlayerEngineStore((state) => state.playerEngineData) === PlayerEngine.GOOGLE_CAST const remoteClient = useRemoteMediaClient() - const navigation = useNavigation>() const trigger = useHapticFeedback() - return useCallback( - async (variables: QueueMutation) => { - trigger('impactLight') - await TrackPlayer.pause() - const { finalStartIndex, tracks } = await loadQueue({ ...variables }) + return async (variables: QueueMutation) => { + trigger('impactLight') + await TrackPlayer.pause() + const { finalStartIndex, tracks } = await loadQueue({ ...variables }) - usePlayerQueueStore.getState().setCurrentIndex(finalStartIndex) - - if (isCasting && remoteClient) { - await TrackPlayer.skip(finalStartIndex) - navigation.navigate('PlayerRoot', { screen: 'PlayerScreen' }) - return - } + usePlayerQueueStore.getState().setCurrentIndex(finalStartIndex) + if (isCasting && remoteClient) { await TrackPlayer.skip(finalStartIndex) + navigationRef.navigate('PlayerRoot', { screen: 'PlayerScreen' }) + return + } - if (variables.startPlayback) await TrackPlayer.play() + await TrackPlayer.skip(finalStartIndex) - usePlayerQueueStore.getState().setQueueRef(variables.queue) - usePlayerQueueStore.getState().setQueue(tracks) - usePlayerQueueStore.getState().setCurrentTrack(tracks[finalStartIndex]) - }, - [isCasting, remoteClient, navigation, trigger, usePlayerQueueStore], - ) + if (variables.startPlayback) await TrackPlayer.play() + + usePlayerQueueStore.getState().setQueueRef(variables.queue) + usePlayerQueueStore.getState().setQueue(tracks) + usePlayerQueueStore.getState().setCurrentTrack(tracks[finalStartIndex]) + } } export const usePrevious = () => { diff --git a/src/screens/Discover/index.tsx b/src/screens/Discover/index.tsx index a6b4b437..db58157d 100644 --- a/src/screens/Discover/index.tsx +++ b/src/screens/Discover/index.tsx @@ -104,3 +104,9 @@ export function Discover(): React.JSX.Element { ) } + +type DiscoverStackType = typeof DiscoverStack + +declare module '@react-navigation/core' { + interface DiscoverNavigator extends DiscoverStackType {} +} diff --git a/src/screens/Home/index.tsx b/src/screens/Home/index.tsx index f5260527..30f84164 100644 --- a/src/screens/Home/index.tsx +++ b/src/screens/Home/index.tsx @@ -103,3 +103,9 @@ export default function Home(): React.JSX.Element { ) } + +type HomeStackType = typeof HomeStack + +declare module '@react-navigation/core' { + interface HomeNavigator extends HomeStackType {} +} diff --git a/src/screens/Library/index.tsx b/src/screens/Library/index.tsx index e3672fda..191494dc 100644 --- a/src/screens/Library/index.tsx +++ b/src/screens/Library/index.tsx @@ -84,3 +84,9 @@ export default function LibraryScreen(): React.JSX.Element { ) } + +type LibraryStackType = typeof LibraryStack + +declare module '@react-navigation/core' { + interface LibraryNavigator extends LibraryStackType {} +} diff --git a/src/screens/Login/server-library.tsx b/src/screens/Login/server-library.tsx index 6980d0ad..90b7308c 100644 --- a/src/screens/Login/server-library.tsx +++ b/src/screens/Login/server-library.tsx @@ -1,11 +1,10 @@ import React from 'react' import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { RootStackParamList } from '../types' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' import LibrarySelector from '../../components/Global/components/library-selector' import LoginStackParamList from './types' -import { useNavigation } from '@react-navigation/native' import { useJellifyLibrary } from '../../stores' +import navigationRef from '../../navigation/ref' export default function ServerLibrary({ navigation, @@ -14,8 +13,6 @@ export default function ServerLibrary({ }): React.JSX.Element { const [, setLibrary] = useJellifyLibrary() - const rootNavigation = useNavigation>() - const handleLibrarySelected = ( libraryId: string, selectedLibrary: BaseItemDto, @@ -28,7 +25,7 @@ export default function ServerLibrary({ playlistLibraryId: playlistLibrary?.Id, playlistLibraryPrimaryImageId: playlistLibrary?.ImageTags?.Primary, }) - rootNavigation.navigate('Tabs', { screen: 'HomeTab' }) + navigationRef.navigate('Tabs', { screen: 'HomeTab' }) } const handleCancel = () => { diff --git a/src/screens/Player/index.tsx b/src/screens/Player/index.tsx index d73de2dd..d977bea8 100644 --- a/src/screens/Player/index.tsx +++ b/src/screens/Player/index.tsx @@ -50,3 +50,9 @@ export default function Player(): React.JSX.Element { ) } + +type PlayerStackType = typeof PlayerStack + +declare module '@react-navigation/core' { + interface PlayerNavigator extends PlayerStackType {} +} diff --git a/src/screens/Search/index.tsx b/src/screens/Search/index.tsx index a0d69e23..dd669513 100644 --- a/src/screens/Search/index.tsx +++ b/src/screens/Search/index.tsx @@ -71,3 +71,9 @@ export default function SearchStack(): React.JSX.Element { ) } + +type SearchStackType = typeof Stack + +declare module '@react-navigation/core' { + interface SearchNavigator extends SearchStackType {} +} diff --git a/src/screens/Settings/index.tsx b/src/screens/Settings/index.tsx index dd3e8935..8a6d2914 100644 --- a/src/screens/Settings/index.tsx +++ b/src/screens/Settings/index.tsx @@ -63,3 +63,9 @@ export default function SettingsScreen(): React.JSX.Element { ) } + +type SettingsStackType = typeof SettingsStack + +declare module '@react-navigation/core' { + interface SettingsNavigator extends SettingsStackType {} +} diff --git a/src/screens/Settings/sign-out-modal.tsx b/src/screens/Settings/sign-out-modal.tsx index 3a9c7d6b..6f79a330 100644 --- a/src/screens/Settings/sign-out-modal.tsx +++ b/src/screens/Settings/sign-out-modal.tsx @@ -6,15 +6,11 @@ import Icon from '../../components/Global/components/icon' import { useResetQueue } from '../../providers/Player/hooks/mutations' import { useClearAllDownloads } from '../../api/mutations/download' import { useJellifyServer } from '../../stores' -import { useNavigation } from '@react-navigation/native' -import { RootStackParamList } from '../types' -import { NativeStackNavigationProp } from '@react-navigation/native-stack' +import navigationRef from '../../navigation/ref' export default function SignOutModal({ navigation }: SignOutModalProps): React.JSX.Element { const [server] = useJellifyServer() - const rootNavigation = useNavigation>() - const { mutate: resetQueue } = useResetQueue() const clearDownloads = useClearAllDownloads() @@ -43,7 +39,7 @@ export default function SignOutModal({ navigation }: SignOutModalProps): React.J borderColor={'$danger'} onPress={() => { navigation.goBack() - rootNavigation.navigate('Login', { screen: 'ServerAddress' }) + navigationRef.navigate('Login', { screen: 'ServerAddress' }) clearDownloads() resetQueue() diff --git a/src/screens/Tabs/index.tsx b/src/screens/Tabs/index.tsx index 1e3bf08a..4e1867aa 100644 --- a/src/screens/Tabs/index.tsx +++ b/src/screens/Tabs/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' +import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation' import Home from '../Home' import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons' import SettingsScreen from '../Settings' @@ -10,41 +10,81 @@ import LibraryScreen from '../Library' import TabParamList from './types' import { TabProps } from '../types' import TabBar from './tab-bar' -import { Platform } from 'react-native' -const Tab = createBottomTabNavigator() +const Tab = createNativeBottomTabNavigator() export default function Tabs({ route, navigation }: TabProps): React.JSX.Element { const theme = useTheme() + const jellyfishIconUnfocused = MaterialDesignIcons.getImageSourceSync( + 'jellyfish-outline', + 24, + theme.borderColor.val, + ) + + const jellyfishIconFocused = MaterialDesignIcons.getImageSourceSync( + 'jellyfish', + 24, + theme.primary.val, + ) + + const libraryIconUnfocused = MaterialDesignIcons.getImageSourceSync( + 'music-box-multiple-outline', + 24, + theme.borderColor.val, + ) + + const libraryIconFocused = MaterialDesignIcons.getImageSourceSync( + 'music-box-multiple', + 24, + theme.primary.val, + ) + + const searchIconUnfocused = MaterialDesignIcons.getImageSourceSync( + 'magnify', + 24, + theme.borderColor.val, + ) + + const searchIconFocused = MaterialDesignIcons.getImageSourceSync( + 'magnify', + 24, + theme.primary.val, + ) + + const discoverIconUnfocused = MaterialDesignIcons.getImageSourceSync( + 'compass-outline', + 24, + theme.borderColor.val, + ) + + const discoverIconFocused = MaterialDesignIcons.getImageSourceSync( + 'compass', + 24, + theme.primary.val, + ) + + const settingsIconUnfocused = MaterialDesignIcons.getImageSourceSync( + 'cogs', + 24, + theme.borderColor.val, + ) + + const settingsIconFocused = MaterialDesignIcons.getImageSourceSync( + 'cogs', + 24, + theme.primary.val, + ) + return ( - } - > + ( - - ), + tabBarIcon: ({ focused }) => + focused ? jellyfishIconFocused! : jellyfishIconUnfocused!, tabBarButtonTestID: 'home-tab-button', }} /> @@ -54,14 +94,8 @@ export default function Tabs({ route, navigation }: TabProps): React.JSX.Element component={LibraryScreen} options={{ title: 'Library', - headerShown: false, - tabBarIcon: ({ color, size, focused }) => ( - - ), + tabBarIcon: ({ focused }) => + focused ? libraryIconFocused! : libraryIconUnfocused!, tabBarButtonTestID: 'library-tab-button', }} /> @@ -71,10 +105,8 @@ export default function Tabs({ route, navigation }: TabProps): React.JSX.Element component={SearchStack} options={{ title: 'Search', - headerShown: false, - tabBarIcon: ({ color, size }) => ( - - ), + tabBarIcon: ({ focused }) => + focused ? searchIconFocused! : searchIconUnfocused!, tabBarButtonTestID: 'search-tab-button', }} /> @@ -84,14 +116,8 @@ export default function Tabs({ route, navigation }: TabProps): React.JSX.Element component={Discover} options={{ title: 'Discover', - headerShown: false, - tabBarIcon: ({ color, size, focused }) => ( - - ), + tabBarIcon: ({ focused }) => + focused ? discoverIconFocused! : discoverIconUnfocused!, tabBarButtonTestID: 'discover-tab-button', }} /> @@ -101,10 +127,8 @@ export default function Tabs({ route, navigation }: TabProps): React.JSX.Element component={SettingsScreen} options={{ title: 'Settings', - headerShown: false, - tabBarIcon: ({ color, size }) => ( - - ), + tabBarIcon: ({ focused }) => + focused ? settingsIconFocused! : settingsIconUnfocused!, tabBarButtonTestID: 'settings-tab-button', }} /> diff --git a/src/screens/index.tsx b/src/screens/index.tsx index a52f5e7c..e55c711f 100644 --- a/src/screens/index.tsx +++ b/src/screens/index.tsx @@ -1,7 +1,7 @@ import Player from './Player' import Tabs from './Tabs' import { RootStackParamList } from './types' -import { useTheme, YStack } from 'tamagui' +import { YStack } from 'tamagui' import Login from './Login' import { createNativeStackNavigator } from '@react-navigation/native-stack' import Context from './Context' @@ -19,8 +19,6 @@ import { Platform } from 'react-native' const RootStack = createNativeStackNavigator() export default function Root(): React.JSX.Element { - const theme = useTheme() - const api = useApi() const [library] = useJellifyLibrary() @@ -31,7 +29,6 @@ export default function Root(): React.JSX.Element { component={Tabs} options={{ headerShown: false, - navigationBarColor: theme.background.val, gestureEnabled: false, }} /> @@ -101,6 +98,12 @@ export default function Root(): React.JSX.Element { ) } +type RootStackType = typeof RootStack + +declare module '@react-navigation/core' { + interface RootNavigator extends RootStackType {} +} + function ContextSheetHeader(item: BaseItemDto): React.JSX.Element { return (