mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 10:37:13 -04:00 
			
		
		
		
	Add avatar upload setting
This commit is contained in:
		
							parent
							
								
									0bd497279d
								
							
						
					
					
						commit
						2ecda09ee4
					
				| @ -34,6 +34,7 @@ | ||||
| 		"expo-dev-client": "~3.3.7", | ||||
| 		"expo-file-system": "~16.0.5", | ||||
| 		"expo-font": "~11.10.2", | ||||
| 		"expo-image-picker": "~14.7.1", | ||||
| 		"expo-linear-gradient": "~12.7.1", | ||||
| 		"expo-linking": "~6.2.2", | ||||
| 		"expo-localization": "~14.8.3", | ||||
|  | ||||
| @ -108,6 +108,7 @@ const nextConfig = { | ||||
| 		"expo-av", | ||||
| 		"expo-modules-core", | ||||
| 		"expo-linear-gradient", | ||||
| 		"expo-image-picker", | ||||
| 	], | ||||
| 	experimental: { | ||||
| 		outputFileTracingRoot: path.join(__dirname, "../../"), | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
| 		"@tanstack/react-query": "^5.17.19", | ||||
| 		"@tanstack/react-query-devtools": "^5.17.21", | ||||
| 		"array-shuffle": "^3.0.0", | ||||
| 		"expo-image-picker": "~14.7.1", | ||||
| 		"expo-linear-gradient": "^12.7.1", | ||||
| 		"expo-modules-core": "^1.11.8", | ||||
| 		"hls.js": "^1.5.2", | ||||
|  | ||||
| @ -48,6 +48,7 @@ export const queryFn = async <Parser extends z.ZodTypeAny>( | ||||
| 		| ({ | ||||
| 				path: (string | false | undefined | null)[]; | ||||
| 				body?: object; | ||||
| 				formData?: FormData; | ||||
| 				plainText?: boolean; | ||||
| 		  } & Partial<QueryFunctionContext>) | ||||
| 	), | ||||
| @ -72,7 +73,12 @@ export const queryFn = async <Parser extends z.ZodTypeAny>( | ||||
| 	try { | ||||
| 		resp = await fetch(path, { | ||||
| 			method: context.method, | ||||
| 			body: "body" in context && context.body ? JSON.stringify(context.body) : undefined, | ||||
| 			body: | ||||
| 				"body" in context && context.body | ||||
| 					? JSON.stringify(context.body) | ||||
| 					: "formData" in context && context.formData | ||||
| 						? context.formData | ||||
| 						: undefined, | ||||
| 			headers: { | ||||
| 				...(token ? { Authorization: token } : {}), | ||||
| 				...("body" in context ? { "Content-Type": "application/json" } : {}), | ||||
|  | ||||
| @ -23,8 +23,7 @@ import { useYoshiki, px, Stylable } from "yoshiki/native"; | ||||
| import { Icon } from "./icons"; | ||||
| import { P } from "./text"; | ||||
| import AccountCircle from "@material-symbols/svg-400/rounded/account_circle-fill.svg"; | ||||
| import { YoshikiStyle } from "yoshiki"; | ||||
| import { ComponentType, forwardRef, RefAttributes, useEffect, useState } from "react"; | ||||
| import { ComponentType, forwardRef, RefAttributes } from "react"; | ||||
| 
 | ||||
| const stringToColor = (string: string) => { | ||||
| 	let hash = 0; | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| 		"@shopify/flash-list": "^1.3.1", | ||||
| 		"@tanstack/react-query": "*", | ||||
| 		"expo-file-system": "*", | ||||
| 		"expo-image-picker": "~14.7.1", | ||||
| 		"expo-linear-gradient": "*", | ||||
| 		"expo-router": "*", | ||||
| 		"i18next": "*", | ||||
|  | ||||
| @ -19,21 +19,33 @@ | ||||
|  */ | ||||
| 
 | ||||
| import { Account, KyooErrors, deleteAccount, logout, queryFn, useAccount } from "@kyoo/models"; | ||||
| import { Alert, Button, H1, Icon, Input, P, Popup, ts, usePopup } from "@kyoo/primitives"; | ||||
| import { Alert, Avatar, Button, H1, Icon, Input, P, Popup, ts, usePopup } from "@kyoo/primitives"; | ||||
| import { useMutation, useQueryClient } from "@tanstack/react-query"; | ||||
| import { ComponentProps, useState } from "react"; | ||||
| import { useTranslation } from "react-i18next"; | ||||
| import { View } from "react-native"; | ||||
| import { rem, useYoshiki } from "yoshiki/native"; | ||||
| import * as ImagePicker from "expo-image-picker"; | ||||
| import { PasswordInput } from "../login/password-input"; | ||||
| import { Preference, SettingsContainer } from "./base"; | ||||
| 
 | ||||
| import Username from "@material-symbols/svg-400/outlined/badge.svg"; | ||||
| import AccountCircle from "@material-symbols/svg-400/rounded/account_circle-fill.svg"; | ||||
| import Mail from "@material-symbols/svg-400/outlined/mail.svg"; | ||||
| import Password from "@material-symbols/svg-400/outlined/password.svg"; | ||||
| import Delete from "@material-symbols/svg-400/rounded/delete.svg"; | ||||
| import Logout from "@material-symbols/svg-400/rounded/logout.svg"; | ||||
| 
 | ||||
| function dataURItoBlob(dataURI: string) { | ||||
| 	const byteString = atob(dataURI.split(",")[1]); | ||||
| 	const ab = new ArrayBuffer(byteString.length); | ||||
| 	const ia = new Uint8Array(ab); | ||||
| 	for (var i = 0; i < byteString.length; i++) { | ||||
| 		ia[i] = byteString.charCodeAt(i); | ||||
| 	} | ||||
| 	return new Blob([ab], { type: "image/jpeg" }); | ||||
| } | ||||
| 
 | ||||
| export const AccountSettings = () => { | ||||
| 	const account = useAccount()!; | ||||
| 	const { css, theme } = useYoshiki(); | ||||
| @ -118,6 +130,33 @@ export const AccountSettings = () => { | ||||
| 					} | ||||
| 				/> | ||||
| 			</Preference> | ||||
| 			<Preference | ||||
| 				icon={AccountCircle} | ||||
| 				customIcon={<Avatar src={account.logo} />} | ||||
| 				label={t("settings.account.avatar.label")} | ||||
| 				description={t("settings.account.avatar.description")} | ||||
| 			> | ||||
| 				<Button | ||||
| 					text={t("misc.edit")} | ||||
| 					onPress={async () => { | ||||
| 						const img = await ImagePicker.launchImageLibraryAsync({ | ||||
| 							mediaTypes: ImagePicker.MediaTypeOptions.Images, | ||||
| 							aspect: [1, 1], | ||||
| 							quality: 1, | ||||
| 							base64: true, | ||||
| 						}); | ||||
| 						if (img.canceled || img.assets.length !== 1) return; | ||||
| 						const data = dataURItoBlob(img.assets[0].uri); | ||||
| 						const formData = new FormData(); | ||||
| 						formData.append("picture", data); | ||||
| 						await queryFn({ | ||||
| 							method: "POST", | ||||
| 							path: ["auth", "me", "logo"], | ||||
| 							formData, | ||||
| 						}); | ||||
| 					}} | ||||
| 				/> | ||||
| 			</Preference> | ||||
| 			<Preference icon={Mail} label={t("settings.account.email.label")} description={account.email}> | ||||
| 				<Button | ||||
| 					text={t("misc.edit")} | ||||
|  | ||||
| @ -36,12 +36,14 @@ import { View } from "react-native"; | ||||
| import { px, rem, useYoshiki } from "yoshiki/native"; | ||||
| 
 | ||||
| export const Preference = ({ | ||||
| 	customIcon, | ||||
| 	icon, | ||||
| 	label, | ||||
| 	description, | ||||
| 	children, | ||||
| 	...props | ||||
| }: { | ||||
| 	customIcon?: ReactElement; | ||||
| 	icon: Icon; | ||||
| 	label: string; | ||||
| 	description: string; | ||||
| @ -62,8 +64,16 @@ export const Preference = ({ | ||||
| 				props, | ||||
| 			)} | ||||
| 		> | ||||
| 			<View {...css({ flexDirection: "row", alignItems: "center", flexShrink: 1 })}> | ||||
| 				<Icon icon={icon} {...css({ marginX: ts(2) })} /> | ||||
| 			<View | ||||
| 				{...css({ | ||||
| 					flexDirection: "row", | ||||
| 					alignItems: "center", | ||||
| 					flexShrink: 1, | ||||
| 					marginX: ts(2), | ||||
| 					gap: ts(2), | ||||
| 				})} | ||||
| 			> | ||||
| 				{customIcon ?? <Icon icon={icon} />} | ||||
| 				<View {...css({ flexShrink: 1 })}> | ||||
| 					<P {...css({ marginBottom: 0 })}>{label}</P> | ||||
| 					<SubP>{description}</SubP> | ||||
|  | ||||
| @ -2619,6 +2619,7 @@ __metadata: | ||||
|     "@shopify/flash-list": ^1.3.1 | ||||
|     "@tanstack/react-query": "*" | ||||
|     expo-file-system: "*" | ||||
|     expo-image-picker: ~14.7.1 | ||||
|     expo-linear-gradient: "*" | ||||
|     expo-router: "*" | ||||
|     i18next: "*" | ||||
| @ -7420,6 +7421,26 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "expo-image-loader@npm:~4.6.0": | ||||
|   version: 4.6.0 | ||||
|   resolution: "expo-image-loader@npm:4.6.0" | ||||
|   peerDependencies: | ||||
|     expo: "*" | ||||
|   checksum: 02981667f03dc429cd9db37e0acc302e4a0c4bb5875dc087b1c26388ef64563481e52dddc1d42dd32794eb7051d1acf5bc0c078413469c29025a02d4d4af1154 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "expo-image-picker@npm:~14.7.1": | ||||
|   version: 14.7.1 | ||||
|   resolution: "expo-image-picker@npm:14.7.1" | ||||
|   dependencies: | ||||
|     expo-image-loader: ~4.6.0 | ||||
|   peerDependencies: | ||||
|     expo: "*" | ||||
|   checksum: f9022cc9162365471b8e979df2c7a2156f43819b4717fb6ba376aedb6b55352a7b60b3a50a279dd58cf2551fbdd8a0719c5c903dcde4703436029e0fdca9c035 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "expo-json-utils@npm:~0.12.0": | ||||
|   version: 0.12.3 | ||||
|   resolution: "expo-json-utils@npm:0.12.3" | ||||
| @ -10426,6 +10447,7 @@ __metadata: | ||||
|     expo-dev-client: ~3.3.7 | ||||
|     expo-file-system: ~16.0.5 | ||||
|     expo-font: ~11.10.2 | ||||
|     expo-image-picker: ~14.7.1 | ||||
|     expo-linear-gradient: ~12.7.1 | ||||
|     expo-linking: ~6.2.2 | ||||
|     expo-localization: ~14.8.3 | ||||
| @ -13998,6 +14020,7 @@ __metadata: | ||||
|     copy-webpack-plugin: ^12.0.2 | ||||
|     eslint: ^8.56.0 | ||||
|     eslint-config-next: 14.1.0 | ||||
|     expo-image-picker: ~14.7.1 | ||||
|     expo-linear-gradient: ^12.7.1 | ||||
|     expo-modules-core: ^1.11.8 | ||||
|     hls.js: ^1.5.2 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user