From 47daa9d14376006c294c5f688fdff15b5cee32e1 Mon Sep 17 00:00:00 2001 From: SleeplessOne1917 Date: Sun, 26 Mar 2023 22:06:42 -0400 Subject: [PATCH] refactor: update UI to use new client uploadImage function (#967) Co-authored-by: Dessalines --- package.json | 30 ++++++++-------- .../components/common/image-upload-form.tsx | 19 +++------- .../components/common/markdown-textarea.tsx | 25 ++++--------- src/shared/components/post/post-form.tsx | 21 +++-------- src/shared/env.ts | 1 - src/shared/utils.ts | 7 ++++ yarn.lock | 36 ++++++++++++------- 7 files changed, 62 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index 26f10e9c..d73f3d0c 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,30 @@ { "name": "lemmy-ui", - "description": "An isomorphic UI for lemmy", "version": "0.17.1", - "author": "Dessalines ", + "description": "An isomorphic UI for lemmy", + "repository": "https://github.com/LemmyNet/lemmy-ui", "license": "AGPL-3.0", + "author": "Dessalines ", "scripts": { + "prebuild:dev": "yarn clean && node generate_translations.js", "build:dev": "webpack --mode=development", + "prebuild:prod": "yarn clean && node generate_translations.js", "build:prod": "webpack --mode=production", "clean": "yarn run rimraf dist", "dev": "yarn start", "lint": "node generate_translations.js && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check 'src/**/*.tsx'", - "prebuild:dev": "yarn clean && node generate_translations.js", - "prebuild:prod": "yarn clean && node generate_translations.js", "prepare": "husky install", "start": "yarn build:dev --watch" }, - "repository": "https://github.com/LemmyNet/lemmy-ui", + "lint-staged": { + "*.{ts,tsx,js}": [ + "prettier --write", + "eslint --fix" + ], + "package.json": [ + "sortpack" + ] + }, "dependencies": { "@babel/plugin-proposal-decorators": "^7.21.0", "@babel/plugin-transform-runtime": "^7.21.0", @@ -45,7 +54,7 @@ "inferno-server": "^8.0.6", "isomorphic-cookie": "^1.2.4", "jwt-decode": "^3.1.2", - "lemmy-js-client": "0.17.2-rc.3", + "lemmy-js-client": "0.17.2-rc.4", "markdown-it": "^13.0.1", "markdown-it-container": "^3.0.0", "markdown-it-footnote": "^3.0.3", @@ -107,15 +116,6 @@ "node": ">=8.9.0" }, "engineStrict": true, - "lint-staged": { - "*.{ts,tsx,js}": [ - "prettier --write", - "eslint --fix" - ], - "package.json": [ - "sortpack" - ] - }, "importSort": { ".js, .jsx, .ts, .tsx": { "style": "module", diff --git a/src/shared/components/common/image-upload-form.tsx b/src/shared/components/common/image-upload-form.tsx index 6cf4e147..cfb86150 100644 --- a/src/shared/components/common/image-upload-form.tsx +++ b/src/shared/components/common/image-upload-form.tsx @@ -1,8 +1,7 @@ import { Component, linkEvent } from "inferno"; -import { pictrsUri } from "../../env"; import { i18n } from "../../i18next"; import { UserService } from "../../services"; -import { randomStr, toast } from "../../utils"; +import { randomStr, toast, uploadImage } from "../../utils"; import { Icon } from "./icon"; interface ImageUploadFormProps { @@ -74,25 +73,17 @@ export class ImageUploadForm extends Component< handleImageUpload(i: ImageUploadForm, event: any) { event.preventDefault(); - let file = event.target.files[0]; - const formData = new FormData(); - formData.append("images[]", file); + const file = event.target.files[0]; i.setState({ loading: true }); - fetch(pictrsUri, { - method: "POST", - body: formData, - }) - .then(res => res.json()) + uploadImage(file) .then(res => { console.log("pictrs upload:"); console.log(res); - if (res.msg == "ok") { - let hash = res.files[0].file; - let url = `${pictrsUri}/${hash}`; + if (res.msg === "ok") { i.setState({ loading: false }); - i.props.onUpload(url); + i.props.onUpload(res.url as string); } else { i.setState({ loading: false }); toast(JSON.stringify(res), "danger"); diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index 48b90428..b2eabe25 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -2,7 +2,6 @@ import autosize from "autosize"; import { Component, linkEvent } from "inferno"; import { Prompt } from "inferno-router"; import { Language } from "lemmy-js-client"; -import { pictrsUri } from "../../env"; import { i18n } from "../../i18next"; import { UserService } from "../../services"; import { @@ -16,6 +15,7 @@ import { setupTippy, setupTribute, toast, + uploadImage, } from "../../utils"; import { Icon, Spinner } from "./icon"; import { LanguageSelect } from "./language-select"; @@ -344,38 +344,27 @@ export class MarkdownTextArea extends Component< file = event; } - const formData = new FormData(); - formData.append("images[]", file); - i.setState({ imageLoading: true }); - fetch(pictrsUri, { - method: "POST", - body: formData, - }) - .then(res => res.json()) + uploadImage(file) .then(res => { console.log("pictrs upload:"); console.log(res); - if (res.msg == "ok") { - let hash = res.files[0].file; - let url = `${pictrsUri}/${hash}`; - let deleteToken = res.files[0].delete_token; - let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`; - let imageMarkdown = `![](${url})`; - let content = i.state.content; + if (res.msg === "ok") { + const imageMarkdown = `![](${res.url})`; + const content = i.state.content; i.setState({ content: content ? `${content}\n${imageMarkdown}` : imageMarkdown, imageLoading: false, }); i.contentChange(); - let textarea: any = document.getElementById(i.id); + const textarea: any = document.getElementById(i.id); autosize.update(textarea); pictrsDeleteToast( `${i18n.t("click_to_delete_picture")}: ${file.name}`, `${i18n.t("picture_deleted")}: ${file.name}`, `${i18n.t("failed_to_delete_picture")}: ${file.name}`, - deleteUrl + res.delete_url as string ); } else { i.setState({ imageLoading: false }); diff --git a/src/shared/components/post/post-form.tsx b/src/shared/components/post/post-form.tsx index 490f7dcd..a9b61a35 100644 --- a/src/shared/components/post/post-form.tsx +++ b/src/shared/components/post/post-form.tsx @@ -18,7 +18,6 @@ import { wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; -import { pictrsUri } from "../../env"; import { i18n } from "../../i18next"; import { PostFormParams } from "../../interfaces"; import { UserService, WebSocketService } from "../../services"; @@ -41,6 +40,7 @@ import { setupTippy, toast, trendingFetchLimit, + uploadImage, validTitle, validURL, webArchiveUrl, @@ -587,31 +587,20 @@ export class PostForm extends Component { file = event; } - const formData = new FormData(); - formData.append("images[]", file); - i.setState({ imageLoading: true }); - fetch(pictrsUri, { - method: "POST", - body: formData, - }) - .then(res => res.json()) + uploadImage(file) .then(res => { console.log("pictrs upload:"); console.log(res); - if (res.msg == "ok") { - let hash = res.files[0].file; - let url = `${pictrsUri}/${hash}`; - let deleteToken = res.files[0].delete_token; - let deleteUrl = `${pictrsUri}/delete/${deleteToken}/${hash}`; - i.state.form.url = url; + if (res.msg === "ok") { + i.state.form.url = res.url; i.setState({ imageLoading: false }); pictrsDeleteToast( `${i18n.t("click_to_delete_picture")}: ${file.name}`, `${i18n.t("picture_deleted")}: ${file.name}`, `${i18n.t("failed_to_delete_picture")}: ${file.name}`, - deleteUrl + res.delete_url as string ); } else { i.setState({ imageLoading: false }); diff --git a/src/shared/env.ts b/src/shared/env.ts index 12260e15..3f56a1fb 100644 --- a/src/shared/env.ts +++ b/src/shared/env.ts @@ -37,7 +37,6 @@ export const httpBaseInternal = `http://${host}`; // Don't use secure here export const httpBase = `http${secure}://${host}`; export const wsUriBase = `ws${secure}://${wsHost}`; export const wsUri = `${wsUriBase}/api/v3/ws`; -export const pictrsUri = `${httpBase}/pictrs/image`; export const isHttps = secure.endsWith("s"); console.log(`httpbase: ${httpBase}`); diff --git a/src/shared/utils.ts b/src/shared/utils.ts index bfbd5386..79e2dd49 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -25,6 +25,7 @@ import { Search, SearchType, SortType, + UploadImageResponse, } from "lemmy-js-client"; import { default as MarkdownIt } from "markdown-it"; import markdown_it_container from "markdown-it-container"; @@ -1441,3 +1442,9 @@ export function selectableLanguages( } } } + +export function uploadImage(image: File): Promise { + const client = new LemmyHttp(httpBase); + + return client.uploadImage({ image }); +} diff --git a/yarn.lock b/yarn.lock index cf26c24b..1502167f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2921,6 +2921,13 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" +cross-fetch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -3972,6 +3979,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -5403,12 +5419,13 @@ leac@^0.6.0: resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== -lemmy-js-client@0.17.2-rc.3: - version "0.17.2-rc.3" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.2-rc.3.tgz#dc2a33e9228aef260b03a6e1f55698a2f975f979" - integrity sha512-FlWEPMrW2Q/FbtihLOHq2YtcRuoX7700LweCnsm6R6dD6SzsnWy9nKJhn24fcjcR2o6tw0oZKgP0ccq9jPDgfQ== +lemmy-js-client@0.17.2-rc.4: + version "0.17.2-rc.4" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.2-rc.4.tgz#b4a2d935e2a8d427c8e30ecaac77a46e02354363" + integrity sha512-pV9JALCUb7hvdP2my9ksWThuLciHWwg0MkUL5ClDfTl0ql5Xk+UY3FJ6NCpsOWErBjfLQvqoep/23W92ISh1+Q== dependencies: - node-fetch "2.6.6" + cross-fetch "^3.1.5" + form-data "^4.0.0" levn@^0.4.1: version "0.4.1" @@ -6057,14 +6074,7 @@ node-fetch-npm@^2.0.2: json-parse-better-errors "^1.0.0" safe-buffer "^5.1.1" -node-fetch@2.6.6: - version "2.6.6" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" - integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.1: +node-fetch@2.6.7, node-fetch@^2.6.1: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==