File indexing completed on 2025-02-09 07:16:41

0001 class HomePage extends React.Component {
0002   constructor(props){
0003         super(props);
0004         this.state = {
0005       device:store.getState().device,
0006       products:store.getState().products
0007     };
0008   }
0009 
0010   componentWillReceiveProps(nextProps) {
0011     if (nextProps.device){
0012       this.setState({device:nextProps.device});
0013     }
0014     if (nextProps.products){
0015       this.setState({products:nextProps.products});
0016     }
0017   }
0018 
0019   render(){
0020     return (
0021       <div id="homepage">
0022         <div className="hp-wrapper">
0023           <Introduction
0024             device={this.state.device}
0025             count={window.totalProjects}
0026           />
0027         </div>
0028       </div>
0029     )
0030   }
0031 }
0032 
0033 const mapStateToHomePageProps = (state) => {
0034   const device = state.device;
0035   const products = state.products;
0036   return {
0037     device,
0038     products
0039   }
0040 }
0041 
0042 const mapDispatchToHomePageProps = (dispatch) => {
0043   return {
0044     dispatch
0045   }
0046 }
0047 
0048 const HomePageWrapper = ReactRedux.connect(
0049   mapStateToHomePageProps,
0050   mapDispatchToHomePageProps
0051 )(HomePage);
0052 
0053 class Introduction extends React.Component {
0054   render(){
0055 
0056     let introductionText, siteTitle, buttonsContainer;
0057     if (window.page === "appimages"){
0058       siteTitle = "AppImageHub";
0059       introductionText = (
0060         <p>
0061           This catalog has {this.props.count} AppImages and counting.<br/>
0062           AppImages are self-contained apps which can simply be downloaded & run on any Linux distribution. For easy integration, download AppImageLauncher:
0063         </p>
0064       );
0065       buttonsContainer = (
0066         <div className="actions">
0067           <a href="/p/1228228" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored mdl-color--primary">
0068             <img src="/theme/react/assets/img/icon-download_white.png"/> AppImageLauncher
0069           </a>
0070           <a href="/browse" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored mdl-color--primary">Browse all apps</a>
0071 
0072           <a href="https://chat.opendesktop.org/#/room/#appimagehub:chat.opendesktop.org" className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored mdl-color--primary" style={{ "margin-left":"50px"}}>Join our chat #AppImageHub</a>
0073         </div>
0074       );
0075     } else if (window.page === "libreoffice"){
0076       siteTitle = "LibreOffice";
0077       introductionText = (
0078         <p>
0079           Extensions add new features to your LibreOffice or make the use of already existing ones easier.
0080           Currently there are {this.props.count} project(s) available.
0081         </p>
0082       );
0083       buttonsContainer = (
0084         <div className="actions green">
0085           <a href={window.baseUrl+"product/add"} className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored mdl-color--primary">Add Extension</a>
0086           <a href={window.baseUrl+"browse/"} className="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored mdl-color--primary">Browse all Extensions</a>
0087         </div>
0088       );
0089     }
0090 
0091     return (
0092       <div id="introduction" className="section">
0093         <div className="container">
0094           <article>
0095             <h2 className="mdl-color-text--primary">Welcome to {siteTitle}</h2>
0096             {introductionText}
0097             {buttonsContainer}
0098           </article>
0099         </div>
0100       </div>
0101     )
0102   }
0103 }
0104 
0105 class HpIntroSection extends React.Component {
0106   constructor(props){
0107         super(props);
0108         this.state = {};
0109   }
0110   render(){
0111     return (
0112       <div id="homepage-search-container" className="section intro">
0113         <div className="container">
0114           <article>
0115             <p>Search thousands of snaps used by millions of people across 50 Linux distributions</p>
0116           </article>
0117           <div id="hp-search-form-container">
0118             <select className="mdl-selectfield__select">
0119               <option>categories</option>
0120             </select>
0121             <input type="text"/>
0122             <button>search</button>
0123           </div>
0124         </div>
0125       </div>
0126     )
0127   }
0128 }
0129 
0130 const mapStateToHpIntroSectionProps = (state) => {
0131   const categories = state.categories;
0132   return {
0133     categories
0134   }
0135 }
0136 
0137 const mapDispatchToHpIntroSectionProps = (dispatch) => {
0138   return {
0139     dispatch
0140   }
0141 }
0142 
0143 const HpIntroSectionWrapper = ReactRedux.connect(
0144   mapStateToHpIntroSectionProps,
0145   mapDispatchToHpIntroSectionProps
0146 )(HpIntroSection);
0147 
0148 class ProductCarousel extends React.Component {
0149   constructor(props){
0150         super(props);
0151         this.state = {
0152       showRightArrow:true,
0153       showLeftArrow:false
0154     };
0155     this.updateDimensions = this.updateDimensions.bind(this);
0156     this.animateProductCarousel = this.animateProductCarousel.bind(this);
0157   }
0158 
0159   componentWillMount() {
0160     window.addEventListener("resize", this.updateDimensions);
0161   }
0162 
0163   componentDidMount() {
0164     this.updateDimensions();
0165   }
0166 
0167   updateDimensions(){
0168     const containerWidth = $('#introduction').find('.container').width();
0169     const sliderWidth = containerWidth * 3;
0170     const itemWidth = containerWidth / 5;
0171     this.setState({
0172       sliderPosition:0,
0173       containerWidth:containerWidth,
0174       sliderWidth:sliderWidth,
0175       itemWidth:itemWidth
0176     });
0177   }
0178 
0179   animateProductCarousel(dir){
0180 
0181     let newSliderPosition = this.state.sliderPosition;
0182     if (dir === 'left'){
0183       newSliderPosition = this.state.sliderPosition - this.state.containerWidth;
0184     } else {
0185       newSliderPosition = this.state.sliderPosition + this.state.containerWidth;
0186     }
0187 
0188     this.setState({sliderPosition:newSliderPosition},function(){
0189 
0190       let showLeftArrow = true,
0191           showRightArrow = true;
0192       const endPoint = this.state.sliderWidth - this.state.containerWidth;
0193       if (this.state.sliderPosition <= 0){
0194         showLeftArrow = false;
0195       }
0196       if (this.state.sliderPosition >= endPoint){
0197         showRightArrow = false;
0198       }
0199 
0200       this.setState({
0201         showLeftArrow:showLeftArrow,
0202         showRightArrow:showRightArrow
0203       });
0204 
0205     });
0206 
0207   }
0208 
0209   render(){
0210 
0211     let carouselItemsDisplay;
0212     if (this.props.products && this.props.products.length > 0){
0213       carouselItemsDisplay = this.props.products.map((product,index) => (
0214         <ProductCarouselItem
0215           key={index}
0216           product={product}
0217           itemWidth={this.state.itemWidth}
0218         />
0219       ));
0220     }
0221 
0222     let rightArrowDisplay, leftArrowDisplay;
0223     if (this.state.showLeftArrow){
0224       leftArrowDisplay = (
0225         <div className="product-carousel-left">
0226           <a onClick={() => this.animateProductCarousel('left')} className="carousel-arrow arrow-left">
0227             <i className="material-icons">chevron_left</i>
0228           </a>
0229         </div>
0230       );
0231     }
0232     if (this.state.showRightArrow){
0233       rightArrowDisplay = (
0234         <div className="product-carousel-right">
0235           <a onClick={() => this.animateProductCarousel('right')} className="carousel-arrow arrow-right">
0236             <i className="material-icons">chevron_right</i>
0237           </a>
0238         </div>
0239       );
0240     }
0241 
0242     return (
0243       <div className="product-carousel">
0244         <div className="product-carousel-header">
0245           <h2><a href={this.props.link}>{this.props.title}<i className="material-icons">chevron_right</i></a></h2>
0246         </div>
0247         <div className="product-carousel-wrapper">
0248           {leftArrowDisplay}
0249           <div className="product-carousel-container">
0250             <div className="product-carousel-slider" style={{"width":this.state.sliderWidth,"left":"-"+this.state.sliderPosition + "px"}}>
0251               {carouselItemsDisplay}
0252             </div>
0253           </div>
0254           {rightArrowDisplay}
0255         </div>
0256       </div>
0257     )
0258   }
0259 }
0260 
0261 class ProductCarouselItem extends React.Component {
0262   constructor(props){
0263         super(props);
0264         this.state = {};
0265   }
0266 
0267   render(){
0268     let imageBaseUrl;
0269     if (store.getState().env === 'live') {
0270       imageBaseUrl = 'cn.opendesktop.org';
0271     } else {
0272       imageBaseUrl = 'cn.pling.it';
0273     }
0274     return (
0275       <div className="product-carousel-item" style={{"width":this.props.itemWidth}}>
0276         <a href={"/p/"+this.props.product.project_id }>
0277           <figure>
0278             <img className="very-rounded-corners" src={'https://' + imageBaseUrl + '/cache/200x171/img/' + this.props.product.image_small} />
0279           </figure>
0280           <div className="product-info">
0281             <span className="product-info-title">{this.props.product.title}</span>
0282             <span className="product-info-user">{this.props.product.username}</span>
0283           </div>
0284         </a>
0285       </div>
0286     )
0287   }
0288 }