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
|
||||
- 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
|
||||
|
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 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 }
|
||||
</Grid>
|
||||
<ReactCSSTransitionGroup
|
||||
transitionName='hovering'
|
||||
transitionEnterTimeout={300}
|
||||
transitionLeaveTimeout={500}
|
||||
>
|
||||
{ (this.state.targetURL === '') ?
|
||||
null :
|
||||
<HoveringURL
|
||||
key='hoveringURL'
|
||||
style={styles.hoveringURL}
|
||||
targetURL={this.state.targetURL}
|
||||
/> }
|
||||
</ReactCSSTransitionGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -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':
|
||||
|
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>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="modules/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@@ -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"
|
||||
|
Reference in New Issue
Block a user