diff --git a/src/controllers/ApiController.ts b/src/controllers/ApiController.ts deleted file mode 100644 index e2cdace..0000000 --- a/src/controllers/ApiController.ts +++ /dev/null @@ -1,80 +0,0 @@ -import axios, { AxiosError, AxiosInstance } from "axios" -import { PostMediaResponse } from "../types/media" -import sha256 from 'crypto-js/sha256' -import Hex from 'crypto-js/enc-hex' -import { NostrController } from "." - -export class ApiController { - private mediaUrl: string = 'https://media.nquiz.io' - private api: AxiosInstance - private baseUrl: string = '' - - private nostrController = NostrController.getInstance() - - constructor(baseUrl?: string) { - this.baseUrl = baseUrl ?? this.baseUrl - - this.api = axios.create({ - withCredentials: true, - baseURL: this.baseUrl, - headers: { - 'Content-Type': 'application/json' - } - }) - } - - uploadMediaImage = async ( - file: Buffer, - ): Promise => { - const mediaUrl = this.mediaUrl - - const formData = new FormData() - const imageBlob = new Blob([file]) - formData.append('mediafile', imageBlob) - - const endpointUrl = 'v1/media' - const tags = [ - ['u', `${mediaUrl}/${endpointUrl}`], - ['method', 'POST'], - ['payload', this.hashString('{}')] - ] - - const authToken = await this.nostrController.createNostrHttpAuthToken(tags) - - console.info('Auth token created for media server.', authToken) - - return axios - .post(`${mediaUrl}/api/v1/media`, formData, { - headers: { - 'Content-Type': 'multipart/form-data', - Authorization: `Nostr ${authToken}` - } - }) - .then((res) => { - console.info( - `POST ${mediaUrl}/api/v1/media | res.data:`, - res.data - ) - // Create correct api url, because res.url is not including 'api/v1/' - if (!res || !res.data) { - console.warn('Image upload: no data returned after upload') - } - - const data = res.data - data.directLink = `${data.url.replace(mediaUrl, `${mediaUrl}/api/v1`)}` - - return data - }) - .catch((err: AxiosError) => { - console.info(`POST ${mediaUrl}/api/v1/media | err:`, err) - throw { - code: 500, - message: err.response?.data || err.response || err.message || err - } - }) - } - - hashString = (payload: any): string => { - return sha256(payload).toString(Hex) - } -} \ No newline at end of file diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 18927b0..4f64858 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -1,10 +1,13 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy' import { CircularProgress, + IconButton, + InputProps, List, ListItem, ListSubheader, TextField, + Tooltip, Typography, useTheme } from '@mui/material' @@ -23,8 +26,7 @@ import { Dispatch } from '../../store/store' import { setMetadataEvent } from '../../store/actions' import { LoadingSpinner } from '../../components/LoadingSpinner' import { LoginMethods } from '../../store/auth/types' -import { ApiController } from '../../controllers/ApiController' -import { PostMediaResponse } from '../../types/media' +import { SmartToy } from '@mui/icons-material' export const ProfilePage = () => { const theme = useTheme() @@ -45,7 +47,6 @@ export const ProfilePage = () => { const metadataState = useSelector((state: State) => state.metadata) const keys = useSelector((state: State) => state.auth?.keyPair) const { usersPubkey, loginMethod } = useSelector((state: State) => state.auth) - const [uploadingImage, setUploadingImage] = useState() const [isUsersOwnProfile, setIsUsersOwnProfile] = useState(false) @@ -118,7 +119,8 @@ export const ProfilePage = () => { key: keyof ProfileMetadata, label: string, multiline = false, - rows = 1 + rows = 1, + inputProps?: InputProps ) => ( { rows={rows} className={styles.textField} disabled={!isUsersOwnProfile} + InputProps={inputProps} onChange={(event: React.ChangeEvent) => { const { value } = event.target @@ -208,41 +211,6 @@ export const ProfilePage = () => { setSavingProfileMetadata(false) } - const onProfileImageChange = (event: any) => { - const file = event?.target?.files[0] - - if (file) { - setUploadingImage(true) - - const apiController = new ApiController() - - apiController.uploadMediaImage(file).then((imageResponse: PostMediaResponse) => { - if (imageResponse && imageResponse.directLink) { - setTimeout(() => { - setProfileMetadata((prev) => ({ - ...prev, - picture: imageResponse.directLink - })) - }, 200) - } else { - toast.error(`Uploading image failed. Please try again.`) - } - }) - .catch((err) => { - console.error('Error uploading image to media server.', err) - }) - .finally(() => { - setUploadingImage(false) - }) - } - } - - const progressSpinner = (show = false) => { - if (!show) return undefined - - return - } - const generateRobotAvatar = () => { setAvatarLoading(true) @@ -261,6 +229,21 @@ export const ProfilePage = () => { }) } + /** + * + * @returns robohash generate button, loading spinner or no button + */ + const robohashButton = () => { + if (profileMetadata?.picture?.includes('robohash')) return null + + return + {avatarLoading ? + : + + } + + } + return ( <> {isLoading && } @@ -304,20 +287,6 @@ export const ProfilePage = () => { alt='Profile Image' /> - Generate Robot Avatar - - - {nostrJoiningBlock && ( { )} + {editItem('picture', 'Picture URL', undefined, undefined, { + endAdornment: robohashButton() + })} + {editItem('name', 'Username')} {editItem('display_name', 'Display Name')} {editItem('nip05', 'Nostr Address (nip05)')} diff --git a/src/types/media.ts b/src/types/media.ts deleted file mode 100644 index 07e25e7..0000000 --- a/src/types/media.ts +++ /dev/null @@ -1,19 +0,0 @@ -export interface PostMediaResponse { - result: boolean - description: string - status: string - id: number - pubkey: string - url: string - directLink: string - hash: string - magnet: string - tags: any[] -} - -export interface GetMediaResponse extends PostMediaResponse {} - -export interface MediaErrorResponse { - description: string - result: boolean -}