11<script lang =" ts" >
22 import { onMount } from ' svelte' ;
33
4- let photo: { raw: string ; source_redirect? : string ; source? : string } | null = null ;
4+ export let hash: string | null = null ;
5+ export let width: string = ' 100%' ;
6+
7+ let photo: {
8+ raw: string ;
9+ source_redirect? : string ;
10+ source? : string ;
11+ mime? : string ;
12+ hash? : string ;
13+ } | null = null ;
514 let error: string | null = null ;
615 let loading = true ;
716
17+ let mounted = false ;
18+ let lastHash: string | null = null ;
19+
20+ function isVideo(item : any ) {
21+ return typeof item ?.mime === ' string' && item .mime .startsWith (' video/' );
22+ }
23+
24+ function getPhotoLink(item : typeof photo ) {
25+ return item ?.source_redirect || item ?.source || null ;
26+ }
27+
828 async function getRandomPhoto() {
929 try {
10- const resp = await fetch (' https://api.canine.tools/wolf/' );
30+ const url = ` https://api.canine.tools/wolf/random?t=${Date .now ()} ` ;
31+ const resp = await fetch (url , {
32+ cache: ' no-store'
33+ });
34+
1135 if (! resp .ok ) throw new Error (` API error ${resp .status } ` );
12- const photos = await resp .json ();
36+ return await resp .json ();
37+ } catch (err ) {
38+ console .error (' Failed to load random wolf photo:' , err );
39+ return null ;
40+ }
41+ }
1342
14- if (! Array .isArray (photos ) || photos .length === 0 ) return null ;
15- const idx = Math .floor (Math .random () * photos .length );
16- return photos [idx ];
43+ async function getByHash(h : string ) {
44+ try {
45+ const resp = await fetch (` https://api.canine.tools/wolf/${h .trim ().toLowerCase ()} ` , {
46+ cache: ' no-store'
47+ });
48+
49+ if (! resp .ok ) throw new Error (` API error ${resp .status } ` );
50+ return await resp .json ();
1751 } catch (err ) {
18- console .error (' Failed to load photos :' , err );
52+ console .error (' Failed to load photo by hash :' , err );
1953 return null ;
2054 }
2155 }
2256
23- onMount (async () => {
24- const result = await getRandomPhoto ();
57+ async function load() {
58+ loading = true ;
59+ error = null ;
60+
61+ const result = hash ? await getByHash (hash ) : await getRandomPhoto ();
62+
2563 if (! result ) {
26- error = ' No wolfy photo available :(' ;
64+ error = hash ? ` No wolf found for hash: ${hash } ` : ' No wolfy photo available :(' ;
65+ photo = null ;
2766 } else {
28- console .log (' Selected Photo:' , result .raw );
29- console .log (' Source:' , result .source ? result .source : ' No source available' );
3067 photo = result ;
3168 }
69+
3270 loading = false ;
71+ }
72+
73+ onMount (async () => {
74+ mounted = true ;
75+ lastHash = hash ;
76+ await load ();
3377 });
78+
79+ $ : if (mounted && hash !== lastHash ) {
80+ lastHash = hash ;
81+ load ();
82+ }
3483 </script >
3584
3685<div class =" random-wolf" >
3988 {:else if error }
4089 <p >{error }</p >
4190 {:else if photo }
42- {#if photo .source_redirect }
43- <a href ={photo .source_redirect } target =" _blank" rel =" noopener noreferrer" >
44- <img src ={photo .raw } alt =" Random Wolf" />
91+ {#if getPhotoLink (photo )}
92+ <a href ={getPhotoLink (photo )} target =" _blank" rel =" noopener noreferrer" >
93+ {#if isVideo (photo )}
94+ <video
95+ src ={photo .raw }
96+ autoplay
97+ muted
98+ loop
99+ playsinline
100+ style ={` width: ${width }; height: auto; ` }
101+ ></video >
102+ {:else }
103+ <img src ={photo .raw } alt ="Random Wolf" style ={` width: ${width }; height: auto; ` } />
104+ {/if }
45105 </a >
106+ {:else if isVideo (photo )}
107+ <video
108+ src ={photo .raw }
109+ autoplay
110+ muted
111+ loop
112+ playsinline
113+ style ={` width: ${width }; height: auto; ` }
114+ ></video >
46115 {:else }
47- <img src ={photo .raw } alt =" Random Wolf" />
116+ <img src ={photo .raw } alt ="Random Wolf" style ={ ` width: ${ width }; height: auto; ` } />
48117 {/if }
49118 {/if }
50119</div >
54123 text-align : center ;
55124 }
56125
57- .random-wolf img {
58- width : 80% ;
59- }
60-
61- @media screen and (max-width : 1030px ) {
62- .random-wolf img {
63- width : 60% ;
64- }
65- }
66- @media screen and (max-width : 500px ) {
67- .random-wolf img {
68- width : 70% ;
69- }
126+ .random-wolf img ,
127+ .random-wolf video {
128+ border-radius : 8px ;
70129 }
71- </style >
130+ </style >
0 commit comments