Merge pull request #141 from lbryio/hide-unavailable-files
Add setting to hide unavailable content
This commit is contained in:
commit
f3c951187d
15 changed files with 190 additions and 108 deletions
|
@ -50,31 +50,6 @@ export let BusyMessage = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var toolTipStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
zIndex: '1',
|
|
||||||
top: '100%',
|
|
||||||
left: '-120px',
|
|
||||||
width: '260px',
|
|
||||||
padding: '15px',
|
|
||||||
border: '1px solid #aaa',
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
fontSize: '14px',
|
|
||||||
};
|
|
||||||
export let ToolTip = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
open: React.PropTypes.bool.isRequired,
|
|
||||||
onMouseOut: React.PropTypes.func
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
return (
|
|
||||||
<div className={this.props.open ? '' : 'hidden'} style={toolTipStyle} onMouseOut={this.props.onMouseOut}>
|
|
||||||
{this.props.children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var creditAmountStyle = {
|
var creditAmountStyle = {
|
||||||
color: '#216C2A',
|
color: '#216C2A',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {Link} from '../component/link.js';
|
||||||
import {Icon} from '../component/common.js';
|
import {Icon} from '../component/common.js';
|
||||||
import Modal from './modal.js';
|
import Modal from './modal.js';
|
||||||
import FormField from './form.js';
|
import FormField from './form.js';
|
||||||
|
import {ToolTip} from '../component/tooltip.js';
|
||||||
import {DropDownMenu, DropDownMenuItem} from './menu.js';
|
import {DropDownMenu, DropDownMenuItem} from './menu.js';
|
||||||
|
|
||||||
let WatchLink = React.createClass({
|
let WatchLink = React.createClass({
|
||||||
|
@ -50,18 +51,14 @@ let WatchLink = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export let FileActions = React.createClass({
|
let FileActionsRow = React.createClass({
|
||||||
_isMounted: false,
|
_isMounted: false,
|
||||||
_fileInfoSubscribeId: null,
|
_fileInfoSubscribeId: null,
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
streamName: React.PropTypes.string,
|
streamName: React.PropTypes.string,
|
||||||
sdHash: React.PropTypes.string.isRequired,
|
sdHash: React.PropTypes.string.isRequired,
|
||||||
metadata: React.PropTypes.object,
|
metadata: React.PropTypes.object
|
||||||
path: React.PropTypes.string,
|
|
||||||
hidden: React.PropTypes.bool,
|
|
||||||
deleteChecked: React.PropTypes.bool,
|
|
||||||
onRemove: React.PropTypes.func,
|
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
|
@ -70,7 +67,7 @@ export let FileActions = React.createClass({
|
||||||
menuOpen: false,
|
menuOpen: false,
|
||||||
deleteChecked: false,
|
deleteChecked: false,
|
||||||
attemptingDownload: false,
|
attemptingDownload: false,
|
||||||
attemptingRemove: false,
|
attemptingRemove: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFileInfoUpdate: function(fileInfo) {
|
onFileInfoUpdate: function(fileInfo) {
|
||||||
|
@ -166,10 +163,11 @@ export let FileActions = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.state.fileInfo === null)
|
if (this.state.fileInfo === null)
|
||||||
{
|
{
|
||||||
return <section className="file-actions--stub"></section>;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
|
const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
|
||||||
showMenu = !!this.state.fileInfo;
|
showMenu = !!this.state.fileInfo;
|
||||||
|
|
||||||
let linkBlock;
|
let linkBlock;
|
||||||
if (this.state.fileInfo === false && !this.state.attemptingDownload) {
|
if (this.state.fileInfo === false && !this.state.attemptingDownload) {
|
||||||
|
@ -180,20 +178,21 @@ export let FileActions = React.createClass({
|
||||||
label = this.state.fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
|
label = this.state.fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
|
||||||
labelWithIcon = <span className="button__content"><Icon icon="icon-download" />{label}</span>;
|
labelWithIcon = <span className="button__content"><Icon icon="icon-download" />{label}</span>;
|
||||||
|
|
||||||
linkBlock =
|
linkBlock = (
|
||||||
<div className="faux-button-block file-actions__download-status-bar">
|
<div className="faux-button-block file-actions__download-status-bar">
|
||||||
<div className="faux-button-block file-actions__download-status-bar-overlay" style={{ width: progress + '%' }}>{labelWithIcon}</div>
|
<div className="faux-button-block file-actions__download-status-bar-overlay" style={{ width: progress + '%' }}>{labelWithIcon}</div>
|
||||||
{labelWithIcon}
|
{labelWithIcon}
|
||||||
</div>;
|
</div>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
linkBlock = <Link button="text" label="Open" icon="icon-folder-open" onClick={this.onOpenClick} />;
|
linkBlock = <Link button="text" label="Open" icon="icon-folder-open" onClick={this.onOpenClick} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="file-actions">
|
<div>
|
||||||
{(this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')) ? <WatchLink streamName={this.props.streamName} /> : null}
|
{(this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')) ? <WatchLink streamName={this.props.streamName} /> : null}
|
||||||
{this.state.fileInfo !== null || this.state.fileInfo.isMine ?
|
{this.state.fileInfo !== null || this.state.fileInfo.isMine ?
|
||||||
<div className="button-container">{linkBlock}</div>
|
<div className="button-container">{linkBlock}</div>
|
||||||
: null}
|
: null}
|
||||||
{ showMenu ?
|
{ showMenu ?
|
||||||
<DropDownMenu>
|
<DropDownMenu>
|
||||||
|
@ -215,7 +214,62 @@ export let FileActions = React.createClass({
|
||||||
|
|
||||||
<label><FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer</label>
|
<label><FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer</label>
|
||||||
</Modal>
|
</Modal>
|
||||||
</section>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export let FileActions = React.createClass({
|
||||||
|
_isMounted: false,
|
||||||
|
_fileInfoSubscribeId: null,
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
streamName: React.PropTypes.string,
|
||||||
|
sdHash: React.PropTypes.string.isRequired,
|
||||||
|
metadata: React.PropTypes.object
|
||||||
|
},
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
available: true,
|
||||||
|
forceShowActions: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onShowFileActionsRowClicked: function() {
|
||||||
|
this.setState({
|
||||||
|
forceShowActions: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
|
this._isMounted = true;
|
||||||
|
lbry.getPeersForBlobHash(this.props.sdHash, (peers) => {
|
||||||
|
if (!this._isMounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
available: peers.length > 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
this._isMounted = false;
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (<section className="file-actions">
|
||||||
|
{
|
||||||
|
this.state.available || this.state.forceShowActions ?
|
||||||
|
<FileActionsRow sdHash={this.props.sdHash} metadata={this.props.metadata} streamName={this.props.streamName} /> :
|
||||||
|
(<div>
|
||||||
|
<div className="button-container empty">This file is not currently available.</div>
|
||||||
|
<div className="button-container">
|
||||||
|
<ToolTip label="Why?"
|
||||||
|
body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment" />
|
||||||
|
</div>
|
||||||
|
<div className="button-container">
|
||||||
|
<Link label="Try Anyway" className="button-text" onClick={this.onShowFileActionsRowClicked} />
|
||||||
|
</div>
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
</section>);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -64,7 +64,8 @@ export let FileTileStream = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
showNsfwHelp: false,
|
showNsfwHelp: false,
|
||||||
isHidden: false
|
isHidden: false,
|
||||||
|
available: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -112,11 +113,10 @@ export let FileTileStream = React.createClass({
|
||||||
|
|
||||||
const metadata = this.props.metadata || {},
|
const metadata = this.props.metadata || {},
|
||||||
obscureNsfw = this.props.obscureNsfw && metadata.nsfw,
|
obscureNsfw = this.props.obscureNsfw && metadata.nsfw,
|
||||||
title = metadata.title ? metadata.title : ('lbry://' + this.props.name);
|
title = metadata.title ? metadata.title : ('lbry://' + this.props.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
<section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
||||||
<div className="row-fluid card-content file-tile__row">
|
<div className={"row-fluid card-content file-tile__row"}>
|
||||||
<div className="span3">
|
<div className="span3">
|
||||||
<a href={'/?show=' + this.props.name}><Thumbnail className="file-tile__thumbnail" src={metadata.thumbnail} alt={'Photo for ' + (title || this.props.name)} /></a>
|
<a href={'/?show=' + this.props.name}><Thumbnail className="file-tile__thumbnail" src={metadata.thumbnail} alt={'Photo for ' + (title || this.props.name)} /></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -157,7 +157,8 @@ export let FileTile = React.createClass({
|
||||||
_isMounted: false,
|
_isMounted: false,
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
name: React.PropTypes.string.isRequired
|
name: React.PropTypes.string.isRequired,
|
||||||
|
available: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -187,6 +188,6 @@ export let FileTile = React.createClass({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <FileTileStream name={this.props.name} sdHash={this.state.sdHash} metadata={this.state.metadata} />;
|
return <FileTileStream sdHash={this.state.sdHash} metadata={this.state.metadata} {... this.props} />;
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Icon, ToolTip} from './common.js';
|
import {Icon} from './common.js';
|
||||||
|
|
||||||
export let Link = React.createClass({
|
export let Link = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -51,54 +51,4 @@ export let Link = React.createClass({
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var linkContainerStyle = {
|
|
||||||
position: 'relative',
|
|
||||||
};
|
|
||||||
|
|
||||||
export let ToolTipLink = React.createClass({
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
showTooltip: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
handleClick: function() {
|
|
||||||
if (this.props.tooltip) {
|
|
||||||
this.setState({
|
|
||||||
showTooltip: !this.state.showTooltip,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.props.onClick) {
|
|
||||||
this.props.onClick();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleTooltipMouseOut: function() {
|
|
||||||
this.setState({
|
|
||||||
showTooltip: false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
var href = this.props.href ? this.props.href : 'javascript:;',
|
|
||||||
icon = this.props.icon ? <Icon icon={this.props.icon} /> : '',
|
|
||||||
className = this.props.className +
|
|
||||||
(this.props.button ? ' button-block button-' + this.props.button : '') +
|
|
||||||
(this.props.hidden ? ' hidden' : '') +
|
|
||||||
(this.props.disabled ? ' disabled' : '');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span style={linkContainerStyle}>
|
|
||||||
<a className={className ? className : 'button-text'} href={href} style={this.props.style ? this.props.style : {}}
|
|
||||||
title={this.props.title} onClick={this.handleClick}>
|
|
||||||
{this.props.icon ? icon : '' }
|
|
||||||
{this.props.label}
|
|
||||||
</a>
|
|
||||||
{(!this.props.tooltip ? null :
|
|
||||||
<ToolTip open={this.state.showTooltip} onMouseOut={this.handleTooltipMouseOut}>
|
|
||||||
{this.props.tooltip}
|
|
||||||
</ToolTip>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
36
js/component/tooltip.js
Normal file
36
js/component/tooltip.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export let ToolTip = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
body: React.PropTypes.string.isRequired,
|
||||||
|
label: React.PropTypes.string.isRequired
|
||||||
|
},
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
showTooltip: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleClick: function() {
|
||||||
|
this.setState({
|
||||||
|
showTooltip: !this.state.showTooltip,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleTooltipMouseOut: function() {
|
||||||
|
this.setState({
|
||||||
|
showTooltip: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<span className={'tooltip ' + (this.props.className || '')}>
|
||||||
|
<a className="tooltip__link" onClick={this.handleClick}>
|
||||||
|
{this.props.label}
|
||||||
|
</a>
|
||||||
|
<div className={'tooltip__body ' + (this.state.showTooltip ? '' : ' hidden')}
|
||||||
|
onMouseOut={this.handleTooltipMouseOut}>
|
||||||
|
{this.props.body}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -10,6 +10,7 @@ var lbry = {
|
||||||
},
|
},
|
||||||
defaultClientSettings: {
|
defaultClientSettings: {
|
||||||
showNsfw: false,
|
showNsfw: false,
|
||||||
|
showUnavailable: true,
|
||||||
debug: false,
|
debug: false,
|
||||||
useCustomLighthouseServers: false,
|
useCustomLighthouseServers: false,
|
||||||
customLighthouseServers: [],
|
customLighthouseServers: [],
|
||||||
|
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
||||||
import lbry from '../lbry.js';
|
import lbry from '../lbry.js';
|
||||||
import lighthouse from '../lighthouse.js';
|
import lighthouse from '../lighthouse.js';
|
||||||
import {FileTile} from '../component/file-tile.js';
|
import {FileTile} from '../component/file-tile.js';
|
||||||
import {Link, ToolTipLink} from '../component/link.js';
|
import {Link} from '../component/link.js';
|
||||||
|
import {ToolTip} from '../component/tooltip.js';
|
||||||
import {BusyMessage} from '../component/common.js';
|
import {BusyMessage} from '../component/common.js';
|
||||||
|
|
||||||
var fetchResultsStyle = {
|
var fetchResultsStyle = {
|
||||||
|
@ -47,7 +48,7 @@ var SearchResults = React.createClass({
|
||||||
if (!seenNames[name]) {
|
if (!seenNames[name]) {
|
||||||
seenNames[name] = name;
|
seenNames[name] = name;
|
||||||
rows.push(
|
rows.push(
|
||||||
<FileTile key={name} name={name} />
|
<FileTile key={name} name={name} sdHash={value.sources.lbry_sd_hash} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -65,6 +66,9 @@ var featuredContentLegendStyle = {
|
||||||
|
|
||||||
var FeaturedContent = React.createClass({
|
var FeaturedContent = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
|
const toolTipText = ('Community Content is a public space where anyone can share content with the ' +
|
||||||
|
'rest of the LBRY community. Bid on the names "one," "two," "three," "four" and ' +
|
||||||
|
'"five" to put your content here!');
|
||||||
return (
|
return (
|
||||||
<div className="row-fluid">
|
<div className="row-fluid">
|
||||||
<div className="span6">
|
<div className="span6">
|
||||||
|
@ -77,8 +81,10 @@ var FeaturedContent = React.createClass({
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="span6">
|
<div className="span6">
|
||||||
<h3>Community Content <ToolTipLink style={featuredContentLegendStyle} label="What's this?"
|
<h3>
|
||||||
tooltip='Community Content is a public space where anyone can share content with the rest of the LBRY community. Bid on the names "one," "two," "three," "four" and "five" to put your content here!' /></h3>
|
Community Content
|
||||||
|
<ToolTip label="What's this?" body={toolTipText} className="tooltip--header"/>
|
||||||
|
</h3>
|
||||||
<FileTile name="one" />
|
<FileTile name="one" />
|
||||||
<FileTile name="two" />
|
<FileTile name="two" />
|
||||||
<FileTile name="three" />
|
<FileTile name="three" />
|
||||||
|
|
|
@ -51,7 +51,8 @@ var SettingsPage = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
settings: null,
|
settings: null,
|
||||||
showNsfw: lbry.getClientSetting('showNsfw')
|
showNsfw: lbry.getClientSetting('showNsfw'),
|
||||||
|
showUnavailable: lbry.getClientSetting('showUnavailable'),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -69,6 +70,9 @@ var SettingsPage = React.createClass({
|
||||||
onShowNsfwChange: function(event) {
|
onShowNsfwChange: function(event) {
|
||||||
lbry.setClientSetting('showNsfw', event.target.checked);
|
lbry.setClientSetting('showNsfw', event.target.checked);
|
||||||
},
|
},
|
||||||
|
onShowUnavailableChange: function(event) {
|
||||||
|
lbry.setClientSetting('showUnavailable', event.target.checked);
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
if (!this.state.daemonSettings) {
|
if (!this.state.daemonSettings) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -114,7 +118,7 @@ var SettingsPage = React.createClass({
|
||||||
<h3>Content</h3>
|
<h3>Content</h3>
|
||||||
<div className="form-row">
|
<div className="form-row">
|
||||||
<label style={settingsCheckBoxOptionStyles}>
|
<label style={settingsCheckBoxOptionStyles}>
|
||||||
<input type="checkbox" onChange={this.onShowNsfwChange} defaultChecked={this.state.showNsfw} /> Show NSFW Content
|
<input type="checkbox" onChange={this.onShowNsfwChange} defaultChecked={this.state.showNsfw} /> Show NSFW content
|
||||||
</label>
|
</label>
|
||||||
<div className="help">
|
<div className="help">
|
||||||
NSFW content may include nudity, intense sexuality, profanity, or other adult content.
|
NSFW content may include nudity, intense sexuality, profanity, or other adult content.
|
||||||
|
@ -122,6 +126,17 @@ var SettingsPage = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section className="card">
|
||||||
|
<h3>Search</h3>
|
||||||
|
<div className="form-row">
|
||||||
|
<div className="help">
|
||||||
|
Would you like search results to include items that are not currently available for download?
|
||||||
|
</div>
|
||||||
|
<label style={settingsCheckBoxOptionStyles}>
|
||||||
|
<input type="checkbox" onChange={this.onShowUnavailableChange} defaultChecked={this.state.showUnavailable} /> Show unavailable content in search results
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<h3>Share Diagnostic Data</h3>
|
<h3>Share Diagnostic Data</h3>
|
||||||
<label style={settingsCheckBoxOptionStyles}>
|
<label style={settingsCheckBoxOptionStyles}>
|
||||||
|
|
|
@ -8,7 +8,7 @@ html
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
font-family: 'Source Sans Pro', sans-serif;
|
font-family: 'Source Sans Pro', sans-serif;
|
||||||
line-height: 1.3333;
|
line-height: $font-line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
$drawer-width: 240px;
|
$drawer-width: 240px;
|
||||||
|
|
|
@ -8,6 +8,7 @@ $color-primary: #155B4A;
|
||||||
$color-light-alt: hsl(hue($color-primary), 15, 85);
|
$color-light-alt: hsl(hue($color-primary), 15, 85);
|
||||||
$color-text-dark: #000;
|
$color-text-dark: #000;
|
||||||
$color-help: rgba(0,0,0,.6);
|
$color-help: rgba(0,0,0,.6);
|
||||||
|
$color-notice: #921010;
|
||||||
$color-canvas: #f5f5f5;
|
$color-canvas: #f5f5f5;
|
||||||
$color-bg: #ffffff;
|
$color-bg: #ffffff;
|
||||||
$color-bg-alt: #D9D9D9;
|
$color-bg-alt: #D9D9D9;
|
||||||
|
@ -15,6 +16,7 @@ $color-money: #216C2A;
|
||||||
$color-meta-light: #505050;
|
$color-meta-light: #505050;
|
||||||
|
|
||||||
$font-size: 16px;
|
$font-size: 16px;
|
||||||
|
$font-line-height: 1.3333;
|
||||||
|
|
||||||
$mobile-width-threshold: 801px;
|
$mobile-width-threshold: 801px;
|
||||||
$max-content-width: 1000px;
|
$max-content-width: 1000px;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@import "global";
|
@import "global";
|
||||||
|
|
||||||
@mixin text-link($color: $color-primary, $hover-opacity: 0.70) {
|
@mixin text-link($color: $color-primary, $hover-opacity: 0.70) {
|
||||||
color: $color;
|
|
||||||
.icon
|
.icon
|
||||||
{
|
{
|
||||||
&:first-child {
|
&:first-child {
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
color: $color;
|
color: $color;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-fixed-width {
|
.icon-fixed-width {
|
||||||
|
@ -200,7 +201,7 @@ input[type="text"], input[type="search"]
|
||||||
}
|
}
|
||||||
.button-text-help
|
.button-text-help
|
||||||
{
|
{
|
||||||
@include text-link(#5b8c80);
|
@include text-link(#aaa);
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,5 @@
|
||||||
@import "component/_file-actions.scss";
|
@import "component/_file-actions.scss";
|
||||||
@import "component/_file-tile.scss";
|
@import "component/_file-tile.scss";
|
||||||
@import "component/_menu.scss";
|
@import "component/_menu.scss";
|
||||||
|
@import "component/_tooltip.scss";
|
||||||
@import "page/_developer.scss";
|
@import "page/_developer.scss";
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
$color-download: #444;
|
$color-download: #444;
|
||||||
|
|
||||||
.file-actions--stub
|
.file-actions
|
||||||
{
|
{
|
||||||
height: $height-button;
|
line-height: $height-button;
|
||||||
|
min-height: $height-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-actions__download-status-bar
|
.file-actions__download-status-bar
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
height: $spacing-vertical * 7;
|
height: $spacing-vertical * 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-tile__row--unavailable {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.file-tile__thumbnail {
|
.file-tile__thumbnail {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: $spacing-vertical * 7;
|
max-height: $spacing-vertical * 7;
|
||||||
|
|
35
scss/component/_tooltip.scss
Normal file
35
scss/component/_tooltip.scss
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
@import "../global";
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip__link {
|
||||||
|
@include text-link();
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip__body {
|
||||||
|
$tooltip-body-width: 300px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: $tooltip-body-width * -1 / 2;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: $spacing-vertical / 2;
|
||||||
|
width: $tooltip-body-width;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
color: $color-text-dark;
|
||||||
|
background-color: $color-bg;
|
||||||
|
font-size: $font-size * 7/8;
|
||||||
|
line-height: $font-line-height;
|
||||||
|
box-shadow: $default-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip--header .tooltip__link {
|
||||||
|
@include text-link(#aaa);
|
||||||
|
font-size: $font-size * 3/4;
|
||||||
|
margin-left: $padding-button;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue