Skip to content

Commit

Permalink
Extract TweetCell into a component
Browse files Browse the repository at this point in the history
  • Loading branch information
YoruNoHikage committed Dec 27, 2016
1 parent 388082a commit 9eeb698
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 151 deletions.
2 changes: 1 addition & 1 deletion chrome/Echofon/content/tweetbox.xml
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@
if (!this.containerWidth) {
this.containerWidth = window.innerWidth - 16;
}
this.querySelector('.echofon-status-message:first-child').style.width = (this.containerWidth-this.padding) + "px";
this.querySelector('.echofon-status-body').style.width = (this.containerWidth-this.padding) + "px";

if (this.pb) {
var target = this;
Expand Down
147 changes: 5 additions & 142 deletions chrome/Echofon/content/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
import { createElement as e } from 'react';
import ReactDOM from 'react-dom';

import AnchorText from '../../../src/components/AnchorText/index.jsx';
import RichText from '../../../src/components/RichText/index.jsx';
import StatusTagLine from '../../../src/components/StatusTagLine/index.jsx';
import AnchorText from '../../../src/components/AnchorText';
import TweetCell from '../../../src/components/TweetCell';

Components.utils.import("resource://echofon/PhotoBackend.jsm");

Expand Down Expand Up @@ -111,146 +110,10 @@ var EchofonCommon = {
const id = "echofon-status-" + tweet.type + "-" + tweet.id;
if (document.getElementById(id)) return null;

var elem = document.createElement("echofon-status");
elem.id = id;
elem.setAttribute("messageId", tweet.id);
elem.setAttribute("type", tweet.type);
if (tweet.retweeted_status_id) {
elem.createdAt = new Date(tweet.retweeted_at).getTime();
}
else {
elem.createdAt = new Date(tweet.created_at).getTime();
}
elem.unread = tweet.unread;
elem.tweet = tweet;
elem.uid = uid;
elem.user = tweet.user;
elem.highlighted = highlighted;
elem.appMode = EchofonCommon.pref().getCharPref("applicationMode");

try{
elem.setAttribute("messageId", elem.tweet.id);
var fontSize = EchofonCommon.fontSize();
if (!elem.getAttribute("user-timeline")) {
elem.setAttribute("mode", elem.appMode);
}
elem.style.fontSize = fontSize + "px";
elem.style.fontFamily = EchofonCommon.pref().getCharPref("fontFace");


var msg = elem.tweet;
var user = elem.user;

elem.setAttribute("profile_image_url", user.profile_image_url);

elem.setAttribute("href", EchofonCommon.userViewURL(user.screen_name));

elem.setAttribute("replyButtonTooltip", EchofonCommon.getFormattedString("ReplyTo", [elem.user.screen_name]));
elem.setAttribute("screen_name", user.screen_name);
if (user.id == elem.uid) {
elem.setAttribute('is_own_tweet', true);
}

elem.setAttribute("name", user.name);
const container = document.createElement('box');
ReactDOM.render(<TweetCell uid={uid} id={id} tweet={tweet} highlighted={highlighted} />, container);

elem.setAttribute("requestFavorite", false);
elem.setAttribute("favorited", msg.favorited);
elem.setAttribute("favoriteButtonTooltip", EchofonCommon.getString(msg.favorited ? "UnfavoriteTweet" : "FavoriteTweet"));
elem.setAttribute("isFavorited", (msg.favorited) ? "block" : "none");
elem.setAttribute("text", msg.text);
elem.setAttribute("protected", user.protected ? 1 : 0);
if (msg.has_mention && msg.type == 'home') {
elem.setAttribute("highlighted", true);
}
if (msg.retweeted_status_id > 0 && msg.retweeter_user_id == uid) {
elem.setAttribute("is_own_retweet", true);
}

const style = this.pref().getIntPref("displayStyle");
let nameNode = null;
if (style === 0) {
const anchor = e(AnchorText, {
link: this.userViewURL(user.screen_name),
text: user.name,
type: 'username',
screen_name: user.screen_name,
additionalClasses: 'echofon-status-user'
}, user.name);

const screenName = e(AnchorText, {
link: this.userViewURL(user.screen_name),
text: `@${user.screen_name}`,
type: 'username',
className: 'echofon-status-additional-screen-name',
screen_name: user.screen_name,
style: msg.type != 'user-timeline' ? {
fontSize: (fontSize - 1) + 'px',
} : undefined,
}, `@${user.screen_name}`);

nameNode = e('description', {
className: 'echofon-status-body',
}, anchor, screenName);
}

const textnode = e(RichText, {
className: 'echofon-status-body',
uid,
msg,
user,
parent_elem: elem,
});

const info = e(StatusTagLine, { msg, fontSize, appMode: elem.appMode, user });

let rt = null;
if (msg.retweeted_status_id > 0) {
const rt_icon = e('image', {
className: 'echofon-retweet-icon'
});

const nameLabel = msg.retweeter_user_id == uid ? EchofonCommon.getString("you") : msg.retweeter_screen_name;
const linkToUser = e(AnchorText, {
link: EchofonCommon.userViewURL(msg.retweeter_screen_name),
text: nameLabel,
screen_name: msg.retweeter_screen_name,
type: 'username',
}, nameLabel);

const rtby = EchofonCommon.formatText({type: 'retweetedBy', children: linkToUser});

rt = e('echofon-status-retweet-status', {
anonid: 'retweet',
style: {
fontSize: (fontSize - 1) + 'px',
},
}, rt_icon, ...rtby);
}

const container = document.createElement('box');
ReactDOM.render(
e('xul:vbox', {
className: 'echofon-status-message-container',
ref: (node) => node.setAttribute('flex', '1')
},
e('xul:description', { className: 'echofon-status-message' }, nameNode, textnode),
e('xul:hbox', {
className: 'echofon-status-info',
ref: (node) => {
node.setAttribute('crop', 'right');
node.setAttribute('align', 'left');
},
}, info),
e('xul:hbox', { className: 'echofon-status-info' }, rt),
),
container
);
elem.appendChild(container.firstChild);
}catch (e) {
dump(e.message+":"+e.fileName+":"+e.lineNumber+"\n");
}

return elem;
return container.firstChild;
},

findStatusElement: function(tweet_id) {
Expand Down
11 changes: 4 additions & 7 deletions src/components/RichText/index.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React from 'react';

// this should be elsewhere
const DISPLAY_STYLE_BOTH = 0;
const DISPLAY_STYLE_NAME = 1;
const DISPLAY_STYLE_SCREEN_NAME = 2;
import * as DisplayStyles from '../../constants/display-style';

class RichText extends React.Component {
componentDidMount() {
Expand All @@ -21,7 +18,7 @@ class RichText extends React.Component {
const { user } = this.props;
const style = EchofonCommon.pref().getIntPref("displayStyle");

const displayName = (style === DISPLAY_STYLE_NAME) ? user.name : user.screen_name;
const displayName = (style === DisplayStyles.NAME) ? user.name : user.screen_name;

return (
<AnchorText
Expand All @@ -45,8 +42,8 @@ class RichText extends React.Component {

return (
<description className="echofon-status-body" ref="node">
{style !== DISPLAY_STYLE_BOTH && this.renderNameHeader()}
{style !== DISPLAY_STYLE_BOTH && ' '}
{style !== DisplayStyles.BOTH && this.renderNameHeader()}
{style !== DisplayStyles.BOTH && ' '}
{/* appended when component mount, this will change */}
</description>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/StatusTagLine/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import AnchorText from '../AnchorText/index.jsx';
import AnchorText from '../AnchorText';

const StatusTagLine = ({ msg, fontSize, appMode, user }) => {
let infoChildren = [];
Expand Down
146 changes: 146 additions & 0 deletions src/components/TweetCell/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import React from 'react';

import * as DisplayStyles from '../../constants/display-style';

import AnchorText from '../AnchorText';
import RichText from '../RichText';
import StatusTagLine from '../StatusTagLine';

class TweetCell extends React.Component {
constructor() {
super();

this.state = {};
}

componentDidMount() {
const { uid, tweet, highlighted } = this.props;

this.node.createdAt = new Date(tweet.retweeted_status_id || tweet.created_at).getTime();
this.node.unread = tweet.unread;
this.node.tweet = tweet;
this.node.uid = uid;
this.node.user = tweet.user;
this.node.highlighted = highlighted;
this.node.appMode = EchofonCommon.pref().getCharPref("applicationMode");

this.setState({node: this.node});
}

render() {
const { uid, id, tweet, highlighted } = this.props;
const appMode = EchofonCommon.pref().getCharPref("applicationMode");
const fontSize = EchofonCommon.fontSize();
const msg = tweet;
const { user } = tweet;
const attrs = {
id,
messageId: tweet.id,
type: tweet.type,
highlighted,
ref: (node) => {
if (node) {
if (!node.getAttribute("user-timeline")) {
node.setAttribute("mode", appMode);
}
this.node = node;
}
},
style: {
fontSize: fontSize + 'px',
fontFamily: EchofonCommon.pref().getCharPref("fontFace"),
},
profile_image_url: user.profile_image_url,
href: EchofonCommon.userViewURL(user.screen_name),
replyButtonTooltip: EchofonCommon.getFormattedString("ReplyTo", [user.screen_name]),
screen_name: user.screen_name,
is_own_tweet: user.id === uid,
name: user.name,
requestFavorite: false,
favorited: msg.favorited,
favoriteButtonTooltip: EchofonCommon.getString(msg.favorited ? "UnfavoriteTweet" : "FavoriteTweet"),
isFavorited: (msg.favorited) ? 'block' : 'none',
text: msg.text,
protected: user.protected ? 1 : 0,
highlighted: msg.has_mention && msg.type == 'home',
is_own_retweet: msg.retweeted_status_id > 0 && msg.retweeter_user_id == uid,
};

const style = EchofonCommon.pref().getIntPref("displayStyle");

const XULVbox = 'xul:vbox';
const XULHbox = 'xul:hbox';
const XULDescription = 'xul:description';

const namesProps = {
link: EchofonCommon.userViewURL(user.screen_name),
text: user.name,
type: 'username',
screen_name: user.screen_name,
};

return (
<echofon-status {...attrs}>
<XULVbox className="echofon-status-message-container" ref={(node) => node && node.setAttribute('flex', '1')}>
<XULDescription className="echofon-status-message">

{style === DisplayStyles.BOTH && (
<description className="echofon-status-body">
<AnchorText additionalClasses="echofon-status-user" {...namesProps}>
{user.name}
</AnchorText>
<AnchorText
style={msg.type != 'user-timeline' ? {
fontSize: (fontSize - 1) + 'px',
} : undefined}
className="echofon-status-additional-screen-name"
{...namesProps}
>
{`@${user.screen_name}`}
</AnchorText>
</description>
)}

{this.state.node && <RichText
className="echofon-status-body"
uid={uid}
msg={msg}
user={user}
parent_elem={this.state.node}
/>}

</XULDescription>
<XULHbox className="echofon-status-info" ref={(node) => {
if (node) {
node.setAttribute('crop', 'right');
node.setAttribute('align', 'left');
}
}}>
<StatusTagLine msg={msg} fontSize={fontSize} appMode={appMode} user={user} />
</XULHbox>
<XULHbox className="echofon-status-info">
{msg.retweeted_status_id > 0 && (
<echofon-status-retweet-status anonid="retweet" style={{fontSize: (fontSize - 1) + 'px'}}>
<image className="echofon-retweet-icon" />
{
EchofonCommon.formatText({type: 'retweetedBy', children: (
<AnchorText
link={EchofonCommon.userViewURL(msg.retweeter_screen_name)}
text={msg.retweeter_user_id == uid ? EchofonCommon.getString("you") : msg.retweeter_screen_name}
screen_name={msg.retweeter_screen_name}
type="username"
>
{msg.retweeter_user_id == uid ? EchofonCommon.getString("you") : msg.retweeter_screen_name}
</AnchorText>
)})
}
</echofon-status-retweet-status>
)}
</XULHbox>
</XULVbox>
</echofon-status>
);
}
}

export default TweetCell;
3 changes: 3 additions & 0 deletions src/constants/display-style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const BOTH = 0;
export const NAME = 1;
export const SCREEN_NAME = 2;
3 changes: 3 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ module.exports = {
},
],
},
resolve: {
extensions: [".js", ".jsx", ".json"],
},
externals: {
react: 'React',
'react-dom': 'ReactDOM',
Expand Down

0 comments on commit 9eeb698

Please sign in to comment.