diff --git a/app.json b/app.json index aa89521..fe0686d 100644 --- a/app.json +++ b/app.json @@ -15,9 +15,7 @@ "updates": { "fallbackToCacheTimeout": 0 }, - "assetBundlePatterns": [ - "**/*" - ], + "assetBundlePatterns": ["**/*"], "ios": { "supportsTablet": true }, @@ -39,7 +37,14 @@ "plugins": [ "expo-font", "expo-localization", - "expo-asset" + "expo-asset", + [ + "expo-media-library", + { + "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.", + "isAccessMediaLocationEnabled": true + } + ] ] } } diff --git a/package.json b/package.json index cda8b60..4ac9771 100644 --- a/package.json +++ b/package.json @@ -38,10 +38,12 @@ "expo": "~51.0.4", "expo-asset": "~10.0.6", "expo-constants": "~16.0.1", + "expo-file-system": "~17.0.1", "expo-font": "~12.0.5", "expo-linking": "~6.3.1", "expo-localization": "~15.0.3", "expo-location": "~17.0.1", + "expo-media-library": "~16.0.3", "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", "expo-web-browser": "~13.0.3", diff --git a/src/screens/WallpaperInfo/index.tsx b/src/screens/WallpaperInfo/index.tsx index 8e036d0..527cd2c 100644 --- a/src/screens/WallpaperInfo/index.tsx +++ b/src/screens/WallpaperInfo/index.tsx @@ -1,4 +1,5 @@ import { RootStackScreenProps } from "@/navigation/types.d"; +import { useWallpaperStorage } from "@/wallpaper/hooks/useWallpaperStorage"; import { useNavigation } from "@react-navigation/native"; import { ImageBackground, StatusBar, StyleSheet } from "react-native"; import { BackButton } from "./BackButton"; @@ -9,21 +10,18 @@ const statusBarHeight = StatusBar.currentHeight ?? 0; export default function WallpaperInfoScreen({ route: { params }, }: RootStackScreenProps<"WallpaperInfo">) { - const { wallpaper } = params; const navigator = useNavigation(); + const { storeWallpaper } = useWallpaperStorage(); - const goBack = () => { - navigator.goBack(); - }; - - const downloadWallpaper = () => { - console.log("Downloading wallpaper..."); - }; + const { wallpaper } = params; return ( - - + + storeWallpaper(wallpaper)} + /> ); } diff --git a/src/wallpaper/hooks/useWallpaperStorage.ts b/src/wallpaper/hooks/useWallpaperStorage.ts new file mode 100644 index 0000000..295d0ff --- /dev/null +++ b/src/wallpaper/hooks/useWallpaperStorage.ts @@ -0,0 +1,56 @@ +import * as FileSystem from "expo-file-system"; +import * as MediaLibrary from "expo-media-library"; +import { useState } from "react"; +import { Uri } from "../interfaces"; + +const ALBUM_NAME = "Sweather Wallpaper"; +const WALLPAPER_NAME = "wallpaper.jpg"; + +export const useWallpaperStorage = () => { + const [error, setError] = useState(""); + const [permissionResponse, requestPermission] = MediaLibrary.usePermissions({ + writeOnly: true, + }); + + const moveWallpaperToAlbum = async (wallpaper: string, albumName: string) => { + try { + const album = await MediaLibrary.getAlbumAsync(albumName); + const asset = await MediaLibrary.createAssetAsync(wallpaper); + + if (album == null) { + await MediaLibrary.createAlbumAsync(albumName, asset, false); + } else { + await MediaLibrary.addAssetsToAlbumAsync([asset], album, false); + } + } catch (err) { + if (err instanceof Error) { + setError( + `Error setting wallpaper in album "${albumName}": ` + err.message + ); + } + } + }; + + const storeWallpaper = async (wallpaper: Uri) => { + const fileUri = FileSystem.documentDirectory + WALLPAPER_NAME; + + try { + const res = await FileSystem.downloadAsync(wallpaper.uri, fileUri); + + if (permissionResponse?.status !== "granted") { + await requestPermission(); + } + + moveWallpaperToAlbum(res.uri, ALBUM_NAME); + } catch (err) { + if (err instanceof Error) { + setError("Error downloading wallpaper: " + err.message); + } + } + }; + + return { + storeWallpaper, + error, + }; +}; diff --git a/yarn.lock b/yarn.lock index e4d4413..ca7d13b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5364,6 +5364,11 @@ expo-location@~17.0.1: resolved "https://registry.yarnpkg.com/expo-location/-/expo-location-17.0.1.tgz#3bdbf91066f1a40ec3468dc1807f3e106473f74c" integrity sha512-m+OzotzlAXO3ZZ1uqW5GC25nXW868zN+ROyBA1V4VF6jGay1ZEs4URPglCVUDzZby2F5wt24cMzqDKw2IX6nRw== +expo-media-library@~16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-16.0.3.tgz#789277a827b9c04e59eef84aa11f4edcf5f1cfce" + integrity sha512-E++h+ZyVOXhGOKddeg/wjoEFH+JAGazcAsMpjAOT+/F69nrIEl27Fymi9XVAzooazp38dKrDBNeOJuWoXUdUAw== + expo-modules-autolinking@1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.11.1.tgz#4a867f727d9dfde07de8dde14b333a3cbf82ce3c" @@ -5382,6 +5387,11 @@ expo-modules-core@1.12.10: dependencies: invariant "^2.2.4" +expo-permissions@^14.4.0: + version "14.4.0" + resolved "https://registry.yarnpkg.com/expo-permissions/-/expo-permissions-14.4.0.tgz#d7bb2f0026b87e1294ee551969c35306193f4ad3" + integrity sha512-oAcnJ7dlZhpBydK73cwomA2xofizayVUz+FW5REl7dMu7MYyeN/3aqhlpZ3mYddrxvG161bqu97MQr01UixUnw== + expo-pwa@0.0.127: version "0.0.127" resolved "https://registry.yarnpkg.com/expo-pwa/-/expo-pwa-0.0.127.tgz#b8d2fd28efff408a24e0f2539bfb47e09f8e4ebe"