diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43de8c20..9de8e25d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ Release date: TBD
- Suppressed verbose error which is related to certificates
- Clear cache on desktop app update: The application cache will be purged whenever the desktop app version changes
- Added CTRL+SHIFT+MINUS as a shortcut for zooming out
+ - Show URL when the mouse cursor is hovering over links
#### Windows
- Copying a links address and pasting it inside the app now works
diff --git a/src/browser/components/HoveringURL.jsx b/src/browser/components/HoveringURL.jsx
new file mode 100644
index 00000000..65bb3d67
--- /dev/null
+++ b/src/browser/components/HoveringURL.jsx
@@ -0,0 +1,18 @@
+const React = require('react');
+
+class HoveringURL extends React.Component {
+ render() {
+ return (
+
+ {this.props.targetURL}
+
+ );
+ }
+}
+
+HoveringURL.propTypes = {
+ style: React.PropTypes.object,
+ targetURL: React.PropTypes.string
+};
+
+module.exports = HoveringURL;
diff --git a/src/browser/components/MainPage.jsx b/src/browser/components/MainPage.jsx
index 059a69ad..cd58cad9 100644
--- a/src/browser/components/MainPage.jsx
+++ b/src/browser/components/MainPage.jsx
@@ -1,4 +1,5 @@
const React = require('react');
+const ReactCSSTransitionGroup = require('react-addons-css-transition-group');
const {Grid, Row} = require('react-bootstrap');
const {ipcRenderer, remote} = require('electron');
@@ -7,6 +8,29 @@ const url = require('url');
const LoginModal = require('./LoginModal.jsx');
const MattermostView = require('./MattermostView.jsx');
const TabBar = require('./TabBar.jsx');
+const HoveringURL = require('./HoveringURL.jsx');
+
+// Todo: Need to consider better way to apply styles
+const styles = {
+ hoveringURL: {
+ color: 'gray',
+ backgroundColor: 'whitesmoke',
+ maxWidth: '95%',
+ whiteSpace: 'nowrap',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ position: 'absolute',
+ bottom: 0,
+ paddingLeft: 4,
+ paddingRight: 16,
+ paddingTop: 2,
+ paddingBottom: 2,
+ borderTopRightRadius: 4,
+ borderTop: 'solid thin lightgray',
+ borderRight: 'solid thin lightgray',
+ pointerEvents: 'none'
+ }
+};
const MainPage = React.createClass({
propTypes: {
@@ -22,7 +46,8 @@ const MainPage = React.createClass({
mentionCounts: new Array(this.props.teams.length),
unreadAtActive: new Array(this.props.teams.length),
mentionAtActiveCounts: new Array(this.props.teams.length),
- loginQueue: []
+ loginQueue: [],
+ targetURL: ''
};
},
componentDidMount() {
@@ -201,6 +226,17 @@ const MainPage = React.createClass({
loginQueue.shift();
this.setState({loginQueue});
},
+ handleTargetURLChange(targetURL) {
+ clearTimeout(this.targetURLDisappearTimeout);
+ if (targetURL === '') {
+ // set delay to avoid momentary disappearance when hovering over multiple links
+ this.targetURLDisappearTimeout = setTimeout(() => {
+ this.setState({targetURL: ''});
+ }, 500);
+ } else {
+ this.setState({targetURL});
+ }
+ },
render() {
var self = this;
@@ -239,6 +275,7 @@ const MainPage = React.createClass({
src={team.url}
name={team.name}
disablewebsecurity={this.props.disablewebsecurity}
+ onTargetURLChange={self.handleTargetURLChange}
onUnreadCountChange={handleUnreadCountChange}
onNotificationClick={handleNotificationClick}
ref={id}
@@ -273,6 +310,19 @@ const MainPage = React.createClass({
{ tabsRow }
{ viewsRow }
+
+ { (this.state.targetURL === '') ?
+ null :
+ }
+
);
}
diff --git a/src/browser/components/MattermostView.jsx b/src/browser/components/MattermostView.jsx
index 7a7aec86..59243a6d 100644
--- a/src/browser/components/MattermostView.jsx
+++ b/src/browser/components/MattermostView.jsx
@@ -13,6 +13,7 @@ const MattermostView = React.createClass({
disablewebsecurity: React.PropTypes.bool,
name: React.PropTypes.string,
id: React.PropTypes.string,
+ onTargetURLChange: React.PropTypes.func,
onUnreadCountChange: React.PropTypes.func,
src: React.PropTypes.string,
style: React.PropTypes.object
@@ -108,6 +109,12 @@ const MattermostView = React.createClass({
});
});
+ webview.addEventListener('update-target-url', (event) => {
+ if (self.props.onTargetURLChange) {
+ self.props.onTargetURLChange(event.url);
+ }
+ });
+
webview.addEventListener('ipc-message', (event) => {
switch (event.channel) {
case 'onUnreadCountChange':
diff --git a/src/browser/css/index.css b/src/browser/css/index.css
new file mode 100644
index 00000000..b0c13b5b
--- /dev/null
+++ b/src/browser/css/index.css
@@ -0,0 +1,18 @@
+
+.hovering-enter {
+ opacity: 0.01;
+}
+
+.hovering-enter.hovering-enter-active {
+ opacity: 1;
+ transition: opacity 300ms ease-in-out;
+}
+
+.hovering-leave {
+ opacity: 1;
+}
+
+.hovering-leave.hovering-leave-active {
+ opacity: 0.01;
+ transition: opacity 500ms ease-in-out;
+}
diff --git a/src/browser/index.html b/src/browser/index.html
index 61900980..99cb3b8f 100644
--- a/src/browser/index.html
+++ b/src/browser/index.html
@@ -4,6 +4,7 @@
+
diff --git a/src/package.json b/src/package.json
index 33521b60..2e175f16 100644
--- a/src/package.json
+++ b/src/package.json
@@ -21,6 +21,7 @@
"electron-squirrel-startup": "^1.0.0",
"os-locale": "^1.4.0",
"react": "^15.3.0",
+ "react-addons-css-transition-group": "^15.3.0",
"react-bootstrap": "~0.30.6",
"react-dom": "^15.3.0",
"yargs": "^3.32.0"