Browse Source
			
			
			
			
				
		Reviewed-on: https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/pulls/124pull/125/head
				 5 changed files with 148 additions and 14 deletions
			
			
		| @ -0,0 +1,97 @@ | |||||
|  | <template> | ||||
|  |   <Teleport to="body"> | ||||
|  |     <Transition name="fade"> | ||||
|  |       <div | ||||
|  |         v-if="isOpen" | ||||
|  |         class="fixed inset-0 z-50 flex flex-col bg-black/90" | ||||
|  |       > | ||||
|  |         <!-- Header bar - fixed height to prevent overlap --> | ||||
|  |         <div class="h-16 flex justify-between items-center px-4 bg-black"> | ||||
|  |           <button | ||||
|  |             class="text-white text-2xl p-2 rounded-full hover:bg-white/10" | ||||
|  |             @click="close" | ||||
|  |           > | ||||
|  |             <fa icon="xmark" /> | ||||
|  |           </button> | ||||
|  | 
 | ||||
|  |           <!-- Mobile share button --> | ||||
|  |           <button | ||||
|  |             v-if="isMobile" | ||||
|  |             class="text-white text-xl p-2 rounded-full hover:bg-white/10" | ||||
|  |             @click="handleShare" | ||||
|  |           > | ||||
|  |             <fa icon="ellipsis" /> | ||||
|  |           </button> | ||||
|  |         </div> | ||||
|  | 
 | ||||
|  |         <!-- Image container - fill remaining space --> | ||||
|  |         <div class="flex-1 flex items-center justify-center p-2"> | ||||
|  |           <div class="w-full h-full flex items-center justify-center"> | ||||
|  |             <img | ||||
|  |               :src="imageUrl" | ||||
|  |               class="max-h-[calc(100vh-5rem)] w-full h-full object-contain" | ||||
|  |               @click.stop | ||||
|  |               alt="expanded shared content" | ||||
|  |             /> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |     </Transition> | ||||
|  |   </Teleport> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script lang="ts"> | ||||
|  | import { Component, Vue, Prop } from "vue-facing-decorator"; | ||||
|  | import { UAParser } from "ua-parser-js"; | ||||
|  | 
 | ||||
|  | @Component({ emits: ["update:isOpen"] }) | ||||
|  | export default class ImageViewer extends Vue { | ||||
|  |   @Prop() imageUrl!: string; | ||||
|  |   @Prop() imageData!: Blob | null; | ||||
|  |   @Prop() isOpen!: boolean; | ||||
|  | 
 | ||||
|  |   userAgent = new UAParser(); | ||||
|  | 
 | ||||
|  |   get isMobile() { | ||||
|  |     const os = this.userAgent.getOS().name; | ||||
|  |     return os === "iOS" || os === "Android"; | ||||
|  |   } | ||||
|  | 
 | ||||
|  |   close() { | ||||
|  |     this.$emit("update:isOpen", false); | ||||
|  |   } | ||||
|  | 
 | ||||
|  |   async handleShare() { | ||||
|  |     const os = this.userAgent.getOS().name; | ||||
|  | 
 | ||||
|  |     try { | ||||
|  |       if (os === "iOS" || os === "Android") { | ||||
|  |         if (navigator.share) { | ||||
|  |           // Always share the URL since it's more reliable across platforms | ||||
|  |           await navigator.share({ | ||||
|  |             url: this.imageUrl | ||||
|  |           }); | ||||
|  |         } else { | ||||
|  |           // Fallback for browsers without share API | ||||
|  |           window.open(this.imageUrl, "_blank"); | ||||
|  |         } | ||||
|  |       } | ||||
|  |     } catch (error) { | ||||
|  |       console.warn("Share failed, opening in new tab:", error); | ||||
|  |       window.open(this.imageUrl, "_blank"); | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style scoped> | ||||
|  | .fade-enter-active, | ||||
|  | .fade-leave-active { | ||||
|  |   transition: opacity 0.2s ease; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .fade-enter-from, | ||||
|  | .fade-leave-to { | ||||
|  |   opacity: 0; | ||||
|  | } | ||||
|  | </style> | ||||
					Loading…
					
					
				
		Reference in new issue