UNPKG

@creaditor/newsletter-starterkit

Version:

Creaditor Newsletter Editor - Starterkit for creating beautiful email newsletters

274 lines (251 loc) 16.4 kB
"use strict";(("undefined"!=typeof self?self:this).webpackChunkCreaditor=("undefined"!=typeof self?self:this).webpackChunkCreaditor||[]).push([[901],{20901:(e,t,r)=>{r.r(t),r.d(t,{PexelsGallery:()=>n});var o=r(56666),a=r(8427),s=(r(70235),r(9085)),l=(r(36351),r(61828),r(59051));const i="jUU57RHRVmWvXd22MBjQkDhcf9Prkbufc6KXUChhrEIOr6IqNeNvMOUl",c="https://api.pexels.com/v1/search",h=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:20;return fetch(`${c}?query=${encodeURIComponent(e)}&page=${t}&per_page=${r}`,{method:"GET",headers:{Authorization:i,"Content-Type":"application/json"}})};class n extends a.oi{constructor(){super(),this.images=[],this.loading=!1,this.searchQuery="",this.page=1,this.hasMore=!0,this.perPage=20,this.multi=!0,this.selectedColor="",this.defaultSearchTerms=["nature","landscape","city","people","technology","food","architecture","travel","business","art"],this.colorOptions=[{name:"Red",value:"red",hex:"#ff0000"},{name:"Orange",value:"orange",hex:"#ff8000"},{name:"Yellow",value:"yellow",hex:"#ffff00"},{name:"Green",value:"green",hex:"#00ff00"},{name:"Blue",value:"blue",hex:"#0000ff"},{name:"Purple",value:"purple",hex:"#8000ff"},{name:"Pink",value:"pink",hex:"#ff0080"},{name:"Brown",value:"brown",hex:"#8b4513"},{name:"Black",value:"black",hex:"#000000"},{name:"White",value:"white",hex:"#ffffff"},{name:"Gray",value:"gray",hex:"#808080"},{name:"Teal",value:"teal",hex:"#008080"},{name:"Navy",value:"navy",hex:"#000080"},{name:"Maroon",value:"maroon",hex:"#800000"},{name:"Olive",value:"olive",hex:"#808000"},{name:"Lime",value:"lime",hex:"#00ff00"},{name:"Aqua",value:"aqua",hex:"#00ffff"},{name:"Silver",value:"silver",hex:"#c0c0c0"},{name:"Fuchsia",value:"fuchsia",hex:"#ff00ff"},{name:"Coral",value:"coral",hex:"#ff7f50"},{name:"Gold",value:"gold",hex:"#ffd700"},{name:"Indigo",value:"indigo",hex:"#4b0082"},{name:"Violet",value:"violet",hex:"#ee82ee"},{name:"Cyan",value:"cyan",hex:"#00ffff"},{name:"Magenta",value:"magenta",hex:"#ff00ff"}],this.cacheKey="pexels-gallery-cache",this.cacheExpiry=864e5,this.isTyping=!1,this.lastSearchQuery="",this.searchTimeout=null}connectedCallback(){super.connectedCallback(),this.loadFromCache()}getCacheData(){try{const e=localStorage.getItem(this.cacheKey);if(!e)return null;const t=JSON.parse(e),r=Date.now();return t.timestamp&&r-t.timestamp>this.cacheExpiry?(localStorage.removeItem(this.cacheKey),null):t}catch(e){return console.error("Error reading cache:",e),null}}saveToCache(){if(!this.isTyping)try{const e={images:this.images,searchQuery:this.searchQuery,selectedColor:this.selectedColor,page:this.page,hasMore:this.hasMore,timestamp:Date.now()};localStorage.setItem(this.cacheKey,JSON.stringify(e))}catch(e){console.error("Error saving to cache:",e)}}loadFromCache(){const e=this.getCacheData();e?(this.images=e.images||[],this.searchQuery=e.searchQuery||"",this.selectedColor=e.selectedColor||"",this.page=e.page||1,this.hasMore=void 0===e.hasMore||e.hasMore,console.log("Gallery state restored from cache"),this.requestUpdate(),this.updateComplete.then((()=>{this.updateSearchInput()}))):this.loadRandomImages()}updateSearchInput(){const e=this.shadowRoot?.querySelector('cdtr-input[type="search"]');e&&(e.value=this.searchQuery)}async loadRandomImages(){this.loading=!0;try{const e=this.defaultSearchTerms[Math.floor(Math.random()*this.defaultSearchTerms.length)],t=await h(e,1,this.perPage);if(t.ok){const e=await t.json();this.images=e.photos||[],this.hasMore=e.photos&&e.photos.length===this.perPage,this.searchQuery="",this.selectedColor="",this.page=1,this.saveToCache()}else console.error("Failed to load images from Pexels"),this.images=[]}catch(e){console.error("Error loading images:",e),this.images=[]}finally{this.loading=!1}}async searchImages(e){if(!e.trim())return this.loadRandomImages();this.loading=!0,this.searchQuery=e,this.page=1;try{const t=await h(e,1,this.perPage);if(t.ok){const e=await t.json();this.images=e.photos||[],this.hasMore=e.photos&&e.photos.length===this.perPage,this.saveToCache()}else console.error("Failed to search images from Pexels"),this.images=[]}catch(e){console.error("Error searching images:",e),this.images=[]}finally{this.loading=!1}}async loadMoreImages(){if(!this.loading&&this.hasMore){this.loading=!0,this.page++;try{let e;if(this.selectedColor&&"all"!==this.selectedColor){let t=this.removeColorFilters(this.searchQuery);e=t.trim()?`${t} ${this.selectedColor}`:this.selectedColor}else{e=this.removeColorFilters(this.searchQuery)||this.defaultSearchTerms[Math.floor(Math.random()*this.defaultSearchTerms.length)]}const t=await h(e,this.page,this.perPage);if(t.ok){const e=(await t.json()).photos||[];this.images=[...this.images,...e],this.hasMore=e.length===this.perPage,this.saveToCache()}}catch(e){console.error("Error loading more images:",e)}finally{this.loading=!1}}}onSearch(e){const t=e.target.value;this.isTyping=!0,t!==this.lastSearchQuery&&(this.lastSearchQuery=t,this.searchTimeout&&clearTimeout(this.searchTimeout),this.searchTimeout=setTimeout((()=>{this.isTyping=!1,this.searchWithColor(t,this.selectedColor)}),500))}onSelectImage(e){const t=`Photo by ${e.photographer} on Pexels`,r=`Photo by <a href="${e.photographer_url}" target="_blank" rel="noopener noreferrer">${e.photographer}</a> on <a href="${e.url}" target="_blank" rel="noopener noreferrer">Pexels</a>`,o={detail:{id:e.id,src:e.src.medium||e.src.large||e.src.original,name:`Pexels Image ${e.id}`,size:`${e.width}x${e.height}`,photographer:e.photographer,photographerUrl:e.photographer_url,pexelsUrl:e.url,alt:e.alt||`Photo by ${e.photographer} on Pexels`,attributionText:t,attributionHtml:r},bubbles:!1,composed:!1};this.dispatchEvent(new CustomEvent("file",o))}sendSelectedImages(){const e={detail:this.images.filter((e=>e.selected)).map((e=>{const t=`Photo by ${e.photographer} on Pexels`,r=`Photo by <a href="${e.photographer_url}" target="_blank" rel="noopener noreferrer">${e.photographer}</a> on <a href="${e.url}" target="_blank" rel="noopener noreferrer">Pexels</a>`;return{id:e.id,src:e.src.medium||e.src.large||e.src.original,name:`Pexels Image ${e.id}`,size:`${e.width}x${e.height}`,photographer:e.photographer,photographerUrl:e.photographer_url,pexelsUrl:e.url,alt:e.alt||`Photo by ${e.photographer} on Pexels`,attributionText:t,attributionHtml:r}})),bubbles:!1,composed:!1};this.dispatchEvent(new CustomEvent("file",e))}onScroll(e){const t=e.target;t.scrollTop+t.offsetHeight>=t.scrollHeight-50&&this.loadMoreImages()}clearCache(){localStorage.removeItem(this.cacheKey),console.log("Gallery cache cleared")}onColorChange(e){console.log("Color change event:",e);const t=e.target.value;console.log("Selected color:",t),this.selectedColor="all"===t?"":t;const r=this.searchQuery||"";this.searchWithColor(r,this.selectedColor)}searchWithColor(e,t){if(t&&"all"!==t){let r=this.removeColorFilters(e),o=r.trim()?`${r} ${t}`:t;this.searchImages(o)}else{let t=this.removeColorFilters(e);this.searchImages(t)}}removeColorFilters(e){if(!e)return"";const t=this.colorOptions.map((e=>e.value));return e.split(" ").filter((e=>{const r=e.toLowerCase().trim();return!t.includes(r)})).join(" ").trim()}getSelectedColorName(){if(!this.selectedColor)return"Filter by color";const e=this.colorOptions.find((e=>e.value===this.selectedColor));return e?e.name:"Filter by color"}getSelectedColorHex(){if(!this.selectedColor)return"#666";const e=this.colorOptions.find((e=>e.value===this.selectedColor));return e?e.hex:"#666"}render(){return a.dy` <div class="gallery-container"> <cdtr-row alignItems="center"> <cdtr-input type="search" @input=${this.onSearch} placeholder="Search images..." class="search" ></cdtr-input> <div class="divider-y"></div> <!-- Color Filter Dropdown --> <div class="color-dropdown"> <cdtr-dropdown .value=${this.selectedColor||""} @change=${this.onColorChange} > <paper-button slot="trigger"> <div class="color-preview" style="background-color: ${this.getSelectedColorHex()}" ></div> </paper-button> <div slot="content"> <cdtr-dropdown-item value="all" .selected=${!this.selectedColor} > <div class="color-circle" style="background-color: transparent; border: 2px dashed #ccc;" ></div> <span style="margin-left: 8px; font-size: 12px;">All Colors</span> </cdtr-dropdown-item> ${this.colorOptions.map((e=>a.dy` <cdtr-dropdown-item value="${e.value}" .selected=${this.selectedColor===e.value} > <div class="color-circle" style="background-color: ${e.hex}" ></div> <span style="margin-left: 8px; font-size: 12px;">${e.name}</span> </cdtr-dropdown-item> `))} </div> </cdtr-dropdown> </div> <paper-button @click=${this.loadRandomImages} class="icon-btn"> <cdtr-tooltip delay="500,0" arrow=${!1} content="refresh"> <cdtr-refresh-icon></cdtr-refresh-icon> </cdtr-tooltip> </paper-button> </cdtr-row> <cdtr-row mt="2" alignItems="center" justify="space-between"> <div class="pexels-header-credit"> <div class="status-indicator"> <div class="connected-dot"></div> </div> <div class="credit-content"> <span class="credit-text">Powered by </span> <a href="https://www.pexels.com" target="_blank" rel="noopener noreferrer" class="pexels-header-link" > Pexels </a> </div> </div> </cdtr-row> <cdtr-row mt="2" justify="space-between"> <cdtr-col sm="12"> <cdtr-row @scroll=${this.onScroll} class="scroll-body" justify="space-evenly" > ${this.loading&&0===this.images.length?a.dy`<cdtr-col sm="12"> <cdtr-row justify="center"> <cdtr-spinner></cdtr-spinner> <lang-text text="loading"></lang-text> </cdtr-row> </cdtr-col>`:(0,s.r)(this.images||[],(e=>e.id),((e,t)=>a.dy`<cdtr-col class="file-col" sm="3"> <cdtr-editor-media-card @dblclick=${()=>this.onSelectImage(e)} @click=${t=>{t.shiftKey&&this.multi||this.images.forEach((e=>e.selected=!1)),e.selected=!e.selected,this.images=[...this.images],this.isTyping||this.saveToCache()}} .selected=${e.selected} .controls=${!1} src=${e.src.medium||e.src.large||e.src.original} name=${`Photo by ${e.photographer}`} subTitle=${`${e.width}x${e.height}`} > <div slot="footer" class="pexels-credit"> <a href="${e.photographer_url}" target="_blank" rel="noopener noreferrer" class="photographer-link" > ${e.photographer} </a> <span class="credit-text"> on </span> <a href="${e.url}" target="_blank" rel="noopener noreferrer" class="pexels-link" > Pexels </a> </div> </cdtr-editor-media-card> </cdtr-col>`))} ${this.loading&&this.images.length>0?a.dy`<cdtr-col sm="12"> <cdtr-row justify="center"> <cdtr-spinner></cdtr-spinner> <lang-text text="loadingMore"></lang-text> </cdtr-row> </cdtr-col>`:null} </cdtr-row> </cdtr-col> </cdtr-row> <cdtr-row alignItems="center" justify="flex-start" class="footer"> <paper-button @click=${this.sendSelectedImages} class="add-btn"> <lang-text text="choose"></lang-text> </paper-button> </cdtr-row> </div> `}}(0,o.Z)(n,"styles",[l.$,a.iv` :host { --alpha: rgba(0, 123, 255, 0.1); --primary: #007bff; } .color-dropdown { display: inline-block; } .color-preview { width: 20px; height: 20px; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); display: inline-block; } .color-circle { width: 20px; height: 20px; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); display: inline-block; } .clear-color { color: #666; font-style: italic; } .pexels-credit { position: absolute; bottom: 5px; left: 5px; right: 5px; background: rgba(0, 0, 0, 0.7); color: white; padding: 4px 8px; border-radius: 4px; font-size: 10px; text-align: center; opacity: 0; transition: opacity 0.2s ease; } .file-col:hover .pexels-credit { opacity: 1; } .photographer-link, .pexels-link { color: #fff; text-decoration: none; font-weight: 500; } .photographer-link:hover, .pexels-link:hover { text-decoration: underline; } .credit-text { color: rgba(255, 255, 255, 0.8); } .pexels-header-credit { display: flex; align-items: center; gap: 8px; background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 12px; padding: 6px 12px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); transition: all 0.2s ease; font-size: 11px; font-weight: 500; letter-spacing: 0.3px; } .pexels-header-credit:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15); border-color: rgba(0, 0, 0, 0.12); } .status-indicator { display: flex; align-items: center; justify-content: center; } .connected-dot { width: 6px; height: 6px; border-radius: 50%; background: #10b981; box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2); animation: pulse-green 2s infinite; } @keyframes pulse-green { 0%, 100% { box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2); transform: scale(1); } 50% { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.1); transform: scale(1.1); } } .credit-content { display: flex; align-items: center; gap: 4px; } .credit-text { color: #6b7280; font-weight: 400; } .pexels-header-link { color: #3b82f6; text-decoration: none; font-weight: 600; transition: color 0.2s ease; } .pexels-header-link:hover { color: #2563eb; } `]),(0,o.Z)(n,"properties",{images:{type:Array},loading:{type:Boolean},searchQuery:{type:String},page:{type:Number},hasMore:{type:Boolean},multi:{type:Boolean},selectedColor:{type:String}}),customElements.define("cdtr-pexels-gallery",n)}}]);