diff --git a/README.md b/README.md index e2584a20..d29dc439 100644 --- a/README.md +++ b/README.md @@ -49,14 +49,14 @@ Developers: you will likely want to run `npm run serve` in one terminal and `npm Ops will want to use `npm run build`, `npm run test` or `npm run test:coverage`, `npm run prettier:check` -## NSFW api +## Configuration -This build uses an API to check nsfw content. +The following environment variables may be used to configure the frontend. -The default API endpoint to is: https://api.ipfs-search.com/nsfw/ -. This can be overridden by injecting environment variable `VITE_NSFW_API` +### Variables -The API call should be: ``, so e.g. - -`https://api.ipfs-search.com/nsfw/QmSZzv7ux1LGwpehVcCMQ9ec945X6qE4qyjKDhCVwY25iw` -https://api.ipfs-search.com/v1/nsfw/classify/ +- `VITE_IPFS_GATEWAY`: Gateway for URL generation. Default: `https://dweb.link` +- `VITE_NSFW_API`: Endpoint for [nsfw-server](https://github.com/ipfs-search/nsfw-server). Default: `https://api.ipfs-search.com/v1/nsfw/classify/` +- `VITE_NYATS_API`: Endpoint for [nyats](https://github.com/ipfs-search/nyats) (Not Yet Another Thumbnail Server) API. Default: `https://api.ipfs-search.com/v1/thumbnail/` +- `VITE_NYATS_IPFS_GATEWAY`: Gateway for nyats. Default: `https://gw.dwebsearch.com` +- `VITE_NYATS_IPNS_ROOT`: Root for thumbnails over IPNS. Default: `/ipns/12D3KooWPVobDRG9Mdmact3ejSe6UAFP8cevmw35HHR1ZDwCozSo/` diff --git a/package-lock.json b/package-lock.json index ca2307fa..fde061be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "masonry-layout": "^4.2.2", "mime": "^3.0.0", "moment": "^2.29.4", + "nyats-client": "^0.2.0-alpha.2", "pretty-bytes": "^6.0.0", "regenerator-runtime": "^0.13.9", "ts-node": "^10.8.0", @@ -49,6 +50,7 @@ "prettier": "2.7.1", "sass": "^1.53.0", "typescript": "^4.7.3", + "url-join": "^5.0.0", "vite": "^3.0.2", "vite-plugin-vuetify": "^1.0.0-alpha.11", "vitest": "^0.13.1" @@ -3419,6 +3421,14 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "node_modules/nyats-client": { + "version": "0.2.0-alpha.2", + "resolved": "https://registry.npmjs.org/nyats-client/-/nyats-client-0.2.0-alpha.2.tgz", + "integrity": "sha512-ctNWNCxmU5d6wiWqXbAIXWiR8/OQ+sp6Ir6vXTpsz7ymsCvVis3M8AzCiRE/V/flY/2dU4jQGiTz6Z6CiPVBEQ==", + "dependencies": { + "url-join": "^5.0.0" + } + }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -4398,6 +4408,14 @@ "querystring": "0.2.0" } }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -7389,6 +7407,14 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "nyats-client": { + "version": "0.2.0-alpha.2", + "resolved": "https://registry.npmjs.org/nyats-client/-/nyats-client-0.2.0-alpha.2.tgz", + "integrity": "sha512-ctNWNCxmU5d6wiWqXbAIXWiR8/OQ+sp6Ir6vXTpsz7ymsCvVis3M8AzCiRE/V/flY/2dU4jQGiTz6Z6CiPVBEQ==", + "requires": { + "url-join": "^5.0.0" + } + }, "object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -8061,6 +8087,11 @@ } } }, + "url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index de31fbfe..5c5d4fa1 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "masonry-layout": "^4.2.2", "mime": "^3.0.0", "moment": "^2.29.4", + "nyats-client": "^0.2.0-alpha.2", "pretty-bytes": "^6.0.0", "regenerator-runtime": "^0.13.9", "ts-node": "^10.8.0", @@ -57,6 +58,7 @@ "prettier": "2.7.1", "sass": "^1.53.0", "typescript": "^4.7.3", + "url-join": "^5.0.0", "vite": "^3.0.2", "vite-plugin-vuetify": "^1.0.0-alpha.11", "vitest": "^0.13.1" diff --git a/src/components/detailViewComponents/ImageDetail.vue b/src/components/detailViewComponents/ImageDetail.vue index c300df4d..fa57320c 100644 --- a/src/components/detailViewComponents/ImageDetail.vue +++ b/src/components/detailViewComponents/ImageDetail.vue @@ -1,22 +1,26 @@ + + + - + diff --git a/src/components/searchViewComponents/ImageList.vue b/src/components/searchViewComponents/ImageList.vue index b4b05f58..bb27f8a6 100644 --- a/src/components/searchViewComponents/ImageList.vue +++ b/src/components/searchViewComponents/ImageList.vue @@ -2,18 +2,17 @@ import NsfwTooltip from "@/components/shared/nsfwTooltip.vue"; import ListBase from "./BaseList.vue"; import HoverCard from "./subcomponents/HoverCard.vue"; -import { useFileListComposable, imports } from "@/composables/useFileListComposable"; +import { useFileListComposable } from "@/composables/useFileListComposable"; import { useBlurExplicit } from "@/composables/BlurExplicitImagesComposable"; import { Types } from "@/helpers/typeHelper"; import { useDisplay } from "vuetify"; +import { mdiRobotDead } from "@mdi/js"; +import NyatsImg from "@/helpers/nyats/vuetify-img-cid.vue"; const fileType = Types.images; const { xs, smAndDown, mdAndDown } = useDisplay(); const { slicedHits } = useFileListComposable({ fileType }); - -const { getResourceURL } = imports; - const { blurExplicit } = useBlurExplicit(); @@ -30,8 +29,9 @@ const { blurExplicit } = useBlurExplicit(); lg="2" > - + + + - + diff --git a/src/components/searchViewComponents/VideoList.vue b/src/components/searchViewComponents/VideoList.vue index 8b76a234..e32cc593 100644 --- a/src/components/searchViewComponents/VideoList.vue +++ b/src/components/searchViewComponents/VideoList.vue @@ -2,38 +2,59 @@ import ListBase from "./BaseList.vue"; import HoverCard from "./subcomponents/HoverCard.vue"; import { useFileListComposable } from "@/composables/useFileListComposable"; +import { useBlurExplicit } from "@/composables/BlurExplicitImagesComposable"; import CardContent from "@/components/searchViewComponents/subcomponents/genericCardContent.vue"; import MediaCenterIcon from "@/components/searchViewComponents/subcomponents/MediaCenterIcon.vue"; import { mdiVideo } from "@mdi/js"; import { Types } from "@/helpers/typeHelper"; -import { picsum } from "@/helpers/picsum"; +import { mdiRobotDead, mdiTimerSand } from "@mdi/js"; +import NyatsImg from "@/helpers/nyats/vuetify-img-cid.vue"; const fileType = Types.video; const { slicedHits } = useFileListComposable({ fileType }); +const { blurExplicit } = useBlurExplicit(); diff --git a/src/composables/useFileListComposable.js b/src/composables/useFileListComposable.js index df9fe007..3c08decd 100644 --- a/src/composables/useFileListComposable.js +++ b/src/composables/useFileListComposable.js @@ -23,7 +23,9 @@ export const useFileListComposable = ({ fileType }) => { return [Types.all, undefined].includes(route.query.type); }); - const infinite = computed(() => route.query.type === Types.images); + const infinite = computed( + () => route.query.type === Types.images || route.query.type === Types.video + ); const loadedPages = computed(() => Math.ceil(store.getters[`results/${fileType}/hits`].length / batchSize) diff --git a/src/helpers/nyats/vuetify-img-cid.vue b/src/helpers/nyats/vuetify-img-cid.vue new file mode 100644 index 00000000..1a0ba9df --- /dev/null +++ b/src/helpers/nyats/vuetify-img-cid.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/helpers/resourceURL.js b/src/helpers/resourceURL.js index 5a79356e..f8054bf5 100644 --- a/src/helpers/resourceURL.js +++ b/src/helpers/resourceURL.js @@ -1,7 +1,6 @@ -const gatewayURL = "https://gateway.ipfs.io"; +const gatewayURL = import.meta.env.VITE_IPFS_GATEWAY || "https://dweb.link"; -function getResourceURL(hash) { - return `${gatewayURL}/ipfs/${hash}`; +export default function getResourceURL(hash) { + const resourcePath = `/ipfs/${hash}`; + return new URL(resourcePath, gatewayURL).toString(); } - -export default getResourceURL; diff --git a/vite.config.js b/vite.config.js index 40106418..47e9e929 100644 --- a/vite.config.js +++ b/vite.config.js @@ -8,7 +8,7 @@ import createVuePlugin from "@vitejs/plugin-vue"; export default defineConfig({ plugins: [createVuePlugin(), vuetify()], server: { - port: 8080, + port: 8082, }, resolve: { alias: {