Merge pull request #372 from yuya-oc/hovering-links
Show URL when hovering over links
This commit is contained in:
@@ -13,6 +13,7 @@ Release date: TBD
|
|||||||
- Suppressed verbose error which is related to certificates
|
- 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
|
- 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
|
- Added CTRL+SHIFT+MINUS as a shortcut for zooming out
|
||||||
|
- Show URL when the mouse cursor is hovering over links
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
- Copying a links address and pasting it inside the app now works
|
- Copying a links address and pasting it inside the app now works
|
||||||
|
18
src/browser/components/HoveringURL.jsx
Normal file
18
src/browser/components/HoveringURL.jsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const React = require('react');
|
||||||
|
|
||||||
|
class HoveringURL extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={this.props.style}>
|
||||||
|
{this.props.targetURL}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoveringURL.propTypes = {
|
||||||
|
style: React.PropTypes.object,
|
||||||
|
targetURL: React.PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = HoveringURL;
|
@@ -1,4 +1,5 @@
|
|||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
const ReactCSSTransitionGroup = require('react-addons-css-transition-group');
|
||||||
const {Grid, Row} = require('react-bootstrap');
|
const {Grid, Row} = require('react-bootstrap');
|
||||||
|
|
||||||
const {ipcRenderer, remote} = require('electron');
|
const {ipcRenderer, remote} = require('electron');
|
||||||
@@ -7,6 +8,29 @@ const url = require('url');
|
|||||||
const LoginModal = require('./LoginModal.jsx');
|
const LoginModal = require('./LoginModal.jsx');
|
||||||
const MattermostView = require('./MattermostView.jsx');
|
const MattermostView = require('./MattermostView.jsx');
|
||||||
const TabBar = require('./TabBar.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({
|
const MainPage = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@@ -22,7 +46,8 @@ const MainPage = React.createClass({
|
|||||||
mentionCounts: new Array(this.props.teams.length),
|
mentionCounts: new Array(this.props.teams.length),
|
||||||
unreadAtActive: new Array(this.props.teams.length),
|
unreadAtActive: new Array(this.props.teams.length),
|
||||||
mentionAtActiveCounts: new Array(this.props.teams.length),
|
mentionAtActiveCounts: new Array(this.props.teams.length),
|
||||||
loginQueue: []
|
loginQueue: [],
|
||||||
|
targetURL: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -201,6 +226,17 @@ const MainPage = React.createClass({
|
|||||||
loginQueue.shift();
|
loginQueue.shift();
|
||||||
this.setState({loginQueue});
|
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() {
|
render() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@@ -239,6 +275,7 @@ const MainPage = React.createClass({
|
|||||||
src={team.url}
|
src={team.url}
|
||||||
name={team.name}
|
name={team.name}
|
||||||
disablewebsecurity={this.props.disablewebsecurity}
|
disablewebsecurity={this.props.disablewebsecurity}
|
||||||
|
onTargetURLChange={self.handleTargetURLChange}
|
||||||
onUnreadCountChange={handleUnreadCountChange}
|
onUnreadCountChange={handleUnreadCountChange}
|
||||||
onNotificationClick={handleNotificationClick}
|
onNotificationClick={handleNotificationClick}
|
||||||
ref={id}
|
ref={id}
|
||||||
@@ -273,6 +310,19 @@ const MainPage = React.createClass({
|
|||||||
{ tabsRow }
|
{ tabsRow }
|
||||||
{ viewsRow }
|
{ viewsRow }
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<ReactCSSTransitionGroup
|
||||||
|
transitionName='hovering'
|
||||||
|
transitionEnterTimeout={300}
|
||||||
|
transitionLeaveTimeout={500}
|
||||||
|
>
|
||||||
|
{ (this.state.targetURL === '') ?
|
||||||
|
null :
|
||||||
|
<HoveringURL
|
||||||
|
key='hoveringURL'
|
||||||
|
style={styles.hoveringURL}
|
||||||
|
targetURL={this.state.targetURL}
|
||||||
|
/> }
|
||||||
|
</ReactCSSTransitionGroup>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ const MattermostView = React.createClass({
|
|||||||
disablewebsecurity: React.PropTypes.bool,
|
disablewebsecurity: React.PropTypes.bool,
|
||||||
name: React.PropTypes.string,
|
name: React.PropTypes.string,
|
||||||
id: React.PropTypes.string,
|
id: React.PropTypes.string,
|
||||||
|
onTargetURLChange: React.PropTypes.func,
|
||||||
onUnreadCountChange: React.PropTypes.func,
|
onUnreadCountChange: React.PropTypes.func,
|
||||||
src: React.PropTypes.string,
|
src: React.PropTypes.string,
|
||||||
style: React.PropTypes.object
|
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) => {
|
webview.addEventListener('ipc-message', (event) => {
|
||||||
switch (event.channel) {
|
switch (event.channel) {
|
||||||
case 'onUnreadCountChange':
|
case 'onUnreadCountChange':
|
||||||
|
18
src/browser/css/index.css
Normal file
18
src/browser/css/index.css
Normal file
@@ -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;
|
||||||
|
}
|
@@ -4,6 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="modules/bootstrap/css/bootstrap.min.css">
|
<link rel="stylesheet" href="modules/bootstrap/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="css/index.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"os-locale": "^1.4.0",
|
"os-locale": "^1.4.0",
|
||||||
"react": "^15.3.0",
|
"react": "^15.3.0",
|
||||||
|
"react-addons-css-transition-group": "^15.3.0",
|
||||||
"react-bootstrap": "~0.30.6",
|
"react-bootstrap": "~0.30.6",
|
||||||
"react-dom": "^15.3.0",
|
"react-dom": "^15.3.0",
|
||||||
"yargs": "^3.32.0"
|
"yargs": "^3.32.0"
|
||||||
|
Reference in New Issue
Block a user