Seed Support #56
23 changed files with 272 additions and 275 deletions
39
ui/js/app.js
39
ui/js/app.js
|
@ -244,51 +244,50 @@ var App = React.createClass({
|
|||
return null;
|
||||
}
|
||||
},
|
||||
getMainContent: function()
|
||||
getContentAndAddress: function()
|
||||
{
|
||||
switch(this.state.viewingPage)
|
||||
{
|
||||
case 'settings':
|
||||
return <SettingsPage />;
|
||||
return ["Settings", "icon-gear", <SettingsPage />];
|
||||
case 'help':
|
||||
return <HelpPage />;
|
||||
return ["Help", "icon-question", <HelpPage />];
|
||||
case 'report':
|
||||
return <ReportPage />;
|
||||
return ['Report', 'icon-file', <ReportPage />];
|
||||
case 'downloaded':
|
||||
return <FileListDownloaded />;
|
||||
return ["Downloads & Purchases", "icon-folder", <FileListDownloaded />];
|
||||
case 'published':
|
||||
return <FileListPublished />;
|
||||
return ["Publishes", "icon-folder", <FileListPublished />];
|
||||
case 'start':
|
||||
return <StartPage />;
|
||||
return ["Start", "icon-file", <StartPage />];
|
||||
case 'rewards':
|
||||
return <RewardsPage />;
|
||||
return ["Rewards", "icon-bank", <RewardsPage />];
|
||||
case 'wallet':
|
||||
case 'send':
|
||||
case 'receive':
|
||||
return <WalletPage viewingPage={this.state.viewingPage} />;
|
||||
return [this.state.viewingPage.charAt(0).toUpperCase() + this.state.viewingPage.slice(1), "icon-bank", <WalletPage viewingPage={this.state.viewingPage} />]
|
||||
case 'show':
|
||||
return <ShowPage uri={this.state.pageArgs} />;
|
||||
return [this.state.pageArgs, "icon-file", <ShowPage uri={this.state.pageArgs} />];
|
||||
case 'publish':
|
||||
return <PublishPage />;
|
||||
return ["Publish", "icon-upload", <PublishPage />];
|
||||
case 'developer':
|
||||
return <DeveloperPage />;
|
||||
return ["Developer", "icon-file", <DeveloperPage />];
|
||||
case 'discover':
|
||||
default:
|
||||
return <DiscoverPage showWelcome={this.state.justRegistered} {... this.state.pageArgs !== null ? {query: this.state.pageArgs} : {} } />;
|
||||
return ["Home", "icon-home", <DiscoverPage showWelcome={this.state.justRegistered} {... this.state.pageArgs !== null ? {query: this.state.pageArgs} : {} } />];
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
var mainContent = this.getMainContent(),
|
||||
headerLinks = this.getHeaderLinks(),
|
||||
searchQuery = this.state.viewingPage == 'discover' && this.state.pageArgs ? this.state.pageArgs : '';
|
||||
|
||||
let [address, wunderBarIcon, mainContent] = this.getContentAndAddress(),
|
||||
headerLinks = this.getHeaderLinks();
|
||||
|
||||
return (
|
||||
this._fullScreenPages.includes(this.state.viewingPage) ?
|
||||
mainContent :
|
||||
<div id="window" className={ this.state.drawerOpen ? 'drawer-open' : 'drawer-closed' }>
|
||||
<Drawer onCloseDrawer={this.closeDrawer} viewingPage={this.state.viewingPage} />
|
||||
<div id="window">
|
||||
<Header onOpenDrawer={this.openDrawer} address={address} wunderBarIcon={wunderBarIcon}
|
||||
onSearch={this.onSearch} links={headerLinks} viewingPage={this.state.viewingPage} />
|
||||
<div id="main-content" className={ headerLinks ? 'with-sub-nav' : 'no-sub-nav' }>
|
||||
<Header onOpenDrawer={this.openDrawer} initialQuery={searchQuery} onSearch={this.onSearch} links={headerLinks} viewingPage={this.state.viewingPage} />
|
||||
{mainContent}
|
||||
</div>
|
||||
<Modal isOpen={this.state.modal == 'upgrade'} contentLabel="Update available"
|
||||
|
|
|
@ -1,72 +1,135 @@
|
|||
import React from 'react';
|
||||
import {Link} from './link.js';
|
||||
import {Icon} from './common.js';
|
||||
import {Icon, CreditAmount} from './common.js';
|
||||
|
||||
var Header = React.createClass({
|
||||
_balanceSubscribeId: null,
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
title: "LBRY",
|
||||
isScrolled: false
|
||||
balance: 0
|
||||
};
|
||||
},
|
||||
componentWillMount: function() {
|
||||
new MutationObserver((mutations) => {
|
||||
this.setState({ title: mutations[0].target.textContent });
|
||||
}).observe(
|
||||
document.querySelector('title'),
|
||||
{ subtree: true, characterData: true, childList: true }
|
||||
);
|
||||
},
|
||||
componentDidMount: function() {
|
||||
document.addEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
document.removeEventListener('scroll', this.handleScroll);
|
||||
if (this.userTypingTimer)
|
||||
{
|
||||
clearTimeout(this.userTypingTimer);
|
||||
}
|
||||
},
|
||||
handleScroll: function() {
|
||||
this.setState({
|
||||
isScrolled: document.body.scrollTop > 0
|
||||
this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
|
||||
this.setState({ balance: balance });
|
||||
});
|
||||
},
|
||||
onQueryChange: function(event) {
|
||||
|
||||
if (this.userTypingTimer)
|
||||
{
|
||||
clearTimeout(this.userTypingTimer);
|
||||
componentWillUnmount: function() {
|
||||
if (this._balanceSubscribeId) {
|
||||
lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
return <div>
|
||||
<header id="header">
|
||||
<div className="header__item">
|
||||
<Link onClick={() => { history.back() }} button="alt button--flat" icon="icon-arrow-left" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link href="?discover" button="alt button--flat" icon="icon-home" />
|
||||
</div>
|
||||
<div className="header__item header__item--wunderbar">
|
||||
<WunderBar address={this.props.address} icon={this.props.wunderBarIcon} onSearch={this.props.onSearch} />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link href="?wallet" button="text" icon="icon-bank" label={lbry.formatCredits(this.state.balance, 1)} ></Link>
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="primary button--flat" href="?publish" icon="icon-upload" label="Publish" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="alt button--flat" href="?downloaded" icon="icon-folder" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="alt button--flat" href="?settings" icon="icon-gear" />
|
||||
</div>
|
||||
</header>
|
||||
{this.props.links ?
|
||||
<SubHeader links={this.props.links} viewingPage={this.props.viewingPage} /> :
|
||||
''}
|
||||
</div>
|
||||
}
|
||||
});
|
||||
|
||||
let WunderBar = React.createClass({
|
||||
_userTypingTimer: null,
|
||||
_input: null,
|
||||
_stateBeforeSearch: null,
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
address: this.props.address,
|
||||
icon: this.props.icon
|
||||
};
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
if (this.userTypingTimer) {
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
},
|
||||
onChange: function(event) {
|
||||
|
||||
if (this._userTypingTimer)
|
||||
{
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
|
||||
this.setState({ address: event.target.value })
|
||||
|
||||
//@TODO: Switch to React.js timing
|
||||
var searchTerm = event.target.value;
|
||||
this.userTypingTimer = setTimeout(() => {
|
||||
|
||||
this._userTypingTimer = setTimeout(() => {
|
||||
this.props.onSearch(searchTerm);
|
||||
}, 800); // 800ms delay, tweak for faster/slower
|
||||
|
||||
},
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.address !== this.state.address || nextProps.icon !== this.state.icon) {
|
||||
this.setState({ address: nextProps.address, icon: nextProps.icon });
|
||||
}
|
||||
},
|
||||
onFocus: function() {
|
||||
this._stateBeforeSearch = this.state;
|
||||
let newState = {
|
||||
icon: "icon-search"
|
||||
}
|
||||
// this._input.value = ""; //trigger placeholder
|
||||
this._focusPending = true;
|
||||
if (!this.state.address.match(/^lbry:\/\//)) //onFocus, if they are not on an exact URL, clear the bar
|
||||
{
|
||||
newState.address = "";
|
||||
}
|
||||
this.setState(newState);
|
||||
},
|
||||
onBlur: function() {
|
||||
this.setState(this._stateBeforeSearch);
|
||||
this._input.value = this.state.address;
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
this._input.value = this.state.address;
|
||||
if (this._input && this._focusPending) {
|
||||
this._input.select();
|
||||
this._focusPending = false;
|
||||
}
|
||||
},
|
||||
onReceiveRef: function(ref) {
|
||||
this._input = ref;
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<header id="header" className={ (this.state.isScrolled ? 'header-scrolled' : 'header-unscrolled') + ' ' + (this.props.links ? 'header-with-subnav' : 'header-no-subnav') }>
|
||||
<div className="header-top-bar">
|
||||
<Link onClick={this.props.onOpenDrawer} icon="icon-bars" className="open-drawer-link" />
|
||||
<h1>{ this.state.title }</h1>
|
||||
<div className="header-search">
|
||||
<Icon icon="icon-search" />
|
||||
<input type="search" onChange={this.onQueryChange} defaultValue={this.props.initialQuery}
|
||||
placeholder="Find movies, music, games, and more"/>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
this.props.links ?
|
||||
<SubHeader links={this.props.links} viewingPage={this.props.viewingPage} /> :
|
||||
''
|
||||
}
|
||||
</header>
|
||||
);
|
||||
return <div className="wunderbar">
|
||||
{this.state.icon ? <Icon fixed icon={this.state.icon} /> : '' }
|
||||
<input className="wunderbar__input" type="search" placeholder="Type a LBRY address or search term"
|
||||
ref={this.onReceiveRef}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onChange={this.onChange}
|
||||
value={ this.state.address }
|
||||
placeholder="Find movies, music, games, and more" />
|
||||
</div>
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
var SubHeader = React.createClass({
|
||||
render: function() {
|
||||
|
|
|
@ -41,7 +41,7 @@ export let Link = React.createClass({
|
|||
content = (
|
||||
<span {... 'button' in this.props ? {className: 'button__content'} : {}}>
|
||||
{'icon' in this.props ? <Icon icon={this.props.icon} fixed={true} /> : null}
|
||||
{<span className="link-label">{this.props.label}</span>}
|
||||
{this.props.label ? <span className="link-label">{this.props.label}</span> : null}
|
||||
{'badge' in this.props ? <span className="badge">{this.props.badge}</span> : null}
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -627,18 +627,18 @@ lbry.claim_list_mine = function(params={}) {
|
|||
}
|
||||
|
||||
lbry.resolve = function(params={}) {
|
||||
const claimCacheKey = 'resolve_claim_cache',
|
||||
claimCache = getSession(claimCacheKey, {})
|
||||
const claimCacheKey = 'resolve_claim_cache3',
|
||||
claimCache = getLocal(claimCacheKey, {})
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!params.uri) {
|
||||
throw "Resolve has hacked cache on top of it that requires a URI"
|
||||
}
|
||||
if (params.uri && claimCache[params.uri]) {
|
||||
if (params.uri && claimCache[params.uri] !== undefined) {
|
||||
resolve(claimCache[params.uri]);
|
||||
} else {
|
||||
lbry.call('resolve', params, function(data) {
|
||||
claimCache[params.uri] = data;
|
||||
setSession(claimCacheKey, claimCache)
|
||||
setLocal(claimCacheKey, claimCache)
|
||||
resolve(data)
|
||||
}, reject)
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@ const lbryio = {
|
|||
_accessToken: getLocal('accessToken'),
|
||||
_authenticationPromise: null,
|
||||
_user : null,
|
||||
enabled: true
|
||||
enabled: false
|
||||
};
|
||||
|
||||
const CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL : 'https://api.lbry.io/';
|
||||
// const CONNECTION_STRING = process.env.LBRY_APP_API_URL ? process.env.LBRY_APP_API_URL : 'https://api.lbry.io/';
|
||||
const CONNECTION_STRING = 'https://api.lbry.io/';
|
||||
const EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000;
|
||||
|
||||
lbryio.getExchangeRates = function() {
|
||||
|
|
|
@ -164,7 +164,7 @@ var DiscoverPage = React.createClass({
|
|||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
document.title = "Discover";
|
||||
document.title = "Home";
|
||||
|
||||
if (this.props.query) {
|
||||
// Rendering with a query already typed
|
||||
|
|
|
@ -19,7 +19,6 @@ export let FileListDownloaded = React.createClass({
|
|||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
document.title = "Downloaded Files";
|
||||
|
||||
lbry.claim_list_mine().then((myClaimInfos) => {
|
||||
if (!this._isMounted) { return; }
|
||||
|
|
|
@ -348,9 +348,6 @@ var PublishPage = React.createClass({
|
|||
componentWillMount: function() {
|
||||
this._updateChannelList();
|
||||
},
|
||||
componentDidMount: function() {
|
||||
document.title = "Publish";
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
},
|
||||
onFileChange: function() {
|
||||
|
|
|
@ -17,7 +17,7 @@ var SettingsPage = React.createClass({
|
|||
setClientSetting: function(name, value) {
|
||||
lbry.setClientSetting(name, value)
|
||||
this._onSettingSaveSuccess()
|
||||
},
|
||||
},
|
||||
onRunOnStartChange: function (event) {
|
||||
this.setDaemonSetting('run_on_startup', event.target.checked);
|
||||
},
|
||||
|
|
|
@ -60,7 +60,6 @@ let ShowPage = React.createClass({
|
|||
},
|
||||
componentWillMount: function() {
|
||||
this._uri = lbryuri.normalize(this.props.uri);
|
||||
document.title = this._uri;
|
||||
|
||||
lbry.resolve({uri: this._uri}).then(({ claim: {txid, nout, has_signature, signature_is_valid, value: {stream: {metadata, source: {contentType}}}}}) => {
|
||||
const outpoint = txid + ':' + nout;
|
||||
|
@ -71,6 +70,8 @@ let ShowPage = React.createClass({
|
|||
});
|
||||
});
|
||||
|
||||
document.title = metadata.title ? metadata.title : this._uri;
|
||||
|
||||
this.setState({
|
||||
outpoint: outpoint,
|
||||
metadata: metadata,
|
||||
|
@ -91,6 +92,7 @@ let ShowPage = React.createClass({
|
|||
render: function() {
|
||||
const metadata = this.state.metadata;
|
||||
const title = metadata ? this.state.metadata.title : this._uri;
|
||||
|
||||
return (
|
||||
<main className="constrained-page">
|
||||
<section className="show-page-media">
|
||||
|
|
|
@ -5,9 +5,6 @@ var StartPage = React.createClass({
|
|||
componentWillMount: function() {
|
||||
lbry.stop();
|
||||
},
|
||||
componentDidMount: function() {
|
||||
document.title = "LBRY is Closed";
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<main className="page">
|
||||
|
|
|
@ -270,9 +270,6 @@ var WalletPage = React.createClass({
|
|||
propTypes: {
|
||||
viewingPage: React.PropTypes.string,
|
||||
},
|
||||
componentDidMount: function() {
|
||||
document.title = "My Wallet";
|
||||
},
|
||||
/*
|
||||
Below should be refactored so that balance is shared all of wallet page. Or even broader?
|
||||
What is the proper React pattern for sharing a global state like balance?
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
* Thin wrapper around localStorage.getItem(). Parses JSON and returns undefined if the value
|
||||
* is not set yet.
|
||||
*/
|
||||
export function getLocal(key) {
|
||||
export function getLocal(key, fallback=undefined) {
|
||||
const itemRaw = localStorage.getItem(key);
|
||||
return itemRaw === null ? undefined : JSON.parse(itemRaw);
|
||||
return itemRaw === null ? fallback : JSON.parse(itemRaw);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,44 +11,12 @@ body
|
|||
line-height: $font-line-height;
|
||||
}
|
||||
|
||||
$drawer-width: 220px;
|
||||
|
||||
#drawer
|
||||
#window
|
||||
{
|
||||
width: $drawer-width;
|
||||
position: fixed;
|
||||
min-height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: $color-bg;
|
||||
z-index: 3;
|
||||
.drawer-item
|
||||
{
|
||||
display: block;
|
||||
padding: $spacing-vertical / 2;
|
||||
font-size: 1.2em;
|
||||
height: $spacing-vertical * 1.5;
|
||||
.icon
|
||||
{
|
||||
margin-right: 6px;
|
||||
}
|
||||
.link-label
|
||||
{
|
||||
line-height: $spacing-vertical * 1.5;
|
||||
}
|
||||
.badge
|
||||
{
|
||||
float: right;
|
||||
margin-top: $spacing-vertical * 0.25 - 2;
|
||||
background: $color-money;
|
||||
}
|
||||
}
|
||||
.drawer-item-selected
|
||||
{
|
||||
background: $color-canvas;
|
||||
color: $color-primary;
|
||||
}
|
||||
background: $color-canvas;
|
||||
}
|
||||
|
||||
.badge
|
||||
{
|
||||
background: $color-money;
|
||||
|
@ -62,119 +30,9 @@ $drawer-width: 220px;
|
|||
font-weight: bold;
|
||||
color: $color-money;
|
||||
}
|
||||
#drawer-handle
|
||||
{
|
||||
padding: $spacing-vertical / 2;
|
||||
max-height: $height-header - $spacing-vertical;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#window
|
||||
{
|
||||
position: relative; /*window has it's own z-index inside of it*/
|
||||
z-index: 1;
|
||||
}
|
||||
#window.drawer-closed
|
||||
{
|
||||
#drawer { display: none }
|
||||
}
|
||||
#window.drawer-open
|
||||
{
|
||||
#main-content { margin-left: $drawer-width; }
|
||||
.open-drawer-link { display: none }
|
||||
#header { padding-left: $drawer-width + $spacing-vertical / 2; }
|
||||
}
|
||||
|
||||
#header
|
||||
{
|
||||
background: $color-primary;
|
||||
color: white;
|
||||
&.header-no-subnav {
|
||||
height: $height-header;
|
||||
}
|
||||
&.header-with-subnav {
|
||||
height: $height-header * 2;
|
||||
}
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
box-sizing: border-box;
|
||||
h1 { font-size: 1.8em; line-height: $height-header - $spacing-vertical; display: inline-block; float: left; }
|
||||
&.header-scrolled
|
||||
{
|
||||
box-shadow: $default-box-shadow;
|
||||
}
|
||||
}
|
||||
.header-top-bar
|
||||
{
|
||||
padding: $spacing-vertical / 2;
|
||||
}
|
||||
.header-search
|
||||
{
|
||||
margin-left: 60px;
|
||||
$padding-adjust: 36px;
|
||||
text-align: center;
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: $spacing-vertical * 1.5 / 2 + 2px; //hacked
|
||||
margin-left: -$padding-adjust + 14px; //hacked
|
||||
}
|
||||
input[type="search"] {
|
||||
position: relative;
|
||||
left: -$padding-adjust;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
color: white;
|
||||
width: 400px;
|
||||
height: $spacing-vertical * 1.5;
|
||||
line-height: $spacing-vertical * 1.5;
|
||||
padding-left: $padding-adjust + 3;
|
||||
padding-right: 3px;
|
||||
@include border-radius(2px);
|
||||
@include placeholder-color(#e8e8e8);
|
||||
&:focus {
|
||||
box-shadow: $focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav.sub-header
|
||||
{
|
||||
background: $color-primary;
|
||||
text-transform: uppercase;
|
||||
padding: $spacing-vertical / 2;
|
||||
> a
|
||||
{
|
||||
$sub-header-selected-underline-height: 2px;
|
||||
display: inline-block;
|
||||
margin: 0 15px;
|
||||
padding: 0 5px;
|
||||
line-height: $height-header - $spacing-vertical - $sub-header-selected-underline-height;
|
||||
color: #e8e8e8;
|
||||
&:first-child
|
||||
{
|
||||
margin-left: 0;
|
||||
}
|
||||
&:last-child
|
||||
{
|
||||
margin-right: 0;
|
||||
}
|
||||
&.sub-header-selected
|
||||
{
|
||||
border-bottom: $sub-header-selected-underline-height solid #fff;
|
||||
color: #fff;
|
||||
}
|
||||
&:hover
|
||||
{
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#main-content
|
||||
{
|
||||
background: $color-canvas;
|
||||
&.no-sub-nav
|
||||
{
|
||||
min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
|
||||
|
@ -182,8 +40,7 @@ nav.sub-header
|
|||
}
|
||||
&.with-sub-nav
|
||||
{
|
||||
min-height: calc(100vh - 120px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
|
||||
main { margin-top: $height-header * 2; }
|
||||
min-height: calc(100vh - 60px); //should be -$height-header, but I'm dumb I guess? It wouldn't work
|
||||
}
|
||||
main
|
||||
{
|
||||
|
@ -195,26 +52,4 @@ nav.sub-header
|
|||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$header-icon-size: 1.5em;
|
||||
|
||||
.open-drawer-link, .close-drawer-link
|
||||
{
|
||||
display: inline-block;
|
||||
font-size: $header-icon-size;
|
||||
padding: 2px 6px 0 6px;
|
||||
float: left;
|
||||
}
|
||||
.close-lbry-link
|
||||
{
|
||||
font-size: $header-icon-size;
|
||||
float: right;
|
||||
padding: 0 6px 0 18px;
|
||||
}
|
||||
|
||||
.full-screen
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
|
@ -34,8 +34,8 @@ $height-header: $spacing-vertical * 2.5;
|
|||
$height-button: $spacing-vertical * 1.5;
|
||||
$height-video-embedded: $width-page-constrained * 9 / 16;
|
||||
|
||||
$default-box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
|
||||
$focus-box-shadow: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12);
|
||||
$box-shadow-layer: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
|
||||
$box-shadow-focus: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12);
|
||||
|
||||
$transition-standard: .225s ease;
|
||||
|
||||
|
|
|
@ -25,12 +25,6 @@
|
|||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
.icon-mega
|
||||
{
|
||||
font-size: 200px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
|
||||
readers do not read off random characters that represent icons */
|
||||
.icon-glass:before {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
@import "component/_file-actions.scss";
|
||||
@import "component/_file-tile.scss";
|
||||
@import "component/_form-field.scss";
|
||||
@import "component/_header.scss";
|
||||
@import "component/_menu.scss";
|
||||
@import "component/_tooltip.scss";
|
||||
@import "component/_load-screen.scss";
|
||||
|
|
|
@ -34,6 +34,11 @@ $button-focus-shift: 12%;
|
|||
{
|
||||
padding-left: 5px;
|
||||
}
|
||||
.icon:only-child
|
||||
{
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
.button-block
|
||||
{
|
||||
|
@ -49,17 +54,17 @@ $button-focus-shift: 12%;
|
|||
$color-button-text: white;
|
||||
color: darken($color-button-text, $button-focus-shift * 0.5);
|
||||
background-color: $color-primary;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
&:focus {
|
||||
color: $color-button-text;
|
||||
//box-shadow: $focus-box-shadow;
|
||||
//box-shadow: $box-shadow-focus;
|
||||
background-color: mix(black, $color-primary, $button-focus-shift)
|
||||
}
|
||||
}
|
||||
.button-alt
|
||||
{
|
||||
background-color: $color-bg-alt;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
}
|
||||
|
||||
.button-text
|
||||
|
@ -76,3 +81,7 @@ $button-focus-shift: 12%;
|
|||
@include text-link(#aaa);
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.button--flat
|
||||
{
|
||||
box-shadow: none !important;
|
||||
}
|
|
@ -7,7 +7,7 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
|
|||
margin-right: auto;
|
||||
max-width: $width-page-constrained;
|
||||
background: $color-bg;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
border-radius: 2px;
|
||||
margin-bottom: $spacing-vertical * 2/3;
|
||||
overflow: auto;
|
||||
|
@ -86,7 +86,7 @@ $card-link-scaling: 1.1;
|
|||
.card--link:hover {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
box-shadow: $focus-box-shadow;
|
||||
box-shadow: $box-shadow-focus;
|
||||
transform: scale($card-link-scaling);
|
||||
transform-origin: 50% 50%;
|
||||
overflow-x: visible;
|
||||
|
|
103
ui/scss/component/_header.scss
Normal file
103
ui/scss/component/_header.scss
Normal file
|
@ -0,0 +1,103 @@
|
|||
@import "../global";
|
||||
|
||||
$color-header: #666;
|
||||
|
||||
|
||||
$header-icon-size: 1.5em;
|
||||
|
||||
.open-drawer-link, .close-drawer-link
|
||||
{
|
||||
display: inline-block;
|
||||
font-size: $header-icon-size;
|
||||
padding: 2px 6px 0 6px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#header
|
||||
{
|
||||
color: $color-header;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
/*
|
||||
&.header-no-subnav {
|
||||
height: $height-header;
|
||||
}
|
||||
&.header-with-subnav {
|
||||
height: $height-header * 2;
|
||||
}*/
|
||||
position: fixed;
|
||||
box-shadow: $box-shadow-layer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
padding: $spacing-vertical / 2;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.header__item {
|
||||
flex: 0 0 content;
|
||||
padding-left: $spacing-vertical / 4;
|
||||
padding-right: $spacing-vertical / 4;
|
||||
}
|
||||
.header__item--wunderbar {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.wunderbar
|
||||
{
|
||||
position: relative;
|
||||
.icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: $spacing-vertical / 2 - 4px; //hacked
|
||||
}
|
||||
}
|
||||
.wunderbar__input {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
width: 100%;
|
||||
color: $color-header;
|
||||
height: $spacing-vertical * 1.5;
|
||||
line-height: $spacing-vertical * 1.5;
|
||||
padding-left: 38px;
|
||||
padding-right: 5px;
|
||||
border: 1px solid $color-text-dark;
|
||||
@include border-radius(2px);
|
||||
border: 1px solid #ccc;
|
||||
&:focus {
|
||||
box-shadow: $box-shadow-focus;
|
||||
border-color: $color-header;
|
||||
}
|
||||
}
|
||||
|
||||
nav.sub-header
|
||||
{
|
||||
text-transform: uppercase;
|
||||
padding: $spacing-vertical / 2;
|
||||
> a
|
||||
{
|
||||
$sub-header-selected-underline-height: 2px;
|
||||
display: inline-block;
|
||||
margin: 0 15px;
|
||||
padding: 0 5px;
|
||||
line-height: $height-header - $spacing-vertical - $sub-header-selected-underline-height;
|
||||
color: $color-header;
|
||||
&:first-child
|
||||
{
|
||||
margin-left: 0;
|
||||
}
|
||||
&:last-child
|
||||
{
|
||||
margin-right: 0;
|
||||
}
|
||||
$color-selected-subheader: darken($color-header, 20%);
|
||||
&.sub-header-selected
|
||||
{
|
||||
border-bottom: $sub-header-selected-underline-height solid $color-selected-subheader;
|
||||
color: $color-selected-subheader;
|
||||
}
|
||||
&:hover
|
||||
{
|
||||
color: $color-selected-subheader;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ $border-radius-menu: 2px;
|
|||
position: absolute;
|
||||
white-space: nowrap;
|
||||
background-color: white;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
border-radius: $border-radius-menu;
|
||||
padding-top: ($spacing-vertical / 5) 0px;
|
||||
z-index: 1;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
overflow: auto;
|
||||
border-radius: 4px;
|
||||
padding: $spacing-vertical;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
background-color: $color-bg;
|
||||
font-size: $font-size * 7/8;
|
||||
line-height: $font-line-height;
|
||||
box-shadow: $default-box-shadow;
|
||||
box-shadow: $box-shadow-layer;
|
||||
}
|
||||
|
||||
.tooltip--header .tooltip__link {
|
||||
|
|
Loading…
Reference in a new issue