diff --git a/CHANGELOG.md b/CHANGELOG.md index f7a66de33..a908973fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,24 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added + * Add setting to automatically purchase low-cost content without a confirmation dialog * New custom styled scrollbar [#574](https://github.com/lbryio/lbry-app/pull/574) * ### Changed + * Updated the daemon from 0.16.1 to [0.16.3](https://github.com/lbryio/lbry/releases/tag/v0.16.3) to improve download performance and download issue detection. + * Changed the File page to make it clearer how to to open the folder for a file. * Improved tabs styles with a nice animation. [#547](https://github.com/lbryio/lbry-app/pull/576) * Display search bar on discover page instead of title and remove duplicated icon. * Minor update for themes. + * ### Fixed + * Improve layout (and implementation) of the icon panel in file tiles and cards + * The folder icon representing a local download now shows up properly on Channel pages (#587) + * While editing a publish, the URL will no longer change if you select a new file. (#601) + * Fixed issues with opening the folder for a file (#606) + * Be consistent with the step property on credit inputs (#604) * Fixed unresponsive header [#613](https://github.com/lbryio/lbry-app/issues/613) * Fixed dark theme issues with text content. * Minor css fixes. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..e7d0dce20 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +## Contributing to LBRY + +https://lbry.io/faq/contributing diff --git a/README.md b/README.md index 623ee135a..179c7abdd 100644 --- a/README.md +++ b/README.md @@ -49,43 +49,49 @@ to create distributable packages, which is run by calling: ## Development on Windows ### Windows Dependency - -1. Download and install `npm` and `node` from nodejs.org -2. Download and install `python 2.7` from python.org -3. Download and Install `Microsoft Visual C++ Compiler for Python 2.7` from Microsoft -4. Download and install `.NET Framework 2.0 Software Development Kit (SDK) (x64)` from Microsoft +1. Download and install `git` from github.io (configure to use command prompt integration) +2. Download and install `npm` and `node` from nodejs.org +3. Download and install `python 2.7` from python.org +4. Download and Install `Microsoft Visual C++ Compiler for Python 2.7` from Microsoft +5. Download and install `.NET Framework 2.0 Software Development Kit (SDK) (x64)` from Microsoft (may need to extract setup.exe and install manually by running install.exe as Administrator) ### One-time Setup -1. Open command prompt in the root of the project and run the following; +1. Open command prompt as adminstrator and run the following: +``` +npm install --global --production windows-build-tools +exit +``` + +2. Open command prompt in the root of the project and run the following: ``` python -m pip install -r build\requirements.txt python build\set_version.py npm install -g yarn yarn install ``` -2. Change directory to `app` and run the following; +3. Change directory to `app` and run the following; ``` yarn install node_modules\.bin\electron-rebuild node_modules\.bin\electron-rebuild cd .. ``` -3. Change directory to `ui` and run the following +4. Change directory to `ui` and run the following: ``` yarn install npm rebuild node-sass node node_modules\node-sass\bin\node-sass --output dist\css --sourcemap=none scss\ node_modules\.bin\webpack --config webpack.dev.config.js -xcopy dist ..\app\dist +xcopy /E dist ..\app\dist cd .. ``` -4. Download the lbry daemon and cli binaries and place them in `app\dist\` +4. Download the lbry daemon and cli [binaries](https://github.com/lbryio/lbry/releases) and place them in `app\dist\` ### Building lbry-app 1. run `node_modules\.bin\build -p never` from the root of the project. ### Running the electron app -1. Run `./node_modules/.bin/electron app` +1. Run `node_modules\.bin\electron app` ### Ongoing Development 1. `cd ui` diff --git a/app/package.json b/app/package.json index 15878e6e7..a5495a156 100644 --- a/app/package.json +++ b/app/package.json @@ -20,7 +20,7 @@ "electron-rebuild": "^1.5.11" }, "lbrySettings": { - "lbrynetDaemonVersion": "0.16.1", + "lbrynetDaemonVersion": "0.16.3", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip" }, "license": "MIT" diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 67fb76071..0fb877573 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -1,5 +1,4 @@ import * as types from "constants/action_types"; -import * as settings from "constants/settings"; import lbry from "lbry"; import { selectUpdateUrl, @@ -8,6 +7,7 @@ import { selectUpgradeFilename, } from "selectors/app"; import { doFetchDaemonSettings } from "actions/settings"; +import { doBalanceSubscribe } from "actions/wallet"; import { doAuthenticate } from "actions/user"; import { doFetchFileInfosAndPublishedClaims } from "actions/file_info"; @@ -178,6 +178,7 @@ export function doDaemonReady() { dispatch(doAuthenticate()); dispatch({ type: types.DAEMON_READY }); dispatch(doFetchDaemonSettings()); + dispatch(doBalanceSubscribe()); dispatch(doFetchFileInfosAndPublishedClaims()); }; } diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index eb62506a2..f6a5ac94b 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -1,4 +1,5 @@ import * as types from "constants/action_types"; +import * as settings from "constants/settings"; import lbry from "lbry"; import lbryio from "lbryio"; import lbryuri from "lbryuri"; @@ -322,29 +323,56 @@ export function doPurchaseUri(uri) { const downloadingByOutpoint = selectDownloadingByOutpoint(state); const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; - const costInfo = makeSelectCostInfoForUri(uri)(state); - const { cost } = costInfo; - if ( - alreadyDownloading || - (fileInfo && fileInfo.completed && fileInfo.written_bytes > 0) - ) { - return; + function attemptPlay(cost, instantPurchaseMax = null) { + if (cost > 0 && (!instantPurchaseMax || cost > instantPurchaseMax)) { + dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri })); + } else { + dispatch(doLoadVideo(uri)); + } } // we already fully downloaded the file. - if ( - cost === 0 || - (fileInfo && (fileInfo.completed || fileInfo.download_directory)) - ) { - return dispatch(doLoadVideo(uri)); + if (fileInfo && fileInfo.completed) { + // If written_bytes is false that means the user has deleted/moved the + // file manually on their file system, so we need to dispatch a + // doLoadVideo action to reconstruct the file from the blobs + if (!fileInfo.written_bytes) dispatch(doLoadVideo(uri)); + + return Promise.resolve(); } + // we are already downloading the file + if (alreadyDownloading) { + return Promise.resolve(); + } + + const costInfo = makeSelectCostInfoForUri(uri)(state); + const { cost } = costInfo; + if (cost > balance) { - return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS)); + dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS)); + return Promise.resolve(); } - return dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri })); + if ( + cost == 0 || + !lbry.getClientSetting(settings.INSTANT_PURCHASE_ENABLED) + ) { + attemptPlay(cost); + } else { + const instantPurchaseMax = lbry.getClientSetting( + settings.INSTANT_PURCHASE_MAX + ); + if (instantPurchaseMax.currency == "LBC") { + attemptPlay(cost, instantPurchaseMax.amount); + } else { + // Need to convert currency of instant purchase maximum before trying to play + lbryio.getExchangeRates().then(({ lbc_usd }) => { + attemptPlay(cost, instantPurchaseMax.amount / lbc_usd); + }); + } + } }; } diff --git a/ui/js/actions/wallet.js b/ui/js/actions/wallet.js index 0e90266fb..e7b36597a 100644 --- a/ui/js/actions/wallet.js +++ b/ui/js/actions/wallet.js @@ -9,12 +9,23 @@ import { doOpenModal, doShowSnackBar } from "actions/app"; import { doNavigate } from "actions/navigation"; import * as modals from "constants/modal_types"; -export function doUpdateBalance(balance) { - return { - type: types.UPDATE_BALANCE, - data: { - balance: balance, - }, +export function doUpdateBalance() { + return function(dispatch, getState) { + lbry.wallet_balance().then(balance => { + return dispatch({ + type: types.UPDATE_BALANCE, + data: { + balance: balance, + }, + }); + }); + }; +} + +export function doBalanceSubscribe() { + return function(dispatch, getState) { + dispatch(doUpdateBalance()); + setInterval(() => dispatch(doUpdateBalance()), 5000); }; } diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js index 574c5f862..06ff45f18 100644 --- a/ui/js/component/app/index.js +++ b/ui/js/component/app/index.js @@ -5,7 +5,6 @@ import { selectUser } from "selectors/user"; import { doCheckUpgradeAvailable, doAlertError } from "actions/app"; import { doRecordScroll } from "actions/navigation"; import { doFetchRewardedContent } from "actions/content"; -import { doUpdateBalance } from "actions/wallet"; import App from "./view"; const select = (state, props) => ({ @@ -16,7 +15,6 @@ const select = (state, props) => ({ const perform = dispatch => ({ alertError: errorList => dispatch(doAlertError(errorList)), checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()), - updateBalance: balance => dispatch(doUpdateBalance(balance)), fetchRewardedContent: () => dispatch(doFetchRewardedContent()), recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), }); diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index 37bd05c72..b349fd2de 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -10,7 +10,6 @@ class App extends React.PureComponent { const { alertError, checkUpgradeAvailable, - updateBalance, fetchRewardedContent, } = this.props; @@ -22,10 +21,6 @@ class App extends React.PureComponent { checkUpgradeAvailable(); } - lbry.balanceSubscribe(balance => { - updateBalance(balance); - }); - fetchRewardedContent(); this.scrollListener = () => this.props.recordScroll(window.scrollY); diff --git a/ui/js/component/fileCard/view.jsx b/ui/js/component/fileCard/view.jsx index eb29a1b2e..3ff093ef0 100644 --- a/ui/js/component/fileCard/view.jsx +++ b/ui/js/component/fileCard/view.jsx @@ -2,12 +2,13 @@ import React from "react"; import lbryuri from "lbryuri.js"; import CardMedia from "component/cardMedia"; import Link from "component/link"; -import { TruncatedText, Icon } from "component/common"; -import IconFeatured from "component/iconFeatured"; +import { TruncatedText } from "component/common"; +import Icon from "component/icon"; import FilePrice from "component/filePrice"; import UriIndicator from "component/uriIndicator"; import NsfwOverlay from "component/nsfwOverlay"; import TruncatedMarkdown from "component/truncatedMarkdown"; +import * as icons from "constants/icons"; class FileCard extends React.PureComponent { constructor(props) { @@ -94,11 +95,12 @@ class FileCard extends React.PureComponent { {title}
- + - {isRewardContent && {" "}} - {fileInfo && - {" "}} + {" "} + {isRewardContent && } + {" "} + {fileInfo && }
diff --git a/ui/js/component/fileDetails/view.jsx b/ui/js/component/fileDetails/view.jsx index c2cfda468..aaa6ab24e 100644 --- a/ui/js/component/fileDetails/view.jsx +++ b/ui/js/component/fileDetails/view.jsx @@ -29,8 +29,9 @@ class FileDetails extends React.PureComponent { const { description, language, license } = metadata; const { height } = claim; const mediaType = lbry.getMediaType(contentType); - const directory = fileInfo && fileInfo.download_path - ? path.dirname(fileInfo.download_path) + + const downloadPath = fileInfo + ? path.normalize(fileInfo.download_path) : null; return ( @@ -59,12 +60,12 @@ class FileDetails extends React.PureComponent { {__("License")}{license} - {directory && + {downloadPath && {__("Downloaded to")} - openFolder(directory)}> - {directory} + openFolder(downloadPath)}> + {downloadPath} } diff --git a/ui/js/component/fileList/view.jsx b/ui/js/component/fileList/view.jsx index 8fad10cdc..97010a104 100644 --- a/ui/js/component/fileList/view.jsx +++ b/ui/js/component/fileList/view.jsx @@ -87,7 +87,8 @@ class FileList extends React.PureComponent { diff --git a/ui/js/component/fileTile/view.jsx b/ui/js/component/fileTile/view.jsx index 1abd44952..b243ea1d6 100644 --- a/ui/js/component/fileTile/view.jsx +++ b/ui/js/component/fileTile/view.jsx @@ -1,4 +1,5 @@ import React from "react"; +import * as icons from "constants/icons"; import lbryuri from "lbryuri.js"; import CardMedia from "component/cardMedia"; import FileActions from "component/fileActions"; @@ -6,12 +7,17 @@ import Link from "component/link"; import { TruncatedText } from "component/common.js"; import FilePrice from "component/filePrice"; import NsfwOverlay from "component/nsfwOverlay"; -import IconFeatured from "component/iconFeatured"; +import Icon from "component/icon"; class FileTile extends React.PureComponent { static SHOW_EMPTY_PUBLISH = "publish"; static SHOW_EMPTY_PENDING = "pending"; + static defaultProps = { + showPrice: true, + showLocal: true, + }; + constructor(props) { super(props); this.state = { @@ -59,8 +65,10 @@ class FileTile extends React.PureComponent { isResolvingUri, showEmpty, navigate, - hidePrice, + showPrice, + showLocal, rewardedContentClaimIds, + fileInfo, } = this.props; const uri = lbryuri.normalize(this.props.uri); @@ -111,8 +119,13 @@ class FileTile extends React.PureComponent {
- {!hidePrice ? : null} - {isRewardContent && } + + {showPrice && } + {" "} + {isRewardContent && } + {" "} + {showLocal && fileInfo && } +
{uri}

{title} diff --git a/ui/js/component/icon/index.js b/ui/js/component/icon/index.js new file mode 100644 index 000000000..72b01f640 --- /dev/null +++ b/ui/js/component/icon/index.js @@ -0,0 +1,5 @@ +import React from "react"; +import { connect } from "react-redux"; +import Icon from "./view"; + +export default connect(null, null)(Icon); diff --git a/ui/js/component/icon/view.jsx b/ui/js/component/icon/view.jsx new file mode 100644 index 000000000..5c23af877 --- /dev/null +++ b/ui/js/component/icon/view.jsx @@ -0,0 +1,40 @@ +import React from "react"; +import * as icons from "constants/icons"; + +export default class Icon extends React.PureComponent { + static propTypes = { + icon: React.PropTypes.string.isRequired, + fixed: React.PropTypes.bool, + }; + + static defaultProps = { + fixed: false, + }; + + getIconClass() { + const { icon } = this.props; + + return icon.startsWith("icon-") ? icon : "icon-" + icon; + } + + getIconTitle() { + switch (this.props.icon) { + case icons.FEATURED: + return __("Watch this and earn rewards."); + case icons.LOCAL: + return __("You have a copy of this file."); + default: + return ""; + } + } + + render() { + const className = this.getIconClass(), + title = this.getIconTitle(); + + const spanClassName = + "icon " + className + (this.props.fixed ? " icon-fixed-width " : ""); + + return ; + } +} diff --git a/ui/js/component/iconFeatured/index.js b/ui/js/component/iconFeatured/index.js deleted file mode 100644 index 02ce8fc38..000000000 --- a/ui/js/component/iconFeatured/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import IconFeatured from "./view"; - -export default connect(null, null)(IconFeatured); diff --git a/ui/js/component/iconFeatured/view.jsx b/ui/js/component/iconFeatured/view.jsx deleted file mode 100644 index 651d82338..000000000 --- a/ui/js/component/iconFeatured/view.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import { Icon } from "component/common.js"; - -const IconFeatured = props => { - return ( - - - - ); -}; - -export default IconFeatured; diff --git a/ui/js/component/publishForm/view.jsx b/ui/js/component/publishForm/view.jsx index b502f4add..e842870bb 100644 --- a/ui/js/component/publishForm/view.jsx +++ b/ui/js/component/publishForm/view.jsx @@ -20,6 +20,7 @@ class PublishForm extends React.PureComponent { this.state = { id: null, + uri: null, rawName: "", name: "", bid: 10, @@ -166,7 +167,6 @@ class PublishForm extends React.PureComponent { claim() { const { claimsByUri } = this.props; const { uri } = this.state; - return claimsByUri[uri]; } @@ -437,9 +437,10 @@ class PublishForm extends React.PureComponent { } onFileChange() { + const { mode } = this.state; if (this.refs.file.getValue()) { this.setState({ hasFile: true }); - if (!this.state.customUrl) { + if (!this.state.customUrl && mode !== "edit") { let fileName = this._getFileName(this.refs.file.getValue()); this.nameChanged(fileName); } @@ -822,7 +823,7 @@ class PublishForm extends React.PureComponent { { diff --git a/ui/js/component/walletSend/view.jsx b/ui/js/component/walletSend/view.jsx index 00beb2a86..3e65cceab 100644 --- a/ui/js/component/walletSend/view.jsx +++ b/ui/js/component/walletSend/view.jsx @@ -33,7 +33,7 @@ class WalletSend extends React.PureComponent { { - lbry._updateBalanceSubscribers(); - }, lbry._balanceSubscribeInterval); - } -}; - -lbry.balanceSubscribe = function(callback) { - const subscribeId = ++lbry._subscribeIdCount; - lbry._balanceSubscribeCallbacks[subscribeId] = callback; - lbry._updateBalanceSubscribers(); - return subscribeId; -}; - -lbry.balanceUnsubscribe = function(subscribeId) { - delete lbry._balanceSubscribeCallbacks[subscribeId]; - if ( - lbry._balanceUpdateInterval && - !Object.keys(lbry._balanceSubscribeCallbacks).length - ) { - clearInterval(lbry._balanceUpdateInterval); - } -}; - -lbry.showMenuIfNeeded = function() { - const showingMenu = sessionStorage.getItem("menuShown") || null; - const chosenMenu = lbry.getClientSetting("showDeveloperMenu") - ? "developer" - : "normal"; - if (chosenMenu != showingMenu) { - menu.showMenubar(chosenMenu == "developer"); - } - sessionStorage.setItem("menuShown", chosenMenu); -}; - lbry.getAppVersionInfo = function() { return new Promise((resolve, reject) => { ipcRenderer.once("version-info-received", (event, versionInfo) => { @@ -407,25 +349,6 @@ lbry.claim_list_mine = function(params = {}) { }); }; -lbry.claim_abandon = function(params = {}) { - return new Promise((resolve, reject) => { - apiCall("claim_abandon", params, resolve, reject); - }); -}; - -lbry.block_show = function(params = {}) { - return new Promise((resolve, reject) => { - apiCall( - "block_show", - params, - block => { - resolve(block); - }, - reject - ); - }); -}; - lbry._resolveXhrs = {}; lbry.resolve = function(params = {}) { return new Promise((resolve, reject) => { diff --git a/ui/js/main.js b/ui/js/main.js index e8a3221a0..9c6059366 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -16,14 +16,12 @@ const { remote, ipcRenderer, shell } = require("electron"); const contextMenu = remote.require("./menu/context-menu"); const app = require("./app"); -lbry.showMenuIfNeeded(); - window.addEventListener("contextmenu", event => { contextMenu.showContextMenu( remote.getCurrentWindow(), event.x, event.y, - lbry.getClientSetting("showDeveloperMenu") + env === "development" ); event.preventDefault(); }); diff --git a/ui/js/page/channel/view.jsx b/ui/js/page/channel/view.jsx index f7ccd1c8f..bb8f5d20b 100644 --- a/ui/js/page/channel/view.jsx +++ b/ui/js/page/channel/view.jsx @@ -52,6 +52,7 @@ class ChannelPage extends React.PureComponent { name: claim.name, claimId: claim.claim_id, })} + showLocal={true} /> ) : {__("No content found.")}; diff --git a/ui/js/page/developer.js b/ui/js/page/developer.js index 4b69df173..970a0d3e7 100644 --- a/ui/js/page/developer.js +++ b/ui/js/page/developer.js @@ -11,7 +11,6 @@ class DeveloperPage extends React.PureComponent { super(props); this.state = { - showDeveloperMenu: lbry.getClientSetting("showDeveloperMenu"), useCustomLighthouseServers: lbry.getClientSetting( "useCustomLighthouseServers" ), @@ -22,14 +21,6 @@ class DeveloperPage extends React.PureComponent { }; } - handleShowDeveloperMenuChange(event) { - lbry.setClientSetting("showDeveloperMenu", event.target.checked); - lbry.showMenuIfNeeded(); - this.setState({ - showDeveloperMenu: event.target.checked, - }); - } - handleUseCustomLighthouseServersChange(event) { lbry.setClientSetting("useCustomLighthouseServers", event.target.checked); this.setState({ @@ -71,19 +62,6 @@ class DeveloperPage extends React.PureComponent {

{__("Developer Settings")}

-
- -
-

{__("Max Purchase Price")}

+

{__("Purchase Settings")}

+
+ +
+
+
+ +
+ { + this.oninstantPurchaseEnabledChange(false); + }} + /> +
+ { + this.oninstantPurchaseEnabledChange(true); + }} + /> + {this.state.instantPurchaseEnabled && + this.onInstantPurchaseMaxChange(val)} + defaultValue={this.state.instantPurchaseMax} + />} +
+
+ When this option is chosen, LBRY won't ask you to confirm + downloads below the given price. +
+
diff --git a/ui/js/reducers/settings.js b/ui/js/reducers/settings.js index 2656c03fd..1c6834a91 100644 --- a/ui/js/reducers/settings.js +++ b/ui/js/reducers/settings.js @@ -6,6 +6,10 @@ import lbry from "lbry"; const reducers = {}; const defaultState = { clientSettings: { + instantPurchaseEnabled: lbry.getClientSetting( + settings.INSTANT_PURCHASE_ENABLED + ), + instantPurchaseMax: lbry.getClientSetting(settings.INSTANT_PURCHASE_MAX), showNsfw: lbry.getClientSetting(settings.SHOW_NSFW), showUnavailable: lbry.getClientSetting(settings.SHOW_UNAVAILABLE), welcome_acknowledged: lbry.getClientSetting(settings.NEW_USER_ACKNOWLEDGED), diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index 34c4ea688..c90b78843 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -180,7 +180,12 @@ export const selectMyChannelClaims = createSelector( const ids = state.myChannelClaims || []; const claims = []; - ids.forEach(id => claims.push(byId[id])); + ids.forEach(id => { + if (byId[id]) { + //I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-app/issues/544 + claims.push(byId[id]); + } + }); return claims; } diff --git a/ui/scss/_icons.scss b/ui/scss/_icons.scss index 537531e19..8fbf846b3 100644 --- a/ui/scss/_icons.scss +++ b/ui/scss/_icons.scss @@ -23,6 +23,17 @@ transform: translate(0, 0); } + +/* Adjustments for icon size and alignment */ +.icon-rocket { + color: orangered; + font-size: 0.95em; + position: relative; + top: -0.04em; + margin-left: 0.025em; + margin-right: 0.025em; +} + /* 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 { diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss index 0562b4040..03b515a4b 100644 --- a/ui/scss/component/_card.scss +++ b/ui/scss/component/_card.scss @@ -167,6 +167,11 @@ $font-size-subtext-multiple: 0.82; position: absolute; top: 36% } + +.card__indicators { + float: right; +} + .card--small { width: var(--card-small-width); overflow-x: hidden; @@ -269,10 +274,6 @@ $padding-right-card-hover-hack: 30px; right: 0; } -.card__icon-featured-content { - color: orangered; -} - /* if we keep doing things like this, we should add a real grid system, but I'm going to be a selective dick about it - Jeremy */ diff --git a/ui/scss/component/_file-tile.scss b/ui/scss/component/_file-tile.scss index 7341cc606..c35be3f9b 100644 --- a/ui/scss/component/_file-tile.scss +++ b/ui/scss/component/_file-tile.scss @@ -3,12 +3,6 @@ $height-file-tile: $spacing-vertical * 6; .file-tile__row { overflow: hidden; height: $height-file-tile; - .credit-amount { - float: right; - } - .icon-featured { - float: right; - } //also a hack .card__media { height: $height-file-tile;