diff --git a/README.md b/README.md index b166b10..415d16d 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,19 @@ ![screenshot](./screenshot.jpg) -## 🎞背景 +## 🎞 背景 无论是电脑版还是手机版的优慕课客户端用起来似乎都不是那么令人满意,电脑版在课程页面只能看到标题不能看到详情,手机版从详情页退出后会回到最顶端。于是就有了做一个第三方客户端的想法,也当是 React Native 的一次练手了 -## 📄TODO +## 🧨 版本说明 + +| 版本 | 说明 | +| ------ | ------------ | +| 0.0.1a | 首个可用版本 | + + + +## 📄 TODO - [ ] 弹出键盘不遮挡输入框 - [ ] 根据像素比例设置登录背景图片大小 @@ -19,4 +27,7 @@ - [ ] Forum 初始化失败后 UI 显示错误信息 - [ ] 当数据获取完成后通过动画转到话题列表 - [ ] 解决当动画进行时点击话题标题动画会被打断的问题 +- [ ] 支持显示回复图片 +- [ ] 在回复中显示头像 +- [ ] 当滑动到页面底部时显示"加载更多" diff --git a/src/component/YooForumTopic.js b/src/component/YooForumTopic.js index 04db5a5..0f4b141 100644 --- a/src/component/YooForumTopic.js +++ b/src/component/YooForumTopic.js @@ -1,13 +1,55 @@ import React, {Component} from 'react'; import YooForumTopicUI from '../ui/YooForumTopicUI'; +import {gbkFetch} from '../api/HTTP'; +import * as cheerio from 'cheerio'; export default class YooForumTopic extends Component { + constructor(props) { + super(props); + this.state = { + replies: [], + }; + this.getReplies = this.getReplies.bind(this); + } + + componentDidMount() { + this.getReplies(); + } + + getReplies() { + gbkFetch( + 'GET', + `http://eol.ctbu.edu.cn/meol/common/faq/thread.jsp?threadid=${this.props.topic.threadID}`, + { + headers: 'YooMooc', + }, + ).then((response) => { + const newReplies = []; + const appendReply = (username, content) => { + newReplies.push({username, content}); + }; + const $ = cheerio.load(response, {ignoreWhitespace: true}); + $('input[type=hidden]').each(function () { + const current = $(this); + const currentUserInfo = current.parent().parent().parent().parent(); + if (currentUserInfo.html().slice(2, 4) === 'td') { + appendReply( + currentUserInfo.find('h6').text().split(' ')[1], + cheerio.load(current.attr('value')).text(), + ); + } + }); + this.setState({replies: [...this.state.replies, ...newReplies]}); + }); + } + render() { return ( ); } diff --git a/src/ui/YooForumTopicUI.js b/src/ui/YooForumTopicUI.js index 8011976..ef8e4ef 100644 --- a/src/ui/YooForumTopicUI.js +++ b/src/ui/YooForumTopicUI.js @@ -49,6 +49,7 @@ export default class YooForumTopicUI extends Component { this.state.translate, this.state.layoutY, this.onAnimationFinished, + this.props.replies, ); } else { this.props.hideDetail(this.state.translate, this.onAnimationFinished); diff --git a/src/ui/YooForumUI.js b/src/ui/YooForumUI.js index dc37342..5c91e20 100644 --- a/src/ui/YooForumUI.js +++ b/src/ui/YooForumUI.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React, {Component, createRef} from 'react'; import { View, ScrollView, @@ -10,13 +10,21 @@ import { Dimensions, } from 'react-native'; import YooForumTopic from '../component/YooForumTopic'; +import YooReply from './YooReply'; const screenWidth = Dimensions.get('window').width; +const screenHeight = Dimensions.get('window').height; const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView); const styles = StyleSheet.create({ container: { width: screenWidth * 2, }, + repliesContainer: { + position: 'absolute', + left: screenWidth, + width: screenWidth, + height: screenHeight - 124, + }, hintContainer: { flex: 1, alignItems: 'center', @@ -44,13 +52,23 @@ export default class YooForumUI extends Component { scrollEnabled: true, currentPosition: 0, translateX: new Animated.Value(0), + currentReplies: [], + replyTranslateY: new Animated.Value(0), }; + this.replyRef = createRef(); this.showDetail = this.showDetail.bind(this); this.hideDetail = this.hideDetail.bind(this); } - showDetail(translate, layoutY, onAnimationFinished) { - this.setState({scrollEnabled: false}); + showDetail(translate, layoutY, onAnimationFinished, replies) { + this.replyRef.current.scrollTo({x: 0, y: 0, animated: false}); + this.setState({ + scrollEnabled: false, + currentReplies: replies, + }); + this.state.replyTranslateY.setValue( + this.state.currentPosition + 100 + screenHeight, + ); Animated.parallel([ Animated.timing(translate, { toValue: { @@ -65,6 +83,12 @@ export default class YooForumUI extends Component { duration: 250, useNativeDriver: true, }), + Animated.timing(this.state.replyTranslateY, { + toValue: this.state.currentPosition + 100, + duration: 250, + delay: 250, + useNativeDriver: true, + }), ]).start(onAnimationFinished); } @@ -84,6 +108,11 @@ export default class YooForumUI extends Component { duration: 250, useNativeDriver: true, }), + Animated.timing(this.state.replyTranslateY, { + toValue: this.state.currentPosition + 100 + screenHeight, + duration: 250, + useNativeDriver: true, + }), ]).start(onAnimationFinished); } @@ -127,6 +156,16 @@ export default class YooForumUI extends Component { /> )} + + {this.state.currentReplies.map((reply, key) => ( + + ))} + ); } diff --git a/src/ui/YooReply.js b/src/ui/YooReply.js new file mode 100644 index 0000000..f78fda3 --- /dev/null +++ b/src/ui/YooReply.js @@ -0,0 +1,28 @@ +import React, {Component} from 'react'; +import {View, Text, StyleSheet} from 'react-native'; + +const styles = StyleSheet.create({ + container: { + backgroundColor: 'lightgray', + borderRadius: 8, + padding: 16, + margin: 8, + }, + username: { + fontSize: 16, + }, + content: { + fontSize: 24, + }, +}); + +export default class YooReply extends Component { + render() { + return ( + + {this.props.reply.username} + {this.props.reply.content} + + ); + } +}