commit ace3b98470a50bd71bfd8051099997080932bf60
parent aecd0484341b987d8cfea3246aa348792ee239c3
Author: Johan Lindskogen <johan.lindskogen@gmail.com>
Date: Fri, 30 Mar 2018 18:59:41 +0200
Fetch lines for bufferId
Diffstat:
14 files changed, 307 insertions(+), 226 deletions(-)
diff --git a/index.js b/index.js
@@ -10,10 +10,11 @@ import store from "./src/store";
import App from "./src/usecase/App";
import ConnectionGate from "./src/usecase/ConnectionGate";
+const connection = new WeechatConnection(store.dispatch, HOSTNAME, PASSWORD);
+
class WeechatNative extends React.Component {
componentWillMount() {
- let connection = new WeechatConnection(store.dispatch, HOSTNAME, PASSWORD);
- let compressed = false;
+ const compressed = false;
connection.connect().then(
conn => {
@@ -33,11 +34,17 @@ class WeechatNative extends React.Component {
}
);
}
+ fetchLines = (bufferId, numLines = 50) => {
+ connection &&
+ connection.send(
+ `(lines) hdata buffer:0x${bufferId}/own_lines/last_line(-${numLines})/data`
+ );
+ };
render() {
return (
<Provider store={store}>
<ConnectionGate>
- <App />
+ <App fetchLinesForBuffer={this.fetchLines} />
</ConnectionGate>
</Provider>
);
diff --git a/src/lib/weechat/action_transformer.ts b/src/lib/weechat/action_transformer.ts
@@ -18,8 +18,8 @@ export const transformToReduxAction = (data: WeechatResponse<any>) => {
return {
type: "FETCH_BUFFERS",
payload: reduceToObjectByKey(
- object.content,
- buffer => buffer.pointers[0]
+ object.content.map(o => ({ ...o, id: o.pointers[0] })),
+ buffer => buffer.id
)
};
}
@@ -31,6 +31,14 @@ export const transformToReduxAction = (data: WeechatResponse<any>) => {
payload: infolist.content.value
};
}
+ case "lines": {
+ const object = data.objects[0] as WeechatObject<WeechatLine[]>;
+ return {
+ type: "FETCH_LINES",
+ bufferId: object.content[0].buffer,
+ payload: object.content
+ };
+ }
}
}
};
diff --git a/src/lib/weechat/types.ts b/src/lib/weechat/types.ts
@@ -49,3 +49,20 @@ interface Header {
length: number;
compression: number;
}
+
+interface WeechatLine {
+ pointers: string[];
+ prefix_length: number;
+ prefix: string;
+ displayed: number;
+ message: string;
+ refresh_needed: number;
+ str_time: string;
+ date: string;
+ tags_count: number;
+ date_printed: string;
+ tags_array: string[];
+ buffer: string;
+ highlight: number;
+ y: number;
+}
diff --git a/src/store/index.js b/src/store/index.js
@@ -1,6 +1,7 @@
import { combineReducers, createStore, applyMiddleware } from "redux";
import buffers from "./buffers";
+import lines from "./lines";
const app = (state = { connected: false }, action) => {
switch (action.type) {
@@ -15,7 +16,8 @@ const app = (state = { connected: false }, action) => {
const reducer = combineReducers({
app,
- buffers
+ buffers,
+ lines
});
export default createStore(
diff --git a/src/store/lines.ts b/src/store/lines.ts
@@ -0,0 +1,15 @@
+type LinesState = { [key: string]: WeechatLine };
+
+const initialState: LinesState = {};
+
+export default (state: LinesState = initialState, action): LinesState => {
+ switch (action.type) {
+ case "FETCH_LINES":
+ return {
+ ...state,
+ [action.bufferId]: action.payload
+ };
+ default:
+ return state;
+ }
+};
diff --git a/src/usecase/App.tsx b/src/usecase/App.tsx
@@ -13,28 +13,41 @@ import BufferList from "./buffers/ui/BufferList";
interface Props {
buffers: WeechatBuffer[];
currentBufferName: string;
+ fetchLinesForBuffer: (string) => void;
}
-class App extends React.Component<Props> {
+interface State {
+ currentBufferId: string | null;
+}
+
+class App extends React.Component<Props, State> {
drawer: Drawer;
- changeCurrentBuffer(bufferName) {
+ state: State = { currentBufferId: null };
+
+ changeCurrentBuffer = buffer => {
// this.props.dispatch(changeCurrentBuffer(bufferName));
this.drawer.close();
- }
+ this.props.fetchLinesForBuffer(buffer.id);
+ console.log(buffer, buffer.id);
+ this.setState({
+ currentBufferId: buffer.id
+ });
+ };
render() {
+ const { currentBufferId } = this.state;
const { buffers, currentBufferName } = this.props;
- console.log(buffers);
-
const sidebar = (
<BufferList
buffers={_.orderBy(buffers, ["number"])}
currentBufferName={currentBufferName}
- onSelectBuffer={b => this.changeCurrentBuffer(b.short_name)}
+ onSelectBuffer={this.changeCurrentBuffer}
/>
);
+ console.log({ currentBufferId });
+
return (
<View style={styles.container}>
<Drawer
@@ -61,7 +74,7 @@ class App extends React.Component<Props> {
</View>
<View style={styles.channels} />
</View>
- <BufferView bufferName={currentBufferName} />
+ <BufferView bufferId={currentBufferId} />
</Drawer>
</View>
);
diff --git a/src/usecase/buffers/ui/Buffer.js b/src/usecase/buffers/ui/Buffer.js
@@ -1,87 +0,0 @@
-import React from "react";
-import { StyleSheet, Animated, Keyboard, ListView, View } from "react-native";
-import { connect } from "react-redux";
-
-import AppleEasing from "react-apple-easing";
-
-import BufferLine from "./BufferLine";
-
-//const easingFunction = Easing.bezier(0.55, 0.085, 0.68, 0.53);
-const easingFunction = AppleEasing.easeIn;
-
-class Buffer extends React.Component {
- state = {
- keyboardOffset: new Animated.Value(0)
- };
-
- componentDidMount() {
- this.cancelKeyboardWillShow = Keyboard.addListener("keyboardWillShow", e =>
- this._keyboardWillShow(e)
- );
- this.cancelKeyboardWillHide = Keyboard.addListener("keyboardWillHide", e =>
- this._keyboardWillHide(e)
- );
- }
- _keyboardWillShow(e) {
- console.log(e);
- Animated.timing(this.state.keyboardOffset, {
- toValue: e.endCoordinates.height,
- duration: e.duration,
- easing: easingFunction
- }).start();
- }
- _keyboardWillHide(e) {
- Animated.timing(this.state.keyboardOffset, {
- toValue: 0,
- duration: e.duration,
- easing: easingFunction
- }).start();
- }
- render() {
- const { dataSource, onLongPress, parseArgs } = this.props;
- return (
- <ListView
- style={styles.main}
- dataSource={dataSource}
- keyboardDismissMode="interactive"
- renderRow={line => (
- <BufferLine
- line={line}
- onLongPress={onLongPress}
- parseArgs={parseArgs}
- />
- )}
- />
- );
- }
-}
-
-export default connect((state, { buffer }) => {
- const dataSource = new ListView.DataSource({
- rowHasChanged: (r1, r2) => r1 !== r2
- });
-
- return {
- dataSource: dataSource.cloneWithRows(buffer.lines)
- };
-})(Buffer);
-
-const styles = StyleSheet.create({
- topbar: {
- height: 20,
- backgroundColor: "#001"
- },
- bottomBox: {
- height: 40,
- paddingHorizontal: 10,
- justifyContent: "center",
- backgroundColor: "#aaa"
- },
- inputBox: {
- height: 25,
- paddingHorizontal: 5,
- justifyContent: "center",
- borderColor: "gray",
- backgroundColor: "#fff"
- }
-});
diff --git a/src/usecase/buffers/ui/Buffer.tsx b/src/usecase/buffers/ui/Buffer.tsx
@@ -0,0 +1,96 @@
+import React from "react";
+import {
+ StyleSheet,
+ Animated,
+ Keyboard,
+ FlatList,
+ View,
+ EmitterSubscription
+} from "react-native";
+import { connect } from "react-redux";
+
+import AppleEasing from "react-apple-easing";
+
+import BufferLine from "./BufferLine";
+
+//const easingFunction = Easing.bezier(0.55, 0.085, 0.68, 0.53);
+const easingFunction = AppleEasing.easeIn;
+
+interface Props {
+ lines: WeechatLine[];
+ onLongPress: () => any;
+ parseArgs: any;
+}
+
+class Buffer extends React.Component<Props> {
+ cancelKeyboardWillShow: EmitterSubscription;
+ cancelKeyboardWillHide: EmitterSubscription;
+
+ state = {
+ keyboardOffset: new Animated.Value(0)
+ };
+
+ componentDidMount() {
+ this.cancelKeyboardWillShow = Keyboard.addListener("keyboardWillShow", e =>
+ this._keyboardWillShow(e)
+ );
+ this.cancelKeyboardWillHide = Keyboard.addListener("keyboardWillHide", e =>
+ this._keyboardWillHide(e)
+ );
+ }
+ _keyboardWillShow(e) {
+ console.log(e);
+ Animated.timing(this.state.keyboardOffset, {
+ toValue: e.endCoordinates.height,
+ duration: e.duration,
+ easing: easingFunction
+ }).start();
+ }
+ _keyboardWillHide(e) {
+ Animated.timing(this.state.keyboardOffset, {
+ toValue: 0,
+ duration: e.duration,
+ easing: easingFunction
+ }).start();
+ }
+ render() {
+ const { lines, onLongPress, parseArgs } = this.props;
+ return (
+ <FlatList
+ data={lines}
+ keyboardDismissMode="interactive"
+ renderItem={({ item }) => (
+ <BufferLine
+ line={item}
+ onLongPress={onLongPress}
+ parseArgs={parseArgs}
+ />
+ )}
+ />
+ );
+ }
+}
+
+export default connect((state, { bufferId }) => ({
+ lines: state.lines[bufferId] || []
+}))(Buffer);
+
+const styles = StyleSheet.create({
+ topbar: {
+ height: 20,
+ backgroundColor: "#001"
+ },
+ bottomBox: {
+ height: 40,
+ paddingHorizontal: 10,
+ justifyContent: "center",
+ backgroundColor: "#aaa"
+ },
+ inputBox: {
+ height: 25,
+ paddingHorizontal: 5,
+ justifyContent: "center",
+ borderColor: "gray",
+ backgroundColor: "#fff"
+ }
+});
diff --git a/src/usecase/buffers/ui/BufferLine.js b/src/usecase/buffers/ui/BufferLine.js
@@ -1,14 +0,0 @@
-import React from "react";
-
-import Default from "./themes/Default";
-import Messenger from "./themes/Messenger";
-
-export default class BufferLine extends React.Component {
- render() {
- const { line, onLongPress, parseArgs } = this.props;
-
- return (
- <Default line={line} onLongPress={onLongPress} parseArgs={parseArgs} />
- );
- }
-}
diff --git a/src/usecase/buffers/ui/BufferLine.tsx b/src/usecase/buffers/ui/BufferLine.tsx
@@ -0,0 +1,20 @@
+import React from "react";
+
+import Default from "./themes/Default";
+import Messenger from "./themes/Messenger";
+
+interface Props {
+ line: WeechatLine;
+ onLongPress: (any) => any;
+ parseArgs: any;
+}
+
+export default class BufferLine extends React.Component<Props> {
+ render() {
+ const { line, onLongPress, parseArgs } = this.props;
+
+ return (
+ <Default line={line} onLongPress={onLongPress} parseArgs={parseArgs} />
+ );
+ }
+}
diff --git a/src/usecase/buffers/ui/BufferList.tsx b/src/usecase/buffers/ui/BufferList.tsx
@@ -61,7 +61,7 @@ export default class BufferList extends React.Component<Props> {
<FlatList
style={styles.container}
data={buffers}
- keyExtractor={buffer => buffer.pointers[0]}
+ keyExtractor={buffer => buffer.id}
renderItem={({ item }) => (
<BufferListItem
buffer={item}
diff --git a/src/usecase/buffers/ui/BufferView.js b/src/usecase/buffers/ui/BufferView.js
@@ -66,7 +66,7 @@ const formatUrl = (type, text) => {
const easingFunction = Easing.bezier(0.55, 0.085, 0.68, 0.53);
//const easingFunction = AppleEasing.easeIn;
-class BufferView extends React.Component {
+export default class BufferView extends React.Component {
state = {
keyboardOffset: new Animated.Value(0),
inputWidth: new Animated.Value(350)
@@ -119,17 +119,19 @@ class BufferView extends React.Component {
);
}
handleOnPress(type, text) {
- console.log(type, text);
- if (type === "channel") {
- this.props.dispatch(changeCurrentBuffer(text));
- } else {
- LinkingIOS.openURL(formatUrl(type, text));
- }
+ // console.log(type, text);
+ // if (type === "channel") {
+ // this.props.dispatch(changeCurrentBuffer(text));
+ // } else {
+ // LinkingIOS.openURL(formatUrl(type, text));
+ // }
}
render() {
- const { buffer } = this.props;
+ const { bufferId } = this.props;
+
+ console.log({ bufferId });
- if (!buffer) {
+ if (!bufferId) {
return <View style={styles.container} />;
}
@@ -138,7 +140,7 @@ class BufferView extends React.Component {
style={[styles.container, { marginBottom: this.state.keyboardOffset }]}
>
<Buffer
- buffer={buffer}
+ bufferId={bufferId}
onLongPress={line => null}
parseArgs={getParseArgs(this.handleOnPress, this.handleOnLongPress)}
/>
@@ -156,10 +158,6 @@ class BufferView extends React.Component {
}
}
-export default connect((state, props) => ({
- buffer: state.buffers[props.bufferName]
-}))(BufferView);
-
const light = false;
const styles = StyleSheet.create({
diff --git a/src/usecase/buffers/ui/themes/Default.js b/src/usecase/buffers/ui/themes/Default.js
@@ -1,97 +0,0 @@
-import React from "react";
-import { StyleSheet, Text, TouchableHighlight, View } from "react-native";
-
-import ParsedText from "react-native-parsed-text";
-
-import { hashNickToColor } from "../../../../lib/helpers/colorizer";
-
-const highlightedViewStyles = line => {
- if (line.highlight) {
- return {
- backgroundColor: "#FFCF7F"
- };
- } else {
- return null;
- }
-};
-
-const getHighlightedTextStyles = line => {
- if (line.highlight) {
- return {
- color: "#000"
- };
- } else {
- return null;
- }
-};
-
-export default class BufferLine extends React.Component {
- render() {
- const { line, onLongPress, parseArgs } = this.props;
- return (
- <TouchableHighlight onLongPress={() => onLongPress(line)}>
- <View style={[styles.container, highlightedViewStyles(line)]}>
- <View style={styles.metaContainer}>
- <View style={styles.userContainer}>
- <Text
- style={[
- styles.text,
- styles.meta,
- { color: hashNickToColor(line.nick) },
- getHighlightedTextStyles(line)
- ]}
- >
- {line.nick}
- </Text>
- </View>
- <Text
- style={[styles.text, styles.meta, getHighlightedTextStyles(line)]}
- >
- {line.time}
- </Text>
- </View>
- <View style={[styles.messageContainer, highlightedViewStyles(line)]}>
- <ParsedText
- style={[
- styles.text,
- { color: hashNickToColor(line.nick) },
- getHighlightedTextStyles(line)
- ]}
- parse={parseArgs}
- >
- {line.message}
- </ParsedText>
- </View>
- </View>
- </TouchableHighlight>
- );
- }
-}
-
-const styles = StyleSheet.create({
- container: {
- backgroundColor: "#222",
- paddingTop: 4,
- paddingBottom: 8,
- paddingHorizontal: 7
- },
- metaContainer: {
- flexDirection: "row",
- paddingBottom: 2
- },
- userContainer: {
- flex: 1
- },
- messageContainer: {
- flex: 1,
- paddingHorizontal: 5
- },
- text: {
- fontFamily: "Menlo",
- color: "#eee",
- fontSize: 12
- },
- meta: {
- fontSize: 10
- }
-});
diff --git a/src/usecase/buffers/ui/themes/Default.tsx b/src/usecase/buffers/ui/themes/Default.tsx
@@ -0,0 +1,103 @@
+import React from "react";
+import { StyleSheet, Text, TouchableHighlight, View } from "react-native";
+
+import ParsedText from "react-native-parsed-text";
+
+import { hashNickToColor } from "../../../../lib/helpers/colorizer";
+
+const highlightedViewStyles = line => {
+ if (line.highlight) {
+ return {
+ backgroundColor: "#FFCF7F"
+ };
+ } else {
+ return null;
+ }
+};
+
+const getHighlightedTextStyles = line => {
+ if (line.highlight) {
+ return {
+ color: "#000"
+ };
+ } else {
+ return null;
+ }
+};
+
+interface Props {
+ line: WeechatLine;
+ onLongPress: (any) => any;
+ parseArgs: any;
+}
+
+export default class BufferLine extends React.Component<Props> {
+ render() {
+ const { line, onLongPress, parseArgs } = this.props;
+ return (
+ <TouchableHighlight onLongPress={() => onLongPress(line)}>
+ <View style={[styles.container, highlightedViewStyles(line)]}>
+ <View style={styles.metaContainer}>
+ <View style={styles.userContainer}>
+ <Text
+ style={[
+ styles.text,
+ styles.meta,
+ { color: hashNickToColor(line.prefix) },
+ getHighlightedTextStyles(line)
+ ]}
+ >
+ {line.prefix}
+ </Text>
+ </View>
+ <Text
+ style={[styles.text, styles.meta, getHighlightedTextStyles(line)]}
+ >
+ {String(line.date_printed)}
+ </Text>
+ </View>
+ <View style={[styles.messageContainer, highlightedViewStyles(line)]}>
+ <ParsedText
+ style={[
+ styles.text,
+ { color: hashNickToColor(line.prefix) },
+ getHighlightedTextStyles(line)
+ ]}
+ parse={parseArgs}
+ >
+ {line.message}
+ </ParsedText>
+ </View>
+ </View>
+ </TouchableHighlight>
+ );
+ }
+}
+
+const styles = StyleSheet.create({
+ container: {
+ backgroundColor: "#222",
+ paddingTop: 4,
+ paddingBottom: 8,
+ paddingHorizontal: 7
+ },
+ metaContainer: {
+ flexDirection: "row",
+ paddingBottom: 2
+ },
+ userContainer: {
+ flex: 1
+ },
+ messageContainer: {
+ flex: 1,
+ paddingHorizontal: 5
+ },
+ text: {
+ fontFamily: "Menlo",
+ color: "#eee",
+ fontSize: 12
+ },
+ meta: {
+ fontSize: 10
+ }
+});