Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

animated view #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 69 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,147 @@
import React from "react";
import { StyleSheet, Text, View } from "react-native";

import React from 'react'
import { StyleSheet, Text, View, Animated } from 'react-native'
const VIEW_MORE_HEIGHT = 33;
export default class ReadMore extends React.Component {
state = {
measured: false,
shouldShowReadMore: false,
showAllText: false
showAllText: false,
fullHeight: 0,
height: new Animated.Value(0),
limitedHeight: 0,
};

async componentDidMount() {
this._isMounted = true;
await nextFrameAsync();
this._isMounted = true
await nextFrameAsync()

if (!this._isMounted) {
return;
return
}

// Get the height of the text with no restriction on number of lines
const fullHeight = await measureHeightAsync(this._text);
this.setState({ measured: true });
await nextFrameAsync();
const fullHeight = await measureHeightAsync(this._text)
this.setState({measured: true})
await nextFrameAsync()

if (!this._isMounted) {
return;
return
}

// Get the height of the text now that number of lines has been set
const limitedHeight = await measureHeightAsync(this._text);

const limitedHeight = await measureHeightAsync(this._text)
if (fullHeight > limitedHeight) {
this.state.height.setValue(limitedHeight + VIEW_MORE_HEIGHT)
this.setState({ shouldShowReadMore: true }, () => {
this.props.onReady && this.props.onReady();
});
this.props.onReady && this.props.onReady()
})
this.setState({fullHeight: fullHeight + VIEW_MORE_HEIGHT, limitedHeight: limitedHeight + VIEW_MORE_HEIGHT})
} else {
this.props.onReady && this.props.onReady();
this.props.onReady && this.props.onReady()
}

}

componentWillUnmount() {
this._isMounted = false;
this._isMounted = false
}

render() {
let { measured, showAllText } = this.state;

let { numberOfLines } = this.props;
let { measured, shouldShowReadMore, limitedHeight, showAllText, height } = this.state

let { numberOfLines } = this.props
return (
<View>
<Animated.View style={{height: !!limitedHeight ? height : undefined}}>
<Text
numberOfLines={measured && !showAllText ? numberOfLines : 0}
ref={text => {
this._text = text;
this._text = text
}}
>
{this.props.children}
</Text>

{this._maybeRenderReadMore()}
</View>
);
{shouldShowReadMore && <View style={styles.readMore}>
{this._maybeRenderReadMore()}
</View>}
</Animated.View>
)
}

_handlePressReadMore = () => {
this.setState({ showAllText: true });
this.setState(
{ showAllText: true },
() => {
Animated.spring(
this.state.height,
{
toValue: this.state.fullHeight
}
).start();
}
)


};

_handlePressReadLess = () => {
this.setState({ showAllText: false });
this.setState(
{ showAllText: false },
() => {
Animated.spring(
this.state.height,
{
toValue: this.state.limitedHeight
}
).start()
}
)
};

_maybeRenderReadMore() {
let { shouldShowReadMore, showAllText } = this.state;
let { shouldShowReadMore, showAllText } = this.state

if (shouldShowReadMore && !showAllText) {
if (this.props.renderTruncatedFooter) {
return this.props.renderTruncatedFooter(this._handlePressReadMore);
return this.props.renderTruncatedFooter(this._handlePressReadMore)
}

return (
<Text style={styles.button} onPress={this._handlePressReadMore}>
Read more
</Text>
);
)
} else if (shouldShowReadMore && showAllText) {
if (this.props.renderRevealedFooter) {
return this.props.renderRevealedFooter(this._handlePressReadLess);
return this.props.renderRevealedFooter(this._handlePressReadLess)
}

return (
<Text style={styles.button} onPress={this._handlePressReadLess}>
Hide
</Text>
);
)
}
}
}

function measureHeightAsync(component) {
return new Promise(resolve => {
component.measure((x, y, w, h) => {
resolve(h);
});
});
resolve(h)
})
})
}

function nextFrameAsync() {
return new Promise(resolve => requestAnimationFrame(() => resolve()));
return new Promise(resolve => requestAnimationFrame(() => resolve()))
}

const styles = StyleSheet.create({
button: {
color: "#888",
color: '#888',
marginTop: 5
},
readMore: {
height: VIEW_MORE_HEIGHT
}
});
})