diff --git a/public/css/index-tailwind-output.css b/public/css/index-tailwind-output.css index 3da0d51cfa..518950b8ed 100644 --- a/public/css/index-tailwind-output.css +++ b/public/css/index-tailwind-output.css @@ -1136,18 +1136,6 @@ input[type="range"].range-lg::-moz-range-thumb { right: 0px; } -.left-24 { - left: 6rem; -} - -.right-24 { - right: 6rem; -} - -.top-56 { - top: 14rem; -} - .bottom-0 { bottom: 0px; } @@ -1332,10 +1320,6 @@ input[type="range"].range-lg::-moz-range-thumb { margin: 0.5rem; } -.m-8 { - margin: 2rem; -} - .m-0\.5 { margin: 0.125rem; } @@ -1356,6 +1340,10 @@ input[type="range"].range-lg::-moz-range-thumb { margin: 1.25rem; } +.m-8 { + margin: 2rem; +} + .m-14 { margin: 3.5rem; } @@ -1694,18 +1682,14 @@ input[type="range"].range-lg::-moz-range-thumb { height: 2.25rem; } -.h-24 { - height: 6rem; +.h-screen { + height: 100vh; } .h-full { height: 100%; } -.h-screen { - height: 100vh; -} - .h-fit { height: -webkit-fit-content; height: -moz-fit-content; @@ -1749,6 +1733,10 @@ input[type="range"].range-lg::-moz-range-thumb { height: 0.75rem; } +.h-80 { + height: 20rem; +} + .h-modal { height: calc(100% - 2rem); } @@ -1785,10 +1773,6 @@ input[type="range"].range-lg::-moz-range-thumb { height: 16rem; } -.h-80 { - height: 20rem; -} - .h-20 { height: 5rem; } @@ -1797,6 +1781,10 @@ input[type="range"].range-lg::-moz-range-thumb { height: 9rem; } +.h-24 { + height: 6rem; +} + .h-96 { height: 24rem; } @@ -2007,6 +1995,10 @@ input[type="range"].range-lg::-moz-range-thumb { width: 0.75rem; } +.w-60 { + width: 15rem; +} + .w-11 { width: 2.75rem; } @@ -2023,11 +2015,6 @@ input[type="range"].range-lg::-moz-range-thumb { width: 3.5rem; } -.w-max { - width: -webkit-max-content; - width: max-content; -} - .w-48 { width: 12rem; } @@ -3060,11 +3047,20 @@ input[type="range"].range-lg::-moz-range-thumb { border-color: rgb(209 213 219 / var(--tw-border-opacity)); } +.border-transparent { + border-color: transparent; +} + .border-gray-600 { --tw-border-opacity: 1; border-color: rgb(75 85 99 / var(--tw-border-opacity)); } +.border-red-500 { + --tw-border-opacity: 1; + border-color: rgb(240 82 82 / var(--tw-border-opacity)); +} + .border-gray-800 { --tw-border-opacity: 1; border-color: rgb(31 41 55 / var(--tw-border-opacity)); @@ -3170,11 +3166,6 @@ input[type="range"].range-lg::-moz-range-thumb { border-color: rgb(14 159 110 / var(--tw-border-opacity)); } -.border-red-500 { - --tw-border-opacity: 1; - border-color: rgb(240 82 82 / var(--tw-border-opacity)); -} - .border-gray-700 { --tw-border-opacity: 1; border-color: rgb(55 65 81 / var(--tw-border-opacity)); @@ -3185,10 +3176,6 @@ input[type="range"].range-lg::-moz-range-thumb { border-color: rgb(239 86 47 / var(--tw-border-opacity)); } -.border-transparent { - border-color: transparent; -} - .border-red-300 { --tw-border-opacity: 1; border-color: rgb(248 180 180 / var(--tw-border-opacity)); @@ -3262,6 +3249,11 @@ input[type="range"].range-lg::-moz-range-thumb { background-color: rgb(249 128 128 / var(--tw-bg-opacity)); } +.bg-gray-400 { + --tw-bg-opacity: 1; + background-color: rgb(156 163 175 / var(--tw-bg-opacity)); +} + .bg-slate-400 { --tw-bg-opacity: 1; background-color: rgb(148 163 184 / var(--tw-bg-opacity)); @@ -3494,11 +3486,6 @@ input[type="range"].range-lg::-moz-range-thumb { background-color: rgb(254 121 93 / var(--tw-bg-opacity)); } -.bg-gray-400 { - --tw-bg-opacity: 1; - background-color: rgb(156 163 175 / var(--tw-bg-opacity)); -} - .bg-pink-500 { --tw-bg-opacity: 1; background-color: rgb(231 70 148 / var(--tw-bg-opacity)); diff --git a/src/Logic/ImageProviders/AllImageProviders.ts b/src/Logic/ImageProviders/AllImageProviders.ts index aaac514a4b..c53be2d79b 100644 --- a/src/Logic/ImageProviders/AllImageProviders.ts +++ b/src/Logic/ImageProviders/AllImageProviders.ts @@ -22,7 +22,7 @@ export default class AllImageProviders { ...WikimediaImageProvider.commonsPrefixes, ...Mapillary.valuePrefixes, ...AllImageProviders.dontLoadFromPrefixes, - "Category:", + "Category:" ]) private static ImageAttributionSource: ImageProvider[] = [ @@ -31,7 +31,7 @@ export default class AllImageProviders { WikidataImageProvider.singleton, WikimediaImageProvider.singleton, Panoramax.singleton, - AllImageProviders.genericImageProvider, + AllImageProviders.genericImageProvider ] public static apiUrls: string[] = [].concat( ...AllImageProviders.ImageAttributionSource.map((src) => src.apiUrls()) @@ -44,7 +44,7 @@ export default class AllImageProviders { mapillary: Mapillary.singleton, wikidata: WikidataImageProvider.singleton, wikimedia: WikimediaImageProvider.singleton, - panoramax: Panoramax.singleton, + panoramax: Panoramax.singleton } public static byName(name: string) { @@ -67,6 +67,28 @@ export default class AllImageProviders { } private static readonly _cachedImageStores: Record> = {} + + /** + * Does a guess on the number of images that are probably there. + * Will simply count all image tags + * + * AllImageProviders.estimateNumberOfImages({image:"abc", "mapillary": "123", "panoramax:0"}) // => 3 + * + */ + public static estimateNumberOfImages(tags: Record, prefixes: string[] = undefined): number { + let count = 0 + + const allPrefixes = prefixes ?? [].concat(...AllImageProviders.ImageAttributionSource.map(s => s.defaultKeyPrefixes)) + for (const k in tags) { + for (const prefix of allPrefixes) { + if (k === prefix || k.startsWith(prefix + ":")) { + count++ + } + } + } + return count + } + /** * Tries to extract all image data for this image. Cached on tags?.data?.id */ @@ -108,7 +130,7 @@ export default class AllImageProviders { */ public static loadImagesFrom(urls: string[]): Store { const tags = { - id: urls.join(";"), + id: urls.join(";") } for (let i = 0; i < urls.length; i++) { tags["image:" + i] = urls[i] diff --git a/src/Logic/ImageProviders/Panoramax.ts b/src/Logic/ImageProviders/Panoramax.ts index b50e4712d9..0e9c7485e5 100644 --- a/src/Logic/ImageProviders/Panoramax.ts +++ b/src/Logic/ImageProviders/Panoramax.ts @@ -149,7 +149,7 @@ export default class PanoramaxImageProvider extends ImageProvider { ) } - Stores.Chronic(1500, () => hasLoading(source.data)).addCallback(() => { + Stores.Chronic(5000, () => hasLoading(source.data)).addCallback(() => { super.getRelevantUrlsFor(tags, prefixes).then((data) => { source.set(data) return !hasLoading(data) diff --git a/src/UI/Base/LoadingPlaceholder.svelte b/src/UI/Base/LoadingPlaceholder.svelte new file mode 100644 index 0000000000..9b9f5ca427 --- /dev/null +++ b/src/UI/Base/LoadingPlaceholder.svelte @@ -0,0 +1,11 @@ + +
+
+
+
+ +
+
diff --git a/src/UI/Image/AttributedImage.svelte b/src/UI/Image/AttributedImage.svelte index 257801e4cc..6b8c16f3ea 100644 --- a/src/UI/Image/AttributedImage.svelte +++ b/src/UI/Image/AttributedImage.svelte @@ -17,6 +17,7 @@ import Translations from "../i18n/Translations" import Tr from "../Base/Tr.svelte" import DotMenu from "../Base/DotMenu.svelte" + import LoadingPlaceholder from "../Base/LoadingPlaceholder.svelte" export let image: Partial let fallbackImage: string = undefined @@ -111,7 +112,11 @@ {/if} + {#if !loaded} + + {/if} (loaded = true)} class={imgClass ?? ""} diff --git a/src/UI/Image/ImageCarousel.svelte b/src/UI/Image/ImageCarousel.svelte index f9b4316205..b8fb8a14bc 100644 --- a/src/UI/Image/ImageCarousel.svelte +++ b/src/UI/Image/ImageCarousel.svelte @@ -3,14 +3,28 @@ import type { ProvidedImage } from "../../Logic/ImageProviders/ImageProvider" import type { SpecialVisualizationState } from "../SpecialVisualization" import DeletableImage from "./DeletableImage.svelte" + import Loading from "../Base/Loading.svelte" + import LoadingPlaceholder from "../Base/LoadingPlaceholder.svelte" export let images: Store export let state: SpecialVisualizationState export let tags: UIEventSource> - -
- {#each $images as image (image.url)} - - {/each} -
+ export let estimated: Store + + images.addCallbackAndRun(imgs => { + console.log(">>><<< imgs are", imgs) + }) + + +{#if $estimated > 0 && $images.length < 1} + +{:else} +
+
+ {#each $images as image (image.url)} + + {/each} +
+
+{/if} diff --git a/src/UI/SpecialVisualizations.ts b/src/UI/SpecialVisualizations.ts index ad9f864c4b..a119908ae2 100644 --- a/src/UI/SpecialVisualizations.ts +++ b/src/UI/SpecialVisualizations.ts @@ -717,7 +717,8 @@ export default class SpecialVisualizations { imagePrefixes = [].concat(...args.map((a) => a.split(","))) } const images = AllImageProviders.loadImagesFor(tags, imagePrefixes) - return new SvelteUIElement(ImageCarousel, { state, tags, images }) + const estimated = tags.mapD(tags => AllImageProviders.estimateNumberOfImages(tags, imagePrefixes)) + return new SvelteUIElement(ImageCarousel, { state, tags, images, estimated }) }, }, {