File indexing completed on 2024-12-22 05:34:44
0001 window.hpHelpers = (function(){ 0002 0003 function dechex(number) { 0004 // discuss at: http://locutus.io/php/dechex/ 0005 // original by: Philippe Baumann 0006 // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman) 0007 // improved by: http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript 0008 // input by: pilus 0009 // example 1: dechex(10) 0010 // returns 1: 'a' 0011 // example 2: dechex(47) 0012 // returns 2: '2f' 0013 // example 3: dechex(-1415723993) 0014 // returns 3: 'ab9dc427' 0015 0016 if (number < 0) { 0017 number = 0xFFFFFFFF + number + 1 0018 } 0019 return parseInt(number, 10).toString(16) 0020 } 0021 0022 function calculateScoreColor(score){ 0023 let blue, red, green, defaultColor = 200; 0024 if (score > 50){ 0025 red = defaultColor - ((score-50)*4); 0026 green = defaultColor; 0027 blue = defaultColor - ((score-50)*4); 0028 } else if (score < 51){ 0029 red = defaultColor; 0030 green = defaultColor - ((score-50)*4); 0031 blue = defaultColor - ((score-50)*4); 0032 } 0033 0034 return "rgb("+red+","+green+","+blue+")"; 0035 } 0036 0037 return { 0038 dechex, 0039 calculateScoreColor 0040 } 0041 }()); 0042 0043 class CarouselsModule extends React.Component { 0044 constructor(props){ 0045 super(props); 0046 this.state = { 0047 0048 }; 0049 this.initCarouselModule = this.initCarouselModule.bind(this); 0050 this.updateDimensions = this.updateDimensions.bind(this); 0051 this.convertDataObject = this.convertDataObject.bind(this); 0052 } 0053 0054 componentWillMount() { 0055 this.updateDimensions(); 0056 } 0057 0058 componentWillUnmount(){ 0059 window.removeEventListener("resize", this.updateDimensions); 0060 window.removeEventListener("orientationchange",this.updateDimensions); 0061 } 0062 0063 componentDidMount() { 0064 this.initCarouselModule(); 0065 } 0066 0067 initCarouselModule(){ 0068 0069 window.addEventListener("resize", this.updateDimensions); 0070 window.addEventListener("orientationchange",this.updateDimensions); 0071 0072 let env = "live"; 0073 if (location.hostname.endsWith('cc')) { 0074 env = "test"; 0075 } else if (location.hostname.endsWith('localhost')) { 0076 env = "test"; 0077 } 0078 0079 this.setState({env:env},function(){ 0080 this.convertDataObject(); 0081 }); 0082 0083 } 0084 0085 updateDimensions(){ 0086 0087 const width = window.innerWidth; 0088 let device; 0089 if (width >= 910){ 0090 device = "large"; 0091 } else if (width < 910 && width >= 610){ 0092 device = "mid"; 0093 } else if (width < 610){ 0094 device = "tablet"; 0095 } 0096 0097 this.setState({device:device}); 0098 0099 } 0100 0101 convertDataObject() { 0102 let productGroupsArray = []; 0103 for (var i in window.data) { 0104 if (i !== "comments" && i !== "featureProducts"){ 0105 const productGroup = { 0106 title:window.data[i].title, 0107 catIds:window.data[i].catIds, 0108 products:JSON.parse(window.data[i].products) 0109 } 0110 productGroupsArray.push(productGroup); 0111 } 0112 } 0113 this.setState({productGroupsArray:productGroupsArray,loading:false}); 0114 } 0115 0116 render(){ 0117 0118 let productCarouselsContainer; 0119 if (this.state.loading === false){ 0120 productCarouselsContainer = this.state.productGroupsArray.map((pgc,index) => { 0121 //if (pgc.catIds){ 0122 return ( 0123 <div key={index} className="section"> 0124 <div className="container"> 0125 <Carousel 0126 products={pgc.products} 0127 device={this.state.device} 0128 title={pgc.title} 0129 catIds={pgc.catIds} 0130 link={'/'} 0131 env={this.state.env} 0132 /> 0133 </div> 0134 </div> 0135 ); 0136 //} 0137 }); 0138 } 0139 0140 return ( 0141 <div id="carousels-module"> 0142 {productCarouselsContainer} 0143 </div> 0144 ) 0145 } 0146 } 0147 0148 class Carousel extends React.Component { 0149 constructor(props){ 0150 super(props); 0151 this.state = { 0152 products:this.props.products, 0153 disableleftArrow:true 0154 }; 0155 this.updateDimensions = this.updateDimensions.bind(this); 0156 this.animateProductCarousel = this.animateProductCarousel.bind(this); 0157 this.getNextProductsBatch = this.getNextProductsBatch.bind(this); 0158 } 0159 0160 componentWillMount() { 0161 window.addEventListener("resize", this.updateDimensions); 0162 } 0163 0164 componentDidMount() { 0165 this.updateDimensions(); 0166 } 0167 0168 updateDimensions(animateCarousel){ 0169 let itemsPerRow = 5; 0170 if (window.hpVersion === 2){ 0171 if (this.props.device === 'large'){ 0172 itemsPerRow = 6; 0173 } else if (this.props.device === 'mid'){ 0174 itemsPerRow = 6; 0175 } else if (this.props.device === 'tablet'){ 0176 itemsPerRow = 2; 0177 } 0178 } 0179 0180 let containerWidth; 0181 if (window.page === "opendesktop"){ 0182 containerWidth = $('#main-content').width(); 0183 0184 } else if (window.page === "appimages" || window.page === "libreoffice"){ 0185 containerWidth = $('#introduction').find('.container').width(); 0186 } 0187 const containerNumber = Math.ceil(this.state.products.length / (itemsPerRow - 1)); 0188 const itemWidth = containerWidth / itemsPerRow; 0189 const sliderWidth = (containerWidth - itemWidth) * containerNumber; 0190 let sliderPosition = 0; 0191 if (this.state.sliderPosition){ 0192 sliderPosition = this.state.sliderPosition; 0193 } 0194 0195 if (window.page === "appimages" || window.page === "libreoffice"){ 0196 $('#carousel-module-container').width(containerWidth); 0197 } 0198 0199 this.setState({ 0200 sliderPosition:sliderPosition, 0201 containerWidth:containerWidth, 0202 containerNumber:containerNumber, 0203 sliderWidth:sliderWidth, 0204 itemWidth:itemWidth, 0205 itemsPerRow:itemsPerRow - 1 0206 },function(){ 0207 if (animateCarousel){ 0208 this.animateProductCarousel('right',animateCarousel); 0209 } else if (this.state.finishedProducts){ 0210 this.setState({disableRightArrow:true}); 0211 } 0212 }); 0213 } 0214 0215 animateProductCarousel(dir,animateCarousel){ 0216 0217 let newSliderPosition = this.state.sliderPosition; 0218 const endPoint = this.state.sliderWidth - (this.state.containerWidth - this.state.itemWidth); 0219 0220 if (dir === 'left'){ 0221 if (this.state.sliderPosition > 0){ 0222 //newSliderPosition = this.state.sliderPosition - (this.state.containerWidth - this.state.itemWidth); 0223 if(this.state.containerWidth<(this.state.itemWidth*3)) 0224 { 0225 newSliderPosition = this.state.sliderPosition - this.state.itemWidth; 0226 }else { 0227 newSliderPosition = this.state.sliderPosition - this.state.itemWidth *2 ; 0228 } 0229 0230 } 0231 } else { 0232 0233 if (Math.trunc(this.state.sliderPosition) < Math.trunc(endPoint)){ 0234 //newSliderPosition = this.state.sliderPosition + (this.state.containerWidth - this.state.itemWidth); 0235 if(this.state.containerWidth<(this.state.itemWidth*3)) 0236 { 0237 newSliderPosition = this.state.sliderPosition + this.state.itemWidth; 0238 }else { 0239 newSliderPosition = this.state.sliderPosition + this.state.itemWidth *2 ; 0240 } 0241 } else { 0242 newSliderPosition = 0 0243 /*if (!animateCarousel){ 0244 if (this.state.products.length >= 15 || this.state.finishedProducts){ 0245 newSliderPosition = 0; 0246 } else { 0247 this.getNextProductsBatch(); 0248 } 0249 }*/ 0250 } 0251 } 0252 0253 this.setState({sliderPosition:newSliderPosition},function(){ 0254 0255 let disableleftArrow = false; 0256 if (this.state.sliderPosition <= 0){ 0257 disableleftArrow = true; 0258 } 0259 0260 let disableRightArrow = false; 0261 /*if (this.state.sliderPosition >= endPoint && this.state.finishedProducts === true){ 0262 disableRightArrow = true; 0263 }*/ 0264 0265 this.setState({disableRightArrow:disableRightArrow,disableleftArrow:disableleftArrow}); 0266 0267 }); 0268 } 0269 0270 getNextProductsBatch(){ 0271 0272 this.setState({disableRightArrow:true},function(){ 0273 let limit = (this.state.itemsPerRow * (this.state.containerNumber + 1)) - this.state.products.length; 0274 if (limit <= 0){ 0275 limit = this.state.itemsPerRow; 0276 } 0277 0278 let url; 0279 if (!this.props.catIds){ 0280 url = "/home/getnewactiveplingedproductjson/?limit="+limit+"&offset="+this.state.offset; 0281 } else { 0282 url = "/home/showlastproductsjson/?page=1&limit="+limit+"&offset="+this.state.offset+"&catIDs="+this.props.catIds+"&isoriginal=0"; 0283 } 0284 0285 const self = this; 0286 $.ajax({url: url,cache: false}).done(function(response){ 0287 let products = self.state.products, 0288 finishedProducts = false, 0289 animateCarousel = true; 0290 0291 if (response.length > 0){ 0292 products = products.concat(response); 0293 } else { 0294 finishedProducts = true; 0295 animateCarousel = false; 0296 } 0297 0298 if (response.length < limit){ 0299 finishedProducts = true; 0300 } 0301 0302 self.setState({ 0303 products:products, 0304 offset:self.state.offset + response.length, 0305 finishedProducts:finishedProducts},function(){ 0306 self.updateDimensions(animateCarousel); 0307 }); 0308 }); 0309 }); 0310 } 0311 0312 render(){ 0313 let carouselItemsDisplay; 0314 if (this.state.products && this.state.products.length > 0){ 0315 let plingedProduct = false; 0316 if (!this.props.catIds) plingedProduct = true; 0317 carouselItemsDisplay = this.state.products.map((product,index) => ( 0318 <CarouselItem 0319 key={index} 0320 product={product} 0321 itemWidth={this.state.itemWidth} 0322 env={this.props.env} 0323 plingedProduct={plingedProduct} 0324 /> 0325 )); 0326 } 0327 0328 let carouselArrowLeftDisplay; 0329 if (this.state.disableleftArrow){ 0330 carouselArrowLeftDisplay = ( 0331 <a className="carousel-arrow arrow-left disabled"> 0332 <span className="glyphicon glyphicon-chevron-left"></span> 0333 </a> 0334 ) 0335 } else { 0336 carouselArrowLeftDisplay = ( 0337 <a onClick={() => this.animateProductCarousel('left')} className="carousel-arrow arrow-left"> 0338 <span className="glyphicon glyphicon-chevron-left"></span> 0339 </a> 0340 ); 0341 } 0342 0343 let carouselArrowRightDisplay; 0344 if (this.state.disableRightArrow){ 0345 carouselArrowRightDisplay = ( 0346 <a className="carousel-arrow arrow-right disabled"> 0347 <span className="glyphicon glyphicon-chevron-right"></span> 0348 </a> 0349 ) 0350 } else { 0351 carouselArrowRightDisplay = ( 0352 <a onClick={() => this.animateProductCarousel('right')} className="carousel-arrow arrow-right"> 0353 <span className="glyphicon glyphicon-chevron-right"></span> 0354 </a> 0355 ); 0356 } 0357 0358 0359 let hpVersionClass = "one"; 0360 let carouselWrapperStyling = {}; 0361 let carouselArrowsMargin; 0362 if (window.hpVersion === 2 && this.state.itemWidth){ 0363 hpVersionClass = "two"; 0364 let itemHeightMultiplier; 0365 // if (this.state.itemWidth > 150){ 0366 itemHeightMultiplier = 1.35; 0367 /*} else { 0368 itemHeightMultiplier = 1.85; 0369 }*/ 0370 carouselWrapperStyling = { 0371 "paddingLeft":this.state.itemWidth / 2, 0372 "paddingRight":this.state.itemWidth / 2, 0373 "height":this.state.itemWidth * itemHeightMultiplier 0374 } 0375 carouselArrowsMargin = this.state.itemWidth / 4; 0376 } 0377 0378 let urlSuffix=''; 0379 if (window.page === "libreoffice"){ 0380 urlSuffix = "/s/LibreOffice"; 0381 } 0382 let titleLink = urlSuffix + "/browse/cat/" + this.props.catIds + "/"; 0383 if (!this.props.catIds){ 0384 titleLink = "/community#plingedproductsPanel"; 0385 }else if(this.props.catIds.indexOf(',')>0){ 0386 titleLink = urlSuffix + "/browse/"; 0387 } 0388 0389 0390 return ( 0391 <div className={"product-carousel " + hpVersionClass}> 0392 <div className="product-carousel-header"> 0393 <h2><a href={titleLink}>{this.props.title} <span className="glyphicon glyphicon-chevron-right"></span></a></h2> 0394 </div> 0395 <div className="product-carousel-wrapper" style={carouselWrapperStyling}> 0396 <div className="product-carousel-left" style={{"left":carouselArrowsMargin}}> 0397 {carouselArrowLeftDisplay} 0398 </div> 0399 <div className="product-carousel-container"> 0400 <div className="product-carousel-slider" style={{"width":this.state.sliderWidth,"left":"-"+this.state.sliderPosition + "px"}}> 0401 {carouselItemsDisplay} 0402 </div> 0403 </div> 0404 <div className="product-carousel-right" style={{"right":carouselArrowsMargin}}> 0405 {carouselArrowRightDisplay} 0406 </div> 0407 </div> 0408 </div> 0409 ) 0410 } 0411 } 0412 0413 class CarouselItem extends React.Component { 0414 constructor(props){ 0415 super(props); 0416 this.state = {}; 0417 } 0418 0419 render(){ 0420 0421 let paddingTop; 0422 let productInfoDisplay = ( 0423 <div className="product-info"> 0424 <span className="product-info-title">{this.props.product.title}</span> 0425 <span className="product-info-user">{this.props.product.username}</span> 0426 </div> 0427 ); 0428 0429 if (window.hpVersion === 2){ 0430 0431 if (this.props.itemWidth){ 0432 paddingTop = ((this.props.itemWidth * 1.35) / 2) - 10; 0433 } 0434 0435 let lastDate; 0436 if (this.props.product.changed_at){ 0437 lastDate = this.props.product.changed_at; 0438 } else { 0439 lastDate = this.props.product.created_at; 0440 } 0441 0442 let cDate = new Date(lastDate); 0443 // cDate = cDate.toString(); 0444 // const createdDate = cDate.split(' ')[1] + " " + cDate.split(' ')[2] + " " + cDate.split(' ')[3]; 0445 const createdDate = jQuery.timeago(cDate) 0446 // const productScoreColor = window.hpHelpers.calculateScoreColor(this.props.product.laplace_score); 0447 0448 let infoDisplay; 0449 let scoreDisplay=( 0450 <div className="score-info"> 0451 <div className="score-number"> 0452 Score {(this.props.product.laplace_score/10).toFixed(1)}% 0453 </div> 0454 <div className="score-bar-container"> 0455 <div className={"score-bar"} style={{"width":this.props.product.laplace_score/10 + "%"}}></div> 0456 </div> 0457 </div> 0458 ); 0459 infoDisplay = scoreDisplay; 0460 0461 0462 if (this.props.plingedProduct){ 0463 let plingDisplay = ( 0464 <div className="plings"> 0465 <img src="/images/system/pling-btn-active.png" /> 0466 {this.props.product.sum_plings} 0467 </div> 0468 ); 0469 0470 infoDisplay=( 0471 <div> 0472 {plingDisplay} 0473 {scoreDisplay} 0474 </div> 0475 ); 0476 } 0477 0478 0479 /*let scoreDisplay; 0480 if (this.props.plingedProduct){ 0481 scoreDisplay = ( 0482 <div className="score-info plings"> 0483 <img src="/images/system/pling-btn-active.png" /> 0484 {this.props.product.sum_plings} 0485 </div> 0486 ); 0487 } else { 0488 scoreDisplay = ( 0489 <div className="score-info"> 0490 <div className="score-number"> 0491 score {this.props.product.laplace_score + "%"} 0492 </div> 0493 <div className="score-bar-container"> 0494 <div className={"score-bar"} style={{"width":this.props.product.laplace_score + "%"}}></div> 0495 </div> 0496 </div> 0497 ); 0498 }*/ 0499 0500 productInfoDisplay = ( 0501 <div className="product-info"> 0502 <span className="product-info-title">{this.props.product.title}</span> 0503 <span className="product-info-category">{this.props.product.cat_title}</span> 0504 <span className="product-info-date">{createdDate}</span> 0505 {infoDisplay} 0506 </div> 0507 ); 0508 } 0509 0510 let projectUrl =""; 0511 if (window.page === "libreoffice"){ 0512 projectUrl = window.baseUrl +"p/"+this.props.product.project_id; 0513 }else 0514 { 0515 projectUrl = "/p/"+this.props.product.project_id; 0516 } 0517 0518 return ( 0519 <div className="product-carousel-item" style={{"width":this.props.itemWidth}}> 0520 <div className="product-carousel-item-wrapper"> 0521 <a href={projectUrl} style={{"paddingTop":paddingTop}}> 0522 <figure style={{"height":paddingTop}}> 0523 <img className="very-rounded-corners" src={this.props.product.image_small} /> 0524 </figure> 0525 {productInfoDisplay} 0526 </a> 0527 </div> 0528 </div> 0529 ) 0530 } 0531 } 0532 0533 ReactDOM.render( 0534 <CarouselsModule />, 0535 document.getElementById('carousel-module-container') 0536 );