链接到WooCommerce产品

发布于 2025-01-26 14:32:34 字数 22944 浏览 3 评论 0原文

我们必须打破移动应用程序中的结帐流,并将其移到应用程序之外。因此,目前,我们已经设置了点击车&帐户将导致其默认浏览器打开到对应URL的网站。但是,我们正在努力获取添加到购物车按钮,以打开网站上对应URL的产品的默认浏览器。

ProductsinglesCreen.js

renderAddToCart = (product) => {
        //console.log(this.props)
        const { purchasable, isOutOfStock, soldIndividually } = product;
        const {isAddingToCart} = this.props
        //console.log(this.props.isAddingToCart)
        if(purchasable) {
            if (isOutOfStock) {
                return (
                    <Text style={styles.addToCartButtonText} uppercase={false}>{I18n.t('Out of Stock!')}</Text>
                )
            }

            return (
                <Row style={styles.addToCartbuttonContainer}>
                {
                    !Boolean(soldIndividually) &&
                    <Col style={styles.quantityButtonsContainer}>
                        <Row>
                            <Col><Button style={styles.quantityAddRemove} bordered full onPress={this.props.decreaseQty}>
                                <Icon type={'Ionicons'} name={'ios-remove'}></Icon>
                            </Button></Col>
                            <Col style={styles.quantityInputBox}><Text>{this.props.getQtyVal}</Text></Col>
                            <Col><Button bordered block style={styles.quantityAddRemove} onPress={this.props.increaseQty}>
                                <Icon name={'ios-add'}></Icon>
                            </Button></Col>
                        </Row>
                    </Col>
                }
                <Col style={styles.addButtons}>
                    <Button disabled={(isAddingToCart || (product.type == 'variable' && !this.state.variation_id)) ? true : false } full onPress={() => this.processAddToCart(product)}>
                        {isAddingToCart && <ActivityIndicator size="large" color="#ffffff" />}
                        {!isAddingToCart && <Text style={styles.addToCartButtonText} uppercase={false}>{I18n.t('Add To Cart')}</Text>}
                    </Button>
                </Col>
            </Row>
            );
        }
    };

    renderEnternalProductButton =(product) => {
        const { purchasable, button_text, external_url } = product;
        if(!purchasable) {
            return (
            <Row style={styles.addToCartbuttonContainer}>
                <Col style={styles.addButtons}>
                    <Button full onPress={ ()=> Linking.openURL(external_url) }>
                        <Text style={styles.addToCartButtonText} uppercase={false}>{button_text}</Text>
                    </Button>
                </Col>
            </Row>
            )
        }
    }

    renderCategories = (product) => {
        const { categories } = product
        if(categories.length == 0 ) return null
        return (
            <View style={styles.categoryList}>
                <View style={styles.categoryLabel} >
                    { categories.length == 1 && <Text style={styles.categoryLabelText}>{I18n.t('Category')}:</Text> }
                    { categories.length > 1 && <Text style={styles.categoryLabelText}>{I18n.t('Categories')}:</Text> }
                </View>
                {
                    categories.map((category, index) => {
                        return(
                            <View style={styles.singleCategory} key={category.id}>
                                <Text style={styles.categoryText}>{decode(category.name)}</Text>
                                { (index+1 < categories.length ) && <Text style={styles.categoryText}>, </Text> }
                            </View>
                            
                        )
                    })
                }
            </View>
        )
    }

    renderTags = (product) => {
        const { tags } = product
        if(tags.length == 0 ) return null
        return (
            <View style={styles.tagList}>
                <View style={styles.categoryLabel} >
                    { tags.length == 1 && <Text style={styles.categoryLabelText}>{I18n.t('Tag')}:</Text> }
                    { tags.length > 1 && <Text style={styles.categoryLabelText}>{I18n.t('Tags')}:</Text> }
                </View>
                {
                    tags.map((category, index) => {
                        return(
                            <View style={styles.singleCategory} key={category.id}>
                                <Text style={styles.categoryText}>{decode(category.name)}</Text>
                                { (index+1 < tags.length ) && <Text style={styles.categoryText}>, </Text> }
                            </View>
                            
                        )
                    })
                }
            </View>
        )
    }

    renderSku = (product) => {
        const { sku } = product
        if( !sku ) return null
        return (
            <View style={styles.tagList}>
                <View style={styles.categoryLabel} >
                    <Text style={styles.categoryLabelText}>{I18n.t('SKU')}:</Text>
                </View>
                <View style={styles.singleCategory} >
                    <Text style={styles.categoryText}>{sku}</Text>
                </View>
            </View>
        )
    }

    renderAdditionalInfo = (product) => {
        return (
            <View>
                { product.weight != "" && <View style={styles.tagList}>
                    <View style={styles.categoryLabel} >
                        <Text style={styles.categoryLabelText}>{I18n.t('Weight')}:</Text>
                    </View>
                    <View style={styles.singleCategory} >
                        <Text style={styles.categoryText}>{product.weight + ' ' + product.product_units.weight_unit}</Text>
                    </View>
                </View>}
                { ( product.dimensions.length != "" || product.dimensions.width != "" || product.dimensions.height != "" ) && 
                <View style={styles.tagList}>
                    <View style={styles.categoryLabel} >
                        <Text style={styles.categoryLabelText}>{I18n.t('Dimensions')}:</Text>
                    </View>
                    <View style={styles.singleCategory} >
                        <Text style={styles.categoryText}>{product.dimensions.length + ' x ' + product.dimensions.width + ' x ' + product.dimensions.height + ' ' + product.product_units.dimension_unit}</Text>
                    </View>
                </View> }
                { product.attributes.length != 0 && 
                    product.attributes.map((attribute, index) => {
                        if(!attribute.visible ) return null
                        return(
                            <View style={styles.tagList} key={attribute.id}>
                                <View style={styles.categoryLabel} >
                                    <Text style={styles.categoryLabelText}>{attribute.name}:</Text>
                                </View>
                                <View style={styles.singleCategory}>
                                    <Text style={styles.categoryText}>{attribute.options.join(', ')}</Text>
                                </View>
                            </View>
                        )
                    })
                }
            </View>
        )
    }
    renderPolicyData = (policyData) => {
        return (
            <View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.shipping_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.shipping_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.refund_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.refund_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.cancellation_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.cancellation_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
            </View>
        )
    }

    

    render() {
        const { product, isLoading, attributes, variations, isLoadingVariations, variationAttributes, validVariationAttributes } = this.props

        // console.log(validVariationAttributes)

        if (!product || isLoading) {
            return (
                <View>
                    <ActivityIndicator animating size='large' />
                </View>
            )
        }

        if( product.type === 'variable' && ( ! attributes || ! variations || !validVariationAttributes ) ) {
            return (
                <View>
                    <ActivityIndicator animating size='large' />
                </View>
            )
        }

        const gallerySlider = [product.illustration, ...product.gallery]
        const { name: productName, price_html: productPrice, hidePrice, store: productStore, description,
            showAdditionalInfoTab, wcfm_product_policy_data: policyData,
            average_rating: productRating
        } = product

        const scrollY = Animated.add(
            this.state.scrollY,
            Platform.OS === 'ios' ? HEADER_MAX_HEIGHT : 0,
        );

        const headerTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -HEADER_SCROLL_DISTANCE],
            extrapolate: 'clamp',
        });
        const backButtonTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, HEADER_SCROLL_DISTANCE -10],
            extrapolate: 'clamp',
        });
        const imageOpacity = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 4, HEADER_SCROLL_DISTANCE],
            outputRange: [1, 1, 0],
            extrapolate: 'clamp',
        });
        const imageTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 100],
            extrapolate: 'clamp',
        });

        return (
            <View style={styles.fill}>
                <StatusBar barStyle={Platform.OS === 'ios' ? "dark-content" : "light-content"} backgroundColor={Colors.statusBar} />
                <Animated.ScrollView
                    style={styles.fill}
                    scrollEventThrottle={16}
                    onScroll={Animated.event(
                        [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
                        { useNativeDriver: true },
                    )}
                    contentInset={{
                        top: HEADER_MAX_HEIGHT,
                    }}
                    contentOffset={{
                        y: -HEADER_MAX_HEIGHT,
                    }}
                >
                    <View style={styles.scrollViewContent}>
                        {/* Product Title Price */}
                        <View style={styles.productNamePriceSection}>
                            <View style={styles.productNameContainer}>
                                <Text style={styles.productName}>{decode(productName)}</Text>
                            </View>
                            {
                                !Boolean(hidePrice) &&
                                <HtmlViewer
                                    html={productPrice}
                                    containerStyle={{ padding: 0, paddingRight: 5 }}
                                    htmlWrapCssString={`color: ${Colors.text}; font-size: 22px;`}
                                />
                            }
                            {
                                Boolean(productRating) &&
                                <View style={styles.productRating}>
                                    {this.renderRating(productRating)}
                                </View>
                            }
                            
                        </View>
                        {/* Product Title Price End */}
                        {/* Add To Cart Section */}
                        <View style={styles.addToCartSection}>

                            {(product.type === 'variable') && 
                                <View style={styles.variationSection}>
                                    <Form>
                                        {Object.keys(validVariationAttributes).length > 0 && attributes.map((attribute, index) => {
                                            if ( attribute.variation ) {
                                                return (
                                                    <View key={index} style={{ paddingBottom: 20 }}>
                                                        <Text>{attribute.name}</Text>
                                                        <View>
                                                            <Field name={attribute.slug} mode="dialog" style={{ left: 10 }} component={this.renderSelect} >
                                                                <Item key={''} label={I18n.t('Choose an option')} value={''} />
                                                                {validVariationAttributes[attribute.slug].map((option, key) => {
                                                                    return (
                                                                        <Item key={key} label={option} value={option} />
                                                                    )
                                                                })}
                                                            </Field>
                                                        </View>
                                                    </View>
                                                )
                                            } else {
                                                return null
                                            }
                                        })}
                                    </Form>
                                </View>
                            }
                            {
                                this.state.variation_id && this.state.variation_price && 
                                <HtmlViewer
                                    html={this.state.variation_price_html}
                                    containerStyle={{ padding: 0, paddingRight: 5 }}
                                    htmlWrapCssString={`color: ${Colors.text}; font-size: 22px;`}
                                />
                            }
                            {   this.renderAddToCart(product)   }
                            {(product.type === 'external') && this.renderEnternalProductButton(product) }

                        </View>
                        {/* Add To Cart Section End */}
                        { this.renderCategories(product) }
                        { this.renderTags(product) }
                        { this.renderSku(product) }
                        <View>
                            <Accordian 
                                    title = {'Description'}
                                    data = {description}
                                    htmlContent = {true}
                            />
                            {
                                !productStore.errors &&
                                <Accordian 
                    title = {'Store'}
                    >
                                    {/* Vendor Section */}
                                    <View style={styles.storeVendorContainer}>
                                        <View style={styles.vendorImageContainer}>
                                            <Image style={styles.vendorImage} small source={{ uri: productStore.vendor_shop_logo }} />
                                        </View>
                                        <View>
                                            <Text>{decode(productStore.vendor_shop_name)}</Text>
                                        </View>
                                    </View>
                                    {/* Vendor Section End */}
                                </Accordian> 
                            }
                            {
                                showAdditionalInfoTab &&
                                <Accordian 
                    title = {'Additional Information'}
                    >
                                    {this.renderAdditionalInfo(product)}
                                </Accordian>
                            }
                            {
                                policyData.visible && 
                                <Accordian 
                    title = {policyData.tab_title}
                    >
                                    {this.renderPolicyData(policyData)}
                                </Accordian>
                            }
                        </View>
                    </View>
                </Animated.ScrollView>
                <Animated.View
                    style={[
                        styles.header,
                        { transform: [{ translateY: headerTranslate }] },
                    ]}
                >
                    <Animated.View 
                        style={[styles.backButtonContainer,
                            { transform: [{ translateY: backButtonTranslate }] },
                        ]}>
                        <TouchableOpacity onPress={() => this.props.navigation.goBack()} style={{flex:1, justifyContent: 'center', alignItems: 'center'}}>
                            <Icon style={{color: Colors.text, marginTop:4, marginRight:4}} name='arrow-back' />
                        </TouchableOpacity>
                    </Animated.View>
                    <Animated.View
                        style={[
                            styles.backgroundImage,
                            {
                                opacity: imageOpacity,
                                transform: [{ translateY: imageTranslate }],
                            },
                        ]}
                    >
                        <AnimatedSlidebox
                            images={gallerySlider}
                            sliderBoxHeight={300}
                            //onCurrentImagePressed={index => console.warn(`image ${index} pressed`)}
                            dotColor={Colors.whiteBackground}
                            inactiveDotColor="#90A4AE"
                            resizeMethod={'resize'}
                            resizeMode={'cover'}
                            dotStyle={styles.sliderNavigationDots}
                        />
                    </Animated.View>
                </Animated.View>
            </View>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        product: ProductSingleSelectors.getProduct(state),
        isLoading: ProductSingleSelectors.isLoading(state),

        attributes: ProductSingleSelectors.getAttributes(state),
        variations: ProductSingleSelectors.getVariations(state),
        isLoadingVariations: ProductSingleSelectors.isLoadingVariations(state),

        variationAttributes: ProductSingleSelectors.getVariationAttributes(state),
        validVariationAttributes: ProductSingleSelectors.getValidVariationAttributes(state),

        getQtyVal: ProductSingleSelectors.getQuantity(state),
        isAddingToCart: CartSelectors.isLoading(state),
    }
}

const mapDispatchToProps = {
    getProduct: ProductSingleActions.productRequest,
    getVariations: ProductSingleActions.variationRequest,
    increaseQty: ProductSingleActions.increaseQty,
    decreaseQty: ProductSingleActions.decreaseQty,
    addToCart: CartActions.addToCartRequest,
    reset: ProductSingleActions.reset,
}

ProductSingleScreen = compose(
    connect(mapStateToProps, mapDispatchToProps),
    withNavigation
)(ProductSingleScreen);

export default reduxForm({
    form: 'variationForm'
})(ProductSingleScreen)

// export default compose(
//   connect(mapStateToProps, mapDispatchToProps),
//   withNavigation
// )(ProductSingleScreen)

这是它处理应用程序内部产品显示的产品显示页面,用于与WooCommerce的REST API连接有关的每个产品。它处理产品选项等。请参阅屏幕截图。 [产品展示页] [1] [1]:https://i.sstatic.net/1jlxg.png

,我们所处的位置正在尝试根据要查看的产品进行动态行为,而当按下添加到购物车时,按下产品的URL打开了产品的URL在设备上安装的默认浏览器中查看。

我们尝试了OnPress = {()=&gt; linking.openurl('https://www.ourwebsite.com/')}} 这使每个产品都打开到上面设置的URL。

We have to break the checkout flow in our mobile app and move it outside the app. So currently we have it setup that tapping Cart & Account will result in their default browser opening to the websites corresponding URL. However we are struggling with getting the Add To Cart Button to open their default browser to the products corresponding URL on the website.

ProductSingleScreen.js

renderAddToCart = (product) => {
        //console.log(this.props)
        const { purchasable, isOutOfStock, soldIndividually } = product;
        const {isAddingToCart} = this.props
        //console.log(this.props.isAddingToCart)
        if(purchasable) {
            if (isOutOfStock) {
                return (
                    <Text style={styles.addToCartButtonText} uppercase={false}>{I18n.t('Out of Stock!')}</Text>
                )
            }

            return (
                <Row style={styles.addToCartbuttonContainer}>
                {
                    !Boolean(soldIndividually) &&
                    <Col style={styles.quantityButtonsContainer}>
                        <Row>
                            <Col><Button style={styles.quantityAddRemove} bordered full onPress={this.props.decreaseQty}>
                                <Icon type={'Ionicons'} name={'ios-remove'}></Icon>
                            </Button></Col>
                            <Col style={styles.quantityInputBox}><Text>{this.props.getQtyVal}</Text></Col>
                            <Col><Button bordered block style={styles.quantityAddRemove} onPress={this.props.increaseQty}>
                                <Icon name={'ios-add'}></Icon>
                            </Button></Col>
                        </Row>
                    </Col>
                }
                <Col style={styles.addButtons}>
                    <Button disabled={(isAddingToCart || (product.type == 'variable' && !this.state.variation_id)) ? true : false } full onPress={() => this.processAddToCart(product)}>
                        {isAddingToCart && <ActivityIndicator size="large" color="#ffffff" />}
                        {!isAddingToCart && <Text style={styles.addToCartButtonText} uppercase={false}>{I18n.t('Add To Cart')}</Text>}
                    </Button>
                </Col>
            </Row>
            );
        }
    };

    renderEnternalProductButton =(product) => {
        const { purchasable, button_text, external_url } = product;
        if(!purchasable) {
            return (
            <Row style={styles.addToCartbuttonContainer}>
                <Col style={styles.addButtons}>
                    <Button full onPress={ ()=> Linking.openURL(external_url) }>
                        <Text style={styles.addToCartButtonText} uppercase={false}>{button_text}</Text>
                    </Button>
                </Col>
            </Row>
            )
        }
    }

    renderCategories = (product) => {
        const { categories } = product
        if(categories.length == 0 ) return null
        return (
            <View style={styles.categoryList}>
                <View style={styles.categoryLabel} >
                    { categories.length == 1 && <Text style={styles.categoryLabelText}>{I18n.t('Category')}:</Text> }
                    { categories.length > 1 && <Text style={styles.categoryLabelText}>{I18n.t('Categories')}:</Text> }
                </View>
                {
                    categories.map((category, index) => {
                        return(
                            <View style={styles.singleCategory} key={category.id}>
                                <Text style={styles.categoryText}>{decode(category.name)}</Text>
                                { (index+1 < categories.length ) && <Text style={styles.categoryText}>, </Text> }
                            </View>
                            
                        )
                    })
                }
            </View>
        )
    }

    renderTags = (product) => {
        const { tags } = product
        if(tags.length == 0 ) return null
        return (
            <View style={styles.tagList}>
                <View style={styles.categoryLabel} >
                    { tags.length == 1 && <Text style={styles.categoryLabelText}>{I18n.t('Tag')}:</Text> }
                    { tags.length > 1 && <Text style={styles.categoryLabelText}>{I18n.t('Tags')}:</Text> }
                </View>
                {
                    tags.map((category, index) => {
                        return(
                            <View style={styles.singleCategory} key={category.id}>
                                <Text style={styles.categoryText}>{decode(category.name)}</Text>
                                { (index+1 < tags.length ) && <Text style={styles.categoryText}>, </Text> }
                            </View>
                            
                        )
                    })
                }
            </View>
        )
    }

    renderSku = (product) => {
        const { sku } = product
        if( !sku ) return null
        return (
            <View style={styles.tagList}>
                <View style={styles.categoryLabel} >
                    <Text style={styles.categoryLabelText}>{I18n.t('SKU')}:</Text>
                </View>
                <View style={styles.singleCategory} >
                    <Text style={styles.categoryText}>{sku}</Text>
                </View>
            </View>
        )
    }

    renderAdditionalInfo = (product) => {
        return (
            <View>
                { product.weight != "" && <View style={styles.tagList}>
                    <View style={styles.categoryLabel} >
                        <Text style={styles.categoryLabelText}>{I18n.t('Weight')}:</Text>
                    </View>
                    <View style={styles.singleCategory} >
                        <Text style={styles.categoryText}>{product.weight + ' ' + product.product_units.weight_unit}</Text>
                    </View>
                </View>}
                { ( product.dimensions.length != "" || product.dimensions.width != "" || product.dimensions.height != "" ) && 
                <View style={styles.tagList}>
                    <View style={styles.categoryLabel} >
                        <Text style={styles.categoryLabelText}>{I18n.t('Dimensions')}:</Text>
                    </View>
                    <View style={styles.singleCategory} >
                        <Text style={styles.categoryText}>{product.dimensions.length + ' x ' + product.dimensions.width + ' x ' + product.dimensions.height + ' ' + product.product_units.dimension_unit}</Text>
                    </View>
                </View> }
                { product.attributes.length != 0 && 
                    product.attributes.map((attribute, index) => {
                        if(!attribute.visible ) return null
                        return(
                            <View style={styles.tagList} key={attribute.id}>
                                <View style={styles.categoryLabel} >
                                    <Text style={styles.categoryLabelText}>{attribute.name}:</Text>
                                </View>
                                <View style={styles.singleCategory}>
                                    <Text style={styles.categoryText}>{attribute.options.join(', ')}</Text>
                                </View>
                            </View>
                        )
                    })
                }
            </View>
        )
    }
    renderPolicyData = (policyData) => {
        return (
            <View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.shipping_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.shipping_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.refund_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.refund_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
                <View>
                    <H3 style={{textDecorationLine: 'underline', fontWeight: 'bold'}}>{policyData.cancellation_policy_heading}</H3>
                    <View>
                        <HtmlViewer
                            html={policyData.cancellation_policy}
                            containerStyle={{ padding: 0, paddingRight: 5 }}
                            htmlWrapCssString={`color: ${Colors.text}; font-size: 14px;`}
                        />
                    </View>
                </View>
            </View>
        )
    }

    

    render() {
        const { product, isLoading, attributes, variations, isLoadingVariations, variationAttributes, validVariationAttributes } = this.props

        // console.log(validVariationAttributes)

        if (!product || isLoading) {
            return (
                <View>
                    <ActivityIndicator animating size='large' />
                </View>
            )
        }

        if( product.type === 'variable' && ( ! attributes || ! variations || !validVariationAttributes ) ) {
            return (
                <View>
                    <ActivityIndicator animating size='large' />
                </View>
            )
        }

        const gallerySlider = [product.illustration, ...product.gallery]
        const { name: productName, price_html: productPrice, hidePrice, store: productStore, description,
            showAdditionalInfoTab, wcfm_product_policy_data: policyData,
            average_rating: productRating
        } = product

        const scrollY = Animated.add(
            this.state.scrollY,
            Platform.OS === 'ios' ? HEADER_MAX_HEIGHT : 0,
        );

        const headerTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -HEADER_SCROLL_DISTANCE],
            extrapolate: 'clamp',
        });
        const backButtonTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, HEADER_SCROLL_DISTANCE -10],
            extrapolate: 'clamp',
        });
        const imageOpacity = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE / 4, HEADER_SCROLL_DISTANCE],
            outputRange: [1, 1, 0],
            extrapolate: 'clamp',
        });
        const imageTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, 100],
            extrapolate: 'clamp',
        });

        return (
            <View style={styles.fill}>
                <StatusBar barStyle={Platform.OS === 'ios' ? "dark-content" : "light-content"} backgroundColor={Colors.statusBar} />
                <Animated.ScrollView
                    style={styles.fill}
                    scrollEventThrottle={16}
                    onScroll={Animated.event(
                        [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
                        { useNativeDriver: true },
                    )}
                    contentInset={{
                        top: HEADER_MAX_HEIGHT,
                    }}
                    contentOffset={{
                        y: -HEADER_MAX_HEIGHT,
                    }}
                >
                    <View style={styles.scrollViewContent}>
                        {/* Product Title Price */}
                        <View style={styles.productNamePriceSection}>
                            <View style={styles.productNameContainer}>
                                <Text style={styles.productName}>{decode(productName)}</Text>
                            </View>
                            {
                                !Boolean(hidePrice) &&
                                <HtmlViewer
                                    html={productPrice}
                                    containerStyle={{ padding: 0, paddingRight: 5 }}
                                    htmlWrapCssString={`color: ${Colors.text}; font-size: 22px;`}
                                />
                            }
                            {
                                Boolean(productRating) &&
                                <View style={styles.productRating}>
                                    {this.renderRating(productRating)}
                                </View>
                            }
                            
                        </View>
                        {/* Product Title Price End */}
                        {/* Add To Cart Section */}
                        <View style={styles.addToCartSection}>

                            {(product.type === 'variable') && 
                                <View style={styles.variationSection}>
                                    <Form>
                                        {Object.keys(validVariationAttributes).length > 0 && attributes.map((attribute, index) => {
                                            if ( attribute.variation ) {
                                                return (
                                                    <View key={index} style={{ paddingBottom: 20 }}>
                                                        <Text>{attribute.name}</Text>
                                                        <View>
                                                            <Field name={attribute.slug} mode="dialog" style={{ left: 10 }} component={this.renderSelect} >
                                                                <Item key={''} label={I18n.t('Choose an option')} value={''} />
                                                                {validVariationAttributes[attribute.slug].map((option, key) => {
                                                                    return (
                                                                        <Item key={key} label={option} value={option} />
                                                                    )
                                                                })}
                                                            </Field>
                                                        </View>
                                                    </View>
                                                )
                                            } else {
                                                return null
                                            }
                                        })}
                                    </Form>
                                </View>
                            }
                            {
                                this.state.variation_id && this.state.variation_price && 
                                <HtmlViewer
                                    html={this.state.variation_price_html}
                                    containerStyle={{ padding: 0, paddingRight: 5 }}
                                    htmlWrapCssString={`color: ${Colors.text}; font-size: 22px;`}
                                />
                            }
                            {   this.renderAddToCart(product)   }
                            {(product.type === 'external') && this.renderEnternalProductButton(product) }

                        </View>
                        {/* Add To Cart Section End */}
                        { this.renderCategories(product) }
                        { this.renderTags(product) }
                        { this.renderSku(product) }
                        <View>
                            <Accordian 
                                    title = {'Description'}
                                    data = {description}
                                    htmlContent = {true}
                            />
                            {
                                !productStore.errors &&
                                <Accordian 
                    title = {'Store'}
                    >
                                    {/* Vendor Section */}
                                    <View style={styles.storeVendorContainer}>
                                        <View style={styles.vendorImageContainer}>
                                            <Image style={styles.vendorImage} small source={{ uri: productStore.vendor_shop_logo }} />
                                        </View>
                                        <View>
                                            <Text>{decode(productStore.vendor_shop_name)}</Text>
                                        </View>
                                    </View>
                                    {/* Vendor Section End */}
                                </Accordian> 
                            }
                            {
                                showAdditionalInfoTab &&
                                <Accordian 
                    title = {'Additional Information'}
                    >
                                    {this.renderAdditionalInfo(product)}
                                </Accordian>
                            }
                            {
                                policyData.visible && 
                                <Accordian 
                    title = {policyData.tab_title}
                    >
                                    {this.renderPolicyData(policyData)}
                                </Accordian>
                            }
                        </View>
                    </View>
                </Animated.ScrollView>
                <Animated.View
                    style={[
                        styles.header,
                        { transform: [{ translateY: headerTranslate }] },
                    ]}
                >
                    <Animated.View 
                        style={[styles.backButtonContainer,
                            { transform: [{ translateY: backButtonTranslate }] },
                        ]}>
                        <TouchableOpacity onPress={() => this.props.navigation.goBack()} style={{flex:1, justifyContent: 'center', alignItems: 'center'}}>
                            <Icon style={{color: Colors.text, marginTop:4, marginRight:4}} name='arrow-back' />
                        </TouchableOpacity>
                    </Animated.View>
                    <Animated.View
                        style={[
                            styles.backgroundImage,
                            {
                                opacity: imageOpacity,
                                transform: [{ translateY: imageTranslate }],
                            },
                        ]}
                    >
                        <AnimatedSlidebox
                            images={gallerySlider}
                            sliderBoxHeight={300}
                            //onCurrentImagePressed={index => console.warn(`image ${index} pressed`)}
                            dotColor={Colors.whiteBackground}
                            inactiveDotColor="#90A4AE"
                            resizeMethod={'resize'}
                            resizeMode={'cover'}
                            dotStyle={styles.sliderNavigationDots}
                        />
                    </Animated.View>
                </Animated.View>
            </View>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        product: ProductSingleSelectors.getProduct(state),
        isLoading: ProductSingleSelectors.isLoading(state),

        attributes: ProductSingleSelectors.getAttributes(state),
        variations: ProductSingleSelectors.getVariations(state),
        isLoadingVariations: ProductSingleSelectors.isLoadingVariations(state),

        variationAttributes: ProductSingleSelectors.getVariationAttributes(state),
        validVariationAttributes: ProductSingleSelectors.getValidVariationAttributes(state),

        getQtyVal: ProductSingleSelectors.getQuantity(state),
        isAddingToCart: CartSelectors.isLoading(state),
    }
}

const mapDispatchToProps = {
    getProduct: ProductSingleActions.productRequest,
    getVariations: ProductSingleActions.variationRequest,
    increaseQty: ProductSingleActions.increaseQty,
    decreaseQty: ProductSingleActions.decreaseQty,
    addToCart: CartActions.addToCartRequest,
    reset: ProductSingleActions.reset,
}

ProductSingleScreen = compose(
    connect(mapStateToProps, mapDispatchToProps),
    withNavigation
)(ProductSingleScreen);

export default reduxForm({
    form: 'variationForm'
})(ProductSingleScreen)

// export default compose(
//   connect(mapStateToProps, mapDispatchToProps),
//   withNavigation
// )(ProductSingleScreen)

This is the Product Display Page it handles the display of products inside the app and is used for every product queried over the rest api connection with Woocommerce. It handles product options etc. see screenshot. [Product Display Page][1]
[1]: https://i.sstatic.net/1jLXG.png

Where we are stuck is trying to get this button to behave dynamically based on the product being viewed and when Add To Cart is pressed opens the url of the product being viewed in the app in the default browser installed on the device.

We have tried onPress={() => Linking.openURL('https://www.ourwebsite.com/')}
which makes every product open to the url set above.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

魄砕の薆 2025-02-02 14:32:34

您可以使用这样的链接:

const loadInBrowser = ( url ) => {
        
        url && Linking.openURL( url ).catch( err => console.log( `Couldn't load page ${err}` ))
    };

首先,我们检查“ URL”是否不是null,然后我们尝试通过链接进行OPENURL,如果有错误,我们将其记录到控制台中。

然后,您可以在按钮或触摸式的情况下调用此功能

    <TouchableOpacity onpress={ loadInBrower } ></TouchableOpacity>
    
<Button
      onPress={ loadInBrower }
      title="open Browser"
      color="#841584"
    />

you can use Linking like this:

const loadInBrowser = ( url ) => {
        
        url && Linking.openURL( url ).catch( err => console.log( `Couldn't load page ${err}` ))
    };

first we check if "url" is not null, then we try to openURL with Linking if we got an error we log it into the console.

then you can call this function in a Button or TouchableOpacity like this

    <TouchableOpacity onpress={ loadInBrower } ></TouchableOpacity>
    
<Button
      onPress={ loadInBrower }
      title="open Browser"
      color="#841584"
    />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文