From e2ded22611ef193c35fb2e81c61f622e62970db2 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:50:51 -0500 Subject: [PATCH 1/7] chore: Add new toast provider - Provides the ability of updating toasts & having multiple providers (so we can put one inside the sheets that need it) --- THIRD_PARTY.md | 1 + mobile/package.json | 1 + mobile/pnpm-lock.yaml | 19 +++++++++++++++++++ .../licenses/licenseClarification.json | 3 +++ mobile/src/resources/licenses.json | 8 ++++++++ 5 files changed, 32 insertions(+) diff --git a/THIRD_PARTY.md b/THIRD_PARTY.md index 6da4cc0..1db0f94 100644 --- a/THIRD_PARTY.md +++ b/THIRD_PARTY.md @@ -1,5 +1,6 @@ | Name | License | Source | | ---- | ------- | ------ | +| @backpackapp-io/react-native-toast | MIT | https://github.com/backpackapp-io/react-native-toast | | @expo/vector-icons | MIT | https://github.com/expo/vector-icons | | @gorhom/bottom-sheet | MIT | https://github.com/gorhom/react-native-bottom-sheet | | @miblanchard/react-native-slider | MIT | https://github.com/miblanchard/react-native-slider | diff --git a/mobile/package.json b/mobile/package.json index d7bfa65..3f4d090 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -23,6 +23,7 @@ "release": "git checkout main -q && git pull && python ./scripts/release/release_bump.py" }, "dependencies": { + "@backpackapp-io/react-native-toast": "^0.11.0", "@expo/vector-icons": "^14.0.4", "@gorhom/bottom-sheet": "5.0.2", "@miblanchard/react-native-slider": "^2.6.0", diff --git a/mobile/pnpm-lock.yaml b/mobile/pnpm-lock.yaml index aeda2f7..29c53a2 100644 --- a/mobile/pnpm-lock.yaml +++ b/mobile/pnpm-lock.yaml @@ -13,6 +13,9 @@ patchedDependencies: path: patches/react-native-actions-sheet@0.9.7.patch dependencies: + '@backpackapp-io/react-native-toast': + specifier: ^0.11.0 + version: 0.11.0(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1) '@expo/vector-icons': specifier: ^14.0.4 version: 14.0.4 @@ -1789,6 +1792,22 @@ packages: '@babel/helper-validator-identifier': 7.25.7 to-fast-properties: 2.0.0 + /@backpackapp-io/react-native-toast@0.11.0(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1): + resolution: {integrity: sha512-ZRVYQPK6QOvt6vP1bF0I5oBpN5pnssdrX1JLV+KHPyxXWSNNvl1oo0qdJ5uzM7zj2TxMMUBPIsMofFeLA8E/dw==} + peerDependencies: + react: '*' + react-native: '*' + react-native-gesture-handler: '>=2.2.1' + react-native-reanimated: '>=2.8.0' + react-native-safe-area-context: '>=4.2.4' + dependencies: + react: 18.3.1 + react-native: 0.75.4(@babel/core@7.25.8)(@babel/preset-env@7.25.8)(@types/react@18.3.11)(react@18.3.1)(typescript@5.6.3) + react-native-gesture-handler: 2.20.0(react-native@0.75.4)(react@18.3.1) + react-native-reanimated: 3.15.5(@babel/core@7.25.8)(react-native@0.75.4)(react@18.3.1) + react-native-safe-area-context: 4.11.1(react-native@0.75.4)(react@18.3.1) + dev: false + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true diff --git a/mobile/scripts/licenses/licenseClarification.json b/mobile/scripts/licenses/licenseClarification.json index 782c418..7ce767e 100644 --- a/mobile/scripts/licenses/licenseClarification.json +++ b/mobile/scripts/licenses/licenseClarification.json @@ -1,4 +1,7 @@ { + "@backpackapp-io/react-native-toast@0.11.0": { + "copyright": "Copyright (c) 2022 Nick DeBaise" + }, "@paralleldrive/cuid2@2.2.2": { "repository": "https://github.com/paralleldrive/cuid2" }, diff --git a/mobile/src/resources/licenses.json b/mobile/src/resources/licenses.json index 7ae3316..5d49e42 100644 --- a/mobile/src/resources/licenses.json +++ b/mobile/src/resources/licenses.json @@ -1,4 +1,12 @@ { + "@backpackapp-io/react-native-toast": { + "name": "@backpackapp-io/react-native-toast", + "version": "0.11.0", + "copyright": "Copyright (c) 2022 Nick DeBaise", + "source": "https://github.com/backpackapp-io/react-native-toast", + "license": "MIT", + "licenseText": "MIT License\n\nCopyright (c) 2022 Nick DeBaise\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, "@expo/vector-icons": { "name": "@expo/vector-icons", "version": "14.0.4", From 77a8318f1e82863849524b9873b72fde0b283007 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:46:59 -0500 Subject: [PATCH 2/7] chore: New toast provider & default toast options --- mobile/src/lib/toast.tsx | 36 ++++++++++++++++++++++++++++++++++ mobile/src/providers/index.tsx | 27 +++++++++++++++---------- 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 mobile/src/lib/toast.tsx diff --git a/mobile/src/lib/toast.tsx b/mobile/src/lib/toast.tsx new file mode 100644 index 0000000..a8144c7 --- /dev/null +++ b/mobile/src/lib/toast.tsx @@ -0,0 +1,36 @@ +import type { + Toast, + ToastOptions as TOptions, +} from "@backpackapp-io/react-native-toast"; +import { ToastPosition } from "@backpackapp-io/react-native-toast"; +import { Text, View } from "react-native"; + +import { cn } from "./style"; + +/** Sensible defaults for toast. */ +export const ToastOptions = { + customToast: CustomToast, + disableShadow: true, + position: ToastPosition.BOTTOM, +} satisfies TOptions; + +/** Render a custom toast (makes styling for light/dark mode easier). */ +function CustomToast({ type, message, height, width }: Toast) { + return ( + + + + {message as string} + + + + ); +} diff --git a/mobile/src/providers/index.tsx b/mobile/src/providers/index.tsx index dee19fa..2998bd3 100644 --- a/mobile/src/providers/index.tsx +++ b/mobile/src/providers/index.tsx @@ -1,7 +1,9 @@ +import { Toasts } from "@backpackapp-io/react-native-toast"; import { BottomSheetModalProvider } from "@gorhom/bottom-sheet"; import { QueryClientProvider } from "@tanstack/react-query"; import { SheetProvider } from "react-native-actions-sheet"; import { GestureHandlerRootView } from "react-native-gesture-handler"; +import { SafeAreaProvider } from "react-native-safe-area-context"; import "@/screens/Sheets"; import { RouteHandlers } from "./RouteHandlers"; @@ -14,16 +16,21 @@ import { queryClient } from "@/lib/react-query"; export function AppProvider({ children }: { children: React.ReactNode }) { return ( - - - - - - {children} - - - - + + + + + + + + {children} + + + + + + + ); } From 84572682afb5e3f4a51b96037fabbc7e07c6e146 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 19:46:18 -0500 Subject: [PATCH 3/7] chore: Patch package - Removed some unnecessary offset - Allow us to press normally around the toast --- mobile/package.json | 3 +- ...ackapp-io__react-native-toast@0.11.0.patch | 29 +++++++++++++++++++ mobile/pnpm-lock.yaml | 8 +++-- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 mobile/patches/@backpackapp-io__react-native-toast@0.11.0.patch diff --git a/mobile/package.json b/mobile/package.json index 3f4d090..6e585c4 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -114,7 +114,8 @@ }, "pnpm": { "patchedDependencies": { - "react-native-actions-sheet@0.9.7": "patches/react-native-actions-sheet@0.9.7.patch" + "react-native-actions-sheet@0.9.7": "patches/react-native-actions-sheet@0.9.7.patch", + "@backpackapp-io/react-native-toast@0.11.0": "patches/@backpackapp-io__react-native-toast@0.11.0.patch" } } } diff --git a/mobile/patches/@backpackapp-io__react-native-toast@0.11.0.patch b/mobile/patches/@backpackapp-io__react-native-toast@0.11.0.patch new file mode 100644 index 0000000..64d8bac --- /dev/null +++ b/mobile/patches/@backpackapp-io__react-native-toast@0.11.0.patch @@ -0,0 +1,29 @@ +diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx +index c598db60ff3d374db094493fb3a90ae5c4d59077..463219603128d5af80fa842c32b33423efdbbc50 100644 +--- a/src/components/Toast.tsx ++++ b/src/components/Toast.tsx +@@ -130,7 +130,7 @@ export const Toast: FC = ({ + kbHeight - + insets.bottom - + (extraInsets?.bottom ?? 0) - +- 24 ++ 0 + : startingY; + + offsetY.value = withSpring(val, { +@@ -241,6 +241,7 @@ export const Toast: FC = ({ + endPause(); + }} + onPress={onPress} ++ pointerEvents="box-none" + style={[ + { + backgroundColor: !toast.customToast +@@ -267,6 +268,7 @@ export const Toast: FC = ({ + updateHeight(toast.id, event.nativeEvent.layout.height) + } + key={toast.id} ++ pointerEvents="box-none" + > + {toast.customToast({ + ...toast, diff --git a/mobile/pnpm-lock.yaml b/mobile/pnpm-lock.yaml index 29c53a2..fb25a47 100644 --- a/mobile/pnpm-lock.yaml +++ b/mobile/pnpm-lock.yaml @@ -8,6 +8,9 @@ overrides: markdown-it: 14.1.0 patchedDependencies: + '@backpackapp-io/react-native-toast@0.11.0': + hash: od77t6fgaovtgbzmvgntqyne5e + path: patches/@backpackapp-io__react-native-toast@0.11.0.patch react-native-actions-sheet@0.9.7: hash: rilo6dygbis6iqezxxrswoam2q path: patches/react-native-actions-sheet@0.9.7.patch @@ -15,7 +18,7 @@ patchedDependencies: dependencies: '@backpackapp-io/react-native-toast': specifier: ^0.11.0 - version: 0.11.0(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1) + version: 0.11.0(patch_hash=od77t6fgaovtgbzmvgntqyne5e)(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1) '@expo/vector-icons': specifier: ^14.0.4 version: 14.0.4 @@ -1792,7 +1795,7 @@ packages: '@babel/helper-validator-identifier': 7.25.7 to-fast-properties: 2.0.0 - /@backpackapp-io/react-native-toast@0.11.0(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1): + /@backpackapp-io/react-native-toast@0.11.0(patch_hash=od77t6fgaovtgbzmvgntqyne5e)(react-native-gesture-handler@2.20.0)(react-native-reanimated@3.15.5)(react-native-safe-area-context@4.11.1)(react-native@0.75.4)(react@18.3.1): resolution: {integrity: sha512-ZRVYQPK6QOvt6vP1bF0I5oBpN5pnssdrX1JLV+KHPyxXWSNNvl1oo0qdJ5uzM7zj2TxMMUBPIsMofFeLA8E/dw==} peerDependencies: react: '*' @@ -1807,6 +1810,7 @@ packages: react-native-reanimated: 3.15.5(@babel/core@7.25.8)(react-native@0.75.4)(react@18.3.1) react-native-safe-area-context: 4.11.1(react-native@0.75.4)(react@18.3.1) dev: false + patched: true /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} From af6149a363c79245744770a2eed6a4bedd9975d5 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:20:50 -0500 Subject: [PATCH 4/7] chore: Allow toasts to display over sheets - Defined proper minimum toast height (default was 50) --- mobile/src/components/new/Sheet/Sheet.tsx | 2 ++ mobile/src/lib/toast.tsx | 8 +++++++- mobile/src/screens/Sheets/Backup/index.tsx | 4 ---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mobile/src/components/new/Sheet/Sheet.tsx b/mobile/src/components/new/Sheet/Sheet.tsx index 89d8f6b..7620383 100644 --- a/mobile/src/components/new/Sheet/Sheet.tsx +++ b/mobile/src/components/new/Sheet/Sheet.tsx @@ -1,3 +1,4 @@ +import { Toasts } from "@backpackapp-io/react-native-toast"; import { cssInterop } from "nativewind"; import type { StyleProp, ViewStyle } from "react-native"; import { View } from "react-native"; @@ -33,6 +34,7 @@ export function Sheet({ } + ExtraOverlayComponent={} containerClassName={cn("rounded-t-lg bg-canvas dark:bg-neutral5", { "h-full": snapTop, })} diff --git a/mobile/src/lib/toast.tsx b/mobile/src/lib/toast.tsx index a8144c7..af5562f 100644 --- a/mobile/src/lib/toast.tsx +++ b/mobile/src/lib/toast.tsx @@ -12,12 +12,18 @@ export const ToastOptions = { customToast: CustomToast, disableShadow: true, position: ToastPosition.BOTTOM, + height: 36, + providerKey: "PERSISTS", } satisfies TOptions; /** Render a custom toast (makes styling for light/dark mode easier). */ function CustomToast({ type, message, height, width }: Toast) { return ( - + ) { id={props.sheetId} title={t("title.backup")} contentContainerClassName="gap-4" - // Work around for toast notification being underneath the modal. - // - Using `isModal` makes the sheet appear slower compared to - // the default behavior or not having it. - isModal={false} > {t("settings.description.backup")} From 42c2b7e0e80f3114092619b2f0c31034ffcfebb7 Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:00:46 -0500 Subject: [PATCH 5/7] chore: Swapped the function used to display the toasts - We no longer need a toast for removing a track from a playlist - Now dismiss keyboard when we attempt to add a new path filter (so toast can be seen if displayed) --- mobile/src/api/tracks/[id]/playlist.ts | 2 -- mobile/src/modules/media/services/Music.ts | 9 +++++--- mobile/src/modules/scanning/helpers/rescan.ts | 21 ++++++++++++------- mobile/src/screens/Sheets/Backup/data.ts | 11 +++++----- .../src/screens/Sheets/ScanFilterList/data.ts | 12 ++++++----- .../screens/Sheets/ScanFilterList/index.tsx | 9 ++++---- mobile/src/screens/Sheets/Track.tsx | 2 +- mobile/src/services/PlaybackService.ts | 9 ++++++-- 8 files changed, 46 insertions(+), 29 deletions(-) diff --git a/mobile/src/api/tracks/[id]/playlist.ts b/mobile/src/api/tracks/[id]/playlist.ts index d732116..653dbdd 100644 --- a/mobile/src/api/tracks/[id]/playlist.ts +++ b/mobile/src/api/tracks/[id]/playlist.ts @@ -6,7 +6,6 @@ import { } from "@tanstack/react-query"; import { and, eq } from "drizzle-orm"; import { useCallback } from "react"; -import { Toast } from "react-native-toast-notifications"; import { db } from "@/db"; import { playlists, tracksToPlaylists } from "@/db/schema"; @@ -138,7 +137,6 @@ export function useDeleteTrackFromPlaylist( if (wasFavorited) { queryClient.invalidateQueries({ queryKey: favoriteKeys.lists() }); } - Toast.show("Removed track from playlist."); }, }); } diff --git a/mobile/src/modules/media/services/Music.ts b/mobile/src/modules/media/services/Music.ts index 51c7b5e..66876d8 100644 --- a/mobile/src/modules/media/services/Music.ts +++ b/mobile/src/modules/media/services/Music.ts @@ -4,9 +4,9 @@ * This file contains classes containing helpers to manipulate the store. */ +import { toast } from "@backpackapp-io/react-native-toast"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { eq } from "drizzle-orm"; -import { Toast } from "react-native-toast-notifications"; import TrackPlayer, { State } from "react-native-track-player"; import { useStore } from "zustand"; import { @@ -27,6 +27,9 @@ import { } from "@/db/queries"; import { formatForMediaCard } from "@/db/utils/formatters"; +import i18next from "@/modules/i18n"; + +import { ToastOptions } from "@/lib/toast"; import { shuffleArray } from "@/utils/object"; import { ReservedPlaylists } from "../constants"; import { @@ -367,11 +370,11 @@ musicStore.subscribe( /** Helpers to manipulate the current queue. */ export class Queue { /** Add a track id at the end of the current queue. */ - static async add(trackId: string) { + static async add(trackId: string, trackName?: string) { musicStore.setState((prev) => ({ queueList: [...prev.queueList, trackId], })); - Toast.show("Added track to queue."); + toast(i18next.t("response.queueAdd", { name: trackName }), ToastOptions); await RNTPManager.reloadNextTrack(); } diff --git a/mobile/src/modules/scanning/helpers/rescan.ts b/mobile/src/modules/scanning/helpers/rescan.ts index d5b4dde..76b40bf 100644 --- a/mobile/src/modules/scanning/helpers/rescan.ts +++ b/mobile/src/modules/scanning/helpers/rescan.ts @@ -1,6 +1,6 @@ +import { toast } from "@backpackapp-io/react-native-toast"; import { useMutation } from "@tanstack/react-query"; import { eq } from "drizzle-orm"; -import { Toast } from "react-native-toast-notifications"; import { db } from "@/db"; import { fileNodes, invalidTracks, tracks } from "@/db/schema"; @@ -9,6 +9,7 @@ import { getTracks } from "@/db/queries"; import i18next from "@/modules/i18n"; import { RecentList, Resynchronize } from "@/modules/media/services/Music"; +import { ToastOptions } from "@/lib/toast"; import { batch } from "@/utils/promise"; import { findAndSaveArtwork, cleanupImages } from "../helpers/artwork"; import { cleanupDatabase, findAndSaveAudio } from "./audio"; @@ -16,7 +17,10 @@ import { savePathComponents } from "./folder"; /** Look through our library for any new or updated tracks. */ export async function rescanForTracks() { - const toastId = Toast.show(i18next.t("response.scanStart"), { duration: 0 }); + const toastId = toast(i18next.t("response.scanStart"), { + ...ToastOptions, + duration: Infinity, + }); try { // Slight buffer before we run our code due to the code blocking the @@ -58,14 +62,17 @@ export async function rescanForTracks() { // Make sure the "recents" list is correct. RecentList.refresh(); - Toast.update(toastId, i18next.t("response.scanSuccess"), { - duration: 3000, + toast(i18next.t("response.scanSuccess"), { + ...ToastOptions, + id: toastId, + duration: 4000, }); } catch (err) { console.log(err); - Toast.update(toastId, i18next.t("response.scanFail"), { - type: "danger", - duration: 3000, + toast.error(i18next.t("response.scanFail"), { + ...ToastOptions, + id: toastId, + duration: 4000, }); } } diff --git a/mobile/src/screens/Sheets/Backup/data.ts b/mobile/src/screens/Sheets/Backup/data.ts index 5ea0307..7e56708 100644 --- a/mobile/src/screens/Sheets/Backup/data.ts +++ b/mobile/src/screens/Sheets/Backup/data.ts @@ -1,3 +1,4 @@ +import { toast } from "@backpackapp-io/react-native-toast"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import * as DocumentPicker from "expo-document-picker"; import * as FileSystem from "expo-file-system"; @@ -5,7 +6,6 @@ import * as Sharing from "expo-sharing"; import { and, eq, isNull } from "drizzle-orm"; import { useTranslation } from "react-i18next"; import { Platform } from "react-native"; -import { Toast } from "react-native-toast-notifications"; import { z } from "zod"; import { db } from "@/db"; @@ -24,6 +24,7 @@ import i18next from "@/modules/i18n"; import { Resynchronize, musicStore } from "@/modules/media/services/Music"; import { clearAllQueries } from "@/lib/react-query"; +import { ToastOptions } from "@/lib/toast"; import { pickKeys } from "@/utils/object"; import { isFulfilled } from "@/utils/promise"; import type { Maybe } from "@/utils/types"; @@ -235,10 +236,10 @@ export const useExportBackup = () => { return useMutation({ mutationFn: exportBackup, onSuccess: () => { - Toast.show(t("response.exportSuccess")); + toast(t("response.exportSuccess"), ToastOptions); }, onError: (err) => { - Toast.show(err.message, { type: "danger" }); + toast.error(err.message, ToastOptions); }, }); }; @@ -251,10 +252,10 @@ export const useImportBackup = () => { mutationFn: importBackup, onSuccess: () => { clearAllQueries({ client: queryClient }); - Toast.show(t("response.importSuccess")); + toast(t("response.importSuccess"), ToastOptions); }, onError: (err) => { - Toast.show(err.message, { type: "danger" }); + toast.error(err.message, ToastOptions); }, }); }; diff --git a/mobile/src/screens/Sheets/ScanFilterList/data.ts b/mobile/src/screens/Sheets/ScanFilterList/data.ts index 9e8d983..3ab261d 100644 --- a/mobile/src/screens/Sheets/ScanFilterList/data.ts +++ b/mobile/src/screens/Sheets/ScanFilterList/data.ts @@ -1,14 +1,15 @@ +import { toast } from "@backpackapp-io/react-native-toast"; import { PrimaryDirectoryPath, StorageVolumesDirectoryPaths, } from "@missingcore/react-native-metadata-retriever"; import { useMutation } from "@tanstack/react-query"; import * as FileSystem from "expo-file-system"; -import { Toast } from "react-native-toast-notifications"; import i18next from "@/modules/i18n"; import { userPreferencesStore } from "@/services/UserPreferences"; +import { ToastOptions } from "@/lib/toast"; import { addTrailingSlash } from "@/utils/string"; const SAF = FileSystem.StorageAccessFramework; @@ -41,7 +42,7 @@ export function validatePath(path: string) { export async function pickPath() { const permissions = await SAF.requestDirectoryPermissionsAsync(); if (!permissions.granted) { - Toast.show(i18next.t("response.actionCancel"), { type: "danger" }); + toast.error(i18next.t("response.actionCancel"), ToastOptions); return; } @@ -83,9 +84,10 @@ async function addPathToList(props: { ); if (!exists || !isDirectory) throw Error(); } catch { - Toast.show(i18next.t("template.notFound", { name: trimmed }), { - type: "danger", - }); + toast.error( + i18next.t("template.notFound", { name: trimmed }), + ToastOptions, + ); return; } userPreferencesStore.setState((prev) => ({ diff --git a/mobile/src/screens/Sheets/ScanFilterList/index.tsx b/mobile/src/screens/Sheets/ScanFilterList/index.tsx index 749e1e7..0b1dcf2 100644 --- a/mobile/src/screens/Sheets/ScanFilterList/index.tsx +++ b/mobile/src/screens/Sheets/ScanFilterList/index.tsx @@ -4,7 +4,7 @@ import { } from "@missingcore/react-native-metadata-retriever"; import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; -import { View } from "react-native"; +import { Keyboard, View } from "react-native"; import type { SheetProps } from "react-native-actions-sheet"; import { FlashList } from "react-native-actions-sheet/dist/src/views/FlashList"; @@ -138,13 +138,14 @@ function FilterForm(props: { + onPress={() => { + Keyboard.dismiss(); mutateGuard(onSubmit, { list: props.listType, path: newPath, onSuccess: () => setNewPath(""), - }) - } + }); + }} disabled={!isValidPath || onSubmit.isPending} className="bg-red" > diff --git a/mobile/src/screens/Sheets/Track.tsx b/mobile/src/screens/Sheets/Track.tsx index bfa41df..85bc224 100644 --- a/mobile/src/screens/Sheets/Track.tsx +++ b/mobile/src/screens/Sheets/Track.tsx @@ -121,7 +121,7 @@ function AddActions({ data }: { data: TrackData }) { preventClose /> Queue.add(data.id)} + onPress={() => Queue.add(data.id, data.name)} Icon={} text={t("trackModal.queueAdd")} /> diff --git a/mobile/src/services/PlaybackService.ts b/mobile/src/services/PlaybackService.ts index 3d60d65..d6b5841 100644 --- a/mobile/src/services/PlaybackService.ts +++ b/mobile/src/services/PlaybackService.ts @@ -1,5 +1,5 @@ +import { toast } from "@backpackapp-io/react-native-toast"; import { router } from "expo-router"; -import { Toast } from "react-native-toast-notifications"; import TrackPlayer, { AppKilledPlaybackBehavior, Capability, @@ -9,6 +9,7 @@ import TrackPlayer, { import { deleteTrack } from "@/db/queries"; +import i18next from "@/modules/i18n"; import type { TrackStatus } from "@/modules/media/services/Music"; import { Queue, @@ -20,6 +21,7 @@ import { MusicControls } from "@/modules/media/services/Playback"; import { removeUnusedCategories } from "@/modules/scanning/helpers/audio"; import { clearAllQueries } from "@/lib/react-query"; +import { ToastOptions } from "@/lib/toast"; /** How we handle the actions in the media control notification. */ export async function PlaybackService() { @@ -120,7 +122,10 @@ export async function PlaybackService() { router.navigate("/"); } - Toast.show("Track no longer exists.", { type: "danger", duration: 3000 }); + toast.error( + i18next.t("template.notFound", { name: erroredTrack?.title }), + ToastOptions, + ); // Clear all reference of the current playing track. await resetState(); }); From 3a1e2ddc62babdfb53e428caa6040ca8236811cc Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:05:15 -0500 Subject: [PATCH 6/7] chore: Removed `react-native-toast-notifications` --- THIRD_PARTY.md | 1 - mobile/package.json | 1 - mobile/pnpm-lock.yaml | 13 ------- .../licenses/licenseClarification.json | 3 -- mobile/src/providers/ToastProvider.tsx | 34 ------------------- mobile/src/providers/index.tsx | 21 +++++------- mobile/src/resources/licenses.json | 8 ----- 7 files changed, 9 insertions(+), 72 deletions(-) delete mode 100644 mobile/src/providers/ToastProvider.tsx diff --git a/THIRD_PARTY.md b/THIRD_PARTY.md index 1db0f94..fd72ee9 100644 --- a/THIRD_PARTY.md +++ b/THIRD_PARTY.md @@ -49,7 +49,6 @@ | react-native-safe-area-context | MIT | https://github.com/th3rdwave/react-native-safe-area-context | | react-native-screens | MIT | https://github.com/software-mansion/react-native-screens | | react-native-svg | MIT | https://github.com/software-mansion/react-native-svg | -| react-native-toast-notifications | MIT | https://github.com/arnnis/react-native-toast-notifications | | react-native-track-player | Apache-2.0 | https://github.com/doublesymmetry/react-native-track-player | | Roboto Font | Apache-2.0 | https://github.com/googlefonts/roboto | | tailwind-merge | MIT | https://github.com/dcastil/tailwind-merge | diff --git a/mobile/package.json b/mobile/package.json index 6e585c4..5e98e0e 100644 --- a/mobile/package.json +++ b/mobile/package.json @@ -68,7 +68,6 @@ "react-native-safe-area-context": "4.11.1", "react-native-screens": "~3.34.0", "react-native-svg": "^15.8.0", - "react-native-toast-notifications": "^3.4.0", "react-native-track-player": "^4.1.1", "tailwind-merge": "^2.5.4", "zod": "^3.23.8", diff --git a/mobile/pnpm-lock.yaml b/mobile/pnpm-lock.yaml index fb25a47..1a93c02 100644 --- a/mobile/pnpm-lock.yaml +++ b/mobile/pnpm-lock.yaml @@ -151,9 +151,6 @@ dependencies: react-native-svg: specifier: ^15.8.0 version: 15.8.0(react-native@0.75.4)(react@18.3.1) - react-native-toast-notifications: - specifier: ^3.4.0 - version: 3.4.0(react-native@0.75.4)(react@18.3.1) react-native-track-player: specifier: ^4.1.1 version: 4.1.1(react-native@0.75.4)(react@18.3.1) @@ -10767,16 +10764,6 @@ packages: warn-once: 0.1.1 dev: false - /react-native-toast-notifications@3.4.0(react-native@0.75.4)(react@18.3.1): - resolution: {integrity: sha512-ZvB//jLhRiBRemtcH7vGP1maiKCikqtW4aDqo+QYvEIOcX0y3GrjxRayVAqI4oh0qJgd/26DkbM8COobj+0MEQ==} - peerDependencies: - react: '*' - react-native: '*' - dependencies: - react: 18.3.1 - react-native: 0.75.4(@babel/core@7.25.8)(@babel/preset-env@7.25.8)(@types/react@18.3.11)(react@18.3.1)(typescript@5.6.3) - dev: false - /react-native-track-player@4.1.1(react-native@0.75.4)(react@18.3.1): resolution: {integrity: sha512-E5N/eK/+HtAVJUAzXpm1cWz8ROheV9jb0TI6h2bM+333U+DWibTTnT2T1122FkCoXLXIYavtm2FR2if+5jH8cA==} peerDependencies: diff --git a/mobile/scripts/licenses/licenseClarification.json b/mobile/scripts/licenses/licenseClarification.json index 7ce767e..28ce911 100644 --- a/mobile/scripts/licenses/licenseClarification.json +++ b/mobile/scripts/licenses/licenseClarification.json @@ -90,9 +90,6 @@ "repository": "https://github.com/expo/expo/tree/main/packages/expo-web-browser", "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2015-present 650 Industries, Inc. (aka Expo)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." }, - "react-native-toast-notifications@3.4.0": { - "repository": "https://github.com/arnnis/react-native-toast-notifications" - }, "react-native-track-player@4.1.1": { "copyright": "Copyright (c) 2017 Double Symmetry" }, diff --git a/mobile/src/providers/ToastProvider.tsx b/mobile/src/providers/ToastProvider.tsx deleted file mode 100644 index 5a0a6a3..0000000 --- a/mobile/src/providers/ToastProvider.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { View } from "react-native"; -import { ToastProvider as RNTNProvider } from "react-native-toast-notifications"; - -import { cn } from "@/lib/style"; -import { StyledText } from "@/components/new/Typography"; - -/** Customize the style of the toasts displayed by `react-native-toast-notifications`. */ -export function ToastProvider({ children }: { children: React.ReactNode }) { - return ( - ( - - - {message} - - - )} - > - {children} - - ); -} diff --git a/mobile/src/providers/index.tsx b/mobile/src/providers/index.tsx index 2998bd3..5e6ba7a 100644 --- a/mobile/src/providers/index.tsx +++ b/mobile/src/providers/index.tsx @@ -8,7 +8,6 @@ import { SafeAreaProvider } from "react-native-safe-area-context"; import "@/screens/Sheets"; import { RouteHandlers } from "./RouteHandlers"; import { ThemeProvider } from "./ThemeProvider"; -import { ToastProvider } from "./ToastProvider"; import { queryClient } from "@/lib/react-query"; @@ -18,17 +17,15 @@ export function AppProvider({ children }: { children: React.ReactNode }) { - - - - - - {children} - - - - - + + + + + {children} + + + + diff --git a/mobile/src/resources/licenses.json b/mobile/src/resources/licenses.json index 5d49e42..854cf97 100644 --- a/mobile/src/resources/licenses.json +++ b/mobile/src/resources/licenses.json @@ -391,14 +391,6 @@ "license": "MIT", "licenseText": "The MIT License (MIT)\n\nCopyright (c) [2015-2016] [Horcrux]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." }, - "react-native-toast-notifications": { - "name": "react-native-toast-notifications", - "version": "3.4.0", - "copyright": "Copyright (c) 2020 Alireza Rezania", - "source": "https://github.com/arnnis/react-native-toast-notifications", - "license": "MIT", - "licenseText": "MIT License\r\n\r\nCopyright (c) 2020 Alireza Rezania\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE." - }, "react-native-track-player": { "name": "react-native-track-player", "version": "4.1.1", From 1a34b81d0c9c506c6c8c3aa56e68f433f095c7fc Mon Sep 17 00:00:00 2001 From: cyanChill <83375816+cyanChill@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:44:12 -0500 Subject: [PATCH 7/7] chore: Add shadow to toast - Narrowed down an elevation that's effective also in dark mode, but doens't look too off-putting in light mode --- mobile/src/lib/toast.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/mobile/src/lib/toast.tsx b/mobile/src/lib/toast.tsx index af5562f..2782482 100644 --- a/mobile/src/lib/toast.tsx +++ b/mobile/src/lib/toast.tsx @@ -25,6 +25,7 @@ function CustomToast({ type, message, height, width }: Toast) { className="items-center justify-center" >